Coolify shadcn 技能规则:图标(Icons)使用规范与 iconLibrary 机制详解
【免费下载链接】coolifyAn open-source, self-hostable PaaS alternative to Vercel, Heroku & Netlify that lets you easily deploy static sites, databases, full-stack applications and 280+ one-click services on your own servers.项目地址: https://gitcode.com/GitHub_Trending/co/coolify
Coolify 仓库中面向 AI Agent 的 shadcn/ui 开发技能(.agents/skills/shadcn/)将 UI 编码约定拆解为多份规则文件,其中 rules/icons.md 专门规定了组件库中图标的三条核心纪律:导入来源必须遵循项目配置而非主观假设、图标尺寸交给组件 CSS 处理、图标以组件对象而非字符串键传递。本文完整覆盖这三条规则的判定标准与正误代码对照,并结合 SKILL.md 中iconLibrary字段的定义机制和仓库内的真实配置示例,说明这套规范在 Coolify v5 前端中的落地背景,帮助你写出与 shadcn 组件 CSS 约定完全对齐的图标代码。
一、总则:导入必须来自项目配置的 iconLibrary,禁止假设 lucide-react
规则文件的第一条硬性约定是:
Always use the project's configured
iconLibraryfor imports.Check theiconLibraryfield from project context:lucide→lucide-react,tabler→@tabler/icons-react, etc. Never assumelucide-react.
含义是:写任何图标代码之前,必须先确认项目上下文中的iconLibrary字段,再决定从哪个 npm 包导入图标组件,绝不能默认lucide-react。字段值到导入包名存在固定映射关系,文档明确给出两个例子:
lucide→ 从lucide-react导入;tabler→ 从@tabler/icons-react导入;- 其余值按同样规则推导("etc." 表示映射模式一致)。
1.1 iconLibrary 字段从何而来
在 SKILL.md 的 "Current Project Context" 一节可以看到,该字段由 CLI 命令注入:
npx shadcn@latest info --json其输出 JSON 中包含了项目配置与已安装组件列表,SKILL.md 的 "Key Fields" 一节对iconLibrary的定义与规则文件逐字呼应:
iconLibrary→ determines icon imports. Uselucide-reactforlucide,@tabler/icons-reactfortabler, etc. Never assumelucide-react.
从源码结构看,该技能的工作流(Workflow 第 7 步)进一步要求:凡是npx shadcn@latest add从社区 registry 添加的组件,若其图标导入与项目iconLibrary不一致(例如 registry 项用了lucide-react而项目实际用hugeicons),必须替换导入与图标名称。也就是说,iconLibrary不仅约束自己写的代码,也约束所有从外部注册表拉进来并需要审查的组件文件。
1.2 Coolify v5 的真实示例:iconLibrary 是 phosphor
这条"永不假设 lucide"的规则在 Coolify 仓库里有一个现成的反面教材。v5 前端的 shadcn 配置存档 docs/v5/archive/components.json.txt 显示:
{ "$schema": "https://ui.shadcn.com/schema.json", "style": "base-lyra", "iconLibrary": "phosphor", "tailwind": { "css": "resources/css/v5/app.css", "baseColor": "zinc", "cssVariables": true }, "aliases": { "components": "@/components", "ui": "@/components/ui" } }该项目iconLibrary取值为phosphor,而非lucide。如果开发者按惯性写出import { SearchIcon } from "lucide-react",就违反了图标来源与项目配置一致性的约定。这个存档也顺带印证了components.json是 CLI 的唯一配置来源——cli.md 开篇即声明 "Configuration is read fromcomponents.json",因此iconLibrary的实际取值始终以该文件(或info --json的解析结果)为准。
二、规则一:Button 内的图标使用><Button> <SearchIcon className="mr-2 size-4" /> Search </Button>
错误点有二:一是用mr-2手工控制图标与文字间距,二是用size-4手工控制图标尺寸——这两件事 shadcn 组件的 CSS 都已经处理好了。
正确示例:
<Button> <SearchIcon>// Icons in buttons:><Button> <SearchIcon className="size-4"><Button> <SearchIcon>const iconMap = { check: CheckIcon, alert: AlertIcon, } function StatusBadge({ icon }: { icon: string }) { const Icon = iconMap[icon] return <Icon /> } <StatusBadge icon="check" />正确做法:
// Import from the project's configured iconLibrary (e.g. lucide-react, @tabler/icons-react). import { CheckIcon } from "lucide-react" function StatusBadge({ icon: Icon }: { icon: React.ComponentType }) { return <Icon /> } <StatusBadge icon={CheckIcon} />对照两段代码可以看到差异集中在类型声明:正确写法将 props 类型声明为React.ComponentType,调用处传的是组件引用{CheckIcon}而非字符串"check"。这样做的好处是可调用性、树摇和类型检查都在编译期成立;字符串查表则引入了运行时映射层——图标不存在时静默得到undefined,且查表本身必须与各 iconLibrary 包的具体图标名保持同步,等于把规则第一条(导入来源不固定)的复杂度扩散到了每个查表模块。
五、三条规则在技能体系中的位置与执行闭环
从 SKILL.md 的 "Critical Rules" 一节可以看到,icons.md 与 styling、forms、composition、base-vs-radix 五份规则文件共同构成"始终强制执行"的约束集合,其中图标部分被摘要为三条:
- Icons in
Buttonusedata-icon.data-icon="inline-start"ordata-icon="inline-end"on the icon. - No sizing classes on icons inside components.Components handle icon sizing via CSS. No
size-4orw-4 h-4. - Pass icons as objects, not string keys.
icon={CheckIcon}, not a string lookup.
每条都回链到 rules/icons.md 查看完整的 Incorrect/Correct 代码对。执行闭环则体现在 Workflow 第 7 步:add任何 registry 组件后必须"读回文件并校验",其中明确包含"将图标导入替换为项目iconLibrary对应的包(并相应调整图标名)"这一动作,最后再检查是否违反上述 Critical Rules。换言之,图标规范不是写给人类自觉遵守的建议,而是被写进了 Agent 每次添加组件后的强制审查清单。
六、实操清单:写图标代码前的三个检查项
综合规则文件与 SKILL.md 的上下文机制,在 Coolify v5 这类 shadcn 项目中编写或审查图标相关代码时,可按以下清单自查:
- 查导入来源:运行
npx shadcn@latest info --json(或查看项目components.json),读取iconLibrary字段,按映射关系选择导入包。Coolify v5 存档配置中该字段为phosphor,此时lucide-react的导入即为违规; - 查组件内尺寸类:确认
Button、DropdownMenuItem、Alert、Sidebar*等组件内部的图标没有size-*、w-* h-*类;按钮内前缀/后缀图标改用data-icon="inline-start"/data-icon="inline-end"声明位置; - 查传递方式:组件 props 中接收图标时使用
React.ComponentType类型的组件对象(icon={CheckIcon}),删除字符串键 +iconMap的查表模式。
以上规范均以仓库文件为事实依据:规则本体见 icons.md,iconLibrary字段定义与强制审查流程见 SKILL.md,CLI 配置来源见 cli.md,Coolify v5 的 iconLibrary 取值实例见 components.json.txt。
【免费下载链接】coolifyAn open-source, self-hostable PaaS alternative to Vercel, Heroku & Netlify that lets you easily deploy static sites, databases, full-stack applications and 280+ one-click services on your own servers.项目地址: https://gitcode.com/GitHub_Trending/co/coolify
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考