1import React from 'react'; 2 3import { InlineCode } from '~/components/base/code'; 4import { B, P } from '~/components/base/paragraph'; 5import { H2, H3Code } from '~/components/plugins/Headings'; 6import { 7 CommentData, 8 GeneratedData, 9 MethodSignatureData, 10 PropData, 11 PropsDefinitionData, 12} from '~/components/plugins/api/APIDataTypes'; 13import APISectionProps from '~/components/plugins/api/APISectionProps'; 14import { CommentTextBlock, resolveTypeName } from '~/components/plugins/api/APISectionUtils'; 15 16export type APISectionComponentsProps = { 17 data: GeneratedData[]; 18 componentsProps: PropsDefinitionData[]; 19}; 20 21const getComponentName = (name?: string, children: PropData[] = []) => { 22 if (name && name !== 'default') return name; 23 const ctor = children.filter((child: PropData) => child.name === 'constructor')[0]; 24 return ctor?.signatures?.[0]?.type?.name ?? 'default'; 25}; 26 27const getComponentComment = (comment: CommentData, signatures: MethodSignatureData[]) => 28 comment || (signatures?.[0]?.comment ?? undefined); 29 30const renderComponent = ( 31 { name, comment, type, extendedTypes, children, signatures }: GeneratedData, 32 componentsProps?: PropsDefinitionData[] 33): JSX.Element => { 34 const resolvedType = extendedTypes?.length ? extendedTypes[0] : type; 35 const resolvedName = getComponentName(name, children); 36 return ( 37 <div key={`component-definition-${resolvedName}`}> 38 <H3Code> 39 <InlineCode>{resolvedName}</InlineCode> 40 </H3Code> 41 {resolvedType && ( 42 <P> 43 <B>Type:</B> <InlineCode>{resolveTypeName(resolvedType)}</InlineCode> 44 </P> 45 )} 46 <CommentTextBlock comment={getComponentComment(comment, signatures)} /> 47 {componentsProps && componentsProps.length ? ( 48 <APISectionProps data={componentsProps} header={`${resolvedName}Props`} /> 49 ) : null} 50 </div> 51 ); 52}; 53 54const APISectionComponents = ({ data, componentsProps }: APISectionComponentsProps) => 55 data?.length ? ( 56 <> 57 <H2 key="components-header">Components</H2> 58 {data.map(component => 59 renderComponent( 60 component, 61 componentsProps.filter(cp => cp.name.includes(component.name)) 62 ) 63 )} 64 </> 65 ) : null; 66 67export default APISectionComponents; 68