@ data- slot/ combobox 数据集
无头可取的组合框组件,可自动完成/型号过滤.
安装
npm install @data-slot/combobox
使用量
HTML 结构
<div data-slot="combobox" data-placeholder="Search fruits...">
<input data-slot="combobox-input" />
<button data-slot="combobox-trigger">▼</button>
<div data-slot="combobox-content" hidden>
<div data-slot="combobox-list">
<div data-slot="combobox-empty">No results found</div>
<div data-slot="combobox-group">
<div data-slot="combobox-label">Fruits</div>
<div data-slot="combobox-item" data-value="apple">
Apple
<span data-slot="combobox-item-indicator">✓</span>
</div>
<div data-slot="combobox-item" data-value="banana">
Banana
<span data-slot="combobox-item-indicator">✓</span>
</div>
</div>
<div data-slot="combobox-separator"></div>
<div data-slot="combobox-item" data-value="other">Other</div>
</div>
</div>
</div>
Java 脚本
import { create, createCombobox } from '@data-slot/combobox';
// Auto-discover and bind all comboboxes
const controllers = create();
// Or bind a specific element
const root = document.querySelector('[data-slot="combobox"]');
const controller = createCombobox(root, {
defaultValue: 'apple',
onValueChange: (value) => console.log('Selected:', value),
});
// Programmatic control
controller.open();
controller.close();
controller.select('banana');
controller.clear();
console.log(controller.value); // 'banana'
// Cleanup
controller.destroy();
API 密码
初始化
create(scope?)
寻找和约束未初始化 [data-slot="combobox"] 后裔 scope (违约) document) (中文(简体) ). 回返 ComboboxController[] 新绑起的根。 初始化范围元素本身,使用 createCombobox。 。 。 .
import { create } from "@data-slot/combobox";
const controllers = create();
createCombobox(root, options?)
创建一个 ComboboxController 用于一个根元素。 JavaScript 选项优先于相应的数据属性. 再次调用此选项为绑定根返回其已存在的控制器; 在重新绑定新选项前将其销毁 .
import { createCombobox } from "@data-slot/combobox";
const controller = createCombobox(element, {});
槽数
运行时间槽
combobox- 根装箱.combobox-input- 过滤和键盘导航所需的文本输入.combobox-trigger- 切掉弹出物的可选按钮.combobox-clear- 清除当前值并集中输入的可选按钮.combobox-value- 可选的选定值文本目标(通常在内部)combobox-trigger) (中文(简体) ).combobox-content- 搜索结果需要弹出容器.combobox-list- 可选可滚动的列表框包装;省略时,内容起到列表框的作用.combobox-item- 个人选择的选项.combobox-item-indicator- 内部可选状态指标combobox-item; 未选中的项目自动隐藏.combobox-group- 与团体有关的项目.combobox-label- 组标签(内置a)combobox-group) (中文(简体) ).combobox-separator- 项目或组别之间的分红;其能见度随着结果的过滤而得到更新.combobox-empty- 没有项目匹配过滤器时显示消息 .combobox-positioner- 可选作者定位包装(重新使用而不是生成包装).combobox-portal- 可选作者的门户包装器,可以包含combobox-positioner。 。 。 .
由门户网站标记( 可选)
<div data-slot="combobox">
<input data-slot="combobox-input" />
<button data-slot="combobox-trigger">▼</button>
<div data-slot="combobox-portal">
<div data-slot="combobox-positioner">
<div data-slot="combobox-content" hidden>...</div>
</div>
</div>
</div>
弹出-输入构成(可选)
如果您想要一个带有承诺值文本的触发器, 以及弹出中单独的搜索输入, 请使用此选项 .
<div data-slot="combobox">
<button data-slot="combobox-trigger">
<span data-slot="combobox-value">Select country...</span>
</button>
<div data-slot="combobox-content" hidden>
<input data-slot="combobox-input" placeholder="Search countries..." />
<div data-slot="combobox-list">...</div>
</div>
</div>
在弹出- 输入模式( E)combobox-input 内部 combobox-content:
- 选择文本同步到
combobox-value。 。 。 . - 每次弹出都清除搜索输入 .
- 关闭保存弹出输入为空 .
清除按钮( 可选)
<div data-slot="combobox">
<input data-slot="combobox-input" />
<button data-slot="combobox-clear">Clear</button>
<div data-slot="combobox-content" hidden>...</div>
</div>
何时 combobox-clear 已单击:
- 当前值已清除 .
- 投入有重点.
- 如果弹出器被关闭,它仍然关闭.
- 如果弹出是打开的,它仍然是打开的.
- 默认是键盘制表顺序出局(
tabindex="-1"行为). 设定tabindex="0"让它成为可标签.
键盘标签站
combobox-input是主键盘制表站.combobox-trigger财务报告和审定财务报表combobox-clear默认已退出标签顺序.- 要选择键盘抓取任一控件, 作者
tabindex="0"这一点.
本地标签支持
使用标准的 HTML <label for="..."> 用于标签组合框的元素。 这个 for 属性应匹配 id 输入。 单击标签以输入为焦点 aria-labelledby 自动设置.
<label for="fruit-input">Choose a fruit</label>
<div data-slot="combobox">
<input data-slot="combobox-input" id="fruit-input" />
<div data-slot="combobox-content" hidden>
<div data-slot="combobox-list">
<div data-slot="combobox-item" data-value="apple">Apple</div>
</div>
</div>
</div>
选项
选项可以通过JavaScript或数据属性(JS优先)传递.
| 选项 | 数据属性 | 类型 | 默认 | 说明 |
|---|---|---|---|---|
defaultValue | data-default-value | string | null | 初始选定值 |
defaultOpen | data-default-open | boolean | false | 初始弹出打开状态 |
placeholder | data-placeholder | string | "" | 输入占位符文本 |
disabled | data-disabled | boolean | false | 禁用交互 |
required | data-required | boolean | false | 需要确认的格式 |
name | data-name | string | - 说吧 | 窗体字段名( 创建隐藏输入) |
openOnFocus | data-open-on-focus | boolean | true | 输入焦点时打开弹出 |
autoHighlight | data-auto-highlight | boolean | false | 在非空白查询输入后自动高亮第一个可见项目 |
filter | - 说吧 | (inputValue: string, itemValue: string, itemLabel: string) => boolean | 大小写不敏感标签子字符串匹配 | 返回时 true 显示项目 |
itemToStringValue | - 说吧 | (item: HTMLElement | null, value: string | null) => string | 项目标签 | 自定义选定值文本的文本解析器(输入入内模式, combobox-value 在弹出输入模式中) |
side | data-side | "top" | "bottom" | "bottom" | 弹出位置 |
align | data-align | "start" | "center" | "end" | "start" | 弹出对齐 |
sideOffset | data-side-offset | number | 4 | 距离输入( px) |
alignOffset | data-align-offset | number | 0 | 从对齐边缘抵消 (px) |
avoidCollisions | data-avoid-collisions | boolean | true | 调整以停留在取景点 |
collisionPadding | data-collision-padding | number | 8 | 查看端口边缘粘贴 (px) |
放置属性( A)data-side, (中文(简体) ), data-align, (中文(简体) ), data-side-offset, (中文(简体) ), data-align-offset, (中文(简体) ), data-avoid-collisions, (中文(简体) ), data-collision-padding(a) 决定按此顺序:
- JavaScript 选项
combobox-contentcombobox-positionercombobox根 (倒计时)
定位要素combobox-positioner,或 combobox-content 当不使用定位器时)接收这些用于样式化的CSS变量:
--transform-origin--available-width--available-height--anchor-width--anchor-height
当一个单独的 combobox-positioner 中,同样值也被映射到 combobox-content 因此复制的样式包可以从任一元素中分支出.
移动行为
- 触摸/粗指环境,外部
pointerdown(例如在卷轴手势时)不会排除弹出. - 外接/ 点击仍然可以排除弹出 .
- 在打开时,弹出位置会滚动,所以弹出位置会被固定.
- 在触摸/粗指针环境中,组合框总是位于
bottom边. - 在触摸/粗指针环境上,相撞相接相接被禁用来避免被跳跃地重新定位.
回电
| 回电 | 类型 | 说明 |
|---|---|---|
onValueChange | (value: string | null) => void | 选择更改时调用 |
onOpenChange | (open: boolean) => void | 弹出打开/ 关闭时调用 |
onInputValueChange | (inputValue: string) => void | 当用户在输入中键入时调用 |
主计长
interface ComboboxController {
readonly value: string | null; // Current selected value
readonly inputValue: string; // Current input text
readonly isOpen: boolean; // Current open state
select(value: string): void; // Select a value
clear(): void; // Clear selection
open(): void; // Open the popup
close(): void; // Close the popup
setItemToStringValue(itemToStringValue: ((item: HTMLElement | null, value: string | null) => string) | null): void;
destroy(): void; // Cleanup
}
主计长销毁
destroy() 永久处理控制器并隐藏任何打开的表面,而不包含
产生额外的变化事件。 重复销毁是安全的
旧控制器变成无操作器。 在同一根上创建新控制器以重新组合 .
活动
境外事件
root.addEventListener('combobox:change', (e) => {
console.log('Value changed:', e.detail.value);
});
root.addEventListener('combobox:open-change', (e) => {
console.log('Open state:', e.detail.open);
});
root.addEventListener('combobox:input-change', (e) => {
console.log('Input changed:', e.detail.inputValue);
});
入境事件
combobox:set 接受这些字段的部分更新,按表格顺序:
| 外地 | 类型 | 说明 |
|---|---|---|
value | string | null | 选择一个值,或以 null |
open | boolean | 打开或关闭弹出; 禁用时关闭打开 |
inputValue | string | 替换输入文本而不过滤或发射输入更改回调 |
itemToStringValue | ComboboxItemToStringValue | null | 替换或清除选中的值, 再同步显示的值 |
程序选择在禁用时有效 。 在内输入模式中,更新前置物质重同步输入,从而可以覆盖 inputValue 在同一事件中提供.
// Set value
root.dispatchEvent(new CustomEvent('combobox:set', {
detail: { value: 'apple' }
}));
// Set open state
root.dispatchEvent(new CustomEvent('combobox:set', {
detail: { open: true }
}));
// Set runtime selected-value text formatter
root.dispatchEvent(new CustomEvent('combobox:set', {
detail: { itemToStringValue: (item, value) => value ? value.toUpperCase() : '' }
}));
键盘导航
| 密钥 | 行动 |
|---|---|
ArrowDown | 打开弹出( 当关闭时); 移动到下一个可见的项目 |
ArrowUp | 打开弹出( 当关闭时); 移动到上次可见的项目 |
Home | 移动到第一个可见的项目 |
End | 移动到最后一个可见项目 |
Enter | 选择突出显示的项目 |
Escape | 关闭弹出, 将输入恢复到承诺值 |
Tab | 关闭弹出, 恢复输入, 允许正常的标签流 |
无障碍
- 输入 :
role="combobox", (中文(简体) ),aria-expanded, (中文(简体) ),aria-controls, (中文(简体) ),aria-activedescendant, (中文(简体) ),aria-autocomplete="list" - 列表 :
role="listbox", (中文(简体) ),aria-labelledby - 项目:
role="option", (中文(简体) ),aria-selected, (中文(简体) ),aria-disabled - 组 :
role="group", (中文(简体) ),aria-labelledby - 键盘导航时跳过已禁用的项目
形式整合
何时 name 为格式提交自动创建隐藏输入:
<form>
<div data-slot="combobox" data-name="fruit">
<input data-slot="combobox-input" />
<div data-slot="combobox-content" hidden>
<div data-slot="combobox-list">
<div data-slot="combobox-item" data-value="apple">Apple</div>
</div>
</div>
</div>
<button type="submit">Submit</button>
</form>
作者 name 在组合框输入上也支持。 生成的输入
提交所选值; 可见输入保留搜索或显示文本.
销毁控制器会删除生成的输入并恢复作者名称.
行为改变 : 之前的释放留下了作者 name 在明显的输入上,
因此,表格收到显示或输入的文本。 它现在收到选中的值
(或无所取时为空字符串). 要提交免费文本, 请保存 name 关闭
组合框输入和镜像 combobox:input-change 进入一个单独的领域.
禁用组合框不提交值 .
重设置窗体还原 defaultValue 选择
释放出价值变化事件。 打开的弹出也重新显示其搜索和突出显示 .
在浏览器重置后, 在下一个事件启动任务上同步
本地控制系统。 通话 preventDefault() 在重置事件上保留当前状态.
许可证
麻省理工学院