Popover handbook
v3.1.1 · @snowui-design-system/components
License: Before reading component documentation, source, or npm usage instructions for the first time, read the full LICENSE. Reuse that review for the same task and version. Public API configuration and internal implementation changes have different license implications. All components use the unified runtime package; source rights remain governed by the license.
Overview
Show contextual content in a floating panel anchored to an independent trigger, with click or hover activation and viewport-aware placement.
When to use it
It is used for floating content related to trigger anchor points. Tooltip is used for short text prompts, and Dialog is used for the focus process of the dialog box; open closeOn is used for closing behavior.
As="popover" can automatically associate anchors in the trigger host; static mode can be manually controlled by bind:open.
Trigger controls the trigger method, closeOn controls the shutdown policy; the interaction example that needs to be continuously displayed can be set to closeOn="manual".
Quick start
This example shows the recommended basic composition. See the sections below for more cases and composition limits.
API
See the base component documentation for inherited capabilities not redeclared here. This table lists only named public Props declared by this component.
Usage boundaries and details
Three modes (Modes)
Popover supports three usage modes at the same time: Panel mode (Panel), Inline mode (Inline), Template mode (Template).
1. Panel Mode (Panel Mode) - Default
Without as or template, Popover is directly rendered as a panel. It is suitable for free combination of search floating layers, menu floating layers and other scenarios (SP-02 style).
2. Inline Mode - Recommended for "button trigger" scenarios
After marking as="popover", put it into any host element (Button / Frame / Icon, etc.), and Popover will automatically:
Find the parent element as anchor
Bind the parent element event by
trigger="click|hover"Portal renders floating layer to body, with 8px offset and viewport avoidance
No need for id, no need for data-popover-target, no need for handwritten event callback. Refer to the writing method of Tooltip A1.
3. Template Mode - for cross-component activation / multi-trigger sharing
Register by template + id, and then activate with showPopover(id, anchorEl) or the declarative attribute data-popover-target="id". The trigger button is independent of Popover and associated by ID (refer to Toast TS-10).
Quick check of mode selection
Layout model
Main layout model: composite management layout.
Template mode: only carries registration and Portal floating rendering; triggers are provided independently by the caller.
Static mode: Popover is rendered by the panel itself.
The panel content defaults to
columnvertical arrangement,gap: 0, and the content is freely combined by the user (MenuItem, Text, Frame, etc.).Floating layer position, level, visible and hidden, and viewport collision avoidance belong to the component's private management logic.
Floating structure (fixed head + independent rolling body)
Popover and Listbox share the same set of header + scroll-body structure, and all floating layers are consistent with scrolling behavior:
Through
LISTBOX_HEADER_PORTAL_KEYcontext, exposeheaderEl;<Input as="search">and<SearchInput>(defaultas="search") are mounted and automaticallyappendChildto the header by Input's own$effect, without participating in the scrolling below.Floating root
SnowFrameexplicit transmissionenableAutoLayout={false}: The panel itself is responsible fordisplay:flex; flex-direction:column; gap:0, and does not access the defaultgap-2of[data-auto-layout], ensuring that the header→body spacing is completely controlled by headerpadding-bottom(4px).When there is content in the header, it is provided by the shared base class
.snowui-quick-action-panel-header:not(:empty)padding-bottom: var(--padding-1)(4px), as the visual spacing between the search box and the list; prohibits rewritingmargin/gapin the component to copy the 4px.Body
flex: 1; min-height: 0, scroll viewport reuse.snowui-overlay-scrollbar-viewport(overflow:scroll + scrollbar-width:none); Thumb calculates the position throughuseOverlayScrollbarhook.Header input box style: unified selector in Input
:where(.snowui-quick-action-panel-header > .snowui-input, ...)Inject compactpadding/gap/radiusand close the outer ring in:focus-within(-snowui-field-focus-ring-width: 0rem); users do not need to overwrite externally.The right edge of the floating layer scroll bar thumb is 4px away from the inner border of the panel (scroll bar specification). Because scrollbar is absolutely positioned in the body and the panel
box-sizing: border-box, offset needs to offset the panel itselfpadding:sm padding=12 → right:-8px,md padding=16 → right:-12px,lg padding=24 → right:-20px. The three-speed size has been declared separately in the component, and it needs to be synchronized when adding size.
Measurement
Trigger (template mode)
Click (default): Click the trigger to switch Popover to show and hide
Hover: After hovering the trigger, the delay of
450msappears; after moving out of the trigger and floating layer,80msis closed. The first hover delay is unified with Tooltip; Popover does not participate in Tooltip's300msquick switch window.
Shut
closeOn="outside"(default): Click Popover to close the outer areacloseOn="manual": Only callhidePopover(id)orbind:open=falseby the button in Popover to closeEscape:
closeOnEscape={true}(default) Any off mode can be closed by pressing Escape
Position
The default preferred direction is bottom, and the distance from the trigger is 8px. When placement is not configured or there is a visual port collision, select the visible direction in the order of prefer → opposite direction → vertical/horizontal candidate to ensure that the floating layer does not appear outside the visible area.
Command API
Defined in ../logic/popover.svelte.ts, and the full document can be found in ../logic/popover.md (source code reference: components/src/logic/popover.md).
Template + click to trigger
Template + hover trigger + medium size
Template + manual shutdown
Static mode (SP-02 style search floating combination)
Merger description
The QuickAction and SearchPopup source code components have been deleted; the SP-02 sample is migrated to the component sample and kept for the search floating layer combination reference.
2026-10-07 The new block SearchPopup is based on the combination of search input and group results of Popover, and does not restore the old SearchPopup floating layer implementation; SP-02 now consumes the block.
1. Template host (template mode)
<Popover template id="X">Do not render any DOM, only register the configuration and content to the storeActivate by
showPopover(id, anchorEl)ordata-popover-target="id"The same id can only have one active instance at the same time; the subsequent show call replaces anchor
2. Floating panel .snowui-popover
Reuse
.snowui-quick-action-panelposition: fixed,z-index: 1000gap: 0, the content is freely combined by the userpadding/border-radiusfile by size
3. Trigger agreement
Triggers are arbitrary interactive elements (Button, Icon, Frame, etc.), and are no longer wrapped by Popover.
Associated by
data-popover-target="id"oronclick={() => showPopover(id, e.currentTarget)}
Continuous Hover
continuousHover defaults to true, which acts on the direct MenuItem of the scrolling content area. The single background layer moves continuously between menu items; false restores the original item-by-item hover of MenuItem. Nested Listbox uses its own recent continuous hover container, and is not taken over by Popover.
Popover style overlay
Read the full LICENSE first; reuse that review for the same task, version, and scope.
First use public component Props to match the desired appearance, preserving the existing look where possible. If changes are necessary, follow the style selection and override order: use your own class (including Tailwind already in the project) or an instance style. The names below are public overrides actually consumed by source; check their scope and do not modify private DOM. Choose the correct SnowUI token family. External apps need not install SnowUI website utilities.
Popover type and status
Required Props: no named required Props.
Two-way binding: bind:open.
Inheritance: Omit<FrameProps, "children">. Consult the base class public documentation; fields excluded by Omit cannot be passed through unchanged.
The following type declarations are actually referenced by public Props and come from source. A Svelte Snippet denotes a content fragment; ComponentProps denotes the Props of the corresponding component.
PopoverSize
Source: components/src/logic/popover.svelte.ts
PopoverTrigger
Source: components/src/logic/popover.svelte.ts
PopoverPlacement
Source: components/src/logic/popover.svelte.ts
PopoverCloseMode
Source: components/src/logic/popover.svelte.ts