HoverCard
hover-card悬停后浮出富内容卡片,移开延时关闭
用法
基础用法
悬停链接/词条延迟展开信息卡,移出延迟关闭;非模态,不锁滚、不抢焦点。
tsx
<HoverCard>
<HoverCardTrigger render={<button type="button">@瑚琏设计系统</button>} />
<HoverCardContent>
<div className="flex gap-3">
<div className="size-10 rounded-full bg-primary/12">瑚</div>
<div>
<p>瑚琏设计系统</p>
<p>吸取各家最佳实现,统一成一套瑚琏 API + 明暗 token。</p>
</div>
</div>
</HoverCardContent>
</HoverCard>弹出方位
side 控制卡片相对触发器的方位,箭头自动续上对应边线。
tsx
<>
<HoverCard>
<HoverCardTrigger render={<button type="button">向上展开</button>} />
<HoverCardContent side="top">{/* 头像 + 简介 */}</HoverCardContent>
</HoverCard>
<HoverCard>
<HoverCardTrigger render={<button type="button">向右展开</button>} />
<HoverCardContent side="right">{/* 头像 + 简介 */}</HoverCardContent>
</HoverCard>
</>何时用
hover 触发展开的富内容卡片(用户名片、术语释义、链接预览),带开/关延迟避免误触。纯文本短提示用 Tooltip;click 触发 + 操作按钮用 Popover;专做「封面图 + 标题 + 域名」链接预览用 Glimpse。
导入
ts
import { HoverCard, HoverCardTrigger, HoverCardContent } from "@hulianui/ui"Props
HoverCard:
| 名称 | 类型 | 默认 | 说明 |
|---|---|---|---|
| openDelay | number | 300 | 悬停多少毫秒后打开 |
| closeDelay | number | 150 | 移出多少毫秒后关闭 |
HoverCardContent:
| 名称 | 类型 | 默认 | 说明 |
|---|---|---|---|
| side | "top"|"right"|"bottom"|"left" | "bottom" | 浮层方位 |
| align | "start"|"center"|"end" | "center" | 对齐 |
| sideOffset | number | - | 与触发器的间距 |
| anchor | Element|RefObject<Element>|VirtualElement|(() => Element|VirtualElement|null) | - | 把卡片锚到别处而不是触发器,口径同 Popover 的 anchor。差别只有一条:触发器不可省,卡片是 hover 打开的,anchor 只改「贴在哪」不改「谁把它打开」 |
| className | string | - | 额外类名 |
Slots
| 插槽 | 类型 | 说明 |
|---|---|---|
HoverCard children | ReactNode | Trigger + Content |
HoverCardContent children | ReactNode | 卡片内容 |
HoverCardTrigger 用 render prop 接管触发元素(行内链接/按钮)。
禁忌 / 坑
- 本组件已按 [[hovercard-on-focus-managing-popover-flickers-set-initial-final-focus-false]] 把焦点交还语义关掉(不在打开时夺取焦点),避免 hover + focus 在 focus-managing popover 上 ping-pong 无限闪烁;若 fork 改造别重新打开焦点托管。
- 用
openDelay/closeDelay调防误触,别把closeDelay设 0,否则光标在 trigger 与卡片间移动的瞬间会闪关。 HoverCardContent继承 div 原生属性,可直接挂data-testid/role/aria-*/onClick。卡片虽被 portal 出去,合成事件仍沿 React 树冒泡回触发器所在的父元素,所以卡片挂在整块可点的行/卡里时要自己onClick={(e) => e.stopPropagation()},否则点卡片内容会顺手触发整行的onClick。透传的onMouseEnter/onMouseLeave与内部计时器是合并而不是覆盖,不会因此把卡片弄关。
相关
Playground
<HoverCard>
<HoverCardTrigger render={<a>@瑚琏</a>} />
<HoverCardContent side="bottom" align="center">
{/* 头像 + 简介 */}
</HoverCardContent>
</HoverCard>