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