jixoai-ui
the terminal design language
loading the style sheet…
Skip to content
docs · print medium: screen

registry:ui · NativeHTML

hover card — intent with an interactive panel

The tooltip's intent model (hover delay in, cancellable close grace, focus opens instantly, Escape closes) on a popover=manual panel — but the card is interactive content: pointer and focus CROSSINGS between trigger and card never dismiss; only a real exit or Escape does. No role=tooltip and no aria-describedby — the card is supplementary rich content, not a description.

crossing-safe grace focus opens CSS anchoring

hover card

Hover the handle, then MOVE ONTO the card — it stays. Click the link inside it. Tab to the trigger: the card opens instantly and stays while focus crosses into it.

shipped by @gaubee

Gaubee — systems

Component grammar, terminal surfaces, the one-brand-hue law.

the component index — the card stays while focus crosses onto this link (the focus-crossing grace).

under MIT.

hover-card-usage.svelte svelte
<HoverCard>
  {#snippet trigger()}<a href="#">@gaubee</a>{/snippet}
  <div>…rich card…</div>
</HoverCard>

types

Hover card variants

Placement and surface paint are the knobs; the delays are hover-card paced by default.

placement

top | bottom | left | right — bottom (under, like a peek) is the convention.

variant

solid | acrylic | auto (default) — the floating-surface paint family.

delays

openDelay=300, closeDelay=200 — tunable per instance.

usage

Usage

The trigger snippet is usually a link; the card is free content — headings, links, images.

HoverCard usage
<script lang="ts">
  import HoverCard from '@ui/hover-card.svelte';
</script>

<HoverCard>
  {#snippet trigger()}
    <a href="/team/gaubee">@gaubee</a>
  {/snippet}
  <div class="flex flex-col gap-2">
    <p><strong>Gaubee</strong> — systems</p>
    <p>component grammar, terminal surfaces</p>
  </div>
</HoverCard>

a11y

Accessibility

No tooltip role and no aria-describedby — the card is supplementary rich content, not a description.

Keyboard

KeyAction
TabFocus opens the card instantly; focus crossings into the card never dismiss
EscapeCloses the card immediately (global)

ARIA

AttributeValueDescription
rolenone imposedNot role=tooltip — compose headings/links inside; the card is content.
aria-describedby—Deliberately absent: the card is not a description of the trigger.
popovermanualLight dismiss stays OFF — pointer and focus crossings must not dismiss.

theming

Density and tokens

The panel rides the shared surface-motion kernel and the jx-surface paint law.

xs
@density

hover the trigger — the card measures panel↔anchor live.

sm
@density

hover the trigger — the card measures panel↔anchor live.

default
@density

hover the trigger — the card measures panel↔anchor live.

lg
@density

hover the trigger — the card measures panel↔anchor live.

TokenDefaultSource
--jx-hover-{id}anchor-namecomponent
--jx-p0 → 1 timelinecomponent
panel widthmax min(88vw, 20rem)structural
open / close delays300ms / 200msstructural
--jx-text11 / 12 / 13 / 15pxdensity
--jx-inset8 / 8 / 12 / 16pxdensity

axes

Universal props

The eight-axis surface (explicit-props): size · shape · radius · density · color · theme · elevation · motion — each axis takes named steps, auto (inherit the ambient context; stamps nothing), an exact number (px · coefficient · dp · hue per axis), or query() for responsive/container-conditional values. The peek card carries its OWN elevation — level2 (3dp, the anchored rung): the theme's level table pairs the shadow recipe with the ladder rung; the carriers stamp the promoted panel root (self-carried across the top layer).

HoverCard · universal props

level2 · default

3dp + the surface-container-low rung — the peek card's own rung.

level3

6dp + the surface-container rung.

hover-card-universal.svelte svelte
<HoverCard elevation="level3">{#snippet trigger()}…trigger…{/snippet}…card…</HoverCard>

api

API

Eight named props plus the eight universal axes (sixteen interface members; the axes fold below per the convention); trigger and children are the two required snippets.

Properties

PropertyTypeDefaultDescription
id stringautoPanel id; also derives the CSS anchor name.
children * Snippet—The card content — compose freely (headings, links, images).
trigger * Snippet—The trigger content; the wrapper span carries the anchoring.
placement 'top' | 'bottom' | 'left' | 'right''bottom'Anchored side — bottom (under, like a peek) is the convention.
openDelay number300Hover delay before the card opens (ms).
closeDelay number200Close grace spanned across trigger AND panel (ms).
variant 'solid' | 'acrylic' | 'auto''auto' · Own default, not ambientFloating-surface paint. Defaults: literal slot — own 'auto', ambient when an axis opens.
class string''Forwarded to the trigger wrapper.

Universal props

PropertyTypeDefaultDescription
size'small' | 'medium' | 'large' | 'auto' | number'auto' · ambient scopethe base scale — root font-size; parts size in em
shape'round' | 'scoop' | 'bevel' | 'notch' | 'square' | 'squircle' | 'auto''auto' · ambient scopecorner geometry (CSS corner-shape; §14 degrade table)
radius'small' | 'medium' | 'large' | 'auto' | number'auto' · ambient scopecorner size; auto = the concentric broadcast (§3)
density'small' | 'medium' | 'large' | 'auto' | number'auto' · ambient scopespacing/leading scale over the kernel channels (§4)
color'primary' | 'secondary' | 'error' | 'warn' | 'success' | 'info' | 'auto' | number | string'auto' · ambient scopethe hue axis of the fixed oklch primary system (§5)
theme'light' | 'dark' | 'system' | 'auto''auto' · ambient scopelight/dark profile; system = the JS-mutable global (§6)
elevation'level-1' | 'level0' | 'level1' | 'level2' | 'level3' | 'level4' | 'level5' | 'auto' | number'auto' · ambient scopeofficial M3 levels over the surface ladder (§7)
motion'reduced' | 'subtle' | 'normal' | 'expressive' | 'auto' | number'auto' · ambient scopeintensity across the motion kernels (§8)
jixoai-ui ui.jixoai.com the jixoai design language

Theme

Brand hue

0°

Auto cycle · 24h