Files
writer-work-flow/apps/web/components/AppShell.tsx
Yaojia Wang 8779530806 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。
2026-06-20 18:19:46 +02:00

69 lines
2.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Link from "next/link";
import type { ReactNode } from "react";
import type { ActiveNav } from "@/lib/nav/items";
import { AiToolbar } from "./AiToolbar";
import { LeftNav } from "./LeftNav";
import { NavDrawer } from "./NavDrawer";
interface AppShellProps {
children: ReactNode;
// 顶栏右侧的上下文信息(如作品名 / 进度)。
title?: string;
subtitle?: string;
// 项目内页给出 projectId → 左导航展开项目级入口(大纲/伏笔/审稿UX §3.1)。
projectId?: string;
// 当前激活的项目级入口键(用于高亮)。
activeNav?: ActiveNav;
}
// 全局外壳:顶栏(64px) + 左导航 + 主区UX §5.1)。
export function AppShell({
children,
title,
subtitle,
projectId,
activeNav,
}: AppShellProps) {
return (
<div
className="min-h-screen"
style={{ ["--chrome" as string]: projectId ? "7rem" : "4rem" }}
>
<header className="flex h-16 items-center gap-4 border-b border-line bg-panel px-4 sm:px-6">
<NavDrawer projectId={projectId} activeNav={activeNav} />
<Link
href="/"
className="font-serif text-xl text-cinnabar"
aria-label="返回作品库"
>
</Link>
{title ? (
<span className="font-serif text-lg text-ink">{title}</span>
) : null}
{subtitle ? (
<span className="font-mono text-xs text-ink-soft">{subtitle}</span>
) : null}
<nav className="ml-auto flex items-center gap-4 text-sm">
<Link
href="/settings/providers"
className="text-ink-soft hover:text-cinnabar"
>
</Link>
</nav>
</header>
{projectId ? (
<AiToolbar projectId={projectId} activeNav={activeNav} />
) : null}
<div className="flex">
<LeftNav projectId={projectId} activeNav={activeNav} />
<main className="min-h-[calc(100vh-var(--chrome,4rem))] flex-1 bg-bg">
{children}
</main>
</div>
</div>
);
}