1import { css } from '@emotion/react';
2import { useTheme, theme, shadows, typography } from '@expo/styleguide';
3import { borderRadius, breakpoints, spacing } from '@expo/styleguide-base';
4import {
5  ChevronDownIcon,
6  Moon01SolidIcon,
7  SunSolidIcon,
8  Contrast02SolidIcon,
9} from '@expo/styleguide-icons';
10import { useEffect, useState } from 'react';
11
12export const ThemeSelector = () => {
13  const { themeName, setAutoMode, setDarkMode, setLightMode } = useTheme();
14  const [isLoaded, setLoaded] = useState(false);
15
16  useEffect(function didMount() {
17    setLoaded(true);
18  }, []);
19
20  if (!isLoaded) return <div css={containerStyle} />;
21
22  return (
23    <div css={containerStyle}>
24      <select
25        aria-label="Theme selector"
26        title="Select theme"
27        css={selectStyle}
28        value={themeName}
29        onChange={e => {
30          const option = e.target.value;
31          if (option === 'auto') setAutoMode();
32          if (option === 'dark') setDarkMode();
33          if (option === 'light') setLightMode();
34        }}>
35        <option value="auto">Auto</option>
36        <option value="light">Light</option>
37        <option value="dark">Dark</option>
38      </select>
39      <div css={selectIconStyle}>
40        {themeName === 'auto' && <Contrast02SolidIcon className="icon-sm text-icon-default" />}
41        {themeName === 'dark' && <Moon01SolidIcon className="icon-sm text-icon-default" />}
42        {themeName === 'light' && <SunSolidIcon className="icon-sm text-icon-default" />}
43      </div>
44      <ChevronDownIcon className="icon-xs text-icon-secondary absolute right-2 top-3 pointer-events-none" />
45    </div>
46  );
47};
48
49const containerStyle = css`
50  position: relative;
51`;
52
53const selectStyle = css`
54  ${typography.fontSizes[14]}
55  display: flex;
56  align-items: center;
57  justify-content: center;
58  height: 36px;
59  color: ${theme.text.default};
60  line-height: 1.3;
61  padding: 0;
62  width: 50px;
63  margin: 0;
64  border: 1px solid ${theme.border.default};
65  box-shadow: ${shadows.xs};
66  border-radius: ${borderRadius.md}px;
67  -moz-appearance: none;
68  -webkit-appearance: none;
69  appearance: none;
70  background-color: ${theme.background.default};
71  cursor: pointer;
72  text-indent: -9999px;
73
74  @media screen and (max-width: ${(breakpoints.medium + breakpoints.large) / 2}px) {
75    width: auto;
76    min-width: 100px;
77    padding: 0 ${spacing[2]}px;
78    padding-left: ${spacing[8]}px;
79    color: ${theme.text.secondary};
80    text-indent: 0;
81  }
82`;
83
84const selectIconStyle = css`
85  position: absolute;
86  left: 10px;
87  top: 10px;
88  pointer-events: none;
89`;
90