Skip to content
WingoUI
ComponentsTemplatesDocsPricingAI agentsBlogChangelogContact
Components
Buttons & Actions
ButtonButton GroupCopy ButtonDelete ButtonTheme ToggleToggleToggle Group
Inputs
Avatar UploadCalendarCheckboxColor PickerComboboxCountry SelectCron PickerCurrency InputDate PickerDate Range PickerDate Time PickerDuration PickerEmail InputEmoji PickerFile UploadFilter BuilderInputInput GroupListboxMasked InputMention InputMonth PickerMulti SelectNumber InputOTP InputPassword InputPhone InputRadio GroupRatingSearch InputSegmented ControlSelectSignature PadSliderSwitchTag InputTextareaTime PickerTimezone SelectTree Select
Forms
Address InputBooking WidgetCSV ImportFieldForm WizardInline EditInvoice line itemsRich Text EditorSchema Builder
Navigation
Back To TopBounce SidebarBreadcrumbCommand MenuGlobal SearchGooey NavHook SidebarNav MenuNav TabsPaginationProximity SidebarScroll ProgressSidebarStepsTable Of ContentsTabsTopbarUser MenuWorkspace Switcher
Overlays
Alert DialogContext MenuDialogDrawerDropdown MenuFamily DrawerHover CardPopoverShare DialogSheetShortcuts DialogTooltipTour
Feedback
AlertBannerCookie ConsentEmoji ReactionEmpty StateNotification BellNotification CenterProgressRoute ProgressSetup ChecklistSkeletonSpinnerToast
Data Display
Approval FlowAvatarBadgeCalendar ViewCode BlockComment ThreadContact cardCountdownDescription ListDiff ViewerFile ListFile managerFolderGanttJSON ViewerKbdLog ViewerMarkdownPresenceSchedulerTagTimelineTree View
Tables & Lists
Audit LogData TableDeal PipelineEditable GridKanbanListMembers tablePermissions MatrixTableTask ListVirtual List
Charts & Stats
Animated CounterArea chartBar chartDonut chartFunnel chartGaugeGitHub ActivityHeatmap calendarLeaderboardLine chartRadar chartRadial barSparklineStat CardTrackerTrend badge
Layout
AccordionApp ShellCardCollapsibleDetail LayoutEntity HeaderPage HeaderScroll AreaSeparatorSettings LayoutSplit ViewToolbar
Media
Audio PlayerCarouselCSV ViewerDOCX EditorDOCX ViewerExcel ViewerFile SystemImage compareImage CropperImage GalleryImage LightboxLocation MapPDF ViewerPowerPoint ViewerQR CodeStep PlayerVideo Player
AI Kit
Agent Status CardChat MessageChat ThreadChat WidgetConversation ListFluid OrbGrid RevealMatrix OrbModel PickerPrompt InputReasoning IndicatorRule BuilderSuggestion ChipsTool Call TimelineUsage MeterVoice InputWorkflow Canvas
Text & Effects
Background PatternGravity LettersMarqueeTerminalText AnimateText Rotate
Mobile
Action SheetBottom Tab BarFABHaptic ButtonHero HeaderInstall PromptLarge Title HeaderNotification BannerOnboarding CarouselPicker WheelPull To RefreshSlide To ConfirmSticky CTA BarSwipe DeckSwipeable Tabs
Commerce
Cart drawerCategory pickerCheckout stepsCoupon inputFavorite buttonFilter panelListing cardListing gridOrder trackerPricePrice rangePricing tableProduct galleryQuantity stepperReviewsSeller card
Marketing Sections
App Download SectionBlog Cards SectionCTA SectionFAQ SectionFeature GridFeature ShowcaseHero SectionIntegrations SectionLogo CloudMarketing FooterMarketing HeaderMarketing SectionNewsletter SectionPricing SectionStats SectionSteps SectionTeam SectionTestimonials SectionTimeline SectionVideo Section
Blocks
Admin Dashboard PageAdmin ShellAI Chat PageAPI Keys PageAutomation Builder PageCheckout PageCRM Contact PageCRM Pipeline PageError PagesInbox PageInvoice PageKPI DashboardListing Detail PageLogin PageMarketplace Home PageMarketplace Search PageMarketplace ShellMobile App HomeOnboarding FlowOrder History PagePost Listing WizardPricing PageProfile PageRegister PageSettings PageUsers Admin Page
Templates
About PageAcademy PageAccessibility PageAffiliate PageAgency PageAI Product PageAppointment Booking PageBlog PageBlog Post PageBug Bounty PageCareers PageChangelog PageCommunity PageCompare PageContact PageCustomer Story PageCustomers PageDemo Booking PageDevelopers PageDocs Home PageDownload PageEnterprise PageEvents PageExperts PageFAQ PageFeature PageGlossary PageHelp Article PageHelp Center PageHome Services PageImpact PageIntegration Detail PageIntegrations PageJob Detail PageLanding PageLaunch PageLegal PageManifesto PagePortfolio PagePress PageProduct Tour PagePromo PageReal Estate PageReferral PageResearch Report PageRestaurant PageRoadmap PageROI Calculator PageSecurity PageSolutions PageStartups PageStatus PageStorefront PageSwitch PageTemplate Gallery PageTravel PageWaitlist PageYear in Review Page
Hooks & Utilities
AI ChatChart kitCommerceDate utilsFile exportFile typesFiltersForm validationHapticsInvoicingMotion presetsNavigationNumber formatRelative timeRomanian locationsSpreadsheetText matchTonesUIProvideruseClipboarduseConsentuseControllableStateuseCooldownuseDebounceuseKeyboardInsetuseLocaleuseLongPressuseMediaControlsuseMediaQueryuseOverflowItemsusePersistedStateuseScrollEdgesuseScrollStateuseSelectionuseShortcutuseStickToBottom
GalleryTheme

Overlays

Hover Card

Overlays

Hover Card React component for Tailwind CSS v4

Family DrawerPopover
Live props
Content
sheetTitle
Appearance
size
radius
padding
arrow
Layout
side
align
sideOffset8px
Behavior
openDelay500ms
closeDelay200ms
responsive
State
defaultOpen
disabled
Code
import { HoverCard } from "@/components/ui/hover-card"

<HoverCard />
  1. Home
  2. Components
  3. Overlays
  4. Hover Card
Pro

Hover Card React component for Tailwind CSS v4

v1.0.0·Added in 1.0.0

A React hover card: a rich preview of a person, listing or link on hover or focus, opening as a bottom sheet on touch screens.

Rest the pointer on a link or a name and after half a second the preview grows out of it on a quick spring. Move onto the card and it stays open, so its buttons and links work; leave both and it fades out 200ms later. Tab to the trigger and it opens the same way; Escape or moving focus on closes it. The card is a supplement: its content is skipped by Tab and every action in it is reachable elsewhere. On phones and tablets there is no hover, so the first tap opens the preview as a bottom sheet instead of following the link: drag it down, tap the dim page or press Escape to close it, and the sheet's own link leads on. With reduced motion it only fades.

Hover Card is a Pro React component in the React overlay components category, written in TypeScript for React 19 and Tailwind CSS v4. It installs as source with npx wingo-ui@latest add hover-card, together with UIProvider, Drawer, Motion presets, useControllableState and useMediaQuery and the npm packages @radix-ui/react-hover-card, @radix-ui/react-slot and motion.

Add to a project

Requirements: React 19 and Tailwind CSS v4, in Next.js (App Router or Pages), Vite or React Router. Installation guide · Next.js setup · Vite setup

npx wingo-ui@latest add hover-card

Hover Card is part of Pro, with 298 more Pro items: $8 a month or $150 once. 14-day refund before you download any Pro item. See plans

Usage

Import HoverCard from @/components/ui/hover-card.

import { HoverCard } from "@/components/ui/hover-card"
import { Avatar } from "@/components/ui/avatar"

export function Mention() {
  return (
    <p className="text-sm">
      Ask{" "}
      <HoverCard
        trigger={
          <a href="/profile/emma.carter" className="font-semibold underline decoration-foreground/25 underline-offset-4">
            @emma.carter
          </a>
        }
        sheetTitle="Emma Carter's profile"
      >
        <div className="flex items-center gap-3">
          <Avatar src="/demo/ana-pop.jpg" name="Emma Carter" size="lg" status="online" className="[--avatar-ring:var(--popover)]" />
          <div className="min-w-0">
            <p className="text-[15px] font-semibold">Emma Carter</p>
            <p className="text-[13px] text-muted-foreground">Portland · member since 2019</p>
          </div>
        </div>
        <p className="mt-3 text-[13px] text-muted-foreground">48 listings · 4.9 ★ · replies in 1 h</p>
        <a href="/profile/emma.carter" className="mt-3 inline-block font-medium underline underline-offset-4">
          View profile
        </a>
      </HoverCard>{" "}
      about the bike.
    </p>
  )
}

Props

  • trigger
    ReactNode

    What you hover, rendered asChild: an <a>, a router Link, a Button or an avatar wrapped in a button. It must pass a ref to its element. Plain text gets a focusable button with a dotted underline, for a name or a term inside a sentence.

  • children
    ReactNode

    The preview: an avatar row and stats, a listing with its photo, an article with its image. Round inner parts with rounded-(--hover-card-inner-radius), which follows radius and padding (and is 16px in the sheet). Put a real link to the destination in it for touch screens.

  • sheetTitledefault "Preview"
    string

    The bottom sheet's title for screen readers. The sheet shows no header, but a dialog needs a name: say what it previews, like "Profilul Anei Pop".

  • sizedefault "md"
    "sm" | "md" | "lg" | "auto"

    Width of the floating card: 256, 288 or 384px, or auto to fit the content (192px at least). Never wider than the screen minus 12px a side. The sheet always spans the phone.

  • radiusdefault "md"
    "none" | "sm" | "md" | "lg" | "full"

    Corner radius of the card: 0, 12, 16 or 24px; full falls back to lg. The sheet keeps its own 28px top corners.

  • paddingdefault "md"
    "none" | "sm" | "md" | "lg"

    Inner padding of the card: 0, 8, 16 or 20px. none lets a photo run to the edges (the card clips it to its corners), sm gives an inset photo with a matching smaller radius. The sheet always pads 20px.

  • arrowdefault false
    boolean

    A small arrow with a rounded tip in the card's color, pointing at the trigger. Its sides carry on the card's hairline and it keeps clear of the corners.

  • sidedefault "bottom"
    "top" | "right" | "bottom" | "left"

    Where the card opens. It flips to the opposite side and slides along the edge when there is no room.

  • aligndefault "center"
    "start" | "center" | "end"

    Alignment along the trigger's edge.

  • sideOffsetdefault 8
    number

    Distance from the trigger in px. The arrow adds its own 8px on top.

  • openDelaydefault 500
    number

    Hover (or keyboard focus) time in ms before it opens, so the pointer can cross a page full of links without cards popping up. 0 opens at once.

  • closeDelaydefault 200
    number

    Time in ms before it closes after the pointer leaves the trigger and the card. It is the grace period for travelling onto the card; at 0 it closes before you get there.

  • responsivedefault true
    boolean

    On phones (below 768px) and touch screens (a coarse pointer, like an iPad at 1024px) the first tap on the trigger opens the preview as a bottom sheet instead of following the link. Off: the floating card everywhere, and a tap follows the link.

  • defaultOpendefault false
    boolean

    Starts open (uncontrolled). Leaving the trigger and the card, Escape or a click outside closes it.

  • disableddefault false
    boolean

    Never opens and closes if it is open, e.g. for your own name in a list. The trigger keeps working: a link navigates on click and on tap.

  • open
    boolean

    Controls it from outside, with onOpenChange.

  • onOpenChange
    (open: boolean) => void

    Called on hover, focus, a tap on touch screens, Escape and outside clicks. Not called for opens refused while disabled.

  • container
    HTMLElement | null

    Where the card (or the sheet) mounts. document.body by default.

  • classNames
    Partial<Record<"content" | "body" | "arrow", string>>

    Extra classes for the card (hover-card-content, also the sheet), its padded scroll region (hover-card-body) and the arrow svg (set a fill-* to recolor it).

  • className
    string

    Extra classes for the card, merged last. Other Radix content props pass through: alignOffset, collisionPadding (12), avoidCollisions, sticky, hideWhenDetached, onEscapeKeyDown, onPointerDownOutside.

Parts

  • HoverCardRoot

    component

    Compound API: holds the state and picks the mode once (the Radix hover card, or the drawer's bottom sheet on phones and touch screens). No DOM. Props: { open, defaultOpen, onOpenChange, openDelay, closeDelay, responsive, disabled }.

  • HoverCardTrigger

    component

    An <a> (or your child with asChild) that opens the card on hover and focus, or the sheet on a tap, where it keeps the link from navigating. A plain element gets data-slot="hover-card-trigger" and data-state; a component child keeps its own and gets data-hover-card-state. Props: ComponentProps<"a"> & { asChild?: boolean }.

  • HoverCardContent

    component

    The portaled, animated card (hover-card-content with data-side, data-align, data-size, data-state) and its body (hover-card-body); in sheet mode the drawer's sheet with the same slots and a hidden title. Props: { side, align, sideOffset, size, radius, padding, arrow, sheetTitle, container, classNames } & Radix HoverCard.Content props.

  • useHoverCard

    hook

    The nearest hover card's state, for content that lays out bigger in the sheet (44px buttons, a larger avatar) or closes the card after an action. Signature: () => { open: boolean, setOpen: (open: boolean) => void, sheet: boolean }.

Examples

Listing preview

padding="sm" insets the photo, whose corners follow --hover-card-inner-radius. The price is formatted in USD.

Sides with the arrow

Four sides, each on a team avatar. size="auto" fits the text; the card flips when there is no room.

Instant vs default delays

Plain text triggers get a dotted underline. 0 / 0 opens at once and closes the moment you leave.

Link preview

padding="none" and size="lg": the cover runs to the card's edges and the card clips it.

On a phone

Touch screens have no hover, so the first tap opens a bottom sheet with 48px buttons (useHoverCard).

Dependencies

@radix-ui/react-hover-card@radix-ui/react-slotmotionui-configdrawermotionuse-controllable-stateuse-media-query

Files

  • components/ui/hover-card.tsx

FAQ

Is the React Hover Card component free?

The preview, props and docs are free; copying the source needs a Pro plan. See plans.

How do I install Hover Card?

Run npx wingo-ui@latest add hover-card. It also adds the Wingo UI items it builds on (UIProvider, Drawer, Motion presets, useControllableState and useMediaQuery) and the npm packages @radix-ui/react-hover-card, @radix-ui/react-slot and motion. With shadcn, add the @wingo-ui registry with your API key, then run npx shadcn@latest add @wingo-ui/hover-card.

How does Hover Card behave on phones?

On phones (below 768px) and touch screens (a coarse pointer, like an iPad at 1024px) the first tap on the trigger opens the preview as a bottom sheet instead of following the link. Off: the floating card everywhere, and a tap follows the link. The responsive prop controls this and is on by default.

See also

PopoverTooltipDrawerAvatar

More React overlay components

Share DialogSheetShortcuts DialogTourDropdown MenuAlert Dialog
All 13 React overlay components
PreviousFamily DrawerNext Popover

Questions about this listing

3 comments
  1. Daniel Reed2 h ago

    @emma.carter is the bike still available? I could come by tomorrow afternoon to see it.

  2. Emma CarterSeller1 h ago

    Yes, it is. I am around after 5 PM, in the Pearl District.

  3. Sophia Lee20 min ago

    I bought a table from @emma.carter last month. Everything was exactly as pictured.

Hover @emma.carter or a name, then move onto the card: it stays open. Tab to a link and it opens too.

Tap @emma.carter or a name: without hover the preview opens as a sheet.

openDelay 500ms · closeDelay 200ms · sheet on touch · sheetTitle "Preview"