or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-radix-ui--react-hover-card

An accessible hover card component for React with controllable state, configurable delays, keyboard navigation, and full ARIA compliance

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@radix-ui/react-hover-card@1.1.x

To install, run

npx @tessl/cli install tessl/npm-radix-ui--react-hover-card@1.1.0

index.mddocs/

Radix UI React Hover Card

An accessible hover card component for React applications that displays rich content when users hover over a trigger element. Built with full accessibility compliance, keyboard navigation support, controllable state, and configurable delays.

Package Information

  • Package Name: @radix-ui/react-hover-card
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @radix-ui/react-hover-card

Core Imports

import {
  HoverCard,
  HoverCardTrigger,
  HoverCardContent,
  HoverCardPortal,
  HoverCardArrow,
  createHoverCardScope,
} from "@radix-ui/react-hover-card";

Alternative shorter imports using aliases:

import {
  Root,
  Trigger,
  Content,
  Portal,
  Arrow,
} from "@radix-ui/react-hover-card";

For CommonJS:

const {
  HoverCard,
  HoverCardTrigger,
  HoverCardContent,
  HoverCardPortal,
  HoverCardArrow,
} = require("@radix-ui/react-hover-card");

Basic Usage

import {
  HoverCard,
  HoverCardTrigger,
  HoverCardContent,
  HoverCardPortal,
} from "@radix-ui/react-hover-card";

function Example() {
  return (
    <HoverCard>
      <HoverCardTrigger asChild>
        <a
          href="https://twitter.com/radix_ui"
          target="_blank"
          rel="noreferrer noopener"
        >
          @radix_ui
        </a>
      </HoverCardTrigger>
      <HoverCardPortal>
        <HoverCardContent className="HoverCardContent" sideOffset={5}>
          <div style={{ display: "flex", flexDirection: "column", gap: 7 }}>
            <img
              src="https://pbs.twimg.com/profile_images/1337055608613253126/r_eiMp2H_400x400.png"
              alt="Radix UI"
              style={{ width: 45, height: 45, borderRadius: "50%" }}
            />
            <div style={{ display: "flex", flexDirection: "column", gap: 15 }}>
              <div>
                <div style={{ fontSize: 15, fontWeight: 500, color: "white" }}>
                  Radix
                </div>
                <div style={{ fontSize: 15, color: "#666" }}>@radix_ui</div>
              </div>
              <div style={{ fontSize: 14, color: "#999" }}>
                Components, icons, colors, and templates for building
                high‑quality, accessible UI. Free & open source.
              </div>
            </div>
          </div>
        </HoverCardContent>
      </HoverCardPortal>
    </HoverCard>
  );
}

Architecture

The hover card system is built on several key concepts:

  • Root Component: HoverCard manages the overall state and provides context
  • Trigger Component: HoverCardTrigger detects hover/focus events and anchors positioning
  • Portal System: HoverCardPortal renders content outside normal DOM hierarchy
  • Content Component: HoverCardContent handles positioning, interactions, and accessibility
  • Context Scoping: createHoverCardScope enables nested hover card isolation
  • Event Handling: Comprehensive pointer and keyboard event management with touch exclusion
  • Accessibility: Full ARIA compliance with dismissable layer integration

Capabilities

Root Component

The main hover card component that provides context and manages state.

interface HoverCardProps {
  children?: React.ReactNode;
  open?: boolean;
  defaultOpen?: boolean;
  onOpenChange?: (open: boolean) => void;
  openDelay?: number; // Default: 700ms
  closeDelay?: number; // Default: 300ms
}

declare const HoverCard: React.FC<HoverCardProps>;

Usage Example:

<HoverCard
  openDelay={500}
  closeDelay={200}
  onOpenChange={(open) => console.log('Hover card is', open ? 'open' : 'closed')}
>
  {/* trigger and content components */}
</HoverCard>

Trigger Component

The element that triggers the hover card when hovered or focused.

type HoverCardTriggerElement = React.ComponentRef<typeof Primitive.a>;
type PrimitiveLinkProps = React.ComponentPropsWithoutRef<typeof Primitive.a>;

interface HoverCardTriggerProps extends PrimitiveLinkProps {}

declare const HoverCardTrigger: React.ForwardRefExoticComponent<
  HoverCardTriggerProps & React.RefAttributes<HoverCardTriggerElement>
>;

Usage Example:

<HoverCardTrigger asChild>
  <button>Hover me</button>
</HoverCardTrigger>

Portal Component

Portal component for rendering content in a different part of the DOM tree.

interface HoverCardPortalProps {
  children?: React.ReactNode;
  /**
   * Specify a container element to portal the content into.
   */
  container?: Element | null;
  /**
   * Used to force mounting when more control is needed. Useful when
   * controlling animation with React animation libraries.
   */
  forceMount?: true;
}

declare const HoverCardPortal: React.FC<HoverCardPortalProps>;

Usage Example:

<HoverCardPortal container={document.getElementById('hover-cards')}>
  <HoverCardContent>Content here</HoverCardContent>
</HoverCardPortal>

Content Component

The content container with positioning, interaction handling, and accessibility features.

type HoverCardContentElement = React.ComponentRef<typeof PopperPrimitive.Content>;
type DismissableLayerProps = React.ComponentPropsWithoutRef<typeof DismissableLayer>;
type PopperContentProps = React.ComponentPropsWithoutRef<typeof PopperPrimitive.Content>;

interface HoverCardContentProps extends Omit<PopperContentProps, 'onPlaced'> {
  /**
   * Used to force mounting when more control is needed. Useful when
   * controlling animation with React animation libraries.
   */
  forceMount?: true;
  /**
   * Event handler called when the escape key is down.
   * Can be prevented.
   */
  onEscapeKeyDown?: DismissableLayerProps['onEscapeKeyDown'];
  /**
   * Event handler called when the a `pointerdown` event happens outside of the `HoverCard`.
   * Can be prevented.
   */
  onPointerDownOutside?: DismissableLayerProps['onPointerDownOutside'];
  /**
   * Event handler called when the focus moves outside of the `HoverCard`.
   * Can be prevented.
   */
  onFocusOutside?: DismissableLayerProps['onFocusOutside'];
  /**
   * Event handler called when an interaction happens outside the `HoverCard`.
   * Specifically, when a `pointerdown` event happens outside or focus moves outside of it.
   * Can be prevented.
   */
  onInteractOutside?: DismissableLayerProps['onInteractOutside'];
}

declare const HoverCardContent: React.ForwardRefExoticComponent<
  HoverCardContentProps & React.RefAttributes<HoverCardContentElement>
>;

Usage Example:

<HoverCardContent
  side="top"
  align="center"
  sideOffset={5}
  onEscapeKeyDown={(event) => {
    console.log('Escape pressed');
    // Prevent default to keep open
    // event.preventDefault();
  }}
>
  <div>Rich content here</div>
</HoverCardContent>

Arrow Component

Optional arrow element that points from the content to the trigger.

type HoverCardArrowElement = React.ComponentRef<typeof PopperPrimitive.Arrow>;
type PopperArrowProps = React.ComponentPropsWithoutRef<typeof PopperPrimitive.Arrow>;

interface HoverCardArrowProps extends PopperArrowProps {}

declare const HoverCardArrow: React.ForwardRefExoticComponent<
  HoverCardArrowProps & React.RefAttributes<HoverCardArrowElement>
>;

Usage Example:

<HoverCardContent>
  <HoverCardArrow className="HoverCardArrow" />
  <div>Content with arrow</div>
</HoverCardContent>

Context Scoping

Creates a scoped context for hover card components to prevent conflicts in nested scenarios.

declare const createHoverCardScope: () => {
  scopeHoverCard: (scope: any) => any;
};

Usage Example:

const { scopeHoverCard } = createHoverCardScope();

function NestedHoverCard() {
  return (
    <HoverCard __scopeHoverCard={scopeHoverCard}>
      <HoverCardTrigger __scopeHoverCard={scopeHoverCard}>
        Trigger
      </HoverCardTrigger>
      <HoverCardContent __scopeHoverCard={scopeHoverCard}>
        Content
      </HoverCardContent>
    </HoverCard>
  );
}

Component Aliases

For convenience, the package exports shorter aliases for all components:

declare const Root: typeof HoverCard;
declare const Trigger: typeof HoverCardTrigger;
declare const Portal: typeof HoverCardPortal;
declare const Content: typeof HoverCardContent;
declare const Arrow: typeof HoverCardArrow;

Usage Example:

import { Root, Trigger, Content, Portal } from "@radix-ui/react-hover-card";

<Root>
  <Trigger>Hover me</Trigger>
  <Portal>
    <Content>Content</Content>
  </Portal>
</Root>

Advanced Usage Patterns

Controlled State

function ControlledHoverCard() {
  const [open, setOpen] = React.useState(false);
  
  return (
    <HoverCard open={open} onOpenChange={setOpen}>
      <HoverCardTrigger>
        Controlled trigger (open: {open.toString()})
      </HoverCardTrigger>
      <HoverCardContent>
        <button onClick={() => setOpen(false)}>Close</button>
      </HoverCardContent>
    </HoverCard>
  );
}

Custom Delays

<HoverCard openDelay={1000} closeDelay={500}>
  <HoverCardTrigger>Slow to open, quick to close</HoverCardTrigger>
  <HoverCardContent>Content with custom timing</HoverCardContent>
</HoverCard>

Animation Integration

import * as React from "react";
import { HoverCard, HoverCardContent, HoverCardPortal, HoverCardTrigger } from "@radix-ui/react-hover-card";

function AnimatedHoverCard() {
  return (
    <HoverCard>
      <HoverCardTrigger>Animated trigger</HoverCardTrigger>
      <HoverCardPortal forceMount>
        <HoverCardContent
          forceMount
          className="data-[state=open]:animate-fadeIn data-[state=closed]:animate-fadeOut"
        >
          Content with CSS animations
        </HoverCardContent>
      </HoverCardPortal>
    </HoverCard>
  );
}

Accessibility Features

  • ARIA Compliance: Full ARIA labeling and role management
  • Keyboard Navigation: Tab, Escape, and arrow key support
  • Focus Management: Automatic focus handling and restoration
  • Screen Reader Support: Proper announcements and descriptions
  • Touch Device Support: Touch events are excluded to prevent conflicts
  • High Contrast: Compatible with high contrast modes and themes

CSS Custom Properties

The hover card components expose CSS custom properties that can be used for styling and positioning:

/* Available on HoverCardContent */
--radix-hover-card-content-transform-origin: var(--radix-popper-transform-origin);
--radix-hover-card-content-available-width: var(--radix-popper-available-width);
--radix-hover-card-content-available-height: var(--radix-popper-available-height);
--radix-hover-card-trigger-width: var(--radix-popper-anchor-width);
--radix-hover-card-trigger-height: var(--radix-popper-anchor-height);

These properties are automatically set by the positioning system and can be used in CSS for responsive styling:

.HoverCardContent {
  width: var(--radix-hover-card-trigger-width);
  max-width: var(--radix-hover-card-content-available-width);
  transform-origin: var(--radix-hover-card-content-transform-origin);
}

Data Attributes

Components automatically receive data attributes for styling based on their state:

  • data-state="open" - Applied to HoverCardTrigger and HoverCardContent when the hover card is open
  • data-state="closed" - Applied to HoverCardTrigger and HoverCardContent when the hover card is closed
.HoverCardTrigger[data-state="open"] {
  background-color: var(--hover-active);
}

.HoverCardContent[data-state="open"] {
  animation: slideIn 200ms ease-out;
}

Browser Support

Supports all modern browsers including:

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)

Peer Dependencies

  • React: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc (hooks support required)
  • React DOM: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
  • @types/react: Optional TypeScript definitions
  • @types/react-dom: Optional TypeScript definitions