From 22567ed5e99639f61ccaa543a913febd538daff8 Mon Sep 17 00:00:00 2001 From: Keita Nonaka Date: Tue, 5 Jul 2022 06:26:04 -0700 Subject: [PATCH] [DataGrid] Fix "stop editing" integration with IME e.g. Japanese (#5257) Co-authored-by: Matheus Wichman --- .../cellEditing.DataGridPro.new.test.tsx | 32 +++++++++++++++++++ .../tests/rowEditing.DataGridPro.new.test.tsx | 32 +++++++++++++++++++ .../tests/rowEditing.DataGridPro.old.test.tsx | 22 +++++++++++++ .../editRows/useGridCellEditing.new.ts | 6 ++++ .../editRows/useGridCellEditing.old.ts | 6 ++++ .../editRows/useGridRowEditing.new.ts | 6 ++++ .../editRows/useGridRowEditing.old.ts | 6 ++++ 7 files changed, 110 insertions(+) diff --git a/packages/grid/x-data-grid-pro/src/tests/cellEditing.DataGridPro.new.test.tsx b/packages/grid/x-data-grid-pro/src/tests/cellEditing.DataGridPro.new.test.tsx index 1a126c49be56..c1b8980b6793 100644 --- a/packages/grid/x-data-grid-pro/src/tests/cellEditing.DataGridPro.new.test.tsx +++ b/packages/grid/x-data-grid-pro/src/tests/cellEditing.DataGridPro.new.test.tsx @@ -726,6 +726,38 @@ describe(' - Cell Editing', () => { deleteValue: true, }); }); + + it(`should ignore keydown event until the IME is confirmed with a letter`, () => { + render(); + const listener = spy(); + apiRef.current.subscribeEvent('cellEditStop', listener); + const cell = getCell(0, 1); + fireEvent.doubleClick(cell); + const input = cell.querySelector('input')!; + fireEvent.change(input, { target: { value: 'あ' } }); + fireEvent.keyDown(cell, { key: 'Enter', keyCode: 229 }); + expect(listener.callCount).to.equal(0); + fireEvent.keyDown(cell, { key: 'Enter', keyCode: 13 }); + expect(listener.callCount).to.equal(1); + expect(input.value).to.equal('あ'); + expect(listener.lastCall.args[0].reason).to.equal('enterKeyDown'); + }); + + it(`should ignore keydown event until the IME is confirmed with multiple letters`, () => { + render(); + const listener = spy(); + apiRef.current.subscribeEvent('cellEditStop', listener); + const cell = getCell(0, 1); + fireEvent.doubleClick(cell); + const input = cell.querySelector('input')!; + fireEvent.change(input, { target: { value: 'ありがとう' } }); + fireEvent.keyDown(cell, { key: 'Enter', keyCode: 229 }); + expect(listener.callCount).to.equal(0); + fireEvent.keyDown(cell, { key: 'Enter', keyCode: 13 }); + expect(listener.callCount).to.equal(1); + expect(input.value).to.equal('ありがとう'); + expect(listener.lastCall.args[0].reason).to.equal('enterKeyDown'); + }); }); }); diff --git a/packages/grid/x-data-grid-pro/src/tests/rowEditing.DataGridPro.new.test.tsx b/packages/grid/x-data-grid-pro/src/tests/rowEditing.DataGridPro.new.test.tsx index 9c5c611fd581..8325c9375167 100644 --- a/packages/grid/x-data-grid-pro/src/tests/rowEditing.DataGridPro.new.test.tsx +++ b/packages/grid/x-data-grid-pro/src/tests/rowEditing.DataGridPro.new.test.tsx @@ -728,6 +728,38 @@ describe(' - Row Editing', () => { deleteValue: true, }); }); + + it(`should ignore keydown event until the IME is confirmed with a letter`, () => { + render(); + const listener = spy(); + apiRef.current.subscribeEvent('rowEditStop', listener); + const cell = getCell(0, 1); + fireEvent.doubleClick(cell); + const input = cell.querySelector('input')!; + fireEvent.change(input, { target: { value: 'あ' } }); + fireEvent.keyDown(input, { key: 'Enter', keyCode: 229 }); + expect(listener.callCount).to.equal(0); + fireEvent.keyDown(input, { key: 'Enter', keyCode: 13 }); + expect(listener.callCount).to.equal(1); + expect(input.value).to.equal('あ'); + expect(listener.lastCall.args[0].reason).to.equal('enterKeyDown'); + }); + + it(`should ignore keydown event until the IME is confirmed with multiple letters`, () => { + render(); + const listener = spy(); + apiRef.current.subscribeEvent('rowEditStop', listener); + const cell = getCell(0, 1); + fireEvent.doubleClick(cell); + const input = cell.querySelector('input')!; + fireEvent.change(input, { target: { value: 'ありがとう' } }); + fireEvent.keyDown(input, { key: 'Enter', keyCode: 229 }); + expect(listener.callCount).to.equal(0); + fireEvent.keyDown(input, { key: 'Enter', keyCode: 13 }); + expect(listener.callCount).to.equal(1); + expect(input.value).to.equal('ありがとう'); + expect(listener.lastCall.args[0].reason).to.equal('enterKeyDown'); + }); }); }); diff --git a/packages/grid/x-data-grid-pro/src/tests/rowEditing.DataGridPro.old.test.tsx b/packages/grid/x-data-grid-pro/src/tests/rowEditing.DataGridPro.old.test.tsx index 6a982cdd98bf..1e80994d7cb4 100644 --- a/packages/grid/x-data-grid-pro/src/tests/rowEditing.DataGridPro.old.test.tsx +++ b/packages/grid/x-data-grid-pro/src/tests/rowEditing.DataGridPro.old.test.tsx @@ -447,4 +447,26 @@ describe(' - Row Editing', () => { clock.runToLast(); expect(getRow(1)).not.to.have.class('MuiDataGrid-row--editing'); }); + + it(`should ignore keydown event until the IME is confirmed`, () => { + const valueSetter = spy(({ row }) => row); + render( + , + ); + + const cell = getCell(0, 0); + fireEvent.doubleClick(cell); + const input = cell.querySelector('input')!; + expect(input!.value).to.equal('こんにちは'); + fireEvent.change(input, { target: { value: 'あ' } }); + fireEvent.keyDown(input, { key: 'Enter', keyCode: 229 }); + expect(valueSetter.callCount).to.equal(0); + fireEvent.keyDown(input, { key: 'Enter', keyCode: 13 }); + expect(valueSetter.callCount).to.equal(1); + expect(input!.value).to.equal('あ'); + }); }); diff --git a/packages/grid/x-data-grid/src/hooks/features/editRows/useGridCellEditing.new.ts b/packages/grid/x-data-grid/src/hooks/features/editRows/useGridCellEditing.new.ts index 9c7eb6ced3a5..c0988ce0aec4 100644 --- a/packages/grid/x-data-grid/src/hooks/features/editRows/useGridCellEditing.new.ts +++ b/packages/grid/x-data-grid/src/hooks/features/editRows/useGridCellEditing.new.ts @@ -125,6 +125,12 @@ export const useGridCellEditing = ( const handleCellKeyDown = React.useCallback>( (params, event) => { if (params.cellMode === GridCellModes.Edit) { + // Wait until IME is settled for Asian languages like Japanese and Chinese + // TODO: `event.which` is depricated but this is a temporary workaround + if (event.which === 229) { + return; + } + let reason: GridCellEditStopReasons | undefined; if (event.key === 'Escape') { diff --git a/packages/grid/x-data-grid/src/hooks/features/editRows/useGridCellEditing.old.ts b/packages/grid/x-data-grid/src/hooks/features/editRows/useGridCellEditing.old.ts index f0bb25e1357b..8054e38166af 100644 --- a/packages/grid/x-data-grid/src/hooks/features/editRows/useGridCellEditing.old.ts +++ b/packages/grid/x-data-grid/src/hooks/features/editRows/useGridCellEditing.old.ts @@ -208,6 +208,12 @@ export const useCellEditing = ( const handleCellKeyDown = React.useCallback>( async (params, event) => { + // Wait until IME is settled for Asian languages like Japanese and Chinese + // TODO: `event.which` is depricated but this is a temporary workaround + if (event.which === 229) { + return; + } + const { id, field, cellMode, isEditable } = params; if (!isEditable) { return; diff --git a/packages/grid/x-data-grid/src/hooks/features/editRows/useGridRowEditing.new.ts b/packages/grid/x-data-grid/src/hooks/features/editRows/useGridRowEditing.new.ts index 4e2c056e2b9d..370771a468c1 100644 --- a/packages/grid/x-data-grid/src/hooks/features/editRows/useGridRowEditing.new.ts +++ b/packages/grid/x-data-grid/src/hooks/features/editRows/useGridRowEditing.new.ts @@ -167,6 +167,12 @@ export const useGridRowEditing = ( const handleCellKeyDown = React.useCallback>( (params, event) => { if (params.cellMode === GridRowModes.Edit) { + // Wait until IME is settled for Asian languages like Japanese and Chinese + // TODO: `event.which` is depricated but this is a temporary workaround + if (event.which === 229) { + return; + } + let reason: GridRowEditStopReasons | undefined; if (event.key === 'Escape') { diff --git a/packages/grid/x-data-grid/src/hooks/features/editRows/useGridRowEditing.old.ts b/packages/grid/x-data-grid/src/hooks/features/editRows/useGridRowEditing.old.ts index 90715d4bee22..a96ff6132e0d 100644 --- a/packages/grid/x-data-grid/src/hooks/features/editRows/useGridRowEditing.old.ts +++ b/packages/grid/x-data-grid/src/hooks/features/editRows/useGridRowEditing.old.ts @@ -212,6 +212,12 @@ export const useGridRowEditing = ( const handleCellKeyDown = React.useCallback>( async (params, event) => { + // Wait until IME is settled for Asian languages like Japanese and Chinese + // TODO: `event.which` is depricated but this is a temporary workaround + if (event.which === 229) { + return; + } + const { cellMode, isEditable } = params; if (!isEditable) { return;