1import { CornerDownRightIcon } from '@expo/styleguide-icons'; 2import ReactMarkdown from 'react-markdown'; 3 4import { APIDataType } from '~/components/plugins/api/APIDataType'; 5import { 6 AccessorDefinitionData, 7 MethodDefinitionData, 8 MethodParamData, 9 MethodSignatureData, 10 PropData, 11 TypeSignaturesData, 12} from '~/components/plugins/api/APIDataTypes'; 13import { APISectionDeprecationNote } from '~/components/plugins/api/APISectionDeprecationNote'; 14import { APISectionPlatformTags } from '~/components/plugins/api/APISectionPlatformTags'; 15import { 16 CommentTextBlock, 17 getMethodName, 18 getTagNamesList, 19 mdComponents, 20 renderParams, 21 resolveTypeName, 22 STYLES_APIBOX, 23 STYLES_APIBOX_NESTED, 24 STYLES_NOT_EXPOSED_HEADER, 25 TypeDocKind, 26 H3Code, 27 H4Code, 28 getTagData, 29 getCommentContent, 30 BoxSectionHeader, 31} from '~/components/plugins/api/APISectionUtils'; 32import { H2, LI, UL, MONOSPACE } from '~/ui/components/Text'; 33 34export type APISectionMethodsProps = { 35 data: (MethodDefinitionData | PropData)[]; 36 apiName?: string; 37 header?: string; 38 exposeInSidebar?: boolean; 39}; 40 41export type RenderMethodOptions = { 42 apiName?: string; 43 header?: string; 44 exposeInSidebar?: boolean; 45}; 46 47export const renderMethod = ( 48 method: MethodDefinitionData | AccessorDefinitionData | PropData, 49 { apiName, exposeInSidebar = true }: RenderMethodOptions = {} 50) => { 51 const signatures = 52 (method as MethodDefinitionData).signatures || 53 (method as PropData)?.type?.declaration?.signatures || [ 54 (method as AccessorDefinitionData)?.getSignature, 55 ] || 56 []; 57 const HeaderComponent = exposeInSidebar ? H3Code : H4Code; 58 return signatures.map( 59 ({ name, parameters, comment, type }: MethodSignatureData | TypeSignaturesData) => { 60 const returnComment = getTagData('returns', comment); 61 return ( 62 <div 63 key={`method-signature-${method.name || name}-${parameters?.length || 0}`} 64 css={[STYLES_APIBOX, STYLES_APIBOX_NESTED]}> 65 <APISectionDeprecationNote comment={comment} /> 66 <APISectionPlatformTags comment={comment} prefix="Only for:" /> 67 <HeaderComponent tags={getTagNamesList(comment)}> 68 <MONOSPACE weight="medium" css={!exposeInSidebar && STYLES_NOT_EXPOSED_HEADER}> 69 {getMethodName(method as MethodDefinitionData, apiName, name, parameters)} 70 </MONOSPACE> 71 </HeaderComponent> 72 {parameters && parameters.length > 0 && ( 73 <> 74 {renderParams(parameters)} 75 <br /> 76 </> 77 )} 78 <CommentTextBlock comment={comment} includePlatforms={false} /> 79 {resolveTypeName(type) !== 'undefined' && ( 80 <> 81 <BoxSectionHeader text="Returns" /> 82 <UL className="!list-none !ml-0"> 83 <LI> 84 <CornerDownRightIcon className="inline-block icon-sm text-icon-secondary align-middle mr-2" /> 85 <APIDataType typeDefinition={type} /> 86 </LI> 87 </UL> 88 <> 89 <br /> 90 {returnComment ? ( 91 <ReactMarkdown components={mdComponents}> 92 {getCommentContent(returnComment.content)} 93 </ReactMarkdown> 94 ) : undefined} 95 </> 96 </> 97 )} 98 </div> 99 ); 100 } 101 ); 102}; 103 104const APISectionMethods = ({ 105 data, 106 apiName, 107 header = 'Methods', 108 exposeInSidebar = true, 109}: APISectionMethodsProps) => 110 data?.length ? ( 111 <> 112 <H2 key={`${header}-header`}>{header}</H2> 113 {data.map((method: MethodDefinitionData | PropData) => 114 renderMethod(method, { apiName, header, exposeInSidebar }) 115 )} 116 </> 117 ) : null; 118 119export default APISectionMethods; 120 121export const APIMethod = ({ 122 name, 123 comment, 124 returnTypeName, 125 isProperty = false, 126 isReturnTypeReference = false, 127 exposeInSidebar = false, 128 parameters = [], 129 platforms = [], 130}: { 131 exposeInSidebar?: boolean; 132 name: string; 133 comment: string; 134 returnTypeName: string; 135 isProperty: boolean; 136 isReturnTypeReference: boolean; 137 platforms: ('Android' | 'iOS' | 'Web')[]; 138 parameters: { 139 name: string; 140 comment?: string; 141 typeName: string; 142 isReference?: boolean; 143 }[]; 144}) => { 145 const parsedParameters = parameters.map( 146 param => 147 ({ 148 name: param.name, 149 type: { name: param.typeName, type: param.isReference ? 'reference' : 'literal' }, 150 comment: { 151 summary: [{ kind: 'text', text: param.comment }], 152 }, 153 } as MethodParamData) 154 ); 155 return renderMethod( 156 { 157 name, 158 signatures: [ 159 { 160 name, 161 parameters: parsedParameters, 162 comment: { 163 summary: [{ kind: 'text', text: comment }], 164 blockTags: platforms.map(text => ({ 165 tag: 'platform', 166 content: [{ kind: 'text', text }], 167 })), 168 }, 169 type: { name: returnTypeName, type: isReturnTypeReference ? 'reference' : 'literal' }, 170 }, 171 ], 172 kind: isProperty ? TypeDocKind.Property : TypeDocKind.Function, 173 }, 174 { exposeInSidebar } 175 ); 176}; 177