-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathListSelector.tsx
90 lines (86 loc) · 2.78 KB
/
ListSelector.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import * as React from 'react';
import { ReactNode, useState } from 'react';
import { ContextSelector, ContextSelectorItem } from '@patternfly/react-core';
export const ListSelector: React.FunctionComponent<
{
onSelect?: (selected: string) => void
listValues: string[]
width?: string
}> = (props) => {
const [selected, setSelected] = useState("")
const [searchValue, setSearchValue] = useState("")
const [filterValue, setFilterValue] = useState("")
const [isDropDownOpen, setIsDropDownOpen] = useState(false)
// The following code is a hacky workaround for a problem where when menuApplyTo
// is set to document.body, the ContextSelector's onSelect doesn't fire if you
// select an item quickly after first opening the dropdown. Stepping through
// the process of opening and closing the drop-down seems to establish the
// necessary conditions for onSelect to work correctly.
const [startupState, setStartupState] = useState(0)
const [startupTimer, setStartupTimer] = useState<NodeJS.Timeout|undefined>(undefined)
switch(startupState) {
case 0:
setIsDropDownOpen(true)
setStartupTimer(setTimeout(() => {setStartupState(2)}, 5))
setStartupState(1)
break
case 1:
// waiting for setTimeout to happen
break
case 2:
setIsDropDownOpen(false)
if (startupTimer) clearTimeout(startupTimer)
setStartupTimer(undefined)
setStartupState(3)
break
case 3:
// normal operation
break
}
// End of terrible hack
const onToggle = (event: Event, isDropDownOpen: boolean): void => {
setIsDropDownOpen(isDropDownOpen)
}
const onSelect = (event: Event, value: ReactNode): void => {
const newSelected = value ? value.toString() : ""
if (props.onSelect) {
props.onSelect(newSelected)
}
setSelected(newSelected)
setIsDropDownOpen(false)
}
const onSearchInputChange = (value: string): void => {
setSearchValue(value)
if (value === "") {
setFilterValue("")
}
}
const onSearchButtonClick = (): void => {
setFilterValue(searchValue)
}
return (
<ContextSelector
toggleText={selected}
onSearchInputChange={onSearchInputChange}
isOpen={isDropDownOpen}
searchInputValue={searchValue}
onToggle={onToggle}
onSelect={onSelect}
onSearchButtonClick={onSearchButtonClick}
menuAppendTo={() => { return document.body }}
>
{
(filterValue === ''
? props.listValues
: props.listValues.filter((item): boolean => {
return item.toLowerCase().indexOf(filterValue.toLowerCase()) !== -1
}))
.map((text, index) => {
return (
<ContextSelectorItem key={index}>{text}</ContextSelectorItem>
)
})
}
</ContextSelector>
)
}