diff --git a/packages/breadcrumbs/spec/web-component-spec.md b/packages/breadcrumbs/spec/web-component-spec.md index 27fce0d599c..9529d0b0c4a 100644 --- a/packages/breadcrumbs/spec/web-component-spec.md +++ b/packages/breadcrumbs/spec/web-component-spec.md @@ -304,3 +304,7 @@ Two shadow slots with the overflow in shadow DOM between them: ``, ``, ``, ``, ``, and ``. A mouse-driven open is a continuation of a pointer interaction — a focus ring appearing under the user's cursor is visual noise. A keyboard-driven open is the user's only signal that focus has moved into a transient popup, so the ring is essential. `isKeyboardActive()` from `@vaadin/a11y-base` reads the cross-component flag set on every keydown and cleared on every mousedown, so the trigger detection is automatic and consistent with the rest of the library. diff --git a/packages/breadcrumbs/src/vaadin-breadcrumbs.js b/packages/breadcrumbs/src/vaadin-breadcrumbs.js index b24610766fb..fd74e1d97de 100644 --- a/packages/breadcrumbs/src/vaadin-breadcrumbs.js +++ b/packages/breadcrumbs/src/vaadin-breadcrumbs.js @@ -6,6 +6,7 @@ import './vaadin-breadcrumbs-item.js'; import './vaadin-breadcrumbs-overlay.js'; import { html, LitElement } from 'lit'; +import { isKeyboardActive } from '@vaadin/a11y-base/src/focus-utils.js'; import { KeyboardDirectionMixin } from '@vaadin/a11y-base/src/keyboard-direction-mixin.js'; import { defineCustomElement } from '@vaadin/component-base/src/define.js'; import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js'; @@ -302,7 +303,7 @@ class Breadcrumbs extends KeyboardDirectionMixin( // Focus first non-disabled overlay item const idx = this._getFocusableIndex(); if (idx >= 0) { - this._focus(idx); + this._focus(idx, { focusVisible: isKeyboardActive() }); } } diff --git a/packages/breadcrumbs/test/dom/__snapshots__/breadcrumbs.test.snap.js b/packages/breadcrumbs/test/dom/__snapshots__/breadcrumbs.test.snap.js index a1fefacd42d..3571d3d4408 100644 --- a/packages/breadcrumbs/test/dom/__snapshots__/breadcrumbs.test.snap.js +++ b/packages/breadcrumbs/test/dom/__snapshots__/breadcrumbs.test.snap.js @@ -236,7 +236,6 @@ snapshots["vaadin-breadcrumbs overflow opened"] = Home { const firstItem = breadcrumbs.querySelector('vaadin-breadcrumbs-item[slot="overlay"]'); expectFocusedItem(firstItem); }); + + it('should not set focus-ring on the first overlay item when opening via mouse', async () => { + mousedown(button); + button.click(); + await oneEvent(overlay, 'vaadin-overlay-open'); + + const firstItem = breadcrumbs.querySelector('vaadin-breadcrumbs-item[slot="overlay"]'); + expectFocusedItem(firstItem); + expect(firstItem.hasAttribute('focus-ring')).to.be.false; + }); + + it('should set focus-ring on the first overlay item when opening via Enter', async () => { + button.focus(); + await sendKeys({ press: 'Enter' }); + await nextRender(); + + const firstItem = breadcrumbs.querySelector('vaadin-breadcrumbs-item[slot="overlay"]'); + expect(firstItem.hasAttribute('focus-ring')).to.be.true; + }); + + it('should set focus-ring on the first overlay item when opening via Space', async () => { + button.focus(); + await sendKeys({ press: 'Space' }); + await nextRender(); + + const firstItem = breadcrumbs.querySelector('vaadin-breadcrumbs-item[slot="overlay"]'); + expect(firstItem.hasAttribute('focus-ring')).to.be.true; + }); }); describe('closing', () => {