# Input OTP Primitive

Input OTP is a Starwind Runtime primitive in the form-value-control contract family.
Astro and React share one semantic component API. React coordinates reactive state through controlled and default props plus callbacks. Astro renders initial state and coordinates later changes through DOM events and Runtime methods. Raw HTML uses Runtime attributes, DOM events, and imperative methods.
## Anatomy
### Astro
Use the Astro primitive adapter to render InputOtp anatomy with the Runtime wiring included.
```astro
---
import { InputOtp } from "@starwind-ui/astro/input-otp";
---

<InputOtp.Root>
  <InputOtp.Group>
    <InputOtp.Slot index={0} />
    <InputOtp.Separator />
    <InputOtp.Slot index={1} />
  </InputOtp.Group>
</InputOtp.Root>
```

### React
Use the React primitive adapter when InputOtp state participates in React rendering.
```tsx
import { InputOtp } from "@starwind-ui/react/input-otp";

export function Example() {
  return (
    <InputOtp.Root>
      <InputOtp.Group>
        <InputOtp.Slot index={0} />
        <InputOtp.Separator />
        <InputOtp.Slot index={1} />
      </InputOtp.Group>
    </InputOtp.Root>
  );
}
```

### HTML
Render the InputOtp data-sw-* contract yourself, then initialize createInputOtp.
```html
<div data-sw-input-otp>
  <input data-sw-input-otp-input autocomplete="one-time-code" class="sr-only" tabindex="-1" />
  <div data-sw-input-otp-group>
    <div data-sw-input-otp-slot data-index="0">
      <span data-sw-input-otp-char></span>
      <div data-sw-input-otp-caret class="pointer-events-none absolute inset-0 hidden items-center justify-center" hidden></div>
    </div>
    <div data-sw-input-otp-separator role="separator" aria-hidden="true"></div>
    <div data-sw-input-otp-slot data-index="1">
      <span data-sw-input-otp-char></span>
      <div data-sw-input-otp-caret class="pointer-events-none absolute inset-0 hidden items-center justify-center" hidden></div>
    </div>
  </div>
</div>

<script type="module">
  import { createInputOtp } from "@starwind-ui/runtime/input-otp";

  const root = document.querySelector("[data-sw-input-otp]");
  if (root) {
    createInputOtp(root);
  }
</script>
```

### Vue
Use the Vue 3.5 beta adapter to render InputOtp anatomy.
```vue
<script setup lang="ts">
import InputOtp from "@starwind-ui/vue/input-otp";
</script>

<template>
  <InputOtp.Root>
    <InputOtp.Group>
      <InputOtp.Slot :index="0" />
      <InputOtp.Separator />
      <InputOtp.Slot :index="1" />
    </InputOtp.Group>
  </InputOtp.Root>
</template>
```
## API Reference
### Root
The main element that owns the Input OTP Runtime instance.
| Fact | Value |
| --- | --- |
| Default element | `div` |
| Discovery hook | `data-sw-input-otp` |
| Role | - |
#### Props
| Prop | Type | Default | Kind | Description | Framework Behavior |
| --- | --- | --- | --- | --- | --- |
| value | `string` | - | control | Controls the current Input OTP value. | **React:** Use value for controlled state and defaultValue for default state, and onValueChange for change proposals.<br>**Astro:** Use value or defaultValue for initial state, listen for starwind:value-change, and call setValue for later updates.<br>**Runtime / HTML:** Use data-value for initial state, listen for starwind:value-change, and call setValue for later updates. |
| defaultValue | `string` | - | control | Sets the initial Input OTP value for uncontrolled usage. | **React:** Use value for controlled state and defaultValue for default state, and onValueChange for change proposals.<br>**Astro:** Use value or defaultValue for initial state, listen for starwind:value-change, and call setValue for later updates.<br>**Runtime / HTML:** Use data-value for initial state, listen for starwind:value-change, and call setValue for later updates. |
| disabled | `boolean` | false | option | Disables the Root part. | - |
| form | `string` | - | option | Associates the control with a form element. | - |
| id | `string` | - | option | Sets the id used by the associated native control. | - |
| maxLength | `number` | 6 | option | Configures the max length option for the Root part. | - |
| name | `string` | - | option | Sets the submitted form field name. | - |
| pattern | `RegExp \| string` | - | option | Configures the pattern option for the Root part. | - |
| readOnly | `boolean` | false | option | Marks the control as read-only. | - |
| required | `boolean` | false | option | Marks the form control as required. | - |
| onValueChange | `(value: string, details: InputOtpValueChangeDetails) => void` | - | callback | Runs when the Input OTP value changes. | **React:** Use value for controlled state and defaultValue for default state, and onValueChange for change proposals.<br>**Astro:** Use value or defaultValue for initial state, listen for starwind:value-change, and call setValue for later updates.<br>**Runtime / HTML:** Use data-value for initial state, listen for starwind:value-change, and call setValue for later updates. |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-input-otp` | runtime | - | Marks the Root part so Starwind Runtime can find it. |
| `data-default-value` | prop | - | Reflects the default value prop on the Root part. |
| `data-disabled` | prop | - | Reflects the disabled prop on the Root part. |
| `data-form` | prop | - | Reflects the form prop on the Root part. |
| `data-id` | prop | - | Reflects the id prop on the Root part. |
| `data-max-length` | prop | - | Reflects the max length prop on the Root part. |
| `data-name` | prop | - | Reflects the name prop on the Root part. |
| `data-pattern` | prop | - | Reflects the pattern prop on the Root part. |
| `data-readonly` | prop | - | Reflects the readonly prop on the Root part. |
| `data-required` | prop | - | Reflects the required prop on the Root part. |
| `data-value` | state | - | Reflects the value state on the Root part. |
#### State
| State | Value Type | Controlled Prop | Default Prop | Initial Attribute | Runtime Getter | Runtime Setter | Description | State Control Support |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| value | `string` | value | defaultValue | `data-value` | `getValue` | `setValue` | Tracks the current Input OTP value. | **React:** Use value for controlled state and defaultValue for default state, and onValueChange for change proposals.<br>**Astro:** Use value or defaultValue for initial state, listen for starwind:value-change, and call setValue for later updates.<br>**Runtime / HTML:** Use data-value for initial state, listen for starwind:value-change, and call setValue for later updates. |
#### Events
| Event | Callback | DOM Event | Value | Details | Timing | Cancelable | Description | Cancellation Sequence |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| valueChange | onValueChange | starwind:value-change | value: `string` | InputOtpValueChangeDetails | before-state-commit | Yes | Fires when the value changes for Input OTP. | 1. Check internal eligibility and intent.<br>2. Create one details object for the proposal.<br>3. Call the Runtime callback with the details object when the controller exposes one.<br>4. Dispatch the cancelable DOM event with the same details object, including when the callback canceled it.<br>5. Read details.isCanceled, including cancellation caused by preventDefault().<br>6. Apply the accepted state.<br>7. Notify Runtime subscribers and other accepted-only observers. |
#### Runtime Setters
| Method | Target | Options | Suppresses Emit | Description |
| --- | --- | --- | --- | --- |
| `setValue` | state: value | emit: false | Yes | Updates the current Input OTP value from Runtime code. |
| `setDisabled` | prop: disabled | - | No | Updates whether Input OTP is disabled from Runtime code. |
| `setFormOptions` | props: form, id, name, required | - | No | Updates Input OTP form-related options from Runtime code. |
#### Refs
| Part | Public |
| --- | --- |
| root | Yes |
#### Initial Markup
| Attributes | Reason |
| --- | --- |
| `data-sw-input-otp`, `data-default-value`, `data-disabled`, `data-form`, `data-id`, `data-max-length`, `data-name`, `data-pattern`, `data-readonly`, `data-required`, `data-value`, `aria-disabled`, `tabindex` | The focusable root needs initial value, disabled, form, pattern, and range metadata before runtime hydration. |
#### Form
| Fact | Value |
| --- | --- |
| Form props | form, id, name, required, value |
| Hidden input | input (text) |

### Input
The native input synchronized by Input OTP.
| Fact | Value |
| --- | --- |
| Default element | `input` |
| Discovery hook | `data-sw-input-otp-input` |
| Role | - |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-input-otp-input` | runtime | - | Marks the Input part so Starwind Runtime can find it. |
#### Initial Markup
| Attributes | Reason |
| --- | --- |
| `data-sw-input-otp-input`, `autocomplete`, `class`, `form`, `id`, `inputmode`, `maxlength`, `name`, `readonly`, `required`, `tabindex`, `value` | The native one-time-code input must participate in forms and mobile OTP affordances before hydration. |
#### Form
| Fact | Value |
| --- | --- |
| Form props | form, id, name, required, value |
| Hidden input | input (text) |

### Group
Groups related Input OTP items.
| Fact | Value |
| --- | --- |
| Default element | `div` |
| Discovery hook | `data-sw-input-otp-group` |
| Role | - |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-input-otp-group` | runtime | - | Marks the Group part so Starwind Runtime can find it. |
#### Refs
| Part | Public |
| --- | --- |
| group | Yes |

### Slot
A character slot inside Input OTP.
| Fact | Value |
| --- | --- |
| Default element | `div` |
| Discovery hook | `data-sw-input-otp-slot` |
| Role | - |
#### Props
| Prop | Type | Default | Kind | Description | Framework Behavior |
| --- | --- | --- | --- | --- | --- |
| index | `number` | - | option | Configures the index option for the Slot part. | - |
| caret | `React.ReactNode` | - | rendering | Changes how the Slot part is rendered. | - |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-input-otp-slot` | runtime | - | Marks the Slot part so Starwind Runtime can find it. |
| `data-index` | prop | - | Reflects the index prop on the Slot part. |
#### Refs
| Part | Public |
| --- | --- |
| slot | Yes |
#### Initial Markup
| Attributes | Reason |
| --- | --- |
| `data-sw-input-otp-slot`, `data-index` | Slots need stable indices before the runtime writes characters and active state. |

### Slot Char
The visible character rendered in a Input OTP slot.
| Fact | Value |
| --- | --- |
| Default element | `span` |
| Discovery hook | `data-sw-input-otp-char` |
| Role | - |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-input-otp-char` | runtime | - | Marks the Slot Char part so Starwind Runtime can find it. |

### Slot Caret
The caret shown inside the active Input OTP slot.
| Fact | Value |
| --- | --- |
| Default element | `div` |
| Discovery hook | `data-sw-input-otp-caret` |
| Role | - |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-input-otp-caret` | runtime | - | Marks the Slot Caret part so Starwind Runtime can find it. |
#### Initial Markup
| Attributes | Reason |
| --- | --- |
| `data-sw-input-otp-caret`, `class`, `hidden` | Carets start hidden until the runtime marks the active empty slot. |

### Separator
Separates groups of Input OTP items.
| Fact | Value |
| --- | --- |
| Default element | `div` |
| Discovery hook | `data-sw-input-otp-separator` |
| Role | `separator` |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-input-otp-separator` | runtime | - | Marks the Separator part so Starwind Runtime can find it. |
#### Refs
| Part | Public |
| --- | --- |
| separator | Yes |
#### Initial Markup
| Attributes | Reason |
| --- | --- |
| `data-sw-input-otp-separator`, `aria-hidden`, `role` | Separators are presentation-only between slot groups. |
## Runtime API
| Fact | Value |
| --- | --- |
| Factory | [`createInputOtp`](/docs/runtime/#create-input-otp) |
| Import | `@starwind-ui/runtime/input-otp` |
| Root part | root |
| Option props | defaultValue, disabled, form, id, maxLength, name, onValueChange, pattern, readOnly, required, value |
| Option lifecycles | defaultValue: constructor-only, disabled: setter-backed, form: setter-backed, id: setter-backed, maxLength: refresh-required, name: setter-backed, onValueChange: constructor-only, pattern: constructor-only, readOnly: constructor-only, required: setter-backed, value: setter-backed |
## Form Participation
| Fact | Value |
| --- | --- |
| Form props | form, id, name, required, value |
| Hidden input | input (text) |
| Field integration | Yes |
## Related Styled Components
| Component | Relationship |
| --- | --- |
| [Input Otp](/docs/components/input-otp/) | Direct Primitive |
## Exports
| Group | Import | Exports |
| --- | --- | --- |
| Runtime | `@starwind-ui/runtime/input-otp` | `createInputOtp` |
| Astro Primitive | `@starwind-ui/astro/input-otp` | `InputOtp`, `InputOtpRoot`, `InputOtpGroup`, `InputOtpSlot`, `InputOtpSeparator` |
| React Primitive | `@starwind-ui/react/input-otp` | `InputOtp`, `InputOtpRoot`, `InputOtpGroup`, `InputOtpSlot`, `InputOtpSeparator` |
## Canonical Names
| Kind | Name |
| --- | --- |
| namespace | `InputOtp` |
| runtime-factory | `createInputOtp` |
| part | `InputOtp.Root` |
| part | `InputOtp.Group` |
| part | `InputOtp.Slot` |
| part | `InputOtp.Separator` |
## Changelog
### v1.0.0
- Promoted this Primitive's vendoring version to the stable 1.0.0 baseline. Its existing API and Runtime behavior carry forward from the previous release.
### v0.1.1
- Marked generated React Primitive files as client modules so vendored installs preserve client boundaries in React server frameworks.
- Kept generated React state-change callbacks and DOM events cancelable until the Runtime accepts the proposed state, then synchronized rendered state.
### v0.1.0
- Introduced segmented value state, keyboard and paste handling, form participation, and value-change events.