diff --git a/eslint-configs/eslint-config-seekingalpha-react/CHANGELOG.md b/eslint-configs/eslint-config-seekingalpha-react/CHANGELOG.md index 8789a28a..c5429e1a 100644 --- a/eslint-configs/eslint-config-seekingalpha-react/CHANGELOG.md +++ b/eslint-configs/eslint-config-seekingalpha-react/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## 10.27.0 - 2026-01-27 + +- [new] add sharable oxlint config with eslint-plugin-jsx-a11y and eslint-plugin-react-hooks rules + ## 10.26.0 - 2026-01-27 - [new] add sharable oxlint config with eslint-plugin-react rules diff --git a/eslint-configs/eslint-config-seekingalpha-react/oxc.js b/eslint-configs/eslint-config-seekingalpha-react/oxc.js index 9aac60e7..19099637 100644 --- a/eslint-configs/eslint-config-seekingalpha-react/oxc.js +++ b/eslint-configs/eslint-config-seekingalpha-react/oxc.js @@ -1,4 +1,6 @@ import { ESLintPluginReactDisabled } from './rules/eslint-plugin-react/oxlint-disabled.js'; +import { ESLintPluginA11YDisabled } from './rules/eslint-plugin-jsx-a11y/oxlint-disabled.js'; +import { ESLintPluginReactHooksDisabled } from './rules/eslint-plugin-react-hooks/oxlint-disabled.js'; import config from './index.js'; @@ -7,6 +9,8 @@ const oxcConfig = { rules: { ...config.rules, ...ESLintPluginReactDisabled, + ...ESLintPluginA11YDisabled, + ...ESLintPluginReactHooksDisabled, }, }; diff --git a/eslint-configs/eslint-config-seekingalpha-react/oxlint-config.json b/eslint-configs/eslint-config-seekingalpha-react/oxlint-config.json index a2054d57..f04d9945 100644 --- a/eslint-configs/eslint-config-seekingalpha-react/oxlint-config.json +++ b/eslint-configs/eslint-config-seekingalpha-react/oxlint-config.json @@ -1,4 +1,8 @@ { "$schema": "./node_modules/oxlint/configuration_schema.json", - "extends": ["./rules/eslint-plugin-react/oxlint-config.json"] + "extends": [ + "./rules/eslint-plugin-react/oxlint-config.json", + "./rules/eslint-plugin-a11y/oxlint-config.json", + "./rules/eslint-plugin-react-hooks/oxlint-config.json" + ] } diff --git a/eslint-configs/eslint-config-seekingalpha-react/package.json b/eslint-configs/eslint-config-seekingalpha-react/package.json index 085e9ec5..220f3354 100644 --- a/eslint-configs/eslint-config-seekingalpha-react/package.json +++ b/eslint-configs/eslint-config-seekingalpha-react/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-seekingalpha-react", - "version": "10.26.0", + "version": "10.27.0", "description": "SeekingAlpha's sharable React.js ESLint config", "main": "index.js", "type": "module", diff --git a/eslint-configs/eslint-config-seekingalpha-react/rules/eslint-plugin-jsx-a11y/index.js b/eslint-configs/eslint-config-seekingalpha-react/rules/eslint-plugin-jsx-a11y/index.js index 87d62df7..883669f8 100644 --- a/eslint-configs/eslint-config-seekingalpha-react/rules/eslint-plugin-jsx-a11y/index.js +++ b/eslint-configs/eslint-config-seekingalpha-react/rules/eslint-plugin-jsx-a11y/index.js @@ -17,6 +17,8 @@ export default { }, ], + 'anchor-ambiguous-text': 'off', + // https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/anchor-has-content.md 'jsx-a11y/anchor-has-content': [ 'error', @@ -268,5 +270,7 @@ export default { 'jsx-a11y/control-has-associated-label': 'error', 'jsx-a11y/prefer-tag-over-role': 'error', + + 'jsx-a11y/no-aria-hidden-on-focusable': 'off', }, }; diff --git a/eslint-configs/eslint-config-seekingalpha-react/rules/eslint-plugin-jsx-a11y/oxlint-config.json b/eslint-configs/eslint-config-seekingalpha-react/rules/eslint-plugin-jsx-a11y/oxlint-config.json new file mode 100644 index 00000000..631e2e63 --- /dev/null +++ b/eslint-configs/eslint-config-seekingalpha-react/rules/eslint-plugin-jsx-a11y/oxlint-config.json @@ -0,0 +1,116 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": ["jsx-a11y"], + "rules": { + "jsx-a11y/alt-text": [ + "error", + { + "elements": ["img", "object", "area", "input[type='image']"], + "img": [], + "object": [], + "area": [], + "input[type='image']": [] + } + ], + "anchor-ambiguous-text": "off", + "jsx-a11y/anchor-has-content": [ + "error", + { + "components": ["Anchor", "Link"] + } + ], + "jsx-a11y/anchor-is-valid": [ + "error", + { + "components": ["Anchor", "Link"], + "specialLink": ["to"], + "aspects": ["noHref", "invalidHref", "preferButton"] + } + ], + "jsx-a11y/aria-activedescendant-has-tabindex": "error", + "jsx-a11y/aria-props": "error", + "jsx-a11y/aria-proptypes": "error", + "jsx-a11y/aria-role": [ + "error", + { + "ignoreNonDom": false + } + ], + "jsx-a11y/aria-unsupported-elements": "error", + "jsx-a11y/autocomplete-valid": "error", + "jsx-a11y/click-events-have-key-events": "error", + "jsx-a11y/heading-has-content": [ + "error", + { + "components": [""] + } + ], + "jsx-a11y/html-has-lang": "error", + "jsx-a11y/iframe-has-title": "error", + "jsx-a11y/img-redundant-alt": "error", + "jsx-a11y/lang": "error", + "jsx-a11y/media-has-caption": [ + "error", + { + "audio": [], + "video": [], + "track": [] + } + ], + "jsx-a11y/mouse-events-have-key-events": "error", + "jsx-a11y/no-access-key": "error", + "jsx-a11y/no-aria-hidden-on-focusable": "off", + "jsx-a11y/no-autofocus": [ + "error", + { + "ignoreNonDOM": true + } + ], + "jsx-a11y/no-distracting-elements": [ + "error", + { + "elements": ["marquee", "blink"] + } + ], + "jsx-a11y/no-noninteractive-tabindex": [ + "error", + { + "tags": [], + "roles": ["tabpanel"] + } + ], + "jsx-a11y/no-redundant-roles": [ + "error", + { + "nav": ["navigation"] + } + ], + "jsx-a11y/no-static-element-interactions": [ + "error", + { + "handlers": [ + "onClick", + "onMouseDown", + "onKeyPress", + "onKeyDown", + "onKeyUp" + ] + } + ], + "jsx-a11y/role-has-required-aria-props": "error", + "jsx-a11y/role-supports-aria-props": "error", + "jsx-a11y/scope": "error", + "jsx-a11y/tabindex-no-positive": "error", + "jsx-a11y/label-has-associated-control": [ + "error", + { + "labelComponents": [], + "labelAttributes": [], + "controlComponents": [], + "assert": "both", + "depth": 10 + } + ], + "jsx-a11y/prefer-tag-over-role": "error" + } +} diff --git a/eslint-configs/eslint-config-seekingalpha-react/rules/eslint-plugin-jsx-a11y/oxlint-disabled.js b/eslint-configs/eslint-config-seekingalpha-react/rules/eslint-plugin-jsx-a11y/oxlint-disabled.js new file mode 100644 index 00000000..3f95742f --- /dev/null +++ b/eslint-configs/eslint-config-seekingalpha-react/rules/eslint-plugin-jsx-a11y/oxlint-disabled.js @@ -0,0 +1,33 @@ +export const ESLintPluginA11YDisabled = { + 'jsx-a11y/alt-text': 'off', + 'anchor-ambiguous-text': 'off', + 'jsx-a11y/anchor-has-content': 'off', + 'jsx-a11y/anchor-is-valid': 'off', + 'jsx-a11y/aria-activedescendant-has-tabindex': 'off', + 'jsx-a11y/aria-props': 'off', + 'jsx-a11y/aria-proptypes': 'off', + 'jsx-a11y/aria-role': 'off', + 'jsx-a11y/aria-unsupported-elements': 'off', + 'jsx-a11y/autocomplete-valid': 'off', + 'jsx-a11y/click-events-have-key-events': 'off', + 'jsx-a11y/heading-has-content': 'off', + 'jsx-a11y/html-has-lang': 'off', + 'jsx-a11y/iframe-has-title': 'off', + 'jsx-a11y/img-redundant-alt': 'off', + 'jsx-a11y/lang': 'off', + 'jsx-a11y/media-has-caption': 'off', + 'jsx-a11y/mouse-events-have-key-events': 'off', + 'jsx-a11y/no-access-key': 'off', + 'jsx-a11y/no-aria-hidden-on-focusable': 'off', + 'jsx-a11y/no-autofocus': 'off', + 'jsx-a11y/no-distracting-elements': 'off', + 'jsx-a11y/no-noninteractive-tabindex': 'off', + 'jsx-a11y/no-redundant-roles': 'off', + 'jsx-a11y/no-static-element-interactions': 'off', + 'jsx-a11y/role-has-required-aria-props': 'off', + 'jsx-a11y/role-supports-aria-props': 'off', + 'jsx-a11y/scope': 'off', + 'jsx-a11y/tabindex-no-positive': 'off', + 'jsx-a11y/label-has-associated-control': 'off', + 'jsx-a11y/prefer-tag-over-role': 'off', +}; diff --git a/eslint-configs/eslint-config-seekingalpha-react/rules/eslint-plugin-react-hooks/oxlint-config.json b/eslint-configs/eslint-config-seekingalpha-react/rules/eslint-plugin-react-hooks/oxlint-config.json new file mode 100644 index 00000000..a6e74bf6 --- /dev/null +++ b/eslint-configs/eslint-config-seekingalpha-react/rules/eslint-plugin-react-hooks/oxlint-config.json @@ -0,0 +1,8 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": ["react"], + "rules": { + "react-hooks/rules-of-hooks": "error", + "react-hooks/exhaustive-deps": "error" + } +} diff --git a/eslint-configs/eslint-config-seekingalpha-react/rules/eslint-plugin-react-hooks/oxlint-disabled.js b/eslint-configs/eslint-config-seekingalpha-react/rules/eslint-plugin-react-hooks/oxlint-disabled.js new file mode 100644 index 00000000..c20c2bad --- /dev/null +++ b/eslint-configs/eslint-config-seekingalpha-react/rules/eslint-plugin-react-hooks/oxlint-disabled.js @@ -0,0 +1,4 @@ +export const ESLintPluginReactHooksDisabled = { + 'react-hooks/rules-of-hooks': 'off', + 'react-hooks/exhaustive-deps': 'off', +}; diff --git a/package.json b/package.json index ed880e6e..b0345d46 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "seekingalpha-javascript-style", - "version": "9.83.0", + "version": "9.84.0", "description": "Set of linting rules, guides and best practices for best Javascript code", "main": "index.js", "type": "module",