Skip to contentAsheeUIAsheeUI

SearchInput

A text field that searches, with a named search region, a clear control and a submit path.

A search field is a text field whose value drives a result list, so it needs three things an input has no opinion about: a region announced as the page's search, a control that empties the field without making the reader select the text and delete it, and a path that reports the query when it is submitted.

It composes the framework's Input, Button and Spinner rather than rebuilding a control, so density, accent, label, description and message are the field family's rather than a second copy.

Usage

import { SearchInput } from "@asheeui/web";

<SearchInput
  placeholder="Search invoices"
  value={query}
  onValueChange={setQuery}
  onSearch={runSearch}
/>

The field is controlled when value is given and owns the query otherwise, starting from defaultValue. onValueChange fires on every change, including the one the clear control makes; onSearch fires when the reader submits, which is the moment a list is usually refreshed rather than the moment each character is typed.

Submitting and clearing

Supplying onSearch renders the region as a <form>, so Enter submits the query and the reader never has to aim at a button. Without it the region is still a named search landmark, but there is nothing to submit to.

clearable (default true) offers the control at the end of the field, and it appears only when there is a query to clear. Pressing it empties the element, returns the caret to it and reports "" through onValueChange; in a controlled field the owner mirrors that in its own state. isLoading reports a search in progress through aria-busy and a spinner, and the query stays readable while it runs.

Name and visibility

Every search field has a name. label defaults to Search, and hideLabel defaults to true, which keeps the name for assistive technology and hides it from view, a search field in a toolbar is named without being captioned.

Set hideLabel={false} when the field deserves a caption, as on a page where it is the point rather than an accessory. The name is part of the component's configuration, so an application that calls it "Find" renames every search field once, under components.searchinput.

shortcut shows the key combination a page has bound, it is a hint, not a handler. Binding a global shortcut is an application concern, because the field cannot know what else the shortcut should do.

Props

size and color are registered on the component as md and primary, and they do not follow the application's defaultColor: a search field leads with the primary accent unless it is told otherwise. clearable, label and hideLabel are registered too, because they are decisions about the product's search, not about one instance.

The rest of the field's treatment belongs to the Input it composes: it is bordered, and its radius resolves from the application's defaultRadius, so a search field and the fields beside it share one corner.

Accessibility

  • The region carries role="search" and is named by aria-label, and it is a real <form> when onSearch is supplied. The field inside is type="search" and announces as a searchbox, so the landmark and the control are both named.
  • The default label is rendered and visually hidden rather than omitted. The field keeps a name that no one sees, which is what lets a toolbar search still be announced as search.
  • The clear control is a real button named Clear search, and it moves focus back into the field after emptying it, so the reader is not dropped at the top of the page.
  • isLoading sets aria-busy and adds a spinner at the end of the field. The kbd hint is text rather than a control, so it is never reached by the keyboard or the pointer.

The label, description and message behave as the field anatomy describes.