1import React from 'react'; 2 3import { InlineCode } from '~/components/base/code'; 4import { LI, UL } from '~/components/base/list'; 5import { P } from '~/components/base/paragraph'; 6import { H2, H4 } from '~/components/plugins/Headings'; 7import { 8 CommentTagData, 9 DefaultPropsDefinitionData, 10 PropData, 11 PropsDefinitionData, 12 TypeDeclarationData, 13 TypePropertyData, 14} from '~/components/plugins/api/APIDataTypes'; 15import { CommentTextBlock, resolveTypeName } from '~/components/plugins/api/APISectionUtils'; 16 17export type APISectionPropsProps = { 18 data: PropsDefinitionData[]; 19 defaultProps: DefaultPropsDefinitionData; 20}; 21 22const UNKNOWN_VALUE = '...'; 23 24const extractDefaultPropValue = ( 25 { comment, name }: PropData, 26 defaultProps: DefaultPropsDefinitionData 27): string | undefined => { 28 const annotationDefault = comment?.tags?.filter((tag: CommentTagData) => tag.tag === 'default'); 29 if (annotationDefault?.length) { 30 return annotationDefault[0].text; 31 } 32 return defaultProps?.type?.declaration?.children?.filter( 33 (defaultProp: TypePropertyData) => defaultProp.name === name 34 )[0]?.defaultValue; 35}; 36 37const renderInheritedProp = (ip: TypeDeclarationData) => { 38 const component = ip?.typeArguments ? ip.typeArguments[0]?.queryType?.name : null; 39 return component ? ( 40 <LI key={`inherited-prop-${component}`}> 41 <InlineCode>{component}</InlineCode> 42 </LI> 43 ) : null; 44}; 45 46const renderInheritedProps = (data: TypeDeclarationData[]): JSX.Element | undefined => { 47 const inheritedProps = data.filter((ip: TypeDeclarationData) => ip.type === 'reference'); 48 if (inheritedProps.length) { 49 return ( 50 <div> 51 <H4>Inherited Props</H4> 52 <UL>{inheritedProps.map(renderInheritedProp)}</UL> 53 </div> 54 ); 55 } 56 return undefined; 57}; 58 59const renderProps = ( 60 { name, type }: PropsDefinitionData, 61 defaultValues: DefaultPropsDefinitionData 62): JSX.Element => { 63 const propsDeclarations = type.types.filter((e: TypeDeclarationData) => e.declaration); 64 return ( 65 <div key={`props-definition-${name}`}> 66 <UL> 67 {propsDeclarations?.map((def: TypeDeclarationData) => 68 def.declaration?.children.map((prop: PropData) => 69 renderProp(prop, extractDefaultPropValue(prop, defaultValues)) 70 ) 71 )} 72 </UL> 73 {renderInheritedProps(type.types)} 74 </div> 75 ); 76}; 77 78const renderProp = ({ comment, name, type }: PropData, defaultValue?: string) => ( 79 <LI key={`prop-entry-${name}`}> 80 <H4>{name}</H4> 81 <P> 82 Type: <InlineCode>{resolveTypeName(type)}</InlineCode> 83 {defaultValue && defaultValue !== UNKNOWN_VALUE ? ( 84 <span> 85   86 {'Default: '} 87 <InlineCode>{defaultValue}</InlineCode> 88 </span> 89 ) : null} 90 </P> 91 <CommentTextBlock comment={comment} /> 92 </LI> 93); 94 95const APISectionProps: React.FC<APISectionPropsProps> = ({ data, defaultProps }) => 96 data?.length ? ( 97 <> 98 <H2 key="props-header">Props</H2> 99 {data.map((propsDefinition: PropsDefinitionData) => 100 renderProps(propsDefinition, defaultProps) 101 )} 102 </> 103 ) : null; 104 105export default APISectionProps; 106