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