import { useState } from "react"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@godxjp/ui/data-display"; import { FormField, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, } from "@godxjp/ui/data-entry"; import { Flex, PageContainer } from "@godxjp/ui/layout"; /** * InputOTP — compound one-time-code input: InputOTP > InputOTPGroup > InputOTPSlot. * ONE field with paste, arrow-key, and caret handling built in. * Never use N separate Input fields for OTP. Composed only from real @godxjp/ui components. */ export default function Demo() { const [emailCode, setEmailCode] = useState(""); const [smsCode, setSmsCode] = useState(""); const [inviteCode, setInviteCode] = useState(""); const [centeredCode, setCenteredCode] = useState(""); // Auto-submit pattern — onComplete fires when every slot is filled. const [completeCode, setCompleteCode] = useState("123456"); const [verified, setVerified] = useState("123456"); // Error path — a wrong code seeded at rest so the invalid styling is visible // without typing. FormField wires aria-invalid + aria-errormessage onto the field. const [wrongCode, setWrongCode] = useState("000000"); return ( メール認証コード(6桁) 6スロット 1グループ · ペースト・矢印キー操作に対応。 {/* この行の id は FIELD ではなく CONTROL 側にある。FormField はその id をそのまま 使い、ラベルのクリックもその id を見る(gh#477:以前は FormField 自身の id を 見ていたので、両者が食い違った瞬間にラベルがどこも指さなくなった)。 */} SMS認証コード(3+3) InputOTPSeparator で 2 グループに分割して視認性を高める。 招待コード(4桁PIN) 4スロット · 数字のみ許可する pattern を指定。 自動送信(onComplete) 全スロットが埋まると onComplete が発火し、ボタンを押さずに検証を実行する。 setVerified(code)} > {/* Align — the centred challenge, without a consumer wrapper div */} 中央寄せ(align="center") 認証画面のコード入力は中央寄せが定型。コンテナ要素は input-otp が所有していて消費側から触れないため、以前は必ず flex の div でラップする必要があった。align はそのラッパーを不要にする (テーマ全体なら --otp-container-align を 1 か所)。 エラー(コードが一致しない) FormField の error で aria-invalid を付与 · スロットの枠が destructive 色に変わる。 無効(再送クールダウン中) disabled · コード再送のクールダウンや検証中は入力をロックする。 {}}> マスク・入力の正規化 入力と貼り付けを大文字に変換。マスクは表示だけに適用されます。 value.toUpperCase()} > {[0, 1, 2, 3].map((index) => ( ))} ); }