src/components/ui/mode-toggle.tsx (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
import { Button } from '@/components/ui/button' import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu' import { Laptop, Moon, Sun } from 'lucide-react' import * as React from 'react' export function ModeToggle() { const [theme, setThemeState] = React.useState< 'theme-light' | 'dark' | 'system' >('theme-light') React.useEffect(() => { const isDarkMode = document.documentElement.classList.contains('dark') setThemeState(isDarkMode ? 'dark' : 'theme-light') }, []) React.useEffect(() => { const isDark = theme === 'dark' || (theme === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches) document.documentElement.classList.add('disable-transitions') document.documentElement.classList[isDark ? 'add' : 'remove']('dark') window .getComputedStyle(document.documentElement) .getPropertyValue('opacity') requestAnimationFrame(() => { document.documentElement.classList.remove('disable-transitions') }) }, [theme]) return ( <DropdownMenu modal={false}> <DropdownMenuTrigger asChild> <Button variant="outline" size="icon" className="group" title="Toggle theme" > <Sun className="size-4 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" /> <Moon className="absolute size-4 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" /> <span className="sr-only">Toggle theme</span> </Button> </DropdownMenuTrigger> <DropdownMenuContent align="end" className="bg-background"> <DropdownMenuItem onClick={() => setThemeState('theme-light')}> <Sun className="mr-2 size-4" /> <span>Light</span> </DropdownMenuItem> <DropdownMenuItem onClick={() => setThemeState('dark')}> <Moon className="mr-2 size-4" /> <span>Dark</span> </DropdownMenuItem> <DropdownMenuItem onClick={() => setThemeState('system')}> <Laptop className="mr-2 size-4" /> <span>System</span> </DropdownMenuItem> </DropdownMenuContent> </DropdownMenu> ) } |