Westy Design Systemv0.2.7
OverviewComponentsExamplesStorybook

Foundations

  • Typography
  • Colors
  • Spacing
  • Radius
  • Shadows
  • Icons

Components

  • Accordion
  • Alert
  • Alert Dialog
  • Aspect Ratio
  • Avatar
  • Badge
  • Breadcrumb
  • Button
  • Button Group
  • Calendar
  • Card
  • Carousel
  • Chart
  • Checkbox
  • Collapsible
  • Combobox
  • Command
  • Context Menu
  • Data Table
  • Date Picker
  • Dialog
  • Direction
  • Drawer
  • Dropdown Menu
  • Empty
  • Field
  • Hover Card
  • Input
  • Input Group
  • Input OTP
  • Item
  • Kbd
  • Label
  • Menubar
  • Native Select
  • Navigation Menu
  • Pagination
  • Popover
  • Progress
  • Questionnaire
  • Radio Group
  • Resizable
  • Scroll Area
  • Select
  • Separator
  • Sheet
  • Sidebar
  • Skeleton
  • Slider
  • Sonner
  • Spinner
  • Switch
  • Table
  • Tabs
  • Textarea
  • Toggle
  • Toggle Group
  • Tooltip

Chat

  • Attachment
  • Bubble
  • Marker
  • Message
  • Message Scroller

Components

Hover Card

For sighted users to preview content available behind a link.

Playground

—side
—align
—sideOffset
—openDelay
—closeDelay
—open
Usage
HoverCard wraps a HoverCardTrigger and the HoverCardContent it reveals on hover. The content renders in a portal, 256px wide (w-64) by default — override with className. The trigger renders an <a>; use asChild to compose it with a link-styled Button or a framework Link.
import {
  HoverCard,
  HoverCardContent,
  HoverCardTrigger,
} from "@workspace/ui/components/hover-card"

<HoverCard>
  <HoverCardTrigger asChild>
    <Button variant="link">@westy</Button>
  </HoverCardTrigger>
  <HoverCardContent>
    <div className="flex gap-4">
      <Avatar>
        <AvatarImage src="https://github.com/shadcn.png" alt="@westy" />
        <AvatarFallback>WY</AvatarFallback>
      </Avatar>
      <div className="space-y-1">
        <h4 className="font-medium">@westy</h4>
        <p>Building a design system, one component at a time.</p>
        <div className="flex items-center gap-2 pt-1 text-muted-foreground">
          <CalendarBlankIcon className="size-4" />
          <span className="text-xs">Joined August 2026</span>
        </div>
      </div>
    </div>
  </HoverCardContent>
</HoverCard>
Delays
openDelay and closeDelay on the root control how long the pointer must rest before the card opens (700ms by default) and how long it lingers after leaving (300ms). Lower them for glossary-style hints; keep the defaults for previews so casual mouse travel does not flash cards open.
<HoverCard openDelay={0} closeDelay={100}>
  <HoverCardTrigger asChild>
    <Button variant="link">Instant</Button>
  </HoverCardTrigger>
  <HoverCardContent className="w-56">
    Opens as soon as the pointer arrives.
  </HoverCardContent>
</HoverCard>
<HoverCard openDelay={1000} closeDelay={700}>
  <HoverCardTrigger asChild>
    <Button variant="link">Patient</Button>
  </HoverCardTrigger>
  <HoverCardContent className="w-56">
    Waits a full second, then lingers on the way out.
  </HoverCardContent>
</HoverCard>
Positioning
HoverCardContent accepts the same positioning props as the other Radix popper surfaces — side, align and sideOffset. When there is not enough room, Radix flips the card to the opposite side automatically.
<HoverCard>
  <HoverCardTrigger asChild>
    <Button variant="link">Top</Button>
  </HoverCardTrigger>
  <HoverCardContent side="top" className="w-56">
    Above the trigger.
  </HoverCardContent>
</HoverCard>
<HoverCard>
  <HoverCardTrigger asChild>
    <Button variant="link">Right, start</Button>
  </HoverCardTrigger>
  <HoverCardContent side="right" align="start" className="w-56">
    To the right, aligned to the start.
  </HoverCardContent>
</HoverCard>
RTL
The content inherits the document direction, and align is logical — start hugs the right edge of the trigger in RTL. side stays physical: "left" is the left regardless of direction.
<div dir="rtl">
  <HoverCard>
    <HoverCardTrigger asChild>
      <Button variant="link">@westy</Button>
    </HoverCardTrigger>
    <HoverCardContent align="start">
      نبني نظام تصميم، مكوّنًا تلو الآخر.
    </HoverCardContent>
  </HoverCard>
</div>
Accessibility
The hover card is a convenience for sighted pointer users — its content is not announced to screen readers, so never make it the only home of essential information. Tab opens and closes it without delay for keyboard users, and Escape dismisses it. The trigger renders an <a> that should point somewhere real: the card previews the destination, the link remains the accessible path to it. Both parts carry data-state="open|closed" for styling.
<a data-slot="hover-card-trigger" data-state="open" href="https://westy.la">
  @westy
</a>
<div data-slot="hover-card-content" data-state="open" data-side="bottom" data-align="center">
  Hover card content
</div>
API Reference
Every part wraps the matching Radix HoverCard primitive and accepts all of its props — open state and delays on the HoverCard root, positioning on HoverCardContent. The most used ones:
PartPropTypeDefault
HoverCardopenboolean—
HoverCarddefaultOpenbooleanfalse
HoverCardonOpenChange(open: boolean) => void—
HoverCardopenDelaynumber700
HoverCardcloseDelaynumber300
HoverCardTriggerasChildbooleanfalse
HoverCardContentside"top" | "right" | "bottom" | "left""bottom"
HoverCardContentalign"start" | "center" | "end""center"
HoverCardContentsideOffsetnumber4
<HoverCard data-slot="hover-card" />                  // Root — state container, renders nothing
<HoverCardTrigger data-slot="hover-card-trigger" />   // <a>, opens on hover or focus
<HoverCardContent data-slot="hover-card-content" />   // portaled panel (w-64, bg-popover)

Tokens used

6 design tokens consumed by the Hover Card component.

  • --popover

    Popover

    bg-popover
  • --popover-foreground

    Popover Foreground

    text-popover-foreground
  • --foreground

    Foreground

    ring-foreground/10
  • --text-sm

    Text Small (14px)

    text-sm
  • --radius-lg

    Radius 1× (10px)

    rounded-lg
  • --spacing

    Spacing unit (4px)

    w-64p-4