React + MotionInputs

Código OTP

Seis casillas para un código de verificación que avanzan al escribir y retroceden al borrar.

Ajustes

12px

Código

import { useRef, useState } from "react";

const LENGTH = 6;

interface OtpInputProps {
  radius?: number;
  value?: string;
  onChange?: (value: string) => void;
}

export default function OtpInput({ radius = 12, value, onChange }: OtpInputProps) {
  const [internal, setInternal] = useState<string[]>(Array(LENGTH).fill(""));
  const refs = useRef<Array<HTMLInputElement | null>>([]);
  const digits =
    value === undefined
      ? internal
      : Array.from({ length: LENGTH }, (_, i) => value[i] ?? "");

  const update = (i: number, x: string) => {
    const next = digits.map((d, j) => (j === i ? x : d));
    if (value === undefined) setInternal(next);
    onChange?.(next.join(""));
  };

  return (
    <div className="flex gap-2">
      {digits.map((d, i) => (
        <input
          key={i}
          ref={(el) => {
            refs.current[i] = el;
          }}
          aria-label={`Dígito ${i + 1}`}
          value={d}
          inputMode="numeric"
          maxLength={1}
          onChange={(e) => {
            const x = e.target.value.replace(/\D/g, "");
            update(i, x);
            if (x) refs.current[i + 1]?.focus();
          }}
          onKeyDown={(e) => {
            if (e.key === "Backspace" && !d) refs.current[i - 1]?.focus();
          }}
          className="h-12 w-10 border border-black/10 bg-white text-center text-lg text-[#1d1d1f] outline-none focus:ring-2 focus:ring-[#0071e3] dark:border-white/10 dark:bg-[#1c1c1e] dark:text-[#f5f5f7]"
          style={{ borderRadius: radius }}
        />
      ))}
    </div>
  );
}

Prompt para IA

Pégalo en ChatGPT, Claude o Cursor y adaptará el bloque a tu proyecto con estos ajustes, aunque no uses React.

Más en Inputs

Dónde usarlo

Los códigos de un solo uso aparecen en registros, en el login con doble factor, en transferencias bancarias y en confirmaciones de entrega. Seis casillas separadas permiten revisar el código de un vistazo, y el cursor avanza solo, así que nadie tiene que tocar cada casilla. Solo acepta números, justo lo que necesita un input OTP en React.

Mucha gente copia el código de un SMS o de un email, así que plantéate añadir que al pegarlo se rellenen las seis casillas. Ajusta el radio a tus otros campos: las casillas redondas se ven amables y las cuadradas más serias, algo que quizá encaje mejor en un banco.