Skip to content
67 changes: 30 additions & 37 deletions src/DataGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ import ScrollToCell from './ScrollToCell';
import { default as defaultRenderSortStatus } from './sortStatus';
import { cellDragHandleClassname, cellDragHandleFrozenClassname } from './style/cell';
import { rootClassname, viewportDraggingClassname } from './style/core';
import SummaryRow from './SummaryRow';
import { defaultRenderSummaryRow } from './SummaryRow';

export interface SelectCellState extends Position {
readonly mode: 'SELECT';
Expand Down Expand Up @@ -298,6 +298,8 @@ export function DataGrid<R, SR = unknown, K extends Key = Key>(props: DataGridPr
const headerRowHeight = rawHeaderRowHeight ?? (typeof rowHeight === 'number' ? rowHeight : 35);
const summaryRowHeight = rawSummaryRowHeight ?? (typeof rowHeight === 'number' ? rowHeight : 35);
const renderRow = renderers?.renderRow ?? defaultRenderers?.renderRow ?? defaultRenderRow;
const renderSummaryRow =
renderers?.renderSummaryRow ?? defaultRenderers?.renderSummaryRow ?? defaultRenderSummaryRow;
const renderCell = renderers?.renderCell ?? defaultRenderers?.renderCell ?? defaultRenderCell;
const renderSortStatus =
renderers?.renderSortStatus ?? defaultRenderers?.renderSortStatus ?? defaultRenderSortStatus;
Expand Down Expand Up @@ -1129,8 +1131,7 @@ export function DataGrid<R, SR = unknown, K extends Key = Key>(props: DataGridPr
lastFrozenColumnIndex,
onRowChange: handleFormatterRowChangeLatest,
selectCell: selectCellLatest,
selectedCellEditor: getCellEditor(rowIdx),
isTreeGrid
selectedCellEditor: getCellEditor(rowIdx)
})
);
}
Expand Down Expand Up @@ -1245,23 +1246,19 @@ export function DataGrid<R, SR = unknown, K extends Key = Key>(props: DataGridPr
const isSummaryRowSelected = selectedPosition.rowIdx === summaryRowIdx;
const top = headerRowsHeight + summaryRowHeight * rowIdx;

return (
<SummaryRow
key={rowIdx}
aria-rowindex={gridRowStart}
rowIdx={summaryRowIdx}
gridRowStart={gridRowStart}
row={row}
top={top}
bottom={undefined}
viewportColumns={getRowViewportColumns(summaryRowIdx)}
lastFrozenColumnIndex={lastFrozenColumnIndex}
selectedCellIdx={isSummaryRowSelected ? selectedPosition.idx : undefined}
isTop
selectCell={selectCellLatest}
isTreeGrid={isTreeGrid}
/>
);
return renderSummaryRow(rowIdx, {
'aria-rowindex': gridRowStart,
rowIdx: summaryRowIdx,
gridRowStart,
row,
top,
bottom: undefined,
viewportColumns: getRowViewportColumns(summaryRowIdx),
lastFrozenColumnIndex,
selectedCellIdx: isSummaryRowSelected ? selectedPosition.idx : undefined,
isTop: true,
selectCell: selectCellLatest
});
})}
<RowSelectionChangeContext value={selectRowLatest}>
{getViewportRows()}
Expand All @@ -1279,23 +1276,19 @@ export function DataGrid<R, SR = unknown, K extends Key = Key>(props: DataGridPr
? summaryRowHeight * (bottomSummaryRows.length - 1 - rowIdx)
: undefined;

return (
<SummaryRow
aria-rowindex={ariaRowCount - bottomSummaryRowsCount + rowIdx + 1}
key={rowIdx}
rowIdx={summaryRowIdx}
gridRowStart={gridRowStart}
row={row}
top={top}
bottom={bottom}
viewportColumns={getRowViewportColumns(summaryRowIdx)}
lastFrozenColumnIndex={lastFrozenColumnIndex}
selectedCellIdx={isSummaryRowSelected ? selectedPosition.idx : undefined}
isTop={false}
selectCell={selectCellLatest}
isTreeGrid={isTreeGrid}
/>
);
return renderSummaryRow(rowIdx, {
'aria-rowindex': ariaRowCount - bottomSummaryRowsCount + rowIdx + 1,
rowIdx: summaryRowIdx,
gridRowStart,
row,
top,
bottom,
viewportColumns: getRowViewportColumns(summaryRowIdx),
lastFrozenColumnIndex,
selectedCellIdx: isSummaryRowSelected ? selectedPosition.idx : undefined,
isTop: false,
selectCell: selectCellLatest
});
})}
</>
)}
Expand Down
5 changes: 1 addition & 4 deletions src/GroupRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { BaseRenderRowProps, GroupRow } from './types';
import { SELECT_COLUMN_KEY } from './Columns';
import GroupCell from './GroupCell';
import { cell, cellFrozen } from './style/cell';
import { rowClassname, rowSelectedClassname } from './style/row';
import { rowClassname } from './style/row';

const groupRow = css`
@layer rdg.GroupedRow {
Expand Down Expand Up @@ -44,7 +44,6 @@ function GroupedRow<R, SR>({
isRowSelectionDisabled: _isRowSelectionDisabled,
...props
}: GroupRowRendererProps<R, SR>) {
const isPositionOnRow = selectedCellIdx === -1;
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed it for now as we do not focus on the header row

// Select is always the first column
const idx = viewportColumns[0].key === SELECT_COLUMN_KEY ? row.level + 1 : row.level;

Expand All @@ -65,12 +64,10 @@ function GroupedRow<R, SR>({
aria-setsize={row.setSize}
aria-posinset={row.posInSet + 1} // aria-posinset is 1-based
aria-expanded={row.isExpanded}
tabIndex={isPositionOnRow ? 0 : -1}
className={classnames(
rowClassname,
groupRowClassname,
`rdg-row-${rowIdx % 2 === 0 ? 'even' : 'odd'}`,
isPositionOnRow && rowSelectedClassname,
className
)}
onMouseDown={handleSelectGroup}
Expand Down
7 changes: 1 addition & 6 deletions src/Row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { RowSelectionContext, useLatestFunc, type RowSelectionContextValue } fro
import { classnames, getColSpan } from './utils';
import type { CalculatedColumn, RenderRowProps } from './types';
import { useDefaultRenderers } from './DataGridDefaultRenderersContext';
import { rowClassname, rowSelectedClassname } from './style/row';
import { rowClassname } from './style/row';

function Row<R, SR>({
className,
Expand All @@ -18,7 +18,6 @@ function Row<R, SR>({
row,
viewportColumns,
selectedCellEditor,
isTreeGrid,
onCellMouseDown,
onCellClick,
onCellDoubleClick,
Expand All @@ -35,12 +34,9 @@ function Row<R, SR>({
onRowChange(column, rowIdx, newRow);
});

const isPositionOnRow = selectedCellIdx === -1;

className = classnames(
rowClassname,
`rdg-row-${rowIdx % 2 === 0 ? 'even' : 'odd'}`,
isPositionOnRow && rowSelectedClassname,
rowClass?.(row, rowIdx),
className
);
Expand Down Expand Up @@ -88,7 +84,6 @@ function Row<R, SR>({
<RowSelectionContext value={selectionValue}>
<div
role="row"
tabIndex={isTreeGrid ? (isPositionOnRow ? 0 : -1) : undefined}
className={className}
style={{
gridRowStart,
Expand Down
48 changes: 19 additions & 29 deletions src/SummaryRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,10 @@ import { memo } from 'react';
import { css } from 'ecij';

import { classnames, getColSpan } from './utils';
import type { RenderRowProps } from './types';
import {
bottomSummaryRowClassname,
rowClassname,
rowSelectedClassname,
topSummaryRowClassname
} from './style/row';
import type { RenderSummaryRowProps } from './types';
import { bottomSummaryRowClassname, rowClassname, topSummaryRowClassname } from './style/row';
import SummaryCell from './SummaryCell';

type SharedRenderRowProps<R, SR> = Pick<
RenderRowProps<R, SR>,
'viewportColumns' | 'rowIdx' | 'gridRowStart' | 'selectCell' | 'isTreeGrid'
>;

interface SummaryRowProps<R, SR> extends SharedRenderRowProps<R, SR> {
'aria-rowindex': number;
row: SR;
top: number | undefined;
bottom: number | undefined;
lastFrozenColumnIndex: number;
selectedCellIdx: number | undefined;
isTop: boolean;
}

const summaryRow = css`
@layer rdg.SummaryRow {
position: sticky;
Expand All @@ -36,6 +16,8 @@ const summaryRow = css`
const summaryRowClassname = `rdg-summary-row ${summaryRow}`;

function SummaryRow<R, SR>({
tabIndex,
className,
rowIdx,
gridRowStart,
row,
Expand All @@ -46,11 +28,8 @@ function SummaryRow<R, SR>({
selectedCellIdx,
isTop,
selectCell,
isTreeGrid,
'aria-rowindex': ariaRowIndex
}: SummaryRowProps<R, SR>) {
const isPositionOnRow = selectedCellIdx === -1;

}: RenderSummaryRowProps<R, SR>) {
const cells = [];

for (let index = 0; index < viewportColumns.length; index++) {
Expand Down Expand Up @@ -79,13 +58,13 @@ function SummaryRow<R, SR>({
<div
role="row"
aria-rowindex={ariaRowIndex}
tabIndex={isTreeGrid ? (isPositionOnRow ? 0 : -1) : undefined}
tabIndex={tabIndex}
className={classnames(
rowClassname,
`rdg-row-${rowIdx % 2 === 0 ? 'even' : 'odd'}`,
summaryRowClassname,
isTop ? topSummaryRowClassname : bottomSummaryRowClassname,
isPositionOnRow && rowSelectedClassname
className
)}
style={{
gridRowStart,
Expand All @@ -98,4 +77,15 @@ function SummaryRow<R, SR>({
);
}

export default memo(SummaryRow) as <R, SR>(props: SummaryRowProps<R, SR>) => React.JSX.Element;
const SummaryRowComponent = memo(SummaryRow) as <R, SR>(
props: RenderSummaryRowProps<R, SR>
) => React.JSX.Element;

export default SummaryRowComponent;

export function defaultRenderSummaryRow<R, SR>(
key: React.Key,
props: RenderSummaryRowProps<R, SR>
) {
return <SummaryRowComponent key={key} {...props} />;
}
40 changes: 35 additions & 5 deletions src/TreeDataGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useCallback, useMemo } from 'react';
import type { Key } from 'react';

import { useLatestFunc } from './hooks';
import { assertIsValidKeyGetter, getLeftRightKey } from './utils';
import { assertIsValidKeyGetter, classnames, getLeftRightKey } from './utils';
import type {
CellClipboardEvent,
CellCopyArgs,
Expand All @@ -14,6 +14,7 @@ import type {
Maybe,
Omit,
RenderRowProps,
RenderSummaryRowProps,
RowHeightArgs,
RowsChangeData
} from './types';
Expand All @@ -24,6 +25,8 @@ import type { DataGridProps } from './DataGrid';
import { useDefaultRenderers } from './DataGridDefaultRenderersContext';
import GroupedRow from './GroupRow';
import { defaultRenderRow } from './Row';
import { rowFocusable, rowSelectedClassname } from './style/row';
import SummaryRowComponent from './SummaryRow';
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import SummaryRowComponent from './SummaryRow';
import SummaryRow from './SummaryRow';


export interface TreeDataGridProps<R, SR = unknown, K extends Key = Key> extends Omit<
DataGridProps<R, SR, K>,
Expand Down Expand Up @@ -381,17 +384,23 @@ export function TreeDataGrid<R, SR = unknown, K extends Key = Key>({
lastFrozenColumnIndex,
draggedOverCellIdx,
selectedCellEditor,
isTreeGrid,
className,
...rowProps
}: RenderRowProps<R, SR>
) {
const isPositionOnRow = rowProps.selectedCellIdx === -1;
const tabIndex = isPositionOnRow ? 0 : -1;
className = classnames(className, rowFocusable, isPositionOnRow && rowSelectedClassname);

if (isGroupRow(row)) {
const { startRowIndex } = row;
return (
<GroupedRow
key={key}
{...rowProps}
aria-rowindex={headerAndTopSummaryRowsCount + startRowIndex + 1}
className={className}
tabIndex={tabIndex}
row={row}
groupBy={groupBy}
toggleGroup={toggleGroupLatest}
Expand All @@ -412,15 +421,16 @@ export function TreeDataGrid<R, SR = unknown, K extends Key = Key>({
'aria-rowindex': ariaRowIndex,
row,
rowClass,
className,
tabIndex,
onCellMouseDown,
onCellClick,
onCellDoubleClick,
onCellContextMenu,
onRowChange,
lastFrozenColumnIndex,
draggedOverCellIdx,
selectedCellEditor,
isTreeGrid
selectedCellEditor
});
}

Expand All @@ -443,7 +453,8 @@ export function TreeDataGrid<R, SR = unknown, K extends Key = Key>({
onCellPaste={rawOnCellPaste ? handleCellPaste : undefined}
renderers={{
...renderers,
renderRow
renderRow,
renderSummaryRow
}}
/>
);
Expand All @@ -453,6 +464,25 @@ function defaultGroupIdGetter(groupKey: string, parentId: string | undefined) {
return parentId !== undefined ? `${parentId}__${groupKey}` : groupKey;
}

function renderSummaryRow<R, SR>(
key: React.Key,
{ selectedCellIdx, className, ...props }: RenderSummaryRowProps<R, SR>
) {
const isPositionOnRow = selectedCellIdx === -1;
const tabIndex = isPositionOnRow ? 0 : -1;
className = classnames(className, rowFocusable, isPositionOnRow && rowSelectedClassname);

return (
<SummaryRowComponent
key={key}
tabIndex={tabIndex}
selectedCellIdx={selectedCellIdx}
className={className}
{...props}
/>
);
}

function isReadonlyArray(arr: unknown): arr is readonly unknown[] {
return Array.isArray(arr);
}
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export { TreeDataGrid, type TreeDataGridProps } from './TreeDataGrid';
export { DataGridDefaultRenderersContext } from './DataGridDefaultRenderersContext';
export { default as Row } from './Row';
export { default as Cell } from './Cell';
export { default as SummaryRow } from './SummaryRow';
export * from './Columns';
export * from './cellRenderers';
export { renderTextEditor } from './editors/renderTextEditor';
Expand Down Expand Up @@ -47,6 +48,7 @@ export type {
RenderSortPriorityProps,
RenderSortStatusProps,
RenderSummaryCellProps,
RenderSummaryRowProps,
RowHeightArgs,
RowsChangeData,
SelectCellOptions,
Expand Down
Loading