Fields
Search Field
A labelled search box with an optional erase button.
When to use it: Use it for a query that filters or finds things.
Example
import { useState } from "react";
import { Label, SearchField, SearchFieldClear, SearchFieldInput } from "@comp0/react";
import { MagnifyingGlassIcon, XMarkIcon } from "@heroicons/react/16/solid";
export function Example() {
const [submitted, setSubmitted] = useState("");
return (
<SearchField as="div" className="flex max-w-xs flex-col gap-2" onSubmit={setSubmitted}>
<Label className="text-base font-medium text-zinc-900 sm:text-sm dark:text-zinc-100">
Search
</Label>
<div className="relative">
<MagnifyingGlassIcon
className="pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2 text-zinc-400"
aria-hidden="true"
/>
<SearchFieldInput
className="w-full rounded border border-zinc-950/10 bg-white py-2.5 pr-11 pl-9 text-base text-zinc-950 outline-teal-600 focus-visible:outline-2 sm:py-2 sm:text-sm dark:border-white/10 dark:bg-zinc-900 dark:text-zinc-50 dark:outline-teal-400 [&::-webkit-search-cancel-button]:hidden"
name="query"
placeholder="Press Enter"
/>
<SearchFieldClear
aria-label="Clear search"
className="absolute top-1/2 right-1 flex size-8 -translate-y-1/2 items-center justify-center rounded text-zinc-500 outline-teal-600 hover:bg-zinc-100 hover:text-zinc-800 focus-visible:outline-2 dark:text-zinc-400 dark:outline-teal-400 dark:hover:bg-zinc-800 dark:hover:text-zinc-100"
>
<XMarkIcon className="size-4" aria-hidden="true" />
</SearchFieldClear>
</div>
{submitted && (
<p className="text-base text-zinc-600 sm:text-sm dark:text-zinc-400">
Searching for “{submitted}”
</p>
)}
</SearchField>
);
}Anatomy
Dashed frames are invisible state providers; shaded shapes own real DOM. Numbered pins match the list below.
A wireframe sketch of the assembled component. Each numbered marker matches a part in the list that follows.
SearchField
Field provider with no DOM by default. Does not add a DOM element.
SearchFieldInput
Native search input. Owns a DOM element.
SearchFieldClearOptional
Optional native clear button shown while the query has text. Owns a DOM element.
Step by step
- 1
Add the main part
Start with SearchField, Label, and SearchFieldInput.
- 2
Add the supporting parts
Add SearchFieldClear if clearing a query is useful; it appears only while the query has text.
- 3
Make the behavior clear
Name the input when the query should be submitted.
Exampletsx <SearchField><Label>Search</Label><SearchFieldInput name="q" /><SearchFieldClear aria-label="Clear search" /></SearchField>
Keyboard
- ↵
- Submits the surrounding form.
- ⇥
- Moves to the clear button while the query has text.
Forms and accessibility
SearchFieldInput submits its native name and query.
Accessibility checklist
- Label the search purpose, even when the placeholder says Search.
- Give the clear button understandable text or an aria-label.
- Announce result counts outside the input when results update.
- Pass as="search" when this is the page's search landmark; the native element announces it.
API reference
import { Label, SearchField, SearchFieldClear, SearchFieldInput } from "@comp0/react";SearchField
Context onlyField provider with no DOM by default.
| Prop | Type | Description |
|---|---|---|
value | string | Controlled field value. |
defaultValue | string | Initial field value. |
onChange | (value: string) => void | Receives the next value. |
disabled / invalid / required | boolean | Field-wide states shared with every part. |
onSubmit | (value: string) => void | Receives the query when Enter submits. |
onClear | () => void | Runs when the query is erased. |
SearchFieldInput
DOM elementNative search input.
| Prop | Type | Description |
|---|---|---|
name | string | Submission name for the query. |
placeholder | string | Hint text; never a replacement for Label. |
SearchFieldClear
OptionalDOM elementOptional native clear button shown while the query has text.
Style hooks
Attributes that appear while a state is true. Target them with Tailwind data variants such as data-open:bg-zinc-100, or with any CSS selector.
[data-invalid]on SearchFieldInput
- The field is invalid.
[data-disabled]on SearchFieldInput
- The field is disabled.