Skip to content

Command palette

Preview Available in release assets

Provide a native-dialog shortcut to server search while retaining an ordinary search destination and server-owned result actions.

Server contract

GET /search?q=<query> renders the durable complete page. Enhanced GET /api/command-search reads signal q and emits one datastar-patch-elements event replacing #command-results. Empty queries and errors return recoverable server markup.

Without Datastar or dialog command support, the visible /search destination and native GET submission provide the complete search workflow.

Command palette primary example

Show code
<section class="thin-command-palette">
  <p>
    <a href="/search">Search everything</a> or <button class="thin-button" commandfor="command-palette" command="show-modal">Open command palette</button>.</p>
    <dialog id="command-palette" aria-labelledby="command-title">
      <header>
        <h2 id="command-title">Search commands and destinations</h2>
        <form method="dialog">
          <button class="thin-button" data-variant="quiet" aria-label="Close command palette">Close</button>
        </form>
      </header>
      <search aria-label="Command search">
        <form id="command-search-form" action="/search" method="get" data-signals="{q: ''}" data-on:input__debounce.200ms="@get('/api/command-search')" data-indicator:searching>
          <label class="thin-field" for="command-query">Search</label>
          <input class="thin-input" id="command-query" type="search" name="q" data-bind="q" autocomplete="off" aria-controls="command-results" />
          <button class="thin-button" type="submit">View all search results</button>
          <p role="status" data-show="$searching" style="display:none">Searching…</p>
        </form>
      </search>
      <section class="thin-search-result-list" id="command-results" aria-labelledby="command-results-title" aria-live="polite" aria-atomic="true">
        <header>
          <h2 id="command-results-title">3 results for “deploy”</h2>
          <p>Server results. Use Tab to reach actions or submit the search for a full results page.</p>
        </header>
        <ul>
          <li>
            <article>
              <h3><a href="/projects/gateway/deploy">Deploy Gateway</a></h3>
              <p>Project action · Platform</p>
            </article>
          </li>
          <li>
            <article>
              <h3><a href="/docs/deployments">Deployment guide with a deliberately long localized title</a></h3>
              <p>Documentation</p>
            </article>
          </li>
        </ul>
      </section>
      <p><a href="/search">Open the full search page</a></p>
    </dialog>
  </section>

Anatomy

  • Durable search link
  • Explicit dialog trigger
  • Native dialog
  • Named native search landmark
  • GET search form
  • Pending status
  • Server result region
  • Close control

Variants and sizes

  • Global search
  • Scoped project search
  • Commands and destinations

Gallery coverage: No structured variant fixtures are published yet; the primary example above is the only verified production markup.

Rendered fixtures exercise authored content and constrained layouts with the same production assets.

  • Closed
  • Open
  • Keyboard
  • Focus restoration
  • Pending
  • Results
  • Empty
  • Server error
  • Disconnected
  • Reconnected
  • Long localized content

Structured state fixtures are not published for this item yet.

Interaction and keyboard behavior

The native dialog handles modality, Escape, and focus restoration. The named native search landmark contains only the command search controls; the GET form and /search link are canonical. Datastar sends the query to the server and replaces #command-results; results and actions remain server-authored links/forms. Do not add a client command registry or SPA command bus.

Accessibility

Name the native search landmark and search field, expose one concise atomic results announcement outside the landmark, keep Tab navigation native, do not steal focus on result patches, and preserve visible pending/error/reconnect text. Keyboard shortcuts are optional and must not conflict with text entry or replace the visible trigger.

Contract
DIALOG
Basis
Native <dialog> with a search form and ordinary result links; no menu/listbox claim
Evidence
  • tests/unit/library/command-search.test.ts

API

GET /search?q=<query> renders the durable complete page. Enhanced GET /api/command-search reads signal q and emits one datastar-patch-elements event replacing #command-results. Empty queries and errors return recoverable server markup.

Behavior tier: datastar-required

Structured host, property, and example tables are not authored for this item yet. Use the summary above and the primary example.

Fallback

Without Datastar or dialog command support, the visible /search destination and native GET submission provide the complete search workflow.

Assets and dependencies

  • /foundation.css
  • /components.css

Dependencies: datastar@1.0.2, dialog, field, status

Source: packages/ui/src/items/command-search/style.ts

Composition

Derived from the examples and style specs, not authored.

Composes