only render editor page controls/previews on change

This commit is contained in:
Shawn Erquhart
2017-06-21 15:58:56 -04:00
parent e01c077efb
commit e682189410
6 changed files with 71 additions and 32 deletions

View File

@ -9,15 +9,18 @@ const style = {
fontFamily: 'Roboto, "Helvetica Neue", HelveticaNeue, Helvetica, Arial, sans-serif', fontFamily: 'Roboto, "Helvetica Neue", HelveticaNeue, Helvetica, Arial, sans-serif',
}; };
export default function Preview({ collection, fields, widgetFor }) { export default class Preview extends React.Component {
if (!collection || !fields) { render() {
return null; const { collection, fields, widgetFor } = this.props;
if (!collection || !fields) {
return null;
}
return (
<div style={style}>
{fields.filter(isVisible).map(field => widgetFor(field.get('name')))}
</div>
);
} }
return (
<div style={style}>
{fields.filter(isVisible).map(field => widgetFor(field.get('name')))}
</div>
);
} }
Preview.propTypes = { Preview.propTypes = {

View File

@ -0,0 +1,22 @@
import React, { PropTypes } from 'react';
import { ScrollSyncPane } from '../ScrollSync';
// We need to create a lightweight component here so that we can
// access the context within the Frame. This allows us to attach
// the ScrollSyncPane to the body.
class PreviewContent extends React.Component {
render() {
const { previewComponent, previewProps } = this.props;
return (
<ScrollSyncPane attachTo={this.context.document.scrollingElement}>
{React.createElement(previewComponent, previewProps)}
</ScrollSyncPane>
);
}
}
PreviewContent.contextTypes = {
document: PropTypes.any,
};
export default PreviewContent;

View File

@ -2,11 +2,12 @@ import React, { PropTypes } from 'react';
import { List, Map } from 'immutable'; import { List, Map } from 'immutable';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import Frame from 'react-frame-component'; import Frame from 'react-frame-component';
import { ScrollSyncPane } from '../ScrollSync';
import registry from '../../lib/registry'; import registry from '../../lib/registry';
import { resolveWidget } from '../Widgets'; import { resolveWidget } from '../Widgets';
import { selectTemplateName, selectInferedField } from '../../reducers/collections'; import { selectTemplateName, selectInferedField } from '../../reducers/collections';
import { INFERABLE_FIELDS } from '../../constants/fieldInference'; import { INFERABLE_FIELDS } from '../../constants/fieldInference';
import PreviewContent from './PreviewContent.js';
import PreviewHOC from '../Widgets/PreviewHOC';
import Preview from './Preview'; import Preview from './Preview';
import styles from './PreviewPane.css'; import styles from './PreviewPane.css';
@ -16,15 +17,18 @@ export default class PreviewPane extends React.Component {
const { fieldsMetaData, getAsset, entry } = props; const { fieldsMetaData, getAsset, entry } = props;
const widget = resolveWidget(field.get('widget')); const widget = resolveWidget(field.get('widget'));
return !widget.preview ? null : React.createElement(widget.preview, { return !widget.preview ? null : (
field, <PreviewHOC
key: field.get('name'), previewComponent={widget.preview}
value: value && Map.isMap(value) ? value.get(field.get('name')) : value, key={field.get('name')}
metadata: fieldsMetaData && fieldsMetaData.get(field.get('name')), field={field}
getAsset, getAsset={getAsset}
entry, value={value && Map.isMap(value) ? value.get(field.get('name')) : value}
fieldsMetaData, metadata={fieldsMetaData && fieldsMetaData.get(field.get('name'))}
}); entry={entry}
fieldsMetaData={fieldsMetaData}
/>
);
}; };
inferedFields = {}; inferedFields = {};
@ -118,7 +122,9 @@ export default class PreviewPane extends React.Component {
return null; return null;
} }
const component = registry.getPreviewTemplate(selectTemplateName(collection, entry.get('slug'))) || Preview; const previewComponent =
registry.getPreviewTemplate(selectTemplateName(collection, entry.get('slug'))) ||
Preview;
this.inferFields(); this.inferFields();
@ -135,18 +141,6 @@ export default class PreviewPane extends React.Component {
return <Frame className={styles.frame} head={styleEls} />; return <Frame className={styles.frame} head={styleEls} />;
} }
// We need to create a lightweight component here so that we can
// access the context within the Frame. This allows us to attach
// the ScrollSyncPane to the body.
const PreviewContent = (props, { document: iFrameDocument }) => (
<ScrollSyncPane attachTo={iFrameDocument.scrollingElement}>
{React.createElement(component, previewProps)}
</ScrollSyncPane>);
PreviewContent.contextTypes = {
document: PropTypes.any,
};
return (<Frame return (<Frame
className={styles.frame} className={styles.frame}
head={styleEls} head={styleEls}
@ -156,7 +150,7 @@ export default class PreviewPane extends React.Component {
<head><base target="_blank"/></head> <head><base target="_blank"/></head>
<body><div></div></body> <body><div></div></body>
</html>`} </html>`}
><PreviewContent /></Frame>); ><PreviewContent {...{ previewComponent, previewProps }}/></Frame>);
} }
} }

View File

@ -22,6 +22,10 @@ class ControlHOC extends Component {
getAsset: PropTypes.func.isRequired, getAsset: PropTypes.func.isRequired,
}; };
shouldComponentUpdate(nextProps) {
return nextProps.value !== this.props.value;
}
processInnerControlRef = (wrappedControl) => { processInnerControlRef = (wrappedControl) => {
if (!wrappedControl) return; if (!wrappedControl) return;
this.wrappedControlValid = wrappedControl.isValid || truthy; this.wrappedControlValid = wrappedControl.isValid || truthy;

View File

@ -166,6 +166,7 @@ const RULES = [
} }
}, },
}, },
/*
{ {
// Special case for links, to grab their href. // Special case for links, to grab their href.
deserialize(el, next) { deserialize(el, next) {
@ -180,6 +181,7 @@ const RULES = [
} }
}, },
}, },
*/
] ]
const serializer = new SlateHtml({ rules: RULES }); const serializer = new SlateHtml({ rules: RULES });

View File

@ -0,0 +1,14 @@
import React from 'react';
class PreviewHOC extends React.Component {
shouldComponentUpdate(nextProps) {
return nextProps.value !== this.props.value;
}
render() {
const { previewComponent, ...props } = this.props;
return React.createElement(previewComponent, props);
}
}
export default PreviewHOC;