Components
Search
Search
Global search lives in the top nav. The trigger is a default-sized outlined button that opens a modal. Results stream in via Alpine-AJAX. Same shape on every viewport — full-screen on mobile, centred card on sm+.
This page documents the search UX pattern. Live rendering depends on the layout's search partial.
Canonical
Trigger button in the navbar opens a modal. Results stream via Alpine-AJAX into #search-results-modal.
Variants
4 variantsDesktop trigger
Outlined button, icon + label + kbd hint.
Mobile trigger
Icon only, fits in the navbar.
Quotes
12 Elm Avenue
Sale · Q-1042
Transactions
88 Greenway Lane
Purchase · T-2207
Open with results
Grouped by type, first row keyboard-highlighted.
No results for “fluffy”.
No matches
Empty body, single line of italic copy.
States
3 statesClick
Trigger button
Desktop trigger or mobile icon button.
/
Slash anywhere
Skipped when typing in an input.
⌘ K
Cmd/Ctrl+K
Works even when an input is focused.
Props
6 parts| Property / method | Purpose |
|---|---|
| searchOpen | Whether the modal is visible. |
| query | Two-way bound to the modal input. |
| activeIndex | Index of the keyboard-highlighted result row. |
| openSearch() | Sets searchOpen = true and focuses the input. |
| doSearch() | Debounced AJAX request that streams results into #search-results-modal. |
| _SearchResults.cshtml | Server-rendered grouped results partial. |
Do & don't
Quotes
12 Elm Avenue
Transactions
88 Greenway Lane
Do
Group results by type. Use the same labels as the area switcher (Quotes, Transactions, Partners).
12 Elm Avenue
88 Greenway Lane
Acme Estates
Don't
Don't dump every result into a single flat list. The user can't tell what they're looking at.