Fix preview panel

This commit is contained in:
Daniel Lautzenheiser 2022-09-19 22:28:01 -04:00
parent 1f2536959f
commit e55804a930
4 changed files with 40 additions and 45 deletions

View File

@ -3,7 +3,6 @@ import React, { Component } from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import { css, Global } from '@emotion/core'; import { css, Global } from '@emotion/core';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import SplitPane from 'react-split-pane';
import { import {
colors, colors,
colorsRaw, colorsRaw,
@ -23,7 +22,6 @@ import { getFileFromSlug } from '../../reducers/collections';
const PREVIEW_VISIBLE = 'cms.preview-visible'; const PREVIEW_VISIBLE = 'cms.preview-visible';
const SCROLL_SYNC_ENABLED = 'cms.scroll-sync-enabled'; const SCROLL_SYNC_ENABLED = 'cms.scroll-sync-enabled';
const SPLIT_PANE_POSITION = 'cms.split-pane-position';
const I18N_VISIBLE = 'cms.i18n-visible'; const I18N_VISIBLE = 'cms.i18n-visible';
const styles = { const styles = {
@ -34,7 +32,6 @@ const styles = {
`, `,
pane: css` pane: css`
height: 100%; height: 100%;
overflow-y: auto;
`, `,
}; };
@ -72,14 +69,18 @@ function ReactSplitPaneGlobalStyles() {
); );
} }
const StyledSplitPane = styled(SplitPane)` const StyledSplitPane = styled.div`
${styles.splitPane}; display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
height: 100%;
/** div:nth-child(2)::before {
* Quick fix for preview pane not fully displaying in Safari content: '';
*/ width: 2px;
.Pane {
height: 100%; height: 100%;
position: relative;
background-color: rgb(223, 223, 227);
display: block;
} }
`; `;
@ -96,7 +97,6 @@ const EditorContainer = styled.div`
left: 0; left: 0;
overflow: hidden; overflow: hidden;
padding-top: 66px; padding-top: 66px;
background-color: ${colors.background};
`; `;
const Editor = styled.div` const Editor = styled.div`
@ -120,7 +120,7 @@ const ControlPaneContainer = styled(PreviewPaneContainer)`
const ViewControls = styled.div` const ViewControls = styled.div`
position: absolute; position: absolute;
top: 10px; top: 10px;
right: 10px; right: 28px;
z-index: ${zIndex.zIndex299}; z-index: ${zIndex.zIndex299};
`; `;
@ -151,20 +151,11 @@ function isPreviewEnabled(collection, entry) {
class EditorInterface extends Component { class EditorInterface extends Component {
state = { state = {
showEventBlocker: false,
previewVisible: localStorage.getItem(PREVIEW_VISIBLE) !== 'false', previewVisible: localStorage.getItem(PREVIEW_VISIBLE) !== 'false',
scrollSyncEnabled: localStorage.getItem(SCROLL_SYNC_ENABLED) !== 'false', scrollSyncEnabled: localStorage.getItem(SCROLL_SYNC_ENABLED) !== 'false',
i18nVisible: localStorage.getItem(I18N_VISIBLE) !== 'false', i18nVisible: localStorage.getItem(I18N_VISIBLE) !== 'false',
}; };
handleSplitPaneDragStart = () => {
this.setState({ showEventBlocker: true });
};
handleSplitPaneDragFinished = () => {
this.setState({ showEventBlocker: false });
};
handleOnPersist = async (opts = {}) => { handleOnPersist = async (opts = {}) => {
const { createNew = false, duplicate = false } = opts; const { createNew = false, duplicate = false } = opts;
await this.controlPaneRef.switchToDefaultLocale(); await this.controlPaneRef.switchToDefaultLocale();
@ -234,7 +225,7 @@ class EditorInterface extends Component {
t, t,
} = this.props; } = this.props;
const { scrollSyncEnabled, showEventBlocker } = this.state; const { scrollSyncEnabled } = this.state;
const previewEnabled = isPreviewEnabled(collection, entry); const previewEnabled = isPreviewEnabled(collection, entry);
@ -252,7 +243,7 @@ class EditorInterface extends Component {
const leftPanelLocale = this.state.leftPanelLocale || locales?.[0]; const leftPanelLocale = this.state.leftPanelLocale || locales?.[0];
const editor = ( const editor = (
<ControlPaneContainer id="control-pane" overFlow blockEntry={showEventBlocker}> <ControlPaneContainer id="control-pane" overFlow>
<EditorControlPane <EditorControlPane
{...editorProps} {...editorProps}
ref={c => (this.controlPaneRef = c)} ref={c => (this.controlPaneRef = c)}
@ -264,7 +255,7 @@ class EditorInterface extends Component {
); );
const editor2 = ( const editor2 = (
<ControlPaneContainer overFlow={!this.state.scrollSyncEnabled} blockEntry={showEventBlocker}> <ControlPaneContainer overFlow={!this.state.scrollSyncEnabled}>
<EditorControlPane {...editorProps} locale={locales?.[1]} t={t} /> <EditorControlPane {...editorProps} locale={locales?.[1]} t={t} />
</ControlPaneContainer> </ControlPaneContainer>
); );
@ -275,17 +266,11 @@ class EditorInterface extends Component {
const editorWithPreview = ( const editorWithPreview = (
<ScrollSync enabled={this.state.scrollSyncEnabled}> <ScrollSync enabled={this.state.scrollSyncEnabled}>
<div> <>
<ReactSplitPaneGlobalStyles /> <ReactSplitPaneGlobalStyles />
<StyledSplitPane <StyledSplitPane>
maxSize={-100}
defaultSize={parseInt(localStorage.getItem(SPLIT_PANE_POSITION), 10) || '50%'}
onChange={size => localStorage.setItem(SPLIT_PANE_POSITION, size)}
onDragStarted={this.handleSplitPaneDragStart}
onDragFinished={this.handleSplitPaneDragFinished}
>
<ScrollSyncPane>{editor}</ScrollSyncPane> <ScrollSyncPane>{editor}</ScrollSyncPane>
<PreviewPaneContainer blockEntry={showEventBlocker}> <PreviewPaneContainer>
<EditorPreviewPane <EditorPreviewPane
collection={collection} collection={collection}
entry={previewEntry} entry={previewEntry}
@ -295,20 +280,14 @@ class EditorInterface extends Component {
/> />
</PreviewPaneContainer> </PreviewPaneContainer>
</StyledSplitPane> </StyledSplitPane>
</div> </>
</ScrollSync> </ScrollSync>
); );
const editorWithEditor = ( const editorWithEditor = (
<ScrollSync enabled={this.state.scrollSyncEnabled}> <ScrollSync enabled={this.state.scrollSyncEnabled}>
<div> <div>
<StyledSplitPane <StyledSplitPane>
maxSize={-100}
defaultSize={parseInt(localStorage.getItem(SPLIT_PANE_POSITION), 10) || '50%'}
onChange={size => localStorage.setItem(SPLIT_PANE_POSITION, size)}
onDragStarted={this.handleSplitPaneDragStart}
onDragFinished={this.handleSplitPaneDragFinished}
>
<ScrollSyncPane>{editor}</ScrollSyncPane> <ScrollSyncPane>{editor}</ScrollSyncPane>
<ScrollSyncPane>{editor2}</ScrollSyncPane> <ScrollSyncPane>{editor2}</ScrollSyncPane>
</StyledSplitPane> </StyledSplitPane>

View File

@ -8,6 +8,10 @@ function isVisible(field) {
} }
const PreviewContainer = styled.div` const PreviewContainer = styled.div`
overflow-y: auto;
height: 100%;
padding: 24px;
box-sizing: border-box;
font-family: Roboto, 'Helvetica Neue', HelveticaNeue, Helvetica, Arial, sans-serif; font-family: Roboto, 'Helvetica Neue', HelveticaNeue, Helvetica, Arial, sans-serif;
`; `;

View File

@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/consistent-type-imports */ /* eslint-disable @typescript-eslint/consistent-type-imports */
/* eslint-disable func-style */ /* eslint-disable func-style */
import styled from '@emotion/styled';
import { CmsWidgetPreviewProps } from 'netlify-cms-core'; import { CmsWidgetPreviewProps } from 'netlify-cms-core';
import React, { ComponentType, ReactNode, useMemo } from 'react'; import React, { ComponentType, ReactNode, useMemo } from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
@ -11,6 +12,14 @@ interface PreviewContentProps {
previewProps: CmsWidgetPreviewProps; previewProps: CmsWidgetPreviewProps;
} }
const StyledPreviewContent = styled.div`
width: calc(50% - 2px);
top: 66px;
right: 0;
position: absolute;
height: calc(100% - 66px);
`;
const PreviewContent = ({ previewComponent, previewProps }: PreviewContentProps) => { const PreviewContent = ({ previewComponent, previewProps }: PreviewContentProps) => {
const element = useMemo(() => document.getElementById('nc-root'), []); const element = useMemo(() => document.getElementById('nc-root'), []);
@ -28,7 +37,10 @@ const PreviewContent = ({ previewComponent, previewProps }: PreviewContentProps)
children = React.createElement(previewComponent, previewProps); children = React.createElement(previewComponent, previewProps);
} }
return ReactDOM.createPortal(<div className="preview-content">{children}</div>, element); return ReactDOM.createPortal(
<StyledPreviewContent className="preview-content">{children}</StyledPreviewContent>,
element,
);
}, [previewComponent, previewProps, element]); }, [previewComponent, previewProps, element]);
}; };

View File

@ -497,6 +497,10 @@ function GlobalStyles() {
margin: 0; margin: 0;
} }
img {
max-width: 100%;
}
${quantifier} { ${quantifier} {
font-family: ${fonts.primary}; font-family: ${fonts.primary};
font-weight: normal; font-weight: normal;
@ -555,10 +559,6 @@ function GlobalStyles() {
text-decoration: none; text-decoration: none;
} }
img {
max-width: 100%;
}
textarea { textarea {
resize: none; resize: none;
} }