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  GeneratedData,
8  MethodDefinitionData,
9  PropsDefinitionData,
10} from '~/components/plugins/api/APIDataTypes';
11import APISectionProps from '~/components/plugins/api/APISectionProps';
12import { CommentTextBlock, resolveTypeName } from '~/components/plugins/api/APISectionUtils';
13
14export type APISectionComponentsProps = {
15  data: GeneratedData[];
16  componentsProps: PropsDefinitionData[];
17};
18
19const getComponentName = (name?: string, children: MethodDefinitionData[] = []) => {
20  if (name && name !== 'default') return name;
21  const ctor = children.filter((child: MethodDefinitionData) => child.name === 'constructor')[0];
22  return ctor.signatures[0]?.type?.name || 'default';
23};
24
25const renderComponent = (
26  { name, comment, type, extendedTypes, children }: GeneratedData,
27  componentsProps?: PropsDefinitionData[]
28): JSX.Element => {
29  const resolvedType = extendedTypes?.length ? extendedTypes[0] : type;
30  const resolvedName = getComponentName(name, children);
31  return (
32    <div key={`component-definition-${resolvedName}`}>
33      <H3Code>
34        <InlineCode>{resolvedName}</InlineCode>
35      </H3Code>
36      {resolvedType && (
37        <P>
38          <B>Type:</B> <InlineCode>{resolveTypeName(resolvedType)}</InlineCode>
39        </P>
40      )}
41      <CommentTextBlock comment={comment} />
42      {componentsProps && componentsProps.length ? (
43        <APISectionProps data={componentsProps} header={`${resolvedName}Props`} />
44      ) : null}
45    </div>
46  );
47};
48
49const APISectionComponents = ({ data, componentsProps }: APISectionComponentsProps) =>
50  data?.length ? (
51    <>
52      <H2 key="components-header">Components</H2>
53      {data.map(component =>
54        renderComponent(
55          component,
56          componentsProps.filter(cp => cp.name.includes(component.name))
57        )
58      )}
59    </>
60  ) : null;
61
62export default APISectionComponents;
63