click-events-have-key-events.js 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. Object.defineProperty(exports, "__esModule", {
  4. value: true
  5. });
  6. exports["default"] = void 0;
  7. var _ariaQuery = require("aria-query");
  8. var _jsxAstUtils = require("jsx-ast-utils");
  9. var _schemas = require("../util/schemas");
  10. var _getElementType = _interopRequireDefault(require("../util/getElementType"));
  11. var _isHiddenFromScreenReader = _interopRequireDefault(require("../util/isHiddenFromScreenReader"));
  12. var _isInteractiveElement = _interopRequireDefault(require("../util/isInteractiveElement"));
  13. var _isPresentationRole = _interopRequireDefault(require("../util/isPresentationRole"));
  14. /**
  15. * @fileoverview Enforce a clickable non-interactive element has at least 1 keyboard event listener.
  16. * @author Ethan Cohen
  17. */
  18. // ----------------------------------------------------------------------------
  19. // Rule Definition
  20. // ----------------------------------------------------------------------------
  21. var errorMessage = 'Visible, non-interactive elements with click handlers must have at least one keyboard listener.';
  22. var schema = (0, _schemas.generateObjSchema)();
  23. var _default = exports["default"] = {
  24. meta: {
  25. docs: {
  26. url: 'https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/click-events-have-key-events.md',
  27. description: 'Enforce a clickable non-interactive element has at least one keyboard event listener.'
  28. },
  29. schema: [schema]
  30. },
  31. create: function create(context) {
  32. var elementType = (0, _getElementType["default"])(context);
  33. return {
  34. JSXOpeningElement: function JSXOpeningElement(node) {
  35. var props = node.attributes;
  36. if ((0, _jsxAstUtils.getProp)(props, 'onclick') === undefined) {
  37. return;
  38. }
  39. var type = elementType(node);
  40. var requiredProps = ['onkeydown', 'onkeyup', 'onkeypress'];
  41. if (!_ariaQuery.dom.has(type)) {
  42. // Do not test higher level JSX components, as we do not know what
  43. // low-level DOM element this maps to.
  44. return;
  45. }
  46. if ((0, _isHiddenFromScreenReader["default"])(type, props) || (0, _isPresentationRole["default"])(type, props)) {
  47. return;
  48. }
  49. if ((0, _isInteractiveElement["default"])(type, props)) {
  50. return;
  51. }
  52. if ((0, _jsxAstUtils.hasAnyProp)(props, requiredProps)) {
  53. return;
  54. }
  55. // Visible, non-interactive elements with click handlers require one keyboard event listener.
  56. context.report({
  57. node,
  58. message: errorMessage
  59. });
  60. }
  61. };
  62. }
  63. };
  64. module.exports = exports.default;