Components / Controls
SearchField
A TextField preset for search: it has a search icon, is clearable, and submits on Enter. For a plain text input, use TextField.
When to useLink to "When to use"
- A search or filter box above a list, table or document.
- Search inside a Toolbar.
Use something else when:
UsageLink to "Usage"
import { SearchField } from "@arshad-shah/cynosure";
<SearchField label="Search documents" onChange={setQuery} onSubmit={runSearch} />
<SearchField label="Search" labelHidden size="sm" />Submit and clearLink to "Submit and clear"
onSubmit(value) runs on Enter. It is ignored while an IME composition is active, so confirming a candidate never submits early. The clear button shows while the field has a value; set clearable={false} to remove it.
Match countLink to "Match count"
trailing shows status text inside the field, at its end: a match count such as "1 of 3". Each new text is announced politely, once, through a live region that is always in the page; the visible copy is hidden from screen readers so it is not read twice. It is for text only; buttons such as "next match" go in addonEnd, after it.
<SearchField label="Find" value={query} onChange={setQuery} trailing={query ? `${at} of ${total}` : undefined} />PropsLink to "Props"
SearchField takes every TextField prop except type and iconStart, plus onSubmit and trailing.
| Prop | What it does | Type | Default |
|---|---|---|---|
labelRequired | The field's label and accessible name. | ReactNode | |
onSubmit | Called with the current value on Enter (never while an IME composition is active). | ((value: string) => void) | |
trailing | Status text inside the field, at its end: a match count such as "3 of 12". When its text changes it is announced politely. Text only: put controls in addonEnd. | ReactNode | |
className | Added to the root element, for layout. | string | |
style | Layout only. | CSSProperties | |
value | The text (controlled). | string | |
defaultValue | Starting text when uncontrolled. | string | |
onChange | Called with the new text on every edit. | ((value: string) => void) | |
description | Help text shown below the field. | ReactNode | |
size | Field height and text size. Default "md". xs (about 20px) is for dense desktop chrome: the input still reaches 24px to press (44px on coarse pointers), and the clear and reveal buttons shrink with it. Its label is set as for sm. Addons keep their own size. | DenseSize | "md" |
width | Width of the control, so the controls of a column of fields line up: "sm", "md" and "lg" are the --cy-field-control-width-* tokens (never wider than the field), "full" is the whole field. Default: the control's own width (the whole field in the stacked layout for TextField and the other fields). | FieldWidth | |
iconEnd | Icon shown at the end of the field, after the input and its clear or reveal button. | IconData | |
variant | outline (default) or soft (tinted, borderless until focus). | "soft" | "outline" | |
data-testid | Test id, set on the native input. | string | |
labelHidden | Visually hide the label (it still names the control). Prefer visible labels. | boolean | |
error | Error message shown below the field; it is announced and marks the field invalid. | ReactNode | |
clearable | Shows a clear button while the field has a value. | boolean | |
addonStart | Controls inside the field's start, before the input (ColorField's swatch button). | ReactNode | |
addonEnd | Controls inside the field's end, after the input (NumberField's steppers). | ReactNode | |
labels | Replace the built-in English text: the names of the clear, show and hide buttons. | { clear?: string; show?: string; hide?: string; } | |
revealable | With type="password": a button to show and hide the value (API keys, tokens, passwords). | boolean | |
boxRef | The field's box (the input with its icons, addons and buttons), for a list or popover that drops from the whole field (Combobox, TagInput). Use it to measure or anchor; restyle through tokens, not its class. | Ref<HTMLDivElement> | |
layout | stack puts the label above the control and the description and error below it. split puts the label and description at the start and the control at the end of one row (a settings row); when the field is too narrow for both, the control moves under the text. Default "stack". | "stack" | "split" | "stack" |
Generated from the type definitions in @arshad-shah/cynosure 0.5.0.
Behaviour and accessibilityLink to "Behaviour and accessibility"
| Input | Result |
|---|---|
| Enter | Calls onSubmit with the current value (not during IME composition) |
| Escape | Clears the field if it has a value; when empty, blurs it |
- Role: it is a native
type="search"input, exposed as a search box. - Label: a visible label is preferred.
labelHiddenhides it visually but it still names the field. - Refs: the ref points at the input element.
- Trailing text: announced politely when it changes (a
role="status"region); the visible copy isaria-hidden.
ThemingLink to "Theming"
The trailing text has --cy-search-field-trailing-color and --cy-search-field-trailing-font-size. The field itself uses the TextField tokens: --cy-text-field-{height-sm,height-md,height-lg,radius,padding-inline,bg,border,soft-bg}.
createTheme({ components: { textField: { radius: "999px" }, searchField: { trailingFontSize: "12px" } } });RelatedLink to "Related"
These examples run Cynosure 0.5.0 (commit 50ce30b), the version on npm.