Verify Code

Web/Mobile

A one-time code field with digit boxes, optional groups, resend timer, description, and error. Values always display as Persian digits.

زمان باقی‌مانده تا دریافت کد مجدد

۰۱:۰۰

Installation

pnpm dlx cubix-ui@latest add verify-code --base radix

Usage

Import
import {
  VerifyCode,
  VerifyCodeControl,
  VerifyCodeLabel,
  VerifyCodeResend,
} from "@/components/cubix/verify-code"
Example
<VerifyCode className="w-full max-w-sm">
  <VerifyCodeLabel>کد تایید</VerifyCodeLabel>
  <VerifyCodeControl />
  <VerifyCodeResend />
</VerifyCode>

Composition

Compose label, control, resend, help text, and error under VerifyCode. VerifyCodeControl renders digit boxes from length and optional groups. Digits always display in Persian. Filling a box moves focus forward; Backspace on an empty box moves back. Paste a full code to fill every box.

Structure
VerifyCode
├── VerifyCodeLabel
├── VerifyCodeControl
│   ├── VerifyCodeDigit
│   └── VerifyCodeSeparator
├── VerifyCodeResend
├── VerifyCodeDescription
└── VerifyCodeError

Accessibility

Each digit box is named by position. Auto-advance and Backspace keep keyboard entry on one path. VerifyCodeResend exposes a clear countdown and becomes a button when ready. VerifyCodeDescription and VerifyCodeError are announced through aria-describedby. Set name on the root to submit a single hidden value for the full code.

Examples

Length

Change how many digit boxes render with the length prop.

زمان باقی‌مانده تا دریافت کد مجدد

۰۱:۰۰

زمان باقی‌مانده تا دریافت کد مجدد

۰۱:۰۰

Groups

Pass groups to insert separators between digit runs (for example 3-3).

زمان باقی‌مانده تا دریافت کد مجدد

۰۱:۰۰

زمان باقی‌مانده تا دریافت کد مجدد

۰۱:۰۰

Resend

Use VerifyCodeResend with duration for a countdown before the user can request a new code.

زمان باقی‌مانده تا دریافت کد مجدد

۰۲:۰۰

Filled

Pass defaultValue on the root to show a complete code.

زمان باقی‌مانده تا دریافت کد مجدد

۰۱:۰۰

Invalid

Set invalid on the root to apply destructive styles and show VerifyCodeError.

زمان باقی‌مانده تا دریافت کد مجدد

۰۱:۰۰

Disabled

Disable the field to block every digit and the resend control. Label and description stay readable.

زمان باقی‌مانده تا دریافت کد مجدد

۰۱:۰۰

Sizes

Two heights ship by default: default (40px) and lg (48px). Use className for any other size.

زمان باقی‌مانده تا دریافت کد مجدد

۰۱:۰۰

زمان باقی‌مانده تا دریافت کد مجدد

۰۱:۰۰

In a form

Set name on the root so the combined code is submitted with the form, and pair the field with Cubix Button.

تایید هویت

کد ارسال‌شده را وارد کنید تا ادامه دهید.

زمان باقی‌مانده تا دریافت کد مجدد

۰۱:۰۰

Custom styling

Every part accepts a className merged with the shipped cn helper.

زمان باقی‌مانده تا دریافت کد مجدد

۰۱:۰۰

API Reference

Note: Parts render data-slot attributes (verify-code, verify-code-label, verify-code-control, verify-code-digit, verify-code-separator, verify-code-resend, verify-code-description, verify-code-error) for targeting in tests and parent selectors. Use the same props on Base UI, React Aria, and Radix.

VerifyCode

PropTypeDefaultDescription
lengthnumber6Number of digit boxes to render (clamped between 4 and 8). Inherited by VerifyCodeControl when it auto-renders digits.
groupsnumber[]-Optional digit grouping. Sum must equal length. Inserts a - between groups when VerifyCodeControl auto-renders - for example [3, 3] or [2, 2, 2]. Ignored when invalid or when you pass custom digit children.
size"default" | "lg""default"Height for the digit boxes: default 40px, lg 48px. Inherited by VerifyCodeControl unless overridden.
disabledbooleanfalseDisables the field and prevents interaction. Forwarded to every digit on every base.
invalidbooleanfalseMarks the field as invalid and applies a destructive border on the digit boxes.
defaultValuestring-Initial code as a digit string (Persian or Latin). Split across the boxes up to length.
valuestring-Controlled code string. Pair with onValueChange when the parent owns the value.
onValueChange(value: string) => void-Called with the combined Persian-digit string whenever a digit changes.
namestring-Writes a hidden input with the combined code (Persian digits, no separators) for form submit.
classNamestring-Additional Tailwind classes merged with the root styles (last one wins).

VerifyCodeControl

PropTypeDefaultDescription
size"default" | "lg"-Overrides the size from VerifyCode. Height matches the default and lg sizes.
digitClassNamestring-Classes merged onto each auto-rendered VerifyCodeDigit. Ignored when you pass custom digit children.
childrenReact.ReactNode-Optional. When omitted, VerifyCodeControl renders length digit boxes and inserts VerifyCodeSeparator between groups when groups is set on the root. Pass VerifyCodeDigit and VerifyCodeSeparator nodes to customize composition.
classNamestring-Additional Tailwind classes merged with the control styles (last one wins).

VerifyCodeDigit

PropTypeDefaultDescription
indexnumber-Zero-based position of the digit box. Required when composing VerifyCodeDigit manually.
placeholderstring""Hint text shown when the digit box is empty. Empty by default.
inputMode"numeric""numeric"Locked to numeric so mobile keyboards show a number pad.
classNamestring-Additional Tailwind classes merged with the digit styles (last one wins).
...propsOmit<React.ComponentProps<'input'>, 'type' | 'inputMode' | 'spellCheck' | 'maxLength' | 'value' | 'defaultValue'>-Native input attributes are forwarded. type, inputMode, spellCheck, maxLength, value, and defaultValue stay locked. Use parseVerifyCodeValue / formatVerifyCodeValue for the combined string.

VerifyCodeSeparator

PropTypeDefaultDescription
childrenReact.ReactNode"-"Separator content between digit groups. Defaults to a hyphen.
classNamestring-Additional Tailwind classes merged with the separator styles (last one wins).

VerifyCodeResend

PropTypeDefaultDescription
durationnumber60Countdown length in seconds before resend is available. Default is 1 minute (60). Pass 120 for two minutes.
waitingLabelReact.ReactNode"زمان باقی‌مانده تا دریافت کد مجدد"Helper text shown beside the muted timer badge while counting down.
expiredLabelReact.ReactNode"دریافت مجدد کد تایید"Helper text shown beside the badge after the countdown reaches zero.
resendLabelReact.ReactNode"دریافت مجدد"Label inside the muted badge after the countdown ends. Clicking the badge restarts the timer.
onResend() => void-Called when the user clicks the badge to resend. The countdown restarts automatically after the click.
classNamestring-Additional Tailwind classes merged with the resend row styles (last one wins).

VerifyCodeLabel / Description / Error

PropTypeDefaultDescription
childrenReact.ReactNode-Label text, helper description, or error message content.
classNamestring-Additional Tailwind classes merged with the part styles (last one wins).
...propsHTML attributes-Native attributes for the rendered element are forwarded.