ThemeSwitcher.tsx101 lines · main
1import {
2 PageType,
3 useRegisterCommands,
4 useRegisterPage,
5 useSetCommandMenuOpen,
6 useSetPage,
7 type CommandOptions,
8} from '..'
9import { Monitor, MonitorDot, Moon, Sun } from 'lucide-react'
10import { useTheme } from 'next-themes'
11import { themes } from 'ui/src/components/ThemeProvider/themes'
12
13const THEME_SWITCHER_PAGE_NAME = 'Switch theme'
14
15const 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
101export { useThemeSwitcherCommands }