PreviewCard
Overview
Section titled “Overview”PreviewCard is a lookless ContentControl whose Content is the trigger and whose
PreviewContent is the hover-revealed panel; it is the WPF port of the web family née HoverCard.
Unlike Popover it is non-modal end to end: it never traps or moves focus, matching the web’s
MoveFocusInside = false. Opening and closing are driven by hover-intent timers (OpenDelay,
CloseDelay) shared between the trigger and the popup content, so the pointer can travel from one
to the other without the card closing.
xmlns:navius="clr-namespace:Navius.Wpf.Primitives.Controls;assembly=Navius.Wpf.Primitives"
<navius:NaviusPreviewCard Side="Bottom" OpenDelay="600" CloseDelay="300"> <navius:NaviusButton Content="@navius" /> <navius:NaviusPreviewCard.PreviewContent> <StackPanel> <TextBlock Text="Navius" FontWeight="Bold" /> <TextBlock Text="A Blazor-native design system." /> </StackPanel> </navius:NaviusPreviewCard.PreviewContent></navius:NaviusPreviewCard>Like Popover, no NaviusOverlayLayer is required: PreviewCard hosts its panel through a native
Popup (NaviusAnchoredPopup) and pushes directly onto OverlayStack.GetFor(window).
Properties
Section titled “Properties”| Property | Type | Default | From | Description |
|---|---|---|---|---|
PreviewContent |
object? |
null |
NaviusPreviewCard |
Content of the preview panel. |
Side |
PlacementSide |
Bottom |
NaviusPreviewCard |
Which side of the trigger the panel is placed against. |
Align |
PlacementAlign |
Center |
NaviusPreviewCard |
Cross-axis alignment relative to the trigger. |
SideOffset |
double |
6 |
NaviusPreviewCard |
Gap, in DIPs, between the trigger and the panel along Side. |
AlignOffset |
double |
0 |
NaviusPreviewCard |
Offset, in DIPs, along the cross axis. |
OpenDelay |
int |
600 |
NaviusPreviewCard |
Hover-intent delay, in ms, before the card opens. |
CloseDelay |
int |
300 |
NaviusPreviewCard |
Grace delay, in ms, before the card closes after the pointer leaves or focus moves away. |
IsOpen |
bool |
false |
NaviusPreviewCard |
Open state. Two-way bindable by default. |
Content |
object |
- |
ContentControl |
The trigger. |
There is no Modal property at all (not even a dead always-false one): the web contract hardcodes
Modal to false for this family and nothing in the WPF port reads a PreviewCard-specific value.
Keyboard interactions
Section titled “Keyboard interactions”| Key | Behavior |
|---|---|
| Focus (Tab into the trigger) | Opens immediately (GotKeyboardFocus), with no OpenDelay. |
| Blur (Tab out of the trigger) | Starts the close-delay timer (LostKeyboardFocus). |
Escape |
Closes immediately via the shared OverlayStack Escape routing (CloseOnEscape is set true when the session opens); there is no dedicated key handler in this family, unlike Tooltip. |
Pointer enter on the trigger starts the open-delay timer (or opens immediately if already open); pointer leave on the trigger or the popup content starts the close-delay timer; pointer enter on the popup content cancels a pending close, letting the pointer travel from trigger to card without flicker. These are pointer, not keyboard, interactions, but share the same timer state machine.
UIA mechanism
Section titled “UIA mechanism”NaviusPreviewCard does not override OnCreateAutomationPeer and applies no AutomationProperties
to its popup content: the web contract itself has no role or Title/Description parts for this
family, and focus never moves into the card (MoveFocusInside is effectively false, matched by
TrapFocus = false/RestoreFocus = false when the session is pushed), so the trigger keeps focus
throughout the entire hover interaction. The unit suite (PreviewCardTests.cs) exercises the
hover-intent timers, the shared open/close state machine between the trigger and the popup
content, and the non-modal, non-restoring session options.
Web deltas
Section titled “Web deltas”- Trigger and Positioner collapse onto the root control, the same pattern as Popover; there is no
separate
NaviusPreviewCardBackdrop(the web contract itself notes it is “rarely used since preview cards are non-modal”). Modalis dropped entirely rather than kept as a dead always-falseproperty, sinceOverlayOptions.Modalalready defaults tofalseand nothing reads a PreviewCard-specific flag.- The trigger and the popup content share one hover-intent state machine (a single
DispatcherTimerpair) on the control instance, mirroring the web’s pointer-enter/leave callbacks wired on both the Trigger and the Popup so the “stay open while hovering the card itself” behavior carries over. - The trigger is rendered as a focusable
Bordertemplate part rather than a trueHyperlink/Button-style element; it still supports Tab stops andGotKeyboardFocus/LostKeyboardFocus. - No arrow glyph in the default template, the same
NaviusAnchoredPopuplimitation as Popover/Tooltip. - No cancelable dismiss callbacks are exposed as public events.
- Known residual (M6 audit):
GotKeyboardFocusstops the pending open timer and opens immediately, but does not stop a pending close timer. If focus arrives while aCloseDelayclose is already pending (e.g. the pointer just left the trigger), the card can open and then still be closed by the still-running close timer. Low severity, not covered by any current test.
Captures
Section titled “Captures”The PreviewCard Gallery page rendered at the pinned commit, in each theme.


