Skip to content

Commit c4fdbd0

Browse files
committed
Add menu virtualization.
1 parent 11c4319 commit c4fdbd0

File tree

7 files changed

+79
-19
lines changed

7 files changed

+79
-19
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
"@prismicio/client": "5.1.1",
3838
"@styled-system/css": "^5.1.5",
3939
"@tanstack/react-table": "^8.5.11",
40-
"@tanstack/react-virtual": "^3.0.0-beta.23",
40+
"@tanstack/react-virtual": "3.0.0-beta.29",
4141
"axios": "^0.27.2",
4242
"polished": "^4.2.2",
4343
"ramda": "^0.28.0",

src/components/drops/menu/dropdown.js

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import React, { useCallback, useMemo, useState } from "react"
1+
import React, { useCallback, useMemo, useState, useRef } from "react"
22
import styled from "styled-components"
3+
import { useVirtualizer } from "@tanstack/react-virtual"
34
import Flex from "src/components/templates/flex"
45
import Search from "src/components/search"
56
import { Box } from "src/index"
@@ -20,9 +21,11 @@ const Dropdown = ({
2021
value,
2122
hasSearch,
2223
searchMargin = [4],
24+
gap = 0,
2325
...rest
2426
}) => {
2527
const [searchParams, setSearchParams] = useState("")
28+
2629
const filteredItems = useMemo(() => {
2730
if (!searchParams) return items
2831
const searchLowerCase = searchParams.toLowerCase()
@@ -32,12 +35,26 @@ const Dropdown = ({
3235
return false
3336
})
3437
}, [items, searchParams])
38+
3539
const handleSearch = useCallback(
3640
event => {
3741
setSearchParams(event.target.value)
3842
},
3943
[setSearchParams]
4044
)
45+
46+
const ref = useRef()
47+
const measuresRef = useRef({})
48+
49+
const rowVirtualizer = useVirtualizer({
50+
count: filteredItems.length,
51+
getScrollElement: () => ref.current,
52+
scrollOffsetFn: event => (event ? event.target.scrollTop - ref.current.offsetTop : 0),
53+
overscan: 3,
54+
enableSmoothScroll: false,
55+
estimateSize: () => 30,
56+
})
57+
4158
return (
4259
<Container
4360
as="ul"
@@ -61,7 +78,47 @@ const Dropdown = ({
6178
/>
6279
</Box>
6380
)}
64-
{filteredItems.map(item => renderItem({ item, itemProps, value, onItemClick }))}
81+
<div
82+
ref={ref}
83+
style={{
84+
minHeight: "100%",
85+
width: "100%",
86+
overflow: "auto",
87+
}}
88+
>
89+
<div
90+
style={{
91+
minHeight: `${rowVirtualizer.getTotalSize()}px`,
92+
width: "100%",
93+
position: "relative",
94+
}}
95+
>
96+
{rowVirtualizer.getVirtualItems().map(virtualRow => (
97+
<div
98+
key={virtualRow.key}
99+
data-index={virtualRow.index}
100+
ref={rowVirtualizer.measureElement}
101+
style={{
102+
position: "absolute",
103+
top: 0,
104+
left: 0,
105+
width: "100%",
106+
transform: `translateY(${virtualRow.start}px)`,
107+
padding: gap * 2,
108+
overflow: "hidden",
109+
}}
110+
>
111+
{renderItem({
112+
item: filteredItems[virtualRow.index],
113+
index: virtualRow.index,
114+
itemProps,
115+
value,
116+
onItemClick,
117+
})}
118+
</div>
119+
))}
120+
</div>
121+
</div>
65122
</Container>
66123
)
67124
}

src/components/drops/menu/dropdownItem.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from "react"
1+
import React, { useLayoutEffect, useRef } from "react"
22
import styled from "styled-components"
33
import { getColor } from "src/theme"
44
import Flex from "src/components/templates/flex"
@@ -23,6 +23,9 @@ const DropdownItem = ({
2323
item: { value, label, icon, reverse, disabled, onClick, ...restItem },
2424
value: selectedValue,
2525
onItemClick,
26+
index,
27+
measureElement,
28+
style,
2629
...rest
2730
}) => {
2831
const selected = selectedValue === value
@@ -34,11 +37,14 @@ const DropdownItem = ({
3437

3538
return (
3639
<ItemContainer
40+
ref={measureElement}
41+
data-index={index}
3742
aria-selected={selected}
3843
disabled={disabled || selected}
3944
onClick={onSelect}
4045
{...restItem}
4146
{...rest}
47+
style={style}
4248
>
4349
{reverse && <Text>{label}</Text>}
4450
{icon}

src/components/drops/menu/index.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@ import DropdownItem from "./dropdownItem"
1010

1111
const defaultRenderDropdown = props => <Dropdown {...props} />
1212

13-
const defaultRenderItem = props => {
14-
const key = props.item.value || props.item.label
15-
return <DropdownItem key={key} {...props} />
16-
}
13+
const defaultRenderItem = props => <DropdownItem {...props} />
1714

1815
const Menu = forwardRef(
1916
(

src/components/tableV2/core/rows.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const Rows = ({
2828
count: rows.length,
2929
getScrollElement: () => scrollParentRef.current,
3030
estimateSize: () => CELL_HEIGHT,
31-
overscan: overscan || 30,
31+
overscan: overscan || 5,
3232
})
3333

3434
const virtualRows = virtualizer.getVirtualItems()

src/components/tabs/styled.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export const StyledTabs = styled(Flex).attrs(props => ({
1515
justifyContent: "start",
1616
alignItems: "center",
1717
padding: [0, 0.5],
18-
flex: true,
18+
flex: false,
1919
...props,
2020
}))`
2121
border-bottom: 1px solid

yarn.lock

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3203,22 +3203,22 @@
32033203
dependencies:
32043204
"@tanstack/table-core" "8.5.11"
32053205

3206-
"@tanstack/react-virtual@^3.0.0-beta.23":
3207-
version "3.0.0-beta.23"
3208-
resolved "https://registry.yarnpkg.com/@tanstack/react-virtual/-/react-virtual-3.0.0-beta.23.tgz#f3d3e049d6b49e2b91c46ec3d35f48d9fdf7426a"
3209-
integrity sha512-FurqZJD7oSXLtL5NP0YQKXNEY+2qczXjzxmxkD51ZO8ykyr2z62IRNfvpOyly2CPLg+M346mA/Ul2hlx4R3KPw==
3206+
"@tanstack/[email protected].29":
3207+
version "3.0.0-beta.29"
3208+
resolved "https://registry.yarnpkg.com/@tanstack/react-virtual/-/react-virtual-3.0.0-beta.29.tgz#fce26a2f9d081dada2e33d6e4b23509feb1ba679"
3209+
integrity sha512-Vwjh/h9J4W6qtlQ7nPmhT6bXueS4mDMXJxJM2lRU6KPGwlWezKp/3NI4ZLAgDqZIxDOkeXq9iERsNxyB7MKHNg==
32103210
dependencies:
3211-
"@tanstack/virtual-core" "3.0.0-beta.23"
3211+
"@tanstack/virtual-core" "3.0.0-beta.29"
32123212

32133213
"@tanstack/[email protected]":
32143214
version "8.5.11"
32153215
resolved "https://registry.yarnpkg.com/@tanstack/table-core/-/table-core-8.5.11.tgz#a23178a097df4b0b64bdfa6f79e6d8933e97c7f7"
32163216
integrity sha512-ZN61ockLaIAiiPbZfMKT2S03nbWx28OHg/nAiDnNfmN4QmAMcdwVajPn2QQwnNVGAr4jS4nbhbYzCcjq8livXQ==
32173217

3218-
"@tanstack/[email protected].23":
3219-
version "3.0.0-beta.23"
3220-
resolved "https://registry.yarnpkg.com/@tanstack/virtual-core/-/virtual-core-3.0.0-beta.23.tgz#2e586256bdb239e35c8d1ca4e8d66c1c55151419"
3221-
integrity sha512-xQfJgz4mdaxifPjOqUBYAar60UAQTrED2SpS0VI5AZvxYI4NDTxx5cFrjaP4baKY3UnVc8IsGFbqr8Q/LZNMag==
3218+
"@tanstack/[email protected].29":
3219+
version "3.0.0-beta.29"
3220+
resolved "https://registry.yarnpkg.com/@tanstack/virtual-core/-/virtual-core-3.0.0-beta.29.tgz#bfb9399d6570f720a5e4967c7e57f295183a8981"
3221+
integrity sha512-fMAX6g2apCdNIWCB5lHo9qxFCn5Qig9rSrplofWfONfuIrnzLGH7H0Y7gUg37KC55BfPhwprjuZXg4B5bMI2fg==
32223222

32233223
"@testing-library/dom@^8.3.0", "@testing-library/dom@^8.5.0":
32243224
version "8.16.0"

0 commit comments

Comments
 (0)