diff --git a/crates/oxc_linter/src/rules.rs b/crates/oxc_linter/src/rules.rs index 0f9bb3fc6aa48..969eb8e12f0fe 100644 --- a/crates/oxc_linter/src/rules.rs +++ b/crates/oxc_linter/src/rules.rs @@ -247,6 +247,7 @@ mod jsx_a11y { pub mod aria_role; pub mod aria_unsupported_elements; pub mod autocomplete_valid; + pub mod click_events_have_key_events; pub mod heading_has_content; pub mod html_has_lang; pub mod iframe_has_title; @@ -508,6 +509,7 @@ oxc_macros::declare_all_lint_rules! { jsx_a11y::anchor_is_valid, jsx_a11y::aria_props, jsx_a11y::aria_unsupported_elements, + jsx_a11y::click_events_have_key_events, jsx_a11y::heading_has_content, jsx_a11y::html_has_lang, jsx_a11y::lang, diff --git a/crates/oxc_linter/src/rules/jsx_a11y/click_events_have_key_events.rs b/crates/oxc_linter/src/rules/jsx_a11y/click_events_have_key_events.rs new file mode 100644 index 0000000000000..951117bdfb925 --- /dev/null +++ b/crates/oxc_linter/src/rules/jsx_a11y/click_events_have_key_events.rs @@ -0,0 +1,150 @@ +use oxc_ast::AstKind; +use oxc_diagnostics::{ + miette::{self, Diagnostic}, + thiserror::Error, +}; +use oxc_macros::declare_oxc_lint; +use oxc_span::Span; + +use crate::{ + context::LintContext, + globals::HTML_TAG, + rule::Rule, + utils::{ + get_element_type, has_jsx_prop, is_hidden_from_screen_reader, is_interactive_element, + is_presentation_role, + }, + AstNode, +}; + +#[derive(Debug, Error, Diagnostic)] +#[error("eslint-plugin-jsx-a11y(click-events-have-key-events): Enforce a clickable non-interactive element has at least one keyboard event listener.")] +#[diagnostic(severity(warning), help("Visible, non-interactive elements with click handlers must have one of keyup, keydown, or keypress listener."))] +struct ClickEventsHaveKeyEventsDiagnostic(#[label] pub Span); + +#[derive(Debug, Default, Clone)] +pub struct ClickEventsHaveKeyEvents; + +declare_oxc_lint!( + /// ### What it does + /// + /// Enforce onClick is accompanied by at least one of the following: onKeyUp, onKeyDown, onKeyPress. + /// + /// ### Why is this bad? + /// + /// Coding for the keyboard is important for users with physical disabilities who cannot use a mouse, AT compatibility, and screenreader users. + /// This does not apply for interactive or hidden elements. + /// + /// ### Example + /// ```jsx + /// // Good + ///