From 8448fdd4164651e17ff6421b7841ddec6647ee15 Mon Sep 17 00:00:00 2001 From: Gordon Ko Date: Sat, 7 Oct 2023 09:46:31 -0400 Subject: [PATCH 1/6] initial idea --- src/DataGrid.tsx | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/DataGrid.tsx b/src/DataGrid.tsx index 9d1b554cff..9631866c60 100644 --- a/src/DataGrid.tsx +++ b/src/DataGrid.tsx @@ -568,6 +568,23 @@ function DataGrid( } } + if (isCtrlKeyHeldDown(event) && event.shiftKey) { + const leftKey = isRtl ? 39 : 37; + const rightKey = isRtl ? 37 : 39; + if (keyCode === leftKey || keyCode === rightKey) { + const { idx } = selectedPosition; + const column = columns[idx]; + if (column.resizable) { + const width = getColumnWidth(column); + const step = 10; + const isIncrease = keyCode === rightKey; + const newWidth = isIncrease ? Number(width) + step : Number(width) - step; + handleColumnResizeLatest(column, newWidth); + } + return; + } + } + switch (event.key) { case 'Escape': setCopiedCell(null); From a2c31e7e11524d3bc137b43de00f6d34396c0f13 Mon Sep 17 00:00:00 2001 From: Gordon Ko Date: Sat, 7 Oct 2023 10:05:19 -0400 Subject: [PATCH 2/6] expose handler --- src/DataGrid.tsx | 22 ++++++++++------------ src/types.ts | 1 + 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/DataGrid.tsx b/src/DataGrid.tsx index 9631866c60..ce45350db2 100644 --- a/src/DataGrid.tsx +++ b/src/DataGrid.tsx @@ -525,6 +525,7 @@ function DataGrid( function handleKeyDown(event: KeyboardEvent) { const { idx, rowIdx, mode } = selectedPosition; + const column = columns[idx]; if (mode === 'EDIT') return; if (onCellKeyDown && isRowIdxWithinViewportBounds(rowIdx)) { @@ -534,9 +535,10 @@ function DataGrid( { mode: 'SELECT', row, - column: columns[idx], + column, rowIdx, - selectCell + selectCell, + resizeColumn: handleColumnResize }, cellEvent ); @@ -568,19 +570,15 @@ function DataGrid( } } - if (isCtrlKeyHeldDown(event) && event.shiftKey) { + if (column.resizable && isCtrlKeyHeldDown(event) && event.shiftKey) { const leftKey = isRtl ? 39 : 37; const rightKey = isRtl ? 37 : 39; if (keyCode === leftKey || keyCode === rightKey) { - const { idx } = selectedPosition; - const column = columns[idx]; - if (column.resizable) { - const width = getColumnWidth(column); - const step = 10; - const isIncrease = keyCode === rightKey; - const newWidth = isIncrease ? Number(width) + step : Number(width) - step; - handleColumnResizeLatest(column, newWidth); - } + const width = getColumnWidth(column); + const step = 10; + const isIncrease = keyCode === rightKey; + const newWidth = isIncrease ? Number(width) + step : Number(width) - step; + handleColumnResizeLatest(column, newWidth); return; } } diff --git a/src/types.ts b/src/types.ts index f433d45f58..33def218d0 100644 --- a/src/types.ts +++ b/src/types.ts @@ -178,6 +178,7 @@ interface SelectCellKeyDownArgs { column: CalculatedColumn; rowIdx: number; selectCell: (position: Position, enableEditor?: Maybe) => void; + resizeColumn: (column: CalculatedColumn, width: number) => void; } export interface EditCellKeyDownArgs { From 2734915bd3cc4c3791248514ae0638d8ab254475 Mon Sep 17 00:00:00 2001 From: Gordon Ko Date: Mon, 9 Oct 2023 18:28:36 -0400 Subject: [PATCH 3/6] add test --- test/column/resizable.test.tsx | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test/column/resizable.test.tsx b/test/column/resizable.test.tsx index 0ef72ea898..1bf885f48f 100644 --- a/test/column/resizable.test.tsx +++ b/test/column/resizable.test.tsx @@ -1,4 +1,5 @@ import { fireEvent } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import type { Column } from '../../src'; import { resizeHandleClassname } from '../../src/HeaderCell'; @@ -104,3 +105,23 @@ test('should use the minWidth if specified', () => { resize({ column: col2, clientXStart: 295, clientXEnd: 100, rect: { right: 300, left: 100 } }); expect(getGrid()).toHaveStyle({ gridTemplateColumns: '100px 100px' }); }); + +test('should resize column via keyboard', async () => { + function resizeCell(left: boolean) { + // eslint-disable-next-line testing-library/prefer-user-event + fireEvent.keyDown(document.activeElement!, { + keyCode: left ? '37' : '39', + ctrlKey: true, + shiftKey: true + }); + } + + setup({ columns, rows: [] }); + const [, col2] = getHeaderCells(); + await userEvent.click(col2); + expect(getGrid()).toHaveStyle({ gridTemplateColumns: '100px 200px' }); + resizeCell(false); + expect(getGrid()).toHaveStyle({ gridTemplateColumns: '100px 210px' }); + resizeCell(true); + expect(getGrid()).toHaveStyle({ gridTemplateColumns: '100px 200px' }); +}); From 80655355c5535c979eeae16cac0432da6fdfa530 Mon Sep 17 00:00:00 2001 From: Gordon Ko Date: Tue, 10 Oct 2023 19:10:22 -0400 Subject: [PATCH 4/6] cleanup --- src/DataGrid.tsx | 3 +-- src/types.ts | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/DataGrid.tsx b/src/DataGrid.tsx index ce45350db2..031be86ac6 100644 --- a/src/DataGrid.tsx +++ b/src/DataGrid.tsx @@ -537,8 +537,7 @@ function DataGrid( row, column, rowIdx, - selectCell, - resizeColumn: handleColumnResize + selectCell }, cellEvent ); diff --git a/src/types.ts b/src/types.ts index 33def218d0..f433d45f58 100644 --- a/src/types.ts +++ b/src/types.ts @@ -178,7 +178,6 @@ interface SelectCellKeyDownArgs { column: CalculatedColumn; rowIdx: number; selectCell: (position: Position, enableEditor?: Maybe) => void; - resizeColumn: (column: CalculatedColumn, width: number) => void; } export interface EditCellKeyDownArgs { From 67b781911e59e475bd283ac2dbb4b90e5c4b0818 Mon Sep 17 00:00:00 2001 From: Gordon Ko Date: Tue, 17 Oct 2023 14:40:20 -0400 Subject: [PATCH 5/6] use handler instead --- src/DataGrid.tsx | 22 +++++++------------- src/types.ts | 2 ++ test/column/resizable.test.tsx | 37 +++++++++++++++++++++++----------- website/demos/AllFeatures.tsx | 19 +++++++++++++++++ 4 files changed, 53 insertions(+), 27 deletions(-) diff --git a/src/DataGrid.tsx b/src/DataGrid.tsx index 031be86ac6..93197342ef 100644 --- a/src/DataGrid.tsx +++ b/src/DataGrid.tsx @@ -449,6 +449,8 @@ function DataGrid( } }); + console.log('called?'); + useLayoutEffect(() => { if (!shouldFocusCellRef.current) return; shouldFocusCellRef.current = false; @@ -526,9 +528,10 @@ function DataGrid( function handleKeyDown(event: KeyboardEvent) { const { idx, rowIdx, mode } = selectedPosition; const column = columns[idx]; + if (mode === 'EDIT') return; - if (onCellKeyDown && isRowIdxWithinViewportBounds(rowIdx)) { + if (onCellKeyDown) { const row = rows[rowIdx]; const cellEvent = createCellEvent(event); onCellKeyDown( @@ -537,7 +540,9 @@ function DataGrid( row, column, rowIdx, - selectCell + selectCell, + resizeColumn: handleColumnResize, + getColumnWidth }, cellEvent ); @@ -569,19 +574,6 @@ function DataGrid( } } - if (column.resizable && isCtrlKeyHeldDown(event) && event.shiftKey) { - const leftKey = isRtl ? 39 : 37; - const rightKey = isRtl ? 37 : 39; - if (keyCode === leftKey || keyCode === rightKey) { - const width = getColumnWidth(column); - const step = 10; - const isIncrease = keyCode === rightKey; - const newWidth = isIncrease ? Number(width) + step : Number(width) - step; - handleColumnResizeLatest(column, newWidth); - return; - } - } - switch (event.key) { case 'Escape': setCopiedCell(null); diff --git a/src/types.ts b/src/types.ts index f433d45f58..896dcc40e2 100644 --- a/src/types.ts +++ b/src/types.ts @@ -178,6 +178,8 @@ interface SelectCellKeyDownArgs { column: CalculatedColumn; rowIdx: number; selectCell: (position: Position, enableEditor?: Maybe) => void; + resizeColumn: (column: CalculatedColumn, width: number) => void; + getColumnWidth: (column: CalculatedColumn) => string | number; } export interface EditCellKeyDownArgs { diff --git a/test/column/resizable.test.tsx b/test/column/resizable.test.tsx index 1bf885f48f..0dc3978e0b 100644 --- a/test/column/resizable.test.tsx +++ b/test/column/resizable.test.tsx @@ -3,6 +3,7 @@ import userEvent from '@testing-library/user-event'; import type { Column } from '../../src'; import { resizeHandleClassname } from '../../src/HeaderCell'; +import { isCtrlKeyHeldDown } from '../../src/utils'; import { getGrid, getHeaderCells, setup } from '../utils'; const pointerId = 1; @@ -107,21 +108,33 @@ test('should use the minWidth if specified', () => { }); test('should resize column via keyboard', async () => { - function resizeCell(left: boolean) { - // eslint-disable-next-line testing-library/prefer-user-event - fireEvent.keyDown(document.activeElement!, { - keyCode: left ? '37' : '39', - ctrlKey: true, - shiftKey: true - }); - } - - setup({ columns, rows: [] }); + setup({ + columns, + rows: [], + onCellKeyDown(args, event) { + if (args.mode === 'SELECT') { + const { key } = event; + const { column, getColumnWidth, resizeColumn } = args; + if (column.resizable && isCtrlKeyHeldDown(event) && event.shiftKey) { + event.preventGridDefault(); + const leftKey = 'ArrowLeft'; + const rightKey = 'ArrowRight'; + if (key === leftKey || key === rightKey) { + const width = getColumnWidth(column); + const step = 10; + const isIncrease = key === rightKey; + const newWidth = isIncrease ? Number(width) + step : Number(width) - step; + resizeColumn(column, newWidth); + } + } + } + } + }); const [, col2] = getHeaderCells(); await userEvent.click(col2); expect(getGrid()).toHaveStyle({ gridTemplateColumns: '100px 200px' }); - resizeCell(false); + await userEvent.keyboard('{Control>}{Shift>}{ArrowRight}{/Control}{/Shift}'); expect(getGrid()).toHaveStyle({ gridTemplateColumns: '100px 210px' }); - resizeCell(true); + await userEvent.keyboard('{Control>}{Shift>}{ArrowLeft}{/Control}{/Shift}'); expect(getGrid()).toHaveStyle({ gridTemplateColumns: '100px 200px' }); }); diff --git a/website/demos/AllFeatures.tsx b/website/demos/AllFeatures.tsx index 2cf0df1ff0..4a3c7fc606 100644 --- a/website/demos/AllFeatures.tsx +++ b/website/demos/AllFeatures.tsx @@ -4,6 +4,7 @@ import { css } from '@linaria/core'; import DataGrid, { SelectColumn, textEditor } from '../../src'; import type { Column, CopyEvent, FillEvent, PasteEvent } from '../../src'; +import { isCtrlKeyHeldDown } from '../../src/utils'; import { renderAvatar, renderDropdown } from './renderers'; import type { Props } from './types'; @@ -218,6 +219,24 @@ export default function AllFeatures({ direction }: Props) { args.selectCell(true); } }} + onCellKeyDown={(args, event) => { + if (args.mode === 'SELECT') { + const { key } = event; + const { column, getColumnWidth, resizeColumn } = args; + if (column.resizable && isCtrlKeyHeldDown(event) && event.shiftKey) { + event.preventGridDefault(); + const leftKey = 'ArrowLeft'; + const rightKey = 'ArrowRight'; + if (key === leftKey || key === rightKey) { + const width = getColumnWidth(column); + const step = 10; + const isIncrease = key === rightKey; + const newWidth = isIncrease ? Number(width) + step : Number(width) - step; + resizeColumn(column, newWidth); + } + } + } + }} /> ); } From 1d1977239608ebc635037e6e6e0ce0d93c73e5b4 Mon Sep 17 00:00:00 2001 From: Gordon Ko Date: Tue, 17 Oct 2023 14:43:34 -0400 Subject: [PATCH 6/6] cleanup --- src/DataGrid.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/DataGrid.tsx b/src/DataGrid.tsx index 93197342ef..be38cd2904 100644 --- a/src/DataGrid.tsx +++ b/src/DataGrid.tsx @@ -449,8 +449,6 @@ function DataGrid( } }); - console.log('called?'); - useLayoutEffect(() => { if (!shouldFocusCellRef.current) return; shouldFocusCellRef.current = false;