# Input OTP

One-time-code input with paste and SMS autofill support, no dependencies.

Group: Forms

## Import

```tsx
import { InputOTP } from "@indoku/ui"
```

## Examples

### Basic usage

```tsx
function InputOtpDemo() {
  const [otp, setOtp] = useState("")
  return (
    <Stack gap="4">
      <InputOTP.Root maxLength={6} value={otp} onChange={setOtp}>
        <InputOTP.Group>
          {[0, 1, 2].map((i) => (
            <InputOTP.Slot key={i} index={i} />
          ))}
        </InputOTP.Group>
        <InputOTP.Separator />
        <InputOTP.Group>
          {[3, 4, 5].map((i) => (
            <InputOTP.Slot key={i} index={i} />
          ))}
        </InputOTP.Group>
      </InputOTP.Root>
      <Text fontSize="xs" color="fg.muted">
        Value: {otp || "(kosong)"}
      </Text>
    </Stack>
  )
}
```

## Props

### Root

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `maxLength` * | `number` |  |  |
| `value` | `string` |  |  |
| `defaultValue` | `string` |  |  |
| `onChange` | `(value: string) => void` |  |  |
| `onComplete` | `(value: string) => void` |  | Called as soon as every slot is filled. |
| `pattern` | `RegExp` | `digits only` | Allowed characters (tested per character). Use `REGEXP_ONLY_DIGITS`, `REGEXP_ONLY_CHARS` or `REGEXP_ONLY_DIGITS_AND_CHARS`. |
| `disabled` | `boolean` |  |  |
| `invalid` | `boolean` |  |  |
| `inputMode` | `"numeric" \| "text" \| "tel" \| "decimal" \| "email" \| "search" \| "url" \| "none"` |  | Virtual keyboard hint. Defaults to `numeric` for the digits pattern, otherwise `text`. |
| `name` | `string` |  |  |
| `autoFocus` | `boolean` |  |  |

### Slot

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `index` * | `number` |  |  |

`*` = required. Style props and HTML attributes are accepted too.
