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