Input

Formulario

Campo de texto de uma linha, com tamanhos, tons de validação, ícone à esquerda e botão de limpar.

Carregando

Instalação

Recebe correções por update de versão. O caminho recomendado.

npm i @trdr/ui

import { Input } from "@trdr/ui/input"

Uso

import { Input } from "@trdr/ui/input"

export function Exemplo() {
  return <Input />
}

Variantes

GrupoValoresPadrão
size
defaultlg
default
tone
defaulterrorwarningsuccess
default

Props

InputPropsestende Omit<React.InputHTMLAttributes<HTMLInputElement>, "size">, VariantProps<typeof inputVariants>
PropTipoDescrição
iconLeft?React.ReactNodeIcone decorativo no inicio do campo. Marcado aria-hidden internamente.
onClear?() => voidChamado quando o usuario aciona o botao de limpar. O botao so aparece quando esta prop existe, o campo nao esta desabilitado nem readOnly, e `value` (controlado) e nao vazio. Sem `value` controlado o botao nunca aparece: o legado tinha a mesma limitacao.
wrapperClassName?stringClasse do wrapper, para quando o consumidor precisa customizar o container, nao o input.

Input

Campo de texto de uma linha. É o primitivo que substitui a variante single-line do antigo TextInput do Hub, agora separado de textarea e sem o variant="quick-action" da boleta de operação (ver nota no final).

Quando usar

  • Formulários de uma linha: nome, e-mail, código de ativo, quantidade, senha.
  • Campo de busca, com iconLeft e o botão de limpar.
  • Sempre acompanhado de um label associado por htmlFor/id. O input sozinho não é um campo de formulário completo, é a parte que recebe o valor.

Quando não usar

  • Texto de mais de uma linha: use textarea.
  • Boleta de operação com o padrão visual quick-action do legado (altura 32px, texto terciário 11px, gap largo): esse caso ficou de fora desta primeira versão porque não coube como uma variante limpa do input genérico. Ele mistura tamanho, cor de texto e espaçamento de um jeito específico da boleta, não do campo de texto em geral. Ver "Nota sobre quick-action" abaixo.

Anatomia

<div data-slot="input">                 wrapper: fundo, borda, raio, foco
  <span data-slot="input-icon">         opcional, só quando iconLeft é passado
  <input data-slot="input-field">       o campo em si, recebe o ref
  <button data-slot="input-clear">      opcional, só quando onClear + value existem
</div>

Variantes

  • size: default (24px de altura) e lg (32px).
  • tone: default, error, warning, success. Controla a cor da borda. Equivalente ao validation do componente legado, renomeado para acompanhar o vocabulário variant/size/tone do restante da biblioteca.

Acessibilidade

  • O ref aponta para o <input> nativo, não para o wrapper: inputRef.current.focus() funciona como em qualquer input HTML.
  • Quando tone="error", o componente já marca aria-invalid="true" sozinho. Se o consumidor passar aria-invalid explicitamente, o valor dele prevalece.
  • aria-describedby funciona por spread de props nativo: passe o id da mensagem de erro ou ajuda e referencie normalmente. É assim que o componente field (fora de escopo aqui) vai casar input, label, descrição e erro.
  • O botão de limpar tem aria-label="Limpar campo" fixo e tabIndex={-1}: ele não entra na ordem de tab porque limpar não é uma ação que precise de foco próprio, mas continua acessível por mouse, toque e leitor de tela via navegação por elemento.
  • O alvo de toque do ícone e do botão de limpar é 24x24px, o mínimo do design system.

Nota sobre quick-action

O legado tinha uma variante quick-action usada especificamente na boleta de operação (Boleta.tsx no Hub antigo): sempre grande, sempre com ícone, texto em cor terciária e gap maior que o padrão. Isso não é uma variação do campo de texto, é uma composição de tamanho + cor de texto + espaçamento amarrada a um contexto de uso específico. Forçar isso como uma variante do input genérico misturaria uma decisão de produto (a boleta) dentro de um primitivo de formulário. Ficou de fora desta implementação; se a boleta precisar dele, a composição correta é um componente próprio (ou do pacote de trading) que usa input por baixo com as classes daquele contexto.

Slots e tokens

Todo elemento renderizado carrega um data-slot para estilizar partes internas sem depender de classe da biblioteca. Os tokens listados são extraídos do código fonte.

[data-slot="input"][data-slot="input-clear"][data-slot="input-field"][data-slot="input-icon"]
18 tokens usados
bg-surface-disabledbg-surface-primarybg-transparentborder-border-disabledborder-border-focusborder-content-errorborder-content-successborder-content-warningborder-transparentoutline-nonering-offset-2ring-offset-backgroundring-ringtext-b3text-content-disabledtext-content-placeholdertext-content-primarytext-content-tertiary