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