oxc-project/oxc · warning

`{attr_name}` must be accompanied by `onBlur` for accessibil

Error message

`{attr_name}` must be accompanied by `onBlur` for accessibility.

What it means

This is the `jsx_a11y/mouse-events-have-key-events` rule in oxlint (port of eslint-plugin-jsx-a11y). The library throws it when a JSX element has a hover-out mouse handler (default `onMouseOut`, configurable via `hoverOutHandlers`) but no `onBlur` handler. Hover interactions are invisible to keyboard-only and screen-reader users, so every mouse handler must have a focus-equivalent handler.

Source

Thrown at crates/oxc_linter/src/rules/jsx_a11y/mouse_events_have_key_events.rs:26

use crate::{
    AstNode,
    context::LintContext,
    globals::HTML_TAG,
    rule::{DefaultRuleConfig, Rule},
    utils::{get_element_type, get_prop_value, has_jsx_prop},
};

fn miss_on_focus(span: Span, attr_name: &str) -> OxcDiagnostic {
    OxcDiagnostic::warn(format!(
        "`{attr_name}` must be accompanied by `onFocus` for accessibility."
    ))
    .with_help("Try to add `onFocus`.")
    .with_label(span)
}

fn miss_on_blur(span: Span, attr_name: &str) -> OxcDiagnostic {
    OxcDiagnostic::warn(format!("`{attr_name}` must be accompanied by `onBlur` for accessibility."))
        .with_help("Try to add `onBlur`.")
        .with_label(span)
}

#[derive(Debug, Default, Clone, Deserialize)]
pub struct MouseEventsHaveKeyEvents(Box<MouseEventsHaveKeyEventsConfig>);

#[derive(Debug, Clone, JsonSchema, Deserialize)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
pub struct MouseEventsHaveKeyEventsConfig {
    /// List of hover-in mouse event handlers that require corresponding keyboard event handlers.
    hover_in_handlers: Vec<CompactStr>,
    /// List of hover-out mouse event handlers that require corresponding keyboard event handlers.
    hover_out_handlers: Vec<CompactStr>,
}

impl Default for MouseEventsHaveKeyEventsConfig {
    fn default() -> Self {

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Add an `onBlur` handler to the same element that mirrors the `onMouseOut` behavior (and `onFocus` for `onMouseOver`).
  2. If the hover-out logic is purely decorative, guard it with `event.relatedTarget` checks or remove it.
  3. Extend the config `hoverOutHandlers`/`hoverInHandlers` lists if your codebase uses custom handler names.
  4. As a last resort, disable the rule for that line with an oxlint disable comment.

Example fix

// before
<div onMouseOut={handleClose} />

// after
<div onMouseOut={handleClose} onBlur={handleClose} onFocus={handleOpen} />
Defensive patterns

Strategy: validation

Validate before calling

npx oxlint --jsx-a11y/mouse-events-have-key-events src/

Type guard

// Type-level reminder: pair hover handlers with focus handlers
type HoverA11yProps<T> = T & { onMouseOut?: ...; onBlur?: ... };
// Runtime check for element props before render:
const hasPairedHandlers = (p: Record<string, unknown>, mouse: string, key: string) =>
  !(mouse in p) || (key in p);

Prevention

When it happens

Trigger: A JSX opening element (HTML tag or configured custom element) carries `onMouseOut` (or any name listed in the rule's `hoverOutHandlers` config) while `onBlur` is absent. The `miss_on_blur` diagnostic constructor at crates/oxc_linter/src/rules/jsx_a11y/mouse_events_have_key_events.rs:25 is the code path that fires.

Common situations: Hover-triggered dropdown menus, tooltips, or highlighting effects written for mouse users only; custom components that spread props and accidentally drop `onBlur`; teams enabling the jsx-a11y recommended preset for the first time; migrating from ESLint to oxlint and seeing pre-existing violations surface.

Related errors


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/1a35e1ee4f5cf978. Report an issue: GitHub.