@ data- slot/ 下拉菜单
香草JavaScript的无头下放菜单. 支持动作项目,单选收音机项目,以及全键盘导航和ARIA支持的多选取复选框项目.
安装
npm install @data-slot/dropdown-menu
使用量
动作菜单
<div data-slot="dropdown-menu">
<button data-slot="dropdown-menu-trigger">Actions</button>
<div data-slot="dropdown-menu-content">
<button data-slot="dropdown-menu-item" data-value="edit">Edit</button>
<button data-slot="dropdown-menu-item" data-value="copy">Copy</button>
<button data-slot="dropdown-menu-item" data-variant="destructive" data-value="delete">
Delete
</button>
</div>
</div>
单选菜单
<div data-slot="dropdown-menu" data-default-value="pro">
<button data-slot="dropdown-menu-trigger">Plan</button>
<div data-slot="dropdown-menu-content">
<button data-slot="dropdown-menu-radio-item" data-value="starter">Starter</button>
<button data-slot="dropdown-menu-radio-item" data-value="pro">Pro</button>
<button data-slot="dropdown-menu-radio-item" data-value="team">Team</button>
</div>
</div>
多选择菜单
<div
data-slot="dropdown-menu"
data-close-on-select="false"
data-default-values='["email","push"]'
>
<button data-slot="dropdown-menu-trigger">Channels</button>
<div data-slot="dropdown-menu-content">
<button data-slot="dropdown-menu-checkbox-item" data-value="email">Email</button>
<button data-slot="dropdown-menu-checkbox-item" data-value="sms">SMS</button>
<button data-slot="dropdown-menu-checkbox-item" data-value="push">Push</button>
</div>
</div>
Java 脚本
import { create, createDropdownMenu } from "@data-slot/dropdown-menu";
const controllers = create();
const root = document.querySelector('[data-slot="dropdown-menu"]');
const controller = createDropdownMenu(root, {
onOpenChange: (open) => console.log("open:", open),
onSelect: (value) => console.log("activation:", value),
onValueChange: (value) => console.log("radio value:", value),
onValuesChange: (values) => console.log("checkbox values:", values),
});
controller.set({ value: "pro" });
controller.set({ values: ["email", "push"] });
controller.set({ open: true, highlightedValue: "push" });
controller.destroy();
createDropdownMenu(root) 每个根具有一能性。 再次调用同一元素返回现有的控制器 .
API 密码
初始化
create(scope?)
寻找和约束未初始化 [data-slot="dropdown-menu"] 后裔 scope (违约) document) (中文(简体) ). 回返 DropdownMenuController[] 新绑起的根。 初始化范围元素本身,使用 createDropdownMenu。 。 。 .
import { create } from "@data-slot/dropdown-menu";
const controllers = create();
createDropdownMenu(root, options?)
创建一个 DropdownMenuController 用于一个根元素。 JavaScript 选项优先于相应的数据属性. 再次调用此选项为绑定根返回其已存在的控制器; 在重新绑定新选项前将其销毁 .
import { createDropdownMenu } from "@data-slot/dropdown-menu";
const controller = createDropdownMenu(element, {});
槽数
运行时间槽
dropdown-menu- 根装箱.dropdown-menu-trigger- 需要切换菜单并锁定其位置的按钮.dropdown-menu-content- 需要包含动作和选择项目的菜单面板.dropdown-menu-item- 没有自有选择状态的动作项目.dropdown-menu-radio-item- 单选菜单项.dropdown-menu-checkbox-item- 多选择菜单项目.dropdown-menu-positioner- 可选作者定位包.dropdown-menu-portal- 可选作者端口包装,包含dropdown-menu-positioner。 。 。 .
只有样式的槽
dropdown-menu-group- 与团体有关的项目.dropdown-menu-label- 非互动标签.dropdown-menu-separator-视觉分裂者.dropdown-menu-shortcut- 可选键盘快捷提示;显示它不会注册键盘快捷键.
由门户标记构成
<div data-slot="dropdown-menu">
<button data-slot="dropdown-menu-trigger">Options</button>
<div data-slot="dropdown-menu-portal">
<div data-slot="dropdown-menu-positioner">
<div data-slot="dropdown-menu-content">...</div>
</div>
</div>
</div>
数据属性
根和内容
| 属性 | 目标 | 说明 |
|---|---|---|
data-state="open|closed" | 根, 内容 | 当前打开状态 |
data-open 编号 : data-closed | 根, 内容 | 状态造型存在化名 |
data-value="..." | 根号 | 目前承诺的无线电值 |
data-side | 内容、 位置 | 碰撞处理后计算侧面 |
data-align | 内容、 位置 | 碰撞处理后计算对齐 |
项目
| 属性 | 目标 | 说明 |
|---|---|---|
data-highlighted | 项目 | 当前突出项目 |
data-checked | 收音机、复选框项目 | 当前已执行的检查状态 |
data-disabled | 项目 | 已禁用的项目 |
data-variant | 项目 | 造型钩等 destructive |
data-inset | 项目 | 左起垫的样式钩 |
默认和选项
| 属性 | 目标 | 说明 |
|---|---|---|
data-default-open | 根号 | 初始打开状态 |
data-default-value | 根号 | 初步无线电值 |
data-default-values='["a","b"]' | 根号 | 作为 JSON 数组字符串的初始复选框值 |
data-default-checked | 收音机,复选框项目 | 项目级别默认已检查状态 |
data-close-on-click-outside | 根号 | 关闭外部互动 |
data-close-on-escape | 根号 | 退出时关闭 |
data-close-on-select | 根号 | 接受激活后关闭 |
data-highlight-item-on-hover | 根号 | 突出和突出悬浮项目 |
默认优先是:
- JavaScript 选项
- 根数据属性
- 项目
data-default-checked - 空状态
对于收音机项目,root默认胜过项目默认. 对于复选框项目, root data-default-values 胜过项目 data-default-checked。 。 。 .
选项
| 选项 | 数据属性 | 类型 | 默认 | 说明 |
|---|---|---|---|---|
defaultOpen | data-default-open | boolean | false | 初始打开状态 |
defaultValue | data-default-value | string | null | 那么项目默认 null | 初始无线电值; 明确无效清除项目默认值 |
defaultValues | data-default-values | string[] | 那么项目默认 [] | 初始复选框值; 将属性编码为 JSON 数组 |
closeOnClickOutside | data-close-on-click-outside | boolean | true | 关闭外部互动 |
closeOnEscape | data-close-on-escape | boolean | true | 退出时关闭 |
closeOnSelect | data-close-on-select | boolean | true | 接受用户激活后关闭 |
highlightItemOnHover | data-highlight-item-on-hover | boolean | true | 突出和突出悬浮项目 |
side | data-side | "top" | "right" | "bottom" | "left" | "bottom" | 首选弹出侧 |
align | data-align | "start" | "center" | "end" | "start" | 首选弹出对齐 |
sideOffset | data-side-offset | number | 4 | 距离触发器( px) |
alignOffset | data-align-offset | number | 0 | 页:1 |
avoidCollisions | data-avoid-collisions | boolean | true | 在视图端口内翻转 |
collisionPadding | data-collision-padding | number | 8 | 查看端口边缘粘贴 (px) |
lockScroll | data-lock-scroll | boolean | true | 打开时锁定页面滚动;启用时使用固定定位,禁用时使用绝对定位 |
onOpenChange | —— 说 | (open: boolean) => void | undefined | 打开状态更改时调用 |
onSelect | —— 说 | (value: string) => void | undefined | 在接受用户激活后调用 |
onValueChange | —— 说 | (value: string | null) => void | undefined | 执行的无线电选择更改时调用 |
onValuesChange | —— 说 | (values: string[]) => void | undefined | 已执行的复选框选择更改时调用 |
注释:
closeOnSelect默认为true多选择菜单通常想要false。 。 。 .onSelect音轨接受用户激活 。 它不会为方案状态的改变起火.onValueChange财务报告和审定财务报表onValuesChange遵守与DOM事件相同的沉默规则.
主计长
interface DropdownMenuController {
open(): void;
close(): void;
toggle(): void;
set(detail: DropdownMenuSetDetail): void;
readonly isOpen: boolean;
readonly value: string | null;
readonly values: string[];
readonly highlightedValue: string | null;
destroy(): void;
}
DropdownMenuSetDetail 是一个部分更新 :
interface DropdownMenuSetDetail {
open?: boolean;
value?: string | null;
values?: string[];
highlightedValue?: string | null;
source?: "programmatic" | "restore";
}
使用 value: null 清除无线电选择, values: [] 以清除复选框选择,以及 highlightedValue: null 清除亮点. source 默认为 "programmatic"。 。 。 .
set() 应用此顺序的字段 : value, (中文(简体) ), values, (中文(简体) ), open, (中文(简体) ), highlightedValue。 。 。 .
set({ value })进行无线电选择.set({ values })承诺选择复选框.set({ open })打开或关闭菜单.set({ highlightedValue })更新仅在菜单打开时突出显示.- 程序化
set()永远不释放dropdown-menu:select。 。 。 . - 无法更新 .
- 未知
value编号 :values目标被忽略,而不是扔出.
下游包装机合同
这个软件包不运送Astro组件, 但下游的包装器应该反映这个作者模型:
DropdownMenuItem调制data-slot="dropdown-menu-item"。 。 。 .DropdownMenuRadioItem调制data-slot="dropdown-menu-radio-item"和要求value。 。 。 .DropdownMenuCheckboxItem调制data-slot="dropdown-menu-checkbox-item"和要求value。 。 。 .- 收音机和收发箱包装可能曝光
defaultChecked,但根默认值仍然优先于项目默认值.
主计长销毁
destroy() 永久处理控制器并隐藏任何打开的表面,而不包含
产生额外的变化事件。 重复销毁是安全的
旧控制器变成无操作器。 在同一根上创建新控制器以重新组合 .
重心修复已经排入了近距离的队列 能够幸存的破坏.
活动
境外事件
| 活动 | 细节 | 页:1 |
|---|---|---|
dropdown-menu:open-change | { open, previousOpen, source, reason } | 实际开放状态变化的起火 |
dropdown-menu:change | 同样的细节 | 折旧的别名 open-change; 仅 detail.open 是相容性保证 |
dropdown-menu:highlight-change | { value, previousValue, item, previousItem, source } | value 财务报告和审定财务报表 item 变成 null 当亮度清澈 |
dropdown-menu:select | { value, item, itemType, source, checked? } | 可取消的,仅限用户使用,在实施前开火 |
dropdown-menu:value-change | { value, previousValue, item, previousItem, source } | 电台只承诺 |
dropdown-menu:values-change | { values, previousValues, changedValue, checked, item, source } | 只输入复选框 |
dropdown-menu:select 行为 :
- 只为用户激活尝试而起火. 已禁用的项目和方案更新不会发出.
- 若为
event.preventDefault(),不更改选择状态,也不发生自动关闭选择状态. - 程序更新从不发布.
dropdown-menu:value-change, (中文(简体) ), dropdown-menu:values-change, (中文(简体) ), onValueChange,以及 onValuesChange 对下列事项保持沉默:
- 初始化
- 无承诺
- 忽略未知目标
对于 dropdown-menu:values-change, (中文(简体) ), changedValue, (中文(简体) ), checked,以及 item 为: null 当一个程序更新一次更改多个复选框时.
入境事件
| 活动 | 细节 | 说明 |
|---|---|---|
dropdown-menu:set | DropdownMenuSetDetail | 部分方案状态更新 |
root.dispatchEvent(
new CustomEvent("dropdown-menu:set", {
detail: { value: "pro", source: "restore" },
})
);
root.dispatchEvent(
new CustomEvent("dropdown-menu:set", {
detail: { values: ["email", "push"], open: true },
})
);
事件顺序
用户无线电选择 :
dropdown-menu:selectdropdown-menu:value-changedropdown-menu:open-change如果菜单关闭
用户复选框选择 :
dropdown-menu:selectdropdown-menu:values-changedropdown-menu:open-change如果菜单关闭
程序选择 :
dropdown-menu:set或者说controller.set(...)dropdown-menu:value-change或者说dropdown-menu:values-change- 没有
dropdown-menu:select
如果关闭菜单也清除了已有的亮点, dropdown-menu:highlight-change 在关闭前释放 dropdown-menu:open-change。 。 。 .
样式
定位
放置属性( A)data-side, (中文(简体) ), data-align, (中文(简体) ), data-side-offset, (中文(简体) ), data-align-offset, (中文(简体) ), data-avoid-collisions, (中文(简体) ), data-collision-padding(a) 决定按此顺序:
- JavaScript 选项
dropdown-menu-contentdropdown-menu-positionerdropdown-menu根号
下拉菜单使用 position: fixed 默认并自动相对于触发器定位:
createDropdownMenu(root, {
side: "bottom",
align: "start",
sideOffset: 4,
alignOffset: 0,
avoidCollisions: true,
collisionPadding: 8,
});
何时 avoidCollisions ,菜单可能会在视图端口内翻转或移动。 定位要素还收到 --transform-origin 动画起源.
键盘导航
| 密钥 | 行动 |
|---|---|
Enter 编号 : Space | 从触发打开菜单, 或激活突出显示的项目 |
ArrowDown | 从触发打开菜单, 或者移动到下一个启用的项目 |
ArrowUp | 移动到上次启用的项目 |
Home | 移动到第一个启用的项目 |
End | 移动到上次启用的项目 |
Escape | 关闭菜单 |
Tab | 关闭菜单并继续执行标签顺序 |
A-Z | 按项目文本排列 |
移徙说明
如果您目前使用下拉菜单作为拾取器 :
- 替换拾取器样式
dropdown-menu-item使用时间dropdown-menu-radio-item或者说dropdown-menu-checkbox-item。 。 。 . - 停止手动写入
data-selected或者说data-checked。 。 。 . - 听着
dropdown-menu:value-change或者说dropdown-menu:values-change承诺状态. - 将外部恢复/随机处理/流行状态/存储的更改推回通过
controller.set(...)或者说dropdown-menu:set。 。 。 . - 切换打开状态的听众
dropdown-menu:change改为dropdown-menu:open-change。 。 。 .
折旧的APIs
以下相容性API被折旧后,将在下个主要发行中被去掉:
// Deprecated open-state alias
root.addEventListener("dropdown-menu:change", (event) => {
console.log(event.detail.open);
});
// Deprecated programmatic shape
root.dispatchEvent(
new CustomEvent("dropdown-menu:set", { detail: { value: true } })
);
使用 dropdown-menu:open-change 财务报告和审定财务报表 dropdown-menu:set { open: boolean } 换句话说.
许可证
麻省理工学院