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