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