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