From 1be496f0a61bf7c1da912caab62804e5e173ca5b Mon Sep 17 00:00:00 2001 From: Bao Nguyen <39545125+giaBaoJS@users.noreply.github.com> Date: Mon, 24 Aug 2026 20:14:16 +0700 Subject: [PATCH] fix: accept `onfocusin`/`onfocusout` in `a11y_mouse_events_have_key_events` (#18689) Fixes #8089 focusin/focusout are the bubble variants of focus/blur --------- Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com> --- .changeset/large-schools-smell.md | 5 +++++ .../98-reference/.generated/compile-warnings.md | 2 +- .../svelte/messages/compile-warnings/a11y.md | 2 +- .../2-analyze/visitors/shared/a11y/index.js | 16 ++++++++++++++-- .../input.svelte | 4 ++++ 5 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 .changeset/large-schools-smell.md diff --git a/.changeset/large-schools-smell.md b/.changeset/large-schools-smell.md new file mode 100644 index 0000000000..61ef571f02 --- /dev/null +++ b/.changeset/large-schools-smell.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: accept `onfocusin`/`onfocusout` in `a11y_mouse_events_have_key_events` diff --git a/documentation/docs/98-reference/.generated/compile-warnings.md b/documentation/docs/98-reference/.generated/compile-warnings.md index f372a010a5..237ec105f6 100644 --- a/documentation/docs/98-reference/.generated/compile-warnings.md +++ b/documentation/docs/98-reference/.generated/compile-warnings.md @@ -360,7 +360,7 @@ Enforce that heading elements (`h1`, `h2`, etc.) and anchors have content and th '%event%' event must be accompanied by '%accompanied_by%' event ``` -Enforce that `onmouseover` and `onmouseout` are accompanied by `onfocus` and `onblur`, respectively. This helps to ensure that any functionality triggered by these mouse events is also accessible to keyboard users. +Enforce that `onmouseover` and `onmouseout` are accompanied by `onfocus` (or `onfocusin`) and `onblur` (or `onfocusout`), respectively. This helps to ensure that any functionality triggered by these mouse events is also accessible to keyboard users. ```svelte diff --git a/packages/svelte/messages/compile-warnings/a11y.md b/packages/svelte/messages/compile-warnings/a11y.md index 1f48ef0dd5..915032bb93 100644 --- a/packages/svelte/messages/compile-warnings/a11y.md +++ b/packages/svelte/messages/compile-warnings/a11y.md @@ -300,7 +300,7 @@ Enforce that heading elements (`h1`, `h2`, etc.) and anchors have content and th > '%event%' event must be accompanied by '%accompanied_by%' event -Enforce that `onmouseover` and `onmouseout` are accompanied by `onfocus` and `onblur`, respectively. This helps to ensure that any functionality triggered by these mouse events is also accessible to keyboard users. +Enforce that `onmouseover` and `onmouseout` are accompanied by `onfocus` (or `onfocusin`) and `onblur` (or `onfocusout`), respectively. This helps to ensure that any functionality triggered by these mouse events is also accessible to keyboard users. ```svelte diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/shared/a11y/index.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/shared/a11y/index.js index a6e801cf5a..e09ab018a8 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/visitors/shared/a11y/index.js +++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/shared/a11y/index.js @@ -373,11 +373,23 @@ export function check_element(node, context) { } } - if (!has_spread && handlers.has('mouseover') && !handlers.has('focus')) { + // `focus`/`blur` don't bubble, so an element that isn't focusable itself can only be notified + // about focus changes inside it through `focusin`/`focusout` — accept those as well + if ( + !has_spread && + handlers.has('mouseover') && + !handlers.has('focus') && + !handlers.has('focusin') + ) { w.a11y_mouse_events_have_key_events(node, 'mouseover', 'focus'); } - if (!has_spread && handlers.has('mouseout') && !handlers.has('blur')) { + if ( + !has_spread && + handlers.has('mouseout') && + !handlers.has('blur') && + !handlers.has('focusout') + ) { w.a11y_mouse_events_have_key_events(node, 'mouseout', 'blur'); } diff --git a/packages/svelte/tests/validator/samples/a11y-mouse-events-have-key-events/input.svelte b/packages/svelte/tests/validator/samples/a11y-mouse-events-have-key-events/input.svelte index f9fe4f15c1..85e9384c98 100644 --- a/packages/svelte/tests/validator/samples/a11y-mouse-events-have-key-events/input.svelte +++ b/packages/svelte/tests/validator/samples/a11y-mouse-events-have-key-events/input.svelte @@ -17,3 +17,7 @@