0.1.0

Hover Card

Hover cards preview rich content behind a link or control on hover or focus — profiles, link previews, and other supplementary detail.

Try it

Usage

Compose a trigger and content surface. Tune delay and closeDelay so pointer movement can reach interactive content inside the card.

import {
  RuiHoverCard,
  RuiHoverCardContent,
  RuiHoverCardTrigger,
} from '@ecopages/radiant-ui/hover-card';
import { RuiAvatar } from '@ecopages/radiant-ui/avatar';
import { RuiButton } from '@ecopages/radiant-ui/button';
 
<RuiHoverCard delay={600} closeDelay={200} placement="bottom-start">
  <RuiHoverCardTrigger>
    <RuiButton variant="link">Jane Cooper</RuiButton>
  </RuiHoverCardTrigger>
  <RuiHoverCardContent>
    <div class="flex gap-3">
      <RuiAvatar fallback="JC" alt="Jane Cooper" />
      <div class="flex flex-col gap-1">
        <p class="font-medium text-sm">Jane Cooper</p>
        <p class="text-on-surface text-xs opacity-80">Product designer on the Radiant team.</p>
      </div>
    </div>
  </RuiHoverCardContent>
</RuiHoverCard>

Custom markup

<rui-hover-card> coordinates any light-DOM tree that matches its query contract. The Rui* helpers stamp these targets; they are not required.

import '@ecopages/radiant-ui/hover-card';
 
<rui-hover-card delay={600} content-label="Jane Cooper preview">
  <span class="rui-hover-card">
    <span class="rui-hover-card__trigger" data-ref="trigger">
      <span data-hover-card-trigger>
        <button type="button">Jane Cooper</button>
      </span>
    </span>
    <div data-ref="content" class="rui-hover-card__content rui-floating" role="dialog">
      <p>Product designer on the Radiant team.</p>
    </div>
  </span>
</rui-hover-card>;

The host queries [data-ref="trigger"] for focus events and [data-hover-card-trigger] for the anchor.

Hover card vs tooltip

Use RuiTooltip for short, non-interactive descriptions. Use RuiHoverCard when the preview includes links, avatars, or other focusable content.

Theming

The preview panel is often portaled; override --rui-hover-card-* on .rui-hover-card__content.

PartDefaultOverride
Width / padding20rem, --space-inset--rui-hover-card-width, --rui-hover-card-padding
Fill / border / radius / shadow--background, --border, --radius-container, --shadow-overlay--rui-hover-card-surface, --rui-hover-card-border-color, --rui-hover-card-radius, --rui-hover-card-shadow
Z-orderoverlaytheme z-index
.rui-hover-card__content {
  --rui-hover-card-width: 24rem;
}

Accessibility

  • The same information should remain available without hover (for example via navigation to a full profile page).
  • The preview dialog has a default accessible name (Preview). Override with content-label when needed.
  • Keyboard users can Tab into card content while it is open.
  • Press Escape to dismiss.

API

RuiHoverCard is a custom element (<rui-hover-card>) that shows a floating preview on hover or focus of its trigger.

Attributes (<rui-hover-card>)

AttributeTypeDefaultDescription
openbooleanfalseWhether the card is open (controlled).
placementRuiPlacementbottom-startPlacement relative to the anchor.
delaynumber600Show delay in ms.
close-delaynumber200Hide delay in ms after pointer/focus leaves.
portalbooleantrueTeleport the surface to document.body.
disabledbooleanfalseSuppress hover/focus preview interactions.
content-labelstringPreviewAccessible name for the preview dialog.

Light-DOM contract

TargetRequiredHost writesAuthor owns
[data-hover-card-trigger]yes—anchor wrapper
[data-ref="trigger"]yes—focus bridge around the anchor
[data-ref="content"]yesid, aria-labelpreview body; view seeds role="dialog"
focusable anchorper triggeraria-controls, aria-expandedcontrol inside [data-hover-card-trigger]

Do not set aria-controls, aria-expanded, or aria-label on the surface. Nested hosts: none.

Events

EventDetailDescription
rui-open-change{ open: boolean }Emitted when open state changes.

Methods

MethodDescription
setOpen(next, emit?)Toggle open state. Pass emit = false to sync without firing rui-open-change.

View helpers

ComponentTarget stampedNotes
RuiHoverCardTrigger[data-ref="trigger"] wrapping [data-hover-card-trigger]Anchor for hover/focus.
RuiHoverCardContent[data-ref="content"]Floating preview surface.
RuiHoverCard.rui-hover-card wrapperCompose trigger + content as children.

CSS classes

ClassDescription
.rui-hover-cardRoot wrapper.
.rui-hover-card__triggerTrigger wrapper.
.rui-hover-card__contentFloating preview surface.