HoverCard
A supplementary detail panel that appears beside a trigger on hover or keyboard focus.
Merged by @sergiodxa two hours ago.
SX
Writes small packages built on web standards.Sergio Xalambrí@sergiodxa
Lima, PeruJoined March 2011
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/uiimport "@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.
HoverCardHoverCard.TriggerRenders HoverCard.TriggerProps.children inside a<span>styleddisplay: 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.
| Prop | Type | Description |
|---|---|---|
children | RemixNode | The compound root's parts: HoverCard.Trigger followed by HoverCard.Content. |
Also accepts everything in TagProps<"span">.
HoverCard.Trigger
| Prop | Type | Description |
|---|---|---|
children | RemixNode | The 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
| Prop | Type | Description |
|---|---|---|
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. |
children | RemixNode | The panel's content. |
Also accepts everything in TagProps<"div">.
Types
| Name | Values | What 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. |