Skip to content

[Accessibility] ui5-input / ui5-date-picker do not expose aria-readonly; read-only state is not conveyed to AT #13995

Description

@zhangliangyi

Bug Description

Summary

The inner <input> rendered by Input sets the native HTML readonly attribute but never aria-readonly. On a bare textbox that would suffice, but Input/DatePicker decorate the same element with composite-widget semantics (role, aria-haspopup, aria-roledescription), and in that context screen readers (verified JAWS/NVDA, de-DE) announce the role/popup but drop the read-only state.

Select renders aria-readonly explicitly and is announced correctly, so on the same read-only form ui5-select reads as read-only while ui5-date-picker does not.

Steps to reproduce

<ui5-select readonly>              <!-- state announced (has aria-readonly) -->
  <ui5-option selected>Personal goals</ui5-option>
</ui5-select>
<ui5-date-picker readonly value="2026-01-01"></ui5-date-picker>  <!-- NOT announced -->
<ui5-input readonly value="hello"></ui5-input>                    <!-- NOT announced -->

Navigate with a screen reader; inspect the shadow inner <input>: readonly present, aria-readonly absent.

Observed (de-DE): ui5-select"… Listenfeld … Die Auswahl ändern Sie mit den Pfeiltasten" ✅; ui5-date-picker"Datumseingabe · Hat Popup · …", no read-only state ❌.

Expected

Read-only ui5-input/ui5-date-picker expose aria-readonly="true" on the focusable inner input, consistent with ui5-select.

Root cause (@ui5/webcomponents@2.26.0)

src/InputTemplate.tsx (inner <input>) sets native readonly but none of its 9 aria-* attributes is aria-readonly:

readonly={this._readonly}                              // line 35 — native attr only
aria-haspopup={this.accInfo.ariaHasPopup}              // line 44
aria-roledescription={this.accInfo.ariaRoledescription}// line 46
aria-required={this.required}                          // line 50
// no aria-readonly

Input.accInfo / DatePicker.accInfo expose no read-only key, so there is nothing to bind (DatePicker even adds aria-haspopup="grid" — the semantics that suppress the native readonly announcement). The signal exists but is used only for behavior: get _readonly() { return this.readonly && !this.disabled; }.

Contrast — src/SelectTemplate.tsx: role="combobox" (line 30) + aria-readonly={this.readonly} (line 38).

Emitter matrix (grep -l aria-readonly dist/*Template.js): CheckBox, MonthPicker, RatingIndicator, Select, Switch, Tokenizer, YearPicker, YearRangePicker emit it; Input and DatePicker (and all Input-based controls: DateTimePicker, DateRangePicker, ComboBox, MultiInput, …) emit 0.

Identical in 2.25.0 and current latest 2.26.0 — not fixed by upgrade.

Suggested fix

Emit aria-readonly from Input so all Input-derived components inherit it:

  1. Add "ariaReadonly": this._readonly || undefined to Input.accInfo (and DatePicker.accInfo if overridden).
  2. Bind aria-readonly={this.accInfo.ariaReadonly} on the inner input in InputTemplate.tsx.

Environment

@ui5/webcomponents 2.25.0 & 2.26.0 · Chromium/Edge · Windows · JAWS/NVDA de-DE · affects ui5-input, ui5-date-picker and other Input-based controls.

Organization

SF

  • I’m not disclosing any internal or sensitive information.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions