Skip to content
63 changes: 28 additions & 35 deletions src/DataGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ import {
viewportDraggingClassname,
frozenColumnShadowTopClassname
} from './style/core';
import SummaryRow from './SummaryRow';
import { defaultRenderSummaryRow } from './SummaryRow';

export type DefaultColumnOptions<R, SR> = Pick<
Column<R, SR>,
Expand Down Expand Up @@ -294,6 +294,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 @@ -1081,8 +1083,7 @@ export function DataGrid<R, SR = unknown, K extends Key = Key>(props: DataGridPr
draggedOverCellIdx: getDraggedOverCellIdx(rowIdx),
onRowChange: handleFormatterRowChangeLatest,
setActivePosition: setPositionLatest,
activeCellEditor: getCellEditor(rowIdx),
isTreeGrid
activeCellEditor: getCellEditor(rowIdx)
});
})
.toArray();
Expand Down Expand Up @@ -1181,22 +1182,18 @@ export function DataGrid<R, SR = unknown, K extends Key = Key>(props: DataGridPr
const isSummaryRowActive = activePosition.rowIdx === summaryRowIdx;
const top = headerRowsHeight + summaryRowHeight * rowIdx;

return (
<SummaryRow
key={rowIdx}
aria-rowindex={gridRowStart}
rowIdx={summaryRowIdx}
gridRowStart={gridRowStart}
row={row}
top={top}
bottom={undefined}
iterateOverViewportColumnsForRow={iterateOverViewportColumnsForRow}
activeCellIdx={isSummaryRowActive ? activePosition.idx : undefined}
isTop
setActivePosition={setPositionLatest}
isTreeGrid={isTreeGrid}
/>
);
return renderSummaryRow(rowIdx, {
'aria-rowindex': gridRowStart,
rowIdx: summaryRowIdx,
gridRowStart,
row,
top,
bottom: undefined,
iterateOverViewportColumnsForRow,
activeCellIdx: isSummaryRowActive ? activePosition.idx : undefined,
isTop: true,
setActivePosition: setPositionLatest
});
})}
<RowSelectionChangeContext value={selectRowLatest}>
{getViewportRows()}
Expand All @@ -1214,22 +1211,18 @@ export function DataGrid<R, SR = unknown, K extends Key = Key>(props: DataGridPr
? summaryRowHeight * (bottomSummaryRowsCount - 1 - rowIdx)
: undefined;

return (
<SummaryRow
aria-rowindex={ariaRowCount - bottomSummaryRowsCount + rowIdx + 1}
key={rowIdx}
rowIdx={summaryRowIdx}
gridRowStart={gridRowStart}
row={row}
top={top}
bottom={bottom}
iterateOverViewportColumnsForRow={iterateOverViewportColumnsForRow}
activeCellIdx={isSummaryRowActive ? activePosition.idx : undefined}
isTop={false}
setActivePosition={setPositionLatest}
isTreeGrid={isTreeGrid}
/>
);
return renderSummaryRow(rowIdx, {
'aria-rowindex': ariaRowCount - bottomSummaryRowsCount + rowIdx + 1,
rowIdx: summaryRowIdx,
gridRowStart,
row,
top,
bottom,
iterateOverViewportColumnsForRow,
activeCellIdx: isSummaryRowActive ? activePosition.idx : undefined,
isTop: false,
setActivePosition: setPositionLatest
});
})}
</>
)}
Expand Down
6 changes: 1 addition & 5 deletions src/GroupRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { BaseRenderRowProps, GroupRow, Omit } from './types';
import { SELECT_COLUMN_KEY } from './Columns';
import GroupCell from './GroupCell';
import { cell, cellFrozen } from './style/cell';
import { rowClassname, rowActiveClassname } from './style/row';
import { rowClassname } from './style/row';

const groupRow = css`
@layer rdg.GroupedRow {
Expand Down Expand Up @@ -46,8 +46,6 @@ function GroupedRow<R, SR>({
toggleGroup,
...props
}: GroupRowRendererProps<R, SR>) {
const isPositionOnRow = activeCellIdx === -1;

let idx = row.level;

function handleSelectGroup() {
Expand All @@ -67,12 +65,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 && rowActiveClassname,
className
)}
onMouseDown={handleSelectGroup}
Expand Down
8 changes: 1 addition & 7 deletions src/HeaderRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import type {
import type { DataGridProps } from './DataGrid';
import HeaderCell from './HeaderCell';
import { cell, cellFrozen } from './style/cell';
import { rowActiveClassname } from './style/row';

type SharedDataGridProps<R, SR, K extends React.Key> = Pick<
DataGridProps<R, SR, K>,
Expand Down Expand Up @@ -67,7 +66,6 @@ function HeaderRow<R, SR, K extends React.Key>({
direction
}: HeaderRowProps<R, SR, K>) {
const [draggedColumnKey, setDraggedColumnKey] = useState<string>();
const isPositionOnRow = activeCellIdx === -1;

const cells = iterateOverViewportColumnsForRow(activeCellIdx, { type: 'HEADER' })
.map(([column, isCellActive, colSpan], index) => (
Expand Down Expand Up @@ -95,11 +93,7 @@ function HeaderRow<R, SR, K extends React.Key>({
<div
role="row"
aria-rowindex={rowIdx} // aria-rowindex is 1 based
className={classnames(
headerRowClassname,
isPositionOnRow && rowActiveClassname,
headerRowClass
)}
className={classnames(headerRowClassname, headerRowClass)}
>
{cells}
</div>
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, type RowSelectionContextValue } from './hooks';
import { classnames } from './utils';
import type { RenderRowProps } from './types';
import { useDefaultRenderers } from './DataGridDefaultRenderersContext';
import { rowClassname, rowActiveClassname } from './style/row';
import { rowClassname } from './style/row';

function Row<R, SR>({
className,
Expand All @@ -17,7 +17,6 @@ function Row<R, SR>({
row,
iterateOverViewportColumnsForRow,
activeCellEditor,
isTreeGrid,
onCellMouseDown,
onCellClick,
onCellDoubleClick,
Expand All @@ -30,12 +29,9 @@ function Row<R, SR>({
}: RenderRowProps<R, SR>) {
const renderCell = useDefaultRenderers<R, SR>()!.renderCell!;

const isPositionOnRow = activeCellIdx === -1;

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

import { classnames } from './utils';
import type { RenderRowProps } from './types';
import {
bottomSummaryRowClassname,
rowClassname,
rowActiveClassname,
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>,
| 'iterateOverViewportColumnsForRow'
| 'rowIdx'
| 'gridRowStart'
| 'setActivePosition'
| 'activeCellIdx'
| 'isTreeGrid'
>;

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

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

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

}: RenderSummaryRowProps<R, SR>) {
const cells = iterateOverViewportColumnsForRow(activeCellIdx, { type: 'SUMMARY', row })
.map(([column, isCellActive, colSpan]) => (
<SummaryCell<R, SR>
Expand All @@ -71,13 +47,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 && rowActiveClassname
className
)}
style={{
gridRowStart,
Expand All @@ -90,4 +66,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, rowActiveClassname } from './style/row';
import SummaryRowComponent from './SummaryRow';
Copy link
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 @@ -379,18 +382,24 @@ export function TreeDataGrid<R, SR = unknown, K extends Key = Key>({
onRowChange,
draggedOverCellIdx,
activeCellEditor,
className,
isRowSelectionDisabled,
isTreeGrid,
...rowProps
}: RenderRowProps<R, SR>
) {
const isPositionOnRow = rowProps.activeCellIdx === -1;
const tabIndex = isPositionOnRow ? 0 : -1;
className = classnames(className, rowFocusable, isPositionOnRow && rowActiveClassname);

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 @@ -411,15 +420,16 @@ export function TreeDataGrid<R, SR = unknown, K extends Key = Key>({
'aria-rowindex': ariaRowIndex,
row,
rowClass,
className,
tabIndex,
onCellMouseDown,
onCellClick,
onCellDoubleClick,
onCellContextMenu,
onRowChange,
draggedOverCellIdx,
activeCellEditor,
isRowSelectionDisabled,
isTreeGrid
isRowSelectionDisabled
});
}

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

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

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

function isReadonlyArray(arr: unknown): arr is readonly unknown[] {
return Array.isArray(arr);
}
Loading
Loading