UNPKG

@jsxtools/eslint-plugin-jsx-a11y

Version:

Static AST checker for accessibility rules on JSX elements for flat ESLint Config.

70 lines (67 loc) 2.78 kB
import { dom } from 'aria-query'; import { getProp, getPropValue } from '../util/module/jsx-ast-utils.js'; import { generateObjSchema, arraySchema } from '../util/schemas.js'; const schema = generateObjSchema({ hoverInHandlers: { ...arraySchema, description: "An array of events that need to be accompanied by `onFocus`" }, hoverOutHandlers: { ...arraySchema, description: "An array of events that need to be accompanied by `onBlur`" } }); const DEFAULT_HOVER_IN_HANDLERS = ["onMouseOver"]; const DEFAULT_HOVER_OUT_HANDLERS = ["onMouseOut"]; const ruleOfMouseEventsHaveKeyEvents = { meta: { docs: { url: "https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/mouse-events-have-key-events.md", description: "Enforce that `onMouseOver`/`onMouseOut` are accompanied by `onFocus`/`onBlur` for keyboard-only users." }, schema: [schema] }, create: (context) => ({ JSXOpeningElement: (node) => { const { name } = node.name; if (!dom.get(name)) { return; } const { options } = context; const hoverInHandlers = options[0]?.hoverInHandlers ?? DEFAULT_HOVER_IN_HANDLERS; const hoverOutHandlers = options[0]?.hoverOutHandlers ?? DEFAULT_HOVER_OUT_HANDLERS; const { attributes } = node; const firstHoverInHandlerWithValue = hoverInHandlers.find((handler) => { const prop = getProp(attributes, handler); const propValue = getPropValue(prop); return propValue != null; }); if (firstHoverInHandlerWithValue != null) { const hasOnFocus = getProp(attributes, "onFocus"); const onFocusValue = getPropValue(hasOnFocus); if (hasOnFocus === false || onFocusValue === null || onFocusValue === void 0) { context.report({ node: getProp(attributes, firstHoverInHandlerWithValue), message: `${firstHoverInHandlerWithValue} must be accompanied by onFocus for accessibility.` }); } } const firstHoverOutHandlerWithValue = hoverOutHandlers.find((handler) => { const prop = getProp(attributes, handler); const propValue = getPropValue(prop); return propValue != null; }); if (firstHoverOutHandlerWithValue != null) { const hasOnBlur = getProp(attributes, "onBlur"); const onBlurValue = getPropValue(hasOnBlur); if (hasOnBlur === false || onBlurValue === null || onBlurValue === void 0) { context.report({ node: getProp(attributes, firstHoverOutHandlerWithValue), message: `${firstHoverOutHandlerWithValue} must be accompanied by onBlur for accessibility.` }); } } } }) }; export { ruleOfMouseEventsHaveKeyEvents as default };