From b74f8a5bbdaca9f044b682e140019a901ff6b545 Mon Sep 17 00:00:00 2001 From: web-padawan Date: Wed, 25 Sep 2024 12:25:50 +0300 Subject: [PATCH] fix: update logic to not close on Tab between pickers --- .../vaadin-grid-pro-inline-editing-mixin.js | 29 ++++++++++++++----- .../grid-pro-custom-editor.test.js | 28 +++++++++++++----- 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/packages/grid-pro/src/vaadin-grid-pro-inline-editing-mixin.js b/packages/grid-pro/src/vaadin-grid-pro-inline-editing-mixin.js index dcf14876ad..1a2c0c6cf7 100644 --- a/packages/grid-pro/src/vaadin-grid-pro-inline-editing-mixin.js +++ b/packages/grid-pro/src/vaadin-grid-pro-inline-editing-mixin.js @@ -306,10 +306,16 @@ export const InlineEditingMixin = (superClass) => /** @private */ _onEditorFocusOut(event) { // Ignore focusout from internal tab event - if (this.__cancelCellSwitch) { + if (this.__cancelCellSwitch || this.__shouldIgnoreFocusOut(event)) { return; } + // Schedule stop on editor component focusout + this._debouncerStopEdit = Debouncer.debounce(this._debouncerStopEdit, animationFrame, this._stopEdit.bind(this)); + } + + /** @private */ + __shouldIgnoreFocusOut(event) { const edited = this.__edited; if (edited) { const { cell, column } = this.__edited; @@ -319,12 +325,9 @@ export const InlineEditingMixin = (superClass) => const nodes = path.slice(0, path.indexOf(editor) + 1).filter((node) => node.nodeType === Node.ELEMENT_NODE); // Detect focus moving to e.g. vaadin-select-overlay or vaadin-date-picker-overlay if (nodes.some((el) => typeof el._shouldRemoveFocus === 'function' && !el._shouldRemoveFocus(event))) { - return; + return true; } } - - // Schedule stop on editor component focusout - this._debouncerStopEdit = Debouncer.debounce(this._debouncerStopEdit, animationFrame, this._stopEdit.bind(this)); } /** @private */ @@ -443,9 +446,21 @@ export const InlineEditingMixin = (superClass) => // Do not prevent Tab to allow native input blur and wait for it, // unless the keydown event is from the edit cell select overlay. if (e.key === 'Tab' && editor && editor.contains(e.target)) { - await new Promise((resolve) => { - editor.addEventListener('focusout', () => resolve(), { once: true }); + const ignore = await new Promise((resolve) => { + editor.addEventListener( + 'focusout', + (event) => { + resolve(this.__shouldIgnoreFocusOut(event)); + }, + { once: true }, + ); }); + + // Ignore focusout event after which focus stays in the field, + // e.g. Tab between date and time pickers in date-time-picker. + if (ignore) { + return; + } } else { e.preventDefault(); } diff --git a/test/integration/grid-pro-custom-editor.test.js b/test/integration/grid-pro-custom-editor.test.js index 1c5d32be6e..aad25302a5 100644 --- a/test/integration/grid-pro-custom-editor.test.js +++ b/test/integration/grid-pro-custom-editor.test.js @@ -226,7 +226,21 @@ describe('grid-pro custom editor', () => { await sendKeys({ press: 'Enter' }); }); - it('should stop editing and update value when closing on date-picker outside click', async () => { + it('should not stop editing when switching between pickers using Tab', async () => { + // Move focus to the time-picker + await sendKeys({ press: 'Tab' }); + await nextRender(); + expect(cell._content.querySelector('vaadin-date-time-picker')).to.be.ok; + + // Move focus to the date-picker + await sendKeys({ down: 'Shift' }); + await sendKeys({ press: 'Tab' }); + await sendKeys({ up: 'Shift' }); + await nextRender(); + expect(cell._content.querySelector('vaadin-date-time-picker')).to.be.ok; + }); + + it('should not stop editing and update value when closing on date-picker outside click', async () => { await sendKeys({ press: 'ArrowDown' }); await waitForOverlayRender(); @@ -244,16 +258,13 @@ describe('grid-pro custom editor', () => { await sendMouse({ type: 'click', position: [10, 10] }); await nextRender(); - // TODO: closing occurs in `vaadin-overlay-outside-click` listener added on global `focusin` - // in grid-pro. Consider replacing it with `_shouldRemoveFocus()` check on editor `focusout` - // so that we don't stop editing on outside click, to align with the combo-box behavior. - expect(cell._content.querySelector('vaadin-date-time-picker')).to.be.not.ok; - expect(cell._content.textContent).to.equal('1984-01-12T09:00'); + const editor = cell._content.querySelector('vaadin-date-time-picker'); + expect(editor).to.be.ok; + expect(editor.value).to.equal('1984-01-12T09:00'); }); it('should not stop editing and update value when closing on time-picker outside click', async () => { - // TODO: replace with Tab and add a separate test to not stop editing on Tab - cell._content.querySelector('vaadin-time-picker').focus(); + await sendKeys({ press: 'Tab' }); // Open the overlay await sendKeys({ press: 'ArrowDown' }); @@ -262,6 +273,7 @@ describe('grid-pro custom editor', () => { await sendKeys({ press: 'ArrowDown' }); await sendMouse({ type: 'click', position: [10, 10] }); + await nextRender(); const editor = cell._content.querySelector('vaadin-date-time-picker'); expect(editor).to.be.ok;