🎨 用一次就爱上的图标定制体验:CustomIcons 实战
在前端项目里,图标不是“点缀”,它往往是信息结构与互动线索的关键。如何让图标既统一又可配、既美观又可国际化?这篇文章带你用
@infinilabs/custom-icons打造一套“可配置、可主题、可国际化”的图标解决方案。
背景
- Coco AI(开源) 用户需要可以配置自定义 Icon。
- 多品牌与多区域:同一产品在不同客户、不同区域需要差异化的风格与语言。
- 设计与工程协作:设计希望图标统一;工程需要灵活调整尺寸、颜色、类型、甚至自定义图片。
- 运营与配置:希望在管理面板里直接挑选或调整图标,而不是改代码、发版本。
于是,我做了一个轻量、直观、开箱即用的组件库:@infinilabs/custom-icons。
适用场景
- 可视化配置台:在后台面板中为功能、菜单或模块选择与配置图标。
- 多主题产品:快速切换深色/浅色主题,保证图标在不同背景下的对比度与风格。
- 国际化应用:在不同语言环境下自动切换文案与控件标签。
- 自定义品牌:支持上传自定义图片作为图标,满足品牌个性化需求。
主要能力
- 图标渲染组件:
ConfigurableIcon- 指定类型(如
lucide)、图标名、颜色与尺寸即可渲染。 - 支持数据 URL(自定义图片)模式。
- 指定类型(如
- 图标选择器:
IconPicker- 一站式选择与配置:类型、名称、尺寸、颜色与图片上传。
- 可选主题与国际化支持。
- 可通过
controls精细开关各子控件。
快速开始
# 使用你熟悉的包管理器安装
pnpm add @infinilabs/custom-icons
# 或
npm i @infinilabs/custom-icons
# 或
yarn add @infinilabs/custom-icons
在项目中引用:
import { useState } from "react";
import { ConfigurableIcon, IconPicker } from "@infinilabs/custom-icons";
export default function Demo() {
const [config, setConfig] = useState({
type: "lucide",
name: "Bot",
size: 28,
color: "#1e90ff",
dataUrl: undefined,
});
return (
<div style={{ padding: 24 }}>
{/* 渲染当前配置的图标 */}
<ConfigurableIcon
type={config.type}
name={config.name}
size={config.size}
color={config.color}
dataUrl={config.dataUrl}
/>
{/* 交互式选择与配置 */}
<IconPicker
value={config}
onChange={setConfig}
configurable
theme="light"
locale="zh-CN"
controls={{
type: true,
name: true,
size: true,
color: true,
image: true,
}}
/>
</div>
);
}
如果你需要查看可选的 Lucide 图标名称,选择器旁已内置快捷链接:
基础效果
![]()
组件详解
ConfigurableIcon
用于在任意位置渲染一个图标。
- 关键属性
-
type: 图标类型(如lucide或自定义) -
name: 图标名称(type=lucide时为 Lucide 名称) -
size: 数值尺寸(px) -
color: 颜色(十六进制或 CSS 颜色) -
dataUrl: 当使用自定义图片时的data:URL
-
示例(自定义图片):
<ConfigurableIcon
type="custom"
name="my-logo"
dataUrl="data:image/png;base64,...."
size={28}
color="#1e90ff" // 自定义图片时通常忽略颜色
/>
IconPicker
一个将预览与配置控件整合在一起的选择器。可插在设置面板或表单中,让用户自行挑选或上传。
-
常用属性
-
value: 当前图标配置对象 -
onChange(next): 配置变化回调 -
configurable: 是否展示配置面板 -
controls: 控件开关集合(type/name/size/color/image等) -
theme:light | dark -
locale:zh-CN | en-US -
i18n: 文案对象(可覆盖默认文案)
-
-
控件开关示例
<IconPicker
value={config}
onChange={setConfig}
configurable
controls={{
type: true,
name: true,
size: true,
color: true,
image: true, // 打开即出现上传控件
}}
/>
- 主题与国际化
<IconPicker
value={config}
onChange={setConfig}
configurable
theme="dark"
locale="en-US"
/>
进阶示例:面板内批量配置
将多个图标配置成一组,供菜单或卡片模块统一管理:
function IconsPanel() {
const [items, setItems] = useState([
{ id: 1, config: { type: "lucide", name: "Home", size: 24, color: "#444" } },
{ id: 2, config: { type: "lucide", name: "Settings", size: 24, color: "#444" } },
]);
const updateItem = (id, next) =>
setItems((prev) =>
prev.map((it) => (it.id === id ? { ...it, config: next } : it))
);
return (
<div style={{ display: "grid", gap: 16 }}>
{items.map((it) => (
<div key={it.id} style={{ padding: 12, border: "1px solid #eee", borderRadius: 8 }}>
<ConfigurableIcon {...it.config} />
<IconPicker
value={it.config}
onChange={(next) => updateItem(it.id, next)}
configurable
theme="light"
locale="zh-CN"
controls={{ type: true, name: true, size: true, color: true, image: false }}
/>
</div>
))}
</div>
);
}
设计与工程协作建议
- 设计提供命名规范:例如统一使用 Lucide 的图标名集合,避免随意命名。
- 管理面板适配:通过
controls开关不同角色看到的控件(运营只改颜色与大小、开发可修改类型与名称)。 - 主题变量托管:将颜色与尺寸作为“设计令牌”,统一管理与回收。
常见问题
- 自定义图片会应用颜色吗?
- 通常不会;颜色更适用于矢量图标。自定义图片由图片本身决定视觉。
- 如何选择 Lucide 图标名?
- 打开
https://lucide.dev/icons/,在选择器里输入对应名称即可。
- 打开
![]()
小结
@infinilabs/custom-icons 让“图标即配置”的能力落地:从主题与国际化,到自定义图片与统一风格,既能保证设计一致性,又给予业务足够自由度。把它接入你的管理面板或设置页,让图标成为产品的强大表达力,而不是维护负担。
如果你对更多场景(如基于角色的控件可见性、图标库扩展)有想法,欢迎继续交流与共建!