playbook_ui 13.9.0 → 13.10.0.pre.alpha.PLAY1046multilevelsingleselectphase21323

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- //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
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
- //this is essentially the return that the user will get when they use the kit
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
- //state for return for default
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
- setFormattedData(addCheckedAndParentProperty(treeData, selectedIds))
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
- setIsClosed(true)
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
- //iterate over tree, find item and set checked or unchecked
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
- item.children = modifyRecursive(item.children, 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
+ }
126
169
  }
127
170
 
128
171
  return item
129
172
  })
130
173
  }
131
174
 
132
- //clone tree, check items + children
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
- //clone tree, uncheck items + children
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
- //setformattedData with proper properties
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
- //function to map over data and add parent_id + depth property to each item
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: number = 0,
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
- //click event for x on form pill
238
+ // Click event for x on form pill
196
239
  const handlePillClose = (event: any, clickedItem: { [key: string]: any }) => {
197
- // prevents the dropdown from closing when clicking on the pill
240
+ // Prevents the dropdown from closing when clicking on the pill
198
241
  event.stopPropagation()
199
242
  const updatedTree = changeItem(clickedItem, false)
200
- //logic for removing items from returnArray or defaultReturn when pills clicked
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
- //handle click on input wrapper(entire div with pills, typeahead, etc) so it doesn't close when input or form pill is clicked
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
- setIsClosed(!isClosed)
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
- //setting filterItem to "" will clear textinput and clear typeahead
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
- const isExpanded = (item: any) => expanded.indexOf(item.id) > -1
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
- //handle click on chevron toggles in dropdown
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 = isExpanded(clickedItem[0])
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,19 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
259
332
  }
260
333
  return items
261
334
  }
262
- //rendering formattedData to UI based on typeahead
335
+
336
+ const singleHiddenInstances = document.querySelectorAll('.singleHidden');
337
+
338
+ singleHiddenInstances.forEach(singleHiddenInstance => {
339
+
340
+ const siblingElement = singleHiddenInstance.nextElementSibling as HTMLElement;
341
+ if (siblingElement && siblingElement.classList.contains('pb_radio_button')) {
342
+ siblingElement.style.display = 'none';
343
+ }
344
+ });
345
+
346
+
347
+ // Rendering formattedData to UI based on typeahead
263
348
  const renderNestedOptions = (items: { [key: string]: any }[]) => {
264
349
  return (
265
350
  <ul>
@@ -267,42 +352,63 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
267
352
  items.map((item: { [key: string]: any }) => {
268
353
  return (
269
354
  <div key={item.id}>
270
- <li className='dropdown_item' data-name={item.id}>
271
- <div className='dropdown_item_checkbox_row'>
355
+ <li
356
+ className="dropdown_item"
357
+ data-name={item.id}
358
+ >
359
+ <div className="dropdown_item_checkbox_row">
272
360
  <div
273
- key={isExpanded(item) ? "chevron-down" : "chevron-right"}
361
+ key={isTreeRowExpanded(item) ? "chevron-down" : "chevron-right"}
274
362
  >
275
363
  <CircleIconButton
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
+ className={
365
+ item.children && item.children.length > 0
366
+ ? ""
367
+ : "toggle_icon"
368
+ }
369
+ icon={
370
+ isTreeRowExpanded(item) ? "chevron-down" : "chevron-right"
371
+ }
372
+ onClick={(event: any) =>
373
+ handleToggleClick(item.id, event)
374
+ }
375
+ variant="link"
288
376
  />
289
377
  </div>
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
- }}
378
+ { variant === "single" ? (
379
+ <Radio
380
+ checked={item.checked}
381
+ class={item.hidden ? "singleHidden" : ""}
382
+ id={`${item.id}-${item.label}`}
383
+ label={item.label}
384
+ name={inputName}
385
+ onChange={(e: React.ChangeEvent<HTMLInputElement>) => (
386
+ handleRadioButtonClick(e)
387
+ )}
388
+ type="radio"
389
+ value={item.label}
299
390
  />
300
- </Checkbox>
391
+ ) : (
392
+ <Checkbox
393
+ id={item.id}
394
+ text={item.label}
395
+ >
396
+ <input
397
+ checked={item.checked}
398
+ name={item.label}
399
+ onChange={(e) => {
400
+ handledropdownItemClick(e, !item.checked)
401
+ }}
402
+ type="checkbox"
403
+ value={item.label}
404
+ />
405
+ </Checkbox>
406
+ )}
301
407
  </div>
302
- {isExpanded(item) &&
408
+ {isTreeRowExpanded(item) &&
303
409
  item.children &&
304
410
  item.children.length > 0 &&
305
- !filterItem && ( // Show children if expanded is true
411
+ (variant === "single" || !filterItem) && ( // Show children if expanded is true
306
412
  <div>{renderNestedOptions(item.children)}</div>
307
413
  )}
308
414
  </li>
@@ -313,68 +419,121 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
313
419
  )
314
420
  }
315
421
 
316
-
317
-
318
422
  return (
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} />
326
- ))
327
- : null}
328
-
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)}
423
+ <div
424
+ {...ariaProps}
425
+ {...dataProps}
426
+ className={classes}
427
+ id={id}
428
+ >
429
+ <div
430
+ className="wrapper"
431
+ ref={dropdownRef}
432
+ >
433
+ <div
434
+ className="input_wrapper"
435
+ onClick={handleInputWrapperClick}
436
+ >
437
+ <div className="input_inner_container">
438
+ {variant === "single" && defaultReturn.length !== 0
439
+ ? defaultReturn.map((selectedItem) => (
440
+ <input
441
+ key={selectedItem.id}
442
+ name={`${name}[]`}
443
+ type="hidden"
444
+ value={selectedItem.id}
336
445
  />
337
446
  ))
338
447
  : 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 />}
448
+
449
+ {variant !== "single" && (
450
+ <>
451
+ {returnAllSelected && returnedArray.length !== 0
452
+ ? returnedArray.map((item) => (
453
+ <input
454
+ key={item.id}
455
+ name={`${name}[]`}
456
+ type="hidden"
457
+ value={item.id}
458
+ />
459
+ ))
460
+ : null}
461
+
462
+ {returnAllSelected &&
463
+ returnedArray.length !== 0 &&
464
+ inputDisplay === "pills"
465
+ ? returnedArray.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
+ defaultReturn.length !== 0 &&
477
+ inputDisplay === "pills"
478
+ ? defaultReturn.map((item, index) => (
479
+ <FormPill
480
+ key={index}
481
+ onClick={(event: any) => handlePillClose(event, item)}
482
+ size="small"
483
+ text={item.label}
484
+ />
485
+ ))
486
+ : null}
487
+
488
+ {returnAllSelected &&
489
+ returnedArray.length !== 0 &&
490
+ inputDisplay === "pills" && <br />}
491
+
492
+ {!returnAllSelected &&
493
+ defaultReturn.length !== 0 &&
494
+ inputDisplay === "pills" && <br />}
495
+ </>
496
+ )}
497
+
353
498
  <input
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
+ id="multiselect_input"
500
+ onChange={(e) =>{
501
+ variant === "single"
502
+ ? handleRadioInputChange(e.target.value)
503
+ : setFilterItem(e.target.value)
504
+ }}
505
+ onClick={() => setIsDropdownClosed(false)}
506
+ placeholder={
507
+ inputDisplay === "none" && itemsSelectedLength()
508
+ ? `${itemsSelectedLength()} ${itemsSelectedLength() === 1 ? "item" : "items"} selected`
509
+ : "Start typing..."
510
+ }
511
+ value={singleSelectedItem.value || filterItem}
363
512
  />
364
513
  </div>
365
- {isClosed ? (
366
- <div key='chevron-down'>
367
- <Icon icon='chevron-down' size="xs"/>
514
+
515
+ {isDropdownClosed ? (
516
+ <div key="chevron-down">
517
+ <Icon
518
+ icon="chevron-down"
519
+ size="xs"
520
+ />
368
521
  </div>
369
522
  ) : (
370
- <div key='chevron-up'>
371
- <Icon icon='chevron-up' size="xs"/>
523
+ <div key="chevron-up">
524
+ <Icon
525
+ icon="chevron-up"
526
+ size="xs"
527
+ />
372
528
  </div>
373
529
  )}
374
530
  </div>
375
- <div className={`dropdown_menu ${isClosed ? "close" : "open"}`}>
531
+
532
+ <div className={`dropdown_menu ${isDropdownClosed ? "close" : "open"}`}>
376
533
  {renderNestedOptions(
377
- filterItem ? findByFilter(formattedData, filterItem) : formattedData
534
+ filterItem
535
+ ? findByFilter(formattedData, filterItem)
536
+ : formattedData
378
537
  )}
379
538
  </div>
380
539
  </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
- <%= pb_rails("multi_level_select", props: {
69
- id: "multi-level-select-default-rails",
70
- name: "my_array",
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,76 @@
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
+ hidden: true,
13
+ children: [
14
+ {
15
+ label: "Talent Acquisition",
16
+ value: "Talent Acquisition",
17
+ id: "202",
18
+ },
19
+ {
20
+ label: "Business Affairs",
21
+ value: "Business Affairs",
22
+ id: "203",
23
+ hidden: true,
24
+ children: [
25
+ {
26
+ label: "Initiatives",
27
+ value: "Initiatives",
28
+ id: "204",
29
+ },
30
+ {
31
+ label: "Learning & Development",
32
+ value: "Learning & Development",
33
+ id: "205",
34
+ },
35
+ ],
36
+ },
37
+ {
38
+ label: "People Experience",
39
+ value: "People Experience",
40
+ id: "206",
41
+ },
42
+ ],
43
+ },
44
+ {
45
+ label: "Contact Center",
46
+ value: "Contact Center",
47
+ id: "207",
48
+ hidden: true,
49
+ children: [
50
+ {
51
+ label: "Appointment Management",
52
+ value: "Appointment Management",
53
+ id: "208",
54
+ },
55
+ {
56
+ label: "Customer Service",
57
+ value: "Customer Service",
58
+ id: "209",
59
+ },
60
+ {
61
+ label: "Energy",
62
+ value: "Energy",
63
+ id: "210",
64
+ },
65
+ ],
66
+ },
67
+ ],
68
+ }] %>
69
+
70
+ <%= pb_rails("multi_level_select", props: {
71
+ id: "multi-level-select-single-rails",
72
+ name: "my_single_select_array",
73
+ tree_data: treeData,
74
+ input_name: "Power",
75
+ variant: "single"
76
+ }) %>