生态产品多个设计器现已发布正式版

查看生态总览
跳转到内容

TagsInput 标签输入 ​

在一个输入框内录入一串标签:回车或分隔符成词,每个词是一个可删除的标签。

用法 ​

在框中输入后按 Enter 落下一个标签;标签由作者按当前值渲染,每个标签自带 value 标识身份,预览与删除按钮就是库内的 tag

Vue
TypeScript

当前:Vue、TypeScript

组件结构 ​

加粗的是必需部件。

data-scope="tags-input":root · label · control · input · item · item-input · clear-trigger · count · hidden-input

示例 ​

上限与粘贴拆分 ​

add-on-paste 使粘贴进来的一串按分隔符拆为多个标签;达到 max 后再输入再粘贴都不能加入

Vue
1 / 4

就地编辑 ​

editable 开启后双击任一标签改写它:Enter 提交、Escape 撤销,改为空白等于删除该标签

前端
组件库
无障碍

当前:前端、组件库、无障碍

禁用与只读 ​

disabled 整个控件退出 Tab 序列、标签一起置灰;read-only 仍可聚焦浏览,但不能加入也不能删除,删除按钮留在原地不可按下、标签不置灰

Vue
Vite
Vue
Vite

变体 ​

variant 只改变控件的颜色槽位,标签的形态按控件的面派生:subtle 控件中是描边标签,其余是淡底标签;落下标签与删除标签的行为三档一致

Vue
TypeScript
Vue
TypeScript
Vue
TypeScript

颜色 ​

tone 决定使用哪族颜色,与 variant 正交;这里固定 outline 只查看语气的差别

标签
标签
标签
标签
标签
标签

尺寸 ​

控件高度、胶囊与输入文字一起换档,不传 size 即默认档

Vue
TypeScript
Vue
TypeScript
Vue
TypeScript

随表单提交 ​

写了 name 与 hidden-input 才参与提交,整份标签按断词符拼接为一串;框中没有内容时回车留给表单

Vue
TypeScript
表单收到:(还没提交)

入库前统一改写 ​

提供 value 后由宿主决定:组件只发变更意图,写回什么形状在这里决定

#vue

当前:#vue

候选词一键添加 ​

根插槽给出 addValue 与 atMax:输入框之外再开一条添加标签的路径,上限同样受控

文档

外部触发的输入会话 ​

输入部件平时收起,按添加后才显示并聚焦;输入时提供候选,选中即落下标签,失焦按 blur-behavior 收尾

hi@xihan.dev

标签使用对象 ​

组件中保存的是标识,显示哪一份由作者决定:条目文本渲染 label,提交仍按标识拼接

张三

提交出去的是标识:u-1 · 框里看到的是名字:张三

准入判定 ​

validate 逐个判定新标签,返回拒绝码即拒收:这一次提交整体不生效、文本留在框里改;tag-reject 报告拒收的标签与原因,重复的照常消费但也会报

ada@example.com

拒收:(暂无)

一组断词符 ​

delimiter 给一组时其中任何一个都断词:半角逗号、全角逗号、分号都行,粘贴多行清单时换行也算;随表单提交的整串用第一个拼接

设计指引 ​

何时使用 ​

  • 关键词、收件人、技能等数量不定的短词集合。
  • 需要粘贴整串并自动拆分。

何时不用 ​

  • 值来自固定清单时,使用选择器的多选。
  • 需要在候选中检索选择时,使用组合框的多选。

特性 ​

  • 不写结构时按标准结构铺出标题、盒里按当前值铺的标签与输入框、清空按钮、计数与表单影子(Vue 不写默认插槽、React 不给 children、Web Components 不写部件或只写 root),三端出自同一个结构函数:label 给标题文字,开了 editable 每个标签带编辑框,开了 showCount 才铺计数。标签文本缺省就是它的值,Vue 的 item 插槽、React 的 renderItem、Web Components 宿主直接子节点上的 slot="item:<值>" 可以接管;标题在 Web Components 里用 slot="label" 接管。
  • delimiter 与 addOnPaste 一起处理粘贴拆分;delimiter 给一组时其中任何一个都断词(如半角与全角逗号),提交串用第一个。
  • validate 逐个判定新标签,返回拒绝码即拒收:这一次提交整体不生效、文本留在框里;拒收的标签连同原因(重复、放不下或自定义码)经 onTagReject 报告。
  • 标签是一个集合:已有的标签再输入一次照常被消费、值不变,只报一笔 duplicate。
  • 每个标签都是库内的 tag:预览、文字与删除按钮就是它的 root、label 与 close-trigger,语气与尺寸随控件,形态按控件的面派生。
  • editable 让已有标签双击就地修改。
  • max 与 allowOverflow 成对:超出上限时拒绝还是标记。
  • 标签的值可以是对象,不限于字符串。
  • showCount 显示计数部件,数字取 count 与 max,达到上限与越界各换一档颜色。
  • required 经 aria-required 上报必填。
  • 标签增删有进退场:首次渲染时已有的标签直接呈现,新落下的淡入、同一批按到达顺序错开,删掉的在原处淡出,其余标签滑到新位置。标签照常按值渲染,删掉即卸载,不必为退场改写法。

组合 ​

最佳实践 ​

  • 入库前统一规范化(去空白、转小写),否则同一个词会出现多份。
  • 说明使用哪个键成词,否则用户会持续输入空格。

反模式 ​

  • 不去重,同一个标签可以重复添加。
  • 标签无法删除。

API 参考 ​

产物 ​

层值
自定义元素<xh-tags-input>
Vue 组件XhTagsInputClearTrigger XhTagsInputControl XhTagsInputCount XhTagsInputHiddenInput XhTagsInputInput XhTagsInputItem XhTagsInputItemDeleteTrigger XhTagsInputItemInput XhTagsInputItemPreview XhTagsInputItemText XhTagsInputLabel XhTagsInputRoot
组合式函数useTagsInput
状态机tagsInputMachine
皮肤@xihan-ui/styles/tags-input.css

Props ​

属性类型必填说明
labelledboolean作者渲染了 label 部件时置真,由适配器统计而不是判断标题文字是否有值。 为假时可聚焦部件不把 label 的 id 写进 aria-labelledby:指向未渲染的 id 是无效引用,作者写在控件上的 aria-label 也会被它压住。
ariaLabelstring不显示出来的名字,写成 aria-label 落在与字段标签同一个部件上。 放进字段(字段接线)或渲染了 label 部件时名字以它们为准,aria-labelledby 盖过它。
valuestring[]受控标签集合;提供后由宿主决定,状态机不自行修改,只发 onValueChange。
defaultValuestring[]非受控初始标签集合。
inputValuestring受控输入文本;与 value 各自独立受控。
defaultInputValuestring非受控初始输入文本。
maxnumber标签数量上限。默认不限;写 0 表示不允许添加任何标签。
allowOverflowboolean允许超过 max。 关闭(默认):到达上限后本次输入整体不生效,文本原样留在框中,不静默丢弃。 开启:照常添加,只在 root / control 上输出 data-overflowing 供样式与提示使用。
disabledboolean
readOnlyboolean
requiredboolean必填标注:经 aria-required 上报,星号由外层的字段壳绘制。
invalidboolean
showCountboolean显示计数部件:关闭时 count 部件带 hidden 收起。
namestring表单字段名;提供后 hidden-input 才带 name,此时整份标签按 delimiter 拼接为一串提交。
placeholderstring
delimiterstring | string[]断词符,默认逗号。输入它即断词为标签,粘贴时也按它拆分。 给一组即任何一个都断词(如 [',', ',', ';']),hidden-input 拼串用第一个。 显式提供空串或空数组即关闭断词:此时只有 Enter 能把文本变为标签。
validate(tag: string, context: TagsInputValidateContext) => string | string[] | null | undefined作者的准入判定:用户提交的每个新标签(Enter、断词、粘贴、失焦加入、addValue 与就地编辑)逐个调用, 返回拒绝码(一个或一组)即拒收;返回 null / undefined / 空数组即放行。 有一个被拒这一次提交就整体不生效,文本原样留在框里(就地编辑则留在编辑框里),拒收的连同码一起进 onTagReject。 setValue 的整份替换不经过它。应为纯函数:粘贴时会先判一次决定接不接管。
addOnPasteboolean粘贴时接管:按 delimiter 拆分为多个标签。默认关闭(交给浏览器照常粘贴进框中)。
editableboolean允许双击标签就地修改。默认关闭。
blurBehaviorTagsInputBlurBehavior | null焦点离开整个组件时输入框中残留文本的处置方式。
variantControlVariant形态:outline / subtle / ghost,决定底色与描边的绘制方式。默认 outline。
toneTone语气:brand / neutral / success / warning / danger / info,决定使用哪族颜色。
sizeSize尺寸:sm / md / lg。
translationsPartial<TagsInputTranslations>
onValueChange(details: TagsInputValueChangeDetails) => void
onClear() => void用户按清空钮(clear-trigger)清掉了值;先发值变化,再发它。程序化的 clear() 不发。
onInputValueChange(details: TagsInputInputValueChangeDetails) => void
onTagReject(details: TagsInputTagRejectDetails) => void提交里有标签没进集合:重复(照常消费)、到了上限或被 validate 拒收,逐个报告原因。

事件 ​

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

事件载荷说明
value-changeTagsInputValueChangeDetails标签集合变化;detail 为 { value: string[] }
clear``用户按清空钮(clear-trigger)清掉了值;先发值变化,再发它。程序化的 clear() 不发。
input-value-changeTagsInputInputValueChangeDetails输入文本变化;detail 为 { inputValue: string }
tag-rejectTagsInputTagRejectDetails提交里有标签没进集合(重复、到了上限或被 validate 拒收);detail 为 { tags: { tag, reasons }[] }

插槽 ​

仅列出带载荷的插槽。

Vue 组件插槽载荷说明
XhTagsInputCountdefaultTagsInputCountSlotProps
XhTagsInputRootdefaultTagsInputRootSlotProps
XhTagsInputRootlabel—
XhTagsInputRootitem{ value: string }只填标签文本,常态部分的删除钮与就地编辑照旧由结构铺

React 适配器 props ​

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

React 组件属性类型必填说明
XhTagsInputCountchildrenSlotChildren<TagsInputCountSlotProps>
XhTagsInputItemvaluestring是
XhTagsInputRootlabelReactNode标题。不给 children 时铺 label 部件。
XhTagsInputRootrenderItem(value: string) => ReactNode不给 children 时标签文本的内容;未提供时就是标签的值。
XhTagsInputRootchildrenSlotChildren<TagsInputRootSlotProps>

状态 ​

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

状态:idle · navigating · editing

事件:VALUE.SET · TAG.ADD · VALUE.CLEAR · INPUT.CHANGE · INPUT.COMMIT · INPUT.BLUR · TAG.HIGHLIGHT · TAG.DELETE · TAG.EDIT · EDIT.CHANGE · EDIT.SUBMIT · EDIT.CANCEL · ITEM.FOCUS_LOST · FORM.RESET · PRESS.START · PRESS.END · LIST.TRACKED

判据:canEdit · canEditTag · canDeleteWithPrev · hasHighlightTarget · canPress · isEditRejected · isBlurEditRejected

connect API ​

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

成员类型说明
valuestring[]
countnumber标签个数,等于 value.length;作者常用它做「3 / 5」这类计数提示。
inputValuestring
emptyboolean没有任何标签。
disabledboolean
readOnlyboolean
requiredboolean
invalidboolean
maxnumber | undefined标签个数的上限;未设 max 时为 undefined,此时只渲染当前个数。
showCountboolean计数部件当前是否显示(开启了 showCount)。
atMaxboolean已到达 max:无法再添加(allowOverflow 开启时只是提示,不拦截)。
overflowboolean已超过 max(只有 allowOverflow 开启时才可能为真)。
highlightedValuestring | null光标停留的标签;不在标签间移动时为 null。
editedValuestring | null正被就地改写的标签;不在编辑态时为 null。
canClearboolean清空按钮当前是否可用(可编辑,且标签或输入文本至少有一项)。
setValue(next: string[]) => void整份替换,去重去空白,不受 max 约束。
addValue(next: string) => void追加一个标签,受 max、allowOverflow 与 validate 约束。
deleteValue(value: string) => void
clear() => void
setInputValue(next: string) => void
highlight(value: string | null) => void把光标移到某个标签上;传 null 即交回输入框。
edit(value: string) => void进入就地编辑;未开启 editable 时被守卫拦截。
getRootProps() => T['element']
getLabelProps() => T['label']
getControlProps() => T['element']
getInputProps() => T['input']
getItemProps(item: TagsInputItemProps) => T['element']
getItemPreviewProps(item: TagsInputItemProps) => T['element']标签的预览:即库内 tag 的 root(data-scope="tag"),就地编辑时收起;双击进入编辑态。
getItemTextProps(item: TagsInputItemProps) => T['element']标签文字:tag 的 label,截断落在该层。
getItemDeleteTriggerProps(item: TagsInputItemProps) => T['button']删除按钮:所在标签那份 tag 的 close-trigger,不占 Tab 位;禁用与只读时保留位置、原生 disabled。
getItemInputProps(item: TagsInputItemProps) => T['input']
getClearTriggerProps() => T['button']
getCountProps() => T['element']计数部件:承载 count / max 两个数字,未开启 showCount 时带 hidden 收起。
getHiddenInputProps() => T['input']

无障碍 ​

键盘 ​

规格出处:W3C APG

按键生效条件行为
Enterfocus in input, 框里有能成标签的内容, not disabled/readOnly把输入框里的文本变成标签(含 delimiter 时一次进多个);有一个被 validate 拒收或放不下就整体不生效、文本留在框里。框里只有空白时不接管,Enter 留给表单提交
delimiter(默认 ,,可给一组)focus in input, not disabled/readOnly断词:分隔符之前的每一段各成一个标签,最后一段留在框里接着打;被拒时整段原样留在框里
Backspace输入框为空且没有标签被高亮, 至少有一个标签高亮最后一个标签(这一下不删任何东西)
Backspace输入框为空且已有标签被高亮删掉高亮的标签,光标落到前一个上;删的是第一个就交回输入框
Delete已有标签被高亮同上,删掉高亮的标签
ArrowLeftfocus in input 且光标贴着最左端(无选区), 至少有一个标签往左走一格;还没走进标签时从最后一个起步,已经在第一个就停住
ArrowRight已有标签被高亮往右走一格;走出末尾即交回输入框。光标还在框里时不接管
Home已有标签被高亮跳到第一个标签
End已有标签被高亮交回输入框
Escape已有标签被高亮取消高亮,光标交回输入框;没在标签间走时不接管该键
Enter已有标签被高亮, editable 开启就地编辑这个标签,焦点进编辑框并整段选中
Enterfocus in item-input(就地编辑中)提交改写;改成空白等于删掉这个标签,改成另一个已有标签则并成一个。焦点交回输入框;被 validate 拒收时留在编辑框里
Escapefocus in item-input(就地编辑中)撤销这次改写,标签保持原样,焦点交回输入框
Enter / Spaceheld in clear-trigger, 有标签或框里有文本, not disabled/readOnly按住期间清空按钮投影 data-pressed,与指针 :active 同一副按压面;抬起或失焦撤下,清空后按钮藏起一并撤下。清空按钮不占 Tab 位,键盘这一路只在焦点落到它身上时有面

ARIA ​

以下属性由 connect 生成。

部件属性值
controlaria-disabled'true' | 'false'
controlaria-labelprops.ariaLabel
controlaria-labelledbylabel 部件的 id | undefined
controlrole'group'
inputaria-invalid'true' | 'false'
inputaria-labelprops.ariaLabel
inputaria-labelledbylabel 部件的 id | undefined
inputaria-required'true' | 'false'
item-inputaria-labellabel.editTagInput(item.value)
clear-triggeraria-labellabel.clearTrigger
countaria-hidden'true'

样式参考 ​

皮肤 ​

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

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

数据属性 ​

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

部件属性值
rootdata-at-max''(条件成立时才出现)
rootdata-disabled''(条件成立时才出现)
rootdata-empty''(条件成立时才出现)
rootdata-invalid''(条件成立时才出现)
rootdata-overflowing''(条件成立时才出现)
rootdata-readonly''(条件成立时才出现)
rootdata-required''(条件成立时才出现)
rootdata-sizeprops.size
rootdata-toneprops.tone
rootdata-variantprops.variant
labeldata-disabled''(条件成立时才出现)
controldata-at-max''(条件成立时才出现)
controldata-disabled''(条件成立时才出现)
controldata-empty''(条件成立时才出现)
controldata-instant''(条件成立时才出现)
controldata-invalid''(条件成立时才出现)
controldata-overflowing''(条件成立时才出现)
controldata-readonly''(条件成立时才出现)
controldata-variantprops.variant
controldata-xh-action-owner''
controldata-xh-field-chrome''
controldata-xh-field-layout'multi-tag'
controldata-xh-field-sizeprops.size
inputdata-disabled''(条件成立时才出现)
inputdata-invalid''(条件成立时才出现)
inputdata-readonly''(条件成立时才出现)
inputdata-xh-field-input''
itemdata-disabled''(条件成立时才出现)
itemdata-editing''(条件成立时才出现)
itemdata-highlighted''(条件成立时才出现)
itemdata-readonly''(条件成立时才出现)
item-inputdata-disabled''(条件成立时才出现)
item-inputdata-editing''(条件成立时才出现)
item-inputdata-highlighted''(条件成立时才出现)
item-inputdata-readonly''(条件成立时才出现)
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'
countdata-at-max''(条件成立时才出现)
countdata-disabled''(条件成立时才出现)

CSS 变量 ​

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

变量部件CSS 属性状态默认来源说明
--xh-tags-input-action-bgclear-trigger--xh-ink-surface
background-color
default
xh-ink-surface
--xh-_action-variant-bg-resttags-input 的 clear-trigger 部件 --xh-ink-surface、background-color 覆盖槽。
--xh-tags-input-action-bg-activeclear-triggerbackground-colordisabled
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-_action-variant-bg-pressedtags-input 的 clear-trigger 部件 background-color 覆盖槽。
--xh-tags-input-action-bg-hoverclear-triggerbackground-colordisabled
hover
loading
not([data-disabled])
not([data-loading])
--xh-_action-variant-bg-hovertags-input 的 clear-trigger 部件 background-color 覆盖槽。
--xh-tags-input-action-fgclear-triggercolordefault--xh-fg-field-cleartags-input 的 clear-trigger 部件 color 覆盖槽。
--xh-tags-input-action-fg-hoverclear-triggercolordisabled
hover
loading
not([data-disabled])
not([data-loading])
--xh-fg-defaulttags-input 的 clear-trigger 部件 color 覆盖槽。
--xh-tags-input-action-font-sizeclear-triggerfont-sizedefault--xh-text-secondary-sizetags-input 的 clear-trigger 部件 font-size 覆盖槽。
--xh-tags-input-action-radiusclear-triggerborder-radiusdefault--xh-shape-circletags-input 的 clear-trigger 部件 border-radius 覆盖槽。
--xh-tags-input-action-sizeclear-triggerblock-size
inline-size
min-inline-size
default
xh-action-profile=field-inset
--xh-_action-profile-visual-sizetags-input 的 clear-trigger 部件 block-size、inline-size、min-inline-size 覆盖槽。
--xh-tags-input-control-bgcontrolbackground-colorxh-field-chrome--xh-_field-variant-bg-resttags-input 的 control 部件 background-color 覆盖槽。
--xh-tags-input-control-bg-disabledcontrolbackground-colordisabled
xh-field-chrome
--xh-_field-variant-bg-disabledtags-input 的 control 部件 background-color 覆盖槽。
--xh-tags-input-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-hovertags-input 的 control 部件 background-color 覆盖槽。
--xh-tags-input-control-bg-readonlycontrolbackground-colorreadonly
xh-field-chrome
--xh-_field-variant-bg-read-onlytags-input 的 control 部件 background-color 覆盖槽。
--xh-tags-input-control-bordercontrolborderxh-field-chrome--xh-_field-variant-border-resttags-input 的 control 部件 border 覆盖槽。
--xh-tags-input-control-border-at-maxcontrolborder-colorat-max
invalid
not([data-invalid])
--xh-border-at-limittags-input 的 control 部件 border-color 覆盖槽。
--xh-tags-input-control-border-focuscontrolborder-color
box-shadow
disabled
focus-within
not([data-disabled])
xh-field-chrome
--xh-_field-variant-border-focustags-input 的 control 部件 border-color、box-shadow 覆盖槽。
--xh-tags-input-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-hovertags-input 的 control 部件 border-color 覆盖槽。
--xh-tags-input-control-border-invalidcontrolborder-colorinvalid
xh-field-chrome
--xh-_field-variant-border-invalidtags-input 的 control 部件 border-color 覆盖槽。
--xh-tags-input-control-fgcontrolcolorxh-field-chrome--xh-fg-defaulttags-input 的 control 部件 color 覆盖槽。
--xh-tags-input-control-gapcontrolgapxh-field-chrome--xh-_tags-input-control-gaptags-input 的 control 部件 gap 覆盖槽。
--xh-tags-input-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-_tags-input-control-htags-input 的 control 部件 block-size、min-block-size 覆盖槽。
--xh-tags-input-control-max-hcontrolmax-block-sizedefault--xh-viewport-h-smtags-input 的 control 部件 max-block-size 覆盖槽。
--xh-tags-input-control-min-wcontrol
root
min-inline-sizedefault
xh-field-chrome
--xh-control-min-wtags-input 的 control、root 部件 min-inline-size 覆盖槽。
--xh-tags-input-control-pscontrolpadding-inline-starthas(> [data-scope='tags-input'][data-part='item'])--xh-space-1tags-input 的 control 部件 padding-inline-start 覆盖槽。
--xh-tags-input-control-pxcontrolpadding-inlinexh-field-chrome--xh-_tags-input-control-pxtags-input 的 control 部件 padding-inline 覆盖槽。
--xh-tags-input-control-radiuscontrolborder-radiusxh-field-chrome--xh-shape-controltags-input 的 control 部件 border-radius 覆盖槽。
--xh-tags-input-control-shadowcontrolbox-shadowxh-field-chromenonetags-input 的 control 部件 box-shadow 覆盖槽。
--xh-tags-input-control-wrootinline-size
min-inline-size
default--xh-control-wtags-input 的 root 部件 inline-size、min-inline-size 覆盖槽。
--xh-tags-input-count-fgcountcolordefault--xh-fg-mutedtags-input 的 count 部件 color 覆盖槽。
--xh-tags-input-count-fg-at-maxcountcolorat-max--xh-fg-warningtags-input 的 count 部件 color 覆盖槽。
--xh-tags-input-count-fg-disabledcountcolordisabled--xh-fg-disabledtags-input 的 count 部件 color 覆盖槽。
--xh-tags-input-count-font-sizecountfont-sizedefault--xh-text-caption-sizetags-input 的 count 部件 font-size 覆盖槽。
--xh-tags-input-gaplabel
root
gap
margin-block-end
default--xh-space-1tags-input 的 label、root 部件 gap、margin-block-end 覆盖槽。
--xh-tags-input-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
tags-input 的 control、root 部件 --xh-icon-size 覆盖槽。
--xh-tags-input-input-autofill-bginputbox-shadow-webkit-autofill
autofill
xh-field-input
--xh-bg-canvastags-input 的 input 部件 box-shadow 覆盖槽。
--xh-tags-input-input-autofill-fginput-webkit-text-fill-color-webkit-autofill
autofill
xh-field-input
--xh-fg-defaulttags-input 的 input 部件 -webkit-text-fill-color 覆盖槽。
--xh-tags-input-input-basisinputflex-basisdefault6remtags-input 的 input 部件 flex-basis 覆盖槽。
--xh-tags-input-input-fginputcolorxh-field-input--xh-fg-defaulttags-input 的 input 部件 color 覆盖槽。
--xh-tags-input-input-font-sizeinputfont-sizexh-field-input--xh-_tags-input-input-font-sizetags-input 的 input 部件 font-size 覆盖槽。
--xh-tags-input-input-min-winputmin-inline-sizedefault--xh-control-input-min-wtags-input 的 input 部件 min-inline-size 覆盖槽。
--xh-tags-input-item-bg-highlightitem
root
backgrounddisabled
highlighted
not([data-disabled])
--xh-_tags-input-accenttags-input 的 item、root 部件 background 覆盖槽。
--xh-tags-input-item-fg-highlightitem
root
colordisabled
highlighted
not([data-disabled])
--xh-_tags-input-accent-fgtags-input 的 item、root 部件 color 覆盖槽。
--xh-tags-input-item-font-sizeitem-inputfont-sizedefault--xh-_tags-input-item-font-sizetags-input 的 item-input 部件 font-size 覆盖槽。
--xh-tags-input-item-hitem-inputmin-block-sizedefault--xh-_tags-input-item-htags-input 的 item-input 部件 min-block-size 覆盖槽。
--xh-tags-input-item-input-bgitem-inputbackgrounddefault--xh-bg-fieldtags-input 的 item-input 部件 background 覆盖槽。
--xh-tags-input-item-input-bg-focusitem-inputbackgroundfocus-within--xh-bg-surfacetags-input 的 item-input 部件 background 覆盖槽。
--xh-tags-input-item-input-borderitem-inputborderdefault--xh-border-controltags-input 的 item-input 部件 border 覆盖槽。
--xh-tags-input-item-input-border-focusitem-inputborder-colorfocus-within--xh-border-control-focustags-input 的 item-input 部件 border-color 覆盖槽。
--xh-tags-input-item-input-border-invalidcontrol
item-input
border-colorinvalid--xh-border-invalidtags-input 的 control、item-input 部件 border-color 覆盖槽。
--xh-tags-input-item-input-fgitem-inputcolordefault--xh-fg-defaulttags-input 的 item-input 部件 color 覆盖槽。
--xh-tags-input-item-pxitem-inputpadding-inlinedefault--xh-_tags-input-item-pxtags-input 的 item-input 部件 padding-inline 覆盖槽。
--xh-tags-input-item-pyitem-inputpadding-blockdefault--xh-_tags-input-item-pytags-input 的 item-input 部件 padding-block 覆盖槽。
--xh-tags-input-item-radiusitem-inputborder-radiusdefault--xh-shape-insettags-input 的 item-input 部件 border-radius 覆盖槽。
--xh-tags-input-label-fglabelcolordefault--xh-fg-mutedtags-input 的 label 部件 color 覆盖槽。
--xh-tags-input-label-fg-disabledlabelcolordisabled--xh-fg-mutedtags-input 的 label 部件 color 覆盖槽。
--xh-tags-input-label-font-sizelabelfont-sizedefault--xh-text-label-sizetags-input 的 label 部件 font-size 覆盖槽。
--xh-tags-input-label-font-weightlabelfont-weightdefault--xh-text-label-weighttags-input 的 label 部件 font-weight 覆盖槽。
--xh-tags-input-label-gaplabelmargin-block-enddefault--xh-space-2tags-input 的 label 部件 margin-block-end 覆盖槽。
--xh-tags-input-placeholder-fginputcolorplaceholder
xh-field-input
--xh-fg-subtletags-input 的 input 部件 color 覆盖槽。

动效 ​

动效角色:按压 · 状态 · 指示与换位 · 出现 · 列表(见动效规范)。

共享关键帧 xh-fade-in · xh-fade-out · xh-pop-in 由 family/motion.css 提供,皮肤 @import 它,单独引入仍成立;color · translate 走 transition 过渡。时长与缓动读动效令牌,改令牌即改全局节奏。

系统开启减弱动效时由令牌层统一收敛,皮肤不另作判断。

RTL ​

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

Released under The MIT License