דילוג לתוכן
uiify

OTP input

שדה לקודים חד-פעמיים, עם תא לכל תו.

דפדפנים
Chrome 123+Firefox 121+Safari 17.5+
שכבה
2
גודל חבילה דחוסה
1.67 kB
מגבלת פריסה כפויה
0 ms
מגבלת Axe
0
תואם SSR
כן
חוזה מפורסם
סביבת בדיקות

מגרש ניסויים

import { OtpInput } from "@gunkin/uiify";

export default function Example() {
  return (
    <OtpInput.Root className="" id="verification-code" length={6}>
      {Array.from({ length: 6 }, (_, index) => (
        <OtpInput.Slot className="" index={index} key={index} />
      ))}
      <OtpInput.HiddenInput />
    </OtpInput.Root>
  );
}
/* OTP input — segmented code entry slots. */

@layer components {
  [data-uiify-otp-input] {
    position: relative;
    display: inline-flex;
    gap: var(--space-sm);
    cursor: text;
  }

  [data-uiify-otp-input] [data-part="slot"] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: var(--uiify-control-size, var(--control-md));
    block-size: var(--uiify-control-size, var(--control-md));
    border: var(--border-width) solid var(--input);
    border-radius: var(--radius-full);
    background-color: var(--card);
    color: var(--foreground);
    font-size: var(--uiify-control-font, var(--text-base));
    font-weight: var(--weight-medium);
    transition: var(--transition-colors);
  }

  [data-uiify-otp-input] [data-part="slot"][data-active] {
    border-color: var(--primary);
    outline: 2px solid color-mix(in oklch, var(--ring) 35%, transparent);
    outline-offset: 0;
  }

  [data-uiify-otp-input] [data-part="slot"][data-active]::after {
    inline-size: 1px;
    block-size: 1em;
    background-color: currentcolor;
    content: "";
    animation: uiify-otp-input-caret-blink 1s step-end infinite;
  }

  @keyframes uiify-otp-input-caret-blink {
    50% {
      opacity: 0;
    }
  }

  @media (prefers-reduced-motion: reduce) {
    [data-uiify-otp-input] [data-part="slot"][data-active]::after {
      animation: none;
    }
  }

  [data-uiify-otp-input] [data-part="slot"][data-filled] {
    border-color: var(--input);
  }

  [data-uiify-otp-input][data-disabled] [data-part="slot"] {
    opacity: 0.5;
    cursor: not-allowed;
  }
}

@layer components {
  [data-uiify-otp-input]:not([data-disabled]) {
    cursor: text;
  }
}
import { OtpInput } from "@gunkin/uiify";

export default function Example() {
  return (
    <OtpInput.Root className="relative inline-flex gap-sm [cursor:text]" id="verification-code" length={6}>
      {Array.from({ length: 6 }, (_, index) => (
        <OtpInput.Slot
          className="
            grid place-items-center [inline-size:var(--control-md)] [block-size:var(--control-md)]
            border-[length:var(--border-width)] border-solid border-input rounded-full bg-card text-foreground text-base
            font-medium tabular-nums [transition:var(--transition-colors)] data-[active]:border-primary
            data-[active]:[outline:2px_solid_color-mix(in_oklch,_var(--ring)_35%,_transparent)]
            data-[active]:[outline-offset:0] data-[active]:after:content-[''] data-[active]:after:[inline-size:1px]
            data-[active]:after:[block-size:1em] data-[active]:after:bg-current
            data-[active]:after:[animation:uiify-otp-input-caret-blink_1s_step-end_infinite]
            motion-reduce:data-[active]:after:[animation:none] data-[filled]:border-input data-[disabled]:opacity-50
            data-[disabled]:cursor-not-allowed
          "
          index={index}
          key={index}
        />
      ))}
      <OtpInput.HiddenInput />
    </OtpInput.Root>
  );
}

API

OtpInput.Root

מאפייןטיפוסברירת מחדלתיאור
size"sm" | "md" | "lg""md"גובה הפקד וגודל הטקסט, בהתאמה ל-Button (32, 40 או 48 px); נכתבים ל-data-size, עם md כשלא הוגדר ערך.
valuestring—הקוד הנוכחי, ההופך את השדה למבוקר.
defaultValuestring""הקוד ההתחלתי של השדה הלא מבוקר.
onValueChange(value: string) => void—נקראת עם הקוד בכל שינוי בו.
onComplete(value: string) => void—נקראת כשהקוד מגיע לאורך שהוגדר.
lengthnumber6מספר התווים שהקוד מכיל.
type"numeric" | "alphanumeric""numeric"התווים שנשמרים בעת הקלדה או הדבקה.
maskbooleanfalseמסתיר את התווים שהוזנו במשבצות.
disabledbooleanfalseמשבית את הקלט המוסתר ומגדיר את המאפיין data-disabled.
autoFocusbooleanfalseממקד את הקלט המוסתר כשהשדה נטען.
idstring—המזהה המוחל על אלמנט השורש המוצג.
renderReactElement | ((props, state) => ReactElement)—החלפת האלמנט המוצג תוך שימור ההתנהגות וקישורי הנגישות.

OtpInput.Slot

מאפייןטיפוסברירת מחדלתיאור
index*number—המיקום בקוד שמשבצת זו מציגה.
renderReactElement | ((props, state) => ReactElement)—החלפת האלמנט המוצג תוך שימור ההתנהגות וקישורי הנגישות.

OtpInput.HiddenInput

מאפייןטיפוסברירת מחדלתיאור
autoFocusboolean—ממקד קלט זה בעת הטעינה, תוך עקיפת הגדרת השורש.
renderReactElement | ((props, state) => ReactElement)—החלפת האלמנט המוצג תוך שימור ההתנהגות וקישורי הנגישות.

מקלדת

מקשפעולה
Tabהעברת המיקוד אל הפקד או ממנו
Enter / Spaceהפעלה כשהפקד ממוקד (פקדים דמויי כפתור)

נגישות

משתמש ב-HTML סמנטי ככל האפשר. בדקו את הסימון המרונדר במגרש הניסויים — ARIA נוסף רק כאשר האלמנטים המובנים אינם מספיקים.

נקודות חיבור לעיצוב

data-disabled
דף זה תורגם אוטומטית וטרם נבדק.