Skip to content

QDate: day buttons lack aria-label for screen readers #18254

@mstroeve

Description

@mstroeve

What happened?

QDate calendar day buttons only have label: day.i (the day number) with no aria-label. When a screen reader (VoiceOver/TalkBack) navigates the calendar, it only announces the number (e.g. "19") instead of the full date (e.g. "Wednesday 19 March").

This makes QDate unusable for blind users who cannot identify which date they are selecting.

What did you expect to happen?

Each day button should have an aria-label with the full localized date, e.g. "Wednesday 19 March" (or "woensdag 19 maart" in Dutch). This would use the already available innerLocale and viewModel data.

Why this should be fixed in Quasar (not userland)

  1. WCAG 2.1 Success Criterion 4.1.2 (Name, Role, Value) requires that interactive elements have an accessible name that describes their purpose. A bare number like "19" does not describe the purpose of a date selection button — "Wednesday 19 March" does. This is a Level A requirement (the minimum level of accessibility compliance).

  2. Every major datepicker already does this. Native iOS/Android date pickers, HTML <input type="date">, Material UI DatePicker, Vuetify, PrimeVue Calendar — all announce the full date on day cells. QDate is an outlier here.

  3. There is no userland workaround. QDate does not expose a slot or prop for individual day cells, so consumers cannot add aria-labels themselves. The only option is patch-package, which is fragile and version-dependent. (See also QDate: provide slot for individual days in month view #7076, open since 2020, requesting a day slot.)

  4. The fix is a single line using data already available in the render scope (viewModel, innerLocale). No new props, no breaking changes, no performance impact.

  5. Quasar's own i18n/locale system makes this trivial. The innerLocale.value.lang is already resolved — toLocaleDateString() with that locale produces the correct output in any language Quasar supports.

Reproduction URL

N/A — visible in source code: src/components/date/QDate.js line ~1251:

label: day.i,  // Only the day number, no aria-label

Suggested fix

Add an ariaLabel prop to the day QBtn with a localized full date:

ariaLabel: new Date(viewModel.value.year, viewModel.value.month - 1, day.i)
  .toLocaleDateString(innerLocale.value.lang, { weekday: 'long', day: 'numeric', month: 'long' }),

This uses the existing viewModel and innerLocale that are already available in the render scope. No new dependencies or props needed. Happy to submit a PR if this approach is accepted.

Quasar info

  • Quasar v2.18.6
  • Tested with VoiceOver on iOS 18 (Capacitor app) and Safari

Additional context

We maintain a mobile app used by teachers, including a blind teacher who needs to navigate the timetable calendar. We currently use patch-package to work around this issue but would love to see it fixed upstream.

Related: #7076 (slot for individual days) would also solve this, but a simple ariaLabel addition is much less invasive.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions