Hover Card
Preview card that appears on hover or focus with configurable delays and placement.
pnpm dlx @glinui/cli@latest add hover-cardRelease notes drafted by @avakim and reviewed by the docs team. Hover the handle to see who wrote it.
Installation
pnpm dlx @glinui/cli@latest add hover-cardPrefer the package?
Usage
Link preview
A small card previewing the target of an inline link.
"use client"
import { HoverCard, HoverCardContent, HoverCardTrigger} from "@glinui/ui"
export function HoverCardLinkExample() { return ( <div className="mx-auto w-full max-w-md text-sm leading-6"> See the{" "} <HoverCard openDelay={100} closeDelay={80}> <HoverCardTrigger asChild><a href="#" className="font-medium underline decoration-dotted underline-offset-4">pricing page</a></HoverCardTrigger> <HoverCardContent className="w-72" size="sm"> <p className="text-sm font-medium">Pricing</p> <p className="mt-1 text-xs text-[var(--color-muted)]">Free for individuals. Team plans start at $20 per seat each month.</p> </HoverCardContent> </HoverCard>{" "} for plan details. </div> )}Delays and surface
import { Badge, HoverCard, HoverCardContent, HoverCardTrigger } from "@glinui/ui"
export function Demo() { return ( <div className="flex flex-wrap items-center gap-4"> <HoverCard openDelay={0} closeDelay={150}> <HoverCardTrigger asChild> <button className="text-sm font-medium underline decoration-dotted underline-offset-4"> Instant preview </button> </HoverCardTrigger> <HoverCardContent size="sm"> <div className="space-y-2"> <Badge>default</Badge> <p className="text-xs text-neutral-600 dark:text-neutral-300">Open delay: 0ms</p> </div> </HoverCardContent> </HoverCard> <HoverCard openDelay={500} closeDelay={250}> <HoverCardTrigger asChild> <button className="text-sm font-medium underline decoration-dotted underline-offset-4"> Delayed preview </button> </HoverCardTrigger> <HoverCardContent variant="plain" size="md"> <p className="text-xs text-neutral-600 dark:text-neutral-300"> Opens after 500ms with the plain surface. </p> </HoverCardContent> </HoverCard> </div> )}Variants
Every look of the shared vocabulary: glinr (the default), plain (shadcn), solid, soft, outline, ghost, gradient and glass. Omit `variant` to follow the ambient design style.
import { Button, HoverCard, HoverCardContent, HoverCardTrigger } from "@glinui/ui"
const variants = ["glinr", "plain", "solid", "soft", "outline", "ghost", "gradient", "glass"] as const
export function Demo() { return ( <div className="flex flex-wrap gap-2"> {variants.map((variant) => ( <HoverCard key={variant} openDelay={0}> <HoverCardTrigger asChild><Button size="sm" variant="outline">{variant}</Button></HoverCardTrigger> <HoverCardContent variant={variant} size="sm"> <p className="font-medium">{variant} hover card</p> <p className="mt-1 text-[var(--color-muted)]">Preview on hover or focus.</p> </HoverCardContent> </HoverCard> ))} </div> )}Glass (opt-in)
variant="glass" is opt-in. It blurs and tints what sits behind the panel (with a readable opacity floor), so it needs a colourful or photographic backdrop: switch the stage backdrop to see it.
import { Button, HoverCard, HoverCardContent, HoverCardTrigger } from "@glinui/ui"
export function Demo() { return ( <HoverCard> <HoverCardTrigger asChild><Button variant="outline">Hover for glass</Button></HoverCardTrigger> <HoverCardContent variant="glass">Frosted, with a readable floor.</HoverCardContent> </HoverCard> )}Delays and Surfaces
import { Badge, HoverCard, HoverCardContent, HoverCardTrigger } from "@glinui/ui"
export function HoverCardDelayDemo() {
return (
<div className="flex flex-wrap items-center gap-4">
<HoverCard openDelay={0} closeDelay={150}>
<HoverCardTrigger asChild>
<button className="text-sm font-medium underline decoration-dotted underline-offset-4">
Instant preview
</button>
</HoverCardTrigger>
<HoverCardContent variant="glass" size="sm">
<div className="space-y-2">
<Badge variant="glass">glass</Badge>
<p className="text-xs text-neutral-600 dark:text-neutral-300">Open delay: 0ms</p>
</div>
</HoverCardContent>
</HoverCard>
<HoverCard openDelay={500} closeDelay={250}>
<HoverCardTrigger asChild>
<button className="text-sm font-medium underline decoration-dotted underline-offset-4">
Delayed preview
</button>
</HoverCardTrigger>
<HoverCardContent variant="outline" size="md">
<p className="text-xs text-neutral-600 dark:text-neutral-300">
Opens after 500ms with outline surface.
</p>
</HoverCardContent>
</HoverCard>
</div>
)
}Accessibility
- Built on Radix Hover Card and opens on hover and keyboard focus.
- Hover card content should be supplemental; avoid critical-only information.
- Use non-interactive preview content for concise summaries.
- Use concise supplemental content, not primary actions.
- Keep the trigger semantic and focusable (`button`, `a`, etc.).
- For interactive panels, prefer `Popover`.
Keyboard Interactions
| Key | Action |
|---|---|
| Tab / Shift+Tab | Move focus to or away from the trigger. |
| Escape | Close the hover card when focused. |
ARIA Attributes
- `aria-describedby` linkage is handled by Radix primitives
- Trigger remains semantic and keyboard reachable
Reduced Motion
Entrance and exit transitions are disabled under `prefers-reduced-motion`.
Affected properties
opacitytransformAPI Reference
HoverCardProps
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
openDelay | number | No | 200 | Delay in milliseconds before opening on hover/focus. |
closeDelay | number | No | 100 | Delay in milliseconds before closing after pointer leaves. |
open | boolean | - | - | Controlled open state. |
defaultOpen | boolean | - | - | Initial open state for uncontrolled usage. |
onOpenChange | (open: boolean) => void | - | - | Open state change handler. |
HoverCardContentProps
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
variant | PanelVariantProp | No | ambient style (glinr) | Panel look. Omit it for the ambient design style (glinr shell with a gradient hairline ring). `plain` is the shadcn border and shadow, `glass` is opt-in and needs a backdrop. |
size | "sm" | "md" | "lg" | No | md | Content width and density scale. |
align | "start" | "center" | "end" | - | center | Alignment relative to the trigger. |
side | "top" | "right" | "bottom" | "left" | No | bottom | Preferred side for content placement. |
sideOffset | number | No | 10 | Distance from trigger in pixels. |
container | HTMLElement | null | No | - | Element to portal into. Defaults to document.body. |
Source
Import directly from the package or browse the source on GitHub. Click any file to view it.
Import
import { HoverCard } from "@glinui/ui"Source Files
Dependencies
@glinui/uiGenerated API Snapshot
Beta
Generated API Snapshot
BetaAuto-extracted from TypeScript source in packages/ui/src/components/hover-card.tsx. This section is in beta and may lag behind hand-curated docs. Regenerate with pnpm --filter @glinui/docs api:generate.
Generated: 2026-10-08T01:41:21.546Z · Full index: /docs/api-metadata
Primary Props Type
HoverCardProps
HoverCardContentProps
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
container | HTMLElement | null | No | - | Element to portal into. Defaults to document.body. |
side | "top" | "right" | "bottom" | "left" | No | - | Preferred side for the hover card. |
sideOffset | number | No | 10 | Gap in px between trigger and content. |
size | "sm" | "md" | "lg" | No | "md" | Variant option from hoverCardContentVariants. |
variant | PanelVariantProp | No | - | Surface look. Omit for the ambient design style (glinr by default). `glass` is opt-in and needs a rich backdrop. |
HoverCardProps
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
closeDelay | number | No | 100 | Delay in ms before closing when pointer leaves. |
openDelay | number | No | 200 | Delay in ms before opening on pointer/focus. |