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, H4Code } from '~/components/plugins/Headings';
7import {
8  MethodDefinitionData,
9  MethodSignatureData,
10  PropData,
11} from '~/components/plugins/api/APIDataTypes';
12import { PlatformTags } from '~/components/plugins/api/APISectionPlatformTags';
13import {
14  CommentTextBlock,
15  listParams,
16  mdComponents,
17  renderParams,
18  resolveTypeName,
19  STYLES_APIBOX,
20  STYLES_APIBOX_NESTED,
21  STYLES_NESTED_SECTION_HEADER,
22  STYLES_NOT_EXPOSED_HEADER,
23} from '~/components/plugins/api/APISectionUtils';
24
25export type APISectionMethodsProps = {
26  data: (MethodDefinitionData | PropData)[];
27  apiName?: string;
28  header?: string;
29};
30
31export const renderMethod = (
32  { signatures = [] }: MethodDefinitionData | PropData,
33  index?: number,
34  dataLength?: number,
35  apiName?: string,
36  header?: string,
37  exposeInSidebar: boolean = true
38): JSX.Element[] => {
39  const HeaderComponent = exposeInSidebar ? H3Code : H4Code;
40  return signatures.map(({ name, parameters, comment, type }: MethodSignatureData) => (
41    <div
42      key={`method-signature-${name}-${parameters?.length || 0}`}
43      css={[STYLES_APIBOX, !exposeInSidebar && STYLES_APIBOX_NESTED]}>
44      <PlatformTags comment={comment} prefix="Only for:" firstElement />
45      <HeaderComponent>
46        <InlineCode customCss={!exposeInSidebar ? STYLES_NOT_EXPOSED_HEADER : undefined}>
47          {apiName && `${apiName}.`}
48          {header !== 'Hooks' ? `${name}(${listParams(parameters)})` : name}
49        </InlineCode>
50      </HeaderComponent>
51      {parameters && renderParams(parameters)}
52      <CommentTextBlock comment={comment} includePlatforms={false} />
53      {resolveTypeName(type) !== 'undefined' && (
54        <>
55          <div css={STYLES_NESTED_SECTION_HEADER}>
56            <H4>Returns</H4>
57          </div>
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        </>
67      )}
68    </div>
69  ));
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