Skip to content

Commit 2da51d7

Browse files
authored
optional search to menu dropdown (#403)
* optional search to menu dropdown * v2.5.1-dev.0 * remove mistaken code * v2.5.1
1 parent 96b754d commit 2da51d7

File tree

3 files changed

+67
-18
lines changed

3 files changed

+67
-18
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@netdata/netdata-ui",
3-
"version": "2.5.0",
3+
"version": "2.5.1",
44
"description": "netdata UI kit",
55
"main": "./lib/index.js",
66
"files": [
Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
import React from "react"
1+
import React, { useCallback, useMemo, useState } from "react"
22
import styled from "styled-components"
33
import Flex from "src/components/templates/flex"
4+
import Search from "src/components/search"
5+
import { Box } from "src/index"
46

57
const Container = styled(Flex)`
68
${({ hideShadow }) =>
@@ -9,20 +11,58 @@ const Container = styled(Flex)`
911
list-style-type: none;
1012
`
1113

12-
const Dropdown = ({ hideShadow, itemProps, items, onItemClick, renderItem, value, ...rest }) => (
13-
<Container
14-
as="ul"
15-
role="listbox"
16-
background="dropdown"
17-
hideShadow={hideShadow}
18-
padding={[0]}
19-
margin={[1, 0]}
20-
column
21-
tabindex="-1"
22-
{...rest}
23-
>
24-
{items.map(item => renderItem({ item, itemProps, value, onItemClick }))}
25-
</Container>
26-
)
14+
const Dropdown = ({
15+
hideShadow,
16+
itemProps,
17+
items,
18+
onItemClick,
19+
renderItem,
20+
value,
21+
hasSearch,
22+
...rest
23+
}) => {
24+
const [searchParams, setSearchParams] = useState("")
25+
const filteredItems = useMemo(() => {
26+
if (!searchParams) return items
27+
const searchLowerCase = searchParams.toLowerCase()
28+
return items.filter(({ label, value }) => {
29+
if (label?.toLowerCase().includes(searchLowerCase)) return true
30+
if (value?.toLowerCase().includes(searchLowerCase)) return true
31+
return false
32+
})
33+
}, [items, searchParams])
34+
const handleSearch = useCallback(
35+
event => {
36+
setSearchParams(event.target.value)
37+
},
38+
[setSearchParams]
39+
)
40+
return (
41+
<Container
42+
as="ul"
43+
role="listbox"
44+
background="dropdown"
45+
hideShadow={hideShadow}
46+
padding={[0]}
47+
margin={[1, 0]}
48+
column
49+
tabindex="-1"
50+
{...rest}
51+
>
52+
{hasSearch && (
53+
<Box margin={[4]}>
54+
<Search
55+
data-testid={"dropdown-search"}
56+
defaultValue={searchParams}
57+
placeholder="Search"
58+
onChange={handleSearch}
59+
size="tiny"
60+
/>
61+
</Box>
62+
)}
63+
{filteredItems.map(item => renderItem({ item, itemProps, value, onItemClick }))}
64+
</Container>
65+
)
66+
}
2767

2868
export default Dropdown

src/components/drops/menu/index.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ const Menu = forwardRef(
3535
renderItem = defaultRenderItem,
3636
renderDropdown = defaultRenderDropdown,
3737
animation,
38+
hasSearch = false,
3839
...rest
3940
},
4041
parentRef
@@ -99,7 +100,15 @@ const Menu = forwardRef(
99100
target={ref.current}
100101
{...dropProps}
101102
>
102-
{renderDropdown({ value, onItemClick, items, itemProps, renderItem, ...dropdownProps })}
103+
{renderDropdown({
104+
value,
105+
onItemClick,
106+
items,
107+
itemProps,
108+
renderItem,
109+
hasSearch,
110+
...dropdownProps,
111+
})}
103112
</Drop>
104113
)}
105114
</Fragment>

0 commit comments

Comments
 (0)