feat(ux): T4-a 全局 AI 工具条 — 项目页顶部常驻写本章/审稿/大纲/设定库/工具箱
新 lib/nav/ai-tools.ts (aiToolItems) + components/AiToolbar.tsx 服务端组件;AppShell 顶栏下渲染(仅项目页),用 --chrome CSS 变量统一 chrome 高度,6 个固定高度页改用 calc(100vh-var(--chrome,4rem)) 适配。TDD: ai-tools 测。前端门禁绿: lint/tsc/vitest/build。
This commit is contained in:
48
apps/web/components/AiToolbar.tsx
Normal file
48
apps/web/components/AiToolbar.tsx
Normal file
@@ -0,0 +1,48 @@
|
||||
import Link from "next/link";
|
||||
|
||||
import { aiToolItems } from "@/lib/nav/ai-tools";
|
||||
import type { ActiveNav } from "@/lib/nav/items";
|
||||
|
||||
interface AiToolbarProps {
|
||||
projectId: string;
|
||||
activeNav?: ActiveNav;
|
||||
}
|
||||
|
||||
// T4-a · 项目内页常驻 AI 工具条(顶栏下,UX §3/§5)。
|
||||
// 纯链接服务端组件:写本章=朱砂主动作,其余次级;激活项朱砂高亮。窄屏横向滚动。
|
||||
export function AiToolbar({ projectId, activeNav }: AiToolbarProps) {
|
||||
return (
|
||||
<nav
|
||||
aria-label="AI 工具条"
|
||||
className="flex h-12 items-center gap-2 overflow-x-auto whitespace-nowrap border-b border-line bg-panel px-4 sm:px-6"
|
||||
>
|
||||
{aiToolItems(projectId).map((item) => {
|
||||
const isActive = item.key === activeNav;
|
||||
const className = toolClassName(item.primary === true, isActive);
|
||||
return (
|
||||
<Link
|
||||
key={item.href}
|
||||
href={item.href}
|
||||
aria-current={isActive ? "page" : undefined}
|
||||
className={className}
|
||||
>
|
||||
<span aria-hidden="true">{item.glyph}</span>
|
||||
<span>{item.label}</span>
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
|
||||
function toolClassName(isPrimary: boolean, isActive: boolean): string {
|
||||
const base =
|
||||
"flex items-center gap-1.5 rounded border px-3 py-1.5 text-sm transition-colors";
|
||||
if (isActive) {
|
||||
return `${base} border-cinnabar text-cinnabar`;
|
||||
}
|
||||
if (isPrimary) {
|
||||
return `${base} border-cinnabar bg-cinnabar text-panel hover:border-cinnabar`;
|
||||
}
|
||||
return `${base} border-line text-ink-soft hover:border-cinnabar hover:text-cinnabar`;
|
||||
}
|
||||
Reference in New Issue
Block a user