1import { css } from '@emotion/react'; 2import { StatusFailedIcon, StatusSuccessIcon, StatusWaitingIcon, theme } from '@expo/styleguide'; 3import * as React from 'react'; 4 5import { H4 } from '~/components/base/headings'; 6import { ElementType } from '~/types/common'; 7import { Cell, HeaderCell, Row, Table, TableHead, TableLayout } from '~/ui/components/Table'; 8 9const STYLES_TITLE = css` 10 margin-bottom: 1rem; 11`; 12 13const STYLES_LINK = css` 14 text-decoration: none; 15 display: grid; 16 grid-template-columns: 20px auto; 17 text-align: left; 18 grid-gap: 8px; 19 color: ${theme.link.default}; 20`; 21 22const platforms = [ 23 { title: 'Android Device', propName: 'android' }, 24 { title: 'Android Emulator', propName: 'emulator' }, 25 { title: 'iOS Device', propName: 'ios' }, 26 { title: 'iOS Simulator', propName: 'simulator' }, 27 { title: 'Web', propName: 'web' }, 28]; 29 30type Platform = ElementType<typeof platforms>; 31type IsSupported = boolean | undefined | { pending: string }; 32 33function getInfo(isSupported: IsSupported, { title }: Platform) { 34 if (isSupported === true) { 35 return { 36 children: <StatusSuccessIcon color={theme.status.success} />, 37 title: `${title} is supported`, 38 }; 39 } else if (typeof isSupported === 'object') { 40 return { 41 children: ( 42 <a css={STYLES_LINK} target="_blank" href={isSupported.pending}> 43 <StatusWaitingIcon color={theme.status.info} /> Pending 44 </a> 45 ), 46 title: `${title} support is pending`, 47 }; 48 } 49 50 return { 51 children: <StatusFailedIcon color={theme.status.error} />, 52 title: `${title} is not supported`, 53 }; 54} 55 56type Props = { 57 title?: string; 58 ios?: boolean; 59 android?: boolean; 60 web?: boolean; 61 simulator?: boolean; 62 emulator?: boolean; 63}; 64 65type PlatformProps = Omit<Props, 'title'>; 66 67const PlatformsSection = (props: Props) => ( 68 <> 69 <H4 css={STYLES_TITLE}>{props.title || 'Platform Compatibility'}</H4> 70 <Table layout={TableLayout.Fixed}> 71 <TableHead> 72 <Row> 73 {platforms.map(({ title }) => ( 74 <HeaderCell key={title}>{title}</HeaderCell> 75 ))} 76 </Row> 77 </TableHead> 78 <tbody> 79 <Row> 80 {platforms.map(platform => ( 81 <Cell 82 key={platform.title} 83 {...getInfo(props[platform.propName as keyof PlatformProps], platform)} 84 /> 85 ))} 86 </Row> 87 </tbody> 88 </Table> 89 </> 90); 91 92export default PlatformsSection; 93