1import React from 'react'; 2 3import { renderMethod } from './APISectionMethods'; 4 5import { InlineCode } from '~/components/base/code'; 6import { B, P } from '~/components/base/paragraph'; 7import { H2, H3Code, H4 } from '~/components/plugins/Headings'; 8import { 9 CommentData, 10 CommentTagData, 11 InterfaceDefinitionData, 12 MethodSignatureData, 13 PropData, 14} from '~/components/plugins/api/APIDataTypes'; 15import { 16 CommentTextBlock, 17 getTagData, 18 mdInlineComponents, 19 renderFlags, 20 renderParamRow, 21 renderTableHeadRow, 22 resolveTypeName, 23 STYLES_APIBOX, 24 STYLES_NESTED_SECTION_HEADER, 25} from '~/components/plugins/api/APISectionUtils'; 26import { Cell, Row, Table } from '~/ui/components/Table'; 27 28export type APISectionInterfacesProps = { 29 data: InterfaceDefinitionData[]; 30}; 31 32const renderDefaultValue = (defaultValue?: CommentTagData) => 33 defaultValue && ( 34 <> 35 <br /> 36 <br /> 37 <B>Default:</B> <InlineCode>{defaultValue.text}</InlineCode> 38 </> 39 ); 40 41const renderInterfaceComment = (comment?: CommentData, signatures?: MethodSignatureData[]) => { 42 if (signatures && signatures.length) { 43 const { type, parameters, comment: signatureComment } = signatures[0]; 44 const defaultValue = getTagData('default', signatureComment); 45 return ( 46 <> 47 {parameters?.length ? parameters.map(param => renderParamRow(param)) : null} 48 <B>Returns: </B> 49 <InlineCode>{resolveTypeName(type)}</InlineCode> 50 {signatureComment && ( 51 <> 52 <br /> 53 <CommentTextBlock 54 comment={signatureComment} 55 components={mdInlineComponents} 56 afterContent={renderDefaultValue(defaultValue)} 57 /> 58 </> 59 )} 60 </> 61 ); 62 } else { 63 const defaultValue = getTagData('default', comment); 64 return ( 65 <CommentTextBlock 66 comment={comment} 67 components={mdInlineComponents} 68 afterContent={renderDefaultValue(defaultValue)} 69 emptyCommentFallback="-" 70 /> 71 ); 72 } 73}; 74 75const renderInterfacePropertyRow = ({ 76 name, 77 flags, 78 type, 79 comment, 80 signatures, 81}: PropData): JSX.Element => { 82 return ( 83 <Row key={name}> 84 <Cell fitContent> 85 <B>{name}</B> 86 {renderFlags(flags)} 87 </Cell> 88 <Cell fitContent> 89 <InlineCode>{resolveTypeName(type)}</InlineCode> 90 </Cell> 91 <Cell fitContent>{renderInterfaceComment(comment, signatures)}</Cell> 92 </Row> 93 ); 94}; 95 96const renderInterface = ({ 97 name, 98 children, 99 comment, 100 extendedTypes, 101}: InterfaceDefinitionData): JSX.Element | null => { 102 const interfaceChildren = children?.filter(child => !child?.inheritedFrom) || []; 103 104 if (!interfaceChildren.length) return null; 105 106 const interfaceMethods = interfaceChildren.filter(child => child.signatures); 107 const interfaceFields = interfaceChildren.filter(child => !child.signatures); 108 109 return ( 110 <div key={`interface-definition-${name}`} css={STYLES_APIBOX}> 111 <H3Code> 112 <InlineCode>{name}</InlineCode> 113 </H3Code> 114 {extendedTypes?.length ? ( 115 <P> 116 <B>Extends: </B> 117 {extendedTypes.map(extendedType => ( 118 <InlineCode key={`extend-${extendedType.name}`}> 119 {resolveTypeName(extendedType)} 120 </InlineCode> 121 ))} 122 </P> 123 ) : null} 124 <CommentTextBlock comment={comment} /> 125 {interfaceMethods.length ? ( 126 <> 127 <div css={STYLES_NESTED_SECTION_HEADER}> 128 <H4>{name} Methods</H4> 129 </div> 130 {interfaceMethods.map(method => renderMethod(method))} 131 </> 132 ) : undefined} 133 {interfaceFields.length ? ( 134 <> 135 <div css={STYLES_NESTED_SECTION_HEADER}> 136 <H4>{name} Properties</H4> 137 </div> 138 <Table> 139 {renderTableHeadRow()} 140 <tbody>{interfaceFields.map(renderInterfacePropertyRow)}</tbody> 141 </Table> 142 </> 143 ) : undefined} 144 </div> 145 ); 146}; 147 148const APISectionInterfaces = ({ data }: APISectionInterfacesProps) => 149 data?.length ? ( 150 <> 151 <H2 key="interfaces-header">Interfaces</H2> 152 {data.map(renderInterface)} 153 </> 154 ) : null; 155 156export default APISectionInterfaces; 157