Overlays
Hover Card.
A preview card that opens when a pointer rests on a link, such as a creator profile behind a username.
Built by @turtlewright on the east server.
import { CalendarDaysIcon, ServerIcon } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/ui/hover-card";
export default function HoverCardDemo() {
return (
<p className="text-sm text-muted-foreground">
Built by{" "}
<HoverCard>
<HoverCardTrigger asChild>
<a
href="#"
className="rounded-sm text-primary underline-offset-4 outline-none hover:underline focus-visible:ring-2 focus-visible:ring-ring"
>
@turtlewright
</a>
</HoverCardTrigger>
<HoverCardContent className="w-80">
<div className="flex gap-4">
<div
aria-hidden="true"
className="flex size-11 shrink-0 items-center justify-center rounded-full border border-input bg-accent font-display text-lg font-semibold text-[#b7ca9e]"
>
T
</div>
<div className="grid min-w-0 gap-2">
<div className="flex flex-wrap items-center gap-2">
<span className="font-display text-base font-medium tracking-tight text-foreground">turtlewright</span>
<Badge variant="success">Online</Badge>
</div>
<p className="text-sm leading-relaxed text-muted-foreground">
Runs the quarry hub and a guestbook with 312 signatures. Mostly writes turtle scripts.
</p>
<div className="flex flex-wrap gap-x-4 gap-y-1 font-mono text-[10px] tracking-[0.12em] text-muted-foreground uppercase">
<span className="inline-flex items-center gap-1.5">
<ServerIcon className="size-3" /> 3 hubs
</span>
<span className="inline-flex items-center gap-1.5">
<CalendarDaysIcon className="size-3" /> Since day 14
</span>
</div>
</div>
</div>
</HoverCardContent>
</HoverCard>{" "}
on the east server.
</p>
);
}Installation#
With the CLI
$npx lanterncn add hover-cardThis also installs the Lantern theme and any Lantern UI components it depends on. The shadcn CLI works directly too: npx shadcn@latest add httptim/lantern-ui/hover-card. See Installation if your project is not set up yet.
Manually
Install the dependencies
npm install radix-uiCopy the source into your project
components/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({ openDelay = 200, closeDelay = 150, ...props }: React.ComponentProps<typeof HoverCardPrimitive.Root>) { return <HoverCardPrimitive.Root data-slot="hover-card" openDelay={openDelay} closeDelay={closeDelay} {...props} />; } function HoverCardTrigger({ ...props }: React.ComponentProps<typeof HoverCardPrimitive.Trigger>) { return <HoverCardPrimitive.Trigger data-slot="hover-card-trigger" {...props} />; } function HoverCardContent({ className, align = "center", sideOffset = 6, ...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( "z-50 w-72 max-w-[calc(100vw-1.5rem)] origin-(--radix-hover-card-content-transform-origin) rounded-lg border bg-popover p-4 text-popover-foreground shadow-block-sm outline-none", "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 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", className, )} {...props} /> </HoverCardPrimitive.Portal> ); } export { HoverCard, HoverCardContent, HoverCardTrigger };Update the import paths to match your project
The source imports
cnfrom@/lib/utils.
Usage#
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/ui/hover-card";<HoverCard>
<HoverCardTrigger asChild>
<a href="#">@turtlewright</a>
</HoverCardTrigger>
<HoverCardContent>Profile preview</HoverCardContent>
</HoverCard>Hover cards are for sighted pointer users. The trigger link should still lead somewhere useful on its own.