图标体系
本地 SVG 图标集(z 集合)、UnoCSS 图标配置与图标跟随主题的做法。
UDhold 插件的图标方案是本地 SVG 图标集 + UnoCSS:图标文件放在自己工程里、离线可用、构建时内联、颜色自动跟随主题。这一章给出完整配置与用法。
图标跟随主题的原理
图标加载器会把 SVG 的 fill / stroke 替换成 currentColor:
<!-- 你的 SVG:back.svg -->
<svg fill="#333" ...>...</svg>
<!-- 渲染结果 -->
<svg fill="currentColor" ...>...</svg>
于是图标的颜色 = 所在元素的 color。文字是 var(--ink),图标就是 --ink;放在主色按钮里就是主色;暗色主题自动反色,零额外代码。
工程配置
第一步:SVG 图标放进 src/assets/icons/,文件名即图标名:
src/assets/icons/
├── back.svg
├── copy.svg
└── search.svg
第二步:uno.config.ts 注册图标集:
import { defineConfig, presetAttributify, presetWind3 } from 'unocss'
import presetIcons from '@unocss/preset-icons'
import { FileSystemIconLoader } from '@iconify/utils/lib/loader/node-loaders'
import { fileURLToPath, URL } from 'node:url'
import transformerDirectives from '@unocss/transformer-directives'
export default defineConfig({
presets: [
presetWind3(),
presetAttributify(),
presetIcons({
collections: {
// z 图标集:本插件 src/assets/icons 目录
z: FileSystemIconLoader(
fileURLToPath(new URL('./src/assets/icons', import.meta.url)),
(svg: any) => {
// fill/stroke 替换为 currentColor,跟随主题色
return svg
.replace(/(<svg.*?fill=)"(?!none)(.*?)"/, '$1"currentColor"')
.replace(/(<svg.*?stroke=)"(?!none)(.*?)"/, '$1"currentColor"')
}
)
},
extraProperties: { display: 'inline-block', 'vertical-align': 'middle' }
})
],
transformers: [transformerDirectives()]
})
预设组合说明:
| 预设 | 作用 |
|---|---|
presetWind3 | Tailwind 风格原子类(flex、p-4、text-sm……) |
presetAttributify | 属性化写法(text="sm" 等价 text-sm),按需启用 |
presetIcons | 图标类支持 |
transformerDirectives | 样式块里可用 @apply |
第三步:入口引入虚拟模块(通常脚手架已带):
import 'virtual:uno.css'
使用
类名规则:i-z-{文件名},尺寸用原子类控制:
<span class="i-z-copy w-4 h-4" />
<span class="i-z-search w-5 h-5 text-[var(--ink-2)]" />
<button class="icon-btn"><span class="i-z-back w-4 h-4" /></button>
官方组件库的
DetailPanel 组件内部使用了 i-z-back 图标——使用它的插件,自己的图标集里必须包含 back.svg(文件名一致),否则返回按钮不显示。位图图标的自适应
logo.png、第三方服务的图标等位图没有 currentColor 可言,暗色主题下深色图标会隐形。这种情况用组件库的 AdaptiveIcon 组件:它自动分析图片主色,在暗色模式下给深色图标做反色处理。用法见通用组件。
另外,宿主有一套 udhold-icon: 资源协议用于指令图标;开发态直连 dev server 时需要在 vite.config.ts 里加 CSP 中间件放行该协议——工程模板(见快速上手的 vite 配置)已包含这段配置。
插件 logo 规范
plugin.json 里的 logo 字段(png / jpg,放插件根目录,与 plugin.json 同级):
- 建议正方形、透明底、256×256 以上;
- 它会出现在搜索结果、活动栏、插件中心、任务栏(分离窗口)等多个位置,过于细长的图会被压变形;
- 深色 logo 记得同时准备浅色环境下的表现,或直接用中性色系。