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