@biem/ui

Hover Card

A card that shows users what is behind a link before they follow it.

A hover card shows a preview of the content behind a link, so users decide whether to follow the link without leaving the page. It opens when users rest the mouse pointer on the trigger or move focus to it with the keyboard. It stays open while the pointer is on the trigger or on the card, and it closes when the pointer or the focus leaves, when users press Escape or when they press outside of the card. Touch input doesn't open the hover card, so everything in it must also be available behind the link. The trigger is a link without styles of its own, so the examples render it as a Button with the link variant. The content is 16rem wide.

Usage

hover-card-default.tsx
import { Button } from "@biem/ui/components/ui/button";
import {
	HoverCard,
	HoverCardContent,
	HoverCardTrigger,
} from "@biem/ui/components/ui/hover-card";

export function HoverCardDefault() {
	return (
		<HoverCard>
			<HoverCardTrigger render={<Button variant="link"/>}>Transfer 4821</HoverCardTrigger>
			<HoverCardContent>
				<p className="font-medium">Transfer in transit</p>
				<p className="text-muted-foreground">
					The 12 cases have left the warehouse and will reach the store on Tuesday.
				</p>
			</HoverCardContent>
		</HoverCard>
	);
}

Examples

References in running text, such as a product in a note or a supplier in an order, usually lead to a page of their own. With an address in href, the trigger becomes a real link to that page, so users can follow it, open it in a new tab or copy its address, and the preview tells them beforehand what they will find there.

Top Side

Links in a footer or in the last rows of a long table sit close to the lower edge of the screen. There, side set to "top" opens the card above the trigger, where it can show its content in full.

Right Side

A navigation along the left edge of a screen, such as a list of stores, stacks its entries closely. Set to "right", side opens the card beside the trigger, so it covers none of the entries above or below.

Bottom Side

Users read a page from top to bottom, and most links leave enough room beneath them. The card therefore opens below the trigger by default, and side set to "bottom" states this explicitly. Where the space below runs short, it moves above the trigger on its own.

Left Side

Panels along the right edge of a screen, such as a list of open tasks, leave no room to their right. With the value "left", side opens the card toward the center of the screen, where it has the space it needs.

Open by Default

A preview can matter before users reach for it, for example when a delivery has changed since their last visit. Through defaultOpen, the card is already open when the page appears. Users close it as they would close any hover card, and afterwards it opens again whenever they return to the link.

Controlled

In some workflows, the application decides when a preview may appear, for example to keep it closed while users rearrange a list by dragging. Once it controls the card through open and onOpenChange, any part of the interface can open or close it as well.

API Reference

HoverCard

Propopen
Typeboolean
Default–
DescriptionSets whether the hover card is open and makes it controlled. Update it in onOpenChange.
PropdefaultOpen
Typeboolean
Defaultfalse
DescriptionOpens the hover card at first render. The hover card then tracks its open state itself.
ProponOpenChange
Type(open: boolean, eventDetails: PreviewCardRootChangeEventDetails) => void
Default–
DescriptionRuns when users open or close the hover card. It receives the open state that follows.
ProponOpenChangeComplete
Type(open: boolean) => void
Default–
DescriptionRuns after the hover card has opened or closed and its animations have finished.
ProptriggerId
Typestring | null
Default–
DescriptionSets the ID of the trigger that a controlled hover card is associated with. A hover card without open doesn't need it.
PropdefaultTriggerId
Typestring | null
Default–
DescriptionSets the ID of the trigger that the hover card is associated with when defaultOpen opens it at first render.
Prophandle
TypePreviewCardHandle<Payload>
Default–
DescriptionConnects the hover card with triggers that are rendered outside of it. Create the handle with PreviewCard.createHandle() from @base-ui/react/preview-card.
PropactionsRef
TypeRefObject<PreviewCardRootActions | null>
Default–
DescriptionReceives the functions close and unmount. close closes the hover card from code, and unmount removes it from the DOM after a closing animation that the code controls itself.
Propchildren
TypeReactNode | ((arg: { payload: Payload | undefined }) => ReactNode)
Default–
DescriptionHolds the parts of the hover card. A function receives the payload of the trigger that opened the hover card.

HoverCardTrigger

Prophref
Typestring
Default–
DescriptionSets the address that the trigger links to. The trigger renders a link and needs it, unless render replaces the link with another element.
Propdelay
Typenumber
Default600
DescriptionSets how many milliseconds the pointer or the focus must rest on the trigger before the hover card opens.
PropcloseDelay
Typenumber
Default300
DescriptionSets how many milliseconds the hover card stays open after the pointer has left the trigger and the content.
Prophandle
TypePreviewCardHandle<Payload>
Default–
DescriptionConnects the trigger with a hover card that it is rendered outside of. Pass the same handle to HoverCard.
Proppayload
TypePayload
Default–
DescriptionPasses a value to the hover card when this trigger opens it. A function as children of HoverCard receives it.
Propid
Typestring
Default–
DescriptionSets the ID of the trigger element. triggerId and defaultTriggerId of HoverCard refer to it.
Proprender
TypeReactElement | render function
Default–
DescriptionReplaces the native element or composes the trigger with another component.

HoverCardContent

Propside
Type"top" | "bottom" | "left" | "right" | "inline-end" | "inline-start"
Default"bottom"
DescriptionSets the side of the trigger that the content opens on. "inline-start" and "inline-end" follow the reading direction. The content moves to the opposite side when the chosen one has too little space.
PropsideOffset
Typenumber | OffsetFunction
Default4
DescriptionSets the distance between the trigger and the content in pixels. A function receives the side, the alignment and the dimensions of the trigger and the content, and returns the distance.
Propalign
Type"start" | "center" | "end"
Default"center"
DescriptionSets where the content lines up with the trigger along the chosen side: at its start, its center or its end.
PropalignOffset
Typenumber | OffsetFunction
Default4
DescriptionMoves the content along the alignment axis by a number of pixels. A function receives the same data as the one for sideOffset and returns the offset.
Proprender
TypeReactElement | render function
Default–
DescriptionReplaces the native element or composes the content with another component.