Skip to content
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 33 additions & 19 deletions src/Cell.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { memo } from 'react';
import { forwardRef, memo, type RefAttributes } from 'react';
import { css } from '@linaria/core';

import { useRovingTabIndex } from './hooks';
Expand All @@ -25,31 +25,36 @@ const cellDraggedOver = css`

const cellDraggedOverClassname = `rdg-cell-dragged-over ${cellDraggedOver}`;

function Cell<R, SR>({
column,
colSpan,
isCellSelected,
isCopied,
isDraggedOver,
row,
rowIdx,
onClick,
onDoubleClick,
onContextMenu,
onRowChange,
selectCell,
...props
}: CellRendererProps<R, SR>) {
function Cell<R, SR>(
{
column,
colSpan,
isCellSelected,
isCopied,
isDraggedOver,
row,
rowIdx,
className,
onClick,
onDoubleClick,
onContextMenu,
onRowChange,
selectCell,
...props
}: CellRendererProps<R, SR>,
refComponent: React.Ref<HTMLDivElement>
) {
const { tabIndex, childTabIndex, onFocus } = useRovingTabIndex(isCellSelected);

const { cellClass } = column;
const className = getCellClassname(
className = getCellClassname(
column,
{
[cellCopiedClassname]: isCopied,
[cellDraggedOverClassname]: isDraggedOver
},
typeof cellClass === 'function' ? cellClass(row) : cellClass
typeof cellClass === 'function' ? cellClass(row) : cellClass,
className
);
const isEditable = isCellEditable(column, row);

Expand Down Expand Up @@ -95,6 +100,7 @@ function Cell<R, SR>({
aria-colspan={colSpan}
aria-selected={isCellSelected}
aria-readonly={!isEditable || undefined}
ref={refComponent}
tabIndex={tabIndex}
className={className}
style={getCellStyle(column, colSpan)}
Expand All @@ -115,4 +121,12 @@ function Cell<R, SR>({
);
}

export default memo(Cell) as <R, SR>(props: CellRendererProps<R, SR>) => JSX.Element;
const CellComponent = memo(forwardRef(Cell)) as <R, SR>(
props: CellRendererProps<R, SR> & RefAttributes<HTMLDivElement>
) => JSX.Element;

export default CellComponent;

export function defaultRenderCell<R, SR>(key: React.Key, props: CellRendererProps<R, SR>) {
return <CellComponent key={key} {...props} />;
}
7 changes: 5 additions & 2 deletions src/DataGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import type {
SelectRowEvent,
SortColumn
} from './types';
import { defaultRenderCell } from './Cell';
import { renderCheckbox as defaultRenderCheckbox } from './cellRenderers';
import {
DataGridDefaultRenderersProvider,
Expand Down Expand Up @@ -252,6 +253,7 @@ function DataGrid<R, SR, K extends Key>(
const headerRowHeight = rawHeaderRowHeight ?? (typeof rowHeight === 'number' ? rowHeight : 35);
const summaryRowHeight = rawSummaryRowHeight ?? (typeof rowHeight === 'number' ? rowHeight : 35);
const renderRow = renderers?.renderRow ?? defaultRenderers?.renderRow ?? defaultRenderRow;
const renderCell = renderers?.renderCell ?? defaultRenderers?.renderCell ?? defaultRenderCell;
const renderSortStatus =
renderers?.renderSortStatus ?? defaultRenderers?.renderSortStatus ?? defaultRenderSortStatus;
const renderCheckbox =
Expand Down Expand Up @@ -334,9 +336,10 @@ function DataGrid<R, SR, K extends Key>(
const defaultGridComponents = useMemo(
() => ({
renderCheckbox,
renderSortStatus
renderSortStatus,
renderCell
}),
[renderCheckbox, renderSortStatus]
[renderCheckbox, renderSortStatus, renderCell]
);

const allRowsSelected = useMemo((): boolean => {
Expand Down
35 changes: 19 additions & 16 deletions src/Row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import clsx from 'clsx';
import { RowSelectionProvider, useLatestFunc } from './hooks';
import { getColSpan, getRowStyle } from './utils';
import type { CalculatedColumn, RenderRowProps } from './types';
import Cell from './Cell';
import { defaultRenderCell } from './Cell';
import { useDefaultRenderers } from './DataGridDefaultRenderersProvider';
import { rowClassname, rowSelectedClassname } from './style/row';

function Row<R, SR>(
Expand Down Expand Up @@ -33,6 +34,9 @@ function Row<R, SR>(
}: RenderRowProps<R, SR>,
ref: React.Ref<HTMLDivElement>
) {
const defaultComponents = useDefaultRenderers<R, SR>();
const cellRenderer = defaultComponents?.renderCell ?? defaultRenderCell;

const handleRowChange = useLatestFunc((column: CalculatedColumn<R, SR>, newRow: R) => {
onRowChange(column, rowIdx, newRow);
});
Expand Down Expand Up @@ -68,21 +72,20 @@ function Row<R, SR>(
cells.push(selectedCellEditor);
} else {
cells.push(
<Cell
key={column.key}
column={column}
colSpan={colSpan}
row={row}
rowIdx={rowIdx}
isCopied={copiedCellIdx === idx}
isDraggedOver={draggedOverCellIdx === idx}
isCellSelected={isCellSelected}
onClick={onCellClick}
onDoubleClick={onCellDoubleClick}
onContextMenu={onCellContextMenu}
onRowChange={handleRowChange}
selectCell={selectCell}
/>
cellRenderer(column.key, {
column,
colSpan,
row,
rowIdx,
isCopied: copiedCellIdx === idx,
isDraggedOver: draggedOverCellIdx === idx,
isCellSelected,
onClick: onCellClick,
onDoubleClick: onCellDoubleClick,
onContextMenu: onCellContextMenu,
onRowChange: handleRowChange,
selectCell
})
);
}
}
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export { default, type DataGridProps, type DataGridHandle } from './DataGrid';
export { default as TreeDataGrid, type TreeDataGridProps } from './TreeDataGrid';
export { DataGridDefaultRenderersProvider } from './DataGridDefaultRenderersProvider';
export { default as Row } from './Row';
export { default as Cell } from './Cell';
export * from './Columns';
export * from './cellRenderers';
export { default as textEditor } from './editors/textEditor';
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ export interface Renderers<TRow, TSummaryRow> {
renderCheckbox?: Maybe<(props: RenderCheckboxProps) => ReactNode>;
renderRow?: Maybe<(key: Key, props: RenderRowProps<TRow, TSummaryRow>) => ReactNode>;
renderSortStatus?: Maybe<(props: RenderSortStatusProps) => ReactNode>;
renderCell?: Maybe<(key: Key, props: CellRendererProps<TRow, TSummaryRow>) => ReactNode>;
noRowsFallback?: Maybe<ReactNode>;
}

Expand Down