only render editor page controls/previews on change
This commit is contained in:
@ -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 = {
|
||||||
|
22
src/components/PreviewPane/PreviewContent.js
Normal file
22
src/components/PreviewPane/PreviewContent.js
Normal 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;
|
@ -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>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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 });
|
||||||
|
14
src/components/Widgets/PreviewHOC.js
Normal file
14
src/components/Widgets/PreviewHOC.js
Normal 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;
|
Reference in New Issue
Block a user