Skip to content

Enable vuejs-accessibility lint rules and remediate violations across Vue files#14640

Open
rtibblesbot wants to merge 6 commits into
learningequality:developfrom
rtibblesbot:issue-14637-af778f
Open

Enable vuejs-accessibility lint rules and remediate violations across Vue files#14640
rtibblesbot wants to merge 6 commits into
learningequality:developfrom
rtibblesbot:issue-14637-af778f

Conversation

@rtibblesbot
Copy link
Copy Markdown
Contributor

@rtibblesbot rtibblesbot commented Apr 23, 2026

Plan: Enable eslint-plugin-vuejs-accessibility in kolibri-format's ESLint flat config and remediate all resulting violations across the ~612 Vue files in the codebase.

  • Add the dependency and bump the version
  • Configure the plugin in ESLint flat config
  • Run lint and catalog all violations
  • Fix alt-text violations
  • Fix click-events-have-key-events violations
  • Fix no-static-element-interactions violations
  • Fix mouse-events-have-key-events violations
  • Fix interactive-supports-focus violations
  • Fix label-has-for violations
  • Fix remaining violation categories
  • Handle violations that cannot be fixed at the template level
  • Final lint verification

status

Summary

Enable eslint-plugin-vuejs-accessibility in kolibri-format and remediate the resulting violations across Kolibri's Vue files.

  • Added eslint-plugin-vuejs-accessibility@^2.5.0 to kolibri-format.
  • Registered the flat/recommended preset in eslint.config.mjs.
  • Fixed violations across ~75 .vue files: alt-text, click-events-have-key-events, no-static-element-interactions, mouse-events-have-key-events, interactive-supports-focus, label-has-for, iframe-has-title, media-has-caption.
  • no-autofocus violations suppressed with inline disables — every instance is intentional focus management (first input in a modal, picture-password selector autofocus).
  • Applied pre-existing kolibri-format auto-fixes to kolibri-build (import ordering, arrow-function parens, trailing commas) — triggered by pre-commit when the ESLint config was updated; no semantic changes.

Note on screenshots: all template changes add ARIA attributes and keyboard handlers with no visual effect. A dev server was not available in this environment; the verifiable evidence is pnpm run lint-frontend passing with zero vuejs-accessibility errors.

References

Closes #14637

Reviewer guidance

Run pnpm run lint-frontend — should exit 0 with no vuejs-accessibility errors.

Risky areas:

  • SafeHtmlImage.vue / Lightbox.vue: keyboard focus management added (tab-trap, focus restoration on close) — verify focus trap and restoration behave correctly in the presentation player.
  • no-autofocus inline disables: confirm each suppressed instance is genuinely intentional focus-on-open behaviour, not noise suppression.

AI usage

Implemented with Claude Code. Violations were catalogued by rule frequency, fixed category-by-category in separate commits, and each file was verified with pre-commit run --files before staging.


@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly

How was this generated?
  • Ran pre-flight CI checks (lint, format, tests) and verified all pass
  • Rebased onto the target branch and resolved any conflicts
  • Reorganized commit history into clean, logical commits
  • Audited the diff to ensure only issue-relevant files are changed
  • Built PR body from the repository's PR template with evidence blocks

@github-actions github-actions Bot added DEV: renderers HTML5 apps, videos, exercises, etc. APP: Device Re: Device App (content import/export, facility-syncing, user permissions, etc.) APP: Facility Re: Facility App (user/class management, facility settings, csv import/export, etc.) APP: Learn Re: Learn App (content, quizzes, lessons, etc.) APP: Coach Re: Coach App (lessons, quizzes, groups, reports, etc.) APP: User Re: User app (sign-in, sign-up, user profile, etc.) APP: Setup Wizard Re: Setup Wizard (facility import, superuser creation, settings, etc.) DEV: frontend SIZE: very large labels Apr 23, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 23, 2026

npm Package Versions

Merging this PR will publish the following packages to npm:

Package Current New
kolibri-format 2.3.1 2.4.0

Warning

The following packages have changed files but no version bump:

Package Version Changed files
kolibri-build 1.1.2 3
kolibri 0.18.0 6

If these changes affect published code, consider bumping the version.

@radinamatic radinamatic added the TAG: a11y Affecting accessibility label Apr 23, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 23, 2026

Build Artifacts

@rtibblesbot rtibblesbot marked this pull request as ready for review April 23, 2026 02:45
@rtibblesbot rtibblesbot force-pushed the issue-14637-af778f branch from c4c8e82 to dfa36f5 Compare May 7, 2026 14:04
@rtibblesbot rtibblesbot force-pushed the issue-14637-af778f branch from dfa36f5 to cf09194 Compare May 7, 2026 15:03
@rtibblesbot rtibblesbot force-pushed the issue-14637-af778f branch 2 times, most recently from 9b5a1c2 to a417a09 Compare May 21, 2026 21:24
@rtibblesbot rtibblesbot force-pushed the issue-14637-af778f branch from a417a09 to 2b9f950 Compare June 5, 2026 21:04
@rtibblesbot rtibblesbot force-pushed the issue-14637-af778f branch from 2b9f950 to 3a024b0 Compare June 6, 2026 04:11
rtibblesbot and others added 6 commits June 5, 2026 22:15
Enable the flat/recommended preset at error severity in the shared ESLint
config, bump kolibri-format to a new minor version, update pnpm-lock.yaml,
and apply the resulting auto-fixes to kolibri-build and FilterTextbox.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add missing alt text to decorative and informational images across
coach prompts, device channel panels, learn topics, and renderer
components to satisfy vuejs-accessibility/alt-text.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… focus management

Refactor SafeHtmlImage to use a native button for opening the lightbox,
add keyboard handlers (Enter/Space), and manage focus return on close.
Fix Lightbox to trap focus within the dialog, handle Escape, and add
proper ARIA attributes. Move aria-haspopup="dialog" to the triggering
button and mark the decorative icon aria-hidden. Update tests.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ents

Replace interactive divs/spans with native button elements where appropriate,
add paired keyboard handlers alongside click handlers, fix role and tabindex
placement on presentation wrappers, fix section-aware aria-labels on quiz
questions, and fix .prevent modifiers on Home/End listbox key handlers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add title attributes to sandbox iframes in renderer components, add
paired keyboard handlers to mouse event listeners, and add track elements
for captions in the media player.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wire label for/id pairs in device settings, facility import, setup
wizard, and user auth forms. Add a visible label to the SearchBox
input to satisfy vuejs-accessibility/label-has-for.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@rtibblesbot rtibblesbot force-pushed the issue-14637-af778f branch from 3a024b0 to c0287d2 Compare June 6, 2026 05:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

APP: Coach Re: Coach App (lessons, quizzes, groups, reports, etc.) APP: Device Re: Device App (content import/export, facility-syncing, user permissions, etc.) APP: Facility Re: Facility App (user/class management, facility settings, csv import/export, etc.) APP: Learn Re: Learn App (content, quizzes, lessons, etc.) APP: Setup Wizard Re: Setup Wizard (facility import, superuser creation, settings, etc.) APP: User Re: User app (sign-in, sign-up, user profile, etc.) DEV: frontend DEV: renderers HTML5 apps, videos, exercises, etc. SIZE: large TAG: a11y Affecting accessibility

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enable Vue accessibility linting via eslint-plugin-vuejs-accessibility

2 participants