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