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