UNPKG

@skbkontur/storybook-addon-live-examples

Version:

Storybook live examples plugin

197 lines (196 loc) 11.4 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.Example = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _react = _interopRequireWildcard(require("react")); var _reactLive = require("react-live"); var _prismReactRenderer = require("prism-react-renderer"); var _theming = require("@storybook/theming"); var _utils = require("./utils"); var _ActionButton = require("./ActionButton"); var _ActionBar = require("./ActionBar"); var _useCode2 = require("./useCode"); var _config = require("../config"); var _events = require("./events"); var _icons = require("@storybook/icons"); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } var ComponentWrapper = _theming.styled.div(function (_ref) { var theme = _ref.theme; return "\n position: relative;\n overflow: hidden;\n border: 1px solid ".concat((0, _config.configValue)('borderColor', theme.appBorderColor), ";\n margin: 25px 0 40px;\n border-radius: ").concat((0, _config.configValue)('borderRadius', '3px'), ";\n font-family: ").concat((0, _config.configValue)('fontBase', 'inherit'), ";\n font-size: ").concat((0, _config.configValue)('fontSizeBase', '') ? (0, _config.configValue)('fontSizeBase', '') + 'px' : 'inherit', ";\n "); }); var Wrapper = _theming.styled.div(function () { return "\n position: relative;\n"; }); var PreviewWrapper = _theming.styled.div(function (_ref2) { var _theme$background; var theme = _ref2.theme; return "\n background-color: ".concat((0, _config.configValue)('bgColor', (_theme$background = theme.background) === null || _theme$background === void 0 ? void 0 : _theme$background.app), ";\n margin: 0 auto;\n position: relative;\n"); }); var Preview = (0, _theming.styled)(_reactLive.LivePreview)(function (_ref3) { var _theme$background2; var theme = _ref3.theme; return "\n padding: 20px;\n background-color: ".concat((0, _config.configValue)('previewBgColor', (_theme$background2 = theme.background) === null || _theme$background2 === void 0 ? void 0 : _theme$background2.app), ";\n box-sizing: border-box;\n overflow: auto;\n"); }); var LiveEditorWrapper = _theming.styled.div(function (_ref4) { var _theme$typography; var theme = _ref4.theme, live = _ref4.live, expanded = _ref4.expanded; return "\n font-size: ".concat((0, _config.configValue)('fontSizeCode', 14), "px;\n\n border-top: ").concat(live && expanded ? "1px solid ".concat((0, _config.configValue)('borderColor', theme.appBorderColor)) : 0, ";\n\n & > div {\n font-family: ").concat((0, _config.configValue)('fontCode', (_theme$typography = theme.typography) === null || _theme$typography === void 0 ? void 0 : _theme$typography.fonts.mono), " !important;\n outline: 0;\n }\n\n & textarea,\n & pre {\n padding: ").concat(live ? '12px' : '24px 40px 24px 24px', " !important;\n outline-color: transparent;\n }\n"); }); var StyledLiveErrors = (0, _theming.styled)(_reactLive.LiveError)(function (_ref5) { var _theme$typography2; var theme = _ref5.theme; return "\n font-family: ".concat((0, _config.configValue)('fontCode', (_theme$typography2 = theme.typography) === null || _theme$typography2 === void 0 ? void 0 : _theme$typography2.fonts.mono), ";\n padding: 10px;\n margin: 0;\n background-color: ").concat((0, _config.configValue)('errorsBg', '#feebea'), ";\n color: ").concat((0, _config.configValue)('errorsColor', '#ef3124'), " !important;\n border-top: 1px solid ").concat((0, _config.configValue)('borderColor', theme.appBorderColor), ";\n"); }); var FixedButtonContainer = _theming.styled.div(function () { return "\n position: absolute;\n right: 8px;\n top: 8px;\n z-index: 1;\n"; }); var Example = exports.Example = function Example(_ref6) { var codeProp = _ref6.code, _ref6$expanded = _ref6.expanded, expandedProp = _ref6$expanded === void 0 ? false : _ref6$expanded, live = _ref6.live, className = _ref6.className, _ref6$language = _ref6.language, language = _ref6$language === void 0 ? (0, _utils.extractLanguageFromClassName)(className) : _ref6$language, scope = _ref6.scope, isDarkTheme = _ref6.isDarkTheme, storyId = _ref6.storyId; var config = (0, _config.getConfig)(); var frameRef = (0, _react.useRef)(); var _useCode = (0, _useCode2.useCode)({ initialCode: codeProp, live: live, language: language, storageKey: storyId, storage: sessionStorage }), code = _useCode.code, setCode = _useCode.setCode, resetCode = _useCode.resetCode, resetKey = _useCode.resetKey, setResetKey = _useCode.setResetKey, ready = _useCode.ready, hasCodeInStorage = _useCode.hasCodeInStorage; var _useState = (0, _react.useState)(expandedProp || !live || hasCodeInStorage), _useState2 = (0, _slicedToArray2["default"])(_useState, 2), expanded = _useState2[0], setExpanded = _useState2[1]; var _useState3 = (0, _react.useState)(false), _useState4 = (0, _slicedToArray2["default"])(_useState3, 2), storyLoaded = _useState4[0], setStoryLoaded = _useState4[1]; var exampleId = (0, _react.useMemo)(function () { return (0, _utils.uniqId)(); }, []); var handleCopy = function handleCopy(value) { (0, _utils.copyToClipboard)(value); }; var handleChange = function handleChange(value) { setCode(value.trim()); }; (0, _react.useEffect)(function () { var handler = function handler(ev) { if (ev.data.exampleId === exampleId.toString()) { setStoryLoaded(true); } }; window.addEventListener('message', handler); return function () { return window.removeEventListener('message', handler); }; }, []); (0, _react.useEffect)(function () { if (frameRef.current) { frameRef.current.contentWindow.postMessage({ code: code, resetKey: resetKey }); } }, [code, storyLoaded, resetKey]); if (!ready) return null; var showEditor = ready && expanded; var showErrors = ready && live; var renderActions = function renderActions() { if (!live) return null; if (live) { return /*#__PURE__*/_react["default"].createElement(_ActionBar.ActionBar, { "data-role": "action-bar" }, /*#__PURE__*/_react["default"].createElement(_ActionBar.ActionBar.Item, null, /*#__PURE__*/_react["default"].createElement(_ActionButton.ActionButton, { icon: (0, _config.configValue)('expandIcon', function () { return /*#__PURE__*/_react["default"].createElement(_icons.ExpandAltIcon, null); }), onClick: function onClick() { setExpanded(!expanded); (0, _events.dispatchCustomEvent)(_events.CUSTOM_EVENTS.SHOW_SOURCE_CODE, { shown: !expanded }); }, title: (0, _config.configValue)('expandText', 'Раскрыть код'), active: expanded }), /*#__PURE__*/_react["default"].createElement(_ActionButton.ActionButton, { icon: (0, _config.configValue)('copyIcon', function () { return /*#__PURE__*/_react["default"].createElement(_icons.CopyIcon, null); }), onClick: function onClick() { handleCopy(code); (0, _events.dispatchCustomEvent)(_events.CUSTOM_EVENTS.COPY); }, title: (0, _config.configValue)('copyText', 'Скопировать код') })), /*#__PURE__*/_react["default"].createElement(_ActionBar.ActionBar.Item, { right: true }, hasCodeInStorage && /*#__PURE__*/_react["default"].createElement(_ActionButton.ActionButton, { icon: (0, _config.configValue)('resetIcon', function () { return /*#__PURE__*/_react["default"].createElement(_icons.UndoIcon, null); }), onClick: resetCode }, (0, _config.configValue)('resetText', 'Вернуть исходный пример')))); } return /*#__PURE__*/_react["default"].createElement(FixedButtonContainer, null, /*#__PURE__*/_react["default"].createElement(_ActionButton.ActionButton, { icon: (0, _config.configValue)('copyIcon', function () { return /*#__PURE__*/_react["default"].createElement(_icons.CopyIcon, null); }), onClick: function onClick() { handleCopy(code); (0, _events.dispatchCustomEvent)(_events.CUSTOM_EVENTS.COPY); }, title: (0, _config.configValue)('copyText', 'copy code'), doneTitle: (0, _config.configValue)('copiedText', 'Code copied') })); }; return /*#__PURE__*/_react["default"].createElement(ComponentWrapper, { "data-role": "wrapper", className: "sb-unstyled" }, /*#__PURE__*/_react["default"].createElement(_reactLive.LiveProvider, { code: code || 'render(null)', noInline: (0, _utils.detectNoInline)(code), theme: config.editorTheme || (isDarkTheme ? _prismReactRenderer.themes.dracula : _prismReactRenderer.themes.github), scope: _objectSpread(_objectSpread({}, config.scope), scope) }, /*#__PURE__*/_react["default"].createElement(Wrapper, { "data-role": "code-wrapper" }, live && /*#__PURE__*/_react["default"].createElement(PreviewWrapper, { "data-role": "preview-wrapper" }, /*#__PURE__*/_react["default"].createElement(Preview, { "data-role": "preview" })), renderActions()), showEditor && /*#__PURE__*/_react["default"].createElement(LiveEditorWrapper, { live: live, expanded: true }, /*#__PURE__*/_react["default"].createElement(_reactLive.LiveEditor, { className: "live-examples-addon-editor", onChange: handleChange, language: language, disabled: !live, key: resetKey, "data-role": "editor" })), showErrors && /*#__PURE__*/_react["default"].createElement(StyledLiveErrors, { "data-role": "errors" }))); };