sdxc

Type to search, or start from one of these:

HoverCard

A supplementary detail panel that appears beside a trigger on hover or keyboard focus.

Merged by @sergiodxa
SX
Sergio Xalambrí@sergiodxa
Writes small packages built on web standards.
Lima, PeruJoined March 2011
two hours ago.
View code
<Text>
	Merged by{" "}
	<HoverCard>
		<HoverCard.Trigger>
			<Link href="/users/sergiodxa">@sergiodxa</Link>
		</HoverCard.Trigger>
		{/* bottom-start keeps the panel inside the column it opens in, rather than
		    centering it under the mention and hanging off the edge. */}
		<HoverCard.Content
			placement="bottom-start"
			aria-label="About @sergiodxa"
			// Every recipe compiles into its own cascade sublayer, and a sublayer's position
			// is fixed the first time it appears on the page. The panel's own hidden state
			// registers after the root's reveal rules, which a later layer wins against, so
			// the reveal is restated here where it lands last.
			mix={[
				when(':is([data-slot="hover-card"]:hover, [data-slot="hover-card"]:focus-within) &', [
					opacity(100),
					visibility(),
				]),
			]}
		>
			<Avatar size="lg">
				<Avatar.Fallback>SX</Avatar.Fallback>
			</Avatar>
			<span>Sergio Xalambrí</span>
			<Text>Writes small packages built on web standards.</Text>
			<span>
				<MapPinIcon aria-hidden="true" /> Lima, Peru
			</span>
			<span>
				<CalendarIcon aria-hidden="true" /> Joined March 2011
			</span>
			<Button size="sm">Follow</Button>
		</HoverCard.Content>
	</HoverCard>{" "}
	two hours ago.
</Text>

Installation

An ordinary dependency: install it, import the theme once, and import the component where it is used.

npm add @sdxc/ui
import "@sdxc/ui/theme.css";

Usage

import { HoverCard } from "@sdxc/ui";

Renders the compound root: a <span> providing HoverCard.Content's anchor and the hover/focus-within scope that reveals it, so hovering or focusing the trigger or panel keeps it open with no script-tracked state.

Composition

The parts the component publishes, each a static property of the host.

  • HoverCard
  • HoverCard.TriggerRenders HoverCard.TriggerProps.children inside a <span> styled display: contents, so the trigger keeps the child's own layout and hover/focus-within participation, visible straight through to the root above.
  • HoverCard.ContentRenders the panel: a <div> sharing Popover's surface and placement contract, kept in normal stacking order for its CSS-driven hover/focus reveal, with delays tuned for pointer and keyboard users.

Props

Read from the component's own types, so every prop, every default and every allowed value is listed.

PropTypeDescription
childrenRemixNodeThe compound root's parts: HoverCard.Trigger followed by HoverCard.Content.

Also accepts everything in TagProps<"span">.

HoverCard.Trigger

PropTypeDescription
childrenRemixNodeThe visible trigger — a link, button, or other element. The root reveals HoverCard.Content whenever focus or a hover-capable pointer rests inside it, so pointer users reach the panel even without a focusable child.

Also accepts everything in TagProps<"span">.

HoverCard.Content

PropTypeDescription
placement?"top" | "top-start" | "top-end" | "bottom" | "bottom-start" | "bottom-end" | "left" | "left-start" | "left-end" | "right" | "right-start" | "right-end"Side of the trigger to render against. Defaults to DEFAULT_PLACEMENT.
childrenRemixNodeThe panel's content.

Also accepts everything in TagProps<"div">.

Types

NameValuesWhat it decides
Placement"top" | "top-start" | "top-end" | "bottom" | "bottom-start" | "bottom-end" | "left" | "left-start" | "left-end" | "right" | "right-start" | "right-end"Side of the trigger the panel renders against, and — for corner variants — which trigger edge it aligns to on the perpendicular axis.