oxc-project/oxc · error

Elements with the '{role}' interactive role must be tabbable

Error message

Elements with the '{role}' interactive role must be tabbable.

What it means

Raised by jsx-a11y/interactive-supports-focus when an element has an interactive ARIA role but is not tabbable (no tabIndex making it reachable by keyboard). Interactive elements must be focusable for keyboard users.

Source

Thrown at crates/oxc_linter/src/rules/jsx_a11y/interactive_supports_focus.rs:24

use schemars::JsonSchema;
use serde::Deserialize;

use crate::{
    AstNode,
    context::LintContext,
    fixer::RuleFixer,
    globals::HTML_TAG,
    rule::{DefaultRuleConfig, Rule},
    utils::{
        KEYBOARD_EVENT_HANDLERS, MOUSE_EVENT_HANDLERS, get_element_type,
        get_string_literal_prop_value, has_jsx_prop, has_jsx_prop_ignore_case, is_disabled_element,
        is_hidden_from_screen_reader, is_interactive_element, is_interactive_role,
        is_non_interactive_element, is_non_interactive_role, is_presentation_role,
    },
};

fn must_be_tabbable_diagnostic(role: &str, span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn(format!("Elements with the '{role}' interactive role must be tabbable."))
        .with_help(
            "Add `tabIndex={0}` to make the element reachable via sequential keyboard navigation.",
        )
        .with_label(span)
}

fn must_be_focusable_diagnostic(role: &str, span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn(format!("Elements with the '{role}' interactive role must be focusable."))
        .with_help("Add `tabIndex={0}` or `tabIndex={-1}` to make the element focusable.")
        .with_label(span)
}

const EVENT_HANDLERS: &[&[&str]] = &[MOUSE_EVENT_HANDLERS, KEYBOARD_EVENT_HANDLERS];

const DEFAULT_TABBABLE: &[&str] =
    &["button", "checkbox", "link", "searchbox", "spinbutton", "switch", "textbox"];

#[derive(Debug, Default, Clone, Deserialize)]

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Add tabIndex={0} (or -1 with programmatic focus) to the element.
  2. Prefer using a native interactive element (button, a) instead of a div with a role.
  3. Avoid the role if the element is not actually interactive.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at crates/oxc_linter/src/rules/jsx_a11y/interactive_supports_focus.rs:24 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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