图标体系

本地 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()]
})

预设组合说明:

预设作用
presetWind3Tailwind 风格原子类(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 记得同时准备浅色环境下的表现,或直接用中性色系。