import { CalendarIcon } from "lucide-react"
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/components/ui/hover-card"
export default function HoverCardDemo() {
return (
<HoverCard>
<HoverCardTrigger asChild>
<a
href="#"
className="text-sm font-medium underline-offset-4 hover:underline"
>
@logic2b
</a>
</HoverCardTrigger>
<HoverCardContent className="w-80">
<div className="flex justify-between gap-4">
<div className="space-y-1">
<h4 className="text-sm font-semibold">@logic2b</h4>
<p className="text-sm">
Beautifully designed components you copy into your project.
</p>
<div className="flex items-center pt-2">
<CalendarIcon className="mr-2 size-4 opacity-70" />
<span className="text-muted-foreground text-xs">
Joined December 2023
</span>
</div>
</div>
</div>
</HoverCardContent>
</HoverCard>
)
}Installation
npx logic2b@latest add hover-cardWorking with an AI assistant? Copy this prompt into Claude Code, Cursor or Copilot — it carries the install steps, a no-CLI fallback and a verification checklist.
Add the "hover-card" item from the logic2b ui registry (https://ui.logic2b.com) to this project. Follow every step and verify at the end. ## Steps 1. If the project has no `components.json` yet, set up logic2b ui first: ```bash npx logic2b@latest init ``` 2. Install the item (the CLI resolves registry dependencies automatically): ```bash npx logic2b@latest add hover-card ``` 3. Install any npm dependencies the command prints. ## If the CLI is not available Do it manually from the registry payload: 1. Fetch https://ui.logic2b.com/r/hover-card.json. 2. Write every entry in `files[]` to its mapped project path (see below). 3. Repeat (recursively) for each name in `registryDependencies`. 4. Install every package listed in `dependencies` across those payloads. ## Registry reference - Index of every item: https://ui.logic2b.com/r/index.json - Item payload (full source): https://ui.logic2b.com/r/<name>.json - Usage examples per item: https://ui.logic2b.com/r/demos/index.json → https://ui.logic2b.com/r/demos/<demo>.json - Docs index for agents: https://ui.logic2b.com/llms.txt (full docs: https://ui.logic2b.com/llms-full.txt) - Every docs page is Markdown when you append `.md` to its URL. Registry file paths map to project paths like this: - `ui/*` → `@/components/ui/*` - `blocks/<name>/*` → `@/components/*` - `charts/*` → `@/components/charts/*` - `hooks/*` → `@/hooks/*` - `lib/utils.ts` → `@/lib/utils.ts` - `theme.css` → next to the project's Tailwind entry stylesheet ## Conventions (do not break these) - Tailwind CSS v4 (CSS-first config; no tailwind.config.js needed) and React 19. - All colors go through semantic tokens (`bg-primary`, `text-muted-foreground`, `border-border`, …). Never hardcode hex/oklch values in components. - Dark mode is class-based: toggle `.dark` on `<html>`. - Icons come from lucide-react. ## Verify before finishing 1. The dev server starts and the app renders without console errors. 2. TypeScript compiles (`tsc --noEmit` or the framework's check). 3. Components use the theme: a `<Button>` shows the primary token color, and toggling `.dark` on `<html>` switches the palette.
Install the dependencies:
npm install radix-uiCopy into ui/hover-card.tsx:
"use client"
import * as React from "react"
import { HoverCard as HoverCardPrimitive } from "radix-ui"
import { cn } from "@/lib/utils"
function HoverCard({
...props
}: React.ComponentProps<typeof HoverCardPrimitive.Root>) {
return <HoverCardPrimitive.Root data-slot="hover-card" {...props} />
}
function HoverCardTrigger({
...props
}: React.ComponentProps<typeof HoverCardPrimitive.Trigger>) {
return (
<HoverCardPrimitive.Trigger data-slot="hover-card-trigger" {...props} />
)
}
function HoverCardContent({
className,
align = "center",
sideOffset = 4,
...props
}: React.ComponentProps<typeof HoverCardPrimitive.Content>) {
return (
<HoverCardPrimitive.Portal data-slot="hover-card-portal">
<HoverCardPrimitive.Content
data-slot="hover-card-content"
align={align}
sideOffset={sideOffset}
className={cn(
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-64 origin-(--radix-hover-card-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden",
className
)}
{...props}
/>
</HoverCardPrimitive.Portal>
)
}
export { HoverCard, HoverCardTrigger, HoverCardContent }Usage
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/components/ui/hover-card"
<HoverCard>
<HoverCardTrigger>@logic2b</HoverCardTrigger>
<HoverCardContent>
Copy-paste components for building beautiful interfaces, fast.
</HoverCardContent>
</HoverCard>
API
| Prop | Type | Default |
|---|---|---|
align (HoverCardContent) |
start | center | end |
center |
sideOffset (HoverCardContent) |
number |
4 |
openDelay / closeDelay (HoverCard) |
number (ms) |
700 / 300 |
open / onOpenChange (HoverCard) |
boolean / (open: boolean) => void |
— |
Examples
Profile
import { CalendarIcon } from "lucide-react"
import { Avatar, AvatarFallback } from "@/components/ui/avatar"
import { Button } from "@/components/ui/button"
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/components/ui/hover-card"
export default function HoverCardProfileDemo() {
return (
<HoverCard>
<HoverCardTrigger asChild>
<Button variant="link">@logic2b</Button>
</HoverCardTrigger>
<HoverCardContent className="w-80">
<div className="flex gap-4">
<Avatar>
<AvatarFallback>L2</AvatarFallback>
</Avatar>
<div className="space-y-1">
<h4 className="text-sm font-semibold">@logic2b</h4>
<p className="text-sm">
A component registry you copy into your project.
</p>
<div className="text-muted-foreground flex items-center pt-2 text-xs">
<CalendarIcon className="mr-2 size-4 opacity-70" />
Joined December 2023
</div>
</div>
</div>
</HoverCardContent>
</HoverCard>
)
}Custom Delay & Alignment
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/components/ui/hover-card"
export default function HoverCardAlignDemo() {
return (
<HoverCard openDelay={100} closeDelay={100}>
<HoverCardTrigger asChild>
<a
href="#"
className="text-sm font-medium underline-offset-4 hover:underline"
>
Hover for details
</a>
</HoverCardTrigger>
<HoverCardContent align="start" className="w-72">
<p className="text-sm font-medium">Instant preview</p>
<p className="text-muted-foreground mt-1 text-sm">
This card opens after a shorter delay and is aligned to the start
edge of the trigger.
</p>
</HoverCardContent>
</HoverCard>
)
}Accessibility
- Built on Radix Hover Card:
it opens on pointer hover and on keyboard focus of the trigger, so it is
reachable with the
Tabkey. - It is a supplementary preview for sighted users — it does not trap focus and is not announced as a dialog, so never place essential content or actions only inside the card.
Escapedismisses an open card.