组件

Popover

一个非模态 React 浮层,锚定在触发元素旁,采用 Liquid Glass 面板。

Popover 内部渲染触发元素、Portal、定位器、玻璃弹窗、指向缺口、标题、描述、可选正文以及可选操作区。指向缺口会自动跟随弹窗实际所在的方位;设置 arrow={false} 可以隐藏它。

与 Dialog 和 Drawer 不同,Popover 默认是非模态的:不会锁定焦点,页面仍可滚动,点击外部或按 Esc 会关闭。适合紧凑的设置面板、上下文操作和筛选条件。

基础示例

trigger 接收单个元素,并且该元素需要把 props 和 ref 透传到根元素,例如内置的 Button。组件会自动为触发元素添加 aria-haspopup="dialog" 和 aria-expanded,点击即可切换浮层。此示例为非受控用法。

受控用法

open 与 onOpenChange 控制显示状态。footer 中的按钮不会自动关闭浮层,需要像示例一样自行更新 open。

No release published.

定位

side、align、sideOffset 和 alignOffset 控制弹窗定位。空间不足时,弹窗会自动翻转或平移。

偏移与箭头

align、alignOffset 与 collisionPadding 会在确定首选方向后进一步微调位置。设置 arrow={false} 可以让浮层不带箭头、紧贴触发器显示。

无障碍

Popover 会为触发器添加 aria-haspopup="dialog" 与 aria-expanded,并渲染由 title 命名、由 description 描述的浮层。

默认是非模态的:焦点不会被限制,页面仍可滚动,Escape 或点击外部会关闭。浮层会修改设置时,请提供可见的关闭或完成操作。当前封装无法通过 modal 启用焦点陷阱:Base UI 只有在渲染了 Popover.Close 时才会启用,而组件没有渲染该部分。modal={true} 仍会锁定页面滚动并阻止外部交互。焦点规则见可访问性指南。

API 参考

属性类型默认值说明
triggerReactElement—打开浮层的元素,必填;需要透传 props 和 ref。
titleReactNode—浮层标题,必填。
descriptionReactNode—标题下方的说明文字。
childrenReactNode—描述与操作区之间的正文内容。
footerReactNode—底部操作区,可放置任意数量的控件。
arrowbooleantrue是否渲染指向缺口。
side"top" | "bottom" | "left" | "right" | "inline-start" | "inline-end""bottom"优先放置在触发元素的哪一侧。
align"start" | "center" | "end""center"相对于触发元素的对齐方式。
sideOffsetnumber | OffsetFunction10触发元素与弹窗之间的距离(像素)。
alignOffsetnumber | OffsetFunction0沿对齐轴的偏移量(像素)。
collisionPaddingPadding每侧 5px弹窗与碰撞边界之间保留的空间。
openboolean—受控的打开状态。
defaultOpenbooleanfalse非受控时的初始打开状态。
onOpenChange(open: boolean, details) => void—浮层打开或关闭时调用。
onOpenChangeComplete(open: boolean) => void—打开或关闭动画结束后调用。
modalboolean | "trap-focus"falsetrue 会锁定页面滚动并阻止外部交互;"trap-focus" 不锁定滚动,也保留外部交互。组件未渲染 Popover.Close,因此两者都不会启用焦点陷阱。
actionsRefRefObject<Actions | null>—命令式的 close 与 unmount 操作。
handlePopoverHandle—将浮层与外部触发器关联。
triggerIdstring | null—与浮层关联的触发器 ID。
defaultTriggerIdstring | null—初始打开时使用的触发器 ID。
classNamestring—合并到弹窗的 Tailwind 类名。
styleCSSProperties—内联样式,合并到与 className 相同的元素。
ui{ positioner?: ClassValue; popup?: ClassValue; glass?: ClassValue; overlay?: ClassValue; arrow?: ClassValue; content?: ClassValue; title?: ClassValue; description?: ClassValue; body?: ClassValue; footer?: ClassValue }—按 data-slot 组织的内部槽位类名。
属性说明
data-open弹窗打开时存在。
data-closed弹窗关闭时存在。
data-starting-style弹窗开始进入动画时存在。
data-ending-style弹窗正在退出动画时存在。
data-side表示解析后的方位(top、bottom、left、right、inline-start 或 inline-end)。
data-align表示解析后的对齐方式(start、center 或 end)。
data-instant动画需要跳过时存在(click、dismiss、focus 或 trigger-change)。
data-anchor-hidden锚点隐藏时存在。
data-uncentered指向缺口未居中时存在。
data-popup-open弹窗打开时存在于触发元素上。
data-pressed触发元素被按下时存在。
data-slot标记内部部件(positioner、popup、glass、overlay、arrow、content、title、description、body、footer),用于样式选择。

主题

组件使用共享玻璃材质。可以在父级调整 --ui-glass-* token,用 className 控制布局,并通过 ui 按 data-slot 调整内部槽位。组件级数值位于 src/theme/popover.ts。Token 分层与预设见主题指南。

相关组件

  • Tooltip — 简短、非交互的提示。
  • Menu — 操作列表。
  • Dialog — 需要焦点限制的模态内容。