悬停卡片 · HoverCard
通过悬停或聚焦展示内容摘要。
安装与前置条件
npm install @astryxdesign/core@0.7.1 @astryxdesign/theme-neutral@0.7.1 @stylexjs/stylex@0.19.0
需要 React 19+,按顺序导入基础 CSS 和主题,并设置 Theme Provider。参见开始使用。
示例与使用方式
- 悬停卡片 · 综合展示 1:首先体验这个示例,再查看代码理解组件的组合方式。
- 悬停卡片 · 交互示例 2:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
- 悬停卡片 · 交互示例 3:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
- 悬停卡片 · 交互示例 4:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
- 悬停卡片 · 交互示例 5:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
API 与上游详细参考
优先使用 0.7.1 官方中文说明;上游尚未提供中文的条目保留英文。属性名、类型及默认值保持原生 API,不把示例状态名称当成组件属性。
Hover Card
HoverCard shows additional information when the user hovers or focuses a trigger element. Use it for profile cards, link summaries, or inline definitions where the user needs more context without navigating away.
使用建议
- Keep content supplementary; hover cards should enhance understanding without blocking the primary workflow.
- Provide a dashed underline on text triggers so users know the element is hoverable.
- Use the hook API (useHoverCard) when you need more control over timing or placement.
- Leave touchTrigger on auto so a tap opens the card on triggers that do nothing else, and stays out of the way on triggers that perform an action.
- 避免:Place critical actions or required information inside a hover card; users may miss content that only appears on hover.
- 避免:Use a hover card when a simple Tooltip or Popover would suffice.
- 避免:Use a HoverCard for content the user must interact with; it disappears when the cursor leaves.
- Prefer placing HoverCard in a block context rather than directly in a <p>, heading, or link. Those placements are supported when necessary through a corrective portal, but the DOM and tab order may differ.
主题 API
{
"targets": [
{
"className": "astryx-hover-card"
}
],
"vars": [
{
"name": "--_hovercard-radius",
"description": "Border radius of the hover card",
"default": "var(--radius-container)",
"private": true
}
],
"derived": [
{
"property": "borderRadius",
"vars": [
"--_hovercard-radius"
]
}
]
}
Hover Card
悬浮卡片显示的组件包装器,在悬停或聚焦时触发更丰富、更大的浮层。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| children | ReactNode | 必须接受 ref 的触发元素。 | |
| content * | ReactNode | 悬浮卡片内容。 | |
| placement | 'above' | 'below' | 'start' | 'end' | 'above' | 相对于锚点元素的位置。逻辑值:start/end 根据弹出层自身继承的方向解析(RTL 镜像)。 |
| alignment | 'start' | 'center' | 'end' | 'center' | 沿放置轴的对齐方式。逻辑值:start/end 根据弹出层自身继承的方向解析(RTL 镜像)。 |
| delay | number | 300 | 显示延迟(毫秒)。 |
| hideDelay | number | 200 | 隐藏延迟(毫秒)。 |
| focusTrigger | 'auto' | 'always' | 'never' | 'auto' | 控制焦点事件何时触发悬浮卡片。 |
| touchTrigger | 'auto' | 'tap' | 'none' | 'auto' | 在没有悬停的触摸设备上,轻点的行为。auto:轻点即打开,除非触发元素本身会执行操作(按钮、链接、表单控件),此时轻点归该控件所有。tap:始终轻点打开。none:触摸永不打开。轻点打开的卡片可通过点击卡片外部关闭。 |
| isEnabled | boolean | true | 启用或禁用悬停和聚焦触发器。 |
| label | string | 悬浮卡片弹出层的无障碍名称。提供时,弹出层以具名的 role="dialog" 暴露;省略时,回退为 role="group"(group 可以合法地没有名称)。 | |
| onOpenChange | (isOpen: boolean) => void | 悬浮卡片可见性变化时触发的回调。显示时传入 true,隐藏时传入 false。 | |
| hasHoverIndication | 'auto' | boolean | 'auto' | 在触发元素上显示虚线下划线。 |
| isDefaultOpen | boolean | 是否在挂载时显示悬浮卡片。仍然可以关闭。 | |
| isOpen | boolean | Controlled open state for the hover card. |
组件结构
- Trigger: The element that opens the hover card on hover or focus: a button, link, or inline text.
- Card: The floating overlay with the preview content, anchored to the trigger.
- Body: The main content area: profile info, link summary, or any rich content.
- Actions: Optional buttons inside the card for follow-up actions like Follow or Message.
useHoverCard
Headless hook for hover-triggered floating cards. Builds on useLayer with hover/focus intent detection, configurable delays, safe hover behavior, and accessible aria-describedby linking. Use for rich previews on hover when you need full control over the trigger or rendered content.
Parameters
| Parameter | Type | Description |
|---|---|---|
| placement | 'above' | 'below' | 'start' | 'end' | Position relative to the trigger. Logical: start/end resolve against the popover's own inherited direction (RTL mirrors in pure CSS). |
| alignment | 'start' | 'center' | 'end' | Alignment along the placement axis. Logical: start/end resolve against the popover's own inherited direction (RTL mirrors in pure CSS). |
| delay | number | Delay before showing the hover card on hover, in milliseconds. |
| hideDelay | number | Delay before hiding after mouse or focus leaves, in milliseconds. |
| focusTrigger | 'auto' | 'always' | 'never' | When focus should open the hover card. auto only attaches focus listeners to naturally focusable elements. |
| touchTrigger | 'auto' | 'tap' | 'none' | What a tap does where there is no hover. auto opens on tap unless the trigger performs an action of its own; tap always opens; none never opens on touch. |
| isEnabled | boolean | Whether hover and focus triggers are enabled. |
| label | string | Accessible name for the hover card popup. When provided, the popup is exposed as a named role="dialog"; when omitted, it falls back to role="group" (a group may validly be unnamed). |
| isOpen | boolean | Controlled open state. true force-shows, false force-hides, undefined lets hover/focus manage visibility. |
| isDefaultOpen | boolean | Whether the hover card should be shown on mount. |
| onShow | () => void | Callback fired when the hover card becomes visible. |
| onHide | () => void | Callback fired when the hover card is hidden. |
Returns
[
{
"name": "ref",
"type": "RefCallback<HTMLElement>",
"description": "Combined ref that sets both position and interaction on the same trigger element."
},
{
"name": "positionRef",
"type": "RefCallback<HTMLElement>",
"description": "Ref for the positioning anchor element. Use when position and interaction live on different elements."
},
{
"name": "interactionRef",
"type": "RefCallback<HTMLElement>",
"description": "Ref for the hover/focus interaction element. Use with positionRef for split trigger patterns."
},
{
"name": "anchorId",
"type": "string",
"description": "CSS anchor name for advanced positioning cases."
},
{
"name": "describedBy",
"type": "string",
"description": "ID to compose into aria-describedby on the trigger."
},
{
"name": "renderHoverCard",
"type": "(children: ReactNode, props?: Omit<ContextRenderProps, 'positioning'>) => ReactNode",
"description": "Render function for the anchor-positioned hover card content. The positioning opt-out is excluded: the hover card always derives its position from placement/alignment."
},
{
"name": "show",
"type": "() => void",
"description": "Imperatively show the hover card immediately."
},
{
"name": "hide",
"type": "() => void",
"description": "Imperatively hide the hover card immediately."
}
]
使用建议
- Use for rich content previews such as user profiles, entity summaries, and link previews.
- Prefer the HoverCard component for standard trigger-content pairs; use the hook for custom trigger patterns.
- 避免:Use for simple text hints: use Tooltip or useTooltip instead.
完整示例的额外依赖
部分示例使用独立图标包。示例清单中的每条安装命令包含该示例实际需要的依赖;若要运行本页全部示例,还需安装:
npm install @heroicons/react@2.2.0