Skip to content

Commit

Permalink
Use context for selection (#2338)
Browse files Browse the repository at this point in the history
* Use context for selection

* Use context for group selection

* Move context provider a level up

* Cleanup context usage

* Use a single 'useRowSelection' hook

* Format

* Fix group selection

* Cleanup import

* Update src/hooks/useRowSelection.ts

Co-authored-by: Nicolas Stepien <[email protected]>

* Cleanup useRowSelection: remove extra functions

* Do not destructure props

* Update src/hooks/useRowSelection.ts

Co-authored-by: Nicolas Stepien <[email protected]>

Co-authored-by: Nicolas Stepien <[email protected]>
  • Loading branch information
amanmahajan7 and nstepien authored May 13, 2021
1 parent 114f73c commit efc361e
Show file tree
Hide file tree
Showing 10 changed files with 130 additions and 124 deletions.
8 changes: 0 additions & 8 deletions src/Cell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ function Cell<R, SR>(
isCellSelected,
isCopied,
isDraggedOver,
isRowSelected,
row,
rowIdx,
dragHandleProps,
Expand All @@ -58,7 +57,6 @@ function Cell<R, SR>(
onContextMenu,
onRowChange,
selectCell,
selectRow,
...props
}: CellRendererProps<R, SR>,
ref: React.Ref<HTMLDivElement>
Expand Down Expand Up @@ -98,10 +96,6 @@ function Cell<R, SR>(
onRowChange(rowIdx, newRow);
}

function onRowSelectionChange(checked: boolean, isShiftClick: boolean) {
selectRow({ rowIdx, checked, isShiftClick });
}

return (
<div
role="gridcell"
Expand All @@ -124,8 +118,6 @@ function Cell<R, SR>(
rowIdx={rowIdx}
row={row}
isCellSelected={isCellSelected}
isRowSelected={isRowSelected}
onRowSelectionChange={onRowSelectionChange}
onRowChange={handleRowChange}
/>
{dragHandleProps && <div className={cellDragHandleClassname} {...dragHandleProps} />}
Expand Down
68 changes: 41 additions & 27 deletions src/Columns.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,46 @@
import { SelectCellFormatter } from './formatters';
import type { Column } from './types';
import { stopPropagation } from './utils/domUtils';
import { useRowSelection } from './hooks';
import type { Column, FormatterProps, GroupFormatterProps } from './types';
import { stopPropagation } from './utils';

export const SELECT_COLUMN_KEY = 'select-row';

function SelectFormatter(props: FormatterProps) {
const [isRowSelected, onRowSelectionChange] = useRowSelection();

return (
<SelectCellFormatter
aria-label="Select"
tabIndex={-1}
isCellSelected={props.isCellSelected}
value={isRowSelected}
onClick={stopPropagation}
onChange={(checked, isShiftClick) => {
onRowSelectionChange({ rowIdx: props.rowIdx, checked, isShiftClick });
}}
/>
);
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
function SelectGroupFormatter(props: GroupFormatterProps<any, any>) {
const [isRowSelected, onRowSelectionChange] = useRowSelection();

return (
<SelectCellFormatter
aria-label="Select Group"
tabIndex={-1}
isCellSelected={props.isCellSelected}
value={isRowSelected}
onChange={(checked) => {
onRowSelectionChange({ checked, isShiftClick: false, rowIdx: props.rowIdx });
}}
// Stop propagation to prevent row selection
onClick={stopPropagation}
/>
);
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const SelectColumn: Column<any, any> = {
key: SELECT_COLUMN_KEY,
Expand All @@ -22,29 +59,6 @@ export const SelectColumn: Column<any, any> = {
/>
);
},
formatter(props) {
return (
<SelectCellFormatter
aria-label="Select"
tabIndex={-1}
isCellSelected={props.isCellSelected}
value={props.isRowSelected}
onClick={stopPropagation}
onChange={props.onRowSelectionChange}
/>
);
},
groupFormatter(props) {
return (
<SelectCellFormatter
aria-label="Select Group"
tabIndex={-1}
isCellSelected={props.isCellSelected}
value={props.isRowSelected}
onChange={props.onRowSelectionChange}
// Stop propagation to prevent row selection
onClick={stopPropagation}
/>
);
}
formatter: SelectFormatter,
groupFormatter: SelectGroupFormatter
};
9 changes: 5 additions & 4 deletions src/DataGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import {
useCalculatedColumns,
useViewportColumns,
useViewportRows,
useLatestFunc
useLatestFunc,
RowSelectionChangeProvider
} from './hooks';
import HeaderRow from './HeaderRow';
import FilterRow from './FilterRow';
Expand Down Expand Up @@ -965,7 +966,6 @@ function DataGrid<R, SR>(
onFocus={selectedPosition.rowIdx === rowIdx ? handleFocus : undefined}
onKeyDown={selectedPosition.rowIdx === rowIdx ? handleKeyDown : undefined}
selectCell={selectCellWrapper}
selectRow={selectRowWrapper}
toggleGroup={toggleGroupWrapper}
/>
);
Expand Down Expand Up @@ -1004,7 +1004,6 @@ function DataGrid<R, SR>(
selectedCellProps={getSelectedCellProps(rowIdx)}
onRowChange={handleFormatterRowChangeWrapper}
selectCell={selectCellWrapper}
selectRow={selectRowWrapper}
/>
);
}
Expand Down Expand Up @@ -1098,7 +1097,9 @@ function DataGrid<R, SR>(
onFocus={onGridFocus}
/>
<div style={{ height: max(totalRowHeight, clientHeight) }} />
{getViewportRows()}
<RowSelectionChangeProvider value={selectRowWrapper}>
{getViewportRows()}
</RowSelectionChangeProvider>
{summaryRows?.map((row, rowIdx) => (
<SummaryRow<R, SR>
aria-rowindex={headerRowsCount + rowsCount + rowIdx + 1}
Expand Down
18 changes: 2 additions & 16 deletions src/GroupCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,7 @@ import type { GroupRowRendererProps } from './GroupRow';

type SharedGroupRowRendererProps<R, SR> = Pick<
GroupRowRendererProps<R, SR>,
| 'id'
| 'rowIdx'
| 'groupKey'
| 'childRows'
| 'isExpanded'
| 'isRowSelected'
| 'selectRow'
| 'toggleGroup'
'id' | 'rowIdx' | 'groupKey' | 'childRows' | 'isExpanded' | 'toggleGroup'
>;

interface GroupCellProps<R, SR> extends SharedGroupRowRendererProps<R, SR> {
Expand All @@ -29,20 +22,14 @@ function GroupCell<R, SR>({
childRows,
isExpanded,
isCellSelected,
isRowSelected,
column,
groupColumnIndex,
selectRow,
toggleGroup: toggleGroupWrapper
}: GroupCellProps<R, SR>) {
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;

Expand All @@ -60,13 +47,12 @@ function GroupCell<R, SR>({
>
{(!column.rowGroup || groupColumnIndex === column.idx) && column.groupFormatter && (
<column.groupFormatter
rowIdx={rowIdx}
groupKey={groupKey}
childRows={childRows}
column={column}
isExpanded={isExpanded}
isCellSelected={isCellSelected}
isRowSelected={isRowSelected}
onRowSelectionChange={onRowSelectionChange}
toggleGroup={toggleGroup}
/>
)}
Expand Down
79 changes: 39 additions & 40 deletions src/GroupRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import clsx from 'clsx';
import { groupRowClassname, groupRowSelectedClassname, rowClassname } from './style';
import { SELECT_COLUMN_KEY } from './Columns';
import GroupCell from './GroupCell';
import type { CalculatedColumn, Position, SelectRowEvent, Omit } from './types';
import type { CalculatedColumn, Position, Omit } from './types';
import { RowSelectionProvider } from './hooks';

export interface GroupRowRendererProps<R, SR = unknown>
extends Omit<React.HTMLAttributes<HTMLDivElement>, 'style' | 'children'> {
Expand All @@ -21,7 +22,6 @@ export interface GroupRowRendererProps<R, SR = unknown>
isExpanded: boolean;
isRowSelected: boolean;
selectCell: (position: Position, enableEditor?: boolean) => void;
selectRow: (selectRowEvent: SelectRowEvent) => void;
toggleGroup: (expandedGroupId: unknown) => void;
}

Expand All @@ -38,7 +38,6 @@ function GroupedRow<R, SR>({
selectedCellIdx,
isRowSelected,
selectCell,
selectRow,
toggleGroup,
...props
}: GroupRowRendererProps<R, SR>) {
Expand All @@ -50,44 +49,44 @@ function GroupedRow<R, SR>({
}

return (
<div
role="row"
aria-level={level}
aria-expanded={isExpanded}
className={clsx(
rowClassname,
groupRowClassname,
`rdg-row-${rowIdx % 2 === 0 ? 'even' : 'odd'}`,
{
[groupRowSelectedClassname]: selectedCellIdx === -1 // Select row if there is no selected cell
<RowSelectionProvider value={isRowSelected}>
<div
role="row"
aria-level={level}
aria-expanded={isExpanded}
className={clsx(
rowClassname,
groupRowClassname,
`rdg-row-${rowIdx % 2 === 0 ? 'even' : 'odd'}`,
{
[groupRowSelectedClassname]: selectedCellIdx === -1 // Select row if there is no selected cell
}
)}
onClick={selectGroup}
style={
{
top,
'--row-height': `${height}px`
} as unknown as CSSProperties
}
)}
onClick={selectGroup}
style={
{
top,
'--row-height': `${height}px`
} as unknown as CSSProperties
}
{...props}
>
{viewportColumns.map((column) => (
<GroupCell<R, SR>
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}
/>
))}
</div>
{...props}
>
{viewportColumns.map((column) => (
<GroupCell<R, SR>
key={column.key}
id={id}
rowIdx={rowIdx}
groupKey={groupKey}
childRows={childRows}
isExpanded={isExpanded}
isCellSelected={selectedCellIdx === column.idx}
column={column}
groupColumnIndex={idx}
toggleGroup={toggleGroup}
/>
))}
</div>
</RowSelectionProvider>
);
}

Expand Down
40 changes: 18 additions & 22 deletions src/Row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { getColSpan } from './utils';
import Cell from './Cell';
import EditCell from './EditCell';
import type { RowRendererProps, SelectedCellProps } from './types';
import { RowSelectionProvider } from './hooks';

function Row<R, SR = unknown>(
{
Expand All @@ -28,9 +29,6 @@ function Row<R, SR = unknown>(
height,
onRowChange,
selectCell,
selectRow,
'aria-rowindex': ariaRowIndex,
'aria-selected': ariaSelected,
...props
}: RowRendererProps<R, SR>,
ref: React.Ref<HTMLDivElement>
Expand Down Expand Up @@ -84,7 +82,6 @@ function Row<R, SR = unknown>(
isCopied={copiedCellIdx === column.idx}
isDraggedOver={draggedOverCellIdx === column.idx}
isCellSelected={isCellSelected}
isRowSelected={isRowSelected}
dragHandleProps={
isCellSelected ? (selectedCellProps as SelectedCellProps).dragHandleProps : undefined
}
Expand All @@ -93,29 +90,28 @@ function Row<R, SR = unknown>(
onRowClick={onRowClick}
onRowChange={onRowChange}
selectCell={selectCell}
selectRow={selectRow}
/>
);
}

return (
<div
role="row"
aria-rowindex={ariaRowIndex}
aria-selected={ariaSelected}
ref={ref}
className={className}
onMouseEnter={handleDragEnter}
style={
{
top,
'--row-height': `${height}px`
} as unknown as CSSProperties
}
{...props}
>
{cells}
</div>
<RowSelectionProvider value={isRowSelected}>
<div
role="row"
ref={ref}
className={className}
onMouseEnter={handleDragEnter}
style={
{
top,
'--row-height': `${height}px`
} as unknown as CSSProperties
}
{...props}
>
{cells}
</div>
</RowSelectionProvider>
);
}

Expand Down
1 change: 1 addition & 0 deletions src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from './useViewportColumns';
export * from './useViewportRows';
export * from './useFocusRef';
export * from './useLatestFunc';
export * from './useRowSelection';
Loading

0 comments on commit efc361e

Please sign in to comment.