From 3fc05758a1ef8042099c05addd7d75014dee7918 Mon Sep 17 00:00:00 2001 From: Aman Mahajan Date: Wed, 17 Mar 2021 12:15:25 -0500 Subject: [PATCH 01/12] Use context for selection --- src/Cell.tsx | 8 ------ src/Columns.tsx | 32 +++++++++++++--------- src/Row.tsx | 43 +++++++++++++++++------------- src/hooks/index.ts | 2 ++ src/hooks/useRowSelection.ts | 12 +++++++++ src/hooks/useRowSelectionChange.ts | 12 +++++++++ src/types.ts | 4 --- 7 files changed, 70 insertions(+), 43 deletions(-) create mode 100644 src/hooks/useRowSelection.ts create mode 100644 src/hooks/useRowSelectionChange.ts diff --git a/src/Cell.tsx b/src/Cell.tsx index e5fc99cae0..92107094c3 100644 --- a/src/Cell.tsx +++ b/src/Cell.tsx @@ -47,7 +47,6 @@ function Cell({ isCellSelected, isCopied, isDraggedOver, - isRowSelected, row, rowIdx, dragHandleProps, @@ -57,7 +56,6 @@ function Cell({ onContextMenu, onRowChange, selectCell, - selectRow, ...props }: CellRendererProps, ref: React.Ref) { const { cellClass } = column; @@ -96,10 +94,6 @@ function Cell({ onRowChange(rowIdx, newRow); } - function onRowSelectionChange(checked: boolean, isShiftClick: boolean) { - selectRow({ rowIdx, checked, isShiftClick }); - } - return (
({ rowIdx={rowIdx} row={row} isCellSelected={isCellSelected} - isRowSelected={isRowSelected} - onRowSelectionChange={onRowSelectionChange} onRowChange={handleRowChange} /> {dragHandleProps && ( diff --git a/src/Columns.tsx b/src/Columns.tsx index 68e49dc952..db50b413ba 100644 --- a/src/Columns.tsx +++ b/src/Columns.tsx @@ -1,9 +1,26 @@ import { SelectCellFormatter } from './formatters'; -import type { Column } from './types'; +import { useRowSelection, useRowSelectionChange } from './hooks'; +import type { Column, FormatterProps } from './types'; import { stopPropagation } from './utils/domUtils'; export const SELECT_COLUMN_KEY = 'select-row'; +function SelectFormatter(props: FormatterProps) { + const isRowSelected = useRowSelection(); + const onRowSelectionChange = useRowSelectionChange(); + + return ( + + ); +} + // eslint-disable-next-line @typescript-eslint/no-explicit-any export const SelectColumn: Column = { key: SELECT_COLUMN_KEY, @@ -22,18 +39,7 @@ export const SelectColumn: Column = { /> ); }, - formatter(props) { - return ( - - ); - }, + formatter: SelectFormatter, groupFormatter(props) { return ( ({ cellRenderer: CellRenderer = Cell, @@ -29,6 +30,10 @@ function Row({ 'aria-selected': ariaSelected, ...props }: RowRendererProps, ref: React.Ref) { + const onRowSelectionChange = useCallback((checked: boolean, isShiftClick: boolean) => { + selectRow({ rowIdx, checked, isShiftClick }); + }, [rowIdx, selectRow]); + function handleDragEnter(event: React.MouseEvent) { setDraggedOverRowIdx?.(rowIdx); onMouseEnter?.(event); @@ -71,23 +76,25 @@ function Row({ } return ( - + + + + + ); })}
diff --git a/src/hooks/index.ts b/src/hooks/index.ts index 1154de7050..dc91f9d39e 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -4,3 +4,5 @@ export * from './useViewportColumns'; export * from './useViewportRows'; export * from './useFocusRef'; export * from './useLatestFunc'; +export * from './useRowSelection'; +export * from './useRowSelectionChange'; diff --git a/src/hooks/useRowSelection.ts b/src/hooks/useRowSelection.ts new file mode 100644 index 0000000000..ab7df3436b --- /dev/null +++ b/src/hooks/useRowSelection.ts @@ -0,0 +1,12 @@ +import { createContext, useContext } from 'react'; + +export const RowSelectionContext = + createContext(undefined); + +export function useRowSelection() { + const context = useContext(RowSelectionContext); + if (context === undefined) { + throw new Error('useRowSelection must be used within a RowSelectionContext'); + } + return context; +} diff --git a/src/hooks/useRowSelectionChange.ts b/src/hooks/useRowSelectionChange.ts new file mode 100644 index 0000000000..8139ae7a85 --- /dev/null +++ b/src/hooks/useRowSelectionChange.ts @@ -0,0 +1,12 @@ +import { createContext, useContext } from 'react'; + +export const RowSelectionChangeContext = + createContext<(((checked: boolean, isShiftClick: boolean) => void) | undefined)>(undefined); + +export function useRowSelectionChange() { + const context = useContext(RowSelectionChangeContext); + if (context === undefined) { + throw new Error('useRowSelectionChange must be used within a RowSelectionChangeContext'); + } + return context; +} diff --git a/src/types.ts b/src/types.ts index b25b205c96..3d00d06322 100644 --- a/src/types.ts +++ b/src/types.ts @@ -80,8 +80,6 @@ export interface FormatterProps { column: CalculatedColumn; row: TRow; isCellSelected: boolean; - isRowSelected: boolean; - onRowSelectionChange: (checked: boolean, isShiftClick: boolean) => void; onRowChange: (row: Readonly) => void; } @@ -148,12 +146,10 @@ export interface CellRendererProps extends Omit, 'onMouseDown' | 'onDoubleClick'>; onRowChange: (rowIdx: number, newRow: TRow) => void; onRowClick?: (rowIdx: number, row: TRow, column: CalculatedColumn) => void; selectCell: (position: Position, enableEditor?: boolean) => void; - selectRow: (selectRowEvent: SelectRowEvent) => void; } export interface RowRendererProps extends Omit, 'style' | 'children'> { From 7c15e37d1433d0caf2151d63f28407d04baec412 Mon Sep 17 00:00:00 2001 From: Aman Mahajan Date: Wed, 17 Mar 2021 12:33:21 -0500 Subject: [PATCH 02/12] Use context for group selection --- src/Columns.tsx | 34 ++++++++++++++++++++-------------- src/GroupCell.tsx | 12 ------------ src/GroupRow.tsx | 36 +++++++++++++++++++++--------------- src/types.ts | 2 -- 4 files changed, 41 insertions(+), 43 deletions(-) diff --git a/src/Columns.tsx b/src/Columns.tsx index db50b413ba..d4bd2543f9 100644 --- a/src/Columns.tsx +++ b/src/Columns.tsx @@ -1,6 +1,6 @@ import { SelectCellFormatter } from './formatters'; import { useRowSelection, useRowSelectionChange } from './hooks'; -import type { Column, FormatterProps } from './types'; +import type { Column, FormatterProps, GroupFormatterProps } from './types'; import { stopPropagation } from './utils/domUtils'; export const SELECT_COLUMN_KEY = 'select-row'; @@ -21,6 +21,24 @@ function SelectFormatter(props: FormatterProps) { ); } +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function SelectGroupFormatter(props: GroupFormatterProps) { + const isRowSelected = useRowSelection(); + const onRowSelectionChange = useRowSelectionChange(); + + return ( + + ); +} + // eslint-disable-next-line @typescript-eslint/no-explicit-any export const SelectColumn: Column = { key: SELECT_COLUMN_KEY, @@ -40,17 +58,5 @@ export const SelectColumn: Column = { ); }, formatter: SelectFormatter, - groupFormatter(props) { - return ( - - ); - } + groupFormatter: SelectGroupFormatter }; diff --git a/src/GroupCell.tsx b/src/GroupCell.tsx index 08ef5479c4..af63b33184 100644 --- a/src/GroupCell.tsx +++ b/src/GroupCell.tsx @@ -7,12 +7,9 @@ import { cellSelectedClassname } from './style'; type SharedGroupRowRendererProps = Pick, | 'id' - | 'rowIdx' | 'groupKey' | 'childRows' | 'isExpanded' - | 'isRowSelected' - | 'selectRow' | 'toggleGroup' >; @@ -24,25 +21,18 @@ interface GroupCellProps extends SharedGroupRowRendererProps { function GroupCell({ id, - rowIdx, groupKey, childRows, isExpanded, isCellSelected, - isRowSelected, column, groupColumnIndex, - selectRow, toggleGroup: toggleGroupWrapper }: GroupCellProps) { function toggleGroup() { toggleGroupWrapper(id); } - function onRowSelectionChange(checked: boolean) { - selectRow({ rowIdx, checked, isShiftClick: false }); - } - // Only make the cell clickable if the group level matches const isLevelMatching = column.rowGroup && groupColumnIndex === column.idx; @@ -67,8 +57,6 @@ function GroupCell({ column={column} isExpanded={isExpanded} isCellSelected={isCellSelected} - isRowSelected={isRowSelected} - onRowSelectionChange={onRowSelectionChange} toggleGroup={toggleGroup} /> )} diff --git a/src/GroupRow.tsx b/src/GroupRow.tsx index 415ee75db5..3b912adcca 100644 --- a/src/GroupRow.tsx +++ b/src/GroupRow.tsx @@ -1,10 +1,11 @@ -import { memo } from 'react'; +import { memo, useCallback } from 'react'; import clsx from 'clsx'; import { groupRowClassname, groupRowSelectedClassname, rowClassname, rowSelectedClassname } from './style'; import { SELECT_COLUMN_KEY } from './Columns'; import GroupCell from './GroupCell'; import type { CalculatedColumn, Position, SelectRowEvent, Omit } from './types'; +import { RowSelectionChangeContext, RowSelectionContext } from './hooks'; export interface GroupRowRendererProps extends Omit, 'style' | 'children'> { id: string; @@ -38,6 +39,10 @@ function GroupedRow({ toggleGroup, ...props }: GroupRowRendererProps) { + const onRowSelectionChange = useCallback((checked: boolean) => { + selectRow({ rowIdx, checked, isShiftClick: false }); + }, [rowIdx, selectRow]); + // Select is always the first column const idx = viewportColumns[0].key === SELECT_COLUMN_KEY ? level + 1 : level; @@ -63,20 +68,21 @@ function GroupedRow({ {...props} > {viewportColumns.map(column => ( - - key={column.key} - id={id} - rowIdx={rowIdx} - groupKey={groupKey} - childRows={childRows} - isExpanded={isExpanded} - isRowSelected={isRowSelected} - isCellSelected={selectedCellIdx === column.idx} - column={column} - groupColumnIndex={idx} - selectRow={selectRow} - toggleGroup={toggleGroup} - /> + + + + key={column.key} + id={id} + groupKey={groupKey} + childRows={childRows} + isExpanded={isExpanded} + isCellSelected={selectedCellIdx === column.idx} + column={column} + groupColumnIndex={idx} + toggleGroup={toggleGroup} + /> + + ))} ); diff --git a/src/types.ts b/src/types.ts index 3d00d06322..7b84c3b31f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -94,8 +94,6 @@ export interface GroupFormatterProps { childRows: readonly TRow[]; isExpanded: boolean; isCellSelected: boolean; - isRowSelected: boolean; - onRowSelectionChange: (checked: boolean) => void; toggleGroup: () => void; } From d51b03bb28c16dc9c8a2b54e770612f0ece7c7cc Mon Sep 17 00:00:00 2001 From: Aman Mahajan Date: Thu, 18 Mar 2021 09:19:26 -0500 Subject: [PATCH 03/12] Move context provider a level up --- src/Row.tsx | 64 ++++++++++++++++++++++++++--------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/Row.tsx b/src/Row.tsx index f16f93cfda..49f32bbdf8 100644 --- a/src/Row.tsx +++ b/src/Row.tsx @@ -50,34 +50,34 @@ function Row({ ); return ( -
- {viewportColumns.map(column => { - const isCellSelected = selectedCellProps?.idx === column.idx; - if (selectedCellProps?.mode === 'EDIT' && isCellSelected) { - return ( - - key={column.key} - rowIdx={rowIdx} - column={column} - row={row} - onKeyDown={selectedCellProps.onKeyDown} - editorProps={selectedCellProps.editorProps} - /> - ); - } + + +
+ {viewportColumns.map(column => { + const isCellSelected = selectedCellProps?.idx === column.idx; + if (selectedCellProps?.mode === 'EDIT' && isCellSelected) { + return ( + + key={column.key} + rowIdx={rowIdx} + column={column} + row={row} + onKeyDown={selectedCellProps.onKeyDown} + editorProps={selectedCellProps.editorProps} + /> + ); + } - return ( - - + return ( ({ onRowChange={onRowChange} selectCell={selectCell} /> - - - ); - })} -
+ ); + })} +
+ + ); } From 6d6cb8b0a4781fb022cb87ae58e1f57dd2b2e575 Mon Sep 17 00:00:00 2001 From: Aman Mahajan Date: Thu, 18 Mar 2021 14:02:47 -0500 Subject: [PATCH 04/12] Cleanup context usage --- src/Columns.tsx | 8 ++- src/DataGrid.tsx | 8 +-- src/GroupCell.tsx | 3 + src/GroupRow.tsx | 79 ++++++++++++-------------- src/Row.tsx | 89 ++++++++++++++---------------- src/hooks/useRowSelection.ts | 4 +- src/hooks/useRowSelectionChange.ts | 5 +- src/types.ts | 2 +- 8 files changed, 98 insertions(+), 100 deletions(-) diff --git a/src/Columns.tsx b/src/Columns.tsx index d4bd2543f9..f33530410d 100644 --- a/src/Columns.tsx +++ b/src/Columns.tsx @@ -16,7 +16,9 @@ function SelectFormatter(props: FormatterProps) { isCellSelected={props.isCellSelected} value={isRowSelected} onClick={stopPropagation} - onChange={onRowSelectionChange} + onChange={(checked, isShiftClick) => { + onRowSelectionChange({ rowIdx: props.rowIdx, checked, isShiftClick }); + }} /> ); } @@ -32,7 +34,9 @@ function SelectGroupFormatter(props: GroupFormatterProps) { tabIndex={-1} isCellSelected={props.isCellSelected} value={isRowSelected} - onChange={onRowSelectionChange} + onChange={(checked) => { + onRowSelectionChange({ checked, isShiftClick: false, rowIdx: props.rowIdx }); + }} // Stop propagation to prevent row selection onClick={stopPropagation} /> diff --git a/src/DataGrid.tsx b/src/DataGrid.tsx index 639c859979..96bbe8f0c2 100644 --- a/src/DataGrid.tsx +++ b/src/DataGrid.tsx @@ -10,7 +10,7 @@ import type { RefAttributes } from 'react'; import clsx from 'clsx'; import { rootClassname, viewportDraggingClassname, focusSinkClassname } from './style'; -import { useGridDimensions, useViewportColumns, useViewportRows, useLatestFunc } from './hooks'; +import { useGridDimensions, useViewportColumns, useViewportRows, useLatestFunc, RowSelectionChangeProvider } from './hooks'; import HeaderRow from './HeaderRow'; import FilterRow from './FilterRow'; import Row from './Row'; @@ -853,7 +853,6 @@ function DataGrid({ onFocus={selectedPosition.rowIdx === rowIdx ? handleFocus : undefined} onKeyDown={selectedPosition.rowIdx === rowIdx ? handleKeyDown : undefined} selectCell={selectCellWrapper} - selectRow={selectRowWrapper} toggleGroup={toggleGroupWrapper} /> ); @@ -886,7 +885,6 @@ function DataGrid({ selectedCellProps={getSelectedCellProps(rowIdx)} onRowChange={handleFormatterRowChangeWrapper} selectCell={selectCellWrapper} - selectRow={selectRowWrapper} /> ); } @@ -955,7 +953,9 @@ function DataGrid({ onFocus={onGridFocus} />
- {getViewportRows()} + + {getViewportRows()} + {summaryRows?.map((row, rowIdx) => ( aria-rowindex={headerRowsCount + rowsCount + rowIdx + 1} diff --git a/src/GroupCell.tsx b/src/GroupCell.tsx index af63b33184..34468e3062 100644 --- a/src/GroupCell.tsx +++ b/src/GroupCell.tsx @@ -7,6 +7,7 @@ import { cellSelectedClassname } from './style'; type SharedGroupRowRendererProps = Pick, | 'id' + | 'rowIdx' | 'groupKey' | 'childRows' | 'isExpanded' @@ -21,6 +22,7 @@ interface GroupCellProps extends SharedGroupRowRendererProps { function GroupCell({ id, + rowIdx, groupKey, childRows, isExpanded, @@ -52,6 +54,7 @@ function GroupCell({ > {(!column.rowGroup || groupColumnIndex === column.idx) && column.groupFormatter && ( extends Omit, 'style' | 'children'> { id: string; @@ -19,7 +19,6 @@ export interface GroupRowRendererProps extends Omit void; - selectRow: (selectRowEvent: SelectRowEvent) => void; toggleGroup: (expandedGroupId: unknown) => void; } @@ -35,14 +34,9 @@ function GroupedRow({ selectedCellIdx, isRowSelected, selectCell, - selectRow, toggleGroup, ...props }: GroupRowRendererProps) { - const onRowSelectionChange = useCallback((checked: boolean) => { - selectRow({ rowIdx, checked, isShiftClick: false }); - }, [rowIdx, selectRow]); - // Select is always the first column const idx = viewportColumns[0].key === SELECT_COLUMN_KEY ? level + 1 : level; @@ -51,40 +45,39 @@ function GroupedRow({ } return ( -
- {viewportColumns.map(column => ( - - - - key={column.key} - id={id} - groupKey={groupKey} - childRows={childRows} - isExpanded={isExpanded} - isCellSelected={selectedCellIdx === column.idx} - column={column} - groupColumnIndex={idx} - toggleGroup={toggleGroup} - /> - - - ))} -
+ +
+ {viewportColumns.map(column => ( + + key={column.key} + id={id} + rowIdx={rowIdx} + groupKey={groupKey} + childRows={childRows} + isExpanded={isExpanded} + isCellSelected={selectedCellIdx === column.idx} + column={column} + groupColumnIndex={idx} + toggleGroup={toggleGroup} + /> + ))} +
+
); } diff --git a/src/Row.tsx b/src/Row.tsx index 49f32bbdf8..caf3f78f27 100644 --- a/src/Row.tsx +++ b/src/Row.tsx @@ -1,4 +1,4 @@ -import { memo, forwardRef, useCallback } from 'react'; +import { memo, forwardRef } from 'react'; import type { RefAttributes } from 'react'; import clsx from 'clsx'; @@ -6,7 +6,7 @@ import { groupRowSelectedClassname, rowClassname, rowSelectedClassname } from '. import Cell from './Cell'; import EditCell from './EditCell'; import type { RowRendererProps, SelectedCellProps } from './types'; -import { RowSelectionChangeContext, RowSelectionContext } from './hooks'; +import { RowSelectionProvider } from './hooks'; function Row({ cellRenderer: CellRenderer = Cell, @@ -25,15 +25,10 @@ function Row({ top, onRowChange, selectCell, - selectRow, 'aria-rowindex': ariaRowIndex, 'aria-selected': ariaSelected, ...props }: RowRendererProps, ref: React.Ref) { - const onRowSelectionChange = useCallback((checked: boolean, isShiftClick: boolean) => { - selectRow({ rowIdx, checked, isShiftClick }); - }, [rowIdx, selectRow]); - function handleDragEnter(event: React.MouseEvent) { setDraggedOverRowIdx?.(rowIdx); onMouseEnter?.(event); @@ -50,54 +45,52 @@ function Row({ ); return ( - - -
- {viewportColumns.map(column => { - const isCellSelected = selectedCellProps?.idx === column.idx; - if (selectedCellProps?.mode === 'EDIT' && isCellSelected) { - return ( - - key={column.key} - rowIdx={rowIdx} - column={column} - row={row} - onKeyDown={selectedCellProps.onKeyDown} - editorProps={selectedCellProps.editorProps} - /> - ); - } - + +
+ {viewportColumns.map(column => { + const isCellSelected = selectedCellProps?.idx === column.idx; + if (selectedCellProps?.mode === 'EDIT' && isCellSelected) { return ( - key={column.key} rowIdx={rowIdx} column={column} row={row} - isCopied={copiedCellIdx === column.idx} - isDraggedOver={draggedOverCellIdx === column.idx} - isCellSelected={isCellSelected} - dragHandleProps={isCellSelected ? (selectedCellProps as SelectedCellProps).dragHandleProps : undefined} - onFocus={isCellSelected ? (selectedCellProps as SelectedCellProps).onFocus : undefined} - onKeyDown={isCellSelected ? selectedCellProps!.onKeyDown : undefined} - onRowClick={onRowClick} - onRowChange={onRowChange} - selectCell={selectCell} + onKeyDown={selectedCellProps.onKeyDown} + editorProps={selectedCellProps.editorProps} /> ); - })} -
- - + } + + return ( + + ); + })} +
+ ); } diff --git a/src/hooks/useRowSelection.ts b/src/hooks/useRowSelection.ts index ab7df3436b..3e0abc0da2 100644 --- a/src/hooks/useRowSelection.ts +++ b/src/hooks/useRowSelection.ts @@ -1,8 +1,10 @@ import { createContext, useContext } from 'react'; -export const RowSelectionContext = +const RowSelectionContext = createContext(undefined); +export const RowSelectionProvider = RowSelectionContext.Provider; + export function useRowSelection() { const context = useContext(RowSelectionContext); if (context === undefined) { diff --git a/src/hooks/useRowSelectionChange.ts b/src/hooks/useRowSelectionChange.ts index 8139ae7a85..66ad20d3e5 100644 --- a/src/hooks/useRowSelectionChange.ts +++ b/src/hooks/useRowSelectionChange.ts @@ -1,7 +1,10 @@ import { createContext, useContext } from 'react'; +import type { SelectRowEvent } from '../types'; export const RowSelectionChangeContext = - createContext<(((checked: boolean, isShiftClick: boolean) => void) | undefined)>(undefined); + createContext<(((selectRowEvent: SelectRowEvent) => void) | undefined)>(undefined); + +export const RowSelectionChangeProvider = RowSelectionChangeContext.Provider; export function useRowSelectionChange() { const context = useContext(RowSelectionChangeContext); diff --git a/src/types.ts b/src/types.ts index 7b84c3b31f..96461917a1 100644 --- a/src/types.ts +++ b/src/types.ts @@ -89,6 +89,7 @@ export interface SummaryFormatterProps { } export interface GroupFormatterProps { + rowIdx: number; groupKey: unknown; column: CalculatedColumn; childRows: readonly TRow[]; @@ -165,7 +166,6 @@ export interface RowRendererProps extends Omit string | undefined; setDraggedOverRowIdx?: (overRowIdx: number) => void; selectCell: (position: Position, enableEditor?: boolean) => void; - selectRow: (selectRowEvent: SelectRowEvent) => void; } export interface FilterRendererProps { From 03324da25ec0f078c7783720d711ff4a5494d87b Mon Sep 17 00:00:00 2001 From: Aman Mahajan Date: Thu, 13 May 2021 10:12:35 -0500 Subject: [PATCH 05/12] Use a single 'useRowSelection' hook --- src/Columns.tsx | 5 ++--- src/hooks/index.ts | 1 - src/hooks/useRowSelection.ts | 23 ++++++++++++++++++++--- src/hooks/useRowSelectionChange.ts | 15 --------------- src/index.ts | 1 + 5 files changed, 23 insertions(+), 22 deletions(-) delete mode 100644 src/hooks/useRowSelectionChange.ts diff --git a/src/Columns.tsx b/src/Columns.tsx index f33530410d..fef78375d7 100644 --- a/src/Columns.tsx +++ b/src/Columns.tsx @@ -1,13 +1,12 @@ import { SelectCellFormatter } from './formatters'; -import { useRowSelection, useRowSelectionChange } from './hooks'; +import { useRowSelection } from './hooks'; import type { Column, FormatterProps, GroupFormatterProps } from './types'; import { stopPropagation } from './utils/domUtils'; export const SELECT_COLUMN_KEY = 'select-row'; function SelectFormatter(props: FormatterProps) { - const isRowSelected = useRowSelection(); - const onRowSelectionChange = useRowSelectionChange(); + const [isRowSelected, onRowSelectionChange] = useRowSelection(); return ( (undefined); +const RowSelectionContext = createContext(undefined); export const RowSelectionProvider = RowSelectionContext.Provider; -export function useRowSelection() { +function useSelection() { const context = useContext(RowSelectionContext); if (context === undefined) { throw new Error('useRowSelection must be used within a RowSelectionContext'); } return context; } + +export const RowSelectionChangeContext = + createContext<((selectRowEvent: SelectRowEvent) => void) | undefined>(undefined); + +export const RowSelectionChangeProvider = RowSelectionChangeContext.Provider; + +function useRowSelectionChange() { + const context = useContext(RowSelectionChangeContext); + if (context === undefined) { + throw new Error('useRowSelectionChange must be used within a RowSelectionChangeContext'); + } + return context; +} + +export function useRowSelection(): readonly [boolean, (selectRowEvent: SelectRowEvent) => void] { + return [useSelection(), useRowSelectionChange()]; +} diff --git a/src/hooks/useRowSelectionChange.ts b/src/hooks/useRowSelectionChange.ts deleted file mode 100644 index 66ad20d3e5..0000000000 --- a/src/hooks/useRowSelectionChange.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { createContext, useContext } from 'react'; -import type { SelectRowEvent } from '../types'; - -export const RowSelectionChangeContext = - createContext<(((selectRowEvent: SelectRowEvent) => void) | undefined)>(undefined); - -export const RowSelectionChangeProvider = RowSelectionChangeContext.Provider; - -export function useRowSelectionChange() { - const context = useContext(RowSelectionChangeContext); - if (context === undefined) { - throw new Error('useRowSelectionChange must be used within a RowSelectionChangeContext'); - } - return context; -} diff --git a/src/index.ts b/src/index.ts index c50ccc1e66..7ccf4c9298 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,6 +6,7 @@ export * from './Columns'; export * from './formatters'; export { default as TextEditor } from './editors/TextEditor'; export { default as SortableHeaderCell } from './headerCells/SortableHeaderCell'; +export { useRowSelection } from './hooks'; export type { Column, CalculatedColumn, From 8fa2be1d06c0ae97d15ee898af49c5c339691161 Mon Sep 17 00:00:00 2001 From: Aman Mahajan Date: Thu, 13 May 2021 10:39:20 -0500 Subject: [PATCH 06/12] Format --- src/GroupCell.tsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/GroupCell.tsx b/src/GroupCell.tsx index a734682ec2..8d86273818 100644 --- a/src/GroupCell.tsx +++ b/src/GroupCell.tsx @@ -6,12 +6,7 @@ import type { GroupRowRendererProps } from './GroupRow'; type SharedGroupRowRendererProps = Pick< GroupRowRendererProps, - | 'id' - | 'rowIdx' - | 'groupKey' - | 'childRows' - | 'isExpanded' - | 'toggleGroup' + 'id' | 'rowIdx' | 'groupKey' | 'childRows' | 'isExpanded' | 'toggleGroup' >; interface GroupCellProps extends SharedGroupRowRendererProps { From 56fbf948a3b1dc90d7dafc6fdeac4520c50aeb88 Mon Sep 17 00:00:00 2001 From: Aman Mahajan Date: Thu, 13 May 2021 10:45:47 -0500 Subject: [PATCH 07/12] Fix group selection --- src/Columns.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Columns.tsx b/src/Columns.tsx index fef78375d7..bc40380033 100644 --- a/src/Columns.tsx +++ b/src/Columns.tsx @@ -24,8 +24,7 @@ function SelectFormatter(props: FormatterProps) { // eslint-disable-next-line @typescript-eslint/no-explicit-any function SelectGroupFormatter(props: GroupFormatterProps) { - const isRowSelected = useRowSelection(); - const onRowSelectionChange = useRowSelectionChange(); + const [isRowSelected, onRowSelectionChange] = useRowSelection(); return ( Date: Thu, 13 May 2021 10:59:29 -0500 Subject: [PATCH 08/12] Cleanup import --- src/Columns.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Columns.tsx b/src/Columns.tsx index bc40380033..8592ceee8f 100644 --- a/src/Columns.tsx +++ b/src/Columns.tsx @@ -1,7 +1,7 @@ import { SelectCellFormatter } from './formatters'; import { useRowSelection } from './hooks'; import type { Column, FormatterProps, GroupFormatterProps } from './types'; -import { stopPropagation } from './utils/domUtils'; +import { stopPropagation } from './utils'; export const SELECT_COLUMN_KEY = 'select-row'; From e695269e85cb82420816c0b12772eea3dc655d94 Mon Sep 17 00:00:00 2001 From: Aman Mahajan Date: Thu, 13 May 2021 11:45:52 -0500 Subject: [PATCH 09/12] Update src/hooks/useRowSelection.ts Co-authored-by: Nicolas Stepien <567105+nstepien@users.noreply.github.com> --- src/hooks/useRowSelection.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/useRowSelection.ts b/src/hooks/useRowSelection.ts index 4f2b0a179e..887231b475 100644 --- a/src/hooks/useRowSelection.ts +++ b/src/hooks/useRowSelection.ts @@ -13,7 +13,7 @@ function useSelection() { return context; } -export const RowSelectionChangeContext = +const RowSelectionChangeContext = createContext<((selectRowEvent: SelectRowEvent) => void) | undefined>(undefined); export const RowSelectionChangeProvider = RowSelectionChangeContext.Provider; From f7b5a1683595edf5e320ff08cacade1d68f1fe90 Mon Sep 17 00:00:00 2001 From: Aman Mahajan Date: Thu, 13 May 2021 11:51:26 -0500 Subject: [PATCH 10/12] Cleanup useRowSelection: remove extra functions --- src/hooks/useRowSelection.ts | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/src/hooks/useRowSelection.ts b/src/hooks/useRowSelection.ts index 887231b475..5ba641bc1c 100644 --- a/src/hooks/useRowSelection.ts +++ b/src/hooks/useRowSelection.ts @@ -5,27 +5,18 @@ const RowSelectionContext = createContext(undefined); export const RowSelectionProvider = RowSelectionContext.Provider; -function useSelection() { - const context = useContext(RowSelectionContext); - if (context === undefined) { - throw new Error('useRowSelection must be used within a RowSelectionContext'); - } - return context; -} - const RowSelectionChangeContext = createContext<((selectRowEvent: SelectRowEvent) => void) | undefined>(undefined); export const RowSelectionChangeProvider = RowSelectionChangeContext.Provider; -function useRowSelectionChange() { - const context = useContext(RowSelectionChangeContext); - if (context === undefined) { - throw new Error('useRowSelectionChange must be used within a RowSelectionChangeContext'); +export function useRowSelection(): readonly [boolean, (selectRowEvent: SelectRowEvent) => void] { + const rowSelectionContext = useContext(RowSelectionContext); + const rowSelectionChangeContext = useContext(RowSelectionChangeContext); + + if (rowSelectionContext === undefined || rowSelectionChangeContext === undefined) { + throw new Error('useRowSelection must be used within DataGrid cells'); } - return context; -} -export function useRowSelection(): readonly [boolean, (selectRowEvent: SelectRowEvent) => void] { - return [useSelection(), useRowSelectionChange()]; + return [rowSelectionContext, rowSelectionChangeContext]; } From 44f08eae508a42f708a38706554eea7505d55652 Mon Sep 17 00:00:00 2001 From: Aman Mahajan Date: Thu, 13 May 2021 11:54:01 -0500 Subject: [PATCH 11/12] Do not destructure props --- src/Row.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Row.tsx b/src/Row.tsx index 3aa09a8a6a..595d7bafc4 100644 --- a/src/Row.tsx +++ b/src/Row.tsx @@ -29,8 +29,6 @@ function Row( height, onRowChange, selectCell, - 'aria-rowindex': ariaRowIndex, - 'aria-selected': ariaSelected, ...props }: RowRendererProps, ref: React.Ref @@ -100,8 +98,6 @@ function Row(
Date: Thu, 13 May 2021 12:08:03 -0500 Subject: [PATCH 12/12] Update src/hooks/useRowSelection.ts Co-authored-by: Nicolas Stepien <567105+nstepien@users.noreply.github.com> --- src/hooks/useRowSelection.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/useRowSelection.ts b/src/hooks/useRowSelection.ts index 5ba641bc1c..a97759c255 100644 --- a/src/hooks/useRowSelection.ts +++ b/src/hooks/useRowSelection.ts @@ -10,7 +10,7 @@ const RowSelectionChangeContext = export const RowSelectionChangeProvider = RowSelectionChangeContext.Provider; -export function useRowSelection(): readonly [boolean, (selectRowEvent: SelectRowEvent) => void] { +export function useRowSelection(): [boolean, (selectRowEvent: SelectRowEvent) => void] { const rowSelectionContext = useContext(RowSelectionContext); const rowSelectionChangeContext = useContext(RowSelectionChangeContext);