dumi
Version:
📖 Documentation Generator of React Component
294 lines (291 loc) • 16.9 kB
JavaScript
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
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; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
import { useAtomAssets, useIntl, useRouteMeta, useSiteData } from 'dumi';
import React, { useEffect, useMemo, useState } from 'react';
import Badge from "../Badge";
import Table from "../Table";
import "./index.less";
function Token(_ref) {
var children = _ref.children;
return /*#__PURE__*/React.createElement("span", {
"data-token": children
}, children);
}
// https://github.com/umijs/dumi/issues/1957
function fixArg(arg) {
if (arg.hasQuestionToken && typeof arg.type === 'string') {
arg.type = arg.type.replace(/\s+\|\s+undefined\s*$/i, '');
}
return arg;
}
// Usually handles types other than basic types, either interfaces or type aliases
var CompositeType = function CompositeType(prop) {
var _prop$source;
var intl = useIntl();
var _useSiteData = useSiteData(),
themeConfig = _useSiteData.themeConfig;
return (_prop$source = prop.source) !== null && _prop$source !== void 0 && _prop$source[0] && themeConfig.sourceLink ? /*#__PURE__*/React.createElement("a", {
className: "dumi-default-api-link",
href: intl.formatMessage({
id: '$internal.api.sourceLink'
}, _objectSpread({}, prop.source[0])),
target: "_blank",
rel: "noreferrer"
}, prop.className) : prop.className;
};
var HANDLERS = {
// entry method
toNode: function toNode(prop) {
if (typeof prop.type === 'string' && prop.type in this) {
// value from TypeMap
if ('enum' in prop) return this.enum(prop);
return this[prop.type](prop);
} else if (prop.type) {
// non-parsed type, such as ReactNode
return this.getValidClassName(prop) || /*#__PURE__*/React.createElement("span", null, prop.type);
} else if ('const' in prop) {
// const value
return /*#__PURE__*/React.createElement("span", null, prop.const);
} else if ('oneOf' in prop) {
// oneOf value
return this.oneOf(prop);
}
// unknown type
return /*#__PURE__*/React.createElement("span", null, "unknown");
},
// type handlers
string: function string(prop) {
return /*#__PURE__*/React.createElement("span", null, prop.type);
},
number: function number(prop) {
return /*#__PURE__*/React.createElement("span", null, prop.type);
},
boolean: function boolean(prop) {
return /*#__PURE__*/React.createElement("span", null, prop.type);
},
any: function any(prop) {
return /*#__PURE__*/React.createElement("span", null, prop.type);
},
object: function object(prop) {
var _this = this;
var entries = Object.entries(prop.properties || {});
var props = entries.map(function (_ref2, index) {
var _prop$required;
var _ref3 = _slicedToArray(_ref2, 2),
key = _ref3[0],
value = _ref3[1];
// skip nested object type
return /*#__PURE__*/React.createElement("span", {
key: key
}, /*#__PURE__*/React.createElement("span", null, key), !((_prop$required = prop.required) !== null && _prop$required !== void 0 && _prop$required.includes(key)) && /*#__PURE__*/React.createElement(Token, null, "?"), /*#__PURE__*/React.createElement(Token, null, ":"), value.type === 'object' ? /*#__PURE__*/React.createElement("span", null, "object") : _this.toNode(value), index < entries.length - 1 && /*#__PURE__*/React.createElement(Token, null, ";"));
});
return /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(Token, null, '{'), props, /*#__PURE__*/React.createElement(Token, null, '}'));
},
array: function array(prop) {
var _this2 = this;
var arrayType = /*#__PURE__*/React.createElement("span", null, "any");
if (prop.items) {
if (Array.isArray(prop.items)) return /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(Token, null, '['), prop.items.map(function (item, i) {
return /*#__PURE__*/React.createElement("span", {
key: "".concat(i)
}, i > 0 && ', ', _this2.toNode(item));
}), /*#__PURE__*/React.createElement(Token, null, ']'));
var className = this.getValidClassName(prop.items);
arrayType = className !== null && className !== void 0 ? className : this.toNode(prop.items);
}
return /*#__PURE__*/React.createElement("span", null, arrayType, /*#__PURE__*/React.createElement(Token, null, '['), /*#__PURE__*/React.createElement(Token, null, ']'));
},
// FIXME: extract real type
element: function element(prop) {
return /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(Token, null, "<"), /*#__PURE__*/React.createElement("span", null, prop.componentName), /*#__PURE__*/React.createElement(Token, null, ">"));
},
// FIXME: extract real type
function: function _function(_ref4) {
var _this3 = this;
var signature = _ref4.signature;
// handle Function type without signature
if (!signature) return /*#__PURE__*/React.createElement("span", null, "Function");
var signatures = 'oneOf' in signature ? signature.oneOf : [signature];
return signatures.map(function (signature, si) {
return /*#__PURE__*/React.createElement("span", {
key: "".concat(si)
}, signature.isAsync ? /*#__PURE__*/React.createElement(Token, null, "async") : '', /*#__PURE__*/React.createElement(Token, null, '('), signature.arguments.map(function (arg, ai) {
return /*#__PURE__*/React.createElement("span", {
key: "".concat(si).concat(ai)
}, /*#__PURE__*/React.createElement("span", null, arg.key), arg.hasQuestionToken && /*#__PURE__*/React.createElement(Token, null, "?"), /*#__PURE__*/React.createElement(Token, null, ":"), _this3.toNode(!!arg.schema ? arg.schema : fixArg(arg)), ai < signature.arguments.length - 1 && /*#__PURE__*/React.createElement(Token, null, ","));
}), /*#__PURE__*/React.createElement(Token, null, ')'), /*#__PURE__*/React.createElement(Token, null, "=>"), _this3.toNode(signature.returnType), si < signatures.length - 1 && /*#__PURE__*/React.createElement(Token, null, "|"));
});
},
// FIXME: extract real type
dom: function dom(prop) {
return /*#__PURE__*/React.createElement("span", null, prop.className || 'DOM');
},
// special handlers
enum: function _enum(prop) {
var enumStringArray = prop.enum.map(function (v) {
return JSON.stringify(v);
});
return /*#__PURE__*/React.createElement("span", null, enumStringArray.map(function (e, i) {
return /*#__PURE__*/React.createElement("span", {
key: i
}, /*#__PURE__*/React.createElement("span", null, e), i < enumStringArray.length - 1 && /*#__PURE__*/React.createElement(Token, null, "|"));
}));
},
oneOf: function oneOf(prop) {
var _this4 = this;
return prop.oneOf.map(function (v, i) {
return /*#__PURE__*/React.createElement("span", {
key: i
}, _this4.getValidClassName(v) || _this4.toNode(v), i < prop.oneOf.length - 1 && /*#__PURE__*/React.createElement(Token, null, "|"));
});
},
reference: function reference(prop) {
var _this5 = this;
var typeParameters = prop.typeParameters || [];
var params = typeParameters.map(function (param, i) {
return /*#__PURE__*/React.createElement("span", {
key: i
}, _this5.toNode(param), i < typeParameters.length - 1 && /*#__PURE__*/React.createElement(Token, null, ","));
});
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("a", {
className: "dumi-default-api-link",
href: prop.externalUrl,
target: "_blank",
rel: "noreferrer"
}, prop.name), params.length ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Token, null, "<"), params, /*#__PURE__*/React.createElement(Token, null, ">")) : '');
},
// utils
getValidClassName: function getValidClassName(prop) {
if ('className' in prop && typeof prop.className === 'string' && prop.className !== '__type') {
return /*#__PURE__*/React.createElement(CompositeType, prop);
}
return null;
}
};
var APIType = function APIType(prop) {
var _useState = useState(function () {
return HANDLERS.toNode(prop);
}),
_useState2 = _slicedToArray(_useState, 2),
type = _useState2[0],
setType = _useState2[1];
useEffect(function () {
setType(HANDLERS.toNode(prop));
}, [prop]);
return /*#__PURE__*/React.createElement("code", {
className: "dumi-default-api-type"
}, type);
};
function getReleaseAndVersionInfo(props) {
var releaseInfo = {};
Object.entries(props).forEach(function (_ref5) {
var _schema$tags, _schema$tags2;
var _ref6 = _slicedToArray(_ref5, 2),
prop = _ref6[0],
schema = _ref6[1];
var modiferTags = (_schema$tags = schema.tags) === null || _schema$tags === void 0 ? void 0 : _schema$tags.modifierTags;
var blockTags = (_schema$tags2 = schema.tags) === null || _schema$tags2 === void 0 ? void 0 : _schema$tags2.blockTags;
modiferTags === null || modiferTags === void 0 ? void 0 : modiferTags.forEach(function (tag) {
if (tag === 'alpha' || tag === 'beta' || tag === 'experimental') {
releaseInfo[prop] = [tag];
}
});
blockTags === null || blockTags === void 0 ? void 0 : blockTags.forEach(function (_ref7) {
var tag = _ref7.tag,
content = _ref7.content;
if (tag === 'deprecated' || tag === 'since') {
var textContent = content.map(function (item) {
return item.text;
}).join('');
releaseInfo[prop] = [tag, textContent];
}
});
});
return releaseInfo;
}
var APIRelease = function APIRelease(_ref8) {
var name = _ref8.name,
info = _ref8.info;
var intl = useIntl();
var _info = _slicedToArray(info, 2),
modifer = _info[0],
text = _info[1];
var modiferProps = _defineProperty({
className: 'dumi-default-api-release-modifer'
}, 'data-release', modifer);
if (text && modifer === 'deprecated') {
modiferProps['data-dumi-tooltip'] = text;
}
var modiferText = modifer === 'since' ? "".concat(text, "+") : intl.formatMessage({
id: "api.component.release.".concat(modifer)
});
return /*#__PURE__*/React.createElement("span", {
className: "dumi-default-api-release"
}, /*#__PURE__*/React.createElement("span", {
className: "dumi-default-api-release-name",
"data-release": modifer
}, name), /*#__PURE__*/React.createElement("span", modiferProps, modifer === 'deprecated' ? modiferText : /*#__PURE__*/React.createElement(Badge, {
type: "info"
}, modiferText)));
};
var API = function API(props) {
var _useRouteMeta = useRouteMeta(),
frontmatter = _useRouteMeta.frontmatter;
var _useAtomAssets = useAtomAssets(),
components = _useAtomAssets.components;
var id = props.id || frontmatter.atomId;
var intl = useIntl();
if (!id) throw new Error('`id` properties if required for API component!');
var definition = components === null || components === void 0 ? void 0 : components[id];
var properties = {};
var type = (props.type || 'props').toLowerCase();
if (definition) {
var _definition$key;
var key = "".concat(type, "Config");
properties = ((_definition$key = definition[key]) === null || _definition$key === void 0 ? void 0 : _definition$key.properties) || {};
}
var releaseInfo = useMemo(function () {
return getReleaseAndVersionInfo(properties);
}, [properties]);
return /*#__PURE__*/React.createElement("div", {
className: "markdown"
}, /*#__PURE__*/React.createElement(Table, null, /*#__PURE__*/React.createElement("thead", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("th", null, intl.formatMessage({
id: 'api.component.name'
})), /*#__PURE__*/React.createElement("th", null, intl.formatMessage({
id: 'api.component.description'
})), /*#__PURE__*/React.createElement("th", null, intl.formatMessage({
id: 'api.component.type'
})), type === 'props' && /*#__PURE__*/React.createElement("th", null, intl.formatMessage({
id: 'api.component.default'
})))), /*#__PURE__*/React.createElement("tbody", null, Object.keys(properties).length ? Object.entries(properties).map(function (_ref9) {
var _definition$propsConf;
var _ref10 = _slicedToArray(_ref9, 2),
name = _ref10[0],
prop = _ref10[1];
return /*#__PURE__*/React.createElement("tr", {
key: name
}, /*#__PURE__*/React.createElement("td", null, releaseInfo[name] ? /*#__PURE__*/React.createElement(APIRelease, {
name: name,
info: releaseInfo[name]
}) : name), /*#__PURE__*/React.createElement("td", null, prop.description || '--'), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(APIType, prop)), type === 'props' && /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("code", null, (_definition$propsConf = definition.propsConfig.required) !== null && _definition$propsConf !== void 0 && _definition$propsConf.includes(name) ? intl.formatMessage({
id: 'api.component.required'
}) : JSON.stringify(prop.default) || '--')));
}) : /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", {
colSpan: 4
}, intl.formatMessage({
id: "api.component.".concat(components ? 'not.found' : 'unavailable')
}, {
id: id
}))))));
};
export default API;