Pricing

SearchPopup handbook

v1.0.0 · @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

A composable search panel with a built-in SearchInput and optional data-driven results. Supports ungrouped items, group headings, and explicit complex content. Its runtime uses @snowui-design-system/components; search algorithms, recent visits, popularity, and application routing rules remain outside the component.

When to use it

Use it for a standard search input and results layout. SearchBox is an opening control; SearchPopup is the panel and is static by default. Set backdrop for the shared modal overlay. Without an overlay, an anchored trigger uses the inherited Popover template or inline mode.

  • items creates text or link results with optional group; showGroupTitles controls group headings.

  • children replaces all built-in results. Use Text as="group-title" for explicit headings and MenuItem as="item" for items.

  • With search={false}, supply an explicit SearchInput as="content". Configure that input directly; it does not consume parts.

Quick start

<script lang="ts">    import { SearchPopup } from '@snowui-design-system/components';</script><SearchPopup items={[{ value: 'button', label: 'Button', href: '/components/button', group: 'Recommended components' }]} />

API

Keyword Type Default Description
backdrop BackdropVariant | false false false keeps static or anchored mode; opaque, blur, and transparent enable the shared Dialog modal overlay.
closeOnOutside boolean true In modal mode, whether clicking the overlay closes the panel; independent of overlay appearance.
value string | number '' Search input value; supports bind:value. The consumer owns filtering.
search boolean true Whether to create the default SearchInput; turn it off when supplying an explicit input.
title string — Optional panel title above the results. Explicit content owns it in children mode.
showGroupTitles boolean true Whether to show group headings for items; does not reorder them.
items SearchPopupItem[] [] value, label, and href are required; group and disabled are optional. Items follow input order; consecutive items with the same group show one heading.
children Snippet — Replaces all default results and headings; items, title, and showGroupTitles are no longer read.
parts ComponentPartsOf<{ SearchInput: typeof SearchInput; MenuItem: typeof MenuItem; Text: typeof Text }> — Configures the generated input, results, and headings. Their data owns value, children, identity, and disabled.

Compatible Props inherit from Popover. Defaults are size=md and closeOn=manual; the standard static search panel has a nominal width of 480px. For an explicit floating panel, set template/id or as="popover", and choose closeOn as needed. Outer class and style pass through to the real Popover host. Modal mode reuses Dialog instead of introducing another modal, positioning, scrolling, or motion system. class/style and parts still apply to the inner search panel; the modal shell uses the panel’s default width.

Usage boundaries and details

Default built-in mode creates SearchInput, Text, and MenuItem. parts does not rewrite explicit children. parts.SearchInput can configure the input’s placeholder, ARIA attributes, and autofocus. Built-in labels follow SearchInput’s locale defaults; SearchPopup adds no fixed application copy. Default results use native links and must supply href. For commands or other non-navigation results, explicitly compose a keyboard-accessible Button in children.

Follow Figma SearchPopup vertical spacing: the default md panel has 16px top and bottom padding; the search area has 4px above and 16px below; the results begin 12px after the input divider. Results form one column. Heading-to-item and item-to-item spacing is gap-1 (4px). Later group headings add gap-2 (8px) above, for 12px total with row spacing. The first heading adds no extra margin; without a heading the first item also begins 12px below the divider. Headings have 0 vertical and 8px horizontal padding; items have 8px vertical padding. Public role group-title accepts multiple items through Text or native data-as; it controls heading color and spacing, not application content. as="item" preserves MenuItem semantics and does not create a Listbox selection owner.

Headings and groups may be omitted. Explicit complex content can combine Avatar, Icon, and MenuItem. With backdrop, the internal Dialog manages the shared overlay, enter/exit motion and reversal, reduced motion, focus containment and restoration, and background scroll lock. closeOnEscape controls Escape; closeOnOutside controls overlay clicks. Use bind:open for visibility. Template/id mode uses data-dialog-target, data-dialog-close, or showDialog/hideDialog; as="popover" uses Dialog’s inline trigger in this mode. Do not wrap another Dialog around it, which would create two overlays. In modal mode, the inner Popover does not close itself; closeOn/closeOnSelect apply only without a backdrop. Default link results close Dialog; explicit results may use data-dialog-close. Static-panel SSR does not access browser globals. Motion and reduced-motion behavior inherit from Popover. Without positioning mode, no new positioning listener is installed.

SearchPopup style overrides

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.

This component source does not directly consume a registered component-specific override. Style composed children through public parts or an explicit child; do not guess variable names.

Design guide · Tokens · Composition boundaries

SearchPopup types and states

Required Props: no named required Props.

Two-way binding: bind:open, bind:value.

Inherited declaration: Omit<ComponentProps<typeof Popover>, "children" | "title" | "value" | "parts">. Consult the base component’s public documentation for inherited capabilities; fields excluded by Omit cannot be used as if inherited unchanged.

Shared Frame API · Back to API

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.

BackdropVariant

Source: components/src/lib/backdrop.ts

export type BackdropVariant = "opaque" | "blur" | "transparent";

SearchPopupItem

Source: components/src/blocks/SearchPopup.svelte

export type SearchPopupItem = { value: string; label: string; href: string; group?: string; disabled?: boolean };

ComponentPartsOf

Source: components/src/logic/component-parts.svelte.ts

export type ComponentPartsOf<    T extends Record<string, Component<any>>,> = {    [K in keyof T]?: ConfigurableComponentPartProps<T[K]>;};

ConfigurableComponentPartProps

Source: components/src/logic/component-parts.svelte.ts

export type ConfigurableComponentPartProps<C extends Component<any>> = Partial<    Omit<ComponentProps<C>, ComponentPartControlledKey>>;

ComponentPartControlledKey

Source: components/src/logic/component-parts.svelte.ts

export type ComponentPartControlledKey =    | "children"    | "as"    | "value"    | "defaultValue"    | "open"    | "selected"    | "checked"    | "disabled"    | "readonly"    | "id"    | `on${string}`    | `aria-${string}`;