From 82a741cfe384a9f61972e2c8a992d9d9437f5f29 Mon Sep 17 00:00:00 2001 From: Jens Hinrichs Date: Thu, 26 Feb 2026 16:34:36 +0100 Subject: [PATCH 01/14] feat(core): add eslint-plugin-jsx-a11y and fix accessibility violations - Add eslint-plugin-jsx-a11y with recommended rules to ESLint config - Fix cat-select: add tabIndex, aria-expanded, aria-controls, role="option", keyboard handlers - Fix cat-tag: add aria-expanded and aria-controls to combobox input - Fix cat-radio: remove incorrect role="radio" from label element - Fix cat-date-inline: remove redundant onClick from label (htmlFor handles focus) - Fix cat-input: add role="presentation" to wrapper div - Fix cat-i18n-registry: remove unused variable in catch block This enables static a11y linting as part of the standard lint workflow. --- core/eslint.config.js | 16 +- core/package.json | 1 + .../cat-date-inline/cat-date-inline.tsx | 2 +- .../components/cat-i18n/cat-i18n-registry.ts | 2 +- core/src/components/cat-input/cat-input.tsx | 1 + core/src/components/cat-radio/cat-radio.tsx | 2 - core/src/components/cat-select/cat-select.tsx | 8 +- core/src/components/cat-tag/cat-tag.tsx | 2 + pnpm-lock.yaml | 2202 ++++++++++++----- 9 files changed, 1605 insertions(+), 631 deletions(-) diff --git a/core/eslint.config.js b/core/eslint.config.js index f9db07965..66c5a45fd 100644 --- a/core/eslint.config.js +++ b/core/eslint.config.js @@ -4,6 +4,7 @@ const globals = require('globals'); const tsParser = require('@typescript-eslint/parser'); const typescriptEslint = require('@typescript-eslint/eslint-plugin'); const js = require('@eslint/js'); +const jsxA11y = require('eslint-plugin-jsx-a11y'); const { FlatCompat } = require('@eslint/eslintrc'); @@ -33,10 +34,11 @@ module.exports = defineConfig([ } }, - extends: compat.extends('eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'), + extends: compat.extends('eslint:recommended', 'plugin:@typescript-eslint/recommended', 'plugin:jsx-a11y/recommended', 'prettier'), plugins: { - '@typescript-eslint': typescriptEslint + '@typescript-eslint': typescriptEslint, + 'jsx-a11y': jsxA11y }, rules: { @@ -52,7 +54,15 @@ module.exports = defineConfig([ allowTernary: true, allowShortCircuit: true } - ] + ], + // A11y rules - adjusted for Stencil web components + 'jsx-a11y/click-events-have-key-events': 'warn', + 'jsx-a11y/no-static-element-interactions': 'warn', + 'jsx-a11y/no-noninteractive-tabindex': 'warn', + // Allow Stencil component patterns + 'jsx-a11y/anchor-is-valid': ['error', { + aspects: ['invalidHref'] + }] } }, { diff --git a/core/package.json b/core/package.json index 96f449519..123c3e845 100644 --- a/core/package.json +++ b/core/package.json @@ -71,6 +71,7 @@ "@typescript-eslint/parser": "8.52.0", "eslint": "9.39.2", "eslint-config-prettier": "9.1.2", + "eslint-plugin-jsx-a11y": "^6.10.0", "jest": "29.7.0", "jest-cli": "29.7.0", "prettier": "3.7.4", diff --git a/core/src/components/cat-date-inline/cat-date-inline.tsx b/core/src/components/cat-date-inline/cat-date-inline.tsx index 556db3a9e..4c1531877 100644 --- a/core/src/components/cat-date-inline/cat-date-inline.tsx +++ b/core/src/components/cat-date-inline/cat-date-inline.tsx @@ -244,7 +244,7 @@ export class CatDateInline {
{(this.hasSlottedLabel || this.label) && ( -