decap-cms-core
Version:
Decap CMS core application, see decap-cms package for the main distribution.
71 lines (70 loc) • 2.19 kB
JavaScript
import PropTypes from 'prop-types';
import React from 'react';
import { isElement } from 'react-is';
import { ScrollSyncPane } from 'react-scroll-sync';
import { FrameContextConsumer } from 'react-frame-component';
import { vercelStegaDecode } from '@vercel/stega';
/**
* PreviewContent renders the preview component and optionally handles visual editing interactions.
* By default it uses scroll sync, but can be configured to use visual editing instead.
*/
import { jsx as _jsx } from "@emotion/react/jsx-runtime";
class PreviewContent extends React.Component {
handleClick = e => {
const {
previewProps,
onFieldClick
} = this.props;
const visualEditing = previewProps?.collection?.getIn(['editor', 'visualEditing'], false);
if (!visualEditing) {
return;
}
try {
const text = e.target.textContent;
const decoded = vercelStegaDecode(text);
if (decoded?.decap) {
if (onFieldClick) {
onFieldClick(decoded.decap);
}
}
} catch (err) {
console.log('Visual editing error:', err);
}
};
renderPreview() {
const {
previewComponent,
previewProps
} = this.props;
return _jsx("div", {
onClick: this.handleClick,
children: isElement(previewComponent) ? /*#__PURE__*/React.cloneElement(previewComponent, previewProps) : /*#__PURE__*/React.createElement(previewComponent, previewProps)
});
}
render() {
const {
previewProps
} = this.props;
const visualEditing = previewProps?.collection?.getIn(['editor', 'visualEditing'], false);
const showScrollSync = !visualEditing;
return _jsx(FrameContextConsumer, {
children: context => {
const preview = this.renderPreview();
if (showScrollSync) {
return _jsx(ScrollSyncPane, {
attachTo: context.document.scrollingElement,
children: preview
});
}
return preview;
}
});
}
}
PreviewContent.propTypes = {
previewComponent: PropTypes.func.isRequired,
getEditorComponents: PropTypes.func,
previewProps: PropTypes.object,
onFieldClick: PropTypes.func
};
export default PreviewContent;