UNPKG

@storybook/addon-info

Version:

A Storybook addon to show additional information for your stories.

562 lines (461 loc) 19.1 kB
"use strict"; require("core-js/modules/es.symbol"); require("core-js/modules/es.symbol.description"); require("core-js/modules/es.symbol.iterator"); require("core-js/modules/es.array.concat"); require("core-js/modules/es.array.for-each"); require("core-js/modules/es.array.from"); require("core-js/modules/es.array.includes"); require("core-js/modules/es.array.is-array"); require("core-js/modules/es.array.iterator"); require("core-js/modules/es.array.join"); require("core-js/modules/es.array.map"); require("core-js/modules/es.array.slice"); require("core-js/modules/es.array.some"); require("core-js/modules/es.array.sort"); require("core-js/modules/es.function.name"); require("core-js/modules/es.map"); require("core-js/modules/es.object.assign"); require("core-js/modules/es.object.create"); require("core-js/modules/es.object.define-property"); require("core-js/modules/es.object.get-prototype-of"); require("core-js/modules/es.object.keys"); require("core-js/modules/es.object.set-prototype-of"); require("core-js/modules/es.object.to-string"); require("core-js/modules/es.regexp.exec"); require("core-js/modules/es.string.includes"); require("core-js/modules/es.string.iterator"); require("core-js/modules/es.string.match"); require("core-js/modules/es.string.split"); require("core-js/modules/es.string.trim"); require("core-js/modules/web.dom-collections.for-each"); require("core-js/modules/web.dom-collections.iterator"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _react = _interopRequireWildcard(require("react")); var _reactIs = require("react-is"); var _reactLifecyclesCompat = require("react-lifecycles-compat"); var _propTypes = _interopRequireDefault(require("prop-types")); var _global = _interopRequireDefault(require("global")); var _marksy = _interopRequireDefault(require("marksy")); var _reactElementToJsxString = _interopRequireDefault(require("react-element-to-jsx-string")); var _markdown = require("./markdown"); var _reactUtils = require("../react-utils"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } _global["default"].STORYBOOK_REACT_CLASSES = _global["default"].STORYBOOK_REACT_CLASSES || []; var STORYBOOK_REACT_CLASSES = _global["default"].STORYBOOK_REACT_CLASSES; var stylesheetBase = { button: { base: { fontFamily: 'sans-serif', fontSize: 12, display: 'block', position: 'fixed', border: 'none', background: '#027ac5', color: '#fff', padding: '5px 15px', cursor: 'pointer' }, topRight: { top: 0, right: 0, borderRadius: '0 0 0 5px' } }, info: { position: 'fixed', background: 'white', top: 0, left: 0, height: '100vh', width: '100vw', overflow: 'auto', zIndex: 99999 }, children: { position: 'relative', zIndex: 0 }, infoBody: { fontFamily: 'Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif', color: 'black', fontWeight: 300, lineHeight: 1.45, fontSize: '15px', padding: '20px 40px 40px', borderRadius: '2px', backgroundColor: '#fff' }, infoContent: { marginBottom: 0 }, infoStory: {}, jsxInfoContent: { borderTop: '1px solid #eee', margin: '20px 0 0 0' }, header: { h1: { margin: 0, padding: 0, fontSize: '35px' }, h2: { margin: '0 0 10px 0', padding: 0, fontWeight: 400, fontSize: '22px' }, h3: { margin: '0 0 10px 0', padding: 0, fontWeight: 400, fontSize: '18px' }, body: { borderBottom: '1px solid #eee', paddingTop: 10, marginBottom: 10 } }, source: { h1: { margin: '20px 0 0 0', padding: '0 0 5px 0', fontSize: '25px', borderBottom: '1px solid #EEE' } }, propTableHead: { margin: '20px 0 0 0' } }; var Story = /*#__PURE__*/ function (_Component) { _inherits(Story, _Component); function Story(props) { var _getPrototypeOf2; var _this; _classCallCheck(this, Story); for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(Story)).call.apply(_getPrototypeOf2, [this, props].concat(args))); _this.state = { open: false }; _this.marksy = (0, _marksy["default"])({ createElement: _react.createElement, elements: props.components }); return _this; } _createClass(Story, [{ key: "_renderStory", value: function _renderStory() { var stylesheet = this.state.stylesheet; var children = this.props.children; return _react["default"].createElement("div", { id: "story-root", style: stylesheet.infoStory }, children); } }, { key: "_renderInline", value: function _renderInline() { var stylesheet = this.state.stylesheet; return _react["default"].createElement(_react.Fragment, null, this._renderInlineHeader(), this._renderStory(), _react["default"].createElement("div", { style: stylesheet.infoPage }, _react["default"].createElement("div", { style: stylesheet.infoBody }, this._getInfoContent(), this._getComponentDescription(), this._getSourceCode(), this._getPropTables()))); } }, { key: "_renderInlineHeader", value: function _renderInlineHeader() { var stylesheet = this.state.stylesheet; var infoHeader = this._getInfoHeader(); return infoHeader && _react["default"].createElement("div", { style: stylesheet.infoPage }, _react["default"].createElement("div", { style: stylesheet.infoBody }, infoHeader)); } }, { key: "_renderOverlay", value: function _renderOverlay() { var _this2 = this; var _this$state = this.state, stylesheet = _this$state.stylesheet, open = _this$state.open; var children = this.props.children; var buttonStyle = Object.assign({}, stylesheet.button.base, {}, stylesheet.button.topRight); var infoStyle = Object.assign({}, stylesheet.info); if (!open) { infoStyle.display = 'none'; } var openOverlay = function openOverlay() { _this2.setState({ open: true }); return false; }; var closeOverlay = function closeOverlay() { _this2.setState({ open: false }); return false; }; return _react["default"].createElement(_react.Fragment, null, _react["default"].createElement("div", { style: stylesheet.children }, children), _react["default"].createElement("button", { type: "button", style: buttonStyle, onClick: openOverlay, className: "info__show-button" }, "Show Info"), open ? _react["default"].createElement("div", { style: infoStyle, className: "info__overlay" }, _react["default"].createElement("button", { type: "button", style: buttonStyle, onClick: closeOverlay, className: "info__close-button" }, "\xD7"), _react["default"].createElement("div", { style: stylesheet.infoPage }, _react["default"].createElement("div", { style: stylesheet.infoBody }, this._getInfoHeader(), this._getInfoContent(), this._getComponentDescription(), this._getSourceCode(), this._getPropTables()))) : null); } }, { key: "_getInfoHeader", value: function _getInfoHeader() { var stylesheet = this.state.stylesheet; var _this$props = this.props, context = _this$props.context, showHeader = _this$props.showHeader; if (!context || !showHeader) { return null; } return _react["default"].createElement("div", { style: stylesheet.header.body }, _react["default"].createElement("h1", { style: stylesheet.header.h1 }, context.kind), _react["default"].createElement("h2", { style: stylesheet.header.h2 }, context.name)); } }, { key: "_getInfoContent", value: function _getInfoContent() { var _this$props2 = this.props, info = _this$props2.info, showInline = _this$props2.showInline; var stylesheet = this.state.stylesheet; if (!info) { return ''; } if (_react["default"].isValidElement(info)) { return _react["default"].createElement("div", { style: showInline ? stylesheet.jsxInfoContent : stylesheet.infoContent }, info); } var lines = info.split('\n'); while (lines[0].trim() === '') { lines.shift(); } var padding = 0; var matches = lines[0].match(/^ */); if (matches) { padding = matches[0].length; } var source = lines.map(function (s) { return s.slice(padding); }).join('\n'); return _react["default"].createElement(_react.Fragment, null, this.marksy(source).tree); } }, { key: "_getComponentDescription", value: function _getComponentDescription() { var _this3 = this; var _this$props$context = this.props.context, kind = _this$props$context.kind, name = _this$props$context.name; var retDiv = null; var validMatches = [kind, name]; if (Object.keys(STORYBOOK_REACT_CLASSES).length) { Object.keys(STORYBOOK_REACT_CLASSES).forEach(function (key) { if (validMatches.includes(STORYBOOK_REACT_CLASSES[key].name)) { var componentDescription = STORYBOOK_REACT_CLASSES[key].docgenInfo.description; retDiv = _react["default"].createElement(_react.Fragment, null, _this3.marksy(componentDescription).tree); } }); } return retDiv; } }, { key: "_getSourceCode", value: function _getSourceCode() { var _this$props3 = this.props, showSource = _this$props3.showSource, children = _this$props3.children; var stylesheet = this.state.stylesheet; if (!showSource) { return null; } return _react["default"].createElement(_react.Fragment, null, _react["default"].createElement("h1", { style: stylesheet.source.h1 }, "Story Source"), _react["default"].createElement(_markdown.Code, { code: (0, _reactElementToJsxString["default"])(children), language: "jsx", format: false })); } }, { key: "_getPropTables", value: function _getPropTables() { var _this4 = this; var _this$props4 = this.props, children = _this$props4.children, propTablesExclude = _this$props4.propTablesExclude, propTableCompare = _this$props4.propTableCompare, maxPropObjectKeys = _this$props4.maxPropObjectKeys, maxPropArrayLength = _this$props4.maxPropArrayLength, maxPropStringLength = _this$props4.maxPropStringLength, excludedPropTypes = _this$props4.excludedPropTypes; var propTables = this.props.propTables; var stylesheet = this.state.stylesheet; var types = new Map(); if (!propTables) { return null; } if (!children) { return null; } propTables.forEach(function (type) { types.set(type, true); }); // depth-first traverse and collect types var extract = function extract(innerChildren) { if (!innerChildren) { return; } if (Array.isArray(innerChildren)) { innerChildren.forEach(extract); return; } if (innerChildren.props && innerChildren.props.children) { extract(innerChildren.props.children); } if ((0, _reactIs.isForwardRef)(innerChildren)) { try { // this might fail because of hooks being used extract(innerChildren.type.render(innerChildren.props)); } catch (e) {// do nothing } } if (typeof innerChildren === 'string' || typeof innerChildren.type === 'string' || propTables.length > 0 && // if propTables is set and has items in it !propTables.includes(innerChildren.type) || // ignore types that are missing from propTables Array.isArray(propTablesExclude) && // also ignore excluded types propTablesExclude.some(function (Comp) { return propTableCompare(innerChildren, Comp); })) { return; } if (innerChildren.type && !types.has(innerChildren.type)) { types.set(innerChildren.type, true); } }; // extract components from children extract(children); var array = Array.from(types.keys()); array.sort(function (a, b) { return (0, _reactUtils.getDisplayName)(a) > (0, _reactUtils.getDisplayName)(b) ? 1 : -1; }); propTables = array.map(function (type, i) { return (// eslint-disable-next-line react/no-array-index-key _react["default"].createElement("div", { key: "".concat((0, _reactUtils.getDisplayName)(type), "_").concat(i) }, _react["default"].createElement("h3", { style: stylesheet.propTableHead }, "\"", (0, _reactUtils.getDisplayName)(type), "\" Component"), _react["default"].createElement(_this4.props.PropTable, { type: (0, _reactUtils.getType)(type), maxPropObjectKeys: maxPropObjectKeys, maxPropArrayLength: maxPropArrayLength, maxPropStringLength: maxPropStringLength, excludedPropTypes: excludedPropTypes })) ); }); if (!propTables || propTables.length === 0) { return null; } return _react["default"].createElement(_react.Fragment, null, _react["default"].createElement("h1", { style: stylesheet.source.h1 }, "Prop Types"), propTables); } }, { key: "render", value: function render() { var showInline = this.props.showInline; return showInline ? this._renderInline() : this._renderOverlay(); } }]); return Story; }(_react.Component); Story.getDerivedStateFromProps = function (_ref) { var styles = _ref.styles; return { stylesheet: styles(stylesheetBase) }; }; Story.displayName = 'Story'; Story.propTypes = { context: _propTypes["default"].shape({ kind: _propTypes["default"].string, name: _propTypes["default"].string }), info: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].node]), propTables: _propTypes["default"].arrayOf(_propTypes["default"].func), propTablesExclude: _propTypes["default"].arrayOf(_propTypes["default"].func), propTableCompare: _propTypes["default"].func.isRequired, showInline: _propTypes["default"].bool, showHeader: _propTypes["default"].bool, showSource: _propTypes["default"].bool, // eslint-disable-next-line react/no-unused-prop-types styles: _propTypes["default"].func.isRequired, children: _propTypes["default"].oneOfType([_propTypes["default"].object, _propTypes["default"].array]), components: _propTypes["default"].shape({}), maxPropObjectKeys: _propTypes["default"].number.isRequired, maxPropArrayLength: _propTypes["default"].number.isRequired, maxPropStringLength: _propTypes["default"].number.isRequired, excludedPropTypes: _propTypes["default"].arrayOf(_propTypes["default"].string) }; Story.defaultProps = { context: null, info: '', children: null, propTables: null, propTablesExclude: [], showInline: false, showHeader: true, showSource: true, components: {}, excludedPropTypes: [] }; (0, _reactLifecyclesCompat.polyfill)(Story); var _default = Story; exports["default"] = _default;