ColorField
color-field颜色输入框 · 紧凑单行:色块(调起系统取色器) + 十六进制文本输入 + 短写自动展开(#abc→#aabbcc) + 草稿态支持手输
用法
受控
value + onValueChange 受控。回调参数恒为规范化后的 #rrggbb —— 输入 #abc 抛出的是 #aabbcc。
#38e8ff
tsx
const [hex, setHex] = useState("#38e8ff");
<ColorField value={hex} onValueChange={setHex} className="w-40" aria-label="主色" />三种尺寸
sm / md / lg,色块随之缩放,与 Input 同一套外壳变体。
tsx
<ColorField size="sm" defaultValue="#38e8ff" className="w-32" />
<ColorField size="md" defaultValue="#7c5cff" className="w-36" />
<ColorField size="lg" defaultValue="#34e8a4" className="w-40" />无色块 / 禁用 / 标红
showSwatch=false 只留文本;输入不可解析的值时组件自己会标红,无需外部传 invalid。
tsx
<ColorField showSwatch={false} defaultValue="#38e8ff" className="w-32" />
<ColorField disabled defaultValue="#6b7d93" className="w-36" />
<ColorField invalid defaultValue="#ff6b6b" className="w-36" />何时用
表单里的一行颜色输入:主题配置表、设计 token 编辑器、图表配色项 —— 已知色值、偶尔微调的场景。
需要完整取色面板(饱和度方块 + HEX/RGB/HSL 格式切换)用 ColorPicker;只从固定几个预设里挑用 ColorSwatchPicker。ColorField 的定位是不抢版面,一行能塞进标签和说明文字旁边。
导入
ts
import { ColorField, normalizeHex, isHexColor } from "@hulianui/ui"Props
继承原生 <input> 属性(size/prefix/value/defaultValue/onChange/type 已被覆盖)。
| 名称 | 类型 | 默认 | 说明 |
|---|---|---|---|
| value | string | — | 受控值。接受 #rgb / #rrggbb / 无 # 写法,内部统一规范为小写 #rrggbb |
| defaultValue | string | "#3b82f6" | 非受控初值 |
| showSwatch | boolean | true | 左侧色块,点开调起系统取色器 |
| size | "sm" | "md" | "lg" | "md" | 尺寸(与 Input 同一套外壳变体,色块随之缩放) |
| invalid | boolean | false | 独立使用时标红;在 hulian Field 内由 Field.Root invalid 自动驱动 |
| disabled | boolean | false | 同时禁用文本框与取色器 |
Events
| 事件 | 类型 | 说明 |
|---|---|---|
| onValueChange | (hex: string) => void | 值变化。参数恒为规范化后的 `#rrggbb`;输入不合法时不触发 |
工具函数
| 函数 | 签名 | 说明 |
|---|---|---|
| normalizeHex | (input: string) => string | null | 规范化成小写 #rrggbb;不可解析返回 null(不抛错、不吐默认色) |
| isHexColor | (input: string) => boolean | 是否可解析(3/6 位,# 可省) |
两个纯函数单独导出:「哪些写法算合法颜色」消费方也要用(比如导入一份主题配置前先校验),不该只活在组件内部。
禁忌 / 坑
- 短写是缩写,不是另一种颜色:
#abc展开成#aabbcc(逐位重复),不是#abc000。normalizeHex已按此实现,自己解析时别写错。 - 不要把 value 直接当 input 的显示值自己实现一遍:受控值经规范化后回灌会让手输在第一个字符就被打回(敲
#3立刻变回原值,根本没法输)。本组件内部维护「草稿态」——键入期间以草稿为准、只在解析成功时抛值、失焦丢草稿归一。扩展/仿写时必须保留这个机制。 onValueChange在输入不合法时不触发,所以它拿到的一定是可用色值;要感知「用户正在敲一个还不合法的值」请监听原生onInput。- 外部传入不可解析的
value时回落到内部值而不是崩,但这是兜底不是契约 —— 受控方应自己保证传合法色。 - 原生
input[type=color]的外观改不动,所以色块是「透明原生 input 铺在 token 着色的 span 上」。别给它加appearance之类的样式,改不动也不生效。
相关
ColorPicker · ColorSwatchPicker · Input · Field · SecretField