Search
Campo de busca pill com ícone, label opcional e botão de limpar.
import { Search, X } from "lucide-react";
import {
InputGroup,
InputGroupAddon,
InputGroupButton,
InputGroupInput,
} from "@/components/ui/input-group";
export function SearchField() {
return (
<InputGroup className="max-w-md">
<InputGroupAddon>
<Search className="size-4" aria-hidden="true" />
</InputGroupAddon>
<InputGroupInput type="search" placeholder="Pesquisar pacientes..." aria-label="Pesquisar pacientes" />
<InputGroupButton type="button" size="icon-xs" aria-label="Limpar busca">
<X className="size-4" aria-hidden="true" />
</InputGroupButton>
</InputGroup>
);
} <script setup lang="ts">
import { Search, X } from "lucide-vue-next";
import {
InputGroup,
InputGroupAddon,
InputGroupButton,
InputGroupInput,
} from "@/components/ui/input-group";
</script>
<template>
<InputGroup class="max-w-md">
<InputGroupAddon>
<Search class="size-4" aria-hidden="true" />
</InputGroupAddon>
<InputGroupInput type="search" placeholder="Pesquisar pacientes..." aria-label="Pesquisar pacientes" />
<InputGroupButton type="button" size="icon-xs" aria-label="Limpar busca">
<X class="size-4" aria-hidden="true" />
</InputGroupButton>
</InputGroup>
</template> <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
Instale o Input Group da sua stack e rode o comando individual ITpS em seguida. O comando itps add search é theme-only: ele valida o slug e confirma que o contrato visual vem do tema ITpS, das classes copy-first e dos snippets desta página.
terminal · React/Next
pnpm dlx shadcn@latest add input-group
pnpm dlx github:ITPS/sinapse-ui-cli add search terminal · Vue3/Nuxt4
pnpm dlx shadcn-vue@latest add input-group
pnpm dlx github:ITPS/sinapse-ui-cli add search O comando individual adapta só este componente; não instala o catálogo inteiro.
Uso
Use itps-search para busca principal ou filtros de lista. O input é nativo type="search"; o botão de limpar usa os hooks data-itps-search-input e data-itps-search-clear.
Em React/Next com shadcn/ui e Vue3/Nuxt4 com shadcn-vue, use InputGroup, InputGroupInput, InputGroupAddon e InputGroupButton. 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 label inline fica dentro da pill; no shadcn, componha o label por fora do InputGroup.
import { Search } from "lucide-react";
import {
InputGroup,
InputGroupAddon,
InputGroupInput,
} from "@/components/ui/input-group";
export function SearchCompositions() {
return (
<div className="grid max-w-md gap-3">
<label htmlFor="search-cpf" className="text-sm font-medium">
Pesquisar
</label>
<InputGroup>
<InputGroupAddon>
<Search className="size-4" aria-hidden="true" />
</InputGroupAddon>
<InputGroupInput id="search-cpf" type="search" placeholder="CPF ou prontuário" aria-label="Buscar por CPF ou prontuário" />
</InputGroup>
<InputGroup className="shadow-lg">
<InputGroupAddon>
<Search className="size-4" aria-hidden="true" />
</InputGroupAddon>
<InputGroupInput type="search" placeholder="O que você precisa hoje?" aria-label="Busca global" />
</InputGroup>
</div>
);
} <script setup lang="ts">
import { Search } from "lucide-vue-next";
import {
InputGroup,
InputGroupAddon,
InputGroupInput,
} from "@/components/ui/input-group";
</script>
<template>
<div class="grid max-w-md gap-3">
<label for="search-cpf" class="text-sm font-medium">
Pesquisar
</label>
<InputGroup>
<InputGroupAddon>
<Search class="size-4" aria-hidden="true" />
</InputGroupAddon>
<InputGroupInput id="search-cpf" type="search" placeholder="CPF ou prontuário" aria-label="Buscar por CPF ou prontuário" />
</InputGroup>
<InputGroup class="shadow-lg">
<InputGroupAddon>
<Search class="size-4" aria-hidden="true" />
</InputGroupAddon>
<InputGroupInput type="search" placeholder="O que você precisa hoje?" aria-label="Busca global" />
</InputGroup>
</div>
</template> <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="Small (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 | Container 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* | Hooks usados pelo script global de formulários. |
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.