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