diff --git a/src/DataGrid.tsx b/src/DataGrid.tsx index 23ad4ec84c..debd97f855 100644 --- a/src/DataGrid.tsx +++ b/src/DataGrid.tsx @@ -528,18 +528,22 @@ 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( { mode: 'SELECT', row, - column: columns[idx], + column, rowIdx, - selectCell + selectCell, + resizeColumn: handleColumnResize, + getColumnWidth }, cellEvent ); diff --git a/src/types.ts b/src/types.ts index 703ec14d0d..c3795097da 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 0ef72ea898..0dc3978e0b 100644 --- a/test/column/resizable.test.tsx +++ b/test/column/resizable.test.tsx @@ -1,7 +1,9 @@ import { fireEvent } from '@testing-library/react'; +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; @@ -104,3 +106,35 @@ 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 () => { + 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' }); + await userEvent.keyboard('{Control>}{Shift>}{ArrowRight}{/Control}{/Shift}'); + expect(getGrid()).toHaveStyle({ gridTemplateColumns: '100px 210px' }); + 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); + } + } + } + }} /> ); }