quasar icon indicating copy to clipboard operation
quasar copied to clipboard

QDate has buttons with inaccessible names

Open hennzen opened this issue 1 year ago • 2 comments
trafficstars

What happened?

Our app needs to comply with WCAG guidelines, which is why we plan to integrate automated checks into our build pipeline as a first stop, prior to manual checks. We strive to reduce the amount of (sometimes non-critical or even purely technical as per specs) errors reported by Lighthouse et al., so that the important errors stay visible.

Currently, QDate's buttons to flip between months or years (chevron-left/-right) as well as the "today" button cause an error "Buttons do not have an accessible name" (Lighthouse) resp. "Buttons must have discernible text" (AxeDevTools).

I think it's important to note that this a11y issue might not be mission critical, if we only use the QDate in conjunction with QInput. Impaired users can always use the QInput then. That's our case, mostly, but we also display the QDate as a widget here and there, i.e. without QInput. So then it becomes important again.

What did you expect to happen?

The button elements should be using ARIA labels such as aria-label="[previous|next] [month|year]" or aria-label="today".

Reproduction URL

https://codepen.io/hennzen/pen/YzBmOVg

How to reproduce?

  1. Go to the provided CodePen
  2. Open DevTools to either use Lighthouse or AxeDevTools Tab
  3. Generate report

Flavour

Quasar CLI with Vite (@quasar/cli | @quasar/app-vite)

Areas

Components (quasar), Accessibility [a11y] (quasar)

Platforms/Browsers

Firefox, Chrome

Quasar info output

No response

Relevant log output

No response

Additional context

No response

hennzen avatar Dec 18 '23 17:12 hennzen

I know the problem (this one and the QTable navigation buttons one). The problem is that it needs lots of translations (all things should have i18n)

pdanpdan avatar Dec 18 '23 23:12 pdanpdan

To solve this, I ended up creating a patch patches/quasar+2.16.4.patch with patch-package, and while I was at it, also added a tooltip with custom class to the today button:

--- a/node_modules/quasar/src/components/date/QDate.js
+++ b/node_modules/quasar/src/components/date/QDate.js
@@ -1,6 +1,7 @@
 import { h, ref, computed, watch, Transition, nextTick, getCurrentInstance } from 'vue'
 
 import QBtn from '../btn/QBtn.js'
+import QTooltip from '../tooltip/QTooltip.js'
 
 import useDark, { useDarkProps } from '../../composables/private.use-dark/use-dark.js'
 import useRenderCache from '../../composables/use-render-cache/use-render-cache.js'
@@ -1131,13 +1132,21 @@ export default createComponent({
 
           props.todayBtn === true ? h(QBtn, {
             class: 'q-date__header-today self-start',
+            ariaLabel: 'today',
             icon: $q.iconSet.datetime.today,
             flat: true,
             size: 'sm',
             round: true,
             tabindex: tabindex.value,
             onClick: setToday
-          }) : null
+          }, () => h(QTooltip, {
+              class: 'ui-tooltip',
+              transitionShow: 'scale',
+              transitionHide: 'scale',
+              delay: 500,
+              hideDelay: 200,
+              anchor: 'top middle',
+              self: 'center middle' }, () => 'today')) : null
         ])
       ])
     }
@@ -1155,6 +1164,7 @@ export default createComponent({
             icon: dateArrow.value[ 0 ],
             tabindex: tabindex.value,
             disable: boundaries.prev === false,
+            ariaLabel: `${ type === 'Months' ? 'previous month' : 'previous year' }`,
             ...getCache('go-#' + type, { onClick () { goTo(-1) } })
           })
         ]),
@@ -1187,6 +1197,7 @@ export default createComponent({
             icon: dateArrow.value[ 1 ],
             tabindex: tabindex.value,
             disable: boundaries.next === false,
+            ariaLabel: `${ type === 'Months' ? 'next month' : 'next year' }`,
             ...getCache('go+#' + type, { onClick () { goTo(1) } })
           })
         ])

The patch applies to node_modules/quasar/src/components/date/QDate.js, and in order to make this work, the parent component needs an explicit import

import { QDate } from '../../../node_modules/quasar/src/components/date'

This took me some time to figure out, because a import { QDate } from 'quasar' is directed to the module's dist directory, which of course stays unaffected.

Can anyone think of a better approach, say JSProxy or something?

I would always try to avoid the extra maintenance of having patches in a project, but then again, this patch is clearly arranged enough (only added lines) to cause no headache.

hennzen avatar Jun 05 '24 09:06 hennzen