# Search Field

> Clearable search with recent queries, loading, empty, and error feedback.

- Category: Forms
- Kind: component
- Page: https://uaiblocks.dev/components/search-field
- Registry item: https://uaiblocks.dev/r/search-field.json
- Source: https://github.com/victor-teles/uai/blob/main/src/registry/uai/components/search-field.tsx

## Install

```bash
bunx shadcn@latest add https://uaiblocks.dev/r/search-field.json
```

## 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>
  );
}
```

## Anatomy

- `SearchField`
  - `SearchFieldLabel`
  - `SearchFieldControl`
    - `SearchFieldInput`
    - `SearchFieldClear`
  - `SearchFieldMessage`
  - `SearchFieldRecent`
    - `SearchFieldRecentItem`

## Accessibility

- 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.
