Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use context for selection #2338

Merged
merged 15 commits into from
May 13, 2021
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