生态产品多个设计器现已发布候选版本

查看生态总览
跳转到内容

ColorField 颜色字段 ​

可以手动输入颜色串的单行框,旁边显示当前颜色的色块。框内文字是草稿,回车或失焦时提交,提交后按 format 重写为规范写法。它属于文本字段家族,面向已知颜色值直接输入的场景;需要在色域中挑选时使用颜色选择器。

用法 ​

输入框中的文字是草稿,回车或失焦提交后按 format 重写;色块绘制的是已提交的值,未完成的输入不会被提交

收下的值:#3b82f6

组件结构 ​

加粗的是必需部件。

data-scope="color-field":root · label · control · swatch · input · clear-trigger · hidden-input

示例 ​

写法与透明度 ​

手动输入的任何写法提交后都按 format 重写;开启 alpha 才保留透明度,配合 rgba 写法一目了然

收下的值:rgba(59, 130, 246, 0.5)

无法提交的草稿 ​

无法解析的文字留在框中并标为无效,让用户看到自己输入的内容;Escape 放弃草稿回到规范文本

已收下

状态与尺寸 ​

禁用、只读、无效三态与 sm / lg 两档;色块与清空按钮跟随字段的尺寸档

设计指引 ​

何时使用 ​

  • 用户持有颜色串(设计稿上的 #3b82f6、rgb()),需要直接填入表单。
  • 主题设置、标注色、图表配色等需要精确到值的场景。
  • 与颜色选择器并排,选完后可以查看并微调该值。

何时不用 ​

特性 ​

  • 支持 #rgb / #rrggbb(aa)、rgb() / rgba()、hsl() / hsla() 与 oklch(),不支持颜色关键字;提交后按 format(hex / rgba / hsla / oklch)重写,alpha 决定是否带透明度。
  • 输入过程只保留草稿:值、色块与 onValueChange 都不变化,data-editing 标记正在编辑;回车或失焦提交,Escape 放弃草稿并回到规范文本。
  • 无法提交的草稿留在框内并标记为无效(aria-invalid、data-invalid),用户可以看到自己的输入;再次修改时移除标记。
  • 空串是合法的“无颜色”:clearable 开启清空按钮与 Escape 清空,空值时色块只绘制棋盘格。
  • 表单出口经 hidden-input:提交的是已确认的值,框内未提交的草稿不会随表单提交;提供 name 后才参与提交。
  • 视觉盒使用 Field Chrome,色块使用 Swatch 家族,清空按钮使用 Action Control 的 field-inset 档,与文本字段外观一致。
  • 不写结构时按标准结构铺出整套部件(Vue 不写默认插槽、React 不给 children、Web Components 不写部件或只写 root),三端出自同一个结构函数:label 给标题文字,盒里依次是色块、输入框与清空按钮(开了 clearable 才铺),给了 name 再带表单影子。Web Components 里标题可以写在宿主的直接子节点 slot="label" 上接管。

组合 ​

  • 放入表单字段:标签、说明与错误由字段渲染并经 aria-describedby 关联到输入框,禁用 / 只读 / 必填 / 无效四轴随字段下发。
  • 与颜色滑块并排:滑块调整一个通道,字段显示完整颜色串,两者共用一个值。

最佳实践 ​

  • 通过 placeholder 提示期望的写法(#rrggbb),减少提交失败。
  • 需要透明度时同时开启 alpha 并把 format 设为 rgba 或 hsla,hex 的第四对字符不易辨识。
  • 在 onValueChange 中取值,不读取输入框:框内可能是尚未提交的草稿。

反模式 ​

  • 将它当作自由文本框:无法解析的输入不会成为值,也不会随表单提交。
  • 传颜色关键字(red)作为初值:无法解析的串会被视为无效值并保持不变。

API 参考 ​

产物 ​

层值
自定义元素<xh-color-field>
Vue 组件XhColorFieldClearTrigger XhColorFieldControl XhColorFieldHiddenInput XhColorFieldInput XhColorFieldLabel XhColorFieldRoot XhColorFieldSwatch
组合式函数useColorField
状态机colorFieldMachine
皮肤@xihan-ui/styles/color-field.css

Props ​

属性类型必填说明
labelledboolean作者渲染了 label 部件时置真,由适配器统计而不是判断标题文字是否有值。 为假时可聚焦部件不把 label 的 id 写进 aria-labelledby:指向未渲染的 id 是无效引用,作者写在控件上的 aria-label 也会被它压住。
ariaLabelstring不显示出来的名字,写成 aria-label 落在与字段标签同一个部件上。 放进字段(字段接线)或渲染了 label 部件时名字以它们为准,aria-labelledby 盖过它。
valuestring受控的颜色串;提供后由宿主决定,状态机不自行修改。空串表示没有颜色。
defaultValuestring非受控初值,默认空串。
formatColorFormat值串的写法,默认 hex。手动输入的任何写法接受后都按它重写。
alphaboolean带透明度,默认关闭。关闭时接受的颜色恒为不透明。
placeholderstring
disabledboolean
readOnlyboolean
requiredboolean
invalidboolean
namestring表单字段名;提供后才参与提交(经表单影子,输入框中未提交的草稿不会被提交)。
clearableboolean开启清空能力:有值时显示清空按钮、Escape 接管。关闭时按钮带 hidden 收起。
variantControlVariant形态:outline / subtle / ghost,决定底色与描边的绘制方式。默认 outline。
toneTone语气:brand / neutral / success / warning / danger / info,决定聚焦强调使用哪族颜色。
sizeSize尺寸:sm / md / lg,决定输入框、色块与清空按钮的几何档位。
translationsPartial<ColorFieldTranslations>读屏文案;默认英文。
onValueChange(details: ColorFieldValueChangeDetails) => void
onClear() => void用户按清空钮(clear-trigger)清掉了值;先发值变化,再发它。程序化的 clear() 不发。

事件 ​

自定义元素将载荷放在 detail;Vue 使用同名 emit。

事件载荷说明
value-changeColorFieldValueChangeDetails已接受的值变化;detail 为 { value: string },输入途中不发出
clear``用户按清空钮(clear-trigger)清掉了值;先发值变化,再发它。程序化的 clear() 不发。

插槽 ​

仅列出带载荷的插槽。

Vue 组件插槽载荷说明
XhColorFieldRootdefaultColorFieldRootSlotProps
XhColorFieldRootlabel—

React 适配器 props ​

只列各组件自己声明的那些:继承自 ComponentPropsWithRef 的 DOM 属性不在其中,根组件上与上面 Props 表同名的也不重复列。Vue 的对应物是上面的插槽表。

React 组件属性类型必填说明
XhColorFieldRootlabelReactNode标题。不给 children 时铺 label 部件。
XhColorFieldRootchildrenSlotChildren<ColorFieldRootSlotProps>

状态 ​

以下名称仅用于内部状态机。

状态:idle

事件:INPUT.CHANGE · INPUT.COMMIT · INPUT.CANCEL · VALUE.SET · VALUE.CLEAR · FORM.RESET · PRESS.START · PRESS.END

判据:canEdit · canClear

connect API ​

getXxxProps() 返回对应部件的宿主属性。

成员类型说明
valuestring当前值串(与 onValueChange 发出的是同一个);空串表示没有颜色。
emptyboolean值为空串。
textstring输入框当前应显示的文字:有草稿显示草稿,否则显示值本身。
editingboolean正在编辑:框中有一份尚未接受的草稿。
draftInvalidboolean上一次接受失败,草稿留在框中。
rgbaColorRgba值解析出的颜色;空串或不可解析时为兜底黑,此时参考 empty / valid。
validboolean值串本身可解析(空串不算有效)。
disabledboolean
readOnlyboolean
invalidboolean作者标记的 invalid,或草稿不可接受。
clearableboolean
canClearboolean清空按钮当前是否可用(开启 clearable、可编辑、且有值)。
setValue(next: string) => void直接写值:空串清空,不可解析的串保持不变;只受 disabled / readOnly 约束。
clear() => void发起清空意图,受 canClear 约束;无条件清空使用 setValue('')。
commit() => void接受框中的草稿(与回车 / 失焦同一路径)。
getRootProps() => T['element']
getControlProps() => T['element']视觉盒;描边、底色与聚焦环绘制在该节点上,色块、输入框与清空按钮排列在其中。
getLabelProps() => T['label']
getSwatchProps() => T['element']当前颜色的色块:纯装饰,颜色已在输入框中;空值或无效时只绘制棋盘格。
getInputProps() => T['input']
getClearTriggerProps() => T['button']
getHiddenInputProps() => T['input']表单影子:提交的是已接受的值,框中的草稿不会被提交。提供 name 后才带 name。

无障碍 ​

键盘 ​

规格出处:W3C APG

按键生效条件行为
Enterfocus in input, 框里有还没收下的草稿收下草稿:解析得了就按 format 重写成值,解析不了保留草稿并标成无效;没在编辑时不接管,回车照常提交表单
Escapefocus in input, 框里有还没收下的草稿放弃草稿,框里回到当前值的规范文本
Escapefocus in input, 没有草稿, clearable 且值非空, not disabled/readOnly清空值;条件不满足即不接管该键,交回给外层与浏览器
Enter / Spaceheld in clear-trigger, clearable 且值非空, not disabled/readOnly按住期间清空按钮投影 data-pressed,与指针 :active 同一副按压面;抬起或失焦撤下,值清空后按钮藏起一并撤下。清空按钮不占 Tab 位,键盘这一路只在焦点落到它身上时有面

ARIA ​

以下属性由 connect 生成。

部件属性值
swatcharia-hidden'true'
inputaria-invalid'true' | 'false'
inputaria-labelprops.ariaLabel
inputaria-labelledbylabel 部件的 id | undefined
inputaria-readonly'true' | 'false'
inputaria-required'true' | 'false'
clear-triggeraria-labellabel.clearTrigger

样式参考 ​

皮肤 ​

@xihan-ui/styles/color-field.css 按 [data-scope="color-field"][data-part="root"] 部件选择器书写,发布产物以挂载类 .xh-scope-color-field 代替其中的 data-scope(特异性相同),位于 xihan.components 层。覆盖样式使用 xihan.overrides,部件选择器照常可用。

forced-colors: active 下另有一套规则:颜色交给系统,边框与状态标记改用系统色关键字。

数据属性 ​

由 connect 生成;条件不成立时不输出无值属性。

部件属性值
rootdata-disabled''(条件成立时才出现)
rootdata-editing''(条件成立时才出现)
rootdata-empty''(条件成立时才出现)
rootdata-invalid''(条件成立时才出现)
rootdata-readonly''(条件成立时才出现)
rootdata-sizeprops.size
rootdata-toneprops.tone
rootdata-variantprops.variant
labeldata-disabled''(条件成立时才出现)
controldata-disabled''(条件成立时才出现)
controldata-editing''(条件成立时才出现)
controldata-empty''(条件成立时才出现)
controldata-invalid''(条件成立时才出现)
controldata-readonly''(条件成立时才出现)
controldata-variantprops.variant
controldata-xh-action-owner''
controldata-xh-field-chrome''
controldata-xh-field-sizeprops.size
swatchdata-disabled''(条件成立时才出现)
swatchdata-empty''(条件成立时才出现)
swatchdata-xh-swatch''
swatchdata-xh-swatch-sizeprops.size
inputdata-disabled''(条件成立时才出现)
inputdata-editing''(条件成立时才出现)
inputdata-empty''(条件成立时才出现)
inputdata-invalid''(条件成立时才出现)
inputdata-xh-field-input''
inputdata-xh-field-layout'single-line'
clear-triggerdata-pressed''(条件成立时才出现)
clear-triggerdata-xh-action-control''
clear-triggerdata-xh-action-display'has-value'
clear-triggerdata-xh-action-has-value''(条件成立时才出现)
clear-triggerdata-xh-action-profile'field-inset'
clear-triggerdata-xh-action-sizeprops.size
clear-triggerdata-xh-action-variant'ghost'

CSS 变量 ​

本组件公开覆盖槽由独立皮肤的实际消费位生成;默认来源、作用部件和状态均与 CSS 同源。

变量部件CSS 属性状态默认来源说明
--xh-color-field-action-bgclear-trigger--xh-ink-surface
background-color
default
xh-ink-surface
--xh-_action-variant-bg-restcolor-field 的 clear-trigger 部件 --xh-ink-surface、background-color 覆盖槽。
--xh-color-field-action-bg-activeclear-triggerbackground-colordisabled
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-_action-variant-bg-pressedcolor-field 的 clear-trigger 部件 background-color 覆盖槽。
--xh-color-field-action-bg-hoverclear-triggerbackground-colordisabled
hover
loading
not([data-disabled])
not([data-loading])
--xh-_action-variant-bg-hovercolor-field 的 clear-trigger 部件 background-color 覆盖槽。
--xh-color-field-action-fgclear-triggercolordefault--xh-fg-field-clearcolor-field 的 clear-trigger 部件 color 覆盖槽。
--xh-color-field-action-fg-hoverclear-triggercolordisabled
hover
loading
not([data-disabled])
not([data-loading])
--xh-fg-defaultcolor-field 的 clear-trigger 部件 color 覆盖槽。
--xh-color-field-action-font-sizeclear-triggerfont-sizedefault--xh-_color-field-action-font-sizecolor-field 的 clear-trigger 部件 font-size 覆盖槽。
--xh-color-field-action-radiusclear-triggerborder-radiusdefault--xh-shape-circlecolor-field 的 clear-trigger 部件 border-radius 覆盖槽。
--xh-color-field-action-sizeclear-triggerblock-size
inline-size
min-inline-size
default
xh-action-profile=field-inset
--xh-_action-profile-visual-sizecolor-field 的 clear-trigger 部件 block-size、inline-size、min-inline-size 覆盖槽。
--xh-color-field-control-bgcontrolbackground-colorxh-field-chrome--xh-_field-variant-bg-restcolor-field 的 control 部件 background-color 覆盖槽。
--xh-color-field-control-bg-disabledcontrolbackground-colordisabled
xh-field-chrome
--xh-_field-variant-bg-disabledcolor-field 的 control 部件 background-color 覆盖槽。
--xh-color-field-control-bg-hovercontrolbackground-colordisabled
hover
invalid
loading
not(:focus-within)
not([data-disabled])
not([data-invalid])
not([data-loading])
not([data-readonly])
readonly
xh-field-chrome
--xh-_field-variant-bg-hovercolor-field 的 control 部件 background-color 覆盖槽。
--xh-color-field-control-bg-readonlycontrolbackground-colorreadonly
xh-field-chrome
--xh-_field-variant-bg-read-onlycolor-field 的 control 部件 background-color 覆盖槽。
--xh-color-field-control-bordercontrolborderxh-field-chrome--xh-_field-variant-border-restcolor-field 的 control 部件 border 覆盖槽。
--xh-color-field-control-border-focuscontrolborder-color
box-shadow
disabled
focus-within
not([data-disabled])
xh-field-chrome
--xh-_field-variant-border-focuscolor-field 的 control 部件 border-color、box-shadow 覆盖槽。
--xh-color-field-control-border-hovercontrolborder-colordisabled
hover
invalid
loading
not(:focus-within)
not([data-disabled])
not([data-invalid])
not([data-loading])
not([data-readonly])
readonly
xh-field-chrome
--xh-_field-variant-border-hovercolor-field 的 control 部件 border-color 覆盖槽。
--xh-color-field-control-border-invalidcontrolborder-colorinvalid
xh-field-chrome
--xh-_field-variant-border-invalidcolor-field 的 control 部件 border-color 覆盖槽。
--xh-color-field-control-fgcontrolcolorxh-field-chrome--xh-fg-defaultcolor-field 的 control 部件 color 覆盖槽。
--xh-color-field-control-gapcontrolgapxh-field-chrome--xh-_color-field-gapcolor-field 的 control 部件 gap 覆盖槽。
--xh-color-field-control-hcontrolblock-size
min-block-size
has([data-xh-field-input][data-xh-field-layout='multi-tag'])
has([data-xh-field-input][data-xh-field-layout='single-line'])
has([data-xh-field-input][data-xh-field-layout='textarea'])
xh-field-chrome
xh-field-input
xh-field-layout=multi-tag
xh-field-layout=single-line
xh-field-layout=textarea
--xh-_color-field-hcolor-field 的 control 部件 block-size、min-block-size 覆盖槽。
--xh-color-field-control-min-wcontrol
root
min-inline-sizedefault
xh-field-chrome
--xh-control-min-wcolor-field 的 control、root 部件 min-inline-size 覆盖槽。
--xh-color-field-control-pxcontrolpadding-inlinexh-field-chrome--xh-_color-field-pxcolor-field 的 control 部件 padding-inline 覆盖槽。
--xh-color-field-control-radiuscontrolborder-radiusxh-field-chrome--xh-shape-controlcolor-field 的 control 部件 border-radius 覆盖槽。
--xh-color-field-control-shadowcontrolbox-shadowxh-field-chromenonecolor-field 的 control 部件 box-shadow 覆盖槽。
--xh-color-field-control-wrootinline-size
min-inline-size
default--xh-control-wcolor-field 的 root 部件 inline-size、min-inline-size 覆盖槽。
--xh-color-field-gaplabel
root
gap
margin-block-end
default--xh-space-1color-field 的 label、root 部件 gap、margin-block-end 覆盖槽。
--xh-color-field-icon-sizecontrol
root
--xh-icon-sizedefault
size=lg
size=sm
xh-field-chrome
--xh-_field-size-glyph-size
--xh-glyph-size-lg
--xh-glyph-size-md
--xh-glyph-size-sm
color-field 的 control、root 部件 --xh-icon-size 覆盖槽。
--xh-color-field-input-autofill-bginputbox-shadow-webkit-autofill
autofill
xh-field-input
--xh-bg-canvascolor-field 的 input 部件 box-shadow 覆盖槽。
--xh-color-field-input-autofill-fginput-webkit-text-fill-color-webkit-autofill
autofill
xh-field-input
--xh-fg-defaultcolor-field 的 input 部件 -webkit-text-fill-color 覆盖槽。
--xh-color-field-input-fginputcolorxh-field-input--xh-fg-defaultcolor-field 的 input 部件 color 覆盖槽。
--xh-color-field-input-font-sizeinputfont-sizexh-field-input--xh-_color-field-font-sizecolor-field 的 input 部件 font-size 覆盖槽。
--xh-color-field-label-fglabelcolordefault--xh-fg-mutedcolor-field 的 label 部件 color 覆盖槽。
--xh-color-field-label-fg-disabledlabelcolordisabled--xh-fg-mutedcolor-field 的 label 部件 color 覆盖槽。
--xh-color-field-label-font-sizelabelfont-sizedefault--xh-text-label-sizecolor-field 的 label 部件 font-size 覆盖槽。
--xh-color-field-label-font-weightlabelfont-weightdefault--xh-text-label-weightcolor-field 的 label 部件 font-weight 覆盖槽。
--xh-color-field-label-gaplabelmargin-block-enddefault--xh-space-2color-field 的 label 部件 margin-block-end 覆盖槽。
--xh-color-field-placeholder-fginputcolorplaceholder
xh-field-input
--xh-fg-subtlecolor-field 的 input 部件 color 覆盖槽。
--xh-color-field-swatch-borderswatch--xh-swatch-borderdefault--xh-border-defaultcolor-field 的 swatch 部件 --xh-swatch-border 覆盖槽。
--xh-color-field-swatch-radiusswatch--xh-swatch-radiusdefault--xh-shape-insetcolor-field 的 swatch 部件 --xh-swatch-radius 覆盖槽。
--xh-color-field-swatch-sizeswatch--xh-swatch-sizedefault--xh-_swatch-sizecolor-field 的 swatch 部件 --xh-swatch-size 覆盖槽。

动效 ​

动效角色:按压 · 状态(见动效规范)。

本组件皮肤不含过渡与关键帧,也没有脚本驱动的动效:状态一变,外观立即到位。

RTL ​

皮肤用逻辑属性排布(inline-start 一族),dir="rtl" 下自动镜像。

Released under The MIT License