Moving Towards Full WCAG 2.1 AA Accessibility Compliance for Frappe UI

Hi everyone,

Frappe UI has grown into an incredible, modern, Tailwind-based component library. However, as we build increasingly complex, JavaScript-heavy components (like Comboboxes, Dropdowns, and Dialogs), we sometimes inherently break native HTML accessibility unless we explicitly polyfill with ARIA attributes and keyboard event listeners.

To ensure applications built with Frappe UI are usable by everyone—including users relying on screen readers and keyboard navigation—I recently conducted a detailed accessibility audit of the repository against WCAG 2.1 AA standards.

I have mapped out exactly what needs to be fixed and have already opened tracking issues on GitHub for each major category. I’d love to hear your thoughts, gather feedback, and see who might be interested in collaborating on these improvements!

:bullseye: The Audit: Tracked Issues & What We Need

The audit highlights targeted improvements across Form Inputs, Focus Management, Keyboard Navigation, ARIA relationships, and Dynamic Live Regions. Here is the breakdown of the newly created issues where we need help:

1. Form Controls & Inputs

(Applies to: TextInput, Textarea, Checkbox, Switch, Select, Password, FormControl, InputLabeling)

  • The Gap: Visual labels and inputs sometimes lack strict association via for and id attributes. Error messages aren’t automatically announced by screen readers. Custom controls like Switch lack native semantic meaning.

  • The Fix: Auto-generate unique IDs in useId.ts and bind them strictly. Dynamically apply aria-invalid="true" and aria-errormessage on validation failures. Add proper role="switch" semantics.

2. Interactive Overlays & Modals

(Applies to: Dialog, Popover, Tooltip, CommandPalette)

  • The Gap: Keyboard focus isn’t always trapped inside open modals, and closing them doesn’t consistently return focus to the trigger. Tooltips don’t perfectly align with WCAG hover/persistence rules.

  • The Fix: Implement strict focus trapping and focus restoration for Dialog. Ensure all overlays are dismissible via the Escape key. Update Tooltip to be persistent and hoverable to meet WCAG 1.4.13.

3. Complex Selection & Navigation

(Applies to: Combobox, MultiSelect, Dropdown, Tabs, Sidebar, Tree)

  • The Gap: These are notoriously tricky. They require rigorous Arrow Key navigation and explicit ARIA parent-child relationships that are currently missing or incomplete.

  • The Fix: Strictly implement the W3C ARIA Combobox pattern (role="combobox", role="listbox", aria-activedescendant) for Combobox and MultiSelect. Add ArrowUp/ArrowDown navigation to Dropdowns. Implement roving tabindex for Tabs.

4. Feedback & Status Messages

(Applies to: Toast, Alert, Progress, CircularProgressBar)

  • The Gap: Toasts visually appear but aren’t programmatically announced to screen readers. Progress bars lack value semantics.

  • The Fix: Wrap toasts in an aria-live="polite" or aria-live="assertive" region. Apply role="alert" or role="status" to Alerts. Add role="progressbar" to progress indicators.

5. Global Design System & Utilities

(Applies to: Icons, Button, Tailwind Configuration)

  • The Gap: Icon-only buttons often lack accessible names. Focus outlines are sometimes disabled. Some secondary text colors fail the 4.5:1 contrast ratio.

  • The Fix: Globally implement focus-visible rings for all interactive elements—no more invisible tabbing! Enforce aria-label on icon-only buttons. Apply aria-hidden="true" to SVG icons.

6. Automated Testing (CI/CD)

To ensure we don’t regress as the library grows, we need tooling.

  • The Fix: Integrate cypress-axe into our component testing (*.cy.ts) and consider eslint-plugin-vuejs-accessibility to catch missing labels and roles directly in our IDEs.

Let’s Build Together! :speech_balloon:

Tackling this all at once is a massive undertaking, which is why it is split into 6 distinct issues.

Are there specific components you feel should be prioritized? Jump into the GitHub issues linked above, grab one that you’re passionate about, and let’s start hacking!

Let’s make Frappe UI the most accessible Vue component library out there!

2 Likes