pteal79 / otp-code
One-time code input EDGE element (<native:otp-code>) for NativePHP Mobile: one box per digit, SwiftUI and Jetpack Compose
1.0.0
2026-10-23 14:28 UTC
Requires
- php: ^8.3
- nativephp/mobile: ^4.6
Requires (Dev)
- pestphp/pest: ^3.0|^4.0|^5.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
One-time code input for NativePHP Mobile: a row of boxes with one character per box, <native:otp-code>. It renders with SwiftUI on iOS and Jetpack Compose on Android.
<native:otp-code class="w-full h-[56]" native:model="code" @submit="verify" :is-error="filled($codeError)" :disabled="$loading" autofocus />
Behaviour
- Tap a box: the cursor moves to that box. It never moves past the first empty box.
- Type: the character replaces whatever is in the box under the cursor, and the cursor moves right.
- Backspace: clears the box under the cursor, and any later characters move left to close the gap. On an empty box, it clears the box before and moves back.
- Paste / autofill: a full-length insertion replaces the whole code. On iOS, one-time codes from Mail and Messages are offered above the keyboard.
- Programmatic updates: setting the bound property from PHP replaces the code. For example, clearing it after a wrong attempt empties the boxes and puts the cursor back on the first one.
Attributes
| Attribute | Default | |
|---|---|---|
native:model |
Two-way binding. The code is sent on every edit. | |
@change |
Handler gets the full code on every edit. native:model sets this for you. |
|
@submit |
Handler gets the full code each time an edit fills the last box. | |
length |
6 |
Number of boxes, from 1 to 12. |
alphanumeric |
false |
Accept letters as well as digits. Letters are upper-cased. |
secure |
false |
Show a dot instead of each character. |
is-error |
false |
Paint every box border in the error colour. |
disabled |
false |
Ignore taps and drop focus. |
autofocus |
false |
Focus the first empty box and open the keyboard when the screen first appears. |
gap |
8 |
Space between boxes (dp/pt). |
radius |
12 |
Box corner radius (dp/pt). |
font-size |
24 |
Character size. |
box-color, border-color, active-color, error-color, text-color |
native-ui theme | Hex colours. Each one has a dark- twin. The defaults come from the surface, outline, primary, destructive and on-surface tokens in config/native-ui.php. |
The size of the whole element comes from class; the default height is 56. The boxes share the width equally.
Only the characters the element accepts reach PHP. Input is filtered on the device, and again in OtpCode::normalize() when the value is rendered.