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