1f4b1168bSBartosz Kaszubowskiimport { mergeClasses } from '@expo/styleguide'; 2f4b1168bSBartosz Kaszubowski 3299f02f2SBartosz Kaszubowskiimport { 4299f02f2SBartosz Kaszubowski DefaultPropsDefinitionData, 5299f02f2SBartosz Kaszubowski PropData, 6299f02f2SBartosz Kaszubowski PropsDefinitionData, 76062847eSBartosz Kaszubowski TypeDefinitionData, 8299f02f2SBartosz Kaszubowski} from '~/components/plugins/api/APIDataTypes'; 925b16883SBartosz Kaszubowskiimport { APISectionDeprecationNote } from '~/components/plugins/api/APISectionDeprecationNote'; 10b3bd70ceSTomasz Sapetaimport { APISectionPlatformTags } from '~/components/plugins/api/APISectionPlatformTags'; 1107337117SBartosz Kaszubowskiimport { 1207337117SBartosz Kaszubowski CommentTextBlock, 13c0b543d7SBartosz Kaszubowski getCommentContent, 14b15ebaf2SBartosz Kaszubowski getCommentOrSignatureComment, 15c8c9d6e8SBartosz Kaszubowski getTagData, 16c4c6b9d1SBartosz Kaszubowski getTagNamesList, 17c0b543d7SBartosz Kaszubowski H3Code, 18c0b543d7SBartosz Kaszubowski H4Code, 19b15ebaf2SBartosz Kaszubowski renderTypeOrSignatureType, 2007337117SBartosz Kaszubowski resolveTypeName, 216a5c065cSBartosz Kaszubowski STYLES_APIBOX, 226a5c065cSBartosz Kaszubowski STYLES_APIBOX_NESTED, 23f4b1168bSBartosz Kaszubowski ELEMENT_SPACING, 246a5c065cSBartosz Kaszubowski STYLES_NESTED_SECTION_HEADER, 256a5c065cSBartosz Kaszubowski STYLES_NOT_EXPOSED_HEADER, 2607337117SBartosz Kaszubowski STYLES_SECONDARY, 27c0b543d7SBartosz Kaszubowski TypeDocKind, 2807337117SBartosz Kaszubowski} from '~/components/plugins/api/APISectionUtils'; 293324c13cSBartosz Kaszubowskiimport { CODE, H2, H3, H4, LI, MONOSPACE, P, UL } from '~/ui/components/Text'; 30299f02f2SBartosz Kaszubowski 31299f02f2SBartosz Kaszubowskiexport type APISectionPropsProps = { 32299f02f2SBartosz Kaszubowski data: PropsDefinitionData[]; 331ef472c3SBartosz Kaszubowski defaultProps?: DefaultPropsDefinitionData; 341ef472c3SBartosz Kaszubowski header?: string; 35299f02f2SBartosz Kaszubowski}; 36299f02f2SBartosz Kaszubowski 37299f02f2SBartosz Kaszubowskiconst UNKNOWN_VALUE = '...'; 38299f02f2SBartosz Kaszubowski 39299f02f2SBartosz Kaszubowskiconst extractDefaultPropValue = ( 40299f02f2SBartosz Kaszubowski { comment, name }: PropData, 411ef472c3SBartosz Kaszubowski defaultProps?: DefaultPropsDefinitionData 42299f02f2SBartosz Kaszubowski): string | undefined => { 43c8c9d6e8SBartosz Kaszubowski const annotationDefault = getTagData('default', comment); 44c8c9d6e8SBartosz Kaszubowski if (annotationDefault) { 455990cc31SBartosz Kaszubowski return getCommentContent(annotationDefault.content); 46299f02f2SBartosz Kaszubowski } 47299f02f2SBartosz Kaszubowski return defaultProps?.type?.declaration?.children?.filter( 48ffc1cfa8SBartosz Kaszubowski (defaultProp: PropData) => defaultProp.name === name 49299f02f2SBartosz Kaszubowski )[0]?.defaultValue; 50299f02f2SBartosz Kaszubowski}; 51299f02f2SBartosz Kaszubowski 526062847eSBartosz Kaszubowskiconst renderInheritedProp = (ip: TypeDefinitionData) => { 531ef472c3SBartosz Kaszubowski return ( 546062847eSBartosz Kaszubowski <LI key={`inherited-prop-${ip.name}-${ip.type}`}> 5512abeb84SBartosz Kaszubowski <CODE>{resolveTypeName(ip)}</CODE> 56299f02f2SBartosz Kaszubowski </LI> 571ef472c3SBartosz Kaszubowski ); 58299f02f2SBartosz Kaszubowski}; 59299f02f2SBartosz Kaszubowski 60f52aa21eSBartosz Kaszubowskiconst renderInheritedProps = ( 61c0b543d7SBartosz Kaszubowski data: PropsDefinitionData | undefined, 62f52aa21eSBartosz Kaszubowski exposeInSidebar?: boolean 63f52aa21eSBartosz Kaszubowski): JSX.Element | undefined => { 64c0b543d7SBartosz Kaszubowski const inheritedData = data?.type?.types ?? data?.extendedTypes ?? []; 65c0b543d7SBartosz Kaszubowski const inheritedProps = 66c0b543d7SBartosz Kaszubowski inheritedData.filter((ip: TypeDefinitionData) => ip.type === 'reference') ?? []; 67299f02f2SBartosz Kaszubowski if (inheritedProps.length) { 68299f02f2SBartosz Kaszubowski return ( 69f52aa21eSBartosz Kaszubowski <> 70f52aa21eSBartosz Kaszubowski {exposeInSidebar ? <H3>Inherited Props</H3> : <H4>Inherited Props</H4>} 71299f02f2SBartosz Kaszubowski <UL>{inheritedProps.map(renderInheritedProp)}</UL> 72f52aa21eSBartosz Kaszubowski </> 73299f02f2SBartosz Kaszubowski ); 74299f02f2SBartosz Kaszubowski } 75299f02f2SBartosz Kaszubowski return undefined; 76299f02f2SBartosz Kaszubowski}; 77299f02f2SBartosz Kaszubowski 78c0b543d7SBartosz Kaszubowskiconst getPropsBaseTypes = (def: PropsDefinitionData) => { 79c0b543d7SBartosz Kaszubowski if (def.kind === TypeDocKind.TypeAlias) { 80c0b543d7SBartosz Kaszubowski const baseTypes = def?.type?.types 81c0b543d7SBartosz Kaszubowski ? def.type.types?.filter((t: TypeDefinitionData) => t.declaration) 82c0b543d7SBartosz Kaszubowski : [def.type]; 83c0b543d7SBartosz Kaszubowski return baseTypes.map(def => def?.declaration?.children); 84c0b543d7SBartosz Kaszubowski } else if (def.kind === TypeDocKind.Interface) { 85c0b543d7SBartosz Kaszubowski return def.children?.filter(child => !child.inheritedFrom) ?? []; 86c0b543d7SBartosz Kaszubowski } 87c0b543d7SBartosz Kaszubowski return []; 88c0b543d7SBartosz Kaszubowski}; 89c0b543d7SBartosz Kaszubowski 90299f02f2SBartosz Kaszubowskiconst renderProps = ( 91c0b543d7SBartosz Kaszubowski def: PropsDefinitionData, 92f52aa21eSBartosz Kaszubowski defaultValues?: DefaultPropsDefinitionData, 93f52aa21eSBartosz Kaszubowski exposeInSidebar?: boolean 94299f02f2SBartosz Kaszubowski): JSX.Element => { 95c0b543d7SBartosz Kaszubowski const propsDeclarations = getPropsBaseTypes(def) 96ffc1cfa8SBartosz Kaszubowski .flat() 97ffc1cfa8SBartosz Kaszubowski .filter((dec, i, arr) => arr.findIndex(t => t?.name === dec?.name) === i); 98ffc1cfa8SBartosz Kaszubowski 99299f02f2SBartosz Kaszubowski return ( 100c0b543d7SBartosz Kaszubowski <div key={`props-definition-${def.name}`}> 101ffc1cfa8SBartosz Kaszubowski {propsDeclarations?.map(prop => 102f52aa21eSBartosz Kaszubowski prop 103f52aa21eSBartosz Kaszubowski ? renderProp(prop, extractDefaultPropValue(prop, defaultValues), exposeInSidebar) 104f52aa21eSBartosz Kaszubowski : null 105299f02f2SBartosz Kaszubowski )} 106c0b543d7SBartosz Kaszubowski {renderInheritedProps(def, exposeInSidebar)} 107299f02f2SBartosz Kaszubowski </div> 108299f02f2SBartosz Kaszubowski ); 109299f02f2SBartosz Kaszubowski}; 110299f02f2SBartosz Kaszubowski 111d8d79196SBartosz Kaszubowskiexport const renderProp = ( 112b15ebaf2SBartosz Kaszubowski { comment, name, type, flags, signatures }: PropData, 113f52aa21eSBartosz Kaszubowski defaultValue?: string, 114f52aa21eSBartosz Kaszubowski exposeInSidebar?: boolean 1156a5c065cSBartosz Kaszubowski) => { 1166a5c065cSBartosz Kaszubowski const HeaderComponent = exposeInSidebar ? H3Code : H4Code; 1175990cc31SBartosz Kaszubowski const extractedSignatures = signatures || type?.declaration?.signatures; 1185990cc31SBartosz Kaszubowski const extractedComment = getCommentOrSignatureComment(comment, extractedSignatures); 119*9d5e5238SSimek 1206a5c065cSBartosz Kaszubowski return ( 12112abeb84SBartosz Kaszubowski <div key={`prop-entry-${name}`} css={[STYLES_APIBOX, STYLES_APIBOX_NESTED]}> 12225b16883SBartosz Kaszubowski <APISectionDeprecationNote comment={extractedComment} /> 123d9bd5b6cSBartosz Kaszubowski <APISectionPlatformTags comment={comment} prefix="Only for:" /> 124c4c6b9d1SBartosz Kaszubowski <HeaderComponent tags={getTagNamesList(comment)}> 1253324c13cSBartosz Kaszubowski <MONOSPACE weight="medium" css={!exposeInSidebar && STYLES_NOT_EXPOSED_HEADER}> 1263324c13cSBartosz Kaszubowski {name} 1273324c13cSBartosz Kaszubowski </MONOSPACE> 1286a5c065cSBartosz Kaszubowski </HeaderComponent> 129f4b1168bSBartosz Kaszubowski <P className={mergeClasses(extractedComment && ELEMENT_SPACING)}> 13007337117SBartosz Kaszubowski {flags?.isOptional && <span css={STYLES_SECONDARY}>Optional • </span>} 1315990cc31SBartosz Kaszubowski <span css={STYLES_SECONDARY}>Type:</span>{' '} 1325990cc31SBartosz Kaszubowski {renderTypeOrSignatureType(type, extractedSignatures)} 133299f02f2SBartosz Kaszubowski {defaultValue && defaultValue !== UNKNOWN_VALUE ? ( 134299f02f2SBartosz Kaszubowski <span> 13507337117SBartosz Kaszubowski <span css={STYLES_SECONDARY}> • Default:</span>{' '} 13612abeb84SBartosz Kaszubowski <CODE>{defaultValue}</CODE> 137299f02f2SBartosz Kaszubowski </span> 138299f02f2SBartosz Kaszubowski ) : null} 13984745a05SBartosz Kaszubowski </P> 14025b16883SBartosz Kaszubowski <CommentTextBlock comment={extractedComment} includePlatforms={false} /> 141f4b1168bSBartosz Kaszubowski {!extractedComment && <br />} 1426a5c065cSBartosz Kaszubowski </div> 143299f02f2SBartosz Kaszubowski ); 1446a5c065cSBartosz Kaszubowski}; 145299f02f2SBartosz Kaszubowski 1469f72d43bSBartosz Kaszubowskiconst APISectionProps = ({ data, defaultProps, header = 'Props' }: APISectionPropsProps) => { 1479f72d43bSBartosz Kaszubowski const baseProp = data.find(prop => prop.name === header); 148f4b1168bSBartosz Kaszubowski return data?.length > 0 ? ( 149299f02f2SBartosz Kaszubowski <> 15013032b48SBartosz Kaszubowski {data?.length === 1 || header === 'Props' ? ( 1511ef472c3SBartosz Kaszubowski <H2 key="props-header">{header}</H2> 1521ef472c3SBartosz Kaszubowski ) : ( 1536a5c065cSBartosz Kaszubowski <div> 15425b16883SBartosz Kaszubowski {baseProp && <APISectionDeprecationNote comment={baseProp.comment} />} 1556a5c065cSBartosz Kaszubowski <div css={STYLES_NESTED_SECTION_HEADER}> 1566a5c065cSBartosz Kaszubowski <H4 key={`${header}-props-header`}>{header}</H4> 1576a5c065cSBartosz Kaszubowski </div> 1586a5c065cSBartosz Kaszubowski {baseProp && baseProp.comment ? <CommentTextBlock comment={baseProp.comment} /> : null} 1596a5c065cSBartosz Kaszubowski </div> 1601ef472c3SBartosz Kaszubowski )} 161299f02f2SBartosz Kaszubowski {data.map((propsDefinition: PropsDefinitionData) => 16213032b48SBartosz Kaszubowski renderProps(propsDefinition, defaultProps, data?.length === 1 || header === 'Props') 163299f02f2SBartosz Kaszubowski )} 164299f02f2SBartosz Kaszubowski </> 165299f02f2SBartosz Kaszubowski ) : null; 1669f72d43bSBartosz Kaszubowski}; 167299f02f2SBartosz Kaszubowski 168299f02f2SBartosz Kaszubowskiexport default APISectionProps; 169