1import { StatusWaitingIcon } from '@expo/styleguide-icons'; 2 3import { ElementType } from '~/types/common'; 4import { NoIcon, YesIcon } from '~/ui/components/DocIcons'; 5import { Cell, HeaderCell, Row, Table, TableHead, TableLayout } from '~/ui/components/Table'; 6import { A, H4 } from '~/ui/components/Text'; 7 8const platforms = [ 9 { title: 'Android Device', propName: 'android' }, 10 { title: 'Android Emulator', propName: 'emulator' }, 11 { title: 'iOS Device', propName: 'ios' }, 12 { title: 'iOS Simulator', propName: 'simulator' }, 13 { title: 'Web', propName: 'web' }, 14]; 15 16type Platform = ElementType<typeof platforms>; 17type IsSupported = boolean | undefined | { pending: string }; 18 19function getInfo(isSupported: IsSupported, { title }: Platform) { 20 if (isSupported === true) { 21 return { 22 children: <YesIcon />, 23 title: `${title} is supported`, 24 }; 25 } else if (typeof isSupported === 'object') { 26 return { 27 children: ( 28 <A className="grid gap-2 grid-cols-[20px_auto]" href={isSupported.pending}> 29 <StatusWaitingIcon className="icon-md text-icon-info" /> Pending 30 </A> 31 ), 32 title: `${title} support is pending`, 33 }; 34 } 35 36 return { 37 children: <NoIcon />, 38 title: `${title} is not supported`, 39 }; 40} 41 42type Props = { 43 title?: string; 44 ios?: boolean; 45 android?: boolean; 46 web?: boolean; 47 simulator?: boolean; 48 emulator?: boolean; 49}; 50 51type PlatformProps = Omit<Props, 'title'>; 52 53const PlatformsSection = (props: Props) => ( 54 <> 55 <H4 className="mb-1">{props.title || 'Platform Compatibility'}</H4> 56 <Table layout={TableLayout.Fixed}> 57 <TableHead> 58 <Row> 59 {platforms.map(({ title }) => ( 60 <HeaderCell key={title}>{title}</HeaderCell> 61 ))} 62 </Row> 63 </TableHead> 64 <tbody> 65 <Row> 66 {platforms.map(platform => ( 67 <Cell 68 key={platform.title} 69 {...getInfo(props[platform.propName as keyof PlatformProps], platform)} 70 /> 71 ))} 72 </Row> 73 </tbody> 74 </Table> 75 </> 76); 77 78export default PlatformsSection; 79