React + MotionChamps

Saisie de code OTP

Six cases pour un code de vérification, qui avancent pendant la saisie et reculent quand on efface.

Réglages

12px

Code

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 pour l’IA

Collez-le dans ChatGPT, Claude ou Cursor : le bloc sera adapté à votre projet avec ces réglages, même sans React.

Plus dans Champs

Où l’utiliser

Les codes à usage unique apparaissent à l’inscription, lors d’une connexion à double facteur, d’un virement bancaire ou d’une confirmation de livraison. Six cases séparées rendent le code facile à vérifier, et le curseur avance tout seul, sans avoir à toucher chaque case. Il n’accepte que des chiffres, ce qu’il faut pour un champ OTP en React.

Beaucoup de gens copient le code depuis un SMS ou un e-mail : pensez à gérer le collage pour remplir les six cases d’un coup. Accordez l’arrondi à vos autres champs ; des cases carrées font plus sérieux, ce qui peut mieux convenir à une banque.