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
JavaScript
"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;