跳转到内容

HoverCard 悬浮卡片 ​

指针停留后出现的信息卡:预览一个对象,不打断当前操作。

用法 ​

与 Tooltip 的分界在于卡片本体可交互:指针停在卡片上不收起,其中的链接与按钮都可点击

最近这批组件由
推上来。

组件结构 ​

加粗的是必需部件。

data-scope="hover-card":root · trigger · positioner · content · title · description · arrow

示例 ​

延时 ​

openDelay 默认 700ms,closeDelay 默认 300ms:收起等待正是留给指针从触发器移动到卡片上的通行时间

受控 ​

传入 open 后由宿主决定;悬停与 Escape 都只发意图,最终是否写回由外部按钮共用的同一份状态决定

当前:收起

尺寸 ​

三档改变卡片的内边距与字号,不写 size 即默认档;把指针停在触发器上查看差别

朝向与间距 ​

placement 是请求值,空间不足时定位引擎会自动翻面;offset 调整卡片与触发器的距离

禁用 ​

disabled 只关闭卡片本身,触发器照常可点击、可聚焦,也照常不进入展开等待

已点 0 次

设计指引 ​

何时使用 ​

  • 链接或头像的预览:用户资料、文档摘要、商品简介。
  • 信息属于顺带查看的内容,不需要专门点击。

何时不用 ​

  • 内容需要交互(按钮、表单)时,使用气泡卡片。
  • 只有一句文字时,使用文字提示。
  • 触摸端是主要场景。

特性 ​

  • openDelay 与 closeDelay 成对:进入需要停留、离开有宽限,指针斜向移到卡片上不会误收。
  • 开合状态可受控。
  • 内容与 Popover 共用 M2 磨砂面:单层背景模糊、柔和顶光和浮层阴影,正文保持不透明。箭头只复用底色与边界,不叠加模糊;减少透明、高对比与强制色偏好由材质令牌统一响应。--xh-hover-card-backdrop 可覆盖模糊配方;打印时整块预览收起。

组合 ​

  • 触发器通常是头像或链接;卡片内使用卡片式的排版。

最佳实践 ​

  • 打开延时设为几百毫秒,否则指针扫过一段文字会弹出一串卡片。
  • 卡片内的信息在其他位置也应有正式入口。

反模式 ​

  • 卡片内放操作按钮:指针移动过去的途中可能已经关闭。
  • 延时为 0。

API 参考 ​

产物 ​

层值
自定义元素<xh-hover-card>
Vue 组件XhHoverCardArrow XhHoverCardContent XhHoverCardDescription XhHoverCardPositioner XhHoverCardRoot XhHoverCardTitle XhHoverCardTrigger
组合式函数useHoverCard
状态机hoverCardMachine
皮肤@xihan-ui/styles/hover-card.css

Props ​

属性类型必填说明
openboolean
defaultOpenboolean
placementPlacement请求的浮层朝向,默认 bottom;空间不足时由定位引擎避让。
offsetnumber浮层与锚点的间距(px)。
openDelaynumber悬停进入到展开的等待毫秒,默认 700。
closeDelaynumber指针离开 trigger 或 content 到收起的等待毫秒,默认 300。
dirDirection文字方向,仅在显式提供时写到根节点上。
disabledboolean只关闭卡片本身,不影响 trigger 元素自身的可用性。
sizeSize尺寸:sm / md / lg,决定卡片的内边距档位。
onOpenChange(details: HoverCardOpenChangeDetails) => voidopen 变化意图回调。

事件 ​

自定义元素将载荷放在 detail;Vue 使用同名 emit。

事件载荷说明
open-changeHoverCardOpenChangeDetailsopen 状态变化;detail 为 { open: boolean }

插槽 ​

仅列出带载荷的插槽。

Vue 组件插槽载荷说明
XhHoverCardRootdefaultHoverCardRootSlotProps

React 适配器 props ​

只列各组件自己声明的那些:继承自 ComponentPropsWithRef 的 DOM 属性不在其中,根组件上与上面 Props 表同名的也不重复列。Vue 的对应物是上面的插槽表。

React 组件属性类型必填说明
XhHoverCardPositionercontainer() => Element | null浮层挂载的容器;未提供时按全局配置,再未提供时挂载到 body。
XhHoverCardRootchildrenSlotChildren<HoverCardRootSlotProps>

状态 ​

公开状态写入 data-state。

部件取值
root'open' | 'closed'
trigger'open' | 'closed'
positioner'open' | 'closed'
content'open' | 'closed'

以下名称仅用于内部状态机。

状态:closed · opening · visible · visible.open · visible.closing

事件:POINTER.ENTER · POINTER.LEAVE · FOCUS · BLUR · ESCAPE · OPEN · CLOSE · after.openDelay · after.closeDelay · CONTROLLED.OPEN · CONTROLLED.CLOSE

判据:isOpenControlled · isDisabled · isFocusHeld

connect API ​

getXxxProps() 返回对应部件的宿主属性。

成员类型说明
openboolean
setOpen(next: boolean) => void
getRootProps() => T['element']
getTriggerProps() => T['button']
getPositionerProps() => T['element']
getContentProps() => T['element']
getTitleProps() => T['element']
getDescriptionProps() => T['element']
getArrowProps() => T['element']

无障碍 ​

键盘 ​

规格出处:W3C APG

按键生效条件行为
Tab / Shift+Tabnot disabled焦点进入 trigger 立即展开、离开卡片即收起,都不走延时
Escape浮层可见(含收起等待期)立即收起,不等 closeDelay

ARIA ​

以下属性由 connect 生成。

部件属性值
triggeraria-controlscontent 部件的 id
triggeraria-expanded'true' | 'false'
triggeraria-haspopup'dialog'
contentaria-describedbydescription 部件的 id | undefined
contentaria-hidden!open || undefined
contentaria-labelledbytitle 部件的 id | trigger 部件的 id
contentaria-modal'false'
contentrole'dialog'
arrowaria-hidden'true'

样式参考 ​

皮肤 ​

@xihan-ui/styles/hover-card.css 使用 [data-scope="hover-card"][data-part="root"] 部件选择器,位于 xihan.components 层。覆盖样式使用 xihan.overrides。

forced-colors: active 下另有一套规则:颜色交给系统,边框与状态标记改用系统色关键字。

数据属性 ​

由 connect 生成;条件不成立时不输出无值属性。

部件属性值
rootdata-disabled''(条件成立时才出现)
rootdata-state'open' | 'closed'
triggerdata-disabled''(条件成立时才出现)
triggerdata-state'open' | 'closed'
positionerdata-hidden''(条件成立时才出现)
positionerdata-placement定位引擎算出的实际落位
positionerdata-positioned''(条件成立时才出现)
positionerdata-state'open' | 'closed'
contentdata-placement定位引擎算出的实际落位
contentdata-sizeprops.size
contentdata-state'open' | 'closed'
contentdata-xh-material'frosted'
arrowdata-placement定位引擎算出的实际落位

CSS 变量 ​

本组件公开覆盖槽由独立皮肤的实际消费位生成;默认来源、作用部件和状态均与 CSS 同源。

变量部件CSS 属性状态默认来源说明
--xh-hover-card-arrow-sizearrow--xh-_overlay-arrow-sizedefault--xh-overlay-arrow-sizehover-card 的 arrow 部件 --xh-_overlay-arrow-size 覆盖槽。
--xh-hover-card-backdropcontent-webkit-backdrop-filter
backdrop-filter
xh-material=frosted--xh-_material-backdrophover-card 的 content 部件 -webkit-backdrop-filter、backdrop-filter 覆盖槽。
--xh-hover-card-bgarrow
content
backgrounddefault
not([data-xh-action-control])
xh-material=frosted
--xh-_material-bg
--xh-material-frosted-bg
hover-card 的 arrow、content 部件 background 覆盖槽。
--xh-hover-card-borderarrow
content
borderdefault
not([data-xh-action-control])
xh-material=frosted
--xh-_material-border
--xh-material-frosted-border
hover-card 的 arrow、content 部件 border 覆盖槽。
--xh-hover-card-description-fgdescriptioncolordefault--xh-fg-mutedhover-card 的 description 部件 color 覆盖槽。
--xh-hover-card-description-font-sizedescriptionfont-sizedefault--xh-text-secondary-sizehover-card 的 description 部件 font-size 覆盖槽。
--xh-hover-card-fgcontentcolornot([data-xh-action-control])
xh-material=frosted
--xh-_material-fghover-card 的 content 部件 color 覆盖槽。
--xh-hover-card-gapcontentgapdefault--xh-space-2hover-card 的 content 部件 gap 覆盖槽。
--xh-hover-card-layerpositionerz-indexdefault--xh-_layerhover-card 的 positioner 部件 z-index 覆盖槽。
--xh-hover-card-max-hcontentmax-block-sizedefault--xh-overlay-max-hhover-card 的 content 部件 max-block-size 覆盖槽。
--xh-hover-card-max-wcontentmax-inline-sizedefault--xh-_hover-card-max-whover-card 的 content 部件 max-inline-size 覆盖槽。
--xh-hover-card-pxcontentpadding-inlinedefault--xh-_hover-card-padhover-card 的 content 部件 padding-inline 覆盖槽。
--xh-hover-card-pycontentpadding-blockdefault--xh-_hover-card-padhover-card 的 content 部件 padding-block 覆盖槽。
--xh-hover-card-radiuscontentborder-radiusdefault--xh-shape-overlayhover-card 的 content 部件 border-radius 覆盖槽。
--xh-hover-card-shadowcontentbox-shadownot([data-xh-action-control])
xh-material=frosted
--xh-_material-shadowhover-card 的 content 部件 box-shadow 覆盖槽。
--xh-hover-card-title-fgtitlecolordefault--xh-fg-defaulthover-card 的 title 部件 color 覆盖槽。
--xh-hover-card-title-font-sizetitlefont-sizedefault--xh-text-label-sizehover-card 的 title 部件 font-size 覆盖槽。
--xh-hover-card-title-font-weighttitlefont-weightdefault--xh-font-weight-semiboldhover-card 的 title 部件 font-weight 覆盖槽。
--xh-hover-card-trigger-gaptriggergapdefault--xh-control-gap-smhover-card 的 trigger 部件 gap 覆盖槽。

动效 ​

动效角色:出现(锚定面板)(见动效规范)。

共享关键帧 xh-overlay-pop-in · xh-pop-out 由 family/motion.css 提供,皮肤 @import 它,单独引入仍成立。时长与缓动读动效令牌,改令牌即改全局节奏。

皮肤之外还有一段:退场由适配器的退场闸门把关,动画播完才真收起。

系统开启减弱动效时由令牌层统一收敛,皮肤不另作判断。

RTL ​

皮肤用逻辑属性排布(inline-start 一族),dir="rtl" 下自动镜像。

Released under The MIT License