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',
};
export default function Preview({ collection, fields, widgetFor }) {
if (!collection || !fields) {
return null;
export default class Preview extends React.Component {
render() {
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 = {

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 ImmutablePropTypes from 'react-immutable-proptypes';
import Frame from 'react-frame-component';
import { ScrollSyncPane } from '../ScrollSync';
import registry from '../../lib/registry';
import { resolveWidget } from '../Widgets';
import { selectTemplateName, selectInferedField } from '../../reducers/collections';
import { INFERABLE_FIELDS } from '../../constants/fieldInference';
import PreviewContent from './PreviewContent.js';
import PreviewHOC from '../Widgets/PreviewHOC';
import Preview from './Preview';
import styles from './PreviewPane.css';
@ -16,15 +17,18 @@ export default class PreviewPane extends React.Component {
const { fieldsMetaData, getAsset, entry } = props;
const widget = resolveWidget(field.get('widget'));
return !widget.preview ? null : React.createElement(widget.preview, {
field,
key: field.get('name'),
value: value && Map.isMap(value) ? value.get(field.get('name')) : value,
metadata: fieldsMetaData && fieldsMetaData.get(field.get('name')),
getAsset,
entry,
fieldsMetaData,
});
return !widget.preview ? null : (
<PreviewHOC
previewComponent={widget.preview}
key={field.get('name')}
field={field}
getAsset={getAsset}
value={value && Map.isMap(value) ? value.get(field.get('name')) : value}
metadata={fieldsMetaData && fieldsMetaData.get(field.get('name'))}
entry={entry}
fieldsMetaData={fieldsMetaData}
/>
);
};
inferedFields = {};
@ -118,7 +122,9 @@ export default class PreviewPane extends React.Component {
return null;
}
const component = registry.getPreviewTemplate(selectTemplateName(collection, entry.get('slug'))) || Preview;
const previewComponent =
registry.getPreviewTemplate(selectTemplateName(collection, entry.get('slug'))) ||
Preview;
this.inferFields();
@ -135,18 +141,6 @@ export default class PreviewPane extends React.Component {
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
className={styles.frame}
head={styleEls}
@ -156,7 +150,7 @@ export default class PreviewPane extends React.Component {
<head><base target="_blank"/></head>
<body><div></div></body>
</html>`}
><PreviewContent /></Frame>);
><PreviewContent {...{ previewComponent, previewProps }}/></Frame>);
}
}

View File

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

View File

@ -166,6 +166,7 @@ const RULES = [
}
},
},
/*
{
// Special case for links, to grab their href.
deserialize(el, next) {
@ -180,6 +181,7 @@ const 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;