Usage
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.
tsimport {useHoverCard} from '@astryxdesign/core/HoverCard'
Best practices
| Guidance | Practices |
|---|---|
| Do | Use for rich content previews such as user profiles, entity summaries, and link previews. |
| Do | Prefer the HoverCard component for standard trigger-content pairs; use the hook for custom trigger patterns. |
| Don't | Use for simple text hints: use Tooltip or useTooltip instead. |
Parameters
| Param | Type | Description |
|---|---|---|
placement | 'above' | 'below' | 'start' | 'end' (default: 'above') | 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' (default: 'center') | Alignment along the placement axis. Logical: start/end resolve against the popover's own inherited direction (RTL mirrors in pure CSS). |
delay | number (default: 300) | Delay before showing the hover card on hover, in milliseconds. |
hideDelay | number (default: 200) | Delay before hiding after mouse or focus leaves, in milliseconds. |
focusTrigger | 'auto' | 'always' | 'never' (default: 'auto') | When focus should open the hover card. auto only attaches focus listeners to naturally focusable elements. |
touchTrigger | 'auto' | 'tap' | 'none' (default: 'auto') | 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 (default: true) | 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 (default: false) | 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
| Field | Type | Description |
|---|---|---|
| ref | RefCallback<HTMLElement> | Combined ref that sets both position and interaction on the same trigger element. |
| positionRef | RefCallback<HTMLElement> | Ref for the positioning anchor element. Use when position and interaction live on different elements. |
| interactionRef | RefCallback<HTMLElement> | Ref for the hover/focus interaction element. Use with positionRef for split trigger patterns. |
| anchorId | string | CSS anchor name for advanced positioning cases. |
| describedBy | string | ID to compose into aria-describedby on the trigger. |
| renderHoverCard | (children: ReactNode, props?: Omit<ContextRenderProps, 'positioning'>) => ReactNode | 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. |
| show | () => void | Imperatively show the hover card immediately. |
| hide | () => void | Imperatively hide the hover card immediately. |
Examples
Common configurations, variations, and states.Custom profile preview using useHoverCard with direct trigger and render control.
Use with shadcn
Already using the shadcn registry workflow? Install the real Astryx package and a local public re-export. Component implementation source stays in Astryx. How compatibility works.
This install URL expires with the draft preview.Install the editable showcase compositionbashnpx shadcn@latest add https://astryx-4p843mspp-fbopensource.vercel.app/r/hooks/use-hover-card.json
bashnpx shadcn@latest add https://astryx-4p843mspp-fbopensource.vercel.app/r/showcases/hover-card/default.json