Sticky Cells
Module Extensions
Section titled “Module Extensions”ColumnRegular (Extended from @revolist/revogrid)
Section titled “ColumnRegular (Extended from @revolist/revogrid)”interface ColumnRegular { /** * Defines whether a cell participates in StickyCellsPlugin row discovery. * * Use this for sticky behavior and keep `cellProperties` focused on cell * styling, attributes, and event props. */ stickyCell?: StickyCellPredicate}AdditionalData (Extended from @revolist/revogrid)
Section titled “AdditionalData (Extended from @revolist/revogrid)”interface AdditionalData { /** * Sticky cells plugin configuration. * * ```ts * grid.additionalData = { * stickyCells: { maxRows: 2 }, * }; * ``` */ stickyCells?: StickyCellsConfig}Plugin API
Section titled “Plugin API”StickyCellsConfig
Section titled “StickyCellsConfig”interface StickyCellsConfig { /** * Maximum amount of active sticky rows appended to `pinnedTopSource`. * * The nearest sticky row is appended last, so it renders closest to the * scrollable body after any user-defined pinned top rows. * * @default 1 */ maxRows?: number; /** * Makes plugin-managed sticky pinned rows readonly. * * This only affects the cloned rows rendered in `rowPinStart`; original source * rows and user-provided pinned top rows keep their normal readonly behavior. * * @default true */ readonlyPinnedRows?: boolean}StickyCellPredicate
Section titled “StickyCellPredicate”export type StickyCellPredicate = boolean | ((params: CellTemplateProp) => boolean);StickyCellsPlugin
Section titled “StickyCellsPlugin”The StickyCellsPlugin keeps marked rows visible by appending the active
sticky rows to RevoGrid’s pinned top row source.
Sticky cells are configured through a column stickyCell predicate. If any
visible cell in a row resolves stickyCell to true, that row can become an
active sticky row. The row is cloned into rowPinStart once it starts
crossing above the visible row viewport.
Key Features:
- Uses a dedicated column
stickyCellpredicate; no separate sticky row data source is required. - Supports one or more active sticky rows pinned at the top of the scrolling row viewport.
- Activates only after the bottom edge of the source row crosses above the visible viewport.
- Preserves user-defined
pinnedTopSourcerows and removes only plugin-managed sticky rows. - Reuses normal pinned row rendering, including
cellTemplateandbeforecellrenderintegrations.
Behavior:
- The last
stickyCells.maxRowssticky rows at or above the scroll position stay active. - User pinned top rows render first; plugin-managed sticky rows are appended after them.
Example
Section titled “Example”import { StickyCellsPlugin } from '@revolist/revogrid-pro';
const stickyCell = ({ model }) => model.isCheckpoint === true;
const grid = document.createElement('revo-grid');grid.plugins = [StickyCellsPlugin];grid.columns = [ { name: 'Account', prop: 'account', stickyCell, }, { name: 'Status', prop: 'status', stickyCell, },];class StickyCellsPlugin {}resolveActiveStickyRows
Section titled “resolveActiveStickyRows”export function resolveActiveStickyRows( rowIndex: number, context: ActiveStickyRowsContext,): number[];resolveBottomStableTreeRows
Section titled “resolveBottomStableTreeRows”export function resolveBottomStableTreeRows( rowIndex: number, rowCount: number, context: ActiveStickyRowsContext,): number[];findIndexedStickyRowsAtOrBefore
Section titled “findIndexedStickyRowsAtOrBefore”export function findIndexedStickyRowsAtOrBefore( indexedStickyRows: number[], rowIndex: number, maxRows: number,): number[];filterVisibleBottomRows
Section titled “filterVisibleBottomRows”export function filterVisibleBottomRows( rowIndexes: number[], providers: PluginProviders, isAtBottom: () => boolean = () => isScrolledToBottom(providers),): number[];filterVisibleRows
Section titled “filterVisibleRows”export function filterVisibleRows( rowIndexes: number[], providers: PluginProviders,): number[];isScrolledToBottom
Section titled “isScrolledToBottom”export function isScrolledToBottom(providers: PluginProviders): boolean;isSameRowIndexes
Section titled “isSameRowIndexes”export function isSameRowIndexes(a: number[], b: number[]): boolean;ActiveStickyRowsContext
Section titled “ActiveStickyRowsContext”interface ActiveStickyRowsContext { maxRows: number; providers: PluginProviders; revogrid: HTMLRevoGridElement; indexedStickyRows: number[]; includeTreeRow?: boolean; isAtBottom(): boolean; resolveStickyColumns(rowIndex: number): boolean}normalizeStickyCellsConfig
Section titled “normalizeStickyCellsConfig”export function normalizeStickyCellsConfig( config: StickyCellsConfig | undefined,): Required<StickyCellsConfig>;STICKY_GRID_CLASS
Section titled “STICKY_GRID_CLASS”STICKY_GRID_CLASS: string;STICKY_ACTIVE_CLASS
Section titled “STICKY_ACTIVE_CLASS”STICKY_ACTIVE_CLASS: string;STICKY_PIN_ANIMATING_CLASS
Section titled “STICKY_PIN_ANIMATING_CLASS”STICKY_PIN_ANIMATING_CLASS: string;STICKY_PIN_ANIMATION_MS
Section titled “STICKY_PIN_ANIMATION_MS”STICKY_PIN_ANIMATION_MS: 180;STICKY_INDEX_SLICE_MS
Section titled “STICKY_INDEX_SLICE_MS”STICKY_INDEX_SLICE_MS: 4;STICKY_INDEX_SLICE_ROWS
Section titled “STICKY_INDEX_SLICE_ROWS”STICKY_INDEX_SLICE_ROWS: 2500;DEFAULT_MAX_STICKY_ROWS
Section titled “DEFAULT_MAX_STICKY_ROWS”DEFAULT_MAX_STICKY_ROWS: 1;StickyRowsIndexer
Section titled “StickyRowsIndexer”class StickyRowsIndexer { reset();
cancel();
schedule(rowIndex: number, callback: () => void);
indexSlice():;
add(rowIndex: number);}createPinnedStickyRow
Section titled “createPinnedStickyRow”export function createPinnedStickyRow( rowStore: RowStore, rowIndex: number,): StickyPinnedRow | null;stripPluginPinnedRows
Section titled “stripPluginPinnedRows”export function stripPluginPinnedRows(source: DataType[]): DataType[];isPluginPinnedRow
Section titled “isPluginPinnedRow”export function isPluginPinnedRow(row: DataType): row is StickyPinnedRow;isSamePinnedTopSource
Section titled “isSamePinnedTopSource”export function isSamePinnedTopSource(current: DataType[], next: DataType[]): boolean;StickyPinnedRow (Extended from sticky-cells.pinned.ts)
Section titled “StickyPinnedRow (Extended from sticky-cells.pinned.ts)”export type StickyPinnedRow = DataType & { [STICKY_PINNED_ROW_SOURCE_INDEX]?: number;};isStickyCell
Section titled “isStickyCell”export function isStickyCell(model: CellTemplateProp): boolean;StickyRowCache
Section titled “StickyRowCache”export type StickyRowCache = Map<DimensionCols, Set<number>>;StickyCellResolver
Section titled “StickyCellResolver”class StickyCellResolver { clear();
resolveStickyColumns(rowIndex: number): StickyRowCache | null;
rememberStickyCell(rowIndex: number, colType: DimensionCols, columnIndex: number);}captureVerticalScrollAnchor
Section titled “captureVerticalScrollAnchor”Captures the main vertical scroll state before Sticky Cells mutates
rowPinStart.
The returned callback must run after the pinned source update. It restores the user’s visual scroll anchor once RevoGrid has had a chance to lay out the new pinned top height.
export function captureVerticalScrollAnchor( revogrid: HTMLRevoGridElement, options: ScrollAnchorOptions =;resolveStickyCellPredicate
Section titled “resolveStickyCellPredicate”export function resolveStickyCellPredicate( stickyCell: StickyCellPredicate | undefined, model: CellTemplateProp,): boolean;