Assist_Design/docs/plans/2026-03-06-otp-input-redesign-design.md

77 lines
2.6 KiB
Markdown
Raw Normal View History

# OTP Input Redesign: Replace Custom with shadcn InputOTP
**Date**: 2026-03-06
**Status**: Approved
## Problem
The custom `OtpInput` component (`components/molecules/OtpInput/OtpInput.tsx`) has fundamental issues:
- `onComplete` never fired on typing due to a JS bug (`!string.includes("")` is always false)
- Manual focus management across 6 separate `<input>` elements is fragile
- No mobile SMS autofill support
- No password manager detection
- Edge cases around paste, backspace, and focus are hard to maintain
## Decision
Replace the custom implementation with `input-otp` via shadcn/ui's InputOTP component (Approach A).
## Architecture
```
input-otp (npm)
-> components/ui/input-otp.tsx (shadcn primitives)
-> components/molecules/OtpInput/OtpInput.tsx (wrapper, same API)
-> LoginOtpStep, OtpStep, VerificationStep (no changes)
```
## Component API (unchanged)
```ts
interface OtpInputProps {
length?: number; // default 6
value: string;
onChange: (value: string) => void;
onComplete?: (value: string) => void;
disabled?: boolean;
error?: string;
autoFocus?: boolean; // default true
}
```
## Visual Design
- Stripe-style grouped layout: two groups of 3 slots separated by a dash
- Slots: `border-border` default, `border-primary` + ring on active, `border-danger` on error
- `bg-card`, `text-foreground`, rounded corners on group edges
- Disabled: `opacity-50 cursor-not-allowed`
- Blinking caret animation
## What Changes
| File | Action |
| --------------------------------------------- | --------------------------------- |
| `package.json` | Add `input-otp` dependency |
| `components/ui/input-otp.tsx` | New — shadcn generated primitives |
| `components/molecules/OtpInput/OtpInput.tsx` | Rewrite internals, keep API |
| `LoginOtpStep`, `OtpStep`, `VerificationStep` | No changes |
## What Gets Deleted
- `useOtpHandlers` hook (focus, paste, keydown management)
- `getInputBorderClass` helper
- All 6 individual `<input>` elements
## Error Handling
Consumer-level error handling (already implemented this session) remains unchanged:
- LoginOtpStep: catches errors, clears input, clears error on typing via `onClearError`
- OtpStep: catches errors, clears input, clears error on typing via `clearOtpError`
- VerificationStep: syncs machine error to local state, clears input and error on typing
## shadcn CLI Note
Generated file imports `cn` from `@/lib/utils`. Project has `cn` at `@/shared/utils`. Fix the import in the generated file after running the CLI.