Frozen Rows and Columns
Keep the first N displayed rows in place below the header, and the first N displayed columns in place at the left, while the rest of the body scrolls, like Excel's Freeze Panes. A subtle divider marks the last frozen row; frozen columns use ordinary column pinning.
Live Demo
Quick Example
import { OGrid } from '@alaarab/ogrid-react-radix';
<OGrid
columns={columns}
data={rows}
getRowId={(r) => r.id}
frozenRows={2}
frozenColumns={1}
/>;
The same props work on @alaarab/ogrid-react-fluent and on the bare DataGridTable.
Freeze commands
Set allowFreeze to add a Freeze section to the cell context menu, like Excel's View → Freeze Panes:
- Freeze panes — freezes the rows above and the columns left of the active cell (or the selection's top-left).
- Freeze top row — freezes the first row.
- Freeze first column — freezes the first column.
- Unfreeze panes — clears both.
<OGrid
columns={columns}
data={rows}
getRowId={(r) => r.id}
allowFreeze
defaultFrozenRows={2}
onFrozenRowsChange={setFrozenRows}
/>
frozenRows / frozenColumns are controlled when passed; leave them off and the grid keeps the state itself, seeded by defaultFrozenRows / defaultFrozenColumns, and reported through onFrozenRowsChange / onFrozenColumnsChange. frozenColumns pins the first N displayed columns left, so it follows column visibility and reordering.
How It Works
- The frozen rows are the first
frozenRowsdisplayed rows: they follow sorting and filtering, and with pagination they are the first rows of the current page. - Frozen cells use
position: stickybelow the header. With column pinning, cells in the intersection stick on both axes. - With virtual scrolling, frozen rows are always rendered, however far the body is scrolled.
- Keyboard navigation scrolls a row out from under the frozen rows when it becomes active.
- A merged cell never spans across the frozen boundary; it is clipped there.
Styling
The divider under the last frozen row uses --ogrid-frozen-divider (default: --ogrid-border-strong). Stacking order uses --ogrid-z-frozen (frozen cells, default 7) and --ogrid-z-frozen-pinned (frozen pinned, checkbox and row-number cells, default 9).
.my-grid {
--ogrid-frozen-divider: #217346;
}