blob: abf4f24fa77b654c0ff15c78f809a20751e7014b (
plain)
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
|
import styles from './mobile-navigation.module.css'
import { useEffect, useRef, useState } from 'react'
import { useLocation } from 'react-router'
import { ActionButton } from '@react-spectrum/s2/ActionButton'
import CloseIcon from '@react-spectrum/s2/icons/Close'
import ViewListIcon from '@react-spectrum/s2/icons/ViewList'
import SidebarMenu from './sidebar-menu'
function MobileNavigation() {
const dialogRef = useRef<HTMLDialogElement>(null)
const [isOpen, setIsOpen] = useState(false)
const { key } = useLocation()
// Close after all route changes, including selecting the current page.
useEffect(() => {
dialogRef.current?.close()
}, [key])
useEffect(() => {
const media = window.matchMedia('(max-width: 640px)')
const closeOnDesktop = () => {
if (!media.matches) dialogRef.current?.close()
}
media.addEventListener('change', closeOnDesktop)
return () => media.removeEventListener('change', closeOnDesktop)
}, [])
return (
<div className={styles.mobileMenuToggle}>
<ActionButton
aria-label="打开菜单"
aria-haspopup="dialog"
aria-expanded={isOpen}
aria-controls="mobile-navigation"
isQuiet
onPress={() => {
dialogRef.current?.showModal()
setIsOpen(true)
}}
>
<ViewListIcon />
</ActionButton>
<dialog
ref={dialogRef}
id="mobile-navigation"
className={styles.mobileNavigation}
aria-labelledby="mobile-navigation-title"
onClose={() => setIsOpen(false)}
>
<header className={styles.mobileNavigationHeader}>
<span id="mobile-navigation-title">菜单</span>
<ActionButton aria-label="关闭菜单" isQuiet onPress={() => dialogRef.current?.close()}>
<CloseIcon />
</ActionButton>
</header>
<nav className={styles.mobileNavigationContent} aria-label="页面导航">
<SidebarMenu />
</nav>
</dialog>
</div>
)
}
export default MobileNavigation
|