codefast/ui

Command Palette

Search for a command to run...

Source
Overlay

Hover Card

Rich preview card that appears on hover. Ideal for user profiles and link previews.

Examples

RTL

Right-to-left layout support for languages such as Arabic and Hebrew.

Translations are AI-generated for demonstration and may be imperfect.

66 lines
import { Button } from "@codefast/ui/button";
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@codefast/ui/hover-card";

import type { Translations } from "#/features/components-catalog/components/detail/language";
import { useTranslation } from "#/features/components-catalog/components/detail/language-context";

const translations: Translations = {
  en: {
    dir: "ltr",
    values: {
      trigger: "Wireless Headphones",
      name: "Wireless Headphones",
      price: "$99.99",
      left: "Left",
      top: "Top",
      bottom: "Bottom",
      right: "Right",
    },
  },
  ar: {
    dir: "rtl",
    values: {
      trigger: "سماعات لاسلكية",
      name: "سماعات لاسلكية",
      price: "٩٩.٩٩ $",
      left: "يسار",
      top: "أعلى",
      bottom: "أسفل",
      right: "يمين",
    },
  },
  he: {
    dir: "rtl",
    values: {
      trigger: "אוזניות אלחוטיות",
      name: "אוזניות אלחוטיות",
      price: "99.99 $",
      left: "שמאל",
      top: "למעלה",
      bottom: "למטה",
      right: "ימין",
    },
  },
};

const physicalSides: Array<"left" | "top" | "bottom" | "right"> = ["left", "top", "bottom", "right"];

export function HoverCardRtl() {
  const { dir, t } = useTranslation(translations, "ar");

  return (
    <div className="flex flex-wrap justify-center gap-2">
      {physicalSides.map((side) => (
        <HoverCard key={side} openDelay={10} closeDelay={100}>
          <HoverCardTrigger asChild>
            <Button variant="outline">{t[side]}</Button>
          </HoverCardTrigger>
          <HoverCardContent side={side} className="flex w-64 flex-col gap-1" dir={dir}>
            <div className="font-semibold">{t.name}</div>
            <div className="text-sm text-muted-foreground">{t.price}</div>
          </HoverCardContent>
        </HoverCard>
      ))}
    </div>
  );
}

Sides

For sighted users to preview content available behind a link.

26 lines
import { Button } from "@codefast/ui/button";
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@codefast/ui/hover-card";

const HOVER_CARD_SIDES = ["left", "top", "bottom", "right"] as const;

export function HoverCardSides() {
  return (
    <div className="flex flex-wrap justify-center gap-2">
      {HOVER_CARD_SIDES.map((side) => (
        <HoverCard key={side} openDelay={100} closeDelay={100}>
          <HoverCardTrigger asChild>
            <Button variant="outline" className="capitalize">
              {side}
            </Button>
          </HoverCardTrigger>
          <HoverCardContent side={side}>
            <div className="flex flex-col gap-1">
              <h4 className="font-medium">Hover Card</h4>
              <p>This hover card appears on the {side} side of the trigger.</p>
            </div>
          </HoverCardContent>
        </HoverCard>
      ))}
    </div>
  );
}

Anatomy

How the parts nest — every slot the component exposes, in composition order.

HoverCard
├── HoverCardTrigger
└── HoverCardContent

Features

  • Opens on hover and on keyboard focus of the trigger — not hover-only.
  • openDelay/closeDelay (default 700ms/300ms) tune how long to hover before opening or closing.
  • side/align on HoverCardContent control placement, the same positioning primitives as Popover and Tooltip.

API reference

Props for each part of the component. All native element props are also forwarded.

HoverCard

Root. Opens on hover/focus of the trigger.

openDelaynumber

Milliseconds to hover before opening.

Default700

closeDelaynumber

Milliseconds before closing after the pointer leaves.

Default300

HoverCardContent

side"top" | "right" | "bottom" | "left"

The preferred edge of the trigger to render against.

Default"bottom"

align"start" | "center" | "end"

The preferred alignment against the trigger.

Default"center"

Accessibility

Built to be keyboard-navigable and screen-reader friendly out of the box.

  • Opens on hover and on keyboard focus of the trigger.
  • Content is supplementary — never put essential info or actions only here.
  • Touch devices don’t hover; ensure the same info is reachable another way.

Guidelines

Conventions that keep usage consistent across an app.

Do

  • Use for non-essential previews — profiles, link cards.
  • Keep the trigger a real link or button.

Don’t

  • Don’t put interactive controls inside — use a Popover.
  • Don’t hide critical content behind hover.

Explore further

Ready to integrate?

Follow the Getting Started guide to install @codefast/ui, or browse the full component gallery.