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