1import { css } from '@emotion/react'; 2import { theme, spacing, UndoIcon, iconSize } from '@expo/styleguide'; 3import React from 'react'; 4import ReactMarkdown from 'react-markdown'; 5 6import { InlineCode } from '~/components/base/code'; 7import { LI, UL } from '~/components/base/list'; 8import { H2, H3Code, H4, H4Code } from '~/components/plugins/Headings'; 9import { 10 MethodDefinitionData, 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 getTagNamesList, 19 listParams, 20 mdComponents, 21 renderParams, 22 resolveTypeName, 23 STYLES_APIBOX, 24 STYLES_APIBOX_NESTED, 25 STYLES_NESTED_SECTION_HEADER, 26 STYLES_NOT_EXPOSED_HEADER, 27} from '~/components/plugins/api/APISectionUtils'; 28 29export type APISectionMethodsProps = { 30 data: (MethodDefinitionData | PropData)[]; 31 apiName?: string; 32 header?: string; 33}; 34 35export type RenderMethodOptions = { 36 apiName?: string; 37 header?: string; 38 exposeInSidebar?: boolean; 39}; 40 41export const renderMethod = ( 42 { signatures = [] }: MethodDefinitionData | PropData, 43 { apiName, header, exposeInSidebar = true }: RenderMethodOptions = {} 44): JSX.Element[] => { 45 const HeaderComponent = exposeInSidebar ? H3Code : H4Code; 46 return signatures.map(({ name, parameters, comment, type }: MethodSignatureData) => ( 47 <div 48 key={`method-signature-${name}-${parameters?.length || 0}`} 49 css={[STYLES_APIBOX, !exposeInSidebar && STYLES_APIBOX_NESTED]}> 50 <APISectionDeprecationNote comment={comment} /> 51 <APISectionPlatformTags comment={comment} prefix="Only for:" firstElement /> 52 <HeaderComponent tags={getTagNamesList(comment)}> 53 <InlineCode customCss={!exposeInSidebar ? STYLES_NOT_EXPOSED_HEADER : undefined}> 54 {apiName && `${apiName}.`} 55 {header !== 'Hooks' ? `${name}(${listParams(parameters)})` : name} 56 </InlineCode> 57 </HeaderComponent> 58 {parameters && renderParams(parameters)} 59 <CommentTextBlock comment={comment} includePlatforms={false} /> 60 {resolveTypeName(type) !== 'undefined' && ( 61 <> 62 <div css={STYLES_NESTED_SECTION_HEADER}> 63 <H4>Returns</H4> 64 </div> 65 <UL hideBullets> 66 <LI> 67 <UndoIcon color={theme.icon.secondary} size={iconSize.small} css={returnIconStyles} /> 68 <InlineCode>{resolveTypeName(type)}</InlineCode> 69 </LI> 70 </UL> 71 {comment?.returns && ( 72 <ReactMarkdown components={mdComponents}>{comment.returns}</ReactMarkdown> 73 )} 74 </> 75 )} 76 </div> 77 )); 78}; 79 80const APISectionMethods = ({ data, apiName, header = 'Methods' }: APISectionMethodsProps) => 81 data?.length ? ( 82 <> 83 <H2 key="methods-header">{header}</H2> 84 {data.map((method: MethodDefinitionData | PropData) => 85 renderMethod(method, { apiName, header }) 86 )} 87 </> 88 ) : null; 89 90const returnIconStyles = css({ 91 transform: 'rotate(180deg)', 92 marginRight: spacing[2], 93 verticalAlign: 'middle', 94}); 95 96export default APISectionMethods; 97