Hover Card
Anatomy
Rich hover overlay with configurable placement and alignment for user profiles, tooltips, and detailed previews.
maud_ui::primitives::hover_card
Props
Generated from public Rust fields. Defaults are evaluated from the implementation.
| Prop | Type | Default | Description |
|---|---|---|---|
trigger | Markup | PreEscaped("") | The trigger element (link, button, text, etc.) |
content | Markup | PreEscaped("") | The rich content displayed in the card |
id | String | "hover-card" | Unique identifier for the card |
open_delay_ms | u32 | 600 | Delay in milliseconds before showing (default 600, matching Base UI). |
close_delay_ms | u32 | 300 | Delay in milliseconds before closing (default 300, matching Base UI). |
side | Placement | Bottom | Which side of the trigger to anchor the card to (default: Bottom) |
align | Align | Center | Alignment along the trigger edge (default: Center) |
Examples
HoverCard — Bottom / Center (default)
Crafting beautiful, accessible interfaces. Passionate about design systems.
HoverCard — Top / End
Crafting beautiful, accessible interfaces. Passionate about design systems.
HoverCard — Right / Start
Crafting beautiful, accessible interfaces. Passionate about design systems.
Usage and composition
Import
use maud_ui::primitives::hover_card::{self, Props, Placement, Align};
Example
use maud::html;
use maud_ui::primitives::hover_card;
html! {
(hover_card::render(hover_card::Props {
trigger: html! { a href="#" { "@jane" } },
content: html! {
div { "Jane Doe" }
p { "Software designer" }
},
id: "user-card-1".to_string(),
side: hover_card::Placement::Bottom,
align: hover_card::Align::Center,
..Default::default()
}))
}
Placement
pub enum Placement {
Top,
Right,
Bottom, // default
Left,
}
Align
pub enum Align {
Start,
Center, // default
End,
}
Related
Shadcn Reference
Mirrors shadcn's HoverCard with Placement and Align variants. Nova uses Floating UI when available and a dependency-free placement fallback. The runtime restores its owned inline placement and animation-origin properties on cleanup. The current comparison still records settled shadow pixels and transformed/clipped ancestor limitations; motion parity alone does not establish complete component parity.
Accessibility
- Trigger is a semantic link or button.
- Card hidden by default with
hiddenattribute. - Uses
data-visible="false"for CSS state management. - No ARIA live region by default (async JavaScript handles visibility).
In Nova, mouse-like hover (mouse or pen) and keyboard-visible trigger focus open the card. Touch compatibility mouse events do not open it. Pointer exit preserves the card while keyboard focus remains on the trigger or inside the popup; a mouse-focused trigger alone does not keep it open. Standard retains its existing interaction policy.
Nova uses the pinned 100 ms entry and exit animations. Entry fades and scales from 95%, sliding 8 px from the resolved side; exit fades and scales without a slide. The transform origin follows the anchor and collision-adjusted placement. Escape closes the card and prevents focus returning to the same trigger from reopening it until focus or the pointer leaves the trigger. Reduced motion retains Maud's animation suppression policy.