diff --git a/packages/field-base/src/clear-button-mixin.js b/packages/field-base/src/clear-button-mixin.js index 0fe18bb8f94..c22f4192f34 100644 --- a/packages/field-base/src/clear-button-mixin.js +++ b/packages/field-base/src/clear-button-mixin.js @@ -3,6 +3,7 @@ * Copyright (c) 2021 - 2025 Vaadin Ltd. * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ */ +import { isElementFocused } from '@vaadin/a11y-base/src/focus-utils.js'; import { KeyboardMixin } from '@vaadin/a11y-base/src/keyboard-mixin.js'; import { isTouch } from '@vaadin/component-base/src/browser-utils.js'; import { InputMixin } from './input-mixin.js'; @@ -71,7 +72,10 @@ export const ClearButtonMixin = (superclass) => * @protected */ _onClearButtonMouseDown(event) { - event.preventDefault(); + if (this._shouldKeepFocusOnClearMousedown(event)) { + event.preventDefault(); + } + if (!isTouch) { this.inputElement.focus(); } @@ -109,4 +113,17 @@ export const ClearButtonMixin = (superclass) => this.inputElement.dispatchEvent(new Event('input', { bubbles: true, composed: true })); this.inputElement.dispatchEvent(new Event('change', { bubbles: true })); } + + /** + * Whether to keep focus inside the field on clear button + * mousedown. By default, if the field has focus, it gets + * preserved using `preventDefault()` on mousedown event + * in order to avoid blur and change events. + * + * @protected + * @return {boolean} + */ + _shouldKeepFocusOnClearMousedown() { + return isElementFocused(this.inputElement); + } }; diff --git a/packages/field-base/test/clear-button-mixin.test.js b/packages/field-base/test/clear-button-mixin.test.js index 2d4cb57ba8d..5f5a4e06709 100644 --- a/packages/field-base/test/clear-button-mixin.test.js +++ b/packages/field-base/test/clear-button-mixin.test.js @@ -67,7 +67,14 @@ describe('ClearButtonMixin', () => { expect(spy.calledOnce).to.be.true; }); - it('should prevent default on clear button mousedown', () => { + it('should not prevent default on clear button mousedown if input is not focused', () => { + const event = new CustomEvent('mousedown', { cancelable: true }); + clearButton.dispatchEvent(event); + expect(event.defaultPrevented).to.be.false; + }); + + it('should prevent default on clear button mousedown if input is focused', () => { + input.focus(); const event = new CustomEvent('mousedown', { cancelable: true }); clearButton.dispatchEvent(event); expect(event.defaultPrevented).to.be.true;