component · 22/108
Search Field
Clearable search with recent queries, loading, empty, and error feedback.
Install
Install manuallyView source on GitHub
Anatomy
- SearchField
- SearchFieldLabel
- SearchFieldControl
- SearchFieldInput
- SearchFieldClear
- SearchFieldMessage
- SearchFieldRecent
- SearchFieldRecentItem
Accessibility3 checks
- Escape and Clear empty the query; Clear and recent-query selection return focus to the input.
- SearchFieldRecent composes ordinary buttons in tab order; it is not an autocomplete listbox.
- The consumer owns search requests, results, and recent history. Status messages expose loading, empty, and error states.
Forms and usability
Recent searches
Code example
usage.tsx"use client";import { useState } from "react";import { SearchField, SearchFieldClear, SearchFieldControl, SearchFieldInput, SearchFieldLabel, SearchFieldMessage, SearchFieldRecent, SearchFieldRecentItem, type SearchFieldStatus, type SearchFieldVariant,} from "@/components/ui/uai/search-field";export function SearchFieldPreview({ variant = "rounded" }: { variant?: SearchFieldVariant }) { const [value, setValue] = useState(""); const [status, setStatus] = useState<SearchFieldStatus>("idle"); return ( <div style={{ display: "grid", gap: 24 }}> <SearchField variant={variant} value={value} onValueChange={(next) => { setValue(next); setStatus(next ? "empty" : "idle"); }} status={status} > <SearchFieldLabel>Search workspace</SearchFieldLabel> <SearchFieldControl> <SearchFieldInput placeholder="Search docs, issues, people…" /> <SearchFieldClear /> </SearchFieldControl> <SearchFieldMessage>{status === "idle" ? "Recent searches" : undefined}</SearchFieldMessage> <SearchFieldRecent> <SearchFieldRecentItem value="Q3 roadmap" /> <SearchFieldRecentItem value="Billing migration" /> <SearchFieldRecentItem value="Onboarding v2" /> </SearchFieldRecent> </SearchField> <label style={{ display: "flex", gap: 10, alignItems: "center", fontSize: 12, color: "var(--uai-muted)", }} > Preview response <select style={{ height: 26, padding: "0 8px", border: 0, borderRadius: 999, background: "var(--uai-surface-raised)", color: "var(--uai-text)", font: "inherit", }} value={status} onChange={(event) => setStatus(event.target.value as SearchFieldStatus)} > <option value="idle">Idle</option> <option value="loading">Loading</option> <option value="empty">No results</option> <option value="error">Error</option> </select> </label> </div> );}Manual installation
search-field.tsxLoading component source…