1import React from 'react';
2
3import { InlineCode } from '~/components/base/code';
4import { B, P } from '~/components/base/paragraph';
5import { H2, H3Code } from '~/components/plugins/Headings';
6import {
7  CommentData,
8  GeneratedData,
9  MethodSignatureData,
10  PropsDefinitionData,
11} from '~/components/plugins/api/APIDataTypes';
12import { APISectionDeprecationNote } from '~/components/plugins/api/APISectionDeprecationNote';
13import APISectionProps from '~/components/plugins/api/APISectionProps';
14import {
15  CommentTextBlock,
16  resolveTypeName,
17  getComponentName,
18  STYLES_APIBOX,
19  getTagNamesList,
20} from '~/components/plugins/api/APISectionUtils';
21
22export type APISectionComponentsProps = {
23  data: GeneratedData[];
24  componentsProps: PropsDefinitionData[];
25};
26
27const getComponentComment = (comment: CommentData, signatures: MethodSignatureData[]) =>
28  comment || (signatures?.[0]?.comment ?? undefined);
29
30const renderComponent = (
31  { name, comment, type, extendedTypes, children, signatures }: GeneratedData,
32  componentsProps?: PropsDefinitionData[]
33): JSX.Element => {
34  const resolvedType = extendedTypes?.length ? extendedTypes[0] : type;
35  const resolvedName = getComponentName(name, children);
36  const extractedComment = getComponentComment(comment, signatures);
37  return (
38    <div key={`component-definition-${resolvedName}`} css={STYLES_APIBOX}>
39      <APISectionDeprecationNote comment={extractedComment} />
40      <H3Code tags={getTagNamesList(comment)}>
41        <InlineCode>{resolvedName}</InlineCode>
42      </H3Code>
43      {resolvedType && (
44        <P>
45          <B>Type:</B> <InlineCode>{resolveTypeName(resolvedType)}</InlineCode>
46        </P>
47      )}
48      <CommentTextBlock comment={extractedComment} />
49      {componentsProps && componentsProps.length ? (
50        <APISectionProps
51          data={componentsProps}
52          header={componentsProps.length === 1 ? 'Props' : `${resolvedName}Props`}
53        />
54      ) : null}
55    </div>
56  );
57};
58
59const APISectionComponents = ({ data, componentsProps }: APISectionComponentsProps) =>
60  data?.length ? (
61    <>
62      <H2 key="components-header">{data.length === 1 ? 'Component' : 'Components'}</H2>
63      {data.map(component =>
64        renderComponent(
65          component,
66          componentsProps.filter(cp =>
67            cp.name.includes(getComponentName(component.name, component.children))
68          )
69        )
70      )}
71    </>
72  ) : null;
73
74export default APISectionComponents;
75