blob: 05f3eefc1a22e30922cfcc58a67ddc33f3214899 (
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
65
66
67
|
import { useState, type ReactNode } from 'react'
import { useMatches } from 'react-router'
import type { PageMetadata } from '../route-config'
import CollapsedNavigation from './collapsed-navigation'
import { ActionButton } from '@react-spectrum/s2/ActionButton'
import { Tooltip, TooltipTrigger } from '@react-spectrum/s2/Tooltip'
import SidebarMenu from './sidebar-menu'
import MobileNavigation from './mobile-navigation'
import GlobalSettings from './global-settings'
import HomeIcon from '@react-spectrum/s2/icons/Home'
import ChevronLeftIcon from '@react-spectrum/s2/icons/ChevronLeft'
import ChevronRightIcon from '@react-spectrum/s2/icons/ChevronRight'
import styles from './layout-basic.module.css'
interface BasicLayoutProps {
children: ReactNode
}
function BasicLayout({ children }: BasicLayoutProps) {
const [isCollapsed, setIsCollapsed] = useState(false)
const currentPage = useMatches().at(-1)?.handle as PageMetadata | undefined
return (
<div className={`${styles.appLayout}${isCollapsed ? ` ${styles.isCollapsed}` : ''}`}>
<a className={styles.skipLink} href="#main-content">Skip to content</a>
<aside id="sidebar" className={styles.sidebar} aria-label="Sidebar">
<div className={styles.sidebarBrand} aria-label="React Spectrum">
{isCollapsed ? <HomeIcon /> : 'React Spectrum'}
</div>
<nav className={styles.sidebarNavigation} aria-label="Main navigation">
{isCollapsed && <CollapsedNavigation activePageId={currentPage?.id} />}
<div className={styles.expandedNavigation} hidden={isCollapsed}>
<SidebarMenu />
</div>
</nav>
</aside>
<div className={styles.contentLayout}>
<header className={styles.topbar}>
<MobileNavigation />
<div className={styles.desktopMenuToggle}>
<TooltipTrigger>
<ActionButton
aria-label={isCollapsed ? 'Expand sidebar' : 'Collapse sidebar'}
aria-expanded={!isCollapsed}
aria-controls="sidebar"
isQuiet
onPress={() => setIsCollapsed((collapsed) => !collapsed)}
>
{isCollapsed ? <ChevronRightIcon /> : <ChevronLeftIcon />}
</ActionButton>
<Tooltip>{isCollapsed ? 'Expand sidebar' : 'Collapse sidebar'}</Tooltip>
</TooltipTrigger>
</div>
<span>{currentPage?.title}</span>
<div className={styles.topbarActions}>
<GlobalSettings />
</div>
</header>
<main id="main-content" className={styles.pageContent} tabIndex={-1}>
{children}
</main>
</div>
</div>
)
}
export default BasicLayout
|