# Search results

What global search returns when the question is a client, an invoice number or a note: a search well, a live count, kind tabs, filters and rows that open.

Block · With a Pass · https://tactileui.dev/blocks/search-results

> The code and styling for this block come with the Pass. Sign in if you have one. Sign in: https://tactileui.dev/auth/sign-in The price: https://tactileui.dev/pricing

## Use it

With a Pass, install it with npx shadcn add @tactile/search-results (https://tactileui.dev/docs/registry-and-mcp). It lands in tactile/search-results/.

Load the stylesheet as well as the module, or it renders unstyled: tactile/search-results/search-results.css. In a bundler such as Vite, import each CSS file next to the module import; in plain HTML, link it.

Then mount(element, options) from tactile/search-results/search-results.mjs. Every option has a default; tactile/search-results-example.html shows it running. The sample copy (headings, labels, figures) is placeholder: replace it with the page's own.

## Anatomy

Global search results, Live count and tab counts, Kind tabs, Filter chip group, Result order segmented, Result rows as links, Two line snippet, Snippet marker draw, Result fade, Paginated results, Compact phone pager, Empty state with clear filters, Loading skeleton rows, Error banner over last results, Keyboard field to results, Command k focus, Phone scrolling rows, Finish following, Quiet volume

## Usage notes

The results screen of an app's global search: one field asks the question, the count and the kind tabs say what came back, the filters narrow it and every row is a link with enough of the record to recognise it. The field stays put while the count, the tabs and the list update as you type. The sample page carries four results of the account's eighteen, because a block is a page, not a database.

## Options

| Option | Type | Description |
| - | - | - |
| title | text | Page title |
| lead | text | Lead |
| query | text | Search query |
| state | enum | Normal, the skeleton while the search runs, the empty result, the moment search fails over the last results, or the success state after a typed question. |
| finish | enum | Auto takes the page’s own finish tokens if it has them, then its data-finish, then the visitor’s system. |

## Methods

- results
- update
- destroy

## States

1. **At rest**: The breadcrumb Ledgerly, Search, Results; the label Ledgerly Four result rows, each a link with a marker, the title, the meta line, a two-line snippet and its kind on a Tag. The pager shows one page.
2. **Typing**: The count line, the four tab counts and the rows update as you type, and none of them moves the field. A typed question searches the four sample rows by every word in it; clearing the field brings all four back. The count and the tabs fall back to the account's totals only with the sample question in the field and no filters down.
3. **Tabs**: All keeps every result; Invoices, Clients and Notes keep one kind each, and the rows and the count follow. The tablist is one tab stop: Left and Right move and select, Home and End go to the ends.
4. **Filters**: This year, Overdue only and Has PDF press down in the kit's Chip group and narrow the rows; the count and the tabs recount. The group's own polite line says how many are chosen.
5. **Order**: The Segmented control switches the rows between the recipe's order as Best match and newest first under Newest; the marker and the row fade run again as the rows arrive.
6. **Loading**: Four Skeleton rows stand under the live count, and the panel status says Searching with a blinking amber lamp. The field, the count and the tabs stay exactly where they are.
7. **Empty**: The count reads No results for ostrander overdue, the tabs read zero, and the Empty state shows the same line over Check the spelling or search just the client name. The words search just the client name are a Link that puts ostrander in the field; Clear the filters is the one contrast key and returns the sample.
8. **Error**: The last results stay under a Banner that reads Search is unavailable for a moment. These are the last results. with an amber lamp and a Try again key; the panel status says Could not search with a red lamp. Try again puts the results back at once.
9. **Success**: The field has not moved.
10. **Phone**: 
11. **Keyboard**: Type in the field. Down moves into the first result, Up and Down move between results, Up from the first returns to the field, and Enter opens the focused row. Cmd/Ctrl K focuses the field from anywhere on the page. Escape in the field clears it through the Search field's own key.
12. **Reduced motion**: A result appears with no fade and the snippet marker is printed whole; nothing else moves.
13. **Finishes and volume**: Every surface and lamp reads the kit's tokens, so all fourteen finishes follow. The screen is set in the Quiet volume; its parts keep their sizes and draw hairlines and a whisper of depth.

## How it works

Original composition. Ledgerly, its clients, invoice numbers, amounts and notes are sample copy for an invented invoicing app, and the preview says so. The screen is made only of the Tactile UI Kit's parts, with the kit's tokens for every surface and lamp; the block writes no colour and restyles no part. It needs the kit's kit.css and kit.mjs beside it. The four rows are the sample page of the account's eighteen results: the count and the four tabs carry the whole set at rest, and any typed question or filter recounts the four sample rows. The search field is the kit's own, so Escape clears it and its clear key is the Tooltip's trigger.
