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