Input
Campo de texto de linha única que adota todo `type` nativo do HTML e expõe estados de focus, erro e disabled controlados por token.
Visão geral
Input é um wrapper estilizado fino ao redor do elemento <input> nativo. Passe qualquer type do HTML (text, email, password, number, search, tel, url, file, date...) e a semântica do browser, a validação e o teclado virtual vêm todos de graça.
Todos os estados visuais são controlados por token: border-input para o padrão, focus-visible:ring-ring/50 para focus de teclado, e aria-invalid:border-destructive para erro. Não há variants - inputs devem parecer iguais em todo lugar para que os usuários possam prever seu comportamento.
Preview
'use client';import { Input, Label } from '@gremorie/rx-forms';export function InputPreview() { return ( <div className="flex max-w-xs flex-col gap-2"> <Label htmlFor="email-input">Email</Label> <Input id="email-input" type="email" placeholder="you@example.com" /> </div> );}Anatomia
Input único elemento <input> nativo estilizado (primitive folha)Instalação
bash npx gremorie@latest add rx-input bash pnpm dlx gremorie@latest add rx-input bash yarn dlx gremorie@latest add rx-input bash bunx --bun gremorie@latest add rx-input Uso
import { Input, Label } from "@gremorie/rx-forms";
export function Example() {
return (
<div className="grid gap-2">
<Label htmlFor="email">Email</Label>
<Input id="email" type="email" placeholder="you@example.com" />
</div>
);
}A edição Angular deste componente hoje é entregue a partir do código-fonte (veja o workbench para o comparativo lado a lado); a entrada de registry vem em seguida.
API
<Input>
| Prop | Type | Default | Description |
|---|---|---|---|
type | string | "text" | Qualquer tipo de input nativo do HTML. Controla o teclado, a validação e a UI da plataforma (ex. date picker, diálogo de arquivo). |
disabled | boolean | false | Desabilita a interação. Aplica pointer-events-none e opacity-50. |
aria-invalid | boolean | - | Quando true, troca a borda e o focus ring para o token destructive. |
Estende todos os React.ComponentProps<"input">. Renderiza com data-slot="input" para que o InputGroup pai possa controlar os estados de focus e erro de todo o grupo.
Composição
<Input>é um primitive folha. Combine-o com um<Label>(vinculado viahtmlFor/id) para que cliques e interações de leitor de tela foquem o campo.- Para ícones ou buttons de prefixo/sufixo, envolva-o com
<InputGroup>e use<InputGroupInput>em vez de<Input>para que o grupo possa controlar os estados de focus compartilhados. - Para uso vinculado a formulário, envolva-o em um
<FormField>+<FormControl>para que labels, descriptions e mensagens de erro conectem automaticamente as relações ARIA.
Variações
Com label
O padrão canônico. type="email" dispara o teclado de e-mail no mobile e habilita a validação nativa do browser. Combine cada input com um <Label> vinculado via htmlFor.
'use client';import { Input, Label } from '@gremorie/rx-forms';export function InputWithLabelPreview() { return ( <div className="grid w-full max-w-sm gap-2"> <Label htmlFor="email">Email</Label> <Input id="email" type="email" placeholder="you@example.com" /> </div> );}Input numérico com min/max
type="number" mostra o teclado numérico no mobile e aceita min, max, step para validação do browser.
<div className="grid gap-2">
<Label htmlFor="quantity">Quantity</Label>
<Input id="quantity" type="number" min={1} max={99} defaultValue={1} />
</div>Estado invalid
Controle aria-invalid a partir da sua biblioteca de validação e aponte aria-describedby para o texto de erro. O ring e a borda destructive vêm de graça.
Enter a valid email address.
'use client';import { Input, Label } from '@gremorie/rx-forms';export function InputInvalidPreview() { return ( <div className="grid w-full max-w-sm gap-2"> <Label htmlFor="invalid-email">Email</Label> <Input id="invalid-email" type="email" defaultValue="not-an-email" aria-invalid="true" aria-describedby="invalid-email-error" /> <p id="invalid-email-error" className="text-sm text-destructive"> Enter a valid email address. </p> </div> );}Input de arquivo
type="file" renderiza o picker nativo. Os seletores internos file: estilizam o trigger em formato de button.
'use client';import { Input, Label } from '@gremorie/rx-forms';export function InputFilePreview() { return ( <div className="grid w-full max-w-sm gap-2"> <Label htmlFor="attachment">Attachment</Label> <Input id="attachment" type="file" /> </div> );}Disabled
disabled remove o input da ordem de tabulação, bloqueia eventos de ponteiro e reduz a opacidade para 50%.
'use client';import { Input } from '@gremorie/rx-forms';export function InputDisabledPreview() { return ( <div className="w-full max-w-sm"> <Input disabled placeholder="Disabled input" defaultValue="Read only" /> </div> );}Acessibilidade
- Labels: todo input precisa de um
<Label>associado (viahtmlForcombinando com oiddo input) ou de umaria-labelexplícito. - Focus: focus-visible ring de 3px controlado por
focus-visible:ring-ring/50, então aparece apenas para usuários de teclado. - Validação: combine
aria-invalid="true"comaria-describedbyapontando para a mensagem de erro para que leitores de tela anunciem a falha quando o focus entra no campo. - Disabled:
disabledremove o input da ordem de tabulação e impede a ativação, incluindo focus emitido por JavaScript. - Autocomplete: respeite as convenções da plataforma definindo
autoComplete="email","current-password","one-time-code", etc.
Relacionados
- Label - o primitive de label acessível
- Input Group - envolva Input com ícones, buttons ou dicas de kbd
- Textarea - contraparte multi-linha
- Form - conecta Input ao react-hook-form com helpers de ARIA
- Input OTP - input segmentado para códigos de uso único