@workday/canvas-kit-docs
Version:
Documentation components of Canvas Kit components
86 lines (85 loc) • 6.33 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import React from 'react';
import { Expandable } from '@workday/canvas-kit-react/expandable';
import { defaultJSDoc } from '../../docgen/docParser';
import { MDX } from '../MDXElements';
import { SymbolDoc } from '../SymbolDoc';
import { PropertiesTable, registerWidget, Value } from '../Value';
import { Heading, HeadingLevelContext, SymbolDialog } from '../widgetUtils';
const ParentComponentNameContext = React.createContext('');
/**
* Used to keep track of JSDoc in subcomponent definitions.
*
* For example:
* ```tsx
* subComponents: {
* // JSDoc goes here instead of on `TabsItem` for better dev experience
* Item: TabsItem
* }
* ```
*/
const ParentComponentJSDocContext = React.createContext(defaultJSDoc);
const fileNameToCategoryMap = {
Layout: [
'utils/layout',
'utils/gridArea',
'utils/gridItem',
'utils/flexItem',
'utils/position',
'utils/space',
],
Color: ['utils/color', 'utils/background'],
Border: ['utils/border'],
Depth: ['utils/depth'],
Text: ['utils/text'],
Other: ['utils/other'],
};
registerWidget('enhancedComponent', ({ value, doc, meta }) => {
var _a, _b, _c;
const groups = groupProps(value.props);
const parentComponentName = React.useContext(ParentComponentNameContext);
const headingLevel = React.useContext(HeadingLevelContext);
// We don't want to re-document a subcomponent that is a container component with a different
// model. If we detect another container, only render the intro and a link to the container
// component
if (parentComponentName && value.componentType === 'container') {
return (_jsx(_Fragment, { children: _jsxs(MDX, { as: "p", children: ["This component references the", ' ', _jsx(ParentComponentNameContext.Provider, { value: "", children: _jsx(ParentComponentJSDocContext.Provider, { value: defaultJSDoc, children: _jsx(SymbolDialog, { value: { kind: 'symbol', name: value.displayName || '' } }) }) }), ' ', "component."] }) }));
}
return (_jsxs(_Fragment, { children: [value.styleComponent ? (_jsxs(_Fragment, { children: [_jsx(Heading, { headingOffset: 1, id: parentComponentName
? `${parentComponentName.toLowerCase()}-layout-component-api`
: `${(_a = value.displayName) === null || _a === void 0 ? void 0 : _a.toLowerCase()}-layout-component-api`, children: "Layout Component" }), _jsxs(MDX, { as: "p", children: [_jsx("code", { children: value.displayName || parentComponentName }), " supports all props from the", _jsx("code", { children: _jsx(ParentComponentJSDocContext.Provider, { value: defaultJSDoc, children: _jsx(SymbolDialog, { value: value.styleComponent }) }) }), "layout component."] })] })) : null, _jsx(Heading, { headingOffset: 1, id: parentComponentName
? `${parentComponentName.toLowerCase()}-props-api`
: `${(_b = value.displayName) === null || _b === void 0 ? void 0 : _b.toLowerCase()}-props-api`, children: "Props" }), value.baseElement && (_jsx(ParentComponentJSDocContext.Provider, { value: defaultJSDoc, children: _jsxs(MDX, { as: "p", children: ["Props extend from ", _jsx(Value, { value: value.baseElement }), ". Changing the ", _jsx("code", { children: "as" }), " prop will change the element interface."] }) })), value.componentType === 'container' && value.model ? (_jsxs(MDX, { as: "p", children: ["Props extend from ", _jsx(SymbolDialog, { value: { kind: 'symbol', name: `${value.model}Config` } }), ". If a ", _jsx("code", { children: "model" }), " is passed, props from ", _jsxs("code", { children: [value.model, "Config"] }), " are ignored."] })) : null, Object.keys(groups).map(key => {
return (_jsx(React.Fragment, { children: key === 'Local' ? (_jsx(PropertiesTable, { properties: groups[key] })) : (_jsxs(Expandable, { children: [_jsxs(Expandable.Target, { headingLevel: "h5", children: [_jsx(Expandable.Title, { children: key }), _jsx(Expandable.Icon, { iconPosition: "end" })] }), _jsx(Expandable.Content, { children: _jsx(PropertiesTable, { properties: groups[key] }) })] })) }, key));
}), value.elemPropsHook ? (_jsx(SymbolDoc, { name: value.elemPropsHook, headingStart: headingLevel + 1 })) : null, value.subComponents
? value.subComponents.map((c, i) => {
var _a;
return (_jsxs(React.Fragment, { children: [_jsxs(Heading, { id: `${(_a = value.displayName) === null || _a === void 0 ? void 0 : _a.toLowerCase()}.${c.name.toLowerCase()}-api`, children: [parentComponentName ? parentComponentName : value.displayName, ".", c.name] }), _jsx(ParentComponentNameContext.Provider, { value: `${parentComponentName ? parentComponentName : value.displayName}.${c.name}`, children: _jsx(ParentComponentJSDocContext.Provider, { value: c, children: _jsx(SymbolDoc, { name: c.symbol, fileName: c.declarations[c.declarations.length - 1].filePath, hideHeading: true, descriptionOverride: c.description }) }) })] }, i));
})
: null, value.componentType === 'container' && value.model ? (_jsxs(_Fragment, { children: [_jsx(Heading, { id: `${(_c = value.displayName) === null || _c === void 0 ? void 0 : _c.toLowerCase()}-model-api`, headingOffset: -1, children: "Model" }), _jsx(SymbolDoc, { name: `use${value.model}` })] })) : null] }));
});
function groupProps(props) {
const categories = { Local: [] };
for (const key in fileNameToCategoryMap) {
categories[key] = [];
}
for (const prop of props) {
let found = false;
for (const key in fileNameToCategoryMap) {
if (fileNameToCategoryMap[key].find(match => { var _a; return (_a = prop.declarations[0]) === null || _a === void 0 ? void 0 : _a.filePath.includes(match); })) {
found = true;
categories[key].push(prop);
}
}
if (!found) {
categories.Local.push(prop);
}
}
// clear out categories that don't have anything in them
return Object.keys(categories).reduce((result, key) => {
if (categories[key].length) {
result[key] = categories[key];
}
return result;
}, {});
}