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