# Search

Campo de busca em pílula com ícone, rótulo opcional e botão de limpar.

> Documentação do Sinapse DS. Snippets shadcn usam os componentes do seu projeto (`@/components/ui/*`); snippets HTML usam as classes `itps-*` do CSS Sinapse (`/css/<versão>/`, veja `/comecar.md`). Componentes do site de documentação não fazem parte do DS.

- Categoria: Forms
- Status: stable
- Relacionados: /componentes/field.md, /componentes/textfield.md, /componentes/select.md

## Em cada stack

- HTML e Astro: Classes `itps-*` do CSS Sinapse, com todas as variantes desta página.
- React e Vue: Componente Sinapse, com as variantes desta página (`add @sinapse/search`).

**React/Next (shadcn/ui)**

```tsx
import { Search } from '@/components/ui/search'

export function SearchField() {
  return (
    <Search className="max-w-md" placeholder="Pesquisar pacientes..." aria-label="Pesquisar pacientes" />
  )
}
```

**Vue 3/Nuxt 4 (shadcn-vue)**

```vue
<script setup lang="ts">
import { ref } from 'vue'

import { Search } from '@/components/ui/search'

const query = ref('')
</script>

<template>
  <Search v-model="query" class="max-w-md" placeholder="Pesquisar pacientes..." aria-label="Pesquisar pacientes" />
</template>
```

**HTML (copy-first)**

```html
<div class="itps-search" data-itps-search>
  <i class="itps-search__icon ti ti-search" aria-hidden="true"></i>
  <input type="search" class="itps-search__input" placeholder="Pesquisar pacientes..." data-itps-search-input />
  <button type="button" class="itps-search__clear ti ti-x" aria-label="Limpar busca" data-itps-search-clear></button>
</div>
```

## Instalação

O comando instala o componente `Search` do Sinapse: pílula, tamanhos, rótulo em linha e botão "Limpar busca". Não é o Input Group do shadcn. Configure o registry uma vez por projeto em [Comece por aqui](/comecar).

**terminal · React/Next**

```sh
pnpm dlx shadcn@latest add @sinapse/search
```

**terminal · Vue 3/Nuxt 4**

```sh
pnpm dlx shadcn-vue@latest add https://dsystem.sinapse.org.br/r/vue/search.json
```

Sem shadcn, não há instalação por componente: use o CSS Sinapse e as classes da API copy-first desta página.

## Uso

Use `itps-search` para busca principal ou filtros de lista. O input é nativo `type="search"`; o botão de limpar usa os atributos `data-itps-search-input` e `data-itps-search-clear`; o comportamento fica por conta do produto (o script deste site não é distribuído).

Em React/Next com shadcn/ui e Vue 3/Nuxt 4 com shadcn-vue, use `Search`. As props vão para o `input` nativo; `size` (`sm`, `md`, `lg`), `floating` e `label` seguem os modificadores do HTML. O botão de limpar esvazia o campo, devolve o foco e chama `onClear` (React) ou emite `clear` (Vue); em Vue, use `v-model`. Para HTML ou wrappers finos, use `itps-search` e os hooks `data-itps-search*`.

## Exemplos

### Composições

Use os modificadores de escala quando a busca participa de layouts densos ou destacados. O rótulo em linha fica dentro da pílula (`label` no componente); sem ele, dê nome ao campo com `aria-label`.

**React/Next (shadcn/ui)**

```tsx
import { Search } from '@/components/ui/search'

export function SearchCompositions() {
  return (
    <div className="flex max-w-md flex-col gap-3">
      <Search size="sm" placeholder="Compacto (40px)" aria-label="Busca compacta" />
      <Search size="lg" label="Pesquisar:" placeholder="paciente, CPF ou prontuário" />
      <Search floating placeholder="O que você precisa hoje?" aria-label="Busca global" />
    </div>
  )
}
```

**Vue 3/Nuxt 4 (shadcn-vue)**

```vue
<script setup lang="ts">
import { Search } from '@/components/ui/search'
</script>

<template>
  <div class="flex max-w-md flex-col gap-3">
    <Search size="sm" placeholder="Compacto (40px)" aria-label="Busca compacta" />
    <Search size="lg" label="Pesquisar:" placeholder="paciente, CPF ou prontuário" />
    <Search floating placeholder="O que você precisa hoje?" aria-label="Busca global" />
  </div>
</template>
```

**HTML (copy-first)**

```html
<div class="itps-search itps-search--sm">
  <i class="itps-search__icon ti ti-search" aria-hidden="true"></i>
  <input type="search" class="itps-search__input" placeholder="Compacto (40px)" />
</div>

<div class="itps-search itps-search--lg">
  <i class="itps-search__icon ti ti-search" aria-hidden="true"></i>
  <label for="search-patient" class="itps-search__label">Pesquisar:</label>
  <input id="search-patient" type="search" class="itps-search__input" placeholder="paciente, CPF ou prontuário" />
  <button type="button" class="itps-search__clear ti ti-x" aria-label="Limpar busca"></button>
</div>

<div class="itps-search itps-search--floating">
  <i class="itps-search__icon ti ti-search" aria-hidden="true"></i>
  <input type="search" class="itps-search__input" placeholder="O que você precisa hoje?" />
</div>
```

## API copy-first

| Classe/atributo | Uso |
|-----------------|-----|
| `itps-search` | Contêiner visual da busca. |
| `itps-search--sm` | Altura compacta de 40px. |
| `itps-search--lg` | Altura ampla de 56px. |
| `itps-search--floating` | Superfície destacada para busca global ou hero. |
| `itps-search__icon` | Ícone decorativo de busca. |
| `itps-search__label` | Label inline opcional. |
| `itps-search__input` | Controle nativo `type="search"`. |
| `itps-search__clear` | Botão opcional para limpar a busca. |
| `data-itps-search*` | Atributos lidos pelo script do produto (este site usa `src/scripts/forms.ts`). |
| `aria-label` | Nomeia busca sem label visível e botão de limpar. |
| `aria-hidden="true"` | Esconde ícones decorativos de tecnologias assistivas. |

## Acessibilidade

Quando houver label visível, conecte `for` e `id`. O botão de limpar deve ser `button type="button"` com `aria-label`. Mantenha a lupa e o X decorativos com `aria-hidden="true"` quando o controle já tiver nome acessível.
