NavDrawer 汉堡按钮补 aria-controls 指向抽屉面板(Drawer 新增可选 id prop,默认 nav-drawer);ForeshadowCard 的 <dl> 裸 <div> 行改真 <dt>/<dd> 结构,可视文案不变,importance 用 sr-only 标签。行为不变。
75 lines
2.2 KiB
TypeScript
75 lines
2.2 KiB
TypeScript
"use client";
|
||
|
||
import { useRef, useState } from "react";
|
||
import { Menu, Search } from "lucide-react";
|
||
|
||
import { Button } from "@/components/ui/Button";
|
||
import { openCommandPalette } from "@/components/command/CommandPalette";
|
||
import type { ActiveNav } from "@/lib/nav/items";
|
||
import { focusRing } from "@/lib/ui/variants";
|
||
import { Drawer } from "./Drawer";
|
||
import { NavItems } from "./NavItems";
|
||
|
||
interface NavDrawerProps {
|
||
projectId?: string;
|
||
activeNav?: ActiveNav;
|
||
}
|
||
|
||
// 抽屉面板 id:供汉堡按钮 aria-controls 关联(无障碍)。
|
||
const DRAWER_ID = "nav-drawer";
|
||
|
||
// 移动端导航:汉堡按钮 + 左侧抽屉(仅 <lg;桌面用 LeftNav 静态侧栏)。UX §5.1。
|
||
export function NavDrawer({ projectId, activeNav }: NavDrawerProps) {
|
||
const [open, setOpen] = useState(false);
|
||
const triggerRef = useRef<HTMLButtonElement>(null);
|
||
|
||
const openSearch = (): void => {
|
||
setOpen(false);
|
||
openCommandPalette();
|
||
};
|
||
|
||
return (
|
||
<>
|
||
<Button
|
||
ref={triggerRef}
|
||
onClick={() => setOpen(true)}
|
||
aria-label="打开导航"
|
||
aria-expanded={open}
|
||
aria-controls={DRAWER_ID}
|
||
variant="ghost"
|
||
size="icon"
|
||
className="-ml-2 lg:hidden"
|
||
>
|
||
<Menu className="h-5 w-5" aria-hidden="true" />
|
||
</Button>
|
||
<Drawer
|
||
open={open}
|
||
onClose={() => setOpen(false)}
|
||
side="left"
|
||
label="主导航"
|
||
id={DRAWER_ID}
|
||
triggerRef={triggerRef}
|
||
>
|
||
<div className="px-2 pb-2">
|
||
<button
|
||
type="button"
|
||
onClick={openSearch}
|
||
className={`flex w-full items-center gap-2 rounded border border-line bg-bg px-3 py-2 text-sm text-ink-soft transition-colors hover:text-cinnabar ${focusRing}`}
|
||
>
|
||
<Search className="h-4 w-4 shrink-0" aria-hidden="true" />
|
||
搜索命令或页面
|
||
<kbd className="ml-auto rounded border border-line bg-panel px-1 font-mono text-2xs">
|
||
⌘K
|
||
</kbd>
|
||
</button>
|
||
</div>
|
||
<NavItems
|
||
projectId={projectId}
|
||
activeNav={activeNav}
|
||
onNavigate={() => setOpen(false)}
|
||
/>
|
||
</Drawer>
|
||
</>
|
||
);
|
||
}
|