diff --git a/packages/x-data-grid-premium/src/tests/clipboard.DataGridPremium.test.tsx b/packages/x-data-grid-premium/src/tests/clipboard.DataGridPremium.test.tsx
index b0c31797af376..3b4c67048c675 100644
--- a/packages/x-data-grid-premium/src/tests/clipboard.DataGridPremium.test.tsx
+++ b/packages/x-data-grid-premium/src/tests/clipboard.DataGridPremium.test.tsx
@@ -184,7 +184,7 @@ describe(' - Clipboard', () => {
getData: () => pasteText,
};
- fireEvent.keyDown(cell, { key: 'v', code: 'KeyV', keyCode: 86, ctrlKey: true }); // Ctrl+V
+ fireEvent.keyDown(cell, { key: 'v', keyCode: 86, ctrlKey: true }); // Ctrl+V
document.activeElement!.dispatchEvent(pasteEvent);
}
@@ -196,7 +196,7 @@ describe(' - Clipboard', () => {
apiRef.current.subscribeEvent('cellEditStart', listener);
const cell = getCell(0, 1);
fireUserEvent.mousePress(cell);
- fireEvent.keyDown(cell, { key: 'v', code: 'KeyV', keyCode: 86, [key]: true }); // Ctrl+V
+ fireEvent.keyDown(cell, { key: 'v', keyCode: 86, [key]: true }); // Ctrl+V
expect(listener.callCount).to.equal(0);
});
});
@@ -209,7 +209,7 @@ describe(' - Clipboard', () => {
apiRef.current.subscribeEvent('rowEditStart', listener);
const cell = getCell(0, 1);
fireUserEvent.mousePress(cell);
- fireEvent.keyDown(cell, { key: 'v', code: 'KeyV', keyCode: 86, [key]: true }); // Ctrl+V
+ fireEvent.keyDown(cell, { key: 'v', keyCode: 86, [key]: true }); // Ctrl+V
expect(listener.callCount).to.equal(0);
});
});
diff --git a/packages/x-data-grid-pro/src/tests/cellEditing.DataGridPro.test.tsx b/packages/x-data-grid-pro/src/tests/cellEditing.DataGridPro.test.tsx
index 61eb25906561a..b86470859ce5e 100644
--- a/packages/x-data-grid-pro/src/tests/cellEditing.DataGridPro.test.tsx
+++ b/packages/x-data-grid-pro/src/tests/cellEditing.DataGridPro.test.tsx
@@ -890,7 +890,7 @@ describe(' - Cell editing', () => {
apiRef.current.subscribeEvent('cellEditStart', listener);
const cell = getCell(0, 0);
fireUserEvent.mousePress(cell);
- fireEvent.keyDown(cell, { key: 'a' }); // A
+ fireEvent.keyDown(cell, { key: 'a', keyCode: 65 }); // A
expect(listener.callCount).to.equal(0);
});
@@ -901,7 +901,7 @@ describe(' - Cell editing', () => {
apiRef.current.subscribeEvent('cellEditStart', listener);
const cell = getCell(0, 1);
fireUserEvent.mousePress(cell);
- fireEvent.keyDown(cell, { key: 'a', [key]: true }); // for example Ctrl + A, copy
+ fireEvent.keyDown(cell, { key: 'a', keyCode: 65, [key]: true }); // for example Ctrl + A, copy
expect(listener.callCount).to.equal(0);
});
});
@@ -912,7 +912,7 @@ describe(' - Cell editing', () => {
apiRef.current.subscribeEvent('cellEditStart', listener);
const cell = getCell(0, 1);
fireUserEvent.mousePress(cell);
- fireEvent.keyDown(cell, { key: 'a', shiftKey: true }); // Print A in uppercase
+ fireEvent.keyDown(cell, { key: 'a', keyCode: 65, shiftKey: true }); // Print A in uppercase
expect(listener.callCount).to.equal(1);
});
@@ -922,7 +922,7 @@ describe(' - Cell editing', () => {
apiRef.current.subscribeEvent('cellEditStart', listener);
const cell = getCell(0, 1);
fireUserEvent.mousePress(cell);
- fireEvent.keyDown(cell, { key: 'v', ctrlKey: true }); // Ctrl+V
+ fireEvent.keyDown(cell, { key: 'v', keyCode: 86, ctrlKey: true }); // Ctrl+V
expect(listener.callCount).to.equal(1);
});
diff --git a/packages/x-data-grid-pro/src/tests/rowEditing.DataGridPro.test.tsx b/packages/x-data-grid-pro/src/tests/rowEditing.DataGridPro.test.tsx
index d469b0bb87a29..56894a1d406c4 100644
--- a/packages/x-data-grid-pro/src/tests/rowEditing.DataGridPro.test.tsx
+++ b/packages/x-data-grid-pro/src/tests/rowEditing.DataGridPro.test.tsx
@@ -874,7 +874,7 @@ describe(' - Row editing', () => {
apiRef.current.subscribeEvent('rowEditStart', listener);
const cell = getCell(0, 1);
fireUserEvent.mousePress(cell);
- fireEvent.keyDown(cell, { key: 'a', [key]: true });
+ fireEvent.keyDown(cell, { key: 'a', keyCode: 65, [key]: true });
expect(listener.callCount).to.equal(0);
});
});
@@ -885,7 +885,7 @@ describe(' - Row editing', () => {
apiRef.current.subscribeEvent('rowEditStart', listener);
const cell = getCell(0, 1);
fireUserEvent.mousePress(cell);
- fireEvent.keyDown(cell, { key: 'a', shiftKey: true });
+ fireEvent.keyDown(cell, { key: 'a', keyCode: 65, shiftKey: true });
expect(listener.callCount).to.equal(1);
});
@@ -905,7 +905,7 @@ describe(' - Row editing', () => {
apiRef.current.subscribeEvent('rowEditStart', listener);
const cell = getCell(0, 1);
fireUserEvent.mousePress(cell);
- fireEvent.keyDown(cell, { key: 'v', ctrlKey: true });
+ fireEvent.keyDown(cell, { key: 'v', keyCode: 86, ctrlKey: true });
expect(listener.callCount).to.equal(1);
});
diff --git a/packages/x-data-grid/src/hooks/features/clipboard/useGridClipboard.ts b/packages/x-data-grid/src/hooks/features/clipboard/useGridClipboard.ts
index 35e8e6081f97c..274be843d9f35 100644
--- a/packages/x-data-grid/src/hooks/features/clipboard/useGridClipboard.ts
+++ b/packages/x-data-grid/src/hooks/features/clipboard/useGridClipboard.ts
@@ -4,6 +4,7 @@ import { useGridApiOptionHandler, useGridNativeEventListener } from '../../utils
import { gridFocusCellSelector } from '../focus/gridFocusStateSelector';
import { serializeCellValue } from '../export/serializers/csvSerializer';
import type { DataGridProcessedProps } from '../../../models/props/DataGridProps';
+import { isCopyShortcut } from '../../../utils/keyboardUtils';
function writeToClipboardPolyfill(data: string) {
const span = document.createElement('span');
@@ -74,14 +75,7 @@ export const useGridClipboard = (
const handleCopy = React.useCallback(
(event: KeyboardEvent) => {
- if (
- !(
- (event.ctrlKey || event.metaKey) &&
- event.key.toLowerCase() === 'c' &&
- !event.shiftKey &&
- !event.altKey
- )
- ) {
+ if (!isCopyShortcut(event)) {
return;
}
diff --git a/packages/x-data-grid/src/hooks/features/rowSelection/useGridRowSelection.ts b/packages/x-data-grid/src/hooks/features/rowSelection/useGridRowSelection.ts
index d50883fa5c366..9586053329947 100644
--- a/packages/x-data-grid/src/hooks/features/rowSelection/useGridRowSelection.ts
+++ b/packages/x-data-grid/src/hooks/features/rowSelection/useGridRowSelection.ts
@@ -673,7 +673,7 @@ export const useGridRowSelection = (
return;
}
- if (event.key === 'a' && (event.ctrlKey || event.metaKey)) {
+ if (String.fromCharCode(event.keyCode) === 'A' && (event.ctrlKey || event.metaKey)) {
event.preventDefault();
selectRows(apiRef.current.getAllRowIds(), true);
}
diff --git a/packages/x-data-grid/src/internals/index.ts b/packages/x-data-grid/src/internals/index.ts
index 7463a879c2f63..116388732fe46 100644
--- a/packages/x-data-grid/src/internals/index.ts
+++ b/packages/x-data-grid/src/internals/index.ts
@@ -157,7 +157,7 @@ export {
getActiveElement,
isEventTargetInPortal,
} from '../utils/domUtils';
-export { isNavigationKey, isPasteShortcut } from '../utils/keyboardUtils';
+export { isNavigationKey, isPasteShortcut, isCopyShortcut } from '../utils/keyboardUtils';
export * from '../utils/utils';
export { exportAs } from '../utils/exportAs';
export * from '../utils/getPublicApiRef';
diff --git a/packages/x-data-grid/src/utils/keyboardUtils.ts b/packages/x-data-grid/src/utils/keyboardUtils.ts
index c70617d75671b..9c41f6ff5a52e 100644
--- a/packages/x-data-grid/src/utils/keyboardUtils.ts
+++ b/packages/x-data-grid/src/utils/keyboardUtils.ts
@@ -45,13 +45,25 @@ export const isHideMenuKey = (key: React.KeyboardEvent['key']) => key === 'Tab'
// In theory, on macOS, ctrl + v doesn't trigger a paste, so the function should return false.
// However, maybe it's overkill to fix, so let's be lazy.
export function isPasteShortcut(event: React.KeyboardEvent) {
- if (
+ return (
(event.ctrlKey || event.metaKey) &&
- event.key.toLowerCase() === 'v' &&
+ // We can't use event.code === 'KeyV' as event.code assumes a QWERTY keyboard layout,
+ // for example, it would be another letter on a Dvorak physical keyboard.
+ // We can't use event.key === 'v' as event.key is not stable with key modifiers and keyboard layouts,
+ // for example, it would be ה on a Hebrew keyboard layout.
+ // https://github.com/w3c/uievents/issues/377 could be a long-term solution
+ String.fromCharCode(event.keyCode) === 'V' &&
!event.shiftKey &&
!event.altKey
- ) {
- return true;
- }
- return false;
+ );
+}
+
+// Checks if the keyboard event corresponds to the copy shortcut (CTRL+C or CMD+C) across different localization keyboards.
+export function isCopyShortcut(event: KeyboardEvent): boolean {
+ return (
+ (event.ctrlKey || event.metaKey) &&
+ String.fromCharCode(event.keyCode) === 'C' &&
+ !event.shiftKey &&
+ !event.altKey
+ );
}
diff --git a/packages/x-date-pickers-pro/src/SingleInputDateRangeField/tests/editing.SingleInputDateRangeField.test.tsx b/packages/x-date-pickers-pro/src/SingleInputDateRangeField/tests/editing.SingleInputDateRangeField.test.tsx
index b392a9d809845..d325d56d82aff 100644
--- a/packages/x-date-pickers-pro/src/SingleInputDateRangeField/tests/editing.SingleInputDateRangeField.test.tsx
+++ b/packages/x-date-pickers-pro/src/SingleInputDateRangeField/tests/editing.SingleInputDateRangeField.test.tsx
@@ -22,7 +22,11 @@ describe(' - Editing', () => {
view.selectSection('month');
// Select all sections
- fireEvent.keyDown(view.getActiveSection(0), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getActiveSection(0), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
fireEvent.keyDown(view.getSectionsContainer(), { key: 'Delete' });
expectFieldValueV7(view.getSectionsContainer(), 'MMMM YYYY – MMMM YYYY');
@@ -40,7 +44,7 @@ describe(' - Editing', () => {
view.selectSection('month');
// Select all sections
- fireEvent.keyDown(input, { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(input, { key: 'a', keyCode: 65, ctrlKey: true });
fireEvent.keyDown(input, { key: 'Delete' });
expectFieldValueV6(input, 'MMMM YYYY – MMMM YYYY');
@@ -60,7 +64,11 @@ describe(' - Editing', () => {
expectFieldValueV7(view.getSectionsContainer(), 'January YYYY – MMMM YYYY');
// Select all sections
- fireEvent.keyDown(view.getActiveSection(0), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getActiveSection(0), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
fireEvent.keyDown(view.getSectionsContainer(), { key: 'Delete' });
expectFieldValueV7(view.getSectionsContainer(), 'MMMM YYYY – MMMM YYYY');
@@ -83,7 +91,7 @@ describe(' - Editing', () => {
expectFieldValueV6(input, 'January YYYY – MMMM YYYY');
// Select all sections
- fireEvent.keyDown(input, { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(input, { key: 'a', keyCode: 65, ctrlKey: true });
fireEvent.keyDown(input, { key: 'Delete' });
expectFieldValueV6(input, 'MMMM YYYY – MMMM YYYY');
@@ -102,7 +110,11 @@ describe(' - Editing', () => {
view.selectSection('month');
// Select all sections
- fireEvent.keyDown(view.getActiveSection(0), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getActiveSection(0), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
fireEvent.keyDown(view.getSectionsContainer(), { key: 'Delete' });
expect(onChangeV7.callCount).to.equal(0);
@@ -122,7 +134,7 @@ describe(' - Editing', () => {
view.selectSection('month');
// Select all sections
- fireEvent.keyDown(input, { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(input, { key: 'a', keyCode: 65, ctrlKey: true });
fireEvent.keyDown(input, { key: 'Delete' });
expect(onChangeV6.callCount).to.equal(0);
@@ -262,7 +274,11 @@ describe(' - Editing', () => {
view.selectSection('month');
// Select all sections
- fireEvent.keyDown(view.getActiveSection(0), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getActiveSection(0), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
view.pressKey(null, '');
expectFieldValueV7(view.getSectionsContainer(), 'MMMM YYYY – MMMM YYYY');
@@ -280,7 +296,7 @@ describe(' - Editing', () => {
view.selectSection('month');
// Select all sections
- fireEvent.keyDown(input, { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(input, { key: 'a', keyCode: 65, ctrlKey: true });
fireEvent.change(input, { target: { value: '' } });
expectFieldValueV6(input, 'MMMM YYYY – MMMM YYYY');
@@ -300,7 +316,11 @@ describe(' - Editing', () => {
expectFieldValueV7(view.getSectionsContainer(), 'January YYYY – MMMM YYYY');
// Select all sections
- fireEvent.keyDown(view.getActiveSection(0), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getActiveSection(0), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
view.pressKey(null, '');
expectFieldValueV7(view.getSectionsContainer(), 'MMMM YYYY – MMMM YYYY');
@@ -323,7 +343,7 @@ describe(' - Editing', () => {
expectFieldValueV6(input, 'January YYYY – MMMM YYYY');
// Select all sections
- fireEvent.keyDown(input, { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(input, { key: 'a', keyCode: 65, ctrlKey: true });
fireEvent.change(input, { target: { value: '' } });
expectFieldValueV6(input, 'MMMM YYYY – MMMM YYYY');
@@ -342,7 +362,11 @@ describe(' - Editing', () => {
view.selectSection('month');
// Select all sections
- fireEvent.keyDown(view.getActiveSection(0), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getActiveSection(0), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
view.pressKey(null, '');
expect(onChangeV7.callCount).to.equal(0);
@@ -362,7 +386,7 @@ describe(' - Editing', () => {
view.selectSection('month');
// Select all sections
- fireEvent.keyDown(input, { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(input, { key: 'a', keyCode: 65, ctrlKey: true });
fireEvent.change(input, { target: { value: 'Delete' } });
expect(onChangeV6.callCount).to.equal(0);
diff --git a/packages/x-date-pickers/src/DateField/tests/editing.DateField.test.tsx b/packages/x-date-pickers/src/DateField/tests/editing.DateField.test.tsx
index b5140fdffb725..fafafc44a61e5 100644
--- a/packages/x-date-pickers/src/DateField/tests/editing.DateField.test.tsx
+++ b/packages/x-date-pickers/src/DateField/tests/editing.DateField.test.tsx
@@ -269,7 +269,11 @@ describe(' - Editing', () => {
view.selectSection('month');
// Select all sections
- fireEvent.keyDown(view.getActiveSection(0), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getActiveSection(0), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
fireUserEvent.keyPress(view.getSectionsContainer(), { key: 'Delete' });
expectFieldValueV7(view.getSectionsContainer(), 'MMMM YYYY');
@@ -287,7 +291,7 @@ describe(' - Editing', () => {
view.selectSection('month');
// Select all sections
- fireUserEvent.keyPress(input, { key: 'a', ctrlKey: true });
+ fireUserEvent.keyPress(input, { key: 'a', keyCode: 65, ctrlKey: true });
fireUserEvent.keyPress(input, { key: 'Delete' });
expectFieldValueV6(input, 'MMMM YYYY');
@@ -307,7 +311,11 @@ describe(' - Editing', () => {
expectFieldValueV7(view.getSectionsContainer(), 'January YYYY');
// Select all sections
- fireEvent.keyDown(view.getActiveSection(0), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getActiveSection(0), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
fireUserEvent.keyPress(view.getSectionsContainer(), { key: 'Delete' });
expectFieldValueV7(view.getSectionsContainer(), 'MMMM YYYY');
@@ -330,7 +338,7 @@ describe(' - Editing', () => {
expectFieldValueV6(input, 'January YYYY');
// Select all sections
- fireUserEvent.keyPress(input, { key: 'a', ctrlKey: true });
+ fireUserEvent.keyPress(input, { key: 'a', keyCode: 65, ctrlKey: true });
fireUserEvent.keyPress(input, { key: 'Delete' });
expectFieldValueV6(input, 'MMMM YYYY');
@@ -398,7 +406,11 @@ describe(' - Editing', () => {
view.selectSection('month');
// Select all sections
- fireEvent.keyDown(view.getActiveSection(0), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getActiveSection(0), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
fireUserEvent.keyPress(view.getSectionsContainer(), { key: 'Delete' });
expect(onChangeV7.callCount).to.equal(0);
@@ -418,7 +430,7 @@ describe(' - Editing', () => {
view.selectSection('month');
// Select all sections
- fireUserEvent.keyPress(input, { key: 'a', ctrlKey: true });
+ fireUserEvent.keyPress(input, { key: 'a', keyCode: 65, ctrlKey: true });
fireUserEvent.keyPress(input, { key: 'Delete' });
expect(onChangeV6.callCount).to.equal(0);
@@ -1206,7 +1218,11 @@ describe(' - Editing', () => {
view.selectSection('month');
// Select all sections
- fireEvent.keyDown(view.getActiveSection(0), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getActiveSection(0), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
view.pressKey(null, '');
expectFieldValueV7(view.getSectionsContainer(), 'MMMM YYYY');
@@ -1224,7 +1240,7 @@ describe(' - Editing', () => {
view.selectSection('month');
// Select all sections
- fireEvent.keyDown(input, { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(input, { key: 'a', keyCode: 65, ctrlKey: true });
fireEvent.change(input, { target: { value: '' } });
expectFieldValueV6(input, 'MMMM YYYY');
@@ -1242,7 +1258,11 @@ describe(' - Editing', () => {
expectFieldValueV7(view.getSectionsContainer(), 'January YYYY');
// Select all sections
- fireEvent.keyDown(view.getActiveSection(0), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getActiveSection(0), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
view.pressKey(null, '');
expectFieldValueV7(view.getSectionsContainer(), 'MMMM YYYY');
@@ -1261,7 +1281,7 @@ describe(' - Editing', () => {
expectFieldValueV6(input, 'January YYYY');
// Select all sections
- fireEvent.keyDown(input, { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(input, { key: 'a', keyCode: 65, ctrlKey: true });
fireEvent.change(input, { target: { value: '' } });
expectFieldValueV6(input, 'MMMM YYYY');
@@ -1433,7 +1453,11 @@ describe(' - Editing', () => {
view.selectSection('month');
// Select all sections
- fireEvent.keyDown(view.getActiveSection(0), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getActiveSection(0), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
firePasteEventV7(view.getSectionsContainer(), '09/16/2022');
@@ -1453,7 +1477,7 @@ describe(' - Editing', () => {
view.selectSection('month');
// Select all sections
- fireUserEvent.keyPress(input, { key: 'a', ctrlKey: true });
+ fireUserEvent.keyPress(input, { key: 'a', keyCode: 65, ctrlKey: true });
firePasteEventV6(input, '09/16/2022');
@@ -1471,7 +1495,11 @@ describe(' - Editing', () => {
view.selectSection('month');
// Select all sections
- fireEvent.keyDown(view.getActiveSection(0), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getActiveSection(0), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
firePasteEventV7(view.getSectionsContainer(), '09/16/2022');
@@ -1489,7 +1517,7 @@ describe(' - Editing', () => {
view.selectSection('month');
// Select all sections
- fireUserEvent.keyPress(input, { key: 'a', ctrlKey: true });
+ fireUserEvent.keyPress(input, { key: 'a', keyCode: 65, ctrlKey: true });
firePasteEventV6(input, '09/16/2022');
@@ -1507,7 +1535,11 @@ describe(' - Editing', () => {
view.selectSection('month');
// Select all sections
- fireEvent.keyDown(view.getActiveSection(0), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getActiveSection(0), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
firePasteEventV7(view.getSectionsContainer(), 'Some invalid content');
expectFieldValueV7(view.getSectionsContainer(), 'MM/DD/YYYY');
@@ -1523,7 +1555,7 @@ describe(' - Editing', () => {
view.selectSection('month');
// Select all sections
- fireUserEvent.keyPress(input, { key: 'a', ctrlKey: true });
+ fireUserEvent.keyPress(input, { key: 'a', keyCode: 65, ctrlKey: true });
firePasteEventV6(input, 'Some invalid content');
expectFieldValueV6(input, 'MM/DD/YYYY');
@@ -1543,7 +1575,11 @@ describe(' - Editing', () => {
view.selectSection('year');
// Select all sections
- fireEvent.keyDown(view.getActiveSection(0), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getActiveSection(0), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
firePasteEventV7(view.getSectionsContainer(), `Escaped 2014`);
expect(onChangeV7.callCount).to.equal(1);
@@ -1562,7 +1598,7 @@ describe(' - Editing', () => {
view.selectSection('year');
// Select all sections
- fireUserEvent.keyPress(input, { key: 'a', ctrlKey: true });
+ fireUserEvent.keyPress(input, { key: 'a', keyCode: 65, ctrlKey: true });
firePasteEventV6(input, `Escaped 2014`);
expect(onChangeV6.callCount).to.equal(1);
@@ -1582,7 +1618,11 @@ describe(' - Editing', () => {
view.selectSection('month');
// Select all sections
- fireEvent.keyDown(view.getActiveSection(0), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getActiveSection(0), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
firePasteEventV7(view.getSectionsContainer(), '09/16/2022');
expect(onChangeV7.callCount).to.equal(0);
@@ -1602,7 +1642,7 @@ describe(' - Editing', () => {
view.selectSection('month');
// Select all sections
- fireUserEvent.keyPress(input, { key: 'a', ctrlKey: true });
+ fireUserEvent.keyPress(input, { key: 'a', keyCode: 65, ctrlKey: true });
firePasteEventV6(input, '09/16/2022');
expect(onChangeV6.callCount).to.equal(0);
@@ -1734,7 +1774,7 @@ describe(' - Editing', () => {
expectFieldValueV7(view.getSectionsContainer(), '12/02/2018');
// Select all sections
- fireEvent.keyDown(view.getActiveSection(1), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getActiveSection(1), { key: 'a', keyCode: 65, ctrlKey: true });
firePasteEventV7(view.getSectionsContainer(), '09/16/2022');
expectFieldValueV7(view.getSectionsContainer(), '09/16/2022');
@@ -1816,7 +1856,11 @@ describe(' - Editing', () => {
view.selectSection('month');
// Select all sections
- fireEvent.keyDown(view.getActiveSection(0), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getActiveSection(0), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
firePasteEventV7(view.getSectionsContainer(), '09/16/2022');
expect(onChangeV7.callCount).to.equal(0);
@@ -1884,7 +1928,11 @@ describe(' - Editing', () => {
});
view.selectSection('month');
- fireEvent.keyDown(view.getActiveSection(0), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getActiveSection(0), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
view.pressKey(null, '');
expectFieldValueV7(view.getSectionsContainer(), 'MM/DD/YYYY');
view.selectSection('month');
@@ -1919,7 +1967,7 @@ describe(' - Editing', () => {
const input = getTextbox();
view.selectSection('month');
- fireUserEvent.keyPress(input, { key: 'a', ctrlKey: true });
+ fireUserEvent.keyPress(input, { key: 'a', keyCode: 65, ctrlKey: true });
fireEvent.change(input, { target: { value: '' } });
fireUserEvent.keyPress(input, { key: 'ArrowLeft' });
@@ -2270,7 +2318,11 @@ describe(' - Editing', () => {
view.selectSection('month');
// Select all sections
- fireEvent.keyDown(view.getActiveSection(0), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getActiveSection(0), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
// When all sections are selected, the value only contains the key pressed
view.pressKey(null, '9');
@@ -2285,7 +2337,7 @@ describe(' - Editing', () => {
const input = getTextbox();
// Select all sections
- fireUserEvent.keyPress(input, { key: 'a', ctrlKey: true });
+ fireUserEvent.keyPress(input, { key: 'a', keyCode: 65, ctrlKey: true });
// When all sections are selected, the value only contains the key pressed
fireEvent.change(input, { target: { value: '9' } });
diff --git a/packages/x-date-pickers/src/DateField/tests/selection.DateField.test.tsx b/packages/x-date-pickers/src/DateField/tests/selection.DateField.test.tsx
index e0b6a0114dd10..6ef20dec53f36 100644
--- a/packages/x-date-pickers/src/DateField/tests/selection.DateField.test.tsx
+++ b/packages/x-date-pickers/src/DateField/tests/selection.DateField.test.tsx
@@ -170,7 +170,11 @@ describe(' - Selection', () => {
// Test with v7 input
let view = renderWithProps({ enableAccessibleFieldDOMStructure: true });
view.selectSection('month');
- fireEvent.keyDown(view.getActiveSection(0), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getActiveSection(0), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
expect(getCleanedSelectedContent()).to.equal('MM/DD/YYYY');
view.unmount();
@@ -179,7 +183,7 @@ describe(' - Selection', () => {
view = renderWithProps({ enableAccessibleFieldDOMStructure: false });
const input = getTextbox();
view.selectSection('month');
- fireEvent.keyDown(input, { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(input, { key: 'a', keyCode: 65, ctrlKey: true });
expect(getCleanedSelectedContent()).to.equal('MM/DD/YYYY');
});
@@ -190,7 +194,11 @@ describe(' - Selection', () => {
format: `- ${adapterToUse.formats.year}`,
});
view.selectSection('year');
- fireEvent.keyDown(view.getActiveSection(0), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getActiveSection(0), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
expect(getCleanedSelectedContent()).to.equal('- YYYY');
view.unmount();
@@ -202,7 +210,7 @@ describe(' - Selection', () => {
});
const input = getTextbox();
view.selectSection('year');
- fireEvent.keyDown(input, { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(input, { key: 'a', keyCode: 65, ctrlKey: true });
expect(getCleanedSelectedContent()).to.equal('- YYYY');
});
});
@@ -250,7 +258,11 @@ describe(' - Selection', () => {
view.selectSection('month');
// Select all sections
- fireEvent.keyDown(view.getActiveSection(0), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getActiveSection(0), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
expect(getCleanedSelectedContent()).to.equal('MM/DD/YYYY');
fireEvent.keyDown(view.getSectionsContainer(), { key: 'ArrowRight' });
@@ -264,7 +276,7 @@ describe(' - Selection', () => {
view.selectSection('month');
// Select all sections
- fireEvent.keyDown(input, { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(input, { key: 'a', keyCode: 65, ctrlKey: true });
expect(getCleanedSelectedContent()).to.equal('MM/DD/YYYY');
fireEvent.keyDown(input, { key: 'ArrowRight' });
@@ -315,7 +327,11 @@ describe(' - Selection', () => {
view.selectSection('month');
// Select all sections
- fireEvent.keyDown(view.getActiveSection(0), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getActiveSection(0), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
expect(getCleanedSelectedContent()).to.equal('MM/DD/YYYY');
fireEvent.keyDown(view.getSectionsContainer(), { key: 'ArrowLeft' });
@@ -329,7 +345,7 @@ describe(' - Selection', () => {
view.selectSection('month');
// Select all sections
- fireEvent.keyDown(input, { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(input, { key: 'a', keyCode: 65, ctrlKey: true });
expect(getCleanedSelectedContent()).to.equal('MM/DD/YYYY');
fireEvent.keyDown(input, { key: 'ArrowLeft' });
diff --git a/packages/x-date-pickers/src/TimeField/tests/editing.TimeField.test.tsx b/packages/x-date-pickers/src/TimeField/tests/editing.TimeField.test.tsx
index 9ddc968fd0609..f1c4c0811bd37 100644
--- a/packages/x-date-pickers/src/TimeField/tests/editing.TimeField.test.tsx
+++ b/packages/x-date-pickers/src/TimeField/tests/editing.TimeField.test.tsx
@@ -679,7 +679,11 @@ describe(' - Editing', () => {
});
view.selectSection('hours');
- fireEvent.keyDown(view.getActiveSection(0), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getActiveSection(0), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
view.pressKey(null, '');
fireEvent.keyDown(view.getSectionsContainer(), { key: 'ArrowLeft' });
@@ -704,7 +708,7 @@ describe(' - Editing', () => {
const input = getTextbox();
view.selectSection('hours');
- fireEvent.keyDown(input, { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(input, { key: 'a', keyCode: 65, ctrlKey: true });
fireEvent.change(input, { target: { value: '' } });
fireEvent.keyDown(input, { key: 'ArrowLeft' });
diff --git a/packages/x-date-pickers/src/internals/hooks/useField/useField.ts b/packages/x-date-pickers/src/internals/hooks/useField/useField.ts
index 2ad8363212a92..c271f2a4f42b6 100644
--- a/packages/x-date-pickers/src/internals/hooks/useField/useField.ts
+++ b/packages/x-date-pickers/src/internals/hooks/useField/useField.ts
@@ -125,7 +125,7 @@ export const useField = <
switch (true) {
// Select all
case (event.ctrlKey || event.metaKey) &&
- event.key.toLowerCase() === 'a' &&
+ String.fromCharCode(event.keyCode) === 'A' &&
!event.shiftKey &&
!event.altKey: {
// prevent default to make sure that the next line "select all" while updating
diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.test.tsx b/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.test.tsx
index 7dab02bcf8b2b..2db89b9501b1c 100644
--- a/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.test.tsx
+++ b/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.test.tsx
@@ -1044,7 +1044,11 @@ describeTreeView<
act(() => {
view.getItemRoot('1').focus();
});
- fireEvent.keyDown(view.getItemRoot('1'), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getItemRoot('1'), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
expect(view.getSelectedTreeItems()).to.deep.equal(['1', '2', '3', '4']);
});
@@ -1058,7 +1062,11 @@ describeTreeView<
act(() => {
view.getItemRoot('1').focus();
});
- fireEvent.keyDown(view.getItemRoot('1'), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getItemRoot('1'), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
expect(view.getSelectedTreeItems()).to.deep.equal([]);
});
@@ -1076,7 +1084,11 @@ describeTreeView<
act(() => {
view.getItemRoot('1').focus();
});
- fireEvent.keyDown(view.getItemRoot('1'), { key: 'a', ctrlKey: true });
+ fireEvent.keyDown(view.getItemRoot('1'), {
+ key: 'a',
+ keyCode: 65,
+ ctrlKey: true,
+ });
expect(view.getSelectedTreeItems()).to.deep.equal(['1', '3', '4']);
});
});
diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.ts
index 88bad3cccb212..5b2739b6f9887 100644
--- a/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.ts
+++ b/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.ts
@@ -16,7 +16,7 @@ import {
import { hasPlugin } from '../../utils/plugins';
import { useTreeViewLabel } from '../useTreeViewLabel';
-function isPrintableCharacter(string: string) {
+function isPrintableKey(string: string) {
return !!string && string.length === 1 && !!string.match(/\S/);
}
@@ -256,7 +256,10 @@ export const useTreeViewKeyboardNavigation: TreeViewPlugin<
// Multi select behavior when pressing Ctrl + a
// Selects all the items
- case key === 'a' && ctrlPressed && params.multiSelect && !params.disableSelection: {
+ case String.fromCharCode(event.keyCode) === 'A' &&
+ ctrlPressed &&
+ params.multiSelect &&
+ !params.disableSelection: {
instance.selectAllNavigableItems(event);
event.preventDefault();
break;
@@ -264,7 +267,7 @@ export const useTreeViewKeyboardNavigation: TreeViewPlugin<
// Type-ahead
// TODO: Support typing multiple characters
- case !ctrlPressed && !event.shiftKey && isPrintableCharacter(key): {
+ case !ctrlPressed && !event.shiftKey && isPrintableKey(key): {
const matchingItem = getFirstMatchingItem(itemId, key);
if (matchingItem != null) {
instance.focusItem(event, matchingItem);
diff --git a/packages/x-tree-view/src/useTreeItem2/useTreeItem2.test.tsx b/packages/x-tree-view/src/useTreeItem2/useTreeItem2.test.tsx
index 8dc7de297623a..51e07dcabc5ab 100644
--- a/packages/x-tree-view/src/useTreeItem2/useTreeItem2.test.tsx
+++ b/packages/x-tree-view/src/useTreeItem2/useTreeItem2.test.tsx
@@ -100,6 +100,7 @@ describeTreeView<[UseTreeViewExpansionSignature, UseTreeViewIconsSignature]>(
const input = view.getItemRoot('1.1').querySelector('.icon-input')!;
const keydownEvent = createEvent.keyDown(input, {
key: 'a',
+ keyCode: 65,
});
const handlePreventDefault = spy();