Search Input

Pronto

Variante de Text Input para busca: ícone Search à esquerda, X à direita pra limpar, debounce e atalho ⌘K opcional.

Usar quando

Topo de listagem para filtrar inline. Header global com command-palette. Busca em selects/comboboxes. Inbox de mensagens.

Não usar quando

Captura de string genérica (use Text Input). Form principal (use Text Input com label).

Variantes

⌘K

Microinterações

MicrointeraçãoDisparada porComportamentoTiming
Clear button revealvalue !== ""X aparece com fade150ms ease
Debounce indicatordigitando + debounce ativoSpinner substitui ícone Search300ms debounce
Focus ringfocusBorder ink + outline brassEdge150ms
Shortcut highlightshortcut visible + focoKbd "⌘K" ganha brilho sutil150ms

Acessibilidade

Acessibilidade — checklist

Teclado
Tab / ⌘K (global)Foco no input
EscLimpa o input
EnterSubmete busca (se form)
ARIA esperado
  • type="search" + role="searchbox"
  • aria-label="Buscar processos"
  • autoComplete="off" (busca não autocompleta)
  • inputMode="search"
Notas
  • type="search" mostra teclado "Buscar" no mobile.
  • Esc deve limpar (padrão Apple/Stripe).
  • Debounce 300ms para busca remota.
  • Atalho global ⌘K em apps power-user.

Código

'use client';
import { Search, X } from 'lucide-react';
import { T } from '@/lib/tokens';

export function SearchInput({ value, onChange, placeholder = 'Buscar...' }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 8, border: `1px solid ${T.border}`, borderRadius: 12, padding: '0 12px', height: 36 }}>
      <Search size={14} color={T.inkSubtle} />
      <input type="search" role="searchbox" inputMode="search"
        value={value} onChange={(e) => onChange(e.target.value)}
        onKeyDown={(e) => { if (e.key === 'Escape') onChange(''); }}
        placeholder={placeholder} style={{ flex: 1, border: 'none', outline: 'none' }} />
      {value && <button onClick={() => onChange('')} aria-label="Limpar"><X size={12} /></button>}
    </div>
  );
}

Regras

Faça

  • type="search" + inputMode="search".
  • Esc limpa.
  • Debounce 300ms se busca remota.
  • X aparece quando há value.
  • Atalho ⌘K global em apps grandes.

Não faça

  • Não use type="text" (perde keyboard mobile).
  • Não esconda o ícone Search (sinaliza propósito).
  • Não force submit em Enter sem feedback.
  • Não busque sem debounce (spam de requests).

Tokens usados

TokenValorPapel
T.surface#FFFFFFbackground
T.border#E3DFD2borda
T.inkSubtle#8A8A8Dícone Search
RADIUS.md12borderRadius