Search Field

A search input with a magnifier and a clear button. Use it to filter a page list, a picker, or a catalog.

States

Placeholder falls back to the label. The clear button appears once there is text. Long text stays on one line.

No placeholder · no limit

Custom placeholder · 120 characters

Filled · 500 characters

Long text · 640 characters

Long placeholder · 254 characters

Apps

Inside a disabled fieldset

Filter a page list

Agents, skills, tasks, tables, members, and models search their list like this. No match shows an empty state with a way back.

Agents

Private instructions you can share with people and teams.

  • Invoice follow-upChases unpaid invoices every Monday
  • People Ops helperAnswers leave and benefits questions
  • Renewal deskDrafts renewal quotes from the CRM
  • Support triageLabels and routes new tickets

Search with a shelf filter

Projects and skills put Active and Archived next to the search. The placeholder names the shelf. Workflows hide the search when a shelf is empty.

  • Q4 launch plan
  • Customer onboarding
  • Security review 2026
  • Weekly pipeline digest
  • New lead routing
  • Invoice reminders

Search with an action

The skill picker keeps an import button beside the search. The MCP catalog searches on submit. GitHub filters repositories by owner too.

  • Linearhttps://mcp.linear.app/sse
  • Notionhttps://mcp.notion.com/mcp
  • Sentryhttps://mcp.sentry.dev/mcp
  • tulipfarm/handbook
  • tulipfarm/runbooks
  • northwind/pricing-api

Beside breadcrumbs

Files and Google Drive put the search at the end of the folder path. It wraps under the path on narrow screens.

  • Board deck Q3.pdf
  • Pricing 2026.xlsx
  • Hiring plan.docx
  • Launch brief.md

Search results from all sources

In a popover and a query bar

Table filters search linked rows inside a picker popover. The first Escape clears the text; the next closes the popover.

Finds rows whose text fields contain these words. Filters still apply.

Pickers in forms

File and member pickers search inline. Results load below with a status, an error with retry, or a no-match message.

Searching files…

0 readers selected, plus you.

Usage

Search Field usageTSX
import { SearchField } from "@tulipfarm/sprout/search-field";

const [search, setSearch] = useState("");

<SearchField
  id="agent-search"
  label="Find agents"
  placeholder="Search agents"
  maxLength={120}
  value={search}
  onChange={setSearch}
/>

// Placeholder falls back to the label.
<SearchField label="Search models" value={query} onChange={setQuery} />

Props

label names the input for screen readers. It is also the placeholder when you leave out placeholder.value and onChange are required;onChange gets the new string, not an event. Reset paging or cursors in it when the search changes.

maxLength and id pass to the input. Cloud uses 120 for agents, skills, tasks, and actions; 254 for invitations; 255 for tables, projects, files, and rows; 500 for Google Drive; and 640 for chats. className goes on the wrapper, which is full width up to 24rem. Put it in a flex child to size it in a toolbar.

There is one size, 32px tall, and no variants. To disable it, wrap it in a disabled fieldset; the input and clear button both turn off.

Behavior

The clear button shows once there is text. It empties the value and puts focus back in the input. Escape does the same while there is text, and stops there, so a popover or dialog stays open. With no text, Escape passes through and closes them. Clicking the magnifier or padding focuses the input. Inside a form, Enter submits.

The input is a native type="search". The browser's own cancel button is hidden, so there is one clear button in every browser. Autocomplete and spell check are off.

Accessibility

The input is named by label, and the clear button is named "Clear search". The group shows a 2px focus ring when the input has keyboard focus; the clear button has its own ring. Show loading, error, and result counts in a status or alert region next to the field.

The clear button fades in over 120ms. Motion and color transitions stop when reduced motion is requested. In forced colors mode the group keeps a system border and a highlight focus ring.

Theme tokens

The border uses --sprout-input, the fill--sprout-surface, text --sprout-text, and the icon and placeholder --sprout-muted. Focus uses--sprout-focus and disabled --sprout-hover. Radius follows --sprout-radius-control. The opt-in TulipFarm theme tints the focus ring through these tokens.