From 3f92cd4b689e437bb9efe6a9fe873501ddf76bf2 Mon Sep 17 00:00:00 2001 From: Cam McHenry Date: Wed, 28 Aug 2024 04:55:25 -0400 Subject: [PATCH] Add `prefer-action-list-item-onselect` (#211) * Add rule * Add tests * Add rule to recommended config * Add autofixer * Add docs * Add changeset * Fix typo * Use replaceText instead of replaceTextRange --------- Co-authored-by: Ian Sanders --- .changeset/sixty-spiders-build.md | 5 ++ .../rules/prefer-action-list-item-onselect.md | 37 ++++++++++ src/configs/recommended.js | 1 + src/index.js | 1 + .../prefer-action-list-item-onselect.test.js | 67 +++++++++++++++++++ src/rules/prefer-action-list-item-onselect.js | 67 +++++++++++++++++++ 6 files changed, 178 insertions(+) create mode 100644 .changeset/sixty-spiders-build.md create mode 100644 docs/rules/prefer-action-list-item-onselect.md create mode 100644 src/rules/__tests__/prefer-action-list-item-onselect.test.js create mode 100644 src/rules/prefer-action-list-item-onselect.js diff --git a/.changeset/sixty-spiders-build.md b/.changeset/sixty-spiders-build.md new file mode 100644 index 0000000..5bedea5 --- /dev/null +++ b/.changeset/sixty-spiders-build.md @@ -0,0 +1,5 @@ +--- +'eslint-plugin-primer-react': major +--- + +[Breaking] Adds `prefer-action-list-item-onselect` lint rule and enables it by default. This may raise new auto-fixable lint errors or type-checking errors in existing codebases. diff --git a/docs/rules/prefer-action-list-item-onselect.md b/docs/rules/prefer-action-list-item-onselect.md new file mode 100644 index 0000000..a280475 --- /dev/null +++ b/docs/rules/prefer-action-list-item-onselect.md @@ -0,0 +1,37 @@ +# Prefer using `onSelect` instead of `onClick` for `ActionList.Item` components (`prefer-action-list-item-onselect`) + +🔧 The `--fix` option on the [ESLint CLI](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +## Rule details + +When using the `onClick` attribute on `ActionList.Item` components, this callback only fires when a user clicks on the element with a mouse. If the user navigates to the element with a keyboard and presses the `Enter` key, the callback will not fire. This produces an inaccessible experience for keyboard users. + +Using `onSelect` will lead to a more accessible experience for keyboard users compared to using `onClick`. + +This rule is generally auto-fixable, though you may encounter type checking errors that result from not properly handling keyboard events which are not part of the `onSelect` callback signature. + +👎 Examples of **incorrect** code for this rule: + +```jsx + + { + event.preventDefault() + handleClick() + }} +/> +``` + +👍 Examples of **correct** code for this rule: + +```jsx + + { + event.preventDefault() + handleClick() + }} +/> +``` diff --git a/src/configs/recommended.js b/src/configs/recommended.js index b7cc948..3bb02d2 100644 --- a/src/configs/recommended.js +++ b/src/configs/recommended.js @@ -19,6 +19,7 @@ module.exports = { 'primer-react/a11y-remove-disable-tooltip': 'error', 'primer-react/a11y-use-next-tooltip': 'error', 'primer-react/no-unnecessary-components': 'error', + 'primer-react/prefer-action-list-item-onselect': 'error', }, settings: { github: { diff --git a/src/index.js b/src/index.js index 5e4a328..9d5e7aa 100644 --- a/src/index.js +++ b/src/index.js @@ -12,6 +12,7 @@ module.exports = { 'a11y-use-next-tooltip': require('./rules/a11y-use-next-tooltip'), 'use-deprecated-from-deprecated': require('./rules/use-deprecated-from-deprecated'), 'primer-react/no-unnecessary-components': require('./rules/no-unnecessary-components'), + 'primer-react/prefer-action-list-item-onselect': require('./rules/prefer-action-list-item-onselect'), }, configs: { recommended: require('./configs/recommended'), diff --git a/src/rules/__tests__/prefer-action-list-item-onselect.test.js b/src/rules/__tests__/prefer-action-list-item-onselect.test.js new file mode 100644 index 0000000..4e8a8c9 --- /dev/null +++ b/src/rules/__tests__/prefer-action-list-item-onselect.test.js @@ -0,0 +1,67 @@ +const {RuleTester} = require('@typescript-eslint/rule-tester') +const rule = require('../prefer-action-list-item-onselect') + +const ruleTester = new RuleTester({ + parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { + ecmaVersion: 2018, + sourceType: 'module', + ecmaFeatures: { + jsx: true, + }, + }, +}) + +ruleTester.run('prefer-action-list-item-onselect', rule, { + valid: [ + {code: ` console.log(1)} />`}, + {code: ` console.log(1)} onClick={() => console.log(1)} />`}, + {code: ` console.log(1)} />`}, + {code: `