Input OTP
One-time password input with auto-focus and paste support.
Installation
Add the component to your project:
rails generate shadcn:component input_otp
Usage
<%= render Shadcn::InputOtpComponent.new(length: 6, name: "otp") %>
Examples
With Separator
Group slots and add separators between them for common OTP formats like XXX-XXX.
<%= render Shadcn::InputOtpComponent.new(length: 6, name: "otp") do |otp| %>
<% otp.with_group(slots: 3) %>
<% otp.with_separator %>
<% otp.with_group(slots: 3) %>
<% end %>
4-Digit PIN
<%= render Shadcn::InputOtpComponent.new(length: 4, name: "pin") %>
Numeric Only
Use pattern validation to restrict input to numbers only.
<%= render Shadcn::InputOtpComponent.new(length: 6, name: "otp", pattern: "^[0-9]*$") %>
Disabled
<%= render Shadcn::InputOtpComponent.new(length: 6, name: "otp", disabled: true) %>
In Form Field
Enter the 6-digit code sent to your email.
<%= render Shadcn::FieldComponent.new do |field| %>
<% field.with_label { "Verification Code" } %>
<% field.with_control do %>
<%= render Shadcn::InputOtpComponent.new(length: 6, name: "verification_code") %>
<% end %>
<% field.with_description { "Enter the 6-digit code sent to your email." } %>
<% end %>
<%= render Shadcn::ButtonComponent.new(class_name: "w-full") { "Verify" } %>
API Reference
Props
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
| length |
Integer
|
6
|
Number of OTP digits |
| name |
String
|
nil
|
Input name for form submission |
| pattern |
String
|
nil
|
Regex pattern for validation |
| disabled |
Boolean
|
false
|
Whether the input is disabled |
| required |
Boolean
|
false
|
Whether the input is required |
| autocomplete |
String
|
one-time-code
|
Autocomplete attribute |
| class_name |
String
|
nil
|
Additional CSS classes to apply |
Slots
| Slot | Props | Description |
|---|---|---|
| with_group | slots: 3 |
Creates a visual group of OTP slots |
| with_separator | - | Adds a separator (dash) between groups |
Stimulus Controller
The Input OTP component requires the shadcn--input-otp Stimulus controller.
Stimulus Controller
This component requires JavaScript. The Stimulus controller docs provides interactivity.
Installation
Add to your config/importmap.rb:
pin "shadcn-rails", to: "shadcn/index.js"
Then in your app/javascript/controllers/index.js:
import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn-rails"
const application = Application.start()
registerShadcnControllers(application)
Install the package:
npm install shadcn-rails
Then in your app/javascript/controllers/index.js:
import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn-rails"
const application = Application.start()
registerShadcnControllers(application)
Install the package:
yarn add shadcn-rails
Then in your app/javascript/controllers/index.js:
import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn-rails"
const application = Application.start()
registerShadcnControllers(application)
Install the package:
npm install shadcn-rails
Then in your app/javascript/controllers/index.js:
import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn-rails"
const application = Application.start()
registerShadcnControllers(application)
Or import just this controller:
import DocsController from "shadcn-rails/controllers/docs_controller"
application.register("docs", DocsController)
Targets
| Name | Description |
|---|---|
| slot | Container for each OTP digit slot |
| input | Individual input elements for each digit |
| hiddenInput | Hidden input storing the full OTP value |
| caret | Blinking caret indicator for empty focused slots |
Values
| Name | Type | Default | Description |
|---|---|---|---|
| length | Number |
6 |
Number of OTP slots |
| pattern | String |
|
Regex pattern for validation |
| disabled | Boolean |
false |
Disabled state |
Actions
| Action | Description |
|---|---|
| handleInput | Processes input and auto-advances |
| handleKeydown | Handles keyboard navigation |
| handlePaste | Processes pasted OTP codes |
| clear | Clears all inputs |
TypeScript
Type definitions are included. Import types as needed:
import type { DocsController } from "shadcn-rails"
Features
- Auto-advance: Cursor moves to next slot automatically after input
- Paste support: Paste a full OTP code and it fills all slots
- Keyboard navigation: Use arrow keys to move between slots
- Backspace handling: Deletes and moves to previous slot
- Pattern validation: Restrict input to specific characters
- Hidden input: Full OTP value is stored in a hidden input for form submission
Accessibility
- Each input is individually focusable via keyboard
- Uses
inputmode="numeric"for mobile numeric keyboard - First slot has
autocomplete="one-time-code"for autofill - Visible focus ring indicates current active slot
On This Page