playbook_ui 13.9.0 → 13.10.0.pre.alpha.PLAY978alphatesthighcharts41330
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/pb_avatar/docs/_avatar_default_swift.md +12 -0
- data/app/pb_kits/playbook/pb_avatar/docs/_avatar_monogram_swift.md +12 -0
- data/app/pb_kits/playbook/pb_avatar/docs/_avatar_props_swift.md +8 -0
- data/app/pb_kits/playbook/pb_avatar/docs/_footer.md +1 -1
- data/app/pb_kits/playbook/pb_avatar/docs/example.yml +3 -1
- data/app/pb_kits/playbook/pb_background/_background.tsx +103 -52
- data/app/pb_kits/playbook/pb_badge/docs/_badge_colors_swift.md +1 -1
- data/app/pb_kits/playbook/pb_button/_button.scss +2 -2
- data/app/pb_kits/playbook/pb_multi_level_select/_helper_functions.tsx +27 -22
- data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.scss +2 -1
- data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +258 -111
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_default.html.erb +6 -7
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_selected_ids.jsx +1 -1
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_single.html.erb +73 -0
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_single.jsx +87 -0
- data/app/pb_kits/playbook/pb_multi_level_select/docs/example.yml +3 -2
- data/app/pb_kits/playbook/pb_multi_level_select/docs/index.js +2 -1
- data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select.rb +7 -0
- data/dist/playbook-rails.js +5 -5
- data/lib/playbook/version.rb +2 -2
- metadata +12 -8
- data/app/pb_kits/playbook/pb_avatar/docs/_avatar_swift.md +0 -82
@@ -3,6 +3,7 @@ import classnames from "classnames"
|
|
3
3
|
import { globalProps, GlobalProps } from "../utilities/globalProps"
|
4
4
|
import { buildAriaProps, buildCss, buildDataProps } from "../utilities/props"
|
5
5
|
import Checkbox from "../pb_checkbox/_checkbox"
|
6
|
+
import Radio from "../pb_radio/_radio"
|
6
7
|
import Icon from "../pb_icon/_icon"
|
7
8
|
import FormPill from "../pb_form_pill/_form_pill"
|
8
9
|
import CircleIconButton from "../pb_circle_icon_button/_circle_icon_button"
|
@@ -24,11 +25,13 @@ type MultiLevelSelectProps = {
|
|
24
25
|
data?: { [key: string]: string }
|
25
26
|
id?: string
|
26
27
|
inputDisplay?: "pills" | "none"
|
28
|
+
inputName?: string
|
27
29
|
name?: string
|
28
30
|
returnAllSelected?: boolean
|
29
31
|
treeData?: { [key: string]: string }[]
|
30
32
|
onSelect?: (prop: { [key: string]: any }) => void
|
31
33
|
selectedIds?: string[]
|
34
|
+
variant?: "multi" | "single"
|
32
35
|
} & GlobalProps
|
33
36
|
|
34
37
|
const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
@@ -38,11 +41,13 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
38
41
|
data = {},
|
39
42
|
id,
|
40
43
|
inputDisplay = "pills",
|
44
|
+
inputName,
|
41
45
|
name,
|
42
46
|
returnAllSelected = false,
|
43
47
|
treeData,
|
44
|
-
onSelect = () =>
|
45
|
-
selectedIds
|
48
|
+
onSelect = () => null,
|
49
|
+
selectedIds,
|
50
|
+
variant = "multi"
|
46
51
|
} = props
|
47
52
|
|
48
53
|
const ariaProps = buildAriaProps(aria)
|
@@ -55,29 +60,61 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
55
60
|
|
56
61
|
const dropdownRef = useRef(null)
|
57
62
|
|
58
|
-
//
|
59
|
-
const [
|
60
|
-
//
|
63
|
+
// State for whether dropdown is open or closed
|
64
|
+
const [isDropdownClosed, setIsDropdownClosed] = useState(true)
|
65
|
+
// State from onChange for textinput, to use for filtering to create typeahead
|
61
66
|
const [filterItem, setFilterItem] = useState("")
|
62
|
-
//
|
63
|
-
const [returnedArray, setReturnedArray] = useState([])
|
64
|
-
//formattedData with checked and parent_id added
|
67
|
+
// FormattedData with checked and parent_id added
|
65
68
|
const [formattedData, setFormattedData] = useState([])
|
66
|
-
//
|
69
|
+
// State for the return of returnAllSelected
|
70
|
+
const [returnedArray, setReturnedArray] = useState([])
|
71
|
+
// State for default return
|
67
72
|
const [defaultReturn, setDefaultReturn] = useState([])
|
68
|
-
// Get expanded items from treeData
|
69
|
-
const initialExpandedItems = getExpandedItems(treeData, selectedIds)
|
70
|
-
// Initialize state with expanded items
|
71
|
-
const [expanded, setExpanded] = useState(initialExpandedItems)
|
72
|
-
|
73
|
+
// Get expanded items from treeData
|
74
|
+
const initialExpandedItems = getExpandedItems(treeData, selectedIds)
|
75
|
+
// Initialize state with expanded items
|
76
|
+
const [expanded, setExpanded] = useState(initialExpandedItems)
|
77
|
+
|
78
|
+
// Single Select specific state
|
79
|
+
const [singleSelectedItem, setSingleSelectedItem] = useState({
|
80
|
+
id: [],
|
81
|
+
value: "",
|
82
|
+
item: []
|
83
|
+
})
|
73
84
|
|
74
85
|
useEffect(() => {
|
75
|
-
|
86
|
+
const formattedData = addCheckedAndParentProperty(
|
87
|
+
treeData,
|
88
|
+
variant === "single" ? [selectedIds?.[0]] : selectedIds
|
89
|
+
)
|
90
|
+
|
91
|
+
setFormattedData(formattedData)
|
92
|
+
|
93
|
+
if (variant === "single") {
|
94
|
+
// No selectedIds, reset state
|
95
|
+
if (selectedIds?.length === 0 || !selectedIds?.length) {
|
96
|
+
setSingleSelectedItem({ id: [], value: "", item: []})
|
97
|
+
} else {
|
98
|
+
// If there is a selectedId but no current item, set the selectedItem
|
99
|
+
if (selectedIds?.length !== 0 && !singleSelectedItem.value) {
|
100
|
+
const selectedItem = filterFormattedDataById(formattedData, selectedIds[0])
|
101
|
+
|
102
|
+
if (!selectedItem.length) {
|
103
|
+
setSingleSelectedItem({ id: [], value: "", item: []})
|
104
|
+
} else {
|
105
|
+
const { id, value } = selectedItem[0]
|
106
|
+
setSingleSelectedItem({ id: [id], value, item: selectedItem})
|
107
|
+
}
|
108
|
+
}
|
109
|
+
}
|
110
|
+
}
|
76
111
|
}, [treeData, selectedIds])
|
77
112
|
|
78
113
|
useEffect(() => {
|
79
114
|
if (returnAllSelected) {
|
80
115
|
setReturnedArray(getCheckedItems(formattedData))
|
116
|
+
} else if (variant === "single") {
|
117
|
+
setDefaultReturn(singleSelectedItem.item)
|
81
118
|
} else {
|
82
119
|
setDefaultReturn(getDefaultCheckedItems(formattedData))
|
83
120
|
}
|
@@ -87,7 +124,7 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
87
124
|
// Function to handle clicks outside the dropdown
|
88
125
|
const handleClickOutside = (event: any) => {
|
89
126
|
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
90
|
-
|
127
|
+
setIsDropdownClosed(true)
|
91
128
|
}
|
92
129
|
}
|
93
130
|
// Attach the event listener
|
@@ -109,7 +146,7 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
109
146
|
})
|
110
147
|
}
|
111
148
|
|
112
|
-
//
|
149
|
+
// Iterate over tree, find item and set checked or unchecked
|
113
150
|
const modifyValue = (
|
114
151
|
id: string,
|
115
152
|
tree: { [key: string]: any }[],
|
@@ -122,14 +159,20 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
122
159
|
if (item.id != id) item.children = modifyValue(id, item.children, check)
|
123
160
|
else {
|
124
161
|
item.checked = check
|
125
|
-
|
162
|
+
|
163
|
+
if (variant === "single") {
|
164
|
+
// Single select: no children should be checked
|
165
|
+
item.children = modifyRecursive(item.children, !check)
|
166
|
+
} else {
|
167
|
+
item.children = modifyRecursive(item.children, check)
|
168
|
+
}
|
126
169
|
}
|
127
170
|
|
128
171
|
return item
|
129
172
|
})
|
130
173
|
}
|
131
174
|
|
132
|
-
//
|
175
|
+
// Clone tree, check items + children
|
133
176
|
const checkItem = (item: { [key: string]: any }) => {
|
134
177
|
const tree = cloneDeep(formattedData)
|
135
178
|
if (returnAllSelected) {
|
@@ -140,7 +183,7 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
140
183
|
}
|
141
184
|
}
|
142
185
|
|
143
|
-
//
|
186
|
+
// Clone tree, uncheck items + children
|
144
187
|
const unCheckItem = (item: { [key: string]: any }) => {
|
145
188
|
const tree = cloneDeep(formattedData)
|
146
189
|
if (returnAllSelected) {
|
@@ -151,7 +194,7 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
151
194
|
}
|
152
195
|
}
|
153
196
|
|
154
|
-
//
|
197
|
+
// setFormattedData with proper properties
|
155
198
|
const changeItem = (item: { [key: string]: any }, check: boolean) => {
|
156
199
|
const tree = check ? checkItem(item) : unCheckItem(item)
|
157
200
|
setFormattedData(tree)
|
@@ -159,12 +202,12 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
159
202
|
return tree
|
160
203
|
}
|
161
204
|
|
162
|
-
//
|
205
|
+
// Function to map over data and add parent_id + depth property to each item
|
163
206
|
const addCheckedAndParentProperty = (
|
164
207
|
treeData: { [key: string]: any }[],
|
165
208
|
selectedIds: string[],
|
166
209
|
parent_id: string = null,
|
167
|
-
depth
|
210
|
+
depth = 0,
|
168
211
|
) => {
|
169
212
|
if (!Array.isArray(treeData)) {
|
170
213
|
return
|
@@ -172,7 +215,7 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
172
215
|
return treeData.map((item: { [key: string]: any } | any) => {
|
173
216
|
const newItem = {
|
174
217
|
...item,
|
175
|
-
checked: selectedIds && selectedIds.length && selectedIds.includes(item.id),
|
218
|
+
checked: Boolean(selectedIds && selectedIds.length && selectedIds.includes(item.id)),
|
176
219
|
parent_id,
|
177
220
|
depth,
|
178
221
|
}
|
@@ -192,12 +235,12 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
192
235
|
})
|
193
236
|
}
|
194
237
|
|
195
|
-
//
|
238
|
+
// Click event for x on form pill
|
196
239
|
const handlePillClose = (event: any, clickedItem: { [key: string]: any }) => {
|
197
|
-
//
|
240
|
+
// Prevents the dropdown from closing when clicking on the pill
|
198
241
|
event.stopPropagation()
|
199
242
|
const updatedTree = changeItem(clickedItem, false)
|
200
|
-
//
|
243
|
+
// Logic for removing items from returnArray or defaultReturn when pills clicked
|
201
244
|
if (returnAllSelected) {
|
202
245
|
onSelect(getCheckedItems(updatedTree))
|
203
246
|
} else {
|
@@ -205,7 +248,7 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
205
248
|
}
|
206
249
|
}
|
207
250
|
|
208
|
-
//
|
251
|
+
// Handle click on input wrapper(entire div with pills, typeahead, etc) so it doesn't close when input or form pill is clicked
|
209
252
|
const handleInputWrapperClick = (e: any) => {
|
210
253
|
e.stopPropagation()
|
211
254
|
if (
|
@@ -214,13 +257,13 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
214
257
|
) {
|
215
258
|
return
|
216
259
|
}
|
217
|
-
|
260
|
+
setIsDropdownClosed(!isDropdownClosed)
|
218
261
|
}
|
219
262
|
|
220
|
-
//Main function to handle any click inside dropdown
|
263
|
+
// Main function to handle any click inside dropdown
|
221
264
|
const handledropdownItemClick = (e: any, check: boolean) => {
|
222
265
|
const clickedItem = e.target.parentNode.id
|
223
|
-
//
|
266
|
+
// Setting filterItem to "" will clear textinput and clear typeahead
|
224
267
|
setFilterItem("")
|
225
268
|
|
226
269
|
const filtered = filterFormattedDataById(formattedData, clickedItem)
|
@@ -232,15 +275,45 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
232
275
|
}
|
233
276
|
}
|
234
277
|
|
235
|
-
|
278
|
+
// Single select
|
279
|
+
const handleRadioButtonClick = (
|
280
|
+
e: React.ChangeEvent<HTMLInputElement>,
|
281
|
+
) => {
|
282
|
+
const { id, value: inputText } = e.target
|
283
|
+
// The radio button needs a unique ID, this grabs the ID before the hyphen
|
284
|
+
const selectedItemID = id.match(/^[^-]*/)[0]
|
285
|
+
// Reset tree checked state, triggering useEffect
|
286
|
+
const treeWithNoSelections = modifyRecursive(formattedData, false)
|
287
|
+
// Update tree with single selection
|
288
|
+
const treeWithSelectedItem = modifyValue(selectedItemID, treeWithNoSelections, true)
|
289
|
+
const selectedItem = filterFormattedDataById(treeWithSelectedItem, selectedItemID)
|
290
|
+
|
291
|
+
setFormattedData(treeWithSelectedItem)
|
292
|
+
setSingleSelectedItem({id: [selectedItemID], value: inputText, item: selectedItem})
|
293
|
+
// Reset the filter to always display dropdown options on click
|
294
|
+
setFilterItem("")
|
295
|
+
setIsDropdownClosed(true)
|
296
|
+
|
297
|
+
onSelect(selectedItem)
|
298
|
+
};
|
299
|
+
|
300
|
+
// Single select: reset the tree state upon typing
|
301
|
+
const handleRadioInputChange = (inputText: string) => {
|
302
|
+
modifyRecursive(formattedData, false)
|
303
|
+
setDefaultReturn([])
|
304
|
+
setSingleSelectedItem({id: [], value: inputText, item: []})
|
305
|
+
setFilterItem(inputText)
|
306
|
+
};
|
236
307
|
|
237
|
-
|
308
|
+
const isTreeRowExpanded = (item: any) => expanded.indexOf(item.id) > -1
|
309
|
+
|
310
|
+
// Handle click on chevron toggles in dropdown
|
238
311
|
const handleToggleClick = (id: string, event: React.MouseEvent) => {
|
239
312
|
event.stopPropagation()
|
240
313
|
const clickedItem = filterFormattedDataById(formattedData, id)
|
241
314
|
if (clickedItem) {
|
242
315
|
let expandedArray = [...expanded]
|
243
|
-
const itemExpanded =
|
316
|
+
const itemExpanded = isTreeRowExpanded(clickedItem[0])
|
244
317
|
|
245
318
|
if (itemExpanded)
|
246
319
|
expandedArray = expandedArray.filter((i) => i != clickedItem[0].id)
|
@@ -259,7 +332,8 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
259
332
|
}
|
260
333
|
return items
|
261
334
|
}
|
262
|
-
|
335
|
+
|
336
|
+
// Rendering formattedData to UI based on typeahead
|
263
337
|
const renderNestedOptions = (items: { [key: string]: any }[]) => {
|
264
338
|
return (
|
265
339
|
<ul>
|
@@ -267,42 +341,62 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
267
341
|
items.map((item: { [key: string]: any }) => {
|
268
342
|
return (
|
269
343
|
<div key={item.id}>
|
270
|
-
<li
|
271
|
-
|
344
|
+
<li
|
345
|
+
className="dropdown_item"
|
346
|
+
data-name={item.id}
|
347
|
+
>
|
348
|
+
<div className="dropdown_item_checkbox_row">
|
272
349
|
<div
|
273
|
-
|
350
|
+
key={isTreeRowExpanded(item) ? "chevron-down" : "chevron-right"}
|
274
351
|
>
|
275
352
|
<CircleIconButton
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
: "
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
353
|
+
className={
|
354
|
+
item.children && item.children.length > 0
|
355
|
+
? ""
|
356
|
+
: "toggle_icon"
|
357
|
+
}
|
358
|
+
icon={
|
359
|
+
isTreeRowExpanded(item) ? "chevron-down" : "chevron-right"
|
360
|
+
}
|
361
|
+
onClick={(event: any) =>
|
362
|
+
handleToggleClick(item.id, event)
|
363
|
+
}
|
364
|
+
variant="link"
|
288
365
|
/>
|
289
366
|
</div>
|
290
|
-
|
291
|
-
<
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
367
|
+
{ variant === "single" ? (
|
368
|
+
<Radio
|
369
|
+
checked={item.checked}
|
370
|
+
id={`${item.id}-${item.label}`}
|
371
|
+
label={item.label}
|
372
|
+
name={inputName}
|
373
|
+
onChange={(e: React.ChangeEvent<HTMLInputElement>) => (
|
374
|
+
handleRadioButtonClick(e)
|
375
|
+
)}
|
376
|
+
type="radio"
|
377
|
+
value={item.label}
|
299
378
|
/>
|
300
|
-
|
379
|
+
) : (
|
380
|
+
<Checkbox
|
381
|
+
id={item.id}
|
382
|
+
text={item.label}
|
383
|
+
>
|
384
|
+
<input
|
385
|
+
checked={item.checked}
|
386
|
+
name={item.label}
|
387
|
+
onChange={(e) => {
|
388
|
+
handledropdownItemClick(e, !item.checked)
|
389
|
+
}}
|
390
|
+
type="checkbox"
|
391
|
+
value={item.label}
|
392
|
+
/>
|
393
|
+
</Checkbox>
|
394
|
+
)}
|
301
395
|
</div>
|
302
|
-
{
|
396
|
+
{isTreeRowExpanded(item) &&
|
303
397
|
item.children &&
|
304
398
|
item.children.length > 0 &&
|
305
|
-
!filterItem && ( // Show children if expanded is true
|
399
|
+
(variant === "single" || !filterItem) && ( // Show children if expanded is true
|
306
400
|
<div>{renderNestedOptions(item.children)}</div>
|
307
401
|
)}
|
308
402
|
</li>
|
@@ -313,68 +407,121 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
313
407
|
)
|
314
408
|
}
|
315
409
|
|
316
|
-
|
317
|
-
|
318
410
|
return (
|
319
|
-
<div
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
411
|
+
<div
|
412
|
+
{...ariaProps}
|
413
|
+
{...dataProps}
|
414
|
+
className={classes}
|
415
|
+
id={id}
|
416
|
+
>
|
417
|
+
<div
|
418
|
+
className="wrapper"
|
419
|
+
ref={dropdownRef}
|
420
|
+
>
|
421
|
+
<div
|
422
|
+
className="input_wrapper"
|
423
|
+
onClick={handleInputWrapperClick}
|
424
|
+
>
|
425
|
+
<div className="input_inner_container">
|
426
|
+
{variant === "single" && defaultReturn.length !== 0
|
427
|
+
? defaultReturn.map((selectedItem) => (
|
428
|
+
<input
|
429
|
+
key={selectedItem.id}
|
430
|
+
name={`${name}[]`}
|
431
|
+
type="hidden"
|
432
|
+
value={selectedItem.id}
|
336
433
|
/>
|
337
434
|
))
|
338
435
|
: null}
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
436
|
+
|
437
|
+
{variant !== "single" && (
|
438
|
+
<>
|
439
|
+
{returnAllSelected && returnedArray.length !== 0
|
440
|
+
? returnedArray.map((item) => (
|
441
|
+
<input
|
442
|
+
key={item.id}
|
443
|
+
name={`${name}[]`}
|
444
|
+
type="hidden"
|
445
|
+
value={item.id}
|
446
|
+
/>
|
447
|
+
))
|
448
|
+
: null}
|
449
|
+
|
450
|
+
{returnAllSelected &&
|
451
|
+
returnedArray.length !== 0 &&
|
452
|
+
inputDisplay === "pills"
|
453
|
+
? returnedArray.map((item, index) => (
|
454
|
+
<FormPill
|
455
|
+
key={index}
|
456
|
+
onClick={(event: any) => handlePillClose(event, item)}
|
457
|
+
size="small"
|
458
|
+
text={item.label}
|
459
|
+
/>
|
460
|
+
))
|
461
|
+
: null}
|
462
|
+
|
463
|
+
{!returnAllSelected &&
|
464
|
+
defaultReturn.length !== 0 &&
|
465
|
+
inputDisplay === "pills"
|
466
|
+
? defaultReturn.map((item, index) => (
|
467
|
+
<FormPill
|
468
|
+
key={index}
|
469
|
+
onClick={(event: any) => handlePillClose(event, item)}
|
470
|
+
size="small"
|
471
|
+
text={item.label}
|
472
|
+
/>
|
473
|
+
))
|
474
|
+
: null}
|
475
|
+
|
476
|
+
{returnAllSelected &&
|
477
|
+
returnedArray.length !== 0 &&
|
478
|
+
inputDisplay === "pills" && <br />}
|
479
|
+
|
480
|
+
{!returnAllSelected &&
|
481
|
+
defaultReturn.length !== 0 &&
|
482
|
+
inputDisplay === "pills" && <br />}
|
483
|
+
</>
|
484
|
+
)}
|
485
|
+
|
353
486
|
<input
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
487
|
+
id="multiselect_input"
|
488
|
+
onChange={(e) =>{
|
489
|
+
variant === "single"
|
490
|
+
? handleRadioInputChange(e.target.value)
|
491
|
+
: setFilterItem(e.target.value)
|
492
|
+
}}
|
493
|
+
onClick={() => setIsDropdownClosed(false)}
|
494
|
+
placeholder={
|
495
|
+
inputDisplay === "none" && itemsSelectedLength()
|
496
|
+
? `${itemsSelectedLength()} ${itemsSelectedLength() === 1 ? "item" : "items"} selected`
|
497
|
+
: "Start typing..."
|
498
|
+
}
|
499
|
+
value={singleSelectedItem.value || filterItem}
|
363
500
|
/>
|
364
501
|
</div>
|
365
|
-
|
366
|
-
|
367
|
-
|
502
|
+
|
503
|
+
{isDropdownClosed ? (
|
504
|
+
<div key="chevron-down">
|
505
|
+
<Icon
|
506
|
+
icon="chevron-down"
|
507
|
+
size="xs"
|
508
|
+
/>
|
368
509
|
</div>
|
369
510
|
) : (
|
370
|
-
<div key=
|
371
|
-
<Icon
|
511
|
+
<div key="chevron-up">
|
512
|
+
<Icon
|
513
|
+
icon="chevron-up"
|
514
|
+
size="xs"
|
515
|
+
/>
|
372
516
|
</div>
|
373
517
|
)}
|
374
518
|
</div>
|
375
|
-
|
519
|
+
|
520
|
+
<div className={`dropdown_menu ${isDropdownClosed ? "close" : "open"}`}>
|
376
521
|
{renderNestedOptions(
|
377
|
-
filterItem
|
522
|
+
filterItem
|
523
|
+
? findByFilter(formattedData, filterItem)
|
524
|
+
: formattedData
|
378
525
|
)}
|
379
526
|
</div>
|
380
527
|
</div>
|
@@ -8,6 +8,7 @@
|
|
8
8
|
label: "People",
|
9
9
|
value: "People",
|
10
10
|
id: "101",
|
11
|
+
expanded: true,
|
11
12
|
children: [
|
12
13
|
{
|
13
14
|
label: "Talent Acquisition",
|
@@ -63,10 +64,8 @@
|
|
63
64
|
],
|
64
65
|
}] %>
|
65
66
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
tree_data: treeData
|
72
|
-
}) %>
|
67
|
+
<%= pb_rails("multi_level_select", props: {
|
68
|
+
id: "multi-level-select-default-rails",
|
69
|
+
name: "my_array",
|
70
|
+
tree_data: treeData
|
71
|
+
}) %>
|
@@ -77,7 +77,7 @@ const MultiLevelSelectSelectedIds = (props) => {
|
|
77
77
|
console.log("Selected Items with Return All Selected Data", selectedNodes)
|
78
78
|
}
|
79
79
|
returnAllSelected
|
80
|
-
selectedIds={["energy1","talent1"]}
|
80
|
+
selectedIds={["energy1", "talent1"]}
|
81
81
|
treeData={treeData}
|
82
82
|
{...props}
|
83
83
|
/>
|
@@ -0,0 +1,73 @@
|
|
1
|
+
<% treeData = [{
|
2
|
+
label: "Power Home Remodeling",
|
3
|
+
value: "Power Home Remodeling",
|
4
|
+
id: "200",
|
5
|
+
expanded: true,
|
6
|
+
children: [
|
7
|
+
{
|
8
|
+
label: "People",
|
9
|
+
value: "People",
|
10
|
+
id: "201",
|
11
|
+
expanded: true,
|
12
|
+
children: [
|
13
|
+
{
|
14
|
+
label: "Talent Acquisition",
|
15
|
+
value: "Talent Acquisition",
|
16
|
+
id: "202",
|
17
|
+
},
|
18
|
+
{
|
19
|
+
label: "Business Affairs",
|
20
|
+
value: "Business Affairs",
|
21
|
+
id: "203",
|
22
|
+
children: [
|
23
|
+
{
|
24
|
+
label: "Initiatives",
|
25
|
+
value: "Initiatives",
|
26
|
+
id: "204",
|
27
|
+
},
|
28
|
+
{
|
29
|
+
label: "Learning & Development",
|
30
|
+
value: "Learning & Development",
|
31
|
+
id: "205",
|
32
|
+
},
|
33
|
+
],
|
34
|
+
},
|
35
|
+
{
|
36
|
+
label: "People Experience",
|
37
|
+
value: "People Experience",
|
38
|
+
id: "206",
|
39
|
+
},
|
40
|
+
],
|
41
|
+
},
|
42
|
+
{
|
43
|
+
label: "Contact Center",
|
44
|
+
value: "Contact Center",
|
45
|
+
id: "207",
|
46
|
+
children: [
|
47
|
+
{
|
48
|
+
label: "Appointment Management",
|
49
|
+
value: "Appointment Management",
|
50
|
+
id: "208",
|
51
|
+
},
|
52
|
+
{
|
53
|
+
label: "Customer Service",
|
54
|
+
value: "Customer Service",
|
55
|
+
id: "209",
|
56
|
+
},
|
57
|
+
{
|
58
|
+
label: "Energy",
|
59
|
+
value: "Energy",
|
60
|
+
id: "210",
|
61
|
+
},
|
62
|
+
],
|
63
|
+
},
|
64
|
+
],
|
65
|
+
}] %>
|
66
|
+
|
67
|
+
<%= pb_rails("multi_level_select", props: {
|
68
|
+
id: "multi-level-select-single-rails",
|
69
|
+
name: "my_single_select_array",
|
70
|
+
tree_data: treeData,
|
71
|
+
input_name: "Power",
|
72
|
+
variant: "single"
|
73
|
+
}) %>
|