xref: /expo/docs/components/plugins/APISection.tsx (revision d574aecb)
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 APISectionConstants from '~/components/plugins/api/APISectionConstants';
7import APISectionEnums from '~/components/plugins/api/APISectionEnums';
8import APISectionInterfaces from '~/components/plugins/api/APISectionInterfaces';
9import APISectionMethods from '~/components/plugins/api/APISectionMethods';
10import APISectionProps from '~/components/plugins/api/APISectionProps';
11import APISectionTypes from '~/components/plugins/api/APISectionTypes';
12import { TypeDocKind } from '~/components/plugins/api/APISectionUtils';
13
14const LATEST_VERSION = `v${require('~/package.json').version}`;
15
16type Props = {
17  packageName: string;
18  apiName?: string;
19};
20
21const filterDataByKind = (
22  entries: GeneratedData[],
23  kind: TypeDocKind,
24  additionalCondition: (entry: GeneratedData) => boolean = () => true
25) =>
26  entries
27    ? entries.filter((entry: GeneratedData) => entry.kind === kind && additionalCondition(entry))
28    : [];
29
30const renderAPI = (
31  packageName: string,
32  version: string = 'unversioned',
33  apiName?: string
34): JSX.Element => {
35  try {
36    const data = require(`~/public/static/data/${version}/${packageName}.json`).children;
37
38    const methods = filterDataByKind(
39      data,
40      TypeDocKind.Function,
41      entry => !entry.name.includes('Listener')
42    );
43    const eventSubscriptions = filterDataByKind(data, TypeDocKind.Function, entry =>
44      entry.name.includes('Listener')
45    );
46    const types = filterDataByKind(
47      data,
48      TypeDocKind.TypeAlias,
49      entry =>
50        !entry.name.includes('Props') &&
51        !!(
52          entry.type.declaration ||
53          entry.type.types ||
54          entry.type.type ||
55          entry.type.typeArguments
56        )
57    );
58
59    const props = filterDataByKind(
60      data,
61      TypeDocKind.TypeAlias,
62      entry => entry.name.includes('Props') && !!entry.type.types
63    );
64    const defaultProps = filterDataByKind(
65      data
66        .filter((entry: GeneratedData) => entry.kind === TypeDocKind.Class)
67        .map((entry: GeneratedData) => entry.children)
68        .flat(),
69      TypeDocKind.Property,
70      entry => entry.name === 'defaultProps'
71    )[0];
72    const enums = filterDataByKind(data, TypeDocKind.Enum);
73    const interfaces = filterDataByKind(data, TypeDocKind.Interface);
74    const constants = filterDataByKind(
75      data,
76      TypeDocKind.Variable,
77      entry => entry?.flags?.isConst || false
78    );
79
80    return (
81      <>
82        <APISectionConstants data={constants} apiName={apiName} />
83        <APISectionMethods data={methods} apiName={apiName} />
84        <APISectionMethods
85          data={eventSubscriptions}
86          apiName={apiName}
87          header="Event Subscriptions"
88        />
89        <APISectionProps data={props} defaultProps={defaultProps} />
90        <APISectionTypes data={types} />
91        <APISectionInterfaces data={interfaces} />
92        <APISectionEnums data={enums} />
93      </>
94    );
95  } catch (error) {
96    return <P>No API data file found, sorry!</P>;
97  }
98};
99
100const APISection: React.FC<Props> = ({ packageName, apiName }) => {
101  const { version } = useContext(DocumentationPageContext);
102  const resolvedVersion =
103    version === 'unversioned' ? version : version === 'latest' ? LATEST_VERSION : version;
104  return renderAPI(packageName, resolvedVersion, apiName);
105};
106
107export default APISection;
108