import js from '@eslint/js' import globals from 'globals' import reactHooks from 'eslint-plugin-react-hooks' import reactRefresh from 'eslint-plugin-react-refresh' import jsxA11y from 'eslint-plugin-jsx-a11y' import { defineConfig, globalIgnores } from 'eslint/config' // ── Lint config (S14) ────────────────────────────────────────────────────── // // On top of the React/hooks defaults, jsx-a11y catches the common // accessibility gaps that creep into icon-button-heavy UIs like this one: // missing aria-labels on bare-icon buttons, alt-less , click-only // affordances on non-interactive elements, etc. // // We use jsxA11y's `recommended` ruleset rather than `strict` because // strict adds rules (no-onchange, click-events-have-key-events) that // produce a high false-positive rate on existing controlled-component // code without meaningfully improving accessibility. The recommended set // is the consensus minimum for production React apps. export default defineConfig([ globalIgnores(['dist']), { files: ['src/**/*.{js,jsx}'], extends: [ js.configs.recommended, reactHooks.configs.flat.recommended, reactRefresh.configs.vite, jsxA11y.flatConfigs.recommended, ], languageOptions: { ecmaVersion: 2020, globals: globals.browser, parserOptions: { ecmaVersion: 'latest', ecmaFeatures: { jsx: true }, sourceType: 'module', }, }, rules: { 'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]', argsIgnorePattern: '^_' }], // jsx-a11y tweaks for this codebase ───────────────────────────────── // // The codebase has several `onClick` handlers on Konva-rendered // shapes (Group, Rect) that don't have a corresponding key handler // because they're inside a and don't take keyboard focus. // jsx-a11y can't tell that those are Konva nodes, not DOM, so we // disable the click-events-have-key-events rule globally rather // than littering eslint-disable comments through canvas code. 'jsx-a11y/click-events-have-key-events': 'off', 'jsx-a11y/no-noninteractive-element-interactions': 'off', 'jsx-a11y/no-static-element-interactions': 'off', // The label-has-associated-control rule fires on labels that wrap // a custom picker (the swatch grid in // TextTab uses `