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
73
|
import { useRef } from 'react'
import {
ActionIcon, Drawer, SegmentedControl, Stack, Text, Tooltip,
useMantineColorScheme, useMatches,
} from '@mantine/core'
import { GearIcon } from '@phosphor-icons/react'
import { useNavigate, useSearchParams } from 'react-router'
import classes from './SiteSettings.module.css'
export function SiteSettings() {
const { colorScheme, setColorScheme } = useMantineColorScheme()
const size = useMatches({ base: '100%', sm: 'sm' })
const [searchParams, setSearchParams] = useSearchParams()
const navigate = useNavigate()
const openedHere = useRef(false)
const opened = searchParams.get('settings') === 'appearance'
function open() {
if (opened) return
openedHere.current = true
setSearchParams((previous) => {
const next = new URLSearchParams(previous)
next.set('settings', 'appearance')
return next
}, { preventScrollReset: true })
}
function close() {
if (openedHere.current) {
openedHere.current = false
void navigate(-1)
return
}
// 直接访问或刷新设置链接时,关闭抽屉不应离开当前页面。
setSearchParams((previous) => {
const next = new URLSearchParams(previous)
next.delete('settings')
return next
}, { replace: true, preventScrollReset: true })
}
return (
<>
<Tooltip label="网站设置" events={{ hover: true, focus: true, touch: false }}>
<ActionIcon className={classes.trigger} variant="subtle" color="gray" size="xl"
aria-label="打开网站设置" aria-haspopup="dialog" aria-expanded={opened} onClick={open}>
<GearIcon size={22} aria-hidden="true" />
</ActionIcon>
</Tooltip>
<Drawer opened={opened} onClose={close} title="网站设置" position="right" size={size}
closeButtonProps={{ 'aria-label': '关闭网站设置', size: 'lg' }}
classNames={{ header: classes.header, body: classes.body }}>
<Stack gap="md">
<Text id="site-color-scheme-label" fw={600}>外观模式</Text>
<SegmentedControl
aria-labelledby="site-color-scheme-label"
value={colorScheme}
data={[
{ value: 'light', label: '亮色' },
{ value: 'dark', label: '暗色' },
{ value: 'auto', label: '跟随系统' },
]}
onChange={(value) => {
if (value === 'light' || value === 'dark' || value === 'auto') setColorScheme(value)
}}
/>
<Text size="sm" c="dimmed">设置即时生效并自动保存。选择“跟随系统”时,外观随设备主题变化。</Text>
</Stack>
</Drawer>
</>
)
}
|