storybook/addons/docs/src/blocks/Description.tsx
2022-03-12 11:52:20 +08:00

84 lines
2.5 KiB
TypeScript

import React, { FunctionComponent, useContext } from 'react';
import { Description, DescriptionProps as PureDescriptionProps } from '@storybook/components';
import { str } from '@storybook/docs-tools';
import { DocsContext, DocsContextProps } from './DocsContext';
import { Component, CURRENT_SELECTION } from './types';
export enum DescriptionType {
INFO = 'info',
NOTES = 'notes',
DOCGEN = 'docgen',
LEGACY_5_2 = 'legacy-5.2',
AUTO = 'auto',
}
type Notes = string | any;
type Info = string | any;
interface DescriptionProps {
of?: '.' | Component;
type?: DescriptionType;
markdown?: string;
children?: string;
}
const getNotes = (notes?: Notes) =>
notes && (typeof notes === 'string' ? notes : str(notes.markdown) || str(notes.text));
const getInfo = (info?: Info) => info && (typeof info === 'string' ? info : str(info.text));
const noDescription = (component?: Component): string | null => null;
export const getDescriptionProps = (
{ of, type, markdown, children }: DescriptionProps,
{ id, storyById }: DocsContextProps<any>
): PureDescriptionProps => {
const { component, parameters } = storyById(id);
if (children || markdown) {
return { markdown: children || markdown };
}
const { notes, info, docs } = parameters;
const { extractComponentDescription = noDescription, description } = docs || {};
const target = of === CURRENT_SELECTION ? component : of;
// override component description
const componentDescriptionParameter = description?.component;
if (componentDescriptionParameter) {
return { markdown: componentDescriptionParameter };
}
switch (type) {
case DescriptionType.INFO:
return { markdown: getInfo(info) };
case DescriptionType.NOTES:
return { markdown: getNotes(notes) };
// FIXME: remove in 6.0
case DescriptionType.LEGACY_5_2:
return {
markdown: `
${getNotes(notes) || getInfo(info) || ''}
${extractComponentDescription(target) || ''}
`.trim(),
};
case DescriptionType.DOCGEN:
case DescriptionType.AUTO:
default:
return { markdown: extractComponentDescription(target, { component, ...parameters }) };
}
};
const DescriptionContainer: FunctionComponent<DescriptionProps> = (props) => {
const context = useContext(DocsContext);
const { markdown } = getDescriptionProps(props, context);
return markdown ? <Description markdown={markdown} /> : null;
};
// since we are in the docs blocks, assume default description if for primary component story
DescriptionContainer.defaultProps = {
of: '.',
};
export { DescriptionContainer as Description };