1import React from 'react'; 2import ReactMarkdown from 'react-markdown'; 3 4import { InlineCode } from '~/components/base/code'; 5import { B, P } from '~/components/base/paragraph'; 6import { H2, H3Code, H4 } from '~/components/plugins/Headings'; 7import { 8 ClassDefinitionData, 9 GeneratedData, 10 PropData, 11} from '~/components/plugins/api/APIDataTypes'; 12import { APISectionDeprecationNote } from '~/components/plugins/api/APISectionDeprecationNote'; 13import { renderMethod } from '~/components/plugins/api/APISectionMethods'; 14import { renderProp } from '~/components/plugins/api/APISectionProps'; 15import { 16 CommentTextBlock, 17 getTagData, 18 getTagNamesList, 19 mdComponents, 20 resolveTypeName, 21 STYLES_APIBOX, 22 STYLES_NESTED_SECTION_HEADER, 23 TypeDocKind, 24} from '~/components/plugins/api/APISectionUtils'; 25 26export type APISectionClassesProps = { 27 data: GeneratedData[]; 28}; 29 30const isProp = (child: PropData) => 31 child.kind === TypeDocKind.Property && 32 !child.overwrites && 33 !child.name.startsWith('_') && 34 !child.implementationOf; 35 36const isMethod = (child: PropData) => 37 child.kind === TypeDocKind.Method && 38 !child.overwrites && 39 !child.name.startsWith('_') && 40 !child?.implementationOf; 41 42const renderClass = (clx: ClassDefinitionData, hasMultipleClasses: boolean): JSX.Element => { 43 const { name, comment, type, extendedTypes, children, implementedTypes } = clx; 44 const properties = children?.filter(isProp); 45 const methods = children 46 ?.filter(isMethod) 47 .sort((a: PropData, b: PropData) => a.name.localeCompare(b.name)); 48 const returnComment = getTagData('returns', comment); 49 50 return ( 51 <div key={`class-definition-${name}`} css={STYLES_APIBOX}> 52 <APISectionDeprecationNote comment={comment} /> 53 {hasMultipleClasses ? ( 54 <H3Code tags={getTagNamesList(comment)}> 55 <InlineCode>{name}</InlineCode> 56 </H3Code> 57 ) : ( 58 <H2>{name}</H2> 59 )} 60 {(extendedTypes?.length || implementedTypes?.length) && ( 61 <P> 62 <B>Type: </B> 63 {type ? <InlineCode>{resolveTypeName(type)}</InlineCode> : 'Class'} 64 {extendedTypes?.length && ( 65 <> 66 <span> extends </span> 67 {extendedTypes.map(extendedType => ( 68 <InlineCode key={`extends-${extendedType.name}`}> 69 {resolveTypeName(extendedType)} 70 </InlineCode> 71 ))} 72 </> 73 )} 74 {implementedTypes?.length && ( 75 <> 76 <span> implements </span> 77 {implementedTypes.map(implementedType => ( 78 <InlineCode key={`implements-${implementedType.name}`}> 79 {resolveTypeName(implementedType)} 80 </InlineCode> 81 ))} 82 </> 83 )} 84 </P> 85 )} 86 <CommentTextBlock comment={comment} /> 87 {returnComment && ( 88 <> 89 <div css={STYLES_NESTED_SECTION_HEADER}> 90 <H4>Returns</H4> 91 </div> 92 <ReactMarkdown components={mdComponents}>{returnComment.text}</ReactMarkdown> 93 </> 94 )} 95 {properties?.length ? ( 96 <> 97 {hasMultipleClasses ? ( 98 <div css={STYLES_NESTED_SECTION_HEADER}> 99 <H4>{name} Properties</H4> 100 </div> 101 ) : ( 102 <H2>{name} Properties</H2> 103 )} 104 <div> 105 {properties.map(property => 106 renderProp(property, property?.defaultValue, !hasMultipleClasses) 107 )} 108 </div> 109 </> 110 ) : null} 111 {methods?.length && ( 112 <> 113 {hasMultipleClasses ? ( 114 <div css={STYLES_NESTED_SECTION_HEADER}> 115 <H4>{name} Methods</H4> 116 </div> 117 ) : ( 118 <H2>{name} Methods</H2> 119 )} 120 {methods.map(method => renderMethod(method, { exposeInSidebar: !hasMultipleClasses }))} 121 </> 122 )} 123 </div> 124 ); 125}; 126 127const APISectionClasses = ({ data }: APISectionClassesProps) => { 128 if (data?.length) { 129 const hasMultipleClasses = data.length > 1; 130 return ( 131 <> 132 {hasMultipleClasses ? <H2>Classes</H2> : null} 133 {data.map(cls => renderClass(cls, hasMultipleClasses))} 134 </> 135 ); 136 } 137 return null; 138}; 139 140export default APISectionClasses; 141