1import { css } from '@emotion/react';
2import { theme, typography, shadows } from '@expo/styleguide';
3import { spacing, borderRadius } from '@expo/styleguide-base';
4import { ChevronDownIcon } from '@expo/styleguide-icons';
5
6import { A } from '../Text';
7
8import * as Utilities from '~/common/utilities';
9import { usePageApiVersion } from '~/providers/page-api-version';
10import versions from '~/public/static/constants/versions.json';
11
12const { VERSIONS, LATEST_VERSION, BETA_VERSION } = versions;
13
14const STYLES_SELECT = css({
15  ...typography.fontSizes[14],
16  color: theme.text.default,
17  margin: 0,
18  marginTop: spacing[1],
19  padding: `${spacing[2]}px ${spacing[3]}px`,
20  minHeight: 40,
21  borderRadius: borderRadius.md,
22  marginBottom: spacing[4],
23  width: '100%',
24  backgroundColor: theme.background.default,
25  border: `1px solid ${theme.border.default}`,
26  boxShadow: shadows.xs,
27  appearance: 'none',
28  outline: 'none',
29  cursor: 'pointer',
30});
31
32export const VersionSelector = () => {
33  const { version, hasVersion, setVersion } = usePageApiVersion();
34
35  if (!hasVersion) {
36    return null;
37  }
38
39  return (
40    <div className="relative">
41      {
42        // Add hidden links to create crawlable references to other SDK versions
43        // We can use JS to switch between them, while helping search bots find other SDK versions
44        VERSIONS.map(version => (
45          <A key={version} style={{ display: 'none' }} href={`/versions/${version}/`} />
46        ))
47      }
48      <select
49        id="version-menu"
50        css={[STYLES_SELECT]}
51        value={version}
52        onChange={e => setVersion(e.target.value)}>
53        {VERSIONS.map(version => (
54          <option key={version} value={version}>
55            {Utilities.getUserFacingVersionString(
56              version,
57              LATEST_VERSION,
58              typeof BETA_VERSION === 'boolean' ? undefined : BETA_VERSION
59            )}
60          </option>
61        ))}
62      </select>
63      <ChevronDownIcon className="icon-sm text-icon-secondary absolute right-3 top-4 pointer-events-none" />
64    </div>
65  );
66};
67