navigation.tsx
概述
书籍分部分导航组件。以卡片网格形式展示书籍的各个部分,支持自定义图标和主题色彩。
组件
BookPartsNav
书籍分部分导航网格组件。
功能特性:
- 响应式网格布局(移动端 1 列,小屏 2 列,大屏 3 列)
- 动态加载本地化书籍部分数据
- 自定义图标支持(使用项目 logo)
- 7 种主题色彩
- 悬停效果
- 无障碍链接
数据来源:
从 locales/*.ts 的 bookParts 字段获取:
interface BookPart {
number: number; // 部分编号(0 为引言)
title: string; // 部分标题
description: string; // 部分描述
customIcon?: boolean; // 是否使用自定义图标
color: string; // 主题颜色
slug: string; // URL 路径
}
图标配置:
内置图标映射(按编号顺序):
| 编号 | 图标 | Lucide 组件 | 用途 |
|---|---|---|---|
| 1 | 指南针 | Compass | 引言 |
| 2 | 设置 | Settings | 第一部分 |
| 3 | 闪电 | Zap | 第二部分 |
| 4 | 目标 | Target | 第三部分 |
| 5 | 宝石 | Gem | 第四部分 |
| 6 | null | - | 第五部分(自定义) |
| 7 | 代码 | Code | 附录 |
自定义图标:
当 customIcon: true 时,显示项目 logo:
- 亮色模式:
/logo.svg - 暗色模式:
/logo-dark.svg
支持的颜色:
| 颜色键 | 背景 | 边框 | 文字 | 悬停 |
|---|---|---|---|---|
| blue | blue-50 | blue-200 | blue-700 | hover:bg-blue-100 |
| purple | purple-50 | purple-200 | purple-700 | hover:bg-purple-100 |
| amber | amber-50 | amber-200 | amber-700 | hover:bg-amber-100 |
| green | green-50 | green-200 | green-700 | hover:bg-green-100 |
| rose | rose-50 | rose-200 | rose-700 | hover:bg-rose-100 |
| cyan | cyan-50 | cyan-200 | cyan-700 | hover:bg-cyan-100 |
| indigo | indigo-50 | indigo-200 | indigo-700 | hover:bg-indigo-100 |
使用示例:
import { BookPartsNav } from "@/components/book/elements/navigation";
export function BookHomePage() {
return (
<div className="container">
<h1>提示工程指南</h1>
<p>选择以下部分开始学习:</p>
<BookPartsNav />
</div>
);
}
本地化数据示例
// locales/zh.ts
export default {
bookParts: [
{
number: 0,
title: "引言",
description: "什么是提示工程以及为什么它很重要",
color: "blue",
slug: "introduction"
},
{
number: 1,
title: "基础",
description: "提示工程的核心概念",
color: "purple",
slug: "part-i-foundations"
},
{
number: 2,
title: "技术",
description: "编写有效提示词的技巧",
color: "amber",
slug: "part-ii-techniques"
},
{
number: 3,
title: "高级",
description: "高级提示工程技术",
color: "green",
slug: "part-iii-advanced"
},
{
number: 4,
title: "最佳实践",
description: "行业最佳实践",
color: "rose",
slug: "part-iv-best-practices"
},
{
number: 5,
title: "用例",
description: "实际应用示例",
color: "cyan",
customIcon: true,
slug: "part-v-use-cases"
},
{
number: 6,
title: "结语",
description: "总结与后续步骤",
color: "indigo",
slug: "part-vi-conclusion"
}
]
} satisfies LocaleData;
视觉样式
卡片样式:
- 内边距:
p-4 - 圆角:
rounded-lg - 边框:1px 实线
- 过渡:
transition-all
图标容器:
- 尺寸:
p-2 rounded-lg - 边框:1px 实线
- 图标大小:
h-5 w-5
文字样式:
- 标题:
font-semibold text-sm - 描述:
text-xs text-muted-foreground - 间距:
mt-0.5
布局:
- 网格:
grid sm:grid-cols-2 lg:grid-cols-3 gap-3 - 最小宽度:
min-w-0(防止溢出)
依赖
| 依赖 | 用途 |
|---|---|
lucide-react | 图标组件(Compass, Settings, Zap, Target, Gem, Code) |
@/lib/utils - cn | 类名合并 |
next-intl - useTranslations, useLocale | 国际化 |
./locales - getLocaleField, BookPart | 本地化数据 |
实现细节
翻译处理:
// 使用 book.interactive 命名空间的 "part" 键
<p className={cn("font-semibold text-sm m-0!", colors.text)}>
{t("part")} {part.number}: {part.title}
</p>
链接处理:
<a
href={`/book/${part.slug}`}
style={{ textDecoration: "none" }} // 去除下划线
className={cn(
"p-4 rounded-lg border transition-all block",
colors.bg,
colors.border,
colors.hover
)}
>
{/* 内容 */}
</a>
自定义图标渲染:
{part.customIcon ? (
<div className="h-5 w-5 flex items-center justify-center">
<img src="/logo.svg" alt="" className="h-5 w-auto dark:hidden" />
<img src="/logo-dark.svg" alt="" className="h-5 w-auto hidden dark:block" />
</div>
) : (
Icon && <Icon className={cn("h-5 w-5", colors.text)} />
)}
响应式行为
| 断点 | 列数 | 说明 |
|---|---|---|
| 默认 (< 640px) | 1 列 | 移动端 |
| sm (≥ 640px) | 2 列 | 小屏平板 |
| lg (≥ 1024px) | 3 列 | 桌面端 |