UNPKG

terra-props-table

Version:

React component to render a table view for the props metadata of another react component.

195 lines (163 loc) 7.96 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = _interopRequireDefault(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _reactDocgen = require("react-docgen"); var _terraMarkdown = _interopRequireDefault(require("terra-markdown")); var _bind = _interopRequireDefault(require("classnames/bind")); var _PropsTableModule = _interopRequireDefault(require("./PropsTable.module.scss")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } var cx = _bind.default.bind(_PropsTableModule.default); var propTypes = { /** * Title of component */ componentName: _propTypes.default.string, /** * Markdown source file */ src: _propTypes.default.string.isRequired, /** * Type of react-docgen resolver to use for prop-types resolution. Supported values are `default` or `findAllComponentDefinitions` */ propsResolution: _propTypes.default.oneOf(['default', 'findAllComponentDefinitions']) }; var defaultProps = { propsResolution: 'default' }; function formatShape(shape) { return JSON.stringify(shape, null, 1); } function determineType(type) { var typeName = type.name; if (typeName === 'enum') { typeName = 'enum'; } else if (typeName === 'arrayOf') { if (type.value.name === 'shape') { typeName = /*#__PURE__*/_react.default.createElement("span", null, ' ', "array of objects structured like:", /*#__PURE__*/_react.default.createElement("pre", { className: cx('props-table-pre') }, ' ', formatShape(type.value.value), ' ')); } else { typeName = "array of ".concat(type.value.name, "s"); } } else if (typeName === 'union') { var options = type.value.map(function (option) { var name = option.name === 'shape' ? /*#__PURE__*/_react.default.createElement("span", { key: option.value }, ' ', "an object structured like:", /*#__PURE__*/_react.default.createElement("pre", { className: cx('props-table-pre') }, ' ', formatShape(option.value), ' ')) : /*#__PURE__*/_react.default.createElement("span", { key: option.name }, ' ', option.name); return name; }); typeName = options.reduce(function (curr, next) { return [curr, /*#__PURE__*/_react.default.createElement("span", { key: "".concat(curr.value, "-").concat(next.value) }, " or "), next]; }); } else if (typeName === 'shape') { typeName = /*#__PURE__*/_react.default.createElement("span", null, ' ', "an object structured like:", /*#__PURE__*/_react.default.createElement("pre", { className: cx('props-table-pre') }, ' ', formatShape(type.value), ' ')); } return typeName; } /** * Renders a table view for the props metadata of a react component generated by react-docgen */ var PropsTable = function PropsTable(_ref) { var componentName = _ref.componentName, propsResolution = _ref.propsResolution, src = _ref.src, customProps = _objectWithoutProperties(_ref, ["componentName", "propsResolution", "src"]); /** * Runs component source code through react-docgen. Passing second argument to parse * function to account for multiple export. * @type {Object} */ var componentMetaData; /** * Alias for props object from componentMetaData * @type {Object} */ var componentProps; // Resolve using react-docgen's default resolver if (propsResolution === 'default') { componentMetaData = (0, _reactDocgen.parse)(src); componentProps = componentMetaData.props; } // Resolve using react-docgen's findAllComponentDefinitions resolver if (propsResolution === 'findAllComponentDefinitions') { componentMetaData = (0, _reactDocgen.parse)(src, _reactDocgen.resolver.findAllComponentDefinitions); componentProps = componentMetaData[0].props; } var tableRowClass = cx('prop-table-row'); var tableClassNames = cx(['props-table', customProps.className]); return /*#__PURE__*/_react.default.createElement("div", { dir: "ltr", className: cx('props-table-markdown') }, /*#__PURE__*/_react.default.createElement("h2", null, componentName, ' ', "Props"), /*#__PURE__*/_react.default.createElement("table", _extends({}, customProps, { className: tableClassNames }), /*#__PURE__*/_react.default.createElement("thead", null, /*#__PURE__*/_react.default.createElement("tr", null, /*#__PURE__*/_react.default.createElement("th", { className: cx('prop-table-name') }, "Prop Name"), /*#__PURE__*/_react.default.createElement("th", { className: cx('prop-table-type') }, "Type"), /*#__PURE__*/_react.default.createElement("th", { className: cx('prop-table-required') }, "Is Required"), /*#__PURE__*/_react.default.createElement("th", { className: cx('prop-table-default') }, "Default Value"), /*#__PURE__*/_react.default.createElement("th", { className: cx('prop-table-description') }, "Description"))), /*#__PURE__*/_react.default.createElement("tbody", null, Object.keys(componentProps).map(function (key) { var prop = componentProps[key]; if (prop.description && prop.description.match(/@private/)) { return null; } var type = determineType(prop.type); /** * Check if the react-docgen parser returned a custom proptype. * If so, parse the raw value to see if the custom proptype has been marked as required. */ var customRequired = prop.type.name === 'custom' && prop.type.raw.includes('isRequired'); /* eslint-disable react/forbid-dom-props */ return /*#__PURE__*/_react.default.createElement("tr", { className: tableRowClass, key: key, style: { fontSize: '90%' } }, /*#__PURE__*/_react.default.createElement("td", { style: { fontWeight: 'bold' } }, key), /*#__PURE__*/_react.default.createElement("td", null, prop.type ? type : ''), customRequired || prop.required ? /*#__PURE__*/_react.default.createElement("td", { style: { color: '#d53700' } }, "required") : /*#__PURE__*/_react.default.createElement("td", { style: { color: '#444' } }, "optional"), prop.defaultValue ? /*#__PURE__*/_react.default.createElement("td", { style: { fontWeight: 'bold' } }, prop.defaultValue.value) : /*#__PURE__*/_react.default.createElement("td", { style: { color: '#444' } }, "none"), /*#__PURE__*/_react.default.createElement("td", null, /*#__PURE__*/_react.default.createElement(_terraMarkdown.default, { src: prop.description }))); /* eslint-enable react/forbid-dom-props */ })))); }; PropsTable.propTypes = propTypes; PropsTable.defaultProps = defaultProps; var _default = PropsTable; exports.default = _default;