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