playbook_ui 13.7.0 → 13.8.0.pre.alpha.PLAY962SingleSelect1256

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_currency/_currency.scss +35 -15
  3. data/app/pb_kits/playbook/pb_currency/_currency.tsx +44 -42
  4. data/app/pb_kits/playbook/pb_currency/currency.html.erb +11 -5
  5. data/app/pb_kits/playbook/pb_currency/currency.rb +10 -2
  6. data/app/pb_kits/playbook/pb_currency/docs/_currency_unstyled.html.erb +14 -0
  7. data/app/pb_kits/playbook/pb_currency/docs/_currency_unstyled.jsx +30 -0
  8. data/app/pb_kits/playbook/pb_currency/docs/_currency_unstyled.md +1 -0
  9. data/app/pb_kits/playbook/pb_currency/docs/_currency_variants.html.erb +2 -1
  10. data/app/pb_kits/playbook/pb_currency/docs/example.yml +2 -0
  11. data/app/pb_kits/playbook/pb_currency/docs/index.js +1 -0
  12. data/app/pb_kits/playbook/pb_multi_level_select/_helper_functions.tsx +27 -22
  13. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.scss +2 -1
  14. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +257 -111
  15. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_default.html.erb +6 -7
  16. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_selected_ids.jsx +1 -1
  17. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_single.html.erb +73 -0
  18. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_single.jsx +88 -0
  19. data/app/pb_kits/playbook/pb_multi_level_select/docs/example.yml +3 -2
  20. data/app/pb_kits/playbook/pb_multi_level_select/docs/index.js +2 -1
  21. data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select.rb +7 -0
  22. data/app/pb_kits/playbook/pb_nav/_item.tsx +12 -9
  23. data/app/pb_kits/playbook/pb_nav/_nav_item.test.js +23 -1
  24. data/app/pb_kits/playbook/pb_nav/_subtle_mixin.scss +6 -0
  25. data/app/pb_kits/playbook/pb_nav/_vertical_nav.scss +3 -0
  26. data/app/pb_kits/playbook/pb_nav/item.rb +7 -2
  27. data/app/pb_kits/playbook/pb_table/styles/_table_header.scss +9 -9
  28. data/app/pb_kits/playbook/pb_table/table_header.html.erb +10 -2
  29. data/dist/playbook-rails.js +5 -5
  30. data/lib/playbook/version.rb +2 -2
  31. metadata +12 -7
@@ -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,44 @@ 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
+ setSingleSelectedItem({id: [], value: inputText, item: []})
304
+ setFilterItem(inputText)
305
+ };
236
306
 
237
- //handle click on chevron toggles in dropdown
307
+ const isTreeRowExpanded = (item: any) => expanded.indexOf(item.id) > -1
308
+
309
+ // Handle click on chevron toggles in dropdown
238
310
  const handleToggleClick = (id: string, event: React.MouseEvent) => {
239
311
  event.stopPropagation()
240
312
  const clickedItem = filterFormattedDataById(formattedData, id)
241
313
  if (clickedItem) {
242
314
  let expandedArray = [...expanded]
243
- const itemExpanded = isExpanded(clickedItem[0])
315
+ const itemExpanded = isTreeRowExpanded(clickedItem[0])
244
316
 
245
317
  if (itemExpanded)
246
318
  expandedArray = expandedArray.filter((i) => i != clickedItem[0].id)
@@ -259,7 +331,8 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
259
331
  }
260
332
  return items
261
333
  }
262
- //rendering formattedData to UI based on typeahead
334
+
335
+ // Rendering formattedData to UI based on typeahead
263
336
  const renderNestedOptions = (items: { [key: string]: any }[]) => {
264
337
  return (
265
338
  <ul>
@@ -267,42 +340,62 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
267
340
  items.map((item: { [key: string]: any }) => {
268
341
  return (
269
342
  <div key={item.id}>
270
- <li className='dropdown_item' data-name={item.id}>
271
- <div className='dropdown_item_checkbox_row'>
343
+ <li
344
+ className="dropdown_item"
345
+ data-name={item.id}
346
+ >
347
+ <div className="dropdown_item_checkbox_row">
272
348
  <div
273
- key={isExpanded(item) ? "chevron-down" : "chevron-right"}
349
+ key={isTreeRowExpanded(item) ? "chevron-down" : "chevron-right"}
274
350
  >
275
351
  <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'
352
+ className={
353
+ item.children && item.children.length > 0
354
+ ? ""
355
+ : "toggle_icon"
356
+ }
357
+ icon={
358
+ isTreeRowExpanded(item) ? "chevron-down" : "chevron-right"
359
+ }
360
+ onClick={(event: any) =>
361
+ handleToggleClick(item.id, event)
362
+ }
363
+ variant="link"
288
364
  />
289
365
  </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
- }}
366
+ { variant === "single" ? (
367
+ <Radio
368
+ checked={item.checked}
369
+ id={`${item.id}-${item.label}`}
370
+ label={item.label}
371
+ name={inputName}
372
+ onChange={(e: React.ChangeEvent<HTMLInputElement>) => (
373
+ handleRadioButtonClick(e)
374
+ )}
375
+ type="radio"
376
+ value={item.label}
299
377
  />
300
- </Checkbox>
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
+ )}
301
394
  </div>
302
- {isExpanded(item) &&
395
+ {isTreeRowExpanded(item) &&
303
396
  item.children &&
304
397
  item.children.length > 0 &&
305
- !filterItem && ( // Show children if expanded is true
398
+ (variant === "single" || !filterItem) && ( // Show children if expanded is true
306
399
  <div>{renderNestedOptions(item.children)}</div>
307
400
  )}
308
401
  </li>
@@ -313,68 +406,121 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
313
406
  )
314
407
  }
315
408
 
316
-
317
-
318
409
  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)}
410
+ <div
411
+ {...ariaProps}
412
+ {...dataProps}
413
+ className={classes}
414
+ id={id}
415
+ >
416
+ <div
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}
336
432
  />
337
433
  ))
338
434
  : 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 />}
435
+
436
+ {variant !== "single" && (
437
+ <>
438
+ {returnAllSelected && returnedArray.length !== 0
439
+ ? returnedArray.map((item) => (
440
+ <input
441
+ key={item.id}
442
+ name={`${name}[]`}
443
+ type="hidden"
444
+ value={item.id}
445
+ />
446
+ ))
447
+ : null}
448
+
449
+ {returnAllSelected &&
450
+ returnedArray.length !== 0 &&
451
+ inputDisplay === "pills"
452
+ ? returnedArray.map((item, index) => (
453
+ <FormPill
454
+ key={index}
455
+ onClick={(event: any) => handlePillClose(event, item)}
456
+ size="small"
457
+ text={item.label}
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
+
353
485
  <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)}
486
+ id="multiselect_input"
487
+ onChange={(e) =>{
488
+ variant === "single"
489
+ ? handleRadioInputChange(e.target.value)
490
+ : setFilterItem(e.target.value)
491
+ }}
492
+ onClick={() => setIsDropdownClosed(false)}
493
+ placeholder={
494
+ inputDisplay === "none" && itemsSelectedLength()
495
+ ? `${itemsSelectedLength()} ${itemsSelectedLength() === 1 ? "item" : "items"} selected`
496
+ : "Start typing..."
497
+ }
498
+ value={singleSelectedItem.value || filterItem}
363
499
  />
364
500
  </div>
365
- {isClosed ? (
366
- <div key='chevron-down'>
367
- <Icon icon='chevron-down' size="xs"/>
501
+
502
+ {isDropdownClosed ? (
503
+ <div key="chevron-down">
504
+ <Icon
505
+ icon="chevron-down"
506
+ size="xs"
507
+ />
368
508
  </div>
369
509
  ) : (
370
- <div key='chevron-up'>
371
- <Icon icon='chevron-up' size="xs"/>
510
+ <div key="chevron-up">
511
+ <Icon
512
+ icon="chevron-up"
513
+ size="xs"
514
+ />
372
515
  </div>
373
516
  )}
374
517
  </div>
375
- <div className={`dropdown_menu ${isClosed ? "close" : "open"}`}>
518
+
519
+ <div className={`dropdown_menu ${isDropdownClosed ? "close" : "open"}`}>
376
520
  {renderNestedOptions(
377
- filterItem ? findByFilter(formattedData, filterItem) : formattedData
521
+ filterItem
522
+ ? findByFilter(formattedData, filterItem)
523
+ : formattedData
378
524
  )}
379
525
  </div>
380
526
  </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,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
+ }) %>