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  CommentData,
8  InterfaceDefinitionData,
9  MethodSignatureData,
10  PropData,
11} from '~/components/plugins/api/APIDataTypes';
12import {
13  CommentTextBlock,
14  mdInlineComponents,
15  renderFlags,
16  renderParam,
17  renderTypeOrSignatureType,
18  resolveTypeName,
19} from '~/components/plugins/api/APISectionUtils';
20
21export type APISectionInterfacesProps = {
22  data: InterfaceDefinitionData[];
23};
24
25const renderInterfaceComment = (comment?: CommentData, signatures?: MethodSignatureData[]) => {
26  if (signatures && signatures.length) {
27    const { type, parameters, comment: signatureComment } = signatures[0];
28    return (
29      <>
30        {parameters?.length ? parameters.map(param => renderParam(param)) : null}
31        <B>Returns: </B>
32        <InlineCode>{resolveTypeName(type)}</InlineCode>
33        {signatureComment && (
34          <>
35            <br />
36            <CommentTextBlock comment={signatureComment} components={mdInlineComponents} />
37          </>
38        )}
39      </>
40    );
41  } else {
42    return comment ? <CommentTextBlock comment={comment} components={mdInlineComponents} /> : '-';
43  }
44};
45
46const renderInterfacePropertyRow = ({
47  name,
48  flags,
49  type,
50  comment,
51  signatures,
52}: PropData): JSX.Element => (
53  <tr key={name}>
54    <td>
55      <B>
56        {name}
57        {signatures && signatures.length ? '()' : ''}
58      </B>
59      {renderFlags(flags)}
60    </td>
61    <td>{renderTypeOrSignatureType(type, signatures)}</td>
62    <td>{renderInterfaceComment(comment, signatures)}</td>
63  </tr>
64);
65
66const renderInterface = ({
67  name,
68  children,
69  comment,
70  extendedTypes,
71}: InterfaceDefinitionData): JSX.Element | null =>
72  children ? (
73    <div key={`interface-definition-${name}`}>
74      <H3Code>
75        <InlineCode>{name}</InlineCode>
76      </H3Code>
77      {extendedTypes?.length && (
78        <P>
79          <B>Extends: </B>
80          {extendedTypes.map(extendedType => (
81            <InlineCode key={`extend-${extendedType.name}`}>
82              {resolveTypeName(extendedType)}
83            </InlineCode>
84          ))}
85        </P>
86      )}
87      <CommentTextBlock comment={comment} />
88      <table>
89        <thead>
90          <tr>
91            <th>Name</th>
92            <th>Type</th>
93            <th>Description</th>
94          </tr>
95        </thead>
96        <tbody>
97          {children.filter(child => !child?.inheritedFrom).map(renderInterfacePropertyRow)}
98        </tbody>
99      </table>
100    </div>
101  ) : null;
102
103const APISectionInterfaces = ({ data }: APISectionInterfacesProps) =>
104  data?.length ? (
105    <>
106      <H2 key="interfaces-header">Interfaces</H2>
107      {data.map(renderInterface)}
108    </>
109  ) : null;
110
111export default APISectionInterfaces;
112