@ data- slot/ popover 数据位/ popover
香草JavaScript的无头弹出器组件. 无障碍而无作相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相.
安装
npm install @data-slot/popover
快速启动
<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) (中文(简体) ).
import { create } from "@data-slot/popover";
const controllers = create(); // Returns PopoverController[]
createPopover(root, options?)
为特定元素创建控制器.
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- 可选作者的门户包装,可以包含位置和内容.
标记
<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>
由门户网站标记( 可选)
<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) 决定按此顺序:
- JavaScript 选项
popover-contentpopover-positionerpopover根 (倒计时)
| 属性 | 类型 | 默认 | 说明 |
|---|---|---|---|
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,内容上,也可以设置作者位置(内容优先):
<div data-slot="popover-content" data-side="top" data-align="end">
data-position 仍支持为已贬值的倒置别名 data-side。 。 。 .
<!-- 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() 永久处理控制器并隐藏任何打开的表面,而不包含
产生额外的变化事件。 重复销毁是安全的
旧控制器变成无操作器。 在同一根上创建新控制器以重新组合 .
重心修复已经排入了近距离的队列 能够幸存的破坏.
活动
境外事件
通过自定义事件聆听更改 :
element.addEventListener("popover:change", (e) => {
console.log("Popover open:", e.detail.open);
});
入境事件
通过事件控制弹出:
| 活动 | 细节 | 说明 |
|---|---|---|
popover:set | { open: boolean } | 方案设置开放状态 |
// 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(中文(简体) )
// 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 为稳定定位,不需要额外内部包装.
[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);
}
}
以尾风:
<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生成
许可证
麻省理工学院