forked from CaliCastle/cali.so
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ThemeSwitcher.tsx
72 lines (65 loc) · 2.19 KB
/
ThemeSwitcher.tsx
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
71
72
'use client'
import { AnimatePresence, motion } from 'framer-motion'
import { useTheme } from 'next-themes'
import React from 'react'
import { LightningIcon, MoonIcon, SunIcon } from '~/assets'
import { Tooltip } from '~/components/ui/Tooltip'
const themes = [
{
label: '浅色模式',
value: 'light',
icon: SunIcon,
},
{
label: '深色模式',
value: 'dark',
icon: MoonIcon,
},
]
export function ThemeSwitcher() {
const [mounted, setMounted] = React.useState(false)
const [open, setOpen] = React.useState(false)
const { setTheme, theme, resolvedTheme } = useTheme()
const ThemeIcon = React.useMemo(
() => themes.find((t) => t.value === theme)?.icon ?? LightningIcon,
[theme]
)
React.useEffect(() => setMounted(true), [])
function toggleTheme() {
setTheme(resolvedTheme === 'dark' ? 'light' : 'dark')
}
if (!mounted) {
return null
}
return (
<Tooltip.Provider disableHoverableContent>
<Tooltip.Root open={open} onOpenChange={setOpen}>
<Tooltip.Trigger asChild>
<button
type="button"
aria-label="切换颜色主题"
className="group rounded-full bg-gradient-to-b from-zinc-50/50 to-white/90 px-3 py-2 shadow-lg shadow-zinc-800/5 ring-1 ring-zinc-900/5 backdrop-blur transition dark:from-zinc-900/50 dark:to-zinc-800/90 dark:ring-white/10 dark:hover:ring-white/20"
onClick={toggleTheme}
>
<ThemeIcon className="h-6 w-6 stroke-zinc-500 p-0.5 transition group-hover:stroke-zinc-700 dark:group-hover:stroke-zinc-200" />
</button>
</Tooltip.Trigger>
<AnimatePresence>
{open && (
<Tooltip.Portal forceMount>
<Tooltip.Content asChild>
<motion.div
initial={{ opacity: 0, scale: 0.96 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.95 }}
>
{themes.find((t) => t.value === theme)?.label || "系统模式"}
</motion.div>
</Tooltip.Content>
</Tooltip.Portal>
)}
</AnimatePresence>
</Tooltip.Root>
</Tooltip.Provider>
)
}