1import React, { useContext } from 'react'; 2 3import DocumentationPageContext from '~/components/DocumentationPageContext'; 4import { P } from '~/components/base/paragraph'; 5import { GeneratedData } from '~/components/plugins/api/APIDataTypes'; 6import APISectionComponents from '~/components/plugins/api/APISectionComponents'; 7import APISectionConstants from '~/components/plugins/api/APISectionConstants'; 8import APISectionEnums from '~/components/plugins/api/APISectionEnums'; 9import APISectionInterfaces from '~/components/plugins/api/APISectionInterfaces'; 10import APISectionMethods from '~/components/plugins/api/APISectionMethods'; 11import APISectionProps from '~/components/plugins/api/APISectionProps'; 12import APISectionTypes from '~/components/plugins/api/APISectionTypes'; 13import { TypeDocKind } from '~/components/plugins/api/APISectionUtils'; 14 15const LATEST_VERSION = `v${require('~/package.json').version}`; 16 17type Props = { 18 packageName: string; 19 apiName?: string; 20}; 21 22const filterDataByKind = ( 23 entries: GeneratedData[], 24 kind: TypeDocKind, 25 additionalCondition: (entry: GeneratedData) => boolean = () => true 26) => 27 entries 28 ? entries.filter((entry: GeneratedData) => entry.kind === kind && additionalCondition(entry)) 29 : []; 30 31const isHook = ({ name }: GeneratedData) => 32 name.startsWith('use') && 33 // note(simek): hardcode this exception until the method will be renamed 34 name !== 'useSystemBrightnessAsync'; 35 36const isListener = ({ name }: GeneratedData) => name.endsWith('Listener'); 37 38const renderAPI = ( 39 packageName: string, 40 version: string = 'unversioned', 41 apiName?: string 42): JSX.Element => { 43 try { 44 const data = require(`~/public/static/data/${version}/${packageName}.json`).children; 45 46 const methods = filterDataByKind( 47 data, 48 TypeDocKind.Function, 49 entry => !isListener(entry) && !isHook(entry) 50 ); 51 const hooks = filterDataByKind(data, TypeDocKind.Function, isHook); 52 const eventSubscriptions = filterDataByKind(data, TypeDocKind.Function, isListener); 53 54 const types = filterDataByKind( 55 data, 56 TypeDocKind.TypeAlias, 57 entry => 58 !entry.name.includes('Props') && 59 !!( 60 entry.type.declaration || 61 entry.type.types || 62 entry.type.type || 63 entry.type.typeArguments 64 ) 65 ); 66 67 const props = filterDataByKind( 68 data, 69 TypeDocKind.TypeAlias, 70 entry => 71 entry.name.includes('Props') && 72 (!!entry.type.types || // inheritance 73 !!entry.type.declaration?.children) // no inheritance 74 ); 75 const defaultProps = filterDataByKind( 76 data 77 .filter((entry: GeneratedData) => entry.kind === TypeDocKind.Class) 78 .map((entry: GeneratedData) => entry.children) 79 .flat(), 80 TypeDocKind.Property, 81 entry => entry.name === 'defaultProps' 82 )[0]; 83 84 const enums = filterDataByKind(data, TypeDocKind.Enum); 85 const interfaces = filterDataByKind(data, TypeDocKind.Interface); 86 const constants = filterDataByKind( 87 data, 88 TypeDocKind.Variable, 89 entry => (entry?.flags?.isConst || false) && entry?.type?.name !== 'React.FC' 90 ); 91 92 const components = filterDataByKind( 93 data, 94 TypeDocKind.Variable, 95 entry => entry?.type?.name === 'React.FC' 96 ); 97 const componentsPropNames = components.map(component => `${component.name}Props`); 98 const componentsProps = filterDataByKind(props, TypeDocKind.TypeAlias, entry => 99 componentsPropNames.includes(entry.name) 100 ); 101 102 return ( 103 <> 104 <APISectionComponents data={components} componentsProps={componentsProps} /> 105 <APISectionConstants data={constants} apiName={apiName} /> 106 <APISectionMethods data={hooks} header="Hooks" /> 107 <APISectionMethods data={methods} apiName={apiName} /> 108 <APISectionMethods 109 data={eventSubscriptions} 110 apiName={apiName} 111 header="Event Subscriptions" 112 /> 113 {props && !componentsProps.length ? ( 114 <APISectionProps data={props} defaultProps={defaultProps} /> 115 ) : null} 116 <APISectionTypes data={types} /> 117 <APISectionInterfaces data={interfaces} /> 118 <APISectionEnums data={enums} /> 119 </> 120 ); 121 } catch (error) { 122 return <P>No API data file found, sorry!</P>; 123 } 124}; 125 126const APISection: React.FC<Props> = ({ packageName, apiName }) => { 127 const { version } = useContext(DocumentationPageContext); 128 const resolvedVersion = 129 version === 'unversioned' ? version : version === 'latest' ? LATEST_VERSION : version; 130 return renderAPI(packageName, resolvedVersion, apiName); 131}; 132 133export default APISection; 134