Skip to Content
ComponentsAtomsInput OTP

Input OTP

Atom

Input OTP coleta códigos curtos e temporários. Use apenas quando há um fluxo real de verificação.

Use para 2FA, confirmação por e-mail ou códigos de recuperação. O campo deve deixar claro o tamanho do código, a origem esperada e o que fazer quando o código expira.

Exemplos copiáveis

React

import * as React from "react" type PulsoInputOtpProps = { length?: number label: string value: string onChange: (value: string) => void description?: string } export function PulsoInputOtp({ length = 6, label, value, onChange, description }: PulsoInputOtpProps) { const descriptionId = React.useId() const cells = Array.from({ length }, (_, index) => value[index] ?? "") return ( <div className="grid gap-2"> <label className="font-mono text-[10.5px] uppercase tracking-[var(--tracking-kicker)] text-[var(--fg-subtle)]"> {label} </label> <input inputMode="numeric" autoComplete="one-time-code" maxLength={length} value={value} onChange={(event) => onChange(event.target.value.replace(/\D/g, "").slice(0, length))} aria-describedby={description ? descriptionId : undefined} className="sr-only" /> <div aria-hidden="true" className="flex gap-2"> {cells.map((cell, index) => ( <span key={index} className="grid size-10 place-items-center rounded-[var(--radius-sm)] border border-[var(--border-strong)] bg-[var(--card)] font-mono text-lg font-semibold tabular-nums text-[var(--fg)]" > {cell || "–"} </span> ))} </div> {description ? <p id={descriptionId} className="text-xs text-[var(--fg-muted)]">{description}</p> : null} </div> ) }
const [code, setCode] = React.useState("") <PulsoInputOtp label="Código de verificação" value={code} onChange={setCode} description="Digite os 6 números enviados para seu e-mail operacional." />

Quando usar

  • Autenticação em dois fatores.
  • Código temporário enviado por canal conhecido.
  • Confirmação curta com expiração.

Quando não usar

  • Para senha permanente.
  • Para token longo ou chave secreta.
  • Para confirmação que pode ser um botão simples.
  • Para capturar dados sensíveis sem contexto de segurança.

Acessibilidade

  • Preserve um input real para teclado, autofill e leitores de tela.
  • Use autocomplete="one-time-code" quando aplicável.
  • Informe tamanho do código e canal de envio.
  • Erro deve explicar se o código expirou, está incompleto ou inválido.

Regras

  1. Código curto, temporário e com origem explícita.
  2. Não masque erro como “falha genérica”.
  3. Permita colar o código inteiro.
  4. Não espalhe foco em múltiplos inputs sem necessidade.
  5. Reenvio precisa ter cooldown claro.
Last updated on