diff --git a/src/elements/internal/InternalFrequencyControl/InternalFrequencyControl.test.ts b/src/elements/internal/InternalFrequencyControl/InternalFrequencyControl.test.ts index eaa69138..6fd6b873 100644 --- a/src/elements/internal/InternalFrequencyControl/InternalFrequencyControl.test.ts +++ b/src/elements/internal/InternalFrequencyControl/InternalFrequencyControl.test.ts @@ -557,4 +557,29 @@ describe('InternalFrequencyControl', () => { focusStub.restore(); }); + + it('does not focus input when clicking on SELECT element', async () => { + const layout = html``; + const control = await fixture(layout); + + const input = control.renderRoot.querySelector('vaadin-integer-field')?.querySelector('input'); + if (!input) return; + + const focusStub = stub(input, 'focus'); + const select = document.createElement('select'); + + const mockEvent = new MouseEvent('click', { bubbles: true }); + Object.defineProperty(mockEvent, 'composedPath', { + value: () => [select], + }); + + // @ts-expect-error accessing protected member for testing purposes + control._handleHostClick(mockEvent); + + expect(focusStub).to.not.have.been.called; + + focusStub.restore(); + }); }); diff --git a/src/elements/internal/InternalFrequencyControl/InternalFrequencyControl.ts b/src/elements/internal/InternalFrequencyControl/InternalFrequencyControl.ts index af98f686..20bf42e3 100644 --- a/src/elements/internal/InternalFrequencyControl/InternalFrequencyControl.ts +++ b/src/elements/internal/InternalFrequencyControl/InternalFrequencyControl.ts @@ -157,7 +157,7 @@ export class InternalFrequencyControl extends InternalEditableControl { protected _handleHostClick(evt: MouseEvent): void { if (this.layout !== 'summary-item') return; const composedPath = evt.composedPath() as HTMLElement[]; - const noOp = new Set(['INPUT', 'LABEL']); + const noOp = new Set(['INPUT', 'LABEL', 'SELECT']); if (!composedPath.some(el => noOp.has(el.tagName))) { this.renderRoot.querySelector('input')?.focus(); super._handleHostClick(evt); diff --git a/src/elements/internal/InternalNativeDateControl/InternalNativeDateControl.test.ts b/src/elements/internal/InternalNativeDateControl/InternalNativeDateControl.test.ts index 0a01dd89..6c226dea 100644 --- a/src/elements/internal/InternalNativeDateControl/InternalNativeDateControl.test.ts +++ b/src/elements/internal/InternalNativeDateControl/InternalNativeDateControl.test.ts @@ -406,4 +406,26 @@ describe('InternalNativeDateControl', () => { focusStub.restore(); }); + + it('does not focus input when clicking on BUTTON element', async () => { + const control = await fixture(html` + + `); + + const input = control.renderRoot.querySelector('input')!; + const focusStub = stub(input, 'focus'); + const button = document.createElement('button'); + + const mockEvent = new MouseEvent('click', { bubbles: true }); + Object.defineProperty(mockEvent, 'composedPath', { + value: () => [button], + }); + + // @ts-expect-error accessing protected member for testing purposes + control._handleHostClick(mockEvent); + + expect(focusStub).to.not.have.been.called; + + focusStub.restore(); + }); }); diff --git a/src/elements/internal/InternalNativeDateControl/InternalNativeDateControl.ts b/src/elements/internal/InternalNativeDateControl/InternalNativeDateControl.ts index e5385903..4f8086cf 100644 --- a/src/elements/internal/InternalNativeDateControl/InternalNativeDateControl.ts +++ b/src/elements/internal/InternalNativeDateControl/InternalNativeDateControl.ts @@ -115,7 +115,7 @@ export class InternalNativeDateControl extends InternalEditableControl { protected _handleHostClick(evt: MouseEvent): void { const composedPath = evt.composedPath() as HTMLElement[]; - const noOp = new Set(['INPUT', 'LABEL']); + const noOp = new Set(['INPUT', 'LABEL', 'BUTTON']); if (!composedPath.some(el => noOp.has(el.tagName))) { this.renderRoot.querySelector('input')?.focus(); super._handleHostClick(evt); diff --git a/src/elements/internal/InternalSelectControl/InternalSelectControl.test.ts b/src/elements/internal/InternalSelectControl/InternalSelectControl.test.ts index 7af4f24c..d7eec34a 100644 --- a/src/elements/internal/InternalSelectControl/InternalSelectControl.test.ts +++ b/src/elements/internal/InternalSelectControl/InternalSelectControl.test.ts @@ -467,4 +467,27 @@ describe('InternalSelectControl', () => { focusStub.restore(); }); + + it('does not focus select when clicking on BUTTON element', async () => { + const layout = html``; + const control = await fixture(layout); + + const select = control.renderRoot.querySelector('select')!; + const focusStub = stub(select, 'focus'); + const button = document.createElement('button'); + + const mockEvent = new MouseEvent('click', { bubbles: true }); + Object.defineProperty(mockEvent, 'composedPath', { + value: () => [button], + }); + + // @ts-expect-error accessing protected member for testing purposes + control._handleHostClick(mockEvent); + + expect(focusStub).to.not.have.been.called; + + focusStub.restore(); + }); }); diff --git a/src/elements/internal/InternalSelectControl/InternalSelectControl.ts b/src/elements/internal/InternalSelectControl/InternalSelectControl.ts index f6c06272..cf609bb1 100644 --- a/src/elements/internal/InternalSelectControl/InternalSelectControl.ts +++ b/src/elements/internal/InternalSelectControl/InternalSelectControl.ts @@ -158,7 +158,7 @@ export class InternalSelectControl extends InternalEditableControl { protected _handleHostClick(evt: MouseEvent): void { if (this.layout !== 'summary-item') return; const composedPath = evt.composedPath() as HTMLElement[]; - const noOp = new Set(['SELECT', 'LABEL']); + const noOp = new Set(['SELECT', 'LABEL', 'BUTTON']); if (!composedPath.some(el => noOp.has(el.tagName))) { this.renderRoot.querySelector('select')?.focus(); super._handleHostClick(evt); diff --git a/src/elements/internal/InternalTextControl/InternalTextControl.test.ts b/src/elements/internal/InternalTextControl/InternalTextControl.test.ts index 4e412ea0..06b93ccc 100644 --- a/src/elements/internal/InternalTextControl/InternalTextControl.test.ts +++ b/src/elements/internal/InternalTextControl/InternalTextControl.test.ts @@ -580,4 +580,29 @@ describe('InternalTextControl', () => { focusStub.restore(); }); + + it('does not focus input when clicking on BUTTON element', async () => { + const layout = html``; + const control = await fixture(layout); + + const input = control.renderRoot.querySelector('vaadin-text-field')?.querySelector('input'); + if (!input) return; + + const focusStub = stub(input, 'focus'); + const button = document.createElement('button'); + + const mockEvent = new MouseEvent('click', { bubbles: true }); + Object.defineProperty(mockEvent, 'composedPath', { + value: () => [button], + }); + + // @ts-expect-error accessing protected member for testing purposes + control._handleHostClick(mockEvent); + + expect(focusStub).to.not.have.been.called; + + focusStub.restore(); + }); }); diff --git a/src/elements/internal/InternalTextControl/InternalTextControl.ts b/src/elements/internal/InternalTextControl/InternalTextControl.ts index 5a11b1d5..1e3e5c1e 100644 --- a/src/elements/internal/InternalTextControl/InternalTextControl.ts +++ b/src/elements/internal/InternalTextControl/InternalTextControl.ts @@ -91,7 +91,7 @@ export class InternalTextControl extends InternalEditableControl { protected _handleHostClick(evt: MouseEvent): void { if (this.layout !== 'summary-item') return; const composedPath = evt.composedPath() as HTMLElement[]; - const noOp = new Set(['INPUT', 'LABEL']); + const noOp = new Set(['INPUT', 'LABEL', 'BUTTON']); if (!composedPath.some(el => noOp.has(el.tagName))) { this.renderRoot.querySelector('input')?.focus(); super._handleHostClick(evt);