ThemeSwitcher.tsx101 lines · main
| 1 | import { |
| 2 | PageType, |
| 3 | useRegisterCommands, |
| 4 | useRegisterPage, |
| 5 | useSetCommandMenuOpen, |
| 6 | useSetPage, |
| 7 | type CommandOptions, |
| 8 | } from '..' |
| 9 | import { Monitor, MonitorDot, Moon, Sun } from 'lucide-react' |
| 10 | import { useTheme } from 'next-themes' |
| 11 | import { themes } from 'ui/src/components/ThemeProvider/themes' |
| 12 | |
| 13 | const THEME_SWITCHER_PAGE_NAME = 'Switch theme' |
| 14 | |
| 15 | const useThemeSwitcherCommands = ({ options }: { options?: CommandOptions } = {}) => { |
| 16 | const setIsOpen = useSetCommandMenuOpen() |
| 17 | const setPage = useSetPage() |
| 18 | |
| 19 | const { resolvedTheme, setTheme } = useTheme() |
| 20 | |
| 21 | const applyTheme = (theme: string) => { |
| 22 | setTheme(theme) |
| 23 | setIsOpen(false) |
| 24 | } |
| 25 | |
| 26 | useRegisterPage(THEME_SWITCHER_PAGE_NAME, { |
| 27 | type: PageType.Commands, |
| 28 | sections: [ |
| 29 | { |
| 30 | id: 'switch-theme', |
| 31 | name: 'Switch theme', |
| 32 | commands: themes |
| 33 | .filter(({ name }) => name === 'System' || name === 'Light' || name === 'Dark') |
| 34 | .map((theme) => ({ |
| 35 | id: `switch-theme-${theme.value}`, |
| 36 | name: theme.name, |
| 37 | value: |
| 38 | theme.name === 'System' |
| 39 | ? 'System theme, Follow system appearance' |
| 40 | : theme.name === 'Light' |
| 41 | ? 'Light theme, Light mode' |
| 42 | : 'Dark theme, Dark mode', |
| 43 | action: () => applyTheme(theme.value), |
| 44 | icon: () => |
| 45 | theme.name === 'System' ? <Monitor /> : theme.name === 'Light' ? <Sun /> : <Moon />, |
| 46 | })), |
| 47 | }, |
| 48 | ], |
| 49 | }) |
| 50 | |
| 51 | useRegisterCommands( |
| 52 | 'Theme', |
| 53 | [ |
| 54 | { |
| 55 | id: 'toggle-theme', |
| 56 | name: 'Toggle theme', |
| 57 | value: |
| 58 | 'Toggle theme, Toggle dark mode, Toggle light mode, Theme toggle, Dark mode, Light mode', |
| 59 | action: () => applyTheme(resolvedTheme === 'dark' ? 'light' : 'dark'), |
| 60 | defaultHidden: true, |
| 61 | icon: () => <MonitorDot />, |
| 62 | }, |
| 63 | { |
| 64 | id: 'set-theme-dark', |
| 65 | name: 'Use dark theme', |
| 66 | value: 'Dark theme, Dark mode, Switch to dark theme, Set theme dark', |
| 67 | action: () => applyTheme('dark'), |
| 68 | defaultHidden: true, |
| 69 | icon: () => <Moon />, |
| 70 | }, |
| 71 | { |
| 72 | id: 'set-theme-light', |
| 73 | name: 'Use light theme', |
| 74 | value: 'Light theme, Light mode, Switch to light theme, Set theme light', |
| 75 | action: () => applyTheme('light'), |
| 76 | defaultHidden: true, |
| 77 | icon: () => <Sun />, |
| 78 | }, |
| 79 | { |
| 80 | id: 'set-theme-system', |
| 81 | name: 'Use system theme', |
| 82 | value: 'System theme, Follow system theme, Auto theme, Match system appearance', |
| 83 | action: () => applyTheme('system'), |
| 84 | defaultHidden: true, |
| 85 | icon: () => <Monitor />, |
| 86 | }, |
| 87 | { |
| 88 | id: 'switch-theme', |
| 89 | name: 'Switch theme...', |
| 90 | value: |
| 91 | 'Theme, Switch theme, Change theme, Appearance, Color mode, Dark mode, Light mode, Toggle theme', |
| 92 | action: () => setPage(THEME_SWITCHER_PAGE_NAME), |
| 93 | defaultHidden: true, |
| 94 | icon: () => <MonitorDot />, |
| 95 | }, |
| 96 | ], |
| 97 | { ...options, deps: [...(options?.deps ?? []), resolvedTheme] } |
| 98 | ) |
| 99 | } |
| 100 | |
| 101 | export { useThemeSwitcherCommands } |