SearchDialog

The search modal component for performing full-text search across documentation pages.

The SearchDialog provides an accessible, fully customizable overlayable command panel that lets users instantly search routes, headings, and descriptions.

Composable Search Dialog ExampleLink

Using the SearchDialog primitive subcomponents, you can compose a custom search window overlay. The following example shows how to wire the overlay to the search state hook and build a clean modal dialog with list results and custom icons:

tsx
// docs/components/CustomSearchDialog.tsx
import React from 'react'
import { SearchDialog } from 'boltdocs/primitives'
import { useSearch } from 'boltdocs/client'

export default function CustomSearchDialog() {
  const { isOpen, close, query, setQuery, results } = useSearch()

  return (
    <SearchDialog
      isOpen={isOpen}
      onOpenChange={(open) => !open && close()}
      className="bg-black/40 backdrop-blur-xs flex items-center justify-center p-4 transition-all"
    >
      <SearchDialog.Content className="w-full max-w-xl bg-white dark:bg-zinc-900 border border-subtle rounded-xl shadow-2xl overflow-hidden">
        <SearchDialog.Dialog>
          
          {/* 1. Styled Search Input in the Header */}
          <SearchDialog.Input className="flex items-center border-b border-subtle px-4 py-3">
            <SearchDialog.Input.SearchInput
              value={query}
              onChange={(e) => setQuery((e.target as HTMLInputElement).value)}
              placeholder="Search documentation..."
              className="text-sm placeholder-zinc-400 outline-none"
            />
            {query && (
              <SearchDialog.Input.Button className="text-xs text-muted hover:text-body">
                Clear
              </SearchDialog.Input.Button>
            )}
          </SearchDialog.Input>

          {/* 2. Scrollable Results List Box */}
          {results.length > 0 && (
            <SearchDialog.Autocomplete>
              <SearchDialog.List className="p-2 max-h-96 overflow-y-auto space-y-1">
                {results.map((item) => (
                  <SearchDialog.Item
                    key={item.path}
                    id={item.path}
                    className="p-2.5 rounded-lg transition-colors hover:bg-zinc-100 dark:hover:bg-zinc-800"
                  >
                    {/* Visual indicators for regular pages vs. deep headings */}
                    <SearchDialog.Item.Icon
                      isHeading={item.path.includes('#')}
                      className="text-muted mr-3"
                    />
                    
                    <SearchDialog.Item.Title className="text-sm font-medium text-body">
                      {item.title}
                    </SearchDialog.Item.Title>
                    
                    {item.description && (
                      <SearchDialog.Item.Bio className="text-xs text-muted">
                        {item.description}
                      </SearchDialog.Item.Bio>
                    )}
                  </SearchDialog.Item>
                ))}
              </SearchDialog.List>
            </SearchDialog.Autocomplete>
          )}

          {/* Empty fallback message */}
          {query && results.length === 0 && (
            <div className="p-8 text-center text-sm text-muted">
              No results found for "{query}"
            </div>
          )}

        </SearchDialog.Dialog>
      </SearchDialog.Content>
    </SearchDialog>
  )
}

Composable SubcomponentsLink

The SearchDialog primitive provides the following subcomponents for structure customization:

ComponentHTML TagDescriptionProps
SearchDialog / SearchDialog.Overlay<div> (Backdrop)The background overlay element dimming the page backdrop.ModalOverlayProps
SearchDialog.Content<div> (Modal)The floating dialog layout wrapper containing the dialog shell.ModalProps
SearchDialog.Dialog<dialog>The interactive dialog container mapping focus and keyboard controls.DialogProps
SearchDialog.Input<div>Wraps the search input form layout.SearchFieldProps
SearchDialog.Input.SearchInput<input>The inner text input control itself.InputProps
SearchDialog.Input.Button<button>A button to clear the active input query text.ButtonProps with slot="clear"
SearchDialog.Autocomplete<div>A wrapper aligning query and autocomplete list highlights.AutocompleteProps
SearchDialog.List<ul>The scrollable vertical list viewport of results.ListBoxProps
SearchDialog.Item<li>The individual result cell item.SearchDialogItemProps
SearchDialog.Item.Icon<span>Renders standard result indicators (hash # for headings, sheet for pages).Icon Props
SearchDialog.Item.Title<div>The main matching result text label.ComponentBaseProps
SearchDialog.Item.Bio<div>Supporting description context or section excerpt label.ComponentBaseProps

Component PropsLink

ComponentBaseProps (Common)Link

PropertyTypeDefaultDescription
childrenReactNodeundefinedChild content elements.
classNamestringundefinedCustom utility CSS classes.
styleCSSPropertiesundefinedInline style settings.

ModalOverlayProps and ModalPropsLink

Inherits the standard React-Aria ModalOverlayProps and ModalProps settings (e.g., isOpen, onOpenChange, isDismissable).

DialogPropsLink

Inherits the standard React-Aria DialogProps settings.

SearchFieldPropsLink

Inherits the standard React-Aria SearchFieldProps settings (e.g., value, onChange).

InputPropsLink

Inherits the standard HTML input element properties.

AutocompletePropsLink

Custom wrapper settings handling search query term highlighting.

ListBoxPropsLink

Inherits standard React-Aria ListBoxProps (e.g., items, selectionMode).

SearchDialogItemPropsLink

PropertyTypeDefaultDescription
idKeyRequiredUnique index key of the item.
textValuestringRequiredRaw text content for keyboard search.
renderHint(state: { isSelected?: boolean; isFocused?: boolean }) => ReactNode(default hint)Custom function that replaces the default "Select" + shortcut-key hint.

Icon PropsLink

PropertyTypeDefaultDescription
isHeadingbooleanfalseWhen true, renders a heading section icon. Otherwise renders a document page icon.
iconReactNode(hash or file icon)Custom leading icon that replaces the default hash/file icon.

Customization & statesLink

The SearchDialog primitive is style-neutral: it ships the overlay, dialog, list, and item behavior from React Aria, and every visual decision belongs to the theme through its className slots. Item state is exposed as data-* attributes on SearchDialog.Item, present only when true.

State / SlotMechanism
SearchDialog (root)<div> backdrop overlay; mounted only while open
SearchDialog.Content / DialogModal surface and <dialog>; size and colors via className
SearchDialog.Input.SearchInputBare <input>; focus and placeholder styles via className
SearchDialog.List<ul> results viewport; scroll-area styling via className
SearchDialog.ItemRAC ListBoxItem; emits data-selected when the result is selected
Keyboard highlightThe focused item exposes data-focused (and data-focus-visible)
tsx
<SearchDialog.List className="max-h-96 overflow-y-auto p-2">
  {results.map((item) => (
    <SearchDialog.Item
      key={item.path}
      id={item.path}
      className="rounded-lg p-2.5 text-body transition-colors data-focused:bg-surface data-focused:outline-none data-selected:bg-primary-500/10"
    >
      <SearchDialog.Item.Title>{item.title}</SearchDialog.Item.Title>
    </SearchDialog.Item>
  ))}
</SearchDialog.List>
Last updated on October 18, 2026

Was this page helpful?