# @data-slot/dropdown-menu 中文文档

规范地址：https://npmcn.com/package/%40data-slot/dropdown-menu/

版本：1\.1\.3
npm 元数据更新时间：2026-11-05T12:12:34.611Z
中文译文更新时间：2026-11-11T13:14:14.347Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40data-slot/dropdown-menu
原文对照：https://npmcn.com/package/%40data-slot/dropdown-menu/?lang=original
项目主页：https://github.com/bejamas/data-slot#readme
源码仓库：https://github.com/bejamas/data-slot

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：58.3 kB，6 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- 运行依赖：1 个
- 首次发布：2026-01-18T17:41:59.906Z
- 最新版本发布：2026-11-05T12:12:34.266Z
- 近 30 天下载量：6656（2026-10-12 至 2026-11-10，npm 官方下载统计）
- 已发布版本数：157（近 12 个月 157 个）

## 中文简介

香草JavaScript的无头下放菜单. 支持动作项目,单选收音机项目,以及全键盘导航和ARIA支持的多选取复选框项目.

## 安装

```sh
npm install @data-slot/dropdown-menu
```

也可以使用：`pnpm add @data-slot/dropdown-menu`、`yarn add @data-slot/dropdown-menu`、`bun add @data-slot/dropdown-menu`

## README

# @ data- slot/ 下拉菜单

香草JavaScript的无头下放菜单. 支持动作项目,单选收音机项目,以及全键盘导航和ARIA支持的多选取复选框项目.

## 安装

```bash
npm install @data-slot/dropdown-menu
```

## 使用量

### 动作菜单

```html
<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>
```

### 单选菜单

```html
<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>
```

### 多选择菜单

```html
<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 脚本

```js
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`。 。 。 .

```typescript
import { create } from "@data-slot/dropdown-menu";

const controllers = create();
```

#### `createDropdownMenu(root, options?)`

创建一个 `DropdownMenuController` 用于一个根元素。 JavaScript 选项优先于相应的数据属性. 再次调用此选项为绑定根返回其已存在的控制器; 在重新绑定新选项前将其销毁 .

```typescript
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` - 可选键盘快捷提示;显示它不会注册键盘快捷键.

#### 由门户标记构成

```html
<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` | 根号 | 突出和突出悬浮项目 |

默认优先是:

1.  JavaScript 选项
2.  根数据属性
3.  项目 `data-default-checked`
4.  空状态

对于收音机项目,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事件相同的沉默规则.

### 主计长

```ts
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` 是一个部分更新 :

```ts
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` | 部分方案状态更新 |

```js
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 },
  })
);
```

#### 事件顺序

用户无线电选择 :

1.  `dropdown-menu:select`
2.  `dropdown-menu:value-change`
3.  `dropdown-menu:open-change` 如果菜单关闭

用户复选框选择 :

1.  `dropdown-menu:select`
2.  `dropdown-menu:values-change`
3.  `dropdown-menu:open-change` 如果菜单关闭

程序选择 :

1.  `dropdown-menu:set` 或者说 `controller.set(...)`
2.  `dropdown-menu:value-change` 或者说 `dropdown-menu:values-change`
3.  没有 `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) 决定按此顺序:

1.  JavaScript 选项
2.  `dropdown-menu-content`
3.  `dropdown-menu-positioner`
4.  `dropdown-menu` 根号

下拉菜单使用 `position: fixed` 默认并自动相对于触发器定位:

```js
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被折旧后,将在下个主要发行中被去掉:

```js
// 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 }` 换句话说.

## 许可证

麻省理工学院

## 常见问题

### @data-slot/dropdown-menu 是什么？

香草JavaScript的无头下放菜单\. 支持动作项目,单选收音机项目,以及全键盘导航和ARIA支持的多选取复选框项目\.

### 如何安装 @data-slot/dropdown-menu？

在项目目录运行 npm install @data-slot/dropdown-menu，或使用 pnpm add / yarn add / bun add。

### @data-slot/dropdown-menu 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @data-slot/dropdown-menu 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @data-slot/dropdown-menu 可以商用吗？

@data-slot/dropdown-menu 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @data-slot/dropdown-menu 的下载量有多少？

根据 npm 官方下载统计，@data-slot/dropdown-menu 在 2026/10/12 – 2026/11/10 这 30 天内被下载 6,656 次，日均约 222 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @data-slot/dropdown-menu 还在维护吗？

最新版本 1\.1\.3 发布于 2026/11/05（6 天前）；至今共发布 157 个版本，其中过去 12 个月发布了 157 个；首次发布于 2026/01/19。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

