1import React from 'react';
2import ReactMarkdown from 'react-markdown';
3
4import { InlineCode } from '~/components/base/code';
5import { LI, UL } from '~/components/base/list';
6import { H2, H3Code, H4 } from '~/components/plugins/Headings';
7import {
8  MethodDefinitionData,
9  MethodSignatureData,
10  PropData,
11} from '~/components/plugins/api/APIDataTypes';
12import {
13  CommentTextBlock,
14  getPlatformTags,
15  listParams,
16  mdComponents,
17  renderParam,
18  resolveTypeName,
19} from '~/components/plugins/api/APISectionUtils';
20
21export type APISectionMethodsProps = {
22  data: (MethodDefinitionData | PropData)[];
23  apiName?: string;
24  header?: string;
25};
26
27export const renderMethod = (
28  { signatures = [] }: MethodDefinitionData | PropData,
29  index?: number,
30  dataLength?: number,
31  apiName?: string,
32  header?: string
33): JSX.Element[] =>
34  signatures.map(({ name, parameters, comment, type }: MethodSignatureData) => (
35    <div key={`method-signature-${name}-${parameters?.length || 0}`}>
36      <H3Code>
37        <InlineCode>
38          {apiName && `${apiName}.`}
39          {header !== 'Hooks' ? `${name}(${listParams(parameters)})` : name}
40        </InlineCode>
41      </H3Code>
42      {getPlatformTags(comment)}
43      <CommentTextBlock
44        comment={comment}
45        beforeContent={
46          parameters && (
47            <>
48              <H4>Arguments</H4>
49              <UL>{parameters?.map(renderParam)}</UL>
50            </>
51          )
52        }
53        includePlatforms={false}
54      />
55      {resolveTypeName(type) !== 'undefined' ? (
56        <div>
57          <H4>Returns</H4>
58          <UL>
59            <LI returnType>
60              <InlineCode>{resolveTypeName(type)}</InlineCode>
61            </LI>
62          </UL>
63          {comment?.returns && (
64            <ReactMarkdown components={mdComponents}>{comment.returns}</ReactMarkdown>
65          )}
66        </div>
67      ) : null}
68      {index !== undefined ? index + 1 !== dataLength && <hr /> : null}
69    </div>
70  ));
71
72const APISectionMethods = ({ data, apiName, header = 'Methods' }: APISectionMethodsProps) =>
73  data?.length ? (
74    <>
75      <H2 key="methods-header">{header}</H2>
76      {data.map((method: MethodDefinitionData | PropData, index: number) =>
77        renderMethod(method, index, data.length, apiName, header)
78      )}
79    </>
80  ) : null;
81
82export default APISectionMethods;
83