UNPKG

@skbkontur/storybook-addon-live-examples

Version:

Storybook live examples plugin

194 lines 9.62 kB
import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } import React, { useState, useEffect, useRef, useMemo, useCallback } from 'react'; import { LiveProvider, LiveEditor, LivePreview, LiveError } from 'react-live'; import { themes } from 'prism-react-renderer'; import { styled } from '@storybook/theming'; import { extractLanguageFromClassName, detectNoInline, copyToClipboard, uniqId } from './utils'; import { ActionButton } from './ActionButton'; import { ActionBar } from './ActionBar'; import { useCode } from './useCode'; import { configValue, getConfig } from '../config'; import { CUSTOM_EVENTS, dispatchCustomEvent } from './events'; import { ExpandAltIcon, CopyIcon, RefreshIcon } from '@storybook/icons'; var ComponentWrapper = styled.div(function (_ref) { var theme = _ref.theme; return "\n position: relative;\n overflow: hidden;\n border: 1px solid ".concat(configValue('borderColor', theme.appBorderColor), ";\n margin: 25px 0 40px;\n border-radius: ").concat(configValue('borderRadius', '3px'), ";\n font-family: ").concat(configValue('fontBase', 'inherit'), ";\n font-size: ").concat(configValue('fontSizeBase', '') ? configValue('fontSizeBase', '') + 'px' : 'inherit', ";\n "); }); var Wrapper = styled.div(function () { return "\n position: relative;\n"; }); var PreviewWrapper = styled.div(function (_ref2) { var _theme$background; var theme = _ref2.theme; return "\n background-color: ".concat(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 = styled(LivePreview)(function (_ref3) { var _theme$background2; var theme = _ref3.theme; return "\n padding: 20px;\n background-color: ".concat(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 = styled.div(function (_ref4) { var _theme$typography; var theme = _ref4.theme, live = _ref4.live, expanded = _ref4.expanded; return "\n font-size: ".concat(configValue('fontSizeCode', 14), "px;\n\n border-top: ").concat(live && expanded ? "1px solid ".concat(configValue('borderColor', theme.appBorderColor)) : 0, ";\n\n & > div {\n font-family: ").concat(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 = styled(LiveError)(function (_ref5) { var _theme$typography2; var theme = _ref5.theme; return "\n font-family: ".concat(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(configValue('errorsBg', '#feebea'), ";\n color: ").concat(configValue('errorsColor', '#ef3124'), " !important;\n border-top: 1px solid ").concat(configValue('borderColor', theme.appBorderColor), ";\n"); }); var FixedButtonContainer = styled.div(function () { return "\n position: absolute;\n right: 8px;\n top: 8px;\n z-index: 1;\n"; }); export var 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 ? extractLanguageFromClassName(className) : _ref6$language, scope = _ref6.scope, isDarkTheme = _ref6.isDarkTheme; var config = getConfig(); var _useState = useState(expandedProp || !live), _useState2 = _slicedToArray(_useState, 2), expanded = _useState2[0], setExpanded = _useState2[1]; var frameRef = useRef(); var _useCode = useCode({ initialCode: codeProp, live: live, language: language }), code = _useCode.code, setCode = _useCode.setCode, resetCode = _useCode.resetCode, resetKey = _useCode.resetKey, setResetKey = _useCode.setResetKey, ready = _useCode.ready; var _useState3 = useState(false), _useState4 = _slicedToArray(_useState3, 2), storyLoaded = _useState4[0], setStoryLoaded = _useState4[1]; var exampleId = useMemo(function () { return uniqId(); }, []); console.log({ exampleId: exampleId, storyLoaded: storyLoaded, code: code }); var handleCopy = useCallback(function (value) { copyToClipboard(value); }, []); var handleChange = useCallback(function (value) { console.log({ value: value }); setCode(value.trim()); }, []); 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); }; }, []); 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.createElement(ActionBar, { "data-role": "action-bar" }, /*#__PURE__*/React.createElement(ActionBar.Item, { right: true }, /*#__PURE__*/React.createElement(ActionButton, { icon: configValue('expandIcon', function () { return /*#__PURE__*/React.createElement(ExpandAltIcon, null); }), onClick: function onClick() { setExpanded(!expanded); dispatchCustomEvent(CUSTOM_EVENTS.SHOW_SOURCE_CODE, { shown: !expanded }); }, title: configValue('expandText', 'Expand code'), active: expanded }), /*#__PURE__*/React.createElement(ActionButton, { icon: configValue('copyIcon', function () { return /*#__PURE__*/React.createElement(CopyIcon, null); }), onClick: function onClick() { handleCopy(code); dispatchCustomEvent(CUSTOM_EVENTS.COPY); }, title: configValue('copyText', 'Copy code'), doneTitle: configValue('copiedText', 'Code copied') }), /*#__PURE__*/React.createElement(ActionButton, { icon: configValue('resetIcon', function () { return /*#__PURE__*/React.createElement(RefreshIcon, null); }), onClick: resetCode, title: configValue('resetText', 'Reset code') }))); } return /*#__PURE__*/React.createElement(FixedButtonContainer, null, /*#__PURE__*/React.createElement(ActionButton, { icon: configValue('copyIcon', function () { return /*#__PURE__*/React.createElement(CopyIcon, null); }), onClick: function onClick() { handleCopy(code); dispatchCustomEvent(CUSTOM_EVENTS.COPY); }, title: configValue('copyText', 'copy code'), doneTitle: configValue('copiedText', 'Code copied') })); }; return /*#__PURE__*/React.createElement(ComponentWrapper, { "data-role": "wrapper", className: "sb-unstyled" }, /*#__PURE__*/React.createElement(LiveProvider, { code: code || 'render(null)', noInline: detectNoInline(code), theme: config.editorTheme || (isDarkTheme ? themes.dracula : themes.github), scope: _objectSpread(_objectSpread({}, config.scope), scope) }, /*#__PURE__*/React.createElement(Wrapper, { "data-role": "code-wrapper" }, live && /*#__PURE__*/React.createElement(PreviewWrapper, { "data-role": "preview-wrapper" }, /*#__PURE__*/React.createElement(Preview, { "data-role": "preview" })), renderActions()), showEditor && /*#__PURE__*/React.createElement(LiveEditorWrapper, { live: live, expanded: true }, /*#__PURE__*/React.createElement(LiveEditor, { className: "live-examples-addon-editor", onChange: handleChange, language: language, disabled: !live, key: resetKey, "data-role": "editor" })), showErrors && /*#__PURE__*/React.createElement(StyledLiveErrors, { "data-role": "errors" }))); };