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