@elastic/eslint-plugin-eui 2.11.1 → 2.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -0
- package/lib/cjs/index.js +3 -0
- package/lib/cjs/rules/prefer_tooltip_trigger_focus_test_utility.d.ts +3 -0
- package/lib/cjs/rules/prefer_tooltip_trigger_focus_test_utility.d.ts.map +1 -0
- package/lib/cjs/rules/prefer_tooltip_trigger_focus_test_utility.js +80 -0
- package/lib/esm/index.js +4 -1
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/rules/prefer_tooltip_trigger_focus_test_utility.d.ts +2 -0
- package/lib/esm/rules/prefer_tooltip_trigger_focus_test_utility.js +93 -0
- package/lib/esm/rules/prefer_tooltip_trigger_focus_test_utility.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -182,6 +182,24 @@ Ensure the `EuiIcon` includes appropriate accessibility attributes.
|
|
|
182
182
|
- `EuiIcon` has an accessible name via `title`, `aria-label`, or `aria-labelledby`; otherwise mark it decorative with `aria-hidden={true}`
|
|
183
183
|
- Do not combine `tabIndex` with `aria-hidden`
|
|
184
184
|
|
|
185
|
+
### `@elastic/eui/prefer-tooltip-trigger-focus-test-utility`
|
|
186
|
+
|
|
187
|
+
Flags `fireEvent.focus()` inside `it`/`test` blocks that also query for a tooltip element (`getByRole('tooltip')`, `queryByRole('tooltip')`, `findByRole('tooltip')` or any selector containing `euiToolTip`). Plain `fireEvent.focus` does not simulate `:focus-visible` in jsdom and will not trigger `EuiToolTip`, so tooltip focus tests will silently pass without actually showing the tooltip.
|
|
188
|
+
|
|
189
|
+
Use `focusEuiToolTipTrigger` from EUI's RTL test utilities instead, which correctly mocks `:focus-visible` before firing the focus event:
|
|
190
|
+
|
|
191
|
+
```tsx
|
|
192
|
+
import { focusEuiToolTipTrigger } from '@elastic/eui/test/rtl';
|
|
193
|
+
|
|
194
|
+
it('shows tooltip on focus', async () => {
|
|
195
|
+
const { getByRole } = render(<MyComponent />);
|
|
196
|
+
const cleanup = focusEuiToolTipTrigger(getByRole('button'));
|
|
197
|
+
expect(getByRole('tooltip')).toBeInTheDocument();
|
|
198
|
+
cleanup();
|
|
199
|
+
});
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
|
|
185
203
|
## Testing
|
|
186
204
|
|
|
187
205
|
### Running unit tests
|
package/lib/cjs/index.js
CHANGED
|
@@ -14,6 +14,7 @@ var _require_aria_label_for_modals = require("./rules/a11y/require_aria_label_fo
|
|
|
14
14
|
var _require_table_caption = require("./rules/a11y/require_table_caption");
|
|
15
15
|
var _sr_output_disabled_tooltip = require("./rules/a11y/sr_output_disabled_tooltip");
|
|
16
16
|
var _tooltip_focusable_anchor = require("./rules/a11y/tooltip_focusable_anchor");
|
|
17
|
+
var _prefer_tooltip_trigger_focus_test_utility = require("./rules/prefer_tooltip_trigger_focus_test_utility");
|
|
17
18
|
var _badge_accessibility_rules = require("./rules/a11y/badge_accessibility_rules");
|
|
18
19
|
var _icon_accessibility_rules = require("./rules/a11y/icon_accessibility_rules");
|
|
19
20
|
/*
|
|
@@ -40,6 +41,7 @@ const config = {
|
|
|
40
41
|
'require-table-caption': _require_table_caption.RequireTableCaption,
|
|
41
42
|
'sr-output-disabled-tooltip': _sr_output_disabled_tooltip.ScreenReaderOutputDisabledTooltip,
|
|
42
43
|
'tooltip-focusable-anchor': _tooltip_focusable_anchor.TooltipFocusableAnchor,
|
|
44
|
+
'prefer-tooltip-trigger-focus-test-utility': _prefer_tooltip_trigger_focus_test_utility.PreferTooltipTriggerFocusTestUtility,
|
|
43
45
|
'badge-accessibility-rules': _badge_accessibility_rules.EuiBadgeAccessibilityRules,
|
|
44
46
|
'icon-accessibility-rules': _icon_accessibility_rules.EuiIconAccessibilityRules
|
|
45
47
|
},
|
|
@@ -61,6 +63,7 @@ const config = {
|
|
|
61
63
|
'@elastic/eui/require-table-caption': 'warn',
|
|
62
64
|
'@elastic/eui/sr-output-disabled-tooltip': 'warn',
|
|
63
65
|
'@elastic/eui/tooltip-focusable-anchor': 'warn',
|
|
66
|
+
'@elastic/eui/prefer-tooltip-trigger-focus-test-utility': 'warn',
|
|
64
67
|
'@elastic/eui/badge-accessibility-rules': 'warn',
|
|
65
68
|
'@elastic/eui/icon-accessibility-rules': 'warn'
|
|
66
69
|
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
2
|
+
export declare const PreferTooltipTriggerFocusTestUtility: ESLintUtils.RuleModule<"preferTooltipTriggerFocusTestUtility", [], unknown, ESLintUtils.RuleListener>;
|
|
3
|
+
//# sourceMappingURL=prefer_tooltip_trigger_focus_test_utility.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prefer_tooltip_trigger_focus_test_utility.d.ts","sourceRoot":"","sources":["../../../src/rules/prefer_tooltip_trigger_focus_test_utility.ts"],"names":[],"mappings":"AAQA,OAAO,EAAY,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAoDjE,eAAO,MAAM,oCAAoC,uGAqD7C,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.PreferTooltipTriggerFocusTestUtility = void 0;
|
|
7
|
+
var _utils = require("@typescript-eslint/utils");
|
|
8
|
+
/*
|
|
9
|
+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
10
|
+
* or more contributor license agreements. Licensed under the Elastic License
|
|
11
|
+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
|
12
|
+
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
|
13
|
+
* Side Public License, v 1.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const TOOLTIP_ROLE_QUERIES = new Set(['getByRole', 'queryByRole', 'findByRole']);
|
|
17
|
+
const isTooltipRoleQuery = node => {
|
|
18
|
+
const firstArg = node.arguments[0];
|
|
19
|
+
if (firstArg?.type !== 'Literal' || firstArg.value !== 'tooltip') return false;
|
|
20
|
+
const callee = node.callee;
|
|
21
|
+
|
|
22
|
+
// `screen.getByRole('tooltip')` or destructured `getByRole('tooltip')`
|
|
23
|
+
if (callee.type === 'MemberExpression') return callee.property.type === 'Identifier' && TOOLTIP_ROLE_QUERIES.has(callee.property.name);
|
|
24
|
+
if (callee.type === 'Identifier') return TOOLTIP_ROLE_QUERIES.has(callee.name);
|
|
25
|
+
return false;
|
|
26
|
+
};
|
|
27
|
+
const isFireEventFocus = node => node.callee.type === 'MemberExpression' && node.callee.object.type === 'Identifier' && node.callee.object.name === 'fireEvent' && node.callee.property.type === 'Identifier' && node.callee.property.name === 'focus';
|
|
28
|
+
const isEuiToolTipClassSelector = node => typeof node.value === 'string' && node.value.includes('euiToolTip');
|
|
29
|
+
const isTestBlock = node => {
|
|
30
|
+
const callee = node.callee;
|
|
31
|
+
return callee.type === 'Identifier' && (callee.name === 'it' || callee.name === 'test');
|
|
32
|
+
};
|
|
33
|
+
const PreferTooltipTriggerFocusTestUtility = exports.PreferTooltipTriggerFocusTestUtility = _utils.ESLintUtils.RuleCreator.withoutDocs({
|
|
34
|
+
create(context) {
|
|
35
|
+
const blockStack = [];
|
|
36
|
+
const currentBlock = () => blockStack[blockStack.length - 1];
|
|
37
|
+
return {
|
|
38
|
+
CallExpression(node) {
|
|
39
|
+
if (isTestBlock(node)) {
|
|
40
|
+
blockStack.push({
|
|
41
|
+
violations: [],
|
|
42
|
+
hasTooltipSignal: false
|
|
43
|
+
});
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const block = currentBlock();
|
|
47
|
+
if (!block) return;
|
|
48
|
+
if (isTooltipRoleQuery(node)) block.hasTooltipSignal = true;
|
|
49
|
+
if (isFireEventFocus(node)) block.violations.push(node);
|
|
50
|
+
},
|
|
51
|
+
Literal(node) {
|
|
52
|
+
const block = currentBlock();
|
|
53
|
+
if (!block) return;
|
|
54
|
+
if (isEuiToolTipClassSelector(node)) block.hasTooltipSignal = true;
|
|
55
|
+
},
|
|
56
|
+
'CallExpression:exit'(node) {
|
|
57
|
+
if (!isTestBlock(node)) return;
|
|
58
|
+
const block = blockStack.pop();
|
|
59
|
+
if (!block?.hasTooltipSignal) return;
|
|
60
|
+
for (const violation of block.violations) {
|
|
61
|
+
context.report({
|
|
62
|
+
node: violation,
|
|
63
|
+
messageId: 'preferTooltipTriggerFocusTestUtility'
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
},
|
|
69
|
+
meta: {
|
|
70
|
+
type: 'suggestion',
|
|
71
|
+
docs: {
|
|
72
|
+
description: 'Prefer `focusEuiToolTipTrigger` over `fireEvent.focus` in tooltip tests. Plain `fireEvent.focus` does not simulate `:focus-visible` in jsdom and will not trigger the tooltip.'
|
|
73
|
+
},
|
|
74
|
+
schema: [],
|
|
75
|
+
messages: {
|
|
76
|
+
preferTooltipTriggerFocusTestUtility: 'Use `focusEuiToolTipTrigger` from EUI test utilities instead of `fireEvent.focus` when testing tooltip focus behavior.'
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
defaultOptions: []
|
|
80
|
+
});
|
package/lib/esm/index.js
CHANGED
|
@@ -21,6 +21,7 @@ const require_aria_label_for_modals_1 = require("./rules/a11y/require_aria_label
|
|
|
21
21
|
const require_table_caption_1 = require("./rules/a11y/require_table_caption");
|
|
22
22
|
const sr_output_disabled_tooltip_1 = require("./rules/a11y/sr_output_disabled_tooltip");
|
|
23
23
|
const tooltip_focusable_anchor_1 = require("./rules/a11y/tooltip_focusable_anchor");
|
|
24
|
+
const prefer_tooltip_trigger_focus_test_utility_1 = require("./rules/prefer_tooltip_trigger_focus_test_utility");
|
|
24
25
|
const badge_accessibility_rules_1 = require("./rules/a11y/badge_accessibility_rules");
|
|
25
26
|
const icon_accessibility_rules_1 = require("./rules/a11y/icon_accessibility_rules");
|
|
26
27
|
const config = {
|
|
@@ -39,8 +40,9 @@ const config = {
|
|
|
39
40
|
'require-table-caption': require_table_caption_1.RequireTableCaption,
|
|
40
41
|
'sr-output-disabled-tooltip': sr_output_disabled_tooltip_1.ScreenReaderOutputDisabledTooltip,
|
|
41
42
|
'tooltip-focusable-anchor': tooltip_focusable_anchor_1.TooltipFocusableAnchor,
|
|
43
|
+
'prefer-tooltip-trigger-focus-test-utility': prefer_tooltip_trigger_focus_test_utility_1.PreferTooltipTriggerFocusTestUtility,
|
|
42
44
|
'badge-accessibility-rules': badge_accessibility_rules_1.EuiBadgeAccessibilityRules,
|
|
43
|
-
'icon-accessibility-rules': icon_accessibility_rules_1.EuiIconAccessibilityRules
|
|
45
|
+
'icon-accessibility-rules': icon_accessibility_rules_1.EuiIconAccessibilityRules,
|
|
44
46
|
},
|
|
45
47
|
configs: {
|
|
46
48
|
recommended: {
|
|
@@ -60,6 +62,7 @@ const config = {
|
|
|
60
62
|
'@elastic/eui/require-table-caption': 'warn',
|
|
61
63
|
'@elastic/eui/sr-output-disabled-tooltip': 'warn',
|
|
62
64
|
'@elastic/eui/tooltip-focusable-anchor': 'warn',
|
|
65
|
+
'@elastic/eui/prefer-tooltip-trigger-focus-test-utility': 'warn',
|
|
63
66
|
'@elastic/eui/badge-accessibility-rules': 'warn',
|
|
64
67
|
'@elastic/eui/icon-accessibility-rules': 'warn',
|
|
65
68
|
},
|
package/lib/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAEH,gGAA4F;AAC5F,sFAAgF;AAChF,0FAAoF;AACpF,+DAAuD;AACvD,uDAAkD;AAClD,iFAA2E;AAC3E,iEAA2D;AAC3D,gGAA0F;AAC1F,gFAA0E;AAC1E,0EAAoE;AACpE,8FAAuF;AACvF,8EAAyE;AACzE,wFAA4F;AAC5F,oFAA+E;AAC/E,iHAAyG;AACzG,sFAAoF;AACpF,oFAAkF;AAElF,MAAM,MAAM,GAAG;IACb,KAAK,EAAE;QACL,gCAAgC,EAAE,8DAA6B;QAC/D,2BAA2B,EAAE,kDAAsB;QACnD,6BAA6B,EAAE,sDAAwB;QACvD,kBAAkB,EAAE,8BAAW;QAC/B,cAAc,EAAE,yBAAU;QAC1B,2BAA2B,EAAE,kDAAsB;QACnD,mBAAmB,EAAE,kCAAc;QACnC,gCAAgC,EAAE,4DAA2B;QAC7D,wBAAwB,EAAE,4CAAmB;QAC7C,qBAAqB,EAAE,sCAAgB;QACvC,+BAA+B,EAAE,yDAAyB;QAC1D,uBAAuB,EAAE,2CAAmB;QAC5C,4BAA4B,EAAE,8DAAiC;QAC/D,0BAA0B,EAAE,iDAAsB;QAClD,2CAA2C,EACzC,gFAAoC;QACtC,2BAA2B,EAAE,sDAA0B;QACvD,0BAA0B,EAAE,oDAAyB;KACtD;IACD,OAAO,EAAE;QACP,WAAW,EAAE;YACX,OAAO,EAAE,CAAC,4BAA4B,CAAC;YACvC,KAAK,EAAE;gBACL,6CAA6C,EAAE,MAAM;gBACrD,wCAAwC,EAAE,MAAM;gBAChD,0CAA0C,EAAE,MAAM;gBAClD,+BAA+B,EAAE,MAAM;gBACvC,2BAA2B,EAAE,MAAM;gBACnC,wCAAwC,EAAE,MAAM;gBAChD,gCAAgC,EAAE,MAAM;gBACxC,6CAA6C,EAAE,MAAM;gBACrD,qCAAqC,EAAE,MAAM;gBAC7C,kCAAkC,EAAE,MAAM;gBAC1C,4CAA4C,EAAE,MAAM;gBACpD,oCAAoC,EAAE,MAAM;gBAC5C,yCAAyC,EAAE,MAAM;gBACjD,uCAAuC,EAAE,MAAM;gBAC/C,wDAAwD,EAAE,MAAM;gBAChE,wCAAwC,EAAE,MAAM;gBAChD,uCAAuC,EAAE,MAAM;aAChD;SACF;KACF;CACF,CAAC;AAEF,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
4
|
+
* or more contributor license agreements. Licensed under the Elastic License
|
|
5
|
+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
|
6
|
+
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
|
7
|
+
* Side Public License, v 1.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.PreferTooltipTriggerFocusTestUtility = void 0;
|
|
11
|
+
const utils_1 = require("@typescript-eslint/utils");
|
|
12
|
+
const TOOLTIP_ROLE_QUERIES = new Set([
|
|
13
|
+
'getByRole',
|
|
14
|
+
'queryByRole',
|
|
15
|
+
'findByRole',
|
|
16
|
+
]);
|
|
17
|
+
const isTooltipRoleQuery = (node) => {
|
|
18
|
+
const firstArg = node.arguments[0];
|
|
19
|
+
if (firstArg?.type !== 'Literal' || firstArg.value !== 'tooltip')
|
|
20
|
+
return false;
|
|
21
|
+
const callee = node.callee;
|
|
22
|
+
// `screen.getByRole('tooltip')` or destructured `getByRole('tooltip')`
|
|
23
|
+
if (callee.type === 'MemberExpression')
|
|
24
|
+
return (callee.property.type === 'Identifier' &&
|
|
25
|
+
TOOLTIP_ROLE_QUERIES.has(callee.property.name));
|
|
26
|
+
if (callee.type === 'Identifier')
|
|
27
|
+
return TOOLTIP_ROLE_QUERIES.has(callee.name);
|
|
28
|
+
return false;
|
|
29
|
+
};
|
|
30
|
+
const isFireEventFocus = (node) => node.callee.type === 'MemberExpression' &&
|
|
31
|
+
node.callee.object.type === 'Identifier' &&
|
|
32
|
+
node.callee.object.name === 'fireEvent' &&
|
|
33
|
+
node.callee.property.type === 'Identifier' &&
|
|
34
|
+
node.callee.property.name === 'focus';
|
|
35
|
+
const isEuiToolTipClassSelector = (node) => typeof node.value === 'string' && node.value.includes('euiToolTip');
|
|
36
|
+
const isTestBlock = (node) => {
|
|
37
|
+
const callee = node.callee;
|
|
38
|
+
return (callee.type === 'Identifier' &&
|
|
39
|
+
(callee.name === 'it' || callee.name === 'test'));
|
|
40
|
+
};
|
|
41
|
+
exports.PreferTooltipTriggerFocusTestUtility = utils_1.ESLintUtils.RuleCreator.withoutDocs({
|
|
42
|
+
create(context) {
|
|
43
|
+
const blockStack = [];
|
|
44
|
+
const currentBlock = () => blockStack[blockStack.length - 1];
|
|
45
|
+
return {
|
|
46
|
+
CallExpression(node) {
|
|
47
|
+
if (isTestBlock(node)) {
|
|
48
|
+
blockStack.push({ violations: [], hasTooltipSignal: false });
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const block = currentBlock();
|
|
52
|
+
if (!block)
|
|
53
|
+
return;
|
|
54
|
+
if (isTooltipRoleQuery(node))
|
|
55
|
+
block.hasTooltipSignal = true;
|
|
56
|
+
if (isFireEventFocus(node))
|
|
57
|
+
block.violations.push(node);
|
|
58
|
+
},
|
|
59
|
+
Literal(node) {
|
|
60
|
+
const block = currentBlock();
|
|
61
|
+
if (!block)
|
|
62
|
+
return;
|
|
63
|
+
if (isEuiToolTipClassSelector(node))
|
|
64
|
+
block.hasTooltipSignal = true;
|
|
65
|
+
},
|
|
66
|
+
'CallExpression:exit'(node) {
|
|
67
|
+
if (!isTestBlock(node))
|
|
68
|
+
return;
|
|
69
|
+
const block = blockStack.pop();
|
|
70
|
+
if (!block?.hasTooltipSignal)
|
|
71
|
+
return;
|
|
72
|
+
for (const violation of block.violations) {
|
|
73
|
+
context.report({
|
|
74
|
+
node: violation,
|
|
75
|
+
messageId: 'preferTooltipTriggerFocusTestUtility',
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
},
|
|
81
|
+
meta: {
|
|
82
|
+
type: 'suggestion',
|
|
83
|
+
docs: {
|
|
84
|
+
description: 'Prefer `focusEuiToolTipTrigger` over `fireEvent.focus` in tooltip tests. Plain `fireEvent.focus` does not simulate `:focus-visible` in jsdom and will not trigger the tooltip.',
|
|
85
|
+
},
|
|
86
|
+
schema: [],
|
|
87
|
+
messages: {
|
|
88
|
+
preferTooltipTriggerFocusTestUtility: 'Use `focusEuiToolTipTrigger` from EUI test utilities instead of `fireEvent.focus` when testing tooltip focus behavior.',
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
defaultOptions: [],
|
|
92
|
+
});
|
|
93
|
+
//# sourceMappingURL=prefer_tooltip_trigger_focus_test_utility.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prefer_tooltip_trigger_focus_test_utility.js","sourceRoot":"","sources":["../../../src/rules/prefer_tooltip_trigger_focus_test_utility.ts"],"names":[],"mappings":"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"}
|