# @data-slot/popover 中文文档

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

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

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

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

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

- 包体积（解压后）：25.3 kB，6 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- 运行依赖：1 个
- 首次发布：2026-01-09T14:58:23.614Z
- 最新版本发布：2026-11-05T12:19:02.092Z
- 近 30 天下载量：4552（2026-10-12 至 2026-11-10，npm 官方下载统计）
- 已发布版本数：164（近 12 个月 164 个）

## 中文简介

香草JavaScript的无头弹出器组件. 无障碍而无作相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相.

## 安装

```sh
npm install @data-slot/popover
```

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

## README

# @ data- slot/ popover 数据位/ popover

香草JavaScript的无头弹出器组件. 无障碍而无作相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相.

## 安装

```bash
npm install @data-slot/popover
```

## 快速启动

```html
<div data-slot="popover">
  <button data-slot="popover-trigger">Open Popover</button>
  <div data-slot="popover-content" hidden>
    <p>Popover content here</p>
    <button data-slot="popover-close">Close</button>
  </div>
</div>

<script type="module">
  import { create } from "@data-slot/popover";
  
  const controllers = create();
</script>
```

## API 密码

### 初始化

#### `create(scope?)`

自动发现并绑定一个范围内的所有弹出例(默认为 `document`) (中文(简体) ).

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

const controllers = create(); // Returns PopoverController[]
```

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

为特定元素创建控制器.

```typescript
import { createPopover } from "@data-slot/popover";

const popover = createPopover(element, {
  defaultOpen: false,
  side: "bottom",
  align: "center",
  sideOffset: 4,
  alignOffset: 0,
  avoidCollisions: true,
  collisionPadding: 8,
  portal: true,
  closeOnClickOutside: true,
  closeOnEscape: true,
  onOpenChange: (open) => console.log(open),
});
```

### 槽数

#### 运行时间槽

-   `popover` - 管理开放状态的根元素.
-   `popover-trigger` - 需要的按钮 切换弹出并锁定它的位置.
-   `popover-content` - 需要包含弹出器内容的浮面板.
-   `popover-close` - 关闭弹出器的内容中的可选按钮.
-   `popover-positioner` - 内容周围可选作者定位包装,再利用而不是生成包装.
-   `popover-portal` - 可选作者的门户包装,可以包含位置和内容.

#### 标记

```html
<div data-slot="popover">
  <button data-slot="popover-trigger">Trigger</button>
  <div data-slot="popover-content">
    Content
    <button data-slot="popover-close">Close</button>
  </div>
</div>
```

#### 由门户网站标记( 可选)

```html
<div data-slot="popover">
  <button data-slot="popover-trigger">Trigger</button>
  <div data-slot="popover-portal">
    <div data-slot="popover-positioner">
      <div data-slot="popover-content">Content</div>
    </div>
  </div>
</div>
```

### 数据属性

选项也可以通过数据属性设定. 联合来文的选择优先于数据属性.

放置属性( A)`data-side`, (中文(简体) ), `data-align`, (中文(简体) ), `data-side-offset`, (中文(简体) ), `data-align-offset`, (中文(简体) ), `data-avoid-collisions`, (中文(简体) ), `data-collision-padding`(a) 决定按此顺序:

1.  JavaScript 选项
2.  `popover-content`
3.  `popover-positioner`
4.  `popover` 根 (倒计时)

| 属性 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `data-default-open` | 布尔 | `false` | 初始打开状态 |
| `data-side` | 字符串 | `"bottom"` | 首选侧面 |
| `data-align` | 字符串 | `"center"` | 首选对齐 |
| `data-side-offset` | 编号 | `4` | 距离触发器( px) |
| `data-align-offset` | 编号 | `0` | 从对齐边缘抵消 (px) |
| `data-avoid-collisions` | 布尔 | `true` | 翻转/移入景点 |
| `data-collision-padding` | 编号 | `8` | 查看端口边缘粘贴 (px) |
| `data-portal` | 布尔 | `true` | 门户内容到 `document.body` 打开时 |
| `data-close-on-click-outside` | 布尔 | `true` | 点击外部时关闭 |
| `data-close-on-escape` | 布尔 | `true` | 按下 Escape 键时关闭 |

布尔属性: 存在或 `"true"` 没错, `"false"` =虚假,缺席=默认.

位置可以设置在 root,内容上,也可以设置作者位置(内容优先):

```html
<div data-slot="popover-content" data-side="top" data-align="end">
```

`data-position` 仍支持为已贬值的倒置别名 `data-side`。 。 。 .

```html
<!-- Popover that stays open when clicking outside -->
<div data-slot="popover" data-close-on-click-outside="false">
  ...
</div>
```

### 选项

| 选项 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `defaultOpen` | `boolean` | `false` | 初始打开状态 |
| `side` | `"top" | "right" | "bottom" | "left"` | `"bottom"` | 首选边相对触发 |
| `align` | `"start" | "center" | "end"` | `"center"` | 偏好侧轴对齐 |
| `sideOffset` | `number` | `4` | 距离像素触发器 |
| `alignOffset` | `number` | `0` | 从像素中的对齐边缘抵消 |
| `avoidCollisions` | `boolean` | `true` | 翻转/移入景点 |
| `collisionPadding` | `number` | `8` | 以像素为单位的视图端点 |
| `portal` | `boolean` | `true` | 门户内容到 `document.body` 打开时 |
| `position` | `"top" | "bottom" | "left" | "right"` | \- 说吧 | 折旧的别名 `side` |
| `closeOnClickOutside` | `boolean` | `true` | 点击外部时关闭 |
| `closeOnEscape` | `boolean` | `true` | 按下 Escape 键时关闭 |
| `onOpenChange` | `(open: boolean) => void` | `undefined` | 打开状态更改时召回 |

### 主计长

| 方法/财产 | 说明 |
| --- | --- |
| `open()` | 打开弹珠 |
| `close()` | 关闭弹出器 |
| `toggle()` | 切换弹出 |
| `isOpen` | 当前打开状态( 只读) `boolean`(中文(简体) ) |
| `destroy()` | 清理所有事件听众 |

#### 主计长销毁

`destroy()` 永久处理控制器并隐藏任何打开的表面,而不包含 产生额外的变化事件。 重复销毁是安全的 旧控制器变成无操作器。 在同一根上创建新控制器以重新组合 .

重心修复已经排入了近距离的队列 能够幸存的破坏.

### 活动

#### 境外事件

通过自定义事件聆听更改 :

```javascript
element.addEventListener("popover:change", (e) => {
  console.log("Popover open:", e.detail.open);
});
```

#### 入境事件

通过事件控制弹出:

| 活动 | 细节 | 说明 |
| --- | --- | --- |
| `popover:set` | `{ open: boolean }` | 方案设置开放状态 |

```javascript
// Open the popover
element.dispatchEvent(
  new CustomEvent("popover:set", { detail: { open: true } })
);

// Close the popover
element.dispatchEvent(
  new CustomEvent("popover:set", { detail: { open: false } })
);
```

##### 折旧形状

下出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出入出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出入出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出

-   `popover:set` 细节 `{ value: boolean }` (使用时 `{ open: boolean }`(中文(简体) )
-   `position` 选项(使用 `side`(中文(简体) )
-   `data-position` 属性( 使用 `data-side`(中文(简体) )

```javascript
// Deprecated: { value: boolean }
element.dispatchEvent(
  new CustomEvent("popover:set", { detail: { value: true } })
);
```

使用上述替换.

### 样式

Popover 位置在 JavaScript 中计算并应用为 `position: absolute` + 内置 `transform: translate3d(...)`。 。 。 . 默认情况下,内容被传送到 `document.body` 打开时(文档坐标)。 如果你提供作者 `popover-positioner` 编号 : `popover-portal` 插槽,这些被重新使用。 否则就是短暂的 `popover-positioner` 包装器生成 . 若为 `portal` ,定位直接应用到 `popover-content`。 。 。 . 定位要素`popover-positioner`,或 `popover-content` 何时 `portal` (已禁用)还收到 `--transform-origin` 所以弹出动画可以由触发锚产生. 使用 `data-open`编号 :`data-closed` 财务报告和审定财务报表 `data-side` 用于造型/活化. 一直这样 `popover-content` 免费用于转换动画. 定位使用布局尺寸,所以 `scale`编号 :`zoom` 动画打开 `popover-content` 为稳定定位,不需要额外内部包装.

```css
[data-slot="popover-content"] {
  transform-origin: var(--transform-origin, center);
  --popover-slide-x: 0px;
  --popover-slide-y: -4px;
}

[data-slot="popover-content"][data-side="top"] {
  --popover-slide-y: 4px;
}
[data-slot="popover-content"][data-side="bottom"] {
  --popover-slide-y: -4px;
}
[data-slot="popover-content"][data-side="left"] {
  --popover-slide-x: 4px;
  --popover-slide-y: 0px;
}
[data-slot="popover-content"][data-side="right"] {
  --popover-slide-x: -4px;
  --popover-slide-y: 0px;
}

[data-slot="popover-content"][data-open] {
  animation: popover-in 160ms cubic-bezier(0.16, 1, 0.3, 1);
}

[data-slot="popover-content"][data-closed] {
  pointer-events: none;
  animation: popover-out 120ms ease-in forwards;
}

@keyframes popover-in {
  from {
    opacity: 0;
    scale: 0.96;
    translate: var(--popover-slide-x) var(--popover-slide-y);
  }
  to {
    opacity: 1;
    scale: 1;
    translate: 0 0;
  }
}

@keyframes popover-out {
  from {
    opacity: 1;
    scale: 1;
    translate: 0 0;
  }
  to {
    opacity: 0;
    scale: 0.96;
    translate: var(--popover-slide-x) var(--popover-slide-y);
  }
}
```

以尾风:

```html
<div data-slot="popover">
  <button data-slot="popover-trigger">Open</button>
  <div
    data-slot="popover-content"
    data-side="bottom"
    data-align="start"
    class="absolute bg-white shadow-lg p-4"
  >
    Content
  </div>
</div>
```

将 Tailwind 用于布局/ 颜色, 并保留上面 CSS 片断中的状态选择器用于淡出/ zoom 动画 .

### 键盘导航

| 密钥 | 行动 |
| --- | --- |
| `Enter` 编号 : `Space` | 切换弹出( 触发) |
| `Escape` | 关闭弹出和返回焦点以触发 |

### 无障碍

该组件自动处理 :

-   `aria-haspopup="dialog"` 触发
-   `aria-controls` 连接触发到内容
-   `aria-expanded` 启动状态
-   内容独有的ID生成

## 许可证

麻省理工学院

## 常见问题

### @data-slot/popover 是什么？

香草JavaScript的无头弹出器组件\. 无障碍而无作相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相\.

### 如何安装 @data-slot/popover？

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

### @data-slot/popover 支持 TypeScript 吗？

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

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

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

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

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

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

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

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

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

