1import { css } from '@emotion/react'; 2import React from 'react'; 3 4import { InlineCode } from '~/components/base/code'; 5import { UL, LI } from '~/components/base/list'; 6import { B, P } from '~/components/base/paragraph'; 7import { H2, H4, H3Code } from '~/components/plugins/Headings'; 8import { 9 ClassDefinitionData, 10 CommentData, 11 GeneratedData, 12 MethodSignatureData, 13 PropData, 14} from '~/components/plugins/api/APIDataTypes'; 15import { 16 CommentTextBlock, 17 listParams, 18 mdInlineComponents, 19 renderParam, 20 renderTypeOrSignatureType, 21 resolveTypeName, 22 STYLES_OPTIONAL, 23 TypeDocKind, 24} from '~/components/plugins/api/APISectionUtils'; 25 26export type APISectionClassesProps = { 27 data: GeneratedData[]; 28}; 29 30const renderPropertyComment = (comment?: CommentData, signatures?: MethodSignatureData[]) => { 31 if (signatures && signatures.length) { 32 const { type, parameters, comment: signatureComment } = signatures[0]; 33 return ( 34 <> 35 <UL> 36 {parameters?.map(param => renderParam(param))} 37 <LI returnType> 38 <InlineCode>{resolveTypeName(type)}</InlineCode> 39 </LI> 40 </UL> 41 {signatureComment && ( 42 <CommentTextBlock comment={signatureComment} components={mdInlineComponents} /> 43 )} 44 </> 45 ); 46 } else { 47 return comment ? <CommentTextBlock comment={comment} components={mdInlineComponents} /> : null; 48 } 49}; 50 51const renderProperty = ({ name, signatures, flags, type, comment }: PropData) => ( 52 <LI customCss={css({ marginBottom: 6 })} key={`class-property-${name}`}> 53 <B> 54 {name} 55 {signatures && signatures.length ? `(${listParams(signatures[0].parameters)})` : null} 56 </B> 57 {!signatures ? <> {renderTypeOrSignatureType(type, signatures)}</> : null} 58 {flags?.isOptional ? <span css={STYLES_OPTIONAL}> • optional</span> : null} 59 {!signatures ? <br /> : null} 60 {renderPropertyComment(comment, signatures)} 61 </LI> 62); 63 64const renderClass = ({ 65 name, 66 comment, 67 type, 68 extendedTypes, 69 children, 70}: ClassDefinitionData): JSX.Element => { 71 const properties = children?.filter( 72 child => child.kind === TypeDocKind.Property && !child.overwrites 73 ); 74 const methods = children?.filter(child => child.kind === TypeDocKind.Method && !child.overwrites); 75 return ( 76 <div key={`class-definition-${name}`}> 77 <H3Code> 78 <InlineCode>{name}</InlineCode> 79 </H3Code> 80 {extendedTypes?.length && ( 81 <P> 82 <B>Type: </B> 83 {type ? <InlineCode>{resolveTypeName(type)}</InlineCode> : 'Class'} 84 <span> extends </span> 85 <InlineCode>{resolveTypeName(extendedTypes[0])}</InlineCode> 86 </P> 87 )} 88 <CommentTextBlock comment={comment} /> 89 {properties?.length ? ( 90 <> 91 <H4>Properties:</H4> 92 <UL>{properties.map(child => renderProperty(child))}</UL> 93 </> 94 ) : null} 95 {methods?.length ? ( 96 <> 97 <H4>Methods:</H4> 98 <UL>{methods.map(child => renderProperty(child))}</UL> 99 </> 100 ) : null} 101 </div> 102 ); 103}; 104 105const APISectionClasses = ({ data }: APISectionClassesProps) => 106 data?.length ? ( 107 <> 108 <H2 key="classes-header">Classes</H2> 109 {data.map(cls => renderClass(cls))} 110 </> 111 ) : null; 112 113export default APISectionClasses; 114