diff --git a/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts b/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts index bd7b7ef4aa38..95e34b2f9e60 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts @@ -548,9 +548,11 @@ export class KeyboardNavigationController extends modules.ViewController { } private _closeEditCell() { + const d = Deferred(); setTimeout(() => { - this._editingController.closeEditCell(); + this._editingController.closeEditCell().always(d.resolve); }); + return d; } /** @@ -1039,12 +1041,13 @@ export class KeyboardNavigationController extends modules.ViewController { const allowEditingOnEnterKey = this._allowEditingOnEnterKey(); if (isEditing || (!allowEditingOnEnterKey && direction)) { - this._handleEnterKeyEditingCell(eventArgs.originalEvent); - if (direction === 'next' || direction === 'previous') { - this._targetCellTabHandler(eventArgs, direction); - } else if (direction === 'upArrow' || direction === 'downArrow') { - this._navigateNextCell(eventArgs.originalEvent, direction); - } + this._handleEnterKeyEditingCell(eventArgs.originalEvent).done(() => { + if (direction === 'next' || direction === 'previous') { + this._targetCellTabHandler(eventArgs, direction); + } else if (direction === 'upArrow' || direction === 'downArrow') { + this._navigateNextCell(eventArgs.originalEvent, direction); + } + }); } else if (allowEditingOnEnterKey) { this._startEditing(eventArgs); } @@ -1067,6 +1070,7 @@ export class KeyboardNavigationController extends modules.ViewController { } private _handleEnterKeyEditingCell(event) { + const d = Deferred(); const { target } = event; const $cell = this._getCellElementFromTarget(target); const isRowEditMode = this._isRowEditMode(); @@ -1078,13 +1082,16 @@ export class KeyboardNavigationController extends modules.ViewController { setTimeout( this._editingController.saveEditData.bind(this._editingController), ); + d.resolve(); } else { // @ts-expect-error eventsEngine.trigger($(target), 'change'); - this._closeEditCell(); + // eslint-disable-next-line @typescript-eslint/no-misused-promises + this._closeEditCell().always(d.resolve); event.preventDefault(); } + return d; } /** diff --git a/packages/devextreme/testing/testcafe/tests/dataGrid/keyboardNavigation/editOnKeyPress.screenshots.ts b/packages/devextreme/testing/testcafe/tests/dataGrid/keyboardNavigation/editOnKeyPress.screenshots.ts index 1afbabc06f94..3cac6958fb49 100644 --- a/packages/devextreme/testing/testcafe/tests/dataGrid/keyboardNavigation/editOnKeyPress.screenshots.ts +++ b/packages/devextreme/testing/testcafe/tests/dataGrid/keyboardNavigation/editOnKeyPress.screenshots.ts @@ -1,4 +1,5 @@ import { createScreenshotsComparer } from 'devextreme-screenshot-comparer'; +import { ClientFunction } from 'testcafe'; import url from '../../../helpers/getPageUrl'; import { createWidget } from '../../../helpers/createWidget'; import DataGrid from '../../../model/dataGrid'; @@ -62,3 +63,75 @@ const DATA_GRID_SELECTOR = '#container'; await makeRowsViewTemplatesAsync(DATA_GRID_SELECTOR); }); }); + +test('Focused cell should not flick (T1206435)', async (t) => { + type TestWindow = (typeof window) & { + counter?: number; + }; + + const dataGrid = new DataGrid(DATA_GRID_SELECTOR); + const firstCell = dataGrid.getDataCell(0, 0).element; + const secondCell = dataGrid.getDataCell(1, 0).element; + const getFocusEventCount = ClientFunction( + () => (window as TestWindow).counter, + ); + + await ClientFunction(() => { + const testWindow = window as TestWindow; + testWindow.counter = 0; + (secondCell() as any as HTMLElement).addEventListener('focusin', () => { + testWindow.counter! += 1; + }); + }, { + dependencies: { secondCell }, + })(); + + await t.click(firstCell); + + await t.pressKey('M'); + await t.pressKey('enter'); + + await t.expect(secondCell.focused).ok(); + + const focusEventCount = await getFocusEventCount(); + await t.expect(focusEventCount).eql(1); + + await ClientFunction(() => { + delete (window as TestWindow).counter; + })(); +}).before(async () => { + await createWidget('dxDataGrid', () => { + const data = [ + { value: 'data' }, + { value: 'data' }, + ]; + return { + dataSource: new (window as any).DevExpress.data.CustomStore({ + load() { + return Promise.resolve(data); + }, + update() { + return new Promise((res) => { + setTimeout(() => { + res(); + }, 100); + }); + }, + }), + keyboardNavigation: { + enabled: true, + editOnKeyPress: true, + enterKeyAction: 'moveFocus', + enterKeyDirection: 'column', + }, + editing: { + mode: 'cell', + allowUpdating: true, + allowAdding: true, + startEditAction: 'dblClick', + refreshMode: 'reshape', + }, + repaintChangesOnly: true, + }; + }); +}); diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/keyboardNavigation.customization.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/keyboardNavigation.customization.tests.js index ead0c7800fa3..1bcf160b6b9c 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/keyboardNavigation.customization.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/keyboardNavigation.customization.tests.js @@ -1066,7 +1066,7 @@ QUnit.module('Customize keyboard navigation', { assert.equal($editor.find('.dx-texteditor-input').val(), 'D', 'input value'); // act - this.triggerKeyDown('enter'); + this.triggerKeyDown('enter', false, false, $editor.find('input')); this.clock.tick(10); $editor = $('.dx-texteditor').eq(0); @@ -1117,7 +1117,7 @@ QUnit.module('Customize keyboard navigation', { assert.equal($editor.find('.dx-texteditor-input').val(), 'D', 'input value'); // act - this.triggerKeyDown('enter'); + this.triggerKeyDown('enter', false, false, $editor.find('input')); this.clock.tick(10); $editor = $('.dx-texteditor').eq(0); @@ -1169,7 +1169,7 @@ QUnit.module('Customize keyboard navigation', { assert.equal($editor.find('.dx-texteditor-input').val(), 'D', 'input value'); // act - this.triggerKeyDown('enter'); + this.triggerKeyDown('enter', false, false, $editor.find('input')); this.clock.tick(10); $editor = $('.dx-texteditor').eq(0); @@ -1220,7 +1220,7 @@ QUnit.module('Customize keyboard navigation', { assert.equal($editor.find('.dx-texteditor-input').val(), 'D', 'input value'); // act - this.triggerKeyDown('enter'); + this.triggerKeyDown('enter', false, false, $editor.find('input')); this.clock.tick(10); $editor = $('.dx-texteditor').eq(0); @@ -1272,7 +1272,7 @@ QUnit.module('Customize keyboard navigation', { assert.equal($editor.find('.dx-texteditor-input').val(), 'D', 'input value'); // act - this.triggerKeyDown('enter'); + this.triggerKeyDown('enter', false, false, $editor.find('input')); this.clock.tick(10); $editor = $('.dx-texteditor').eq(0); @@ -2007,7 +2007,7 @@ QUnit.module('Customize keyboard navigation', { assert.ok(this.keyboardNavigationController._isFastEditingStarted(), 'Fast editing mode'); assert.equal($input.val(), '#_1.00', 'input value'); - this.triggerKeyDown('enter'); + this.triggerKeyDown('enter', false, false, $input); this.clock.tick(10); // arrange, assert