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

Remove onRowsUpdate, enableCellCopyPaste and enableCellDragAndDrop Props #2194

Merged
merged 17 commits into from
Oct 30, 2020
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
- **Props:**
- `className`
- `style`
- `onRowsChange`
- `onFill`
- `onPaste`
- `onSelectedCellChange`
- ⚠️ This replaces the `onCellSelected` and `onCellDeSelected` props
- `enableFilters`
Expand Down Expand Up @@ -58,6 +61,8 @@
- ⚠️ `onGridKeyDown`
- ⚠️ `onGridKeyUp`
- ⚠️ `onRowDoubleClick`
- ⚠️ `onRowsUpdate`
- Use `onRowsChange`, `onFill`, and `onPaste` instead.
- ⚠️ `onHeaderDrop`
- ⚠️ `draggableHeaderCell`
- Check [#2007](https://github.com/adazzle/react-data-grid/pull/2007) on how to migrate
Expand Down Expand Up @@ -95,7 +100,6 @@
- ⚠️ `minHeight` to `height`
- ⚠️ `minWidth` to `width`
- ⚠️ `onGridSort` to `onSort`
- ⚠️ `onGridRowsUpdated` to `onRowsUpdate`
- ⚠️ `emptyRowsView` to `emptyRowsRenderer`
- ⚠️ `rowKey` to `rowKeyGetter`
- ⚠️ `rowData` to `row`
Expand Down
161 changes: 68 additions & 93 deletions src/DataGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ import {
Filters,
Position,
RowRendererProps,
RowsUpdateEvent,
SelectRowEvent,
CommitEvent,
SelectedCellProps,
EditCellProps,
Dictionary
Dictionary,
FillEvent,
PasteEvent
} from './types';
import { CellNavigationMode, SortDirection } from './enums';

Expand Down Expand Up @@ -89,14 +89,6 @@ export interface DataGridProps<R, SR = unknown> extends SharedDivProps {
summaryRows?: readonly SR[];
/** The getter should return a unique key for each row */
rowKeyGetter?: (row: R) => React.Key;
/**
* Callback called whenever row data is updated
* When editing is enabled, this callback will be called for the following scenarios
* 1. Copy/pasting the value from one cell to another <kbd>CTRL</kbd>+<kbd>C</kbd>, <kbd>CTRL</kbd>+<kbd>V</kbd>
* 2. Update multiple cells by dragging the fill handle of a cell up or down to a destination cell.
* 3. Update all cells under a given cell by double clicking the cell's fill handle.
*/
onRowsUpdate?: <E extends RowsUpdateEvent>(event: E) => void;
onRowsChange?: (rows: R[]) => void;

/**
Expand Down Expand Up @@ -129,6 +121,8 @@ export interface DataGridProps<R, SR = unknown> extends SharedDivProps {
rowGrouper?: (rows: readonly R[], columnKey: string) => Dictionary<readonly R[]>;
expandedGroupIds?: ReadonlySet<unknown>;
onExpandedGroupIdsChange?: (expandedGroupIds: Set<unknown>) => void;
onFill?: (event: FillEvent<R>) => R[];
onPaste?: (event: PasteEvent<R>) => R;

/**
* Custom renderers
Expand Down Expand Up @@ -178,7 +172,6 @@ function DataGrid<R, SR>({
rows: rawRows,
summaryRows,
rowKeyGetter,
onRowsUpdate,
onRowsChange,
// Dimensions props
rowHeight = 35,
Expand All @@ -205,6 +198,8 @@ function DataGrid<R, SR>({
onScroll,
onColumnResize,
onSelectedCellChange,
onFill,
onPaste,
// Toggles and modes
enableFilters = false,
enableCellCopyPaste = false,
Expand All @@ -228,15 +223,10 @@ function DataGrid<R, SR>({
const [scrollLeft, setScrollLeft] = useState(0);
const [columnWidths, setColumnWidths] = useState<ReadonlyMap<string, number>>(() => new Map());
const [selectedPosition, setSelectedPosition] = useState<SelectCellState | EditCellState<R>>({ idx: -1, rowIdx: -1, mode: 'SELECT' });
const [copiedPosition, setCopiedPosition] = useState<Position & { value: unknown } | null>(null);
const [copiedCell, setCopiedCell] = useState<{ row: R; columnKey: string } | null>(null);
const [isDragging, setDragging] = useState(false);
const [draggedOverRowIdx, setOverRowIdx] = useState<number | undefined>(undefined);

const setDraggedOverRowIdx = useCallback((rowIdx?: number) => {
setOverRowIdx(rowIdx);
latestDraggedOverRowIdx.current = rowIdx;
}, []);

/**
* refs
*/
Expand Down Expand Up @@ -376,8 +366,24 @@ function DataGrid<R, SR>({
}));

/**
* event handlers
*/
* callbacks
*/
const handleColumnResize = useCallback((column: CalculatedColumn<R, SR>, width: number) => {
const newColumnWidths = new Map(columnWidths);
newColumnWidths.set(column.key, width);
setColumnWidths(newColumnWidths);

onColumnResize?.(column.idx, width);
}, [columnWidths, onColumnResize]);

const setDraggedOverRowIdx = useCallback((rowIdx?: number) => {
setOverRowIdx(rowIdx);
latestDraggedOverRowIdx.current = rowIdx;
}, []);

/**
* event handlers
*/
function handleKeyDown(event: React.KeyboardEvent<HTMLDivElement>) {
const { key, keyCode } = event;
const row = rows[selectedPosition.rowIdx];
Expand Down Expand Up @@ -420,7 +426,7 @@ function DataGrid<R, SR>({

switch (event.key) {
case 'Escape':
setCopiedPosition(null);
setCopiedCell(null);
closeEditor();
return;
case 'ArrowUp':
Expand Down Expand Up @@ -451,31 +457,10 @@ function DataGrid<R, SR>({
onScroll?.(event);
}

const handleColumnResize = useCallback((column: CalculatedColumn<R, SR>, width: number) => {
const newColumnWidths = new Map(columnWidths);
newColumnWidths.set(column.key, width);
setColumnWidths(newColumnWidths);

onColumnResize?.(column.idx, width);
}, [columnWidths, onColumnResize]);

function getRawRowIdx(rowIdx: number) {
return hasGroups ? rawRows.indexOf(rows[rowIdx] as R) : rowIdx;
}

function handleCommit({ cellKey, rowIdx, updated }: CommitEvent) {
rowIdx = getRawRowIdx(rowIdx);
onRowsUpdate?.({
cellKey,
fromRow: rowIdx,
toRow: rowIdx,
updated,
action: 'CELL_UPDATE'
});

closeEditor();
}

function commitEditorChanges() {
if (
columns[selectedPosition.idx]?.editor === undefined
Expand All @@ -491,33 +476,32 @@ function DataGrid<R, SR>({

function handleCopy() {
const { idx, rowIdx } = selectedPosition;
const rawRowIdx = getRawRowIdx(rowIdx);
const value = rawRows[rawRowIdx][columns[idx].key as keyof R];
setCopiedPosition({ idx, rowIdx, value });
setCopiedCell({ row: rawRows[getRawRowIdx(rowIdx)], columnKey: columns[idx].key });
}

function handlePaste() {
const { idx, rowIdx } = selectedPosition;
const targetRow = rawRows[getRawRowIdx(rowIdx)];
if (
copiedPosition === null
!onPaste
|| !onRowsChange
|| copiedCell === null
|| !isCellEditable(selectedPosition)
|| (copiedPosition.idx === selectedPosition.idx && copiedPosition.rowIdx === selectedPosition.rowIdx)
) {
return;
}

const fromRow = getRawRowIdx(copiedPosition.rowIdx);
const fromCellKey = columns[copiedPosition.idx].key;
const toRow = getRawRowIdx(selectedPosition.rowIdx);
const cellKey = columns[selectedPosition.idx].key;

onRowsUpdate?.({
cellKey,
fromRow,
toRow,
updated: { [cellKey]: copiedPosition.value } as unknown as never,
action: 'COPY_PASTE',
fromCellKey
const updatedTargetRow = onPaste({
sourceRow: copiedCell.row,
sourceColumnKey: copiedCell.columnKey,
targetRow,
targetColumnKey: columns[idx].key
});

const updatedRows = [...rawRows];
updatedRows[rowIdx] = updatedTargetRow;

onRowsChange(updatedRows);
}

function handleCellInput(event: React.KeyboardEvent<HTMLDivElement>) {
Expand Down Expand Up @@ -552,21 +536,21 @@ function DataGrid<R, SR>({
}

function handleDragEnd() {
if (latestDraggedOverRowIdx.current === undefined) return;
const overRowIdx = latestDraggedOverRowIdx.current;
if (overRowIdx === undefined || !onFill || !onRowsChange) return;

const { idx, rowIdx } = selectedPosition;
const column = columns[idx];
const cellKey = column.key;
const value = rawRows[rowIdx][cellKey as keyof R];

onRowsUpdate?.({
cellKey,
fromRow: rowIdx,
toRow: latestDraggedOverRowIdx.current,
updated: { [cellKey]: value } as unknown as never,
action: 'CELL_DRAG'
});
const sourceRow = rawRows[rowIdx];
const startRowIndex = rowIdx < overRowIdx ? rowIdx + 1 : overRowIdx;
const endRowIndex = rowIdx < overRowIdx ? overRowIdx + 1 : rowIdx;
const targetRows = rawRows.slice(startRowIndex, endRowIndex);

const updatedTargetRows = onFill({ columnKey: columns[idx].key, sourceRow, targetRows });
const updatedRows = [...rawRows];
for (let i = startRowIndex; i < endRowIndex; i++) {
updatedRows[i] = updatedTargetRows[i - startRowIndex];
}
onRowsChange(updatedRows);
setDraggedOverRowIdx(undefined);
}

Expand All @@ -593,18 +577,18 @@ function DataGrid<R, SR>({

function handleDoubleClick(event: React.MouseEvent<HTMLDivElement>) {
event.stopPropagation();
if (!onFill || !onRowsChange) return;

const column = columns[selectedPosition.idx];
const cellKey = column.key;
const value = rawRows[selectedPosition.rowIdx][cellKey as keyof R];

onRowsUpdate?.({
cellKey,
fromRow: selectedPosition.rowIdx,
toRow: rawRows.length - 1,
updated: { [cellKey]: value } as unknown as never,
action: 'COLUMN_FILL'
});
const { idx, rowIdx } = selectedPosition;
const sourceRow = rawRows[rowIdx];
const targetRows = rawRows.slice(rowIdx + 1);

const updatedTargetRows = onFill({ columnKey: columns[idx].key, sourceRow, targetRows });
const updatedRows = [...rawRows];
for (let i = rowIdx + 1; i < updatedRows.length; i++) {
updatedRows[i] = updatedTargetRows[i - rowIdx - 1];
}
onRowsChange(updatedRows);
}

function handleRowChange(row: Readonly<R>, commitChanges?: boolean) {
Expand Down Expand Up @@ -788,16 +772,8 @@ function DataGrid<R, SR>({
mode: 'EDIT',
idx: selectedPosition.idx,
onKeyDown: handleKeyDown,
editorPortalTarget,
editorContainerProps: {
rowHeight,
scrollLeft,
scrollTop,
firstEditorKeyPress: selectedPosition.key,
onCommit: handleCommit,
onCommitCancel: closeEditor
},
editorProps: {
editorPortalTarget,
rowHeight,
row: selectedPosition.row,
onRowChange: handleRowChange,
Expand Down Expand Up @@ -871,7 +847,7 @@ function DataGrid<R, SR>({
onRowClick={onRowClick}
rowClass={rowClass}
top={top}
copiedCellIdx={copiedPosition?.rowIdx === rowIdx ? copiedPosition.idx : undefined}
copiedCellIdx={copiedCell?.row === row ? columns.findIndex(c => c.key === copiedCell.columnKey) : undefined}
draggedOverCellIdx={getDraggedOverCellIdx(rowIdx)}
setDraggedOverRowIdx={isDragging ? setDraggedOverRowIdx : undefined}
selectedCellProps={getSelectedCellProps(rowIdx)}
Expand All @@ -885,7 +861,6 @@ function DataGrid<R, SR>({
// Reset the positions if the current values are no longer valid. This can happen if a column or row is removed
if (selectedPosition.idx >= columns.length || selectedPosition.rowIdx >= rows.length) {
setSelectedPosition({ idx: -1, rowIdx: -1, mode: 'SELECT' });
setCopiedPosition(null);
setDraggedOverRowIdx(undefined);
}

Expand Down
13 changes: 3 additions & 10 deletions src/EditCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,15 @@ import React, { useState, useCallback } from 'react';
import clsx from 'clsx';

import EditorContainer from './editors/EditorContainer';
import { CellRendererProps, SharedEditorContainerProps, SharedEditorProps } from './types';
import { CellRendererProps, SharedEditorProps, Omit } from './types';

type SharedCellRendererProps<R, SR> = Pick<CellRendererProps<R, SR>,
| 'rowIdx'
| 'row'
| 'column'
>;

interface EditCellRendererProps<R, SR> extends SharedCellRendererProps<R, SR>, Omit<React.HTMLAttributes<HTMLDivElement>, 'style' | 'children'> {
editorPortalTarget: Element;
editorContainerProps: SharedEditorContainerProps;
interface EditCellProps<R, SR> extends SharedCellRendererProps<R, SR>, Omit<React.HTMLAttributes<HTMLDivElement>, 'style' | 'children'> {
amanmahajan7 marked this conversation as resolved.
Show resolved Hide resolved
editorProps: SharedEditorProps<R>;
}

amanmahajan7 marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -21,12 +19,9 @@ export default function EditCell<R, SR>({
column,
row,
rowIdx,
editorPortalTarget,
editorContainerProps,
editorProps,
onKeyDown,
...props
}: EditCellRendererProps<R, SR>) {
}: EditCellProps<R, SR>) {
const [dimensions, setDimensions] = useState<{ left: number; top: number } | null>(null);

const cellRef = useCallback(node => {
Expand Down Expand Up @@ -59,7 +54,6 @@ export default function EditCell<R, SR>({
return (
<EditorContainer
{...editorProps}
editorPortalTarget={editorPortalTarget}
rowIdx={rowIdx}
column={column}
left={gridLeft}
Expand All @@ -79,7 +73,6 @@ export default function EditCell<R, SR>({
width: column.width,
left: column.left
}}
onKeyDown={onKeyDown}
{...props}
>
{getCellContent()}
Expand Down
2 changes: 0 additions & 2 deletions src/Row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ function Row<R, SR = unknown>({
column={column}
row={row}
onKeyDown={selectedCellProps.onKeyDown}
editorPortalTarget={selectedCellProps.editorPortalTarget}
editorContainerProps={selectedCellProps.editorContainerProps}
editorProps={selectedCellProps.editorProps}
/>
);
Expand Down
1 change: 0 additions & 1 deletion src/enums.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export type CellNavigationMode = 'NONE' | 'CHANGE_ROW' | 'LOOP_OVER_ROW';
export type UpdateActions = 'CELL_UPDATE' | 'COLUMN_FILL' | 'COPY_PASTE' | 'CELL_DRAG';
export type SortDirection = 'ASC' | 'DESC' | 'NONE';
Loading