@workday/canvas-kit-docs
Version:
Documentation components of Canvas Kit components
65 lines (64 loc) • 3.02 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
//@ts-ignore
import { useMDXComponents } from '@mdx-js/react';
import React from 'react';
import MarkdownToJSX from 'markdown-to-jsx';
import { Box, createComponent } from '@workday/canvas-kit-react';
import { HeadingLevelContext, SymbolDialog } from './widgetUtils';
/**
* Special component that taps into @mdx-js/react components that are used by both Storybook and the
* Canvas Site. This means our docs can use the same components used in our MDX files without
* needing to use MDX directly.
*/
export const MDX = createComponent('div')({
Component({ children, ...elemProps }, _ref, Element) {
const components = useMDXComponents();
return React.createElement(components[Element] || Element, elemProps, children);
},
});
/**
* Custom component that allows us to convert any `button` in JSDoc that contains a `[data-symbol]`
* to a `<SymbolDialog>` component.
*/
const Button = (props) => {
const components = useMDXComponents();
if (props['data-symbol'] !== undefined && props.children) {
return (_jsx("code", { children: _jsx(SymbolDialog, { value: {
kind: 'symbol',
name: props.children[0],
displayName: props['data-symbol'],
value: props.children[0],
} }) }));
}
return React.createElement(components['button'] || 'button', props, props.children);
};
/**
* Convert [JSDoc link](https://jsdoc.app/tags-inline-link.html) into a `button` element for later
* processing. This allows us to convert {@link SymbolName Link Text} to a `<SymbolDialog>`!
*/
function convertLinkToSymbolLinks(input) {
return input.replace(/{@link ([a-z0-9.]+)( [a-z0-9.]+)?}/gi, (_substr, symbol, text = '') => `<button data-symbol="${text.trim()}" className="token symbol">${symbol}</button>`);
}
/**
* Replace all heading levels in the JSDoc to start at the same heading level as `startingLevel`.
* This allows JSDoc markdown to seamlessly flow into MDX.
*/
function rewriteHeadingLevels(input, startingLevel) {
const firstHeadingMatch = input.match(/(#+ )[A-Za-z]/);
if (!firstHeadingMatch) {
return input;
}
const firstHeadingLevel = firstHeadingMatch[1];
return input.replace(new RegExp(firstHeadingLevel, 'g'), Array.from({ length: startingLevel }, () => '#').join('') + ' ');
}
/**
* Custom MDX to JSX parsing
*/
export const MdxJSToJSX = (props) => {
const components = useMDXComponents();
const headingLevel = React.useContext(HeadingLevelContext);
return (
// This fixes the `pre` element inside of the `<Table.Cell/>` element.
// This prevents the code block from going outside the width of the `<Table.Cell/>` element.
_jsx(Box, { cs: { minWidth: '0' }, children: _jsx(MarkdownToJSX, { options: { overrides: { ...components, button: Button }, forceBlock: true }, children: rewriteHeadingLevels(convertLinkToSymbolLinks(props.children), headingLevel) }) }));
};