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