11import * as React from "react"
22
3+ import { PinnedColumn } from "../PinnedColumn"
34import { SizingDiv } from "../SizingDiv"
45import { StickyDiv } from "../StickyDiv"
56import { getHorizontalGap , getVerticalGap } from "../itemGapUtilities"
6- import type { NumberOrPercent , VirtualWindowBaseProps } from "../types"
7+ import type { GridProps } from "../types"
78import { useDataDimension } from "../useDataDimension"
89import { useIndicesForDimensions } from "../useDimensionIndices"
910import { useScrollAdjustWindowDims } from "../useScrollAdjustedDim"
11+ import { useScrollItems } from "../useScrollItems"
1012import { useSmartSticky } from "../useSmartSticky"
1113import { useWindowApi } from "../useWindowApi"
1214import { useWindowDimensions } from "../useWindowDimensions"
1315import { useWindowScroll } from "../useWindowScroll"
1416
15- export interface CellMeta {
16- column : number
17- row : number
18- }
19-
20- export interface GridProps < T > extends VirtualWindowBaseProps < T > {
21- data : T [ ] [ ]
22- children : < B extends T > ( props : {
23- data : B
24- style : React . CSSProperties
25- cellMeta : CellMeta
26- } ) => JSX . Element
27- defaultRowHeight : NumberOrPercent
28- rowHeights ?: NumberOrPercent [ ]
29- defaultColumnWidth : NumberOrPercent
30- columnWidths ?: NumberOrPercent [ ]
31- }
32-
33- export type RenderItem < T > = GridProps < T > [ "children" ]
34-
3517export function Grid < T > ( {
3618 data,
3719 children,
@@ -57,6 +39,9 @@ export function Grid<T>({
5739 height : sizingHeight ,
5840
5941 onScroll : userOnScroll ,
42+
43+ pinnedLeft,
44+ leftWidths,
6045} : GridProps < T > ) {
6146 const windowRef = React . useRef < HTMLDivElement > ( null )
6247 const transRef = React . useRef < HTMLDivElement > ( null )
@@ -120,70 +105,30 @@ export function Grid<T>({
120105 overscan : overscan ?? 0 ,
121106 } )
122107
123- const scrollableItems = React . useMemo (
124- function Items ( ) {
125- return (
126- < >
127- < div style = { { height : runningHeight } } > </ div >
128- { data . slice ( vertStart , vertEnd ) . map ( ( row , i ) => {
129- const rowKey = i + vertStart
130- const itemHeight = dataHeights [ vertStart + i ]
131-
132- const rowChildren = row . slice ( horiStart , horiEnd ) . map ( ( cell , j ) => {
133- const cellKey = getKey ?.( cell ) ?? horiStart + j
134- const itemWidth = dataWidths [ horiStart + j ]
135-
136- return (
137- < RenderItem
138- key = { cellKey }
139- itemWidth = { itemWidth }
140- Component = { children }
141- marginLeft = { rtl || j + horiStart === 0 ? 0 : horizontalGap }
142- marginRight = { ! rtl || j + horiStart === 0 ? 0 : horizontalGap }
143- itemProps = { cell }
144- column = { horiStart + j }
145- row = { vertStart + i }
146- />
147- )
148- } )
108+ const [ lWidths , leftTotalWidth ] = useDataDimension ( {
109+ count : pinnedLeft ?. length ?? 0 ,
110+ defaultDimension : defaultColumnWidth ,
111+ windowDim : adjustedWidth ,
112+ gap : horizontalGap ,
113+ dimensions : leftWidths ,
114+ } )
149115
150- return (
151- < div
152- key = { rowKey }
153- style = { {
154- display : "flex" ,
155- height : itemHeight ,
156- minHeight : itemHeight ,
157- maxHeight : itemHeight ,
158- marginTop : i + vertStart === 0 ? 0 : verticalGap ,
159- marginBottom : i + vertStart === data . length - 1 ? 0 : verticalGap ,
160- } }
161- >
162- < div style = { { width : runningWidth } } />
163- { rowChildren }
164- </ div >
165- )
166- } ) }
167- </ >
168- )
169- } ,
170- [
171- children ,
172- data ,
173- dataHeights ,
174- dataWidths ,
175- getKey ,
176- horiEnd ,
177- horiStart ,
178- horizontalGap ,
179- rtl ,
180- runningHeight ,
181- runningWidth ,
182- vertEnd ,
183- vertStart ,
184- verticalGap ,
185- ] ,
186- )
116+ const scrollableItems = useScrollItems ( {
117+ children,
118+ data,
119+ dataHeights,
120+ dataWidths,
121+ getKey,
122+ horiEnd,
123+ horiStart,
124+ horizontalGap,
125+ rtl,
126+ runningHeight,
127+ runningWidth,
128+ vertEnd,
129+ vertStart,
130+ verticalGap,
131+ } )
187132
188133 return (
189134 < SizingDiv
@@ -206,7 +151,7 @@ export function Grid<T>({
206151 direction : rtl ? "rtl" : "ltr" ,
207152 } }
208153 >
209- < div style = { { width : innerWidth , height : innerHeight , contain : "strict" } } >
154+ < div style = { { width : innerWidth + leftTotalWidth - horizontalGap , height : innerHeight } } >
210155 < StickyDiv
211156 disabled = { disableSticky ?? false }
212157 rtl = { rtl ?? false }
@@ -221,51 +166,34 @@ export function Grid<T>({
221166 disableSticky ? 0 : - topOffset
222167 } px, 0px)`,
223168 top : 0 ,
224- left : rtl ? undefined : 0 ,
225- right : rtl ? 0 : undefined ,
169+ left : rtl ? undefined : leftTotalWidth ,
170+ right : rtl ? leftTotalWidth : undefined ,
226171 willChange : "transform" ,
227172 } }
228173 >
229174 { scrollableItems }
230175 </ div >
176+ { pinnedLeft && (
177+ < PinnedColumn
178+ Component = { children }
179+ totalWidth = { leftTotalWidth }
180+ left = { rtl ? undefined : 0 }
181+ right = { rtl ? 0 : undefined }
182+ topOffset = { disableSticky ? 0 : - topOffset }
183+ columns = { pinnedLeft }
184+ widths = { lWidths }
185+ heights = { dataHeights }
186+ vertStart = { vertStart }
187+ vertEnd = { vertEnd }
188+ verticalGap = { verticalGap }
189+ horizontalGap = { horizontalGap }
190+ runningHeight = { runningHeight }
191+ rtl = { rtl }
192+ />
193+ ) }
231194 </ StickyDiv >
232195 </ div >
233196 </ div >
234197 </ SizingDiv >
235198 )
236199}
237-
238- type RenderItemsProps < T > = {
239- Component : GridProps < T > [ "children" ]
240- itemProps : T
241- itemWidth : number
242- column : number
243- row : number
244- marginLeft : number
245- marginRight : number
246- }
247-
248- const RenderItem = function < T > ( {
249- Component,
250- itemProps,
251- itemWidth,
252- column,
253- row,
254- marginRight,
255- marginLeft,
256- } : RenderItemsProps < T > ) {
257- const itemStyles = React . useMemo ( ( ) => {
258- return {
259- width : itemWidth ,
260- minWidth : itemWidth ,
261- maxWidth : itemWidth ,
262- height : "100%" ,
263- marginLeft,
264- marginRight,
265- }
266- } , [ itemWidth , marginLeft , marginRight ] )
267-
268- const cellMeta = React . useMemo < CellMeta > ( ( ) => ( { row, column } ) , [ column , row ] )
269-
270- return < Component data = { itemProps } style = { itemStyles } cellMeta = { cellMeta } />
271- }
0 commit comments