UNPKG

wix-storybook-utils

Version:

Utilities for automated component documentation within Storybook

198 lines 12.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var react_1 = tslib_1.__importDefault(require("react")); var prop_types_1 = tslib_1.__importDefault(require("prop-types")); var react_live_1 = require("react-live"); var classnames_1 = tslib_1.__importDefault(require("classnames")); var react_collapse_1 = require("react-collapse"); var DuplicateSmall_1 = tslib_1.__importDefault(require("../icons/DuplicateSmall")); var RevertSmall_1 = tslib_1.__importDefault(require("../icons/RevertSmall")); var CodeSmall_1 = tslib_1.__importDefault(require("../icons/CodeSmall")); var MagicWandSmall_1 = tslib_1.__importDefault(require("../icons/MagicWandSmall")); var LinkSmall_1 = tslib_1.__importDefault(require("../icons/LinkSmall")); var doctor_code_1 = require("./doctor-code"); var CopyButton_1 = require("../CopyButton"); var toggle_switch_1 = tslib_1.__importDefault(require("../ui/toggle-switch")); var TextButton_1 = tslib_1.__importDefault(require("../TextButton")); var Editor_1 = tslib_1.__importDefault(require("./Editor")); var index_scss_1 = tslib_1.__importDefault(require("./index.scss")); var utils_1 = require("../utils"); var LiveCodeExample = /** @class */ (function (_super) { tslib_1.__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: (0, doctor_code_1.formatCode)(code) }); }, function () { return _this.state.setEditorValue(_this.state.code); }); } catch (e) { console.error('Unable to prettify code', e); } }; _this.onResetCode = function () { var code = (0, doctor_code_1.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 = (0, doctor_code_1.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_1.default.createElement("div", { className: index_scss_1.default.error }, _this.state.parseError)) : (react_1.default.createElement(react_live_1.LiveError, { className: index_scss_1.default.error })); } return null; }; _this.renderLivePreview = function () { var _a = _this.props, examplesPreviewWrapper = _a.examplesPreviewWrapper, previewProps = _a.previewProps, previewRow = _a.previewRow; var livePreviewComp = (react_1.default.createElement(react_live_1.LivePreview, tslib_1.__assign({}, previewProps, { className: previewRow ? index_scss_1.default.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 = (0, doctor_code_1.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 || (0, utils_1.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_1.default.createElement("div", { className: (0, classnames_1.default)(index_scss_1.default.wrapper, (_a = {}, _a[index_scss_1.default.compact] = compact, _a)) }, !hideCodeEditor && !compact && (react_1.default.createElement("div", { className: index_scss_1.default.header }, react_1.default.createElement(CopyButton_1.CopyButton, { source: this.state.code, prefixIcon: react_1.default.createElement(DuplicateSmall_1.default, null) }), react_1.default.createElement("div", { className: index_scss_1.default.spacer }), dirty && (react_1.default.createElement("div", { className: index_scss_1.default.headerControl }, react_1.default.createElement(TextButton_1.default, { onClick: function () { return _this.prettifyCode(); }, prefixIcon: react_1.default.createElement(MagicWandSmall_1.default, null) }, "Prettify"))), react_1.default.createElement("div", { className: index_scss_1.default.headerControl }, "Imitate RTL:\u00A0", react_1.default.createElement(toggle_switch_1.default, { size: "small", checked: isRtl, onChange: this.onToggleRtl })), react_1.default.createElement("div", { className: index_scss_1.default.headerControl }, "Dark Background:\u00A0", react_1.default.createElement(toggle_switch_1.default, { size: "small", checked: isDarkBackground, onChange: this.onToggleBackground })), dirty && (react_1.default.createElement(TextButton_1.default, { onClick: this.onResetCode, prefixIcon: react_1.default.createElement(RevertSmall_1.default, null) }, "Reset")))), react_1.default.createElement(react_live_1.LiveProvider, { code: code.trim(), scope: tslib_1.__assign({ isRtl: isRtl }, scope), noInline: !autoRender, transformCode: this.transformCode }, react_1.default.createElement("div", { className: index_scss_1.default.liveExampleWrapper }, react_1.default.createElement("div", { className: (0, classnames_1.default)(index_scss_1.default.preview, previewProps.className, (_b = { rtl: isRtl }, _b[index_scss_1.default.darkPreview] = isDarkBackground, _b[index_scss_1.default.compactPreview] = compact && !noBackground, _b)), dir: isRtl ? 'rtl' : '' }, renderPreview ? this.renderLivePreview() : this.previewWarning(), this.renderError()), !hideCodeEditor && (react_1.default.createElement(react_collapse_1.Collapse, { isOpened: isEditorOpened, className: index_scss_1.default.editor }, react_1.default.createElement(Editor_1.default, { initialFormattedCode: this.state.initialFormattedCode, onChange: this.onEditorChange, hints: hints, editorCodeUpdater: function (updater) { return _this.setState({ setEditorValue: updater }); } }))))), !hideCodeEditor && compact && (react_1.default.createElement("div", { className: index_scss_1.default.controlButtons }, react_1.default.createElement(CopyButton_1.CopyButton, { source: this.state.code, prefixIcon: react_1.default.createElement(DuplicateSmall_1.default, null) }), figmaLink && react_1.default.createElement(TextButton_1.default, { className: index_scss_1.default.figmaLink, prefixIcon: react_1.default.createElement(LinkSmall_1.default, null), onClick: function () { return window.open(figmaLink, '_blank'); } }, "Figma"), dirty && (react_1.default.createElement(TextButton_1.default, { onClick: function () { return _this.prettifyCode(); }, prefixIcon: react_1.default.createElement(MagicWandSmall_1.default, null) }, "Prettify")), react_1.default.createElement("div", { style: { marginLeft: 'auto' } }), dirty && (react_1.default.createElement(TextButton_1.default, { onClick: this.onResetCode, prefixIcon: react_1.default.createElement(RevertSmall_1.default, null) }, "Reset")), react_1.default.createElement(TextButton_1.default, { onClick: this.onToggleCode, prefixIcon: react_1.default.createElement(CodeSmall_1.default, null) }, this.state.isEditorOpened ? 'Hide' : 'Show', " code"))))); }; LiveCodeExample.propTypes = { initialCode: prop_types_1.default.string, title: prop_types_1.default.string, figmaLink: prop_types_1.default.string, storyName: prop_types_1.default.string, storage: prop_types_1.default.object, scope: prop_types_1.default.object, compact: prop_types_1.default.bool, initiallyOpen: prop_types_1.default.bool, previewRow: prop_types_1.default.bool, previewProps: prop_types_1.default.object, autoRender: prop_types_1.default.bool, darkBackground: prop_types_1.default.bool, noBackground: prop_types_1.default.bool, forceInitialCode: prop_types_1.default.bool, }; LiveCodeExample.defaultProps = { compact: false, initiallyOpen: false, previewRow: false, previewProps: {}, autoRender: true, darkBackground: false, noBackground: false, forceInitialCode: false, onChange: function () { }, scope: {}, }; return LiveCodeExample; }(react_1.default.PureComponent)); exports.default = LiveCodeExample; //# sourceMappingURL=LiveCodeExample.js.map