1
- import React , { useCallback , useMemo , useState } from "react"
1
+ import React , { useCallback , useMemo , useState , useRef } from "react"
2
2
import styled from "styled-components"
3
+ import { useVirtualizer } from "@tanstack/react-virtual"
3
4
import Flex from "src/components/templates/flex"
4
5
import Search from "src/components/search"
5
6
import { Box } from "src/index"
@@ -20,9 +21,11 @@ const Dropdown = ({
20
21
value,
21
22
hasSearch,
22
23
searchMargin = [ 4 ] ,
24
+ gap = 0 ,
23
25
...rest
24
26
} ) => {
25
27
const [ searchParams , setSearchParams ] = useState ( "" )
28
+
26
29
const filteredItems = useMemo ( ( ) => {
27
30
if ( ! searchParams ) return items
28
31
const searchLowerCase = searchParams . toLowerCase ( )
@@ -32,12 +35,26 @@ const Dropdown = ({
32
35
return false
33
36
} )
34
37
} , [ items , searchParams ] )
38
+
35
39
const handleSearch = useCallback (
36
40
event => {
37
41
setSearchParams ( event . target . value )
38
42
} ,
39
43
[ setSearchParams ]
40
44
)
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
+
41
58
return (
42
59
< Container
43
60
as = "ul"
@@ -61,7 +78,47 @@ const Dropdown = ({
61
78
/>
62
79
</ Box >
63
80
) }
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 >
65
122
</ Container >
66
123
)
67
124
}
0 commit comments