One-time code
Six-digit one-time-code field backed by one real input, so typing, paste and code autofill work; a wrong code shakes and falls away.
Playground
Change a prop and the component re-renders. Props marked remounts set an initial value, so the component starts over.
<PxOtp code="424242" hint="Demo code: 424242" />
Installation
pnpm dlx shadcn@latest add @lumesec/px-otpFirst timeRegister the @lumesec registry once, or install by URL+
Adds @lumesec to your components.json:
pnpm dlx shadcn@latest registry add @lumesec=https://elements.lumesec.ai/r/{name}.jsonOr skip the setup and install by URL:
npx shadcn@latest add https://elements.lumesec.ai/r/px-otp.jsonUsage
import { PxOtp } from "@/components/lumesec/px-otp";
export function Example() {
return (
<PxOtp
name="code"
onComplete={(code, valid) => {
if (valid) console.log("verify", code);
}}
/>
);
}Behaviour
Six boxes backed by one real input, so typing, pasting and the phone’s one-time-code autofill all work. Digits rise into their boxes; a wrong code shakes and falls away.
API reference
Props
Also accepts every prop of <div> (React.ComponentProps<"div">), spread onto the root element.
valueTypestringControlled digits entered so far. Use with onValueChange.
defaultValueTypestringDefault""Initial digits when uncontrolled.
codeTypestringExpected code. When set, a complete entry is compared with it; when missing, any six digits are valid.
hintTypestringDefault"Enter the 6-digit code"Message under the boxes until a code is checked, and again after reset().
nameTypestringForm field name; the digits submit under it.
disabledTypebooleanDefaultfalseDims the boxes and disables the input.
onValueChangeType(value: string) => voidCalled with the digits entered so far on every change.
onCompleteType(code: string, valid: boolean) => voidCalled when the sixth digit is entered, with the code and whether it matched code.
Ref
ref receives a PxOtpHandle handle with these methods.
reset(): voidClears the digits and the result, and shows the hint again.
focus(): voidMoves focus into the code input.
Keyboard
| Keys | Action |
|---|---|
| ArrowLeft / ArrowRight / Home / End | Ignored, so the caret stays at the end of the code. |
Accessibility
- One native
<input>withinputmode="numeric",autocomplete="one-time-code"andaria-label="6-digit code"covers the boxes. The boxes are drawn on anaria-hiddencanvas and the digits in them arearia-hiddentext, so assistive technology reads the input's value. - The message line is an
aria-live="polite"region, so "Code verified" and the mismatch message are announced. - After a wrong code the field clears and focus returns to the input; after a correct code the input loses focus.
- A native
<input>submits the digits entered so far undername. It never reports itself invalid; after a wrong code the value is cleared 650 ms later. Form reset works likereset(). - Reduced motion: digits appear in place without rising, and the success sparks and error shake are skipped; removed digits still break into pixels.
Theming
Styled with Tailwind classes on your shadcn theme tokens, so light and dark follow your theme. The accent comes from --lumesec. See Theming.
This component reads --foreground, --muted-foreground, --lumesec, --lumesec-shine, --lumesec-success and --destructive.
Notes
- The comparison with
coderuns in the browser, so the expected code is visible to anyone who looks; treat it as a demo aid and verify codes on the server. - Digits are text in the mono font with tabular figures. They rise into their boxes; a removed digit breaks into pixels sampled from its glyph, and a rejected code falls away as red pixels.
- After a correct code, further typing is ignored until
reset()is called. - Non-digits are stripped and input stops at six digits, so a pasted or autofilled "424 242" completes. Messages are in English.
- The root carries
data-state="ok"ordata-state="error"while a result shows.
Related
Was this page helpful?