wix-storybook-utils
Version:
Utilities for automated component documentation within Storybook
196 lines • 11.1 kB
JavaScript
import { __assign, __extends } from "tslib";
import React from 'react';
import PropTypes from 'prop-types';
import { LiveProvider, LiveError, LivePreview } from 'react-live';
import classnames from 'classnames';
import { Collapse } from 'react-collapse';
import DuplicateSmall from '../icons/DuplicateSmall';
import RevertSmall from '../icons/RevertSmall';
import CodeSmall from '../icons/CodeSmall';
import MagicWandSmall from '../icons/MagicWandSmall';
import LinkSmall from '../icons/LinkSmall';
import { transformCode, formatCode } from './doctor-code';
import { CopyButton } from '../CopyButton';
import ToggleSwitch from '../ui/toggle-switch';
import TextButton from '../TextButton';
import Editor from './Editor';
import styles from './index.scss';
import { getComponentsHints } from '../utils';
var LiveCodeExample = /** @class */ (function (_super) {
__extends(LiveCodeExample, _super);
function LiveCodeExample(props) {
var _this = _super.call(this, props) || this;
_this.prettifyCode = function () {
try {
_this.setState(function (_a) {
var code = _a.code;
return ({ code: formatCode(code) });
}, function () { return _this.state.setEditorValue(_this.state.code); });
}
catch (e) {
console.error('Unable to prettify code', e);
}
};
_this.onResetCode = function () {
var code = formatCode(_this.props.initialCode);
_this.state.setEditorValue(code);
_this.setState({ code: code });
};
_this.onEditorChange = function (code) {
var _a = _this.props, title = _a.title, onChange = _a.onChange, storyName = _a.storyName, storage = _a.storage;
_this.setState({ code: code }, function () { return onChange(_this.state.code); });
storage && storage.setItem("".concat(storyName, "-").concat(title), code);
};
_this.onToggleRtl = function (isRtl) { return _this.setState({ isRtl: isRtl }); };
_this.onToggleBackground = function (isDarkBackground) {
return _this.setState({ isDarkBackground: isDarkBackground });
};
_this.onToggleCode = function () {
return _this.setState(function (state) { return ({
isEditorOpened: !state.isEditorOpened,
}); });
};
_this.transformCode = function (code) {
if (code === void 0) { code = ''; }
var parseError = _this.state.parseError;
var newParseError;
var returnValue = code;
try {
returnValue = transformCode(code);
newParseError = null;
}
catch (error) {
// @ts-expect-error
newParseError = error.message;
}
if (newParseError !== parseError) {
_this.setState({ parseError: newParseError });
}
return returnValue;
};
_this.previewWarning = function () {
return _this.props.previewWarning({
onConfirm: function () { return _this.setState({ renderPreview: true }); },
});
};
_this.renderError = function () {
if (_this.state.renderPreview) {
return _this.state.parseError ? (React.createElement("div", { className: styles.error }, _this.state.parseError)) : (React.createElement(LiveError, { className: styles.error }));
}
return null;
};
_this.renderLivePreview = function () {
var _a = _this.props, examplesPreviewWrapper = _a.examplesPreviewWrapper, previewProps = _a.previewProps, previewRow = _a.previewRow;
var livePreviewComp = (React.createElement(LivePreview, __assign({}, previewProps, { className: previewRow ? styles.previewRow : null })));
return examplesPreviewWrapper
? examplesPreviewWrapper({ component: livePreviewComp })
: livePreviewComp;
};
var storyName = props.storyName, title = props.title, initialCode = props.initialCode, darkBackground = props.darkBackground, compact = props.compact, initiallyOpen = props.initiallyOpen, previewWarning = props.previewWarning, storage = props.storage, forceInitialCode = props.forceInitialCode;
var codeFromStorage = storage && storage.getItem("".concat(storyName, "-").concat(title));
var initialOriginalCode = formatCode(initialCode).trim();
var formattedCode = codeFromStorage && !forceInitialCode
? codeFromStorage
: initialOriginalCode;
_this.state = {
initialOriginalCode: initialOriginalCode,
initialFormattedCode: formattedCode,
code: formattedCode,
isRtl: false,
isDarkBackground: darkBackground,
isEditorOpened: !compact || initiallyOpen,
parseError: null,
renderPreview: !Boolean(previewWarning),
setEditorValue: null,
};
return _this;
}
LiveCodeExample.prototype.componentDidUpdate = function (prevProps) {
var renderPreview = this.state.renderPreview;
if (this.props.previewWarning !== prevProps.previewWarning &&
typeof prevProps.previewWarning === 'function' &&
renderPreview) {
this.setState({ renderPreview: false });
}
};
LiveCodeExample.prototype.componentDidMount = function () {
var _a = this.props, hints = _a.hints, scope = _a.scope;
this.setState({ hints: hints || getComponentsHints(scope) });
};
LiveCodeExample.prototype.render = function () {
var _a, _b;
var _this = this;
var _c = this.props, scope = _c.scope, compact = _c.compact, previewProps = _c.previewProps, autoRender = _c.autoRender, noBackground = _c.noBackground, hideCodeEditor = _c.hideCodeEditor, figmaLink = _c.figmaLink;
var _d = this.state, code = _d.code, isRtl = _d.isRtl, isDarkBackground = _d.isDarkBackground, isEditorOpened = _d.isEditorOpened, renderPreview = _d.renderPreview, hints = _d.hints;
var dirty = this.state.initialOriginalCode !== this.state.code;
return (React.createElement("div", { className: classnames(styles.wrapper, (_a = {},
_a[styles.compact] = compact,
_a)) },
!hideCodeEditor && !compact && (React.createElement("div", { className: styles.header },
React.createElement(CopyButton, { source: this.state.code, prefixIcon: React.createElement(DuplicateSmall, null) }),
React.createElement("div", { className: styles.spacer }),
dirty && (React.createElement("div", { className: styles.headerControl },
React.createElement(TextButton, { onClick: function () { return _this.prettifyCode(); }, prefixIcon: React.createElement(MagicWandSmall, null) }, "Prettify"))),
React.createElement("div", { className: styles.headerControl },
"Imitate RTL:\u00A0",
React.createElement(ToggleSwitch, { size: "small", checked: isRtl, onChange: this.onToggleRtl })),
React.createElement("div", { className: styles.headerControl },
"Dark Background:\u00A0",
React.createElement(ToggleSwitch, { size: "small", checked: isDarkBackground, onChange: this.onToggleBackground })),
dirty && (React.createElement(TextButton, { onClick: this.onResetCode, prefixIcon: React.createElement(RevertSmall, null) }, "Reset")))),
React.createElement(LiveProvider, { code: code.trim(), scope: __assign({ isRtl: isRtl }, scope), noInline: !autoRender, transformCode: this.transformCode },
React.createElement("div", { className: styles.liveExampleWrapper },
React.createElement("div", { className: classnames(styles.preview, previewProps.className, (_b = {
rtl: isRtl
},
_b[styles.darkPreview] = isDarkBackground,
_b[styles.compactPreview] = compact && !noBackground,
_b)), dir: isRtl ? 'rtl' : '' },
renderPreview ? this.renderLivePreview() : this.previewWarning(),
this.renderError()),
!hideCodeEditor && (React.createElement(Collapse, { isOpened: isEditorOpened, className: styles.editor },
React.createElement(Editor, { initialFormattedCode: this.state.initialFormattedCode, onChange: this.onEditorChange, hints: hints, editorCodeUpdater: function (updater) {
return _this.setState({ setEditorValue: updater });
} }))))),
!hideCodeEditor && compact && (React.createElement("div", { className: styles.controlButtons },
React.createElement(CopyButton, { source: this.state.code, prefixIcon: React.createElement(DuplicateSmall, null) }),
figmaLink && React.createElement(TextButton, { className: styles.figmaLink, prefixIcon: React.createElement(LinkSmall, null), onClick: function () { return window.open(figmaLink, '_blank'); } }, "Figma"),
dirty && (React.createElement(TextButton, { onClick: function () { return _this.prettifyCode(); }, prefixIcon: React.createElement(MagicWandSmall, null) }, "Prettify")),
React.createElement("div", { style: { marginLeft: 'auto' } }),
dirty && (React.createElement(TextButton, { onClick: this.onResetCode, prefixIcon: React.createElement(RevertSmall, null) }, "Reset")),
React.createElement(TextButton, { onClick: this.onToggleCode, prefixIcon: React.createElement(CodeSmall, null) },
this.state.isEditorOpened ? 'Hide' : 'Show',
" code")))));
};
LiveCodeExample.propTypes = {
initialCode: PropTypes.string,
title: PropTypes.string,
figmaLink: PropTypes.string,
storyName: PropTypes.string,
storage: PropTypes.object,
scope: PropTypes.object,
compact: PropTypes.bool,
initiallyOpen: PropTypes.bool,
previewRow: PropTypes.bool,
previewProps: PropTypes.object,
autoRender: PropTypes.bool,
darkBackground: PropTypes.bool,
noBackground: PropTypes.bool,
forceInitialCode: PropTypes.bool,
};
LiveCodeExample.defaultProps = {
compact: false,
initiallyOpen: false,
previewRow: false,
previewProps: {},
autoRender: true,
darkBackground: false,
noBackground: false,
forceInitialCode: false,
onChange: function () { },
scope: {},
};
return LiveCodeExample;
}(React.PureComponent));
export default LiveCodeExample;
//# sourceMappingURL=LiveCodeExample.js.map