Skip to content
This repository was archived by the owner on Dec 16, 2022. It is now read-only.

Commit 18efba3

Browse files
authored
[WINDOW]: enabled pinned rows top and bottom for the grid. (#171)
1 parent b93fc87 commit 18efba3

5 files changed

Lines changed: 105 additions & 21 deletions

File tree

.changeset/loud-cars-happen.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@resembli/react-virtualized-window": patch
3+
---
4+
5+
Added support for pinned rows top and bottom

packages/react-virtualized-window/src/ScrollDiv.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,18 @@ import type { PropsWithChildren } from "react"
33

44
interface ScrollDivProps {
55
disableSticky?: boolean
6+
style?: React.CSSProperties
67
leftOffset: number
78
topOffset: number
9+
top: number
810
}
911

1012
export function ScrollDiv({
1113
disableSticky,
14+
style,
1215
leftOffset,
1316
topOffset,
17+
top,
1418
children,
1519
}: PropsWithChildren<ScrollDivProps>) {
1620
return (
@@ -20,8 +24,9 @@ export function ScrollDiv({
2024
transform: `translate3d(${disableSticky ? 0 : -leftOffset}px, ${
2125
disableSticky ? 0 : -topOffset
2226
}px, 0px)`,
23-
top: 0,
27+
top,
2428
willChange: "transform",
29+
...style,
2530
}}
2631
>
2732
{children}

packages/react-virtualized-window/src/components/Grid.tsx

Lines changed: 89 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ export function Grid<T>({
3535
height: sizingHeight,
3636

3737
onScroll: userOnScroll,
38+
39+
pinnedTopCount = 0,
40+
pinnedBottomCount = 0,
3841
}: GridProps<T>) {
3942
const windowRef = React.useRef<HTMLDivElement>(null)
4043
useWindowApi(windowRef, apiRef)
@@ -46,6 +49,14 @@ export function Grid<T>({
4649
userOnScroll,
4750
})
4851

52+
const [topData, botData, scrollData] = React.useMemo(() => {
53+
return [
54+
data.slice(0, pinnedTopCount),
55+
data.slice(pinnedTopCount, pinnedTopCount + pinnedBottomCount),
56+
data.slice(pinnedTopCount + pinnedBottomCount),
57+
]
58+
}, [data, pinnedBottomCount, pinnedTopCount])
59+
4960
const [adjustedWidth, adjustedHeight] = useScrollAdjustWindowDims({
5061
height,
5162
width,
@@ -58,19 +69,33 @@ export function Grid<T>({
5869
})
5970

6071
const [dataHeights, innerHeight] = useDataDimension({
61-
count: data.length,
72+
count: scrollData.length,
6273
defaultDimension: defaultRowHeight,
6374
windowDim: adjustedHeight,
6475
dimensions: rowHeights,
6576
})
6677

6778
const [dataWidths, innerWidth] = useDataDimension({
68-
count: data[0]?.length ?? 0,
79+
count: scrollData[0]?.length ?? 0,
6980
defaultDimension: defaultColumnWidth,
7081
windowDim: adjustedWidth,
7182
dimensions: columnWidths,
7283
})
7384

85+
const [topHeights, totalTopHeight] = useDataDimension({
86+
count: topData.length,
87+
defaultDimension: defaultRowHeight,
88+
windowDim: adjustedHeight,
89+
dimensions: rowHeights,
90+
})
91+
92+
const [botHeights, totalBotHeight] = useDataDimension({
93+
count: botData.length,
94+
defaultDimension: defaultRowHeight,
95+
windowDim: adjustedHeight,
96+
dimensions: rowHeights,
97+
})
98+
7499
const [vertStart, vertEnd, runningHeight] = useIndicesForDimensions({
75100
itemDimensions: dataHeights,
76101
offset: topOffset,
@@ -87,7 +112,7 @@ export function Grid<T>({
87112

88113
const scrollableItems = useScrollItems({
89114
children,
90-
data,
115+
data: scrollData,
91116
dataHeights,
92117
dataWidths,
93118
getKey,
@@ -99,6 +124,34 @@ export function Grid<T>({
99124
vertStart,
100125
})
101126

127+
const topItems = useScrollItems({
128+
children,
129+
data: topData,
130+
dataHeights: topHeights,
131+
dataWidths,
132+
getKey,
133+
horiStart,
134+
horiEnd,
135+
runningHeight: 0,
136+
runningWidth,
137+
vertStart: 0,
138+
vertEnd: topData.length,
139+
})
140+
141+
const botItems = useScrollItems({
142+
children,
143+
data: botData,
144+
dataHeights: botHeights,
145+
dataWidths,
146+
getKey,
147+
horiStart,
148+
horiEnd,
149+
runningHeight: 0,
150+
runningWidth,
151+
vertStart: 0,
152+
vertEnd: topData.length,
153+
})
154+
102155
return (
103156
<SizingDiv
104157
width={sizingWidth}
@@ -122,17 +175,48 @@ export function Grid<T>({
122175
<div
123176
style={{
124177
width: innerWidth,
125-
height: innerHeight,
178+
height: innerHeight + totalTopHeight + totalBotHeight,
126179
}}
127180
>
128181
<StickyDiv
129182
disabled={disableSticky ?? false}
130183
height={adjustedHeight}
131184
width={adjustedWidth}
132185
>
133-
<ScrollDiv disableSticky={disableSticky} topOffset={topOffset} leftOffset={leftOffset}>
186+
<ScrollDiv
187+
disableSticky={disableSticky}
188+
topOffset={topOffset}
189+
leftOffset={leftOffset}
190+
top={totalTopHeight}
191+
>
134192
{scrollableItems}
135193
</ScrollDiv>
194+
<div
195+
style={{
196+
position: "sticky",
197+
top: 0,
198+
left: 0,
199+
}}
200+
>
201+
<ScrollDiv
202+
top={0}
203+
topOffset={0}
204+
leftOffset={leftOffset}
205+
disableSticky={disableSticky}
206+
>
207+
{topItems}
208+
</ScrollDiv>
209+
</div>
210+
<div style={{ position: "sticky", top: adjustedHeight - totalBotHeight, left: 0 }}>
211+
<ScrollDiv
212+
top={0}
213+
leftOffset={leftOffset}
214+
topOffset={0}
215+
disableSticky={disableSticky}
216+
>
217+
{botItems}
218+
</ScrollDiv>
219+
</div>
136220
</StickyDiv>
137221
</div>
138222
</div>

packages/react-virtualized-window/src/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ export interface VirtualWindowBaseProps<T> {
1717
width?: React.CSSProperties["width"]
1818
height?: React.CSSProperties["height"]
1919

20+
pinnedTopCount?: number
21+
pinnedBottomCount?: number
22+
2023
"data-testid"?: string
2124
}
2225

playgrounds/src/App.tsx

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,6 @@ const data = Array.from({ length: 1000 }, (_, row) => {
3737
})
3838
})
3939

40-
const pinnedLeft = [
41-
Array.from({ length: 1000 }, (_, row) => [row, -1]),
42-
Array.from({ length: 1000 }, (_, row) => [row, -2]),
43-
Array.from({ length: 1000 }, (_, row) => [row, -3]),
44-
]
45-
46-
const pinnedRight = [
47-
Array.from({ length: 1000 }, (_, row) => [row, "R1"]),
48-
Array.from({ length: 1000 }, (_, row) => [row, "R2"]),
49-
Array.from({ length: 1000 }, (_, row) => [row, "R2"]),
50-
]
51-
5240
function App() {
5341
const [disableSticky, setStickyDisabled] = useState(false)
5442

@@ -71,9 +59,8 @@ function App() {
7159
width="70%"
7260
height="70%"
7361
disableSticky={disableSticky}
74-
pinnedRight={pinnedRight}
75-
pinnedLeft={pinnedLeft}
76-
gap={20}
62+
pinnedTopCount={2}
63+
pinnedBottomCount={2}
7764
>
7865
{({ data, style, cellMeta }) => (
7966
<div

0 commit comments

Comments
 (0)