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