1- import React from 'react' ;
1+ import React , { useMemo } from 'react' ;
22import { formatAggregationValue } from '../../hooks/features/useAggregation' ;
3- import type { GridColDef , GridAggregationModel , GridAggregationResult } from '../../types' ;
3+ import type { GridColDef , GridAggregationModel , GridAggregationResult , GridColumnPinning } from '../../types' ;
4+ import { calculatePinnedPositions , isColumnPinned } from '../../utils/pinning' ;
45
56interface GridAggregationFooterProps {
67 columns : GridColDef [ ] ;
@@ -11,6 +12,7 @@ interface GridAggregationFooterProps {
1112 checkboxSelection : boolean ;
1213 hasDetailPanel : boolean ;
1314 rowReordering : boolean ;
15+ pinnedColumns ?: GridColumnPinning ;
1416}
1517
1618export function GridAggregationFooter ( {
@@ -22,7 +24,28 @@ export function GridAggregationFooter({
2224 checkboxSelection,
2325 hasDetailPanel,
2426 rowReordering,
27+ pinnedColumns,
2528} : GridAggregationFooterProps ) {
29+ // Compute sticky left/right pixel offsets for each pinned column.
30+ // The footer always renders checkbox/detail/reorder spacers unconditionally,
31+ // so treat pinCheckboxColumn and pinExpandColumn as always true.
32+ const pinnedOffsets = useMemo (
33+ ( ) => calculatePinnedPositions (
34+ columns ,
35+ columnWidths ,
36+ pinnedColumns ,
37+ checkboxSelection ,
38+ true ,
39+ hasDetailPanel ,
40+ true ,
41+ rowReordering ,
42+ ) ,
43+ [ columns , columnWidths , pinnedColumns , checkboxSelection , hasDetailPanel , rowReordering ]
44+ ) ;
45+
46+ const lastLeftField = pinnedColumns ?. left ?. [ pinnedColumns . left . length - 1 ] ;
47+ const firstRightField = pinnedColumns ?. right ?. [ 0 ] ;
48+
2649 return (
2750 < div
2851 className = "ogx__aggregation-footer"
@@ -40,17 +63,32 @@ export function GridAggregationFooter({
4063 const rawValue = aggregationResult [ col . field ] ;
4164 const colWidth = columnWidths [ col . field ] ?? ( typeof col . width === 'number' ? col . width : 120 ) ;
4265
66+ const pinnedPosition = isColumnPinned ( col . field , pinnedColumns ) ;
67+ const pinnedOffset = pinnedPosition ? pinnedOffsets [ col . field ] : undefined ;
68+
69+ const className = [
70+ 'ogx__aggregation-cell' ,
71+ pinnedPosition === 'left' && 'ogx__aggregation-cell--pinned-left' ,
72+ pinnedPosition === 'right' && 'ogx__aggregation-cell--pinned-right' ,
73+ pinnedPosition === 'left' && col . field === lastLeftField && 'ogx__aggregation-cell--pinned-left-last' ,
74+ pinnedPosition === 'right' && col . field === firstRightField && 'ogx__aggregation-cell--pinned-right-first' ,
75+ ] . filter ( Boolean ) . join ( ' ' ) ;
76+
77+ const style : React . CSSProperties = {
78+ width : colWidth ,
79+ minWidth : colWidth ,
80+ maxWidth : colWidth ,
81+ textAlign : ( col . align as React . CSSProperties [ 'textAlign' ] ) || 'left' ,
82+ } ;
83+ if ( pinnedPosition === 'left' && pinnedOffset !== undefined ) style . left = pinnedOffset ;
84+ if ( pinnedPosition === 'right' && pinnedOffset !== undefined ) style . right = pinnedOffset ;
85+
4386 return (
4487 < div
4588 key = { col . field }
46- className = "ogx__aggregation-cell"
89+ className = { className }
4790 role = "gridcell"
48- style = { {
49- width : colWidth ,
50- minWidth : colWidth ,
51- maxWidth : colWidth ,
52- textAlign : ( col . align as React . CSSProperties [ 'textAlign' ] ) || 'left' ,
53- } }
91+ style = { style }
5492 >
5593 { fnName ? (
5694 < >
0 commit comments