气泡卡片 popover
反馈与浮层组件。三层同源:无头内核给出解剖与状态机,Vue 组件与自定义元素只是它的两层外壳,行为完全一致。
示例
基础用法
点击展开,Escape 或点外部关闭;positioner 负责摆位,content 才是浮层本体
订阅设置
role=dialog,触发器与内容四处 ARIA 互指;非模态,焦点不被陷住。
朝向与间距
placement 是请求值,空间不够时定位引擎会自动翻面;offset 调的是浮层与触发器的距离
请求的朝向是 top。
请求的朝向是 right。
请求的朝向是 bottom-end。
受控
传了 open 就由宿主说了算;这里额外关掉点外部关闭,只有按钮与 Escape 能收起
受控浮层
点页面别处不再关它,Escape 仍然有效。
尺寸
三档换的是浮层的内边距与字号,不写 size 即缺省档;逐个点开触发器看差别
小档
size = sm。
缺省档
size = 未指定。
大档
size = lg。
确认气泡
标题、说明与两颗按钮拼成一次就地确认;两颗按钮都只调 setOpen 收起浮层
删除后不可恢复
这条记录连同它的附件一起清掉。
长内容滚动
浮层自己不限高,给里面的容器设上限并开滚动,标题与关闭按钮就不跟着滚
历史版本
v1.18 更新了若干细节
v1.17 更新了若干细节
v1.16 更新了若干细节
v1.15 更新了若干细节
v1.14 更新了若干细节
v1.13 更新了若干细节
v1.12 更新了若干细节
v1.11 更新了若干细节
v1.10 更新了若干细节
v1.9 更新了若干细节
v1.8 更新了若干细节
v1.7 更新了若干细节
v1.6 更新了若干细节
v1.5 更新了若干细节
v1.4 更新了若干细节
v1.3 更新了若干细节
v1.2 更新了若干细节
v1.1 更新了若干细节
模态浮层
modal 让焦点陷在浮层里:Tab 到末尾回绕,旁边那颗按钮这时接不到焦点
移动到分组
按 Tab 试试,焦点只在浮层里打转。
事件
open-change 带一份 { open },报的是这次要落到的状态;非受控时内部开合也照发一次
按钮、Escape、点浮层外部,三条路都会发一次意图。
书写方向
start / end 是逻辑对齐不是左右:RTL 下 bottom-start 贴的是锚点右缘,块轴上的对齐不受影响
start
LTR 贴左缘,RTL 贴右缘
end
与 start 恰好相反
浮层与触发器同宽
量出触发器的实际宽度写进 content 的行内样式,同时解掉最大宽度上限;触发器换了文案宽度也跟着走
切换环境
面板宽 0 像素,与触发器一致。
落在指针位置
触发器缩成一个像素、按点击坐标固定摆放,浮层就钉在刚点到的那一点上;再点一下换个落点
这一点
落点 0 / 0,按 Escape 收起。
产物
| 层 | 值 |
|---|---|
| 自定义元素 | <xh-popover> |
| Vue 组件 | XhPopoverArrow XhPopoverCloseTrigger XhPopoverContent XhPopoverDescription XhPopoverPositioner XhPopoverRoot XhPopoverTitle XhPopoverTrigger |
| 组合式函数 | usePopover |
| 状态机 | popoverMachine |
| 皮肤 | @xihan-ui/styles/popover.css |
解剖
部件名即 data-part 属性值,也是皮肤的选择器。加粗的是必备部件,不渲染它组件不工作(Web Components 适配器会在诊断通道上报 wc.missing-part)。
data-scope="popover":trigger · positioner · content · title · description · close-trigger · arrow
Props
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
open | boolean | ||
defaultOpen | boolean | ||
placement | Placement | ||
dir | Direction | 文字方向,缺省 ltr。只改写浮层在行内轴上 start 与 end 的落点。 | |
offset | number | ||
modal | boolean | 模态浮层陷住焦点;默认 false(非模态,Tab 可离开)。 | |
closeOnEscape | boolean | ||
closeOnInteractOutside | boolean | ||
translations | Partial<PopoverTranslations> | ||
size | Size | 尺寸:sm / md / lg,决定面板的内边距档位。 | |
onOpenChange | (details: PopoverOpenChangeDetails) => void | open 变化意图回调;受控时是唯一出口,非受控时随内部转移一并通知。 |
状态机
状态:open · closed
事件:OPEN · TOGGLE · CLOSE · CONTROLLED.OPEN · CONTROLLED.CLOSE
判据:isOpenControlled
connect API
usePopover 产出的对象。getXxxProps() 铺到对应部件的宿主元素上,其余是可读状态与操作入口。
| 成员 | 类型 | 说明 |
|---|---|---|
open | boolean | |
setOpen | (next: boolean) => void | |
getTriggerProps | () => T['button'] | |
getPositionerProps | () => T['element'] | |
getContentProps | () => T['element'] | |
getTitleProps | () => T['element'] | |
getDescriptionProps | () => T['element'] | |
getCloseTriggerProps | () => T['button'] | |
getArrowProps | () => T['element'] |
键盘
规格出处:W3C APG
| 按键 | 生效条件 | 行为 |
|---|---|---|
Enter / Space | focus in trigger | 切换开合,展开时把焦点移入 content |
Escape | open | 关闭并把焦点还给 trigger |
Tab | open 且 modal | 在 content 内向后循环焦点 |
Shift+Tab | open 且 modal | 在 content 内向前循环焦点 |
