A11y OTP Field

Example 08 · Native semantics

Disabled and readonly

Compare two native non-editable states and see how the decorative slots follow the input instead of recreating state behavior.

Live example

Compare the focus behavior

Press Tab through the examples. The disabled field is unavailable; the readonly value can still receive focus and be selected.

Disabled

Disabled fields do not receive focus.

Readonly

Readonly fields remain focusable and readable.

Implementation

Build this example

Use separate component roots for the two fields, but keep exactly one native input inside each root. Apply the state to the input itself.

JavaScript

One initializer enhances both roots while preserving their native states.

import { initA11yOtpFields } from "./dist/index.js";

initA11yOtpFields();

HTML

The surrounding labels and hints are omitted here only to highlight the native state attributes.

<section>
  <h3>Disabled</h3>
  <div class="a11y-otp" data-a11y-otp
    data-otp-length="6" data-otp-type="numeric">
    <label for="disabled-code">Verification code</label>
    <div class="a11y-otp__control">
      <input class="a11y-otp__input" id="disabled-code"
        name="disabledCode" type="text" inputmode="numeric"
        maxlength="6" disabled value="123456" />
    </div>
  </div>
</section>

<section>
  <h3>Readonly</h3>
  <div class="a11y-otp" data-a11y-otp
    data-otp-length="6" data-otp-type="numeric">
    <label for="readonly-code">Verification code</label>
    <div class="a11y-otp__control">
      <input class="a11y-otp__input" id="readonly-code"
        name="readonlyCode" type="text" inputmode="numeric"
        maxlength="6" readonly value="012345" />
    </div>
  </div>
</section>