wix-storybook-utils
Version:
Utilities for automated component documentation within Storybook
198 lines • 12.6 kB
JavaScript
"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