# SearchField

> El buscador de una lista: la lupa adentro del campo, «Borrar búsqueda» cuando hay texto y Escape que vacía.

```tsx
import { SearchField } from "sebs7n-ui/search-field"
```

## Ejemplos

### Filtrar una lista

La lupa adentro, «Borrar búsqueda» con texto y Escape que vacía. El filtrado es de la app.

```tsx
import { SearchField } from "sebs7n-ui/search-field"
import { useState } from "react"

function FilterList() {
  const [query, setQuery] = useState("")
  const shown = CLIENTS.filter((client) => client.toLowerCase().includes(query.trim().toLowerCase()))
  return (
    <div className="flex w-full max-w-sm flex-col gap-3">
      <SearchField aria-label="Buscar clientes" onValueChange={setQuery} placeholder="Buscar clientes" value={query} />
      <ul className="flex flex-col gap-1 text-callout text-label">
        {shown.map((client) => (
          <li key={client}>{client}</li>
        ))}
        {shown.length === 0 && <li className="text-label-secondary">Sin resultados</li>}
      </ul>
    </div>
  )
}
```

### Tamaños

28, 36 y 40, como los campos del formulario.

```tsx
import { SearchField } from "sebs7n-ui/search-field"

function Sizes() {
  return (
    <div className="flex w-full max-w-sm flex-col gap-3">
      <SearchField aria-label="Buscar facturas, chico" size="sm" />
      <SearchField aria-label="Buscar facturas" defaultValue="F-0012" />
      <SearchField aria-label="Buscar facturas, grande" size="lg" />
    </div>
  )
}
```

## Props

### SearchField

| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
| `defaultValue` | `string` | `""` | El texto al montar, sin controlar. |
| `disabled` | `boolean` | — | Apaga el campo y el botón de borrar. |
| `groupClassName` | `string` | — | Clases de la superficie. El `className` va al `<input>`. |
| `labels` | `Partial<SearchFieldLabels>` | — | Textos: `placeholder` y `clear`. Por defecto, `searchFieldLabels`. |
| `onKeyDown` | `KeyboardEventHandler<T>` | — | Corre antes que el Escape propio. Con `preventDefault()`, Escape no vacía el campo. |
| `onValueChange` | `(value: string) => void` | — | Avisa el texto en cada tecla y al borrar (con `""`). El debounce, si hace falta, es de la app. |
| `placeholder` | `string` | — | Lo que dice el campo vacío. Por defecto, `labels.placeholder` («Buscar»). |
| `size` | `"sm" \| "md" \| "lg"` | `"md"` | 28, 36 (default) o 40, como los campos. |
| `value` | `string` | — | El texto, controlado. |
| `className` | `string` | — | Clases del `<input>`. Las de la superficie van en `groupClassName`. |

## Teclado

| Tecla | Qué hace |
|---|---|
| Escape | Con texto, lo vacía; vacío, sigue de largo (cierra el diálogo de afuera). |
| Enter | Lo del formulario: envía, si hay uno. |
| Tab | Del campo al botón de borrar, si hay texto. |

## Accesibilidad

- Es un `<input type="search">`: el lector lo anuncia como campo de búsqueda. Nombralo con `aria-label` o metiéndolo en un `Field` (toma `FieldLabel` y `FieldDescription`, y el `name` del campo).
- La lupa es decorativa; el botón de borrar se llama «Borrar búsqueda» (`labels.clear`) y, al vaciar, el foco vuelve al campo.

## Reglas de uso

- Para filtrar una lista o una tabla con lo que se escribe. No filtra ni busca: avisa el texto con `onValueChange` y la app decide (en memoria, o contra el servidor con su debounce).
- Para sugerencias mientras se escribe, `Autocomplete` con `startIcon`.
- `size` 28/36/40 como los campos. Es la superficie de `InputGroup`: reemplaza las copias a mano de `InputGroup` + lupa + ✕.
- Solo por subpath (`sebs7n-ui/search-field`).

## Relacionados

[input-group](/docs/components/input-group.md) · [autocomplete](/docs/components/autocomplete.md) · [input](/docs/components/input.md)
