Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
74 changes: 39 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ Control column widths using the [`width`](#width-maybenumber--string), [`minWidt

### Custom Renderers

Replace default components with custom implementations using the [`renderers`](#renderers-mayberenderersr-sr) prop. Columns can also have custom renderers using the [`renderCell`](#rendercell-maybeprops-rendercellpropstrow-tsummaryrow--reactnode), [`renderHeaderCell`](#renderheadercell-maybeprops-renderheadercellpropstrow-tsummaryrow--reactnode), [`renderSummaryCell`](#rendersummarycell-maybeprops-rendersummarycellpropstsummaryrow-trow--reactnode), [`renderGroupCell`](#rendergroupcell-maybeprops-rendergroupcellpropstrow-tsummaryrow--reactnode), and [`renderEditCell`](#rendereditcell-maybeprops-rendereditcellpropstrow-tsummaryrow--reactnode) properties.
Replace default components with custom implementations using the [`renderers`](#renderers-mayberenderersr-sr) prop. Columns can also have custom renderers using the [`renderCell`](#rendercell-maybeprops-rendercellcontentpropstrow-tsummaryrow--reactnode), [`renderHeaderCell`](#renderheadercell-maybeprops-renderheadercellcontentpropstrow-tsummaryrow--reactnode), [`renderSummaryCell`](#rendersummarycell-maybeprops-rendersummarycellcontentpropstsummaryrow-trow--reactnode), [`renderGroupCell`](#rendergroupcell-maybeprops-rendergroupcellcontentpropstrow-tsummaryrow--reactnode), and [`renderEditCell`](#rendereditcell-maybeprops-rendereditcellcontentpropstrow-tsummaryrow--reactnode) properties.

## API Reference

Expand Down Expand Up @@ -869,6 +869,8 @@ function rowGrouper(rows: readonly Row[], columnKey: string): Record<string, rea
}
```

:warning: **Performance:** Define this function outside your component or memoize it with `useCallback` to prevent unnecessary re-renders.

###### `expandedGroupIds: ReadonlySet<unknown>`

**Required.** A set of group IDs that are currently expanded. Group IDs are generated by `groupIdGetter`.
Expand Down Expand Up @@ -898,6 +900,8 @@ function MyGrid() {

Function to generate unique IDs for group rows. If not provided, a default implementation is used that concatenates parent and group keys with `__`.

:warning: **Performance:** Define this function outside your component or memoize it with `useCallback` to prevent unnecessary re-renders.

###### `rowHeight?: Maybe<number | ((args: RowHeightArgs<R>) => number)>`

**Note:** Unlike `DataGrid`, the `rowHeight` function receives [`RowHeightArgs<R>`](#rowheightargstrow) which includes a `type` property to distinguish between regular rows and group rows:
Expand Down Expand Up @@ -927,11 +931,11 @@ The default cell component. Can be wrapped via the `renderers.renderCell` prop.

##### Props

[`CellRendererProps<TRow, TSummaryRow>`](#cellrendererpropstrow-tsummaryrow)
[`RenderCellProps<TRow, TSummaryRow>`](#rendercellpropstrow-tsummaryrow)

#### `<SelectCellFormatter />`
#### `<SelectCheckbox />`

A formatter component for rendering row selection checkboxes.
A component for rendering row selection checkboxes.

##### Props

Expand Down Expand Up @@ -1018,7 +1022,7 @@ Hook for managing row selection state. Used within custom cell renderers to impl
**Example:**

```tsx
function CustomSelectCell({ row }: RenderCellProps<Row>) {
function CustomSelectCell({ row }: RenderCellContentProps<Row>) {
const { isRowSelectionDisabled, isRowSelected, onRowSelectionChange } = useRowSelection();

return (
Expand All @@ -1040,7 +1044,7 @@ function CustomSelectCell({ row }: RenderCellProps<Row>) {

### Render Functions

#### `renderHeaderCell<R, SR>(props: RenderHeaderCellProps<R, SR>)`
#### `renderHeaderCell<R, SR>(props: RenderHeaderCellContentProps<R, SR>)`

The default header cell renderer. Renders sortable columns with sort indicators.

Expand All @@ -1059,7 +1063,7 @@ const columns: readonly Column<Row>[] = [
];
```

#### `renderTextEditor<TRow, TSummaryRow>(props: RenderEditCellProps<TRow, TSummaryRow>)`
#### `renderTextEditor<TRow, TSummaryRow>(props: RenderEditCellContentProps<TRow, TSummaryRow>)`

A basic text editor provided for convenience.

Expand Down Expand Up @@ -1119,13 +1123,13 @@ import { DataGrid, renderCheckbox } from 'react-data-grid';
/>;
```

#### `renderToggleGroup<R, SR>(props: RenderGroupCellProps<R, SR>)`
#### `renderToggleGroup<R, SR>(props: RenderGroupCellContentProps<R, SR>)`

The default group cell renderer used by the columns used for grouping (`groupBy` prop). This renders the expand/collapse toggle.

##### Props

[`RenderGroupCellProps<TRow, TSummaryRow>`](#rendergroupcellpropstrow-tsummaryrow)
[`RenderGroupCellContentProps<TRow, TSummaryRow>`](#rendergroupcellcontentpropstrow-tsummaryrow)

**Example:**

Expand All @@ -1141,7 +1145,7 @@ const columns: readonly Column<Row>[] = [
];
```

#### `renderValue<R, SR>(props: RenderCellProps<R, SR>)`
#### `renderValue<R, SR>(props: RenderCellContentProps<R, SR>)`

The default cell renderer that renders the value of `row[column.key]`.

Expand Down Expand Up @@ -1347,23 +1351,23 @@ Class name(s) for the header cell.

Class name(s) for summary cells. Can be a string or a function that returns a class name based on the summary row.

##### `renderCell?: Maybe<(props: RenderCellProps<TRow, TSummaryRow>) => ReactNode>`
##### `renderCell?: Maybe<(props: RenderCellContentProps<TRow, TSummaryRow>) => ReactNode>`

Render function to render the content of cells.

##### `renderHeaderCell?: Maybe<(props: RenderHeaderCellProps<TRow, TSummaryRow>) => ReactNode>`
##### `renderHeaderCell?: Maybe<(props: RenderHeaderCellContentProps<TRow, TSummaryRow>) => ReactNode>`

Render function to render the content of the header cell.

##### `renderSummaryCell?: Maybe<(props: RenderSummaryCellProps<TSummaryRow, TRow>) => ReactNode>`
##### `renderSummaryCell?: Maybe<(props: RenderSummaryCellContentProps<TSummaryRow, TRow>) => ReactNode>`

Render function to render the content of summary cells

##### `renderGroupCell?: Maybe<(props: RenderGroupCellProps<TRow, TSummaryRow>) => ReactNode>`
##### `renderGroupCell?: Maybe<(props: RenderGroupCellContentProps<TRow, TSummaryRow>) => ReactNode>`

Render function to render the content of group cells when using `TreeDataGrid`.

##### `renderEditCell?: Maybe<(props: RenderEditCellProps<TRow, TSummaryRow>) => ReactNode>`
##### `renderEditCell?: Maybe<(props: RenderEditCellContentProps<TRow, TSummaryRow>) => ReactNode>`

Render function to render the content of edit cells. When set, the column is automatically set to be editable

Expand Down Expand Up @@ -1533,12 +1537,12 @@ function getRowHeight(args: RowHeightArgs<Row>): number {
<TreeDataGrid rowHeight={getRowHeight} ... />
```

#### `RenderCellProps<TRow, TSummaryRow>`
#### `RenderCellContentProps<TRow, TSummaryRow>`

Props passed to custom cell renderers.

```tsx
interface RenderCellProps<TRow, TSummaryRow = unknown> {
interface RenderCellContentProps<TRow, TSummaryRow = unknown> {
column: CalculatedColumn<TRow, TSummaryRow>;
row: TRow;
rowIdx: number;
Expand All @@ -1551,9 +1555,9 @@ interface RenderCellProps<TRow, TSummaryRow = unknown> {
**Example:**

```tsx
import type { RenderCellProps } from 'react-data-grid';
import type { RenderCellContentProps } from 'react-data-grid';

function renderCell({ row, column, onRowChange }: RenderCellProps<MyRow>) {
function renderCell({ row, column, onRowChange }: RenderCellContentProps<MyRow>) {
return (
<div>
{row[column.key]}
Expand All @@ -1563,25 +1567,25 @@ function renderCell({ row, column, onRowChange }: RenderCellProps<MyRow>) {
}
```

#### `RenderHeaderCellProps<TRow, TSummaryRow>`
#### `RenderHeaderCellContentProps<TRow, TSummaryRow>`

Props passed to custom header cell renderers.

```tsx
interface RenderHeaderCellProps<TRow, TSummaryRow = unknown> {
interface RenderHeaderCellContentProps<TRow, TSummaryRow = unknown> {
column: CalculatedColumn<TRow, TSummaryRow>;
sortDirection: SortDirection | undefined;
priority: number | undefined;
tabIndex: number;
}
```

#### `RenderEditCellProps<TRow, TSummaryRow>`
#### `RenderEditCellContentProps<TRow, TSummaryRow>`

Props passed to custom edit cell renderers (editors).

```tsx
interface RenderEditCellProps<TRow, TSummaryRow = unknown> {
interface RenderEditCellContentProps<TRow, TSummaryRow = unknown> {
column: CalculatedColumn<TRow, TSummaryRow>;
row: TRow;
rowIdx: number;
Expand All @@ -1593,9 +1597,9 @@ interface RenderEditCellProps<TRow, TSummaryRow = unknown> {
**Example:**

```tsx
import type { RenderEditCellProps } from 'react-data-grid';
import type { RenderEditCellContentProps } from 'react-data-grid';

function CustomEditor({ row, column, onRowChange, onClose }: RenderEditCellProps<MyRow>) {
function renderEditor({ row, column, onRowChange, onClose }: RenderEditCellContentProps<MyRow>) {
return (
<input
autoFocus
Expand All @@ -1607,24 +1611,24 @@ function CustomEditor({ row, column, onRowChange, onClose }: RenderEditCellProps
}
```

#### `RenderSummaryCellProps<TSummaryRow, TRow>`
#### `RenderSummaryCellContentProps<TSummaryRow, TRow>`

Props passed to summary cell renderers.

```tsx
interface RenderSummaryCellProps<TSummaryRow, TRow = unknown> {
interface RenderSummaryCellContentProps<TSummaryRow, TRow = unknown> {
column: CalculatedColumn<TRow, TSummaryRow>;
row: TSummaryRow;
tabIndex: number;
}
```

#### `RenderGroupCellProps<TRow, TSummaryRow>`
#### `RenderGroupCellContentProps<TRow, TSummaryRow>`

Props passed to group cell renderers when using `TreeDataGrid`.

```tsx
interface RenderGroupCellProps<TRow, TSummaryRow = unknown> {
interface RenderGroupCellContentProps<TRow, TSummaryRow = unknown> {
groupKey: unknown;
column: CalculatedColumn<TRow, TSummaryRow>;
row: GroupRow<TRow>;
Expand All @@ -1650,14 +1654,14 @@ interface RenderRowProps<TRow, TSummaryRow = unknown> {
gridRowStart: number;
lastFrozenColumnIndex: number;
draggedOverCellIdx: number | undefined;
selectedCellEditor: ReactElement<RenderEditCellProps<TRow>> | undefined;
selectedCellEditor: ReactElement<EditCellProps<TRow, TSummaryRow>> | undefined;
onRowChange: (column: CalculatedColumn<TRow, TSummaryRow>, rowIdx: number, newRow: TRow) => void;
rowClass: Maybe<(row: TRow, rowIdx: number) => Maybe<string>>;
// ... and event handlers
}
```

#### `CellRendererProps<TRow, TSummaryRow>`
#### `RenderCellProps<TRow, TSummaryRow>`

Props passed to the cell renderer when using `renderers.renderCell`.

Expand All @@ -1669,7 +1673,7 @@ Custom renderer configuration for the grid.

```tsx
interface Renderers<TRow, TSummaryRow> {
renderCell?: Maybe<(key: Key, props: CellRendererProps<TRow, TSummaryRow>) => ReactNode>;
renderCell?: Maybe<(key: Key, props: RenderCellProps<TRow, TSummaryRow>) => ReactNode>;
renderCheckbox?: Maybe<(props: RenderCheckboxProps) => ReactNode>;
renderRow?: Maybe<(key: Key, props: RenderRowProps<TRow, TSummaryRow>) => ReactNode>;
renderSortStatus?: Maybe<(props: RenderSortStatusProps) => ReactNode>;
Expand Down Expand Up @@ -1778,9 +1782,9 @@ Arguments passed to the `onCellKeyDown` handler. The shape differs based on whet
**SELECT mode:**

```tsx
interface SelectCellKeyDownArgs<TRow, TSummaryRow> {
interface SelectCellKeyDownArgs<TRow, TSummaryRow = unknown> {
mode: 'SELECT';
column: CalculatedColumn<TRow, TSummaryRow>;
column: CalculatedColumn<TRow, TSummaryRow> | undefined;
row: TRow;
rowIdx: number;
selectCell: (position: Position, options?: SelectCellOptions) => void;
Expand All @@ -1790,7 +1794,7 @@ interface SelectCellKeyDownArgs<TRow, TSummaryRow> {
**EDIT mode:**

```tsx
interface EditCellKeyDownArgs<TRow, TSummaryRow> {
interface EditCellKeyDownArgs<TRow, TSummaryRow = unknown> {
mode: 'EDIT';
column: CalculatedColumn<TRow, TSummaryRow>;
row: TRow;
Expand Down
12 changes: 6 additions & 6 deletions src/Cell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { css } from 'ecij';

import { useRovingTabIndex } from './hooks';
import { createCellEvent, getCellClassname, getCellStyle, isCellEditableUtil } from './utils';
import type { CellMouseEventHandler, CellRendererProps } from './types';
import type { CellMouseEventHandler, RenderCellProps } from './types';

const cellDraggedOver = css`
@layer rdg.Cell {
Expand Down Expand Up @@ -33,7 +33,7 @@ function Cell<R, SR>({
selectCell,
style,
...props
}: CellRendererProps<R, SR>) {
}: RenderCellProps<R, SR>) {
const { tabIndex, childTabIndex, onFocus } = useRovingTabIndex(isCellSelected);

const { cellClass } = column;
Expand Down Expand Up @@ -126,10 +126,10 @@ function Cell<R, SR>({
);
}

const CellComponent = memo(Cell) as <R, SR>(props: CellRendererProps<R, SR>) => React.JSX.Element;
const MemoCell = memo(Cell) as <R, SR>(props: RenderCellProps<R, SR>) => React.JSX.Element;

export default CellComponent;
export { MemoCell as Cell };

export function defaultRenderCell<R, SR>(key: React.Key, props: CellRendererProps<R, SR>) {
return <CellComponent key={key} {...props} />;
export function defaultRenderCell<R, SR>(key: React.Key, props: RenderCellProps<R, SR>) {
return <MemoCell key={key} {...props} />;
}
27 changes: 16 additions & 11 deletions src/Columns.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import { useHeaderRowSelection, useRowSelection } from './hooks';
import type { Column, RenderCellProps, RenderGroupCellProps, RenderHeaderCellProps } from './types';
import { SelectCellFormatter } from './cellRenderers';
import type {
Column,
RenderCellContentProps,
RenderGroupCellContentProps,
RenderHeaderCellContentProps
} from './types';
import { SelectCheckbox } from './cellRenderers';

export const SELECT_COLUMN_KEY = 'rdg-select-column';

function HeaderRenderer({ tabIndex }: RenderHeaderCellProps<unknown>) {
function SelectAllCell({ tabIndex }: RenderHeaderCellContentProps<unknown>) {
const { isIndeterminate, isRowSelected, onRowSelectionChange } = useHeaderRowSelection();

return (
<SelectCellFormatter
<SelectCheckbox
aria-label="Select All"
tabIndex={tabIndex}
indeterminate={isIndeterminate}
Expand All @@ -20,11 +25,11 @@ function HeaderRenderer({ tabIndex }: RenderHeaderCellProps<unknown>) {
);
}

function SelectFormatter({ row, tabIndex }: RenderCellProps<unknown>) {
function RowSelectCell({ row, tabIndex }: RenderCellContentProps<unknown>) {
const { isRowSelectionDisabled, isRowSelected, onRowSelectionChange } = useRowSelection();

return (
<SelectCellFormatter
<SelectCheckbox
aria-label="Select"
tabIndex={tabIndex}
disabled={isRowSelectionDisabled}
Expand All @@ -36,11 +41,11 @@ function SelectFormatter({ row, tabIndex }: RenderCellProps<unknown>) {
);
}

function SelectGroupFormatter({ row, tabIndex }: RenderGroupCellProps<unknown>) {
function GroupSelectCell({ row, tabIndex }: RenderGroupCellContentProps<unknown>) {
const { isRowSelected, onRowSelectionChange } = useRowSelection();

return (
<SelectCellFormatter
<SelectCheckbox
aria-label="Select Group"
tabIndex={tabIndex}
value={isRowSelected}
Expand All @@ -62,12 +67,12 @@ export const SelectColumn: Column<any, any> = {
sortable: false,
frozen: true,
renderHeaderCell(props) {
return <HeaderRenderer {...props} />;
return <SelectAllCell {...props} />;
},
renderCell(props) {
return <SelectFormatter {...props} />;
return <RowSelectCell {...props} />;
},
renderGroupCell(props) {
return <SelectGroupFormatter {...props} />;
return <GroupSelectCell {...props} />;
}
};
Loading