1import ReactMarkdown from 'react-markdown';
2
3import {
4  ClassDefinitionData,
5  GeneratedData,
6  PropData,
7} from '~/components/plugins/api/APIDataTypes';
8import { APISectionDeprecationNote } from '~/components/plugins/api/APISectionDeprecationNote';
9import { renderMethod } from '~/components/plugins/api/APISectionMethods';
10import {
11  CommentTextBlock,
12  getAPISectionHeader,
13  getTagData,
14  getTagNamesList,
15  mdComponents,
16  STYLES_APIBOX,
17  STYLES_NESTED_SECTION_HEADER,
18  TypeDocKind,
19  H3Code,
20} from '~/components/plugins/api/APISectionUtils';
21import { H2, H4, CODE } from '~/ui/components/Text';
22
23export type APISectionNamespacesProps = {
24  data: GeneratedData[];
25};
26
27const isMethod = (child: PropData, allowOverwrites: boolean = false) =>
28  child.kind &&
29  [TypeDocKind.Method, TypeDocKind.Function].includes(child.kind) &&
30  (allowOverwrites || !child.overwrites) &&
31  !child.name.startsWith('_') &&
32  !child?.implementationOf;
33
34const renderNamespace = (namespace: ClassDefinitionData, exposeInSidebar: boolean): JSX.Element => {
35  const { name, comment, children } = namespace;
36  const Header = getAPISectionHeader(exposeInSidebar);
37
38  const methods = children
39    ?.filter(child => isMethod(child))
40    .sort((a: PropData, b: PropData) => a.name.localeCompare(b.name));
41  const returnComment = getTagData('returns', comment);
42
43  return (
44    <div key={`class-definition-${name}`} css={STYLES_APIBOX}>
45      <APISectionDeprecationNote comment={comment} />
46      <H3Code tags={getTagNamesList(comment)}>
47        <CODE>{name}</CODE>
48      </H3Code>
49      <CommentTextBlock comment={comment} />
50      {returnComment && (
51        <>
52          <div css={STYLES_NESTED_SECTION_HEADER}>
53            <H4>Returns</H4>
54          </div>
55          <ReactMarkdown components={mdComponents}>{returnComment.text}</ReactMarkdown>
56        </>
57      )}
58      {methods?.length ? (
59        <>
60          <div css={STYLES_NESTED_SECTION_HEADER}>
61            <Header>{name} Methods</Header>
62          </div>
63          {methods.map(method => renderMethod(method, { exposeInSidebar }))}
64        </>
65      ) : undefined}
66    </div>
67  );
68};
69
70const APISectionNamespaces = ({ data }: APISectionNamespacesProps) => {
71  if (data?.length) {
72    const exposeInSidebar = data.length < 2;
73    return (
74      <>
75        <H2>Namespaces</H2>
76        {data.map(namespace => renderNamespace(namespace, exposeInSidebar))}
77      </>
78    );
79  }
80  return null;
81};
82
83export default APISectionNamespaces;
84