跳到主要内容

Popover 气泡卡片

点击一个按钮,在它旁边弹出一小块可以交互的内容:筛选条件、快速编辑、补充设置。它不打断页面(非模态)。只是一句说明用 Tooltip;一串操作用 Menu;需要用户必须处理完才能继续时用 Dialog。

基本用法

trigger 是一个能接收 ref 和事件的元素,通常是 Button。打开时焦点移进浮层,Esc 或点外面关闭,关闭后焦点回到触发按钮。记得给浮层 aria-label。

位置

placement 由“方向”和可选的“对齐”组成,默认 bottom(居中)。放不下时自动翻到对面,并沿边缘平移回视口内。

受控与关闭

children 传函数可以拿到 close(关闭并把焦点还给触发按钮)。用 open / onOpenChange 受控。想指定打开时聚焦谁,给那个元素加 data-autofocus,或传 initialFocus。

当前名称:未命名项目 · 浮层已关闭

关闭方式

closeOnOutsidePress / closeOnEscape 可以分别关掉。两个都关时,浮层里必须有一个明确的关闭按钮。

相对别的元素定位

anchorRef 让浮层相对另一个元素定位(触发按钮仍然负责开关)。matchWidth 让浮层和锚点等宽,'min' 表示不窄于锚点。

浮层相对这一整条定位

API

属性

属性类型默认值说明
trigger*ReactElement—触发元素:要能接收 ref 和事件。会被补上 aria-haspopup、aria-expanded、aria-controls 和 onClick。
children*ReactNode | ({ close }) => ReactNode—内容;传函数可以拿到 close。
openboolean—是否打开(受控)。
defaultOpenbooleanfalse初始是否打开(非受控)。
onOpenChange(open: boolean) => void—开关状态变化时触发。
placement'top' | 'bottom' | 'left' | 'right' 及其 -start / -end'bottom'相对锚点的位置。
offsetnumber8与锚点的间距(px)。
matchWidthboolean | 'min'falsetrue:与锚点等宽;'min':不窄于锚点。
anchorRefRefObject<Element>—相对另一个元素定位,默认相对触发元素。
initialFocusRefObject<HTMLElement>—打开时聚焦的元素;不传则找 [data-autofocus],再是第一个可聚焦元素,最后是浮层本身。
autoFocusbooleantrue打开时是否把焦点移进去。
closeOnOutsidePressbooleantrue点外面关闭。
closeOnEscapebooleantrue按 Esc 关闭。
rolestring'dialog'浮层的角色。
…restHTMLAttributes<HTMLDivElement>—其余属性(aria-label、className…)和 ref 落在浮层上。

无障碍

  • 浮层是 role="dialog"(非模态),请用 aria-label 或 aria-labelledby 给它起名。触发元素带 aria-haspopup="dialog" 和 aria-expanded。
  • Enter / Space 在触发按钮上打开或关闭;打开后焦点移进浮层。
  • Esc 关闭并把焦点还给触发按钮;点外面关闭时不抢焦点。
  • 不困住焦点:Tab 走过最后一个元素(或 Shift+Tab 走过第一个)时浮层关闭,焦点从触发按钮继续往下(上)走。
  • 浮层渲染在 body 末尾的 portal 里;嵌套的浮层(浮层里的 Select 等)点击时不算“点外面”。
  • 不要用悬停触发 Popover——触屏和键盘用户用不了。