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  renderParam,
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      <CommentTextBlock
49        comment={comment}
50        beforeContent={
51          parameters && (
52            <>
53              <H4>Arguments</H4>
54              <UL>{parameters?.map(renderParam)}</UL>
55            </>
56          )
57        }
58        includePlatforms={false}
59      />
60      {resolveTypeName(type) !== 'undefined' ? (
61        <div>
62          <H4>Returns</H4>
63          <UL>
64            <LI returnType>
65              <InlineCode>{resolveTypeName(type)}</InlineCode>
66            </LI>
67          </UL>
68          {comment?.returns && (
69            <ReactMarkdown components={mdComponents}>{comment.returns}</ReactMarkdown>
70          )}
71        </div>
72      ) : null}
73      {index !== undefined ? index + 1 !== dataLength && <hr /> : null}
74    </div>
75  ));
76};
77
78const APISectionMethods = ({ data, apiName, header = 'Methods' }: APISectionMethodsProps) =>
79  data?.length ? (
80    <>
81      <H2 key="methods-header">{header}</H2>
82      {data.map((method: MethodDefinitionData | PropData, index: number) =>
83        renderMethod(method, index, data.length, apiName, header)
84      )}
85    </>
86  ) : null;
87
88export default APISectionMethods;
89