StartFoundationsComponentsContent

Search field

A search field takes a search query. It has a search icon, a clear button, and a loading state. It doesn't search; you run the query and show the results.

Stable Figma
OverviewUsageAPIAccessibility
<form action="/search">
  <tk-search-field name="q" label="Search invoices" placeholder="Invoice number or customer"></tk-search-field>
</form>

Anatomy

Part What it is
tk-search-field the element; submits one value under name
field part the bordered box
search icon decorative; a spinner replaces it while loading
input part the native <input type="search">
clear part the clear button; shows once there is text, and takes focus

Label

<tk-search-field label="Search orders"></tk-search-field>
<tk-field label="Find a customer" helper="Name, email, or account ID">
  <tk-search-field name="customer"></tk-search-field>
</tk-field>
  • A search field has no visible label. It names itself from label, "Search" by default. Change it to say what is searched: label="Search orders".
  • For a visible label, help text, or an error, wrap it in a Field. The Field's label then names it; don't also set label.

Sizes

<tk-search-field label="Search files"></tk-search-field>
<tk-search-field label="Search files" size="large"></tk-search-field>
size Height Padding-inline Value text
medium (default) 32px space-8 start, space-4 end Body Small (14/20)
large 36px space-10 start, space-4 end Body Medium (16/24)

The heights match medium and large buttons. There is no small; size="small" renders as medium and logs a console warning.

States

<tk-search-field label="Search invoices" value="March" loading></tk-search-field>
<tk-search-field label="Search invoices" disabled></tk-search-field>

The box doesn't change on hover. On focus in the text, its border takes the focus color and grows thicker inward; the clear button has its own focus ring.

  • loading: a spinner replaces the search icon, and the field tells screen readers it's busy. The clear button stays, so people can still cancel by clearing.
  • disabled: the field can't be focused or edited, the clear button is hidden, and it's left out of the form.
  • Error and required: set error and required on a Field.

Clearing

  • The clear button and Escape both empty the field. Focus moves to the text, so it's never lost.
  • Escape only acts when there is text. In a Dialog or Popover, the first Escape clears the field and the next one closes the overlay.
  • A clear fires input, change, and tk-clear. tk-clear says how: detail.reason is button or escape. You can't cancel it.

The field holds the query. You decide when to search, how long to wait, and how to tell people what you found:

<tk-search-field id="filter" label="Filter sections"></tk-search-field>
<p id="count" role="status"></p>
<script>
  const field = document.getElementById('filter');
  field.addEventListener('input', debounce(() => render(field.value), 200));
  field.addEventListener('tk-clear', () => render(''));
</script>
  • Listen for input while people type, change when they commit, or the form's submit on Enter.
  • There is no built-in delay; wait as long as your search needs.
  • Announce the result count in your own role="status" region, such as "12 results".