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
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1377,11 +1377,23 @@ const columns: readonly Column<Row>[] = [
];
```

##### `frozen?: Maybe<boolean>`
##### `frozen?: Maybe<boolean | 'start' | 'end'>`

**Default**: `false`

Determines whether column is frozen. Frozen columns are pinned to the start edge (left in LTR, right in RTL). Per-column pinning to the end edge is not supported at the moment.
Determines whether the column is frozen, and on which edge. Frozen columns stay in place when the grid is scrolled horizontally.

- `'start'` (or `true` for backwards compatibility) — pins the column to the start edge (left in LTR, right in RTL).
- `'end'` — pins the column to the end edge (right in LTR, left in RTL).
- `false` (default) — the column scrolls with the rest of the grid.

```tsx
const columns: readonly Column<Row>[] = [
{ key: 'id', name: 'ID', frozen: 'start' },
{ key: 'name', name: 'Name' },
{ key: 'actions', name: 'Actions', frozen: 'end' }
];
```

##### `resizable?: Maybe<boolean>`

Expand Down
123 changes: 79 additions & 44 deletions src/DataGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,11 @@ import { default as defaultRenderSortStatus } from './sortStatus';
import { cellDragHandleClassname, cellDragHandleFrozenClassname } from './style/cell';
import {
rootClassname,
frozenColumnShadowClassname,
viewportDraggingClassname,
frozenColumnShadowTopClassname
frozenColumnShadowEndClassname,
frozenColumnShadowEndTopClassname,
frozenColumnShadowStartClassname,
frozenColumnShadowTopClassname,
viewportDraggingClassname
} from './style/core';
import SummaryRow from './SummaryRow';

Expand Down Expand Up @@ -344,12 +346,14 @@ export function DataGrid<R, SR = unknown, K extends Key = Key>(props: DataGridPr
columns,
colSpanColumns,
lastFrozenColumnIndex,
firstEndFrozenColumnIndex,
headerRowsCount,
colOverscanStartIdx,
colOverscanEndIdx,
templateColumns,
layoutCssVars,
totalFrozenColumnWidth
totalFrozenColumnWidth,
totalEndFrozenColumnWidth
} = useCalculatedColumns({
rawColumns,
defaultColumnOptions,
Expand Down Expand Up @@ -382,6 +386,11 @@ export function DataGrid<R, SR = unknown, K extends Key = Key>(props: DataGridPr
gridColumnStart: lastFrozenColumnIndex + 2,
insetInlineStart: totalFrozenColumnWidth
};
const frozenEndShadowStyles: React.CSSProperties = {
gridColumnStart: firstEndFrozenColumnIndex + 1,
gridColumnEnd: -1,
insetInlineEnd: totalEndFrozenColumnWidth
};

const {
activePosition,
Expand Down Expand Up @@ -464,6 +473,7 @@ export function DataGrid<R, SR = unknown, K extends Key = Key>(props: DataGridPr
colOverscanStartIdx,
colOverscanEndIdx,
lastFrozenColumnIndex,
firstEndFrozenColumnIndex,
rowOverscanStartIdx,
rowOverscanEndIdx,
rows,
Expand Down Expand Up @@ -903,6 +913,7 @@ export function DataGrid<R, SR = unknown, K extends Key = Key>(props: DataGridPr
mainHeaderRowIdx,
maxRowIdx,
lastFrozenColumnIndex,
firstEndFrozenColumnIndex,
cellNavigationMode,
activePosition,
nextPosition,
Expand Down Expand Up @@ -967,6 +978,53 @@ export function DataGrid<R, SR = unknown, K extends Key = Key>(props: DataGridPr
);
}

function renderFrozenShadow(
shadowStyles: React.CSSProperties,
bodyClassname: string,
topClassname: string
) {
return (
<>
<div
className={topClassname}
style={{
...shadowStyles,
gridRowStart: 1,
gridRowEnd: headerRowsCount + 1 + topSummaryRowsCount,
insetBlockStart: 0
}}
/>

{rows.length > 0 && (
<div
className={bodyClassname}
style={{
...shadowStyles,
gridRowStart: headerAndTopSummaryRowsCount + rowOverscanStartIdx + 1,
gridRowEnd: headerAndTopSummaryRowsCount + rowOverscanEndIdx + 2
}}
/>
)}

{bottomSummaryRows != null && bottomSummaryRowsCount > 0 && (
<div
className={topClassname}
style={{
...shadowStyles,
gridRowStart: headerAndTopSummaryRowsCount + rows.length + 1,
gridRowEnd: headerAndTopSummaryRowsCount + rows.length + 1 + bottomSummaryRowsCount,
insetBlockStart:
clientHeight > totalRowHeight
? gridHeight - summaryRowHeight * bottomSummaryRowsCount
: undefined,
insetBlockEnd: clientHeight > totalRowHeight ? undefined : 0
}}
/>
)}
</>
);
}

function getCellEditor(rowIdx: number) {
if (
!activePositionIsCellInViewport ||
Expand All @@ -978,7 +1036,10 @@ export function DataGrid<R, SR = unknown, K extends Key = Key>(props: DataGridPr

const { row } = activePosition;
const column = getActiveColumn();
const colSpan = getColSpan(column, lastFrozenColumnIndex, { type: 'ROW', row });
const colSpan = getColSpan(column, lastFrozenColumnIndex, firstEndFrozenColumnIndex, {
type: 'ROW',
row
});

function closeEditor(shouldFocus: boolean) {
const newPosition: ActivePosition = { idx: activePosition.idx, rowIdx, mode: 'ACTIVE' };
Expand Down Expand Up @@ -1114,6 +1175,7 @@ export function DataGrid<R, SR = unknown, K extends Key = Key>(props: DataGridPr
...style,
// set scrollPadding to correctly scroll to non-sticky cells/rows
scrollPaddingInlineStart: totalFrozenColumnWidth,
scrollPaddingInlineEnd: totalEndFrozenColumnWidth,
scrollPaddingBlockStart: headerRowsHeight + topSummaryRowsCount * summaryRowHeight,
scrollPaddingBlockEnd: bottomSummaryRowsCount * summaryRowHeight,
gridTemplateColumns,
Expand Down Expand Up @@ -1227,46 +1289,19 @@ export function DataGrid<R, SR = unknown, K extends Key = Key>(props: DataGridPr
)}
</DataGridDefaultRenderersContext>

{lastFrozenColumnIndex > -1 && (
<>
<div
className={frozenColumnShadowTopClassname}
style={{
...frozenShadowStyles,
gridRowStart: 1,
gridRowEnd: headerRowsCount + 1 + topSummaryRowsCount,
insetBlockStart: 0
}}
/>
{lastFrozenColumnIndex > -1 &&
renderFrozenShadow(
frozenShadowStyles,
frozenColumnShadowStartClassname,
frozenColumnShadowTopClassname
)}

{rows.length > 0 && (
<div
className={frozenColumnShadowClassname}
style={{
...frozenShadowStyles,
gridRowStart: headerAndTopSummaryRowsCount + rowOverscanStartIdx + 1,
gridRowEnd: headerAndTopSummaryRowsCount + rowOverscanEndIdx + 2
}}
/>
)}

{bottomSummaryRows != null && bottomSummaryRowsCount > 0 && (
<div
className={frozenColumnShadowTopClassname}
style={{
...frozenShadowStyles,
gridRowStart: headerAndTopSummaryRowsCount + rows.length + 1,
gridRowEnd: headerAndTopSummaryRowsCount + rows.length + 1 + bottomSummaryRowsCount,
insetBlockStart:
clientHeight > totalRowHeight
? gridHeight - summaryRowHeight * bottomSummaryRowsCount
: undefined,
insetBlockEnd: clientHeight > totalRowHeight ? undefined : 0
}}
/>
)}
</>
)}
{firstEndFrozenColumnIndex > -1 &&
renderFrozenShadow(
frozenEndShadowStyles,
frozenColumnShadowEndClassname,
frozenColumnShadowEndTopClassname
)}

{getDragHandle()}

Expand Down
3 changes: 2 additions & 1 deletion src/GroupRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ const groupRow = css`
}

> .${cell}:not(:last-child, .${cellFrozen}),
> :nth-last-child(n + 2 of .${cellFrozen}) {
> :nth-last-child(n + 2 of .rdg-cell-frozen),
> :nth-child(n + 2 of .rdg-cell-frozen-end) {
border-inline-end: none;
}
}
Expand Down
Loading