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