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