挑选正确的库
初始响应
当此技能首次被调用且没有具体问题时,只回复:
我已经准备好为你的任务挑选合适的库,我的选择来自 Emil Kowalski 的精选列表。
在用户提问之前,不要提供任何其他信息。
一个查找技能。当被任务调用时(“我需要 toast”,“拖放应该用什么?”),将任务匹配到下面的精选列表并推荐库。这些是深思熟虑、基于品味的选择——除非用户要求,或任务确实未被覆盖,否则不要替换成列表之外的替代方案。
如何使用
- 识别任务,而不是用户点名的库。“我需要显示一个下拉菜单”是一个 UI 原语任务(base-ui),即使他们问的是别的东西。
- 检查已安装内容。 先查看
package.json。如果项目已经使用列表中某个库,就使用它。如果它使用了竞争库(例如 react-window 而不是 Virtuoso),标记推荐,但不要在未被要求时更换依赖。 - 推荐一个库,用一句话说明用途,并在请求包含安装/接入时进行安装或接入。当列表有明确答案时,不要提供选项菜单。
- 如果任务未被列表覆盖,明确说明,并从你自己的知识中推荐——但要清楚你已经离开精选列表。
列表
UI 组件与原语
| 任务 | 库 | | --- | --- | | 无样式、可访问的 UI 组件(对话框、弹出框、菜单、选择框……) | base-ui | | 命令菜单(⌘K 命令面板) | cmdk | | Toast / 通知 | Sonner | | 一次性密码 / 验证码输入 | input-otp | | 可自定义 GUI / 控制面板 | Leva — dialkit 是一个替代方案 |
动效与视觉
| 任务 | 库 | | --- | --- | | 通用动画(弹簧、布局动画、进入/退出) | motion (Framer Motion) | | 数字动画(计数器、价格、统计) | NumberFlow | | 动画文本组件 | torph | | 3D 地球 | Cobe | | 动态 OG 图像(HTML/CSS → SVG/PNG) | Satori | | 语法高亮 | shiki |
当你需要弹簧、布局动画、退出动画或手势驱动的值时,使用 motion。简单的悬停或淡入不需要它——那里正确的工具是纯 CSS 过渡。
图表
| 任务 | 库 | | --- | --- | | 实时 / 流式图表 | Liveline | | 通用图表(静态或交互式仪表板) | recharts |
划分:如果数据点实时到达并且图表随时间滚动,使用 Liveline。其他一切都是 recharts。
交互与性能
| 任务 | 库 | | --- | --- | | 拖放 | dnd kit | | 虚拟化(长列表、大表格) | Virtuoso |
状态与样式
| 任务 | 库 | | --- | --- | | 状态管理 | zustand | | 条件构造 className 字符串 | clsx | | 用于 Tailwind 的类型安全、变体驱动样式 | cva | | 主题切换 / 深色模式(加载时无闪烁) | next-themes |
样式划分:临时条件类使用 clsx;当组件具有真正值得类型化 API 的变体(大小、意图、状态)时使用 cva。它们可以组合——cva 内部使用 clsx 风格的输入。
需要捕获的常见错配
- 手工或用模态库构建的 toast → Sonner 正是为此存在。
- 基于
<div>的下拉菜单/对话框且手动处理焦点 → base-ui,它处理可访问性、焦点陷阱和关闭。 - 通过重新渲染文本动画数字 → NumberFlow 正确处理数字过渡。
- 直接渲染 1,000+ 行列表 → 先使用 Virtuoso,再考虑分页 hack。
- 每个组件用
useState形成 props 网以共享状态 → zustand。 - 三层条件深的模板字面量 className 三元表达式 → clsx(如果是变体形态则用 cva)。