playbook_ui 12.25.0.pre.alpha.play824786 → 12.25.0.pre.alpha.railsmultilevelimprovements758

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/_playbook.scss +0 -1
  3. data/app/pb_kits/playbook/index.js +0 -1
  4. data/app/pb_kits/playbook/pb_avatar/docs/_avatar_swift.md +1 -82
  5. data/app/pb_kits/playbook/pb_docs/kit_example.html.erb +13 -14
  6. data/app/pb_kits/playbook/pb_form_pill/_form_pill.tsx +2 -3
  7. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.scss +98 -58
  8. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +102 -337
  9. data/app/pb_kits/playbook/pb_multi_level_select/_multi_select_helper.tsx +31 -0
  10. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_default.html.erb +4 -4
  11. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_default.md +1 -1
  12. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_return_all_selected.html.erb +0 -1
  13. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_with_form.html.erb +72 -0
  14. data/app/pb_kits/playbook/pb_multi_level_select/docs/example.yml +1 -0
  15. data/app/pb_kits/playbook/pb_multi_level_select/helper_functions.ts +87 -0
  16. data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select.rb +3 -0
  17. data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select.test.jsx +1 -1
  18. data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +44 -109
  19. data/app/pb_kits/playbook/pb_phone_number_input/docs/example.yml +1 -3
  20. data/app/pb_kits/playbook/pb_phone_number_input/docs/index.js +0 -1
  21. data/app/pb_kits/playbook/pb_phone_number_input/phone_number_input.rb +0 -6
  22. data/app/pb_kits/playbook/pb_phone_number_input/phone_number_input.test.js +62 -110
  23. data/app/pb_kits/playbook/playbook-doc.js +0 -2
  24. data/dist/menu.yml +0 -1
  25. data/dist/playbook-rails.js +7 -7
  26. data/lib/playbook/forms/builder/{intl_telephone_field.rb → multi_level_select_field.rb} +2 -2
  27. data/lib/playbook/forms/builder.rb +1 -1
  28. data/lib/playbook/version.rb +1 -1
  29. metadata +6 -26
  30. data/app/pb_kits/playbook/pb_detail/_detail.scss +0 -44
  31. data/app/pb_kits/playbook/pb_detail/_detail.tsx +0 -55
  32. data/app/pb_kits/playbook/pb_detail/_detail_mixins.scss +0 -29
  33. data/app/pb_kits/playbook/pb_detail/detail.html.erb +0 -7
  34. data/app/pb_kits/playbook/pb_detail/detail.rb +0 -31
  35. data/app/pb_kits/playbook/pb_detail/detail.test.jsx +0 -46
  36. data/app/pb_kits/playbook/pb_detail/docs/_description.md +0 -1
  37. data/app/pb_kits/playbook/pb_detail/docs/_detail_bold.html.erb +0 -34
  38. data/app/pb_kits/playbook/pb_detail/docs/_detail_bold.jsx +0 -49
  39. data/app/pb_kits/playbook/pb_detail/docs/_detail_bold.md +0 -1
  40. data/app/pb_kits/playbook/pb_detail/docs/_detail_colors.html.erb +0 -24
  41. data/app/pb_kits/playbook/pb_detail/docs/_detail_colors.jsx +0 -38
  42. data/app/pb_kits/playbook/pb_detail/docs/_detail_colors.md +0 -6
  43. data/app/pb_kits/playbook/pb_detail/docs/_detail_default.html.erb +0 -3
  44. data/app/pb_kits/playbook/pb_detail/docs/_detail_default.jsx +0 -13
  45. data/app/pb_kits/playbook/pb_detail/docs/_detail_styled.html.erb +0 -22
  46. data/app/pb_kits/playbook/pb_detail/docs/_detail_styled.jsx +0 -32
  47. data/app/pb_kits/playbook/pb_detail/docs/example.yml +0 -11
  48. data/app/pb_kits/playbook/pb_detail/docs/index.js +0 -4
  49. data/app/pb_kits/playbook/pb_multi_level_select/_helper_functions.tsx +0 -212
  50. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_validation.html.erb +0 -14
  51. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_validation.jsx +0 -60
  52. data/app/pb_kits/playbook/utilities/object.ts +0 -3
@@ -1,34 +1,20 @@
1
- import React, { useState, useEffect, useRef } from "react";
1
+ import React, { useState, useEffect, useMemo } from "react";
2
2
  import classnames from "classnames";
3
3
  import { buildAriaProps, buildCss, buildDataProps } from "../utilities/props";
4
- import { globalProps, GlobalProps } from "../utilities/globalProps";
5
- import Icon from "../pb_icon/_icon";
6
- import Checkbox from "../pb_checkbox/_checkbox";
7
- import FormPill from "../pb_form_pill/_form_pill";
8
- import CircleIconButton from "../pb_circle_icon_button/_circle_icon_button";
9
- import {
10
- unCheckIt,
11
- getAncestorsOfUnchecked,
12
- unCheckedRecursive,
13
- checkedRecursive,
14
- filterFormattedDataById,
15
- findByFilter,
16
- getCheckedItems,
17
- updateReturnItems,
18
- recursiveReturnOnlyParent,
19
- removeChildrenIfParentChecked,
20
- getChildIds,
21
- } from "./_helper_functions";
4
+ import { globalProps } from "../utilities/globalProps";
5
+ import { findItemById, checkIt, unCheckIt, getParentAndAncestorsIds } from "./helper_functions";
6
+ import MultiSelectHelper from "./_multi_select_helper";
22
7
 
23
8
  type MultiLevelSelectProps = {
24
9
  aria?: { [key: string]: string };
25
10
  className?: string;
26
11
  data?: { [key: string]: string };
27
12
  id?: string;
13
+ name?: string;
28
14
  returnAllSelected?: boolean;
29
15
  treeData?: { [key: string]: string }[];
30
16
  onSelect?: (prop: { [key: string]: any }) => void;
31
- } & GlobalProps;
17
+ };
32
18
 
33
19
  const MultiLevelSelect = (props: MultiLevelSelectProps) => {
34
20
  const {
@@ -36,6 +22,7 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
36
22
  className,
37
23
  data = {},
38
24
  id,
25
+ name,
39
26
  returnAllSelected = false,
40
27
  treeData,
41
28
  onSelect = () => {},
@@ -49,343 +36,121 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
49
36
  className
50
37
  );
51
38
 
52
- const dropdownRef = useRef(null);
53
-
54
- //state for whether dropdown is open or closed
55
- const [isClosed, setIsClosed] = useState(true);
56
- //state from onchange for textinput, to use for filtering to create typeahead
57
- const [filterItem, setFilterItem] = useState("");
58
- //this is essentially the return that the user will get when they use the kit
59
- const [returnedArray, setReturnedArray] = useState([]);
60
- //formattedData with checked and parent_id added
61
39
  const [formattedData, setFormattedData] = useState(treeData);
62
- //toggle chevron in dropdown
63
- //@ts-ignore
64
- const [isToggled, setIsToggled] = useState<{ [id: number]: boolean }>({});
65
- //state for return for default
66
- const [defaultReturn, setDefaultReturn] = useState([]);
67
-
68
- useEffect(() => {
69
- let el = document.getElementById(`pb_data_wrapper_${id}`);
70
- if (el) {
71
- el.setAttribute(
72
- "data-tree",
73
- JSON.stringify(returnAllSelected ? returnedArray : defaultReturn)
74
- );
75
- }
76
- returnAllSelected
77
- ? onSelect(returnedArray)
78
- : onSelect(
79
- defaultReturn.filter(
80
- (item, index, self) =>
81
- index === self.findIndex((obj) => obj.id === item.id)
82
- )
83
- );
84
- }, [returnedArray, defaultReturn]);
85
-
86
- useEffect(() => {
87
- //Create new formattedData array for use
88
- setFormattedData(addCheckedAndParentProperty(treeData));
89
- // Function to handle clicks outside the dropdown
90
- const handleClickOutside = (event: any) => {
91
- if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
92
- setIsClosed(true);
93
- }
94
- };
95
- //if any items already checked in first render, set return accordingly
96
- const initialChecked = getCheckedItems(treeData)
97
- initialChecked && returnAllSelected && setReturnedArray(initialChecked)
98
- initialChecked && !returnAllSelected && setDefaultReturn(initialChecked)
99
-
100
- // Attach the event listener
101
- window.addEventListener("click", handleClickOutside);
102
- // Clean up the event listener on unmount
103
- return () => {
104
- window.removeEventListener("click", handleClickOutside);
105
- };
106
- }, []);
107
-
108
- //function to map over data and add parent_id + depth property to each item
109
- const addCheckedAndParentProperty = (
110
- treeData: { [key: string]: any }[],
111
- parent_id: string = null,
112
- depth: number = 0,
113
- ) => {
114
- if (!Array.isArray(treeData)) {
115
- return;
116
- }
117
- return treeData.map((item: { [key: string]: any } | any) => {
118
- const newItem = {
119
- ...item,
120
- parent_id,
121
- depth,
122
- };
123
- if (newItem.children && newItem.children.length > 0) {
124
- newItem.children = addCheckedAndParentProperty(
125
- newItem.children,
126
- newItem.id,
127
- depth + 1,
128
- );
129
- }
130
- return newItem;
131
- });
132
- };
133
-
134
- //click event for x on form pill
135
- const handlePillClose = (event: any, clickedItem: { [key: string]: any }) => {
136
- // prevents the dropdown from closing when clicking on the pill
137
- event.stopPropagation();
138
- //logic for removing items from returnArray or defaultReturn when pills clicked
139
- if (returnAllSelected) {
140
- if (returnedArray.includes(clickedItem)) {
141
- if (clickedItem.children && clickedItem.children.length > 0) {
142
- const childrenOfChecked = getChildIds(clickedItem, returnedArray);
143
- const updatedFiltered = returnedArray
144
- .filter((item) => item !== clickedItem)
145
- .filter((item) => !childrenOfChecked.includes(item.id));
146
- setReturnedArray(updatedFiltered);
40
+ const [selectedItems, setSelectedItems] = useState([]);
41
+ const [checkedData, setCheckedData] = useState([]);
42
+
43
+ const onChange = (currentNode: { [key: string]: any }) => {
44
+ console.log("currentNode", currentNode)
45
+ const updatedData = formattedData.map((item: any) => {
46
+ if (item.id === currentNode._id) {
47
+ console.log("GETTING HERE --------- item", item)
48
+ if (currentNode.checked) {
49
+ console.log("GETTING HERE --------- currentNode.checked", currentNode.checked)
50
+ checkIt(item, selectedItems, setSelectedItems, false);
147
51
  } else {
148
- const updatedFiltered = returnedArray.filter(
149
- (item) => item !== clickedItem
150
- );
151
- setReturnedArray(updatedFiltered);
52
+ unCheckIt(item, selectedItems, setSelectedItems, false);
53
+ }
54
+ } else if (item.children) {
55
+ console.log("GETTING HERE --------- item.children", item.children)
56
+ const foundItem = findItemById(item.children, currentNode._id);
57
+ if (foundItem) {
58
+ console.log("GETTING HERE --------- foundItem", foundItem)
59
+ if (currentNode.checked) {
60
+ console.log("GETTING HERE --------- currentNode.checked other one", currentNode.checked)
61
+ checkIt(foundItem, selectedItems, setSelectedItems, false);
62
+ if (currentNode._parent) {
63
+ const parents = getParentAndAncestorsIds(currentNode._parent, formattedData)
64
+ parents.forEach((item:string) => {
65
+ const ancestor = findItemById(formattedData,item)
66
+ ancestor.expanded = true
67
+ });
68
+ }
69
+ } else {
70
+ unCheckIt(foundItem, selectedItems, setSelectedItems, false);
71
+ if (currentNode._parent) {
72
+ const parents = getParentAndAncestorsIds(currentNode._parent, formattedData)
73
+ parents.forEach((item:string) => {
74
+ const ancestor = findItemById(formattedData,item)
75
+ ancestor.expanded = true
76
+ });
77
+ }
78
+ }
152
79
  }
153
80
  }
154
- } else {
155
- if (defaultReturn.includes(clickedItem)) {
156
- getAncestorsOfUnchecked(formattedData, clickedItem);
157
- const newChecked = getCheckedItems(formattedData);
158
- const filteredReturn = updateReturnItems(newChecked).filter(
159
- (item) => item.id !== clickedItem.id
160
- );
161
- setDefaultReturn(filteredReturn);
162
- }
163
- }
164
- if (clickedItem.children && clickedItem.children.length > 0) {
165
- unCheckedRecursive(clickedItem);
166
- }
167
- //logic to uncheck clickedItem in formattedData
168
- unCheckIt(formattedData, clickedItem.id);
169
- };
170
81
 
171
- //handle click on input wrapper(entire div with pills, typeahead, etc) so it doesn't close when input or form pill is clicked
172
- const handleInputWrapperClick = (e: any) => {
173
- e.stopPropagation();
174
- if (
175
- e.target.id === "multiselect_input" ||
176
- e.target.classList.contains("pb_form_pill_tag")
177
- ) {
178
- return;
179
- }
180
- setIsClosed(!isClosed);
82
+ return item;
83
+ });
84
+ console.log("updatedData", updatedData)
85
+ setFormattedData(updatedData);
181
86
  };
182
87
 
183
- //Main function to handle any click inside dropdown
184
- const handledropdownItemClick = (e: any) => {
185
- const clickedItem = e.target.parentNode.id;
186
- //setting filterItem to "" will clear textinput and clear typeahead
187
- setFilterItem("");
188
-
189
- const filtered = filterFormattedDataById(formattedData, clickedItem);
190
- //check and uncheck all children of checked/unchecked parent item
191
- if (filtered[0].children && filtered[0].children.length > 0) {
192
- if (filtered[0].checked) {
193
- filtered[0].children.forEach((item: { [key: string]: any }) => {
194
- checkedRecursive(item);
195
- });
196
- } else if (!filtered[0].checked) {
197
- filtered[0].children.forEach((item: { [key: string]: any }) => {
198
- unCheckedRecursive(item);
199
- });
200
- }
201
- }
202
-
203
- const checkedItems = getCheckedItems(formattedData);
204
-
205
- //checking and unchecking items for returnAllSelected variant
206
- if (returnedArray.includes(filtered[0])) {
207
- if (!filtered[0].checked) {
208
- if (filtered[0].children && filtered[0].children.length > 0) {
209
- const childrenOfChecked = getChildIds(filtered[0], returnedArray);
210
- const updatedFiltered = returnedArray
211
- .filter((item) => item !== filtered[0])
212
- .filter((item) => !childrenOfChecked.includes(item.id));
213
-
214
- setReturnedArray(updatedFiltered);
215
- } else {
216
- const updatedFiltered = returnedArray.filter(
217
- (item) => item !== filtered[0]
218
- );
219
- setReturnedArray(updatedFiltered);
220
- }
221
- }
222
- } else {
223
- setReturnedArray(checkedItems);
88
+ const updateHiddenInputValue = (value: any) => {
89
+ const hiddenInput = document.querySelector('input#'+id) as HTMLInputElement;
90
+ if (hiddenInput) {
91
+ hiddenInput.value = JSON.stringify(value);
224
92
  }
93
+ };
225
94
 
226
- //when item is unchecked for default variant
227
- if (!filtered[0].checked && !returnAllSelected) {
228
- //uncheck parent and grandparent if any child unchecked
229
- getAncestorsOfUnchecked(formattedData, filtered[0]);
230
95
 
231
- const newChecked = getCheckedItems(formattedData);
232
- //get all checked items, and filter to check if all children checked, if yes return only parent
233
- const filteredReturn = updateReturnItems(newChecked);
234
- setDefaultReturn(filteredReturn);
96
+ useEffect(() => {
97
+ if (returnAllSelected) {
98
+ const selected = selectedItems.filter(
99
+ (item: { [key: string]: any }) => item.checked
100
+ );
101
+ //filter to remove duplicate items
102
+ const uniqueSelected = selected.filter(
103
+ (obj, index, self) => index === self.findIndex((t) => t.id === obj.id)
104
+ );
105
+ setCheckedData(uniqueSelected);
235
106
  }
107
+ }, [selectedItems]);
236
108
 
237
- //when item is checked for default variant
238
- if (!returnAllSelected && filtered[0].checked) {
239
- //if checked item has children
240
- if (filtered[0].children && filtered[0].children.length > 0) {
241
- removeChildrenIfParentChecked(
242
- filtered[0],
243
- defaultReturn,
244
- setDefaultReturn
245
- );
246
- }
247
-
248
- //if clicked item has parent_id, find parent and check if all children checked or not
249
- if (filtered[0].parent_id !== null) {
250
- recursiveReturnOnlyParent(
251
- filtered[0],
252
- formattedData,
253
- defaultReturn,
254
- setDefaultReturn
255
- );
256
- } else {
257
- setDefaultReturn([filtered[0]]);
258
- }
109
+ useEffect(() => {
110
+ let el = document.getElementById(`pb_data_wrapper_${id}`);
111
+ if (el) {
112
+ el.setAttribute("data-tree", JSON.stringify(checkedData));
259
113
  }
260
- };
261
-
262
- //handle click on chevron toggles in dropdown
263
- const handleToggleClick = (id: string, event: React.MouseEvent) => {
264
- event.stopPropagation();
265
- setIsToggled((prevState: { [id: string]: boolean }) => ({
266
- ...prevState,
267
- [id]: !prevState[id],
268
- }));
269
- const clickedItem = filterFormattedDataById(formattedData, id);
270
-
271
- if (clickedItem) {
272
- clickedItem[0].expanded = !clickedItem[0].expanded;
114
+ updateHiddenInputValue(checkedData);
115
+ if (returnAllSelected) {
116
+ onSelect(checkedData);
273
117
  }
274
- };
118
+ }, [checkedData]);
275
119
 
276
- //rendering formattedData to UI based on typeahead
277
- const renderNestedOptions = (items: { [key: string]: any }[]) => {
120
+ const DropDownSelectComponent = useMemo(() => {
278
121
  return (
279
- <ul>
280
- {Array.isArray(items) &&
281
- items.map((item: { [key: string]: any }) => {
282
- return (
283
- <>
284
- <li
285
- key={item.id}
286
- className="dropdown_item"
287
- data-name={item.id}
288
- >
289
- <div className="dropdown_item_checkbox_row">
290
- <div
291
- key={
292
- item.expanded ? "chevron-down" : "chevron-right"
293
- }
294
- >
295
- <CircleIconButton
296
- icon={
297
- item.expanded ? "chevron-down" : "chevron-right"
298
- }
299
- className={item.children && item.children.length > 0 ? "" : "toggle_icon"}
300
- onClick={(event) => handleToggleClick(item.id, event)}
301
- variant="link"
302
- />
303
- </div>
304
- <Checkbox text={item.label} id={item.id}>
305
- <input
306
- checked={item.checked}
307
- type="checkbox"
308
- name={item.label}
309
- value={item.label}
310
- onChange={(e) => {
311
- item.checked = !item.checked;
312
- handledropdownItemClick(e);
313
- }}
314
- />
315
- </Checkbox>
316
- </div>
317
- {item.expanded &&
318
- item.children &&
319
- item.children.length > 0 &&
320
- !filterItem && ( // Show children if expanded is true
321
- <div>{renderNestedOptions(item.children)}</div>
322
- )}
323
- </li>
324
- </>
325
- );
326
- })}
327
- </ul>
122
+ <MultiSelectHelper
123
+ treeData={formattedData}
124
+ onChange={(
125
+ // @ts-ignore
126
+ selectedNodes: { [key: string]: any }[],
127
+ currentNode: { [key: string]: any }[]
128
+ ) => {
129
+ setCheckedData(currentNode);
130
+ onSelect(currentNode);
131
+
132
+ }}
133
+ id={id}
134
+ {...props}
135
+ />
328
136
  );
329
- };
137
+ }, [formattedData])
330
138
 
331
139
  return (
332
140
  <div {...ariaProps} {...dataProps} className={classes} id={id}>
333
- <div ref={dropdownRef} className="wrapper">
334
- <div className="input_wrapper" onClick={handleInputWrapperClick}>
335
- <div className="input_inner_container">
336
- {returnedArray.length !== 0 && returnAllSelected
337
- ? returnedArray.map((item, index) => (
338
- <FormPill
339
- key={index}
340
- text={item.label}
341
- size="small"
342
- onClick={(event) => handlePillClose(event, item)}
343
- />
344
- ))
345
- : null}
346
- {!returnAllSelected &&
347
- defaultReturn.length !== 0 &&
348
- defaultReturn
349
- .filter(
350
- (item, index, self) =>
351
- index === self.findIndex((obj) => obj.id === item.id)
352
- )
353
- .map((item, index) => (
354
- <FormPill
355
- key={index}
356
- text={item.label}
357
- size="small"
358
- onClick={(event) => handlePillClose(event, item)}
359
- />
360
- ))}
361
- {returnedArray.length !== 0 && returnAllSelected && <br />}
362
- {defaultReturn.length !== 0 && !returnAllSelected && <br />}
363
- <input
364
- id="multiselect_input"
365
- onChange={(e) => {
366
- setFilterItem(e.target.value);
367
- }}
368
- placeholder="Start typing..."
369
- value={filterItem}
370
- onClick={() => setIsClosed(false)}
371
- />
372
- </div>
373
- {isClosed ? (
374
- <div key="chevron-down">
375
- <Icon icon="chevron-down" />
376
- </div>
377
- ) : (
378
- <div key="chevron-up">
379
- <Icon icon="chevron-up" />
380
- </div>
381
- )}
382
- </div>
383
- <div className={`dropdown_menu ${isClosed ? "close" : "open"}`}>
384
- {renderNestedOptions(
385
- filterItem ? findByFilter(formattedData, filterItem) : formattedData
386
- )}
387
- </div>
388
- </div>
141
+
142
+ <input type="hidden" id={id} name={name} value="" />
143
+ {returnAllSelected ? (
144
+ <MultiSelectHelper
145
+ treeData={formattedData}
146
+ treeMode={returnAllSelected}
147
+ id={id}
148
+ onChange={onChange}
149
+ {...props}
150
+ />
151
+ ) : (
152
+ <>{DropDownSelectComponent}</>
153
+ )}
389
154
  </div>
390
155
  );
391
156
  };
@@ -0,0 +1,31 @@
1
+ import React from "react"
2
+ import DropdownTreeSelect from "react-dropdown-tree-select"
3
+ import "react-dropdown-tree-select/dist/styles.css"
4
+
5
+ type HelperProps = {
6
+ id?: string
7
+ treeData?: { [key: string]: string }[]
8
+ treeMode?: boolean
9
+ onChange?: any
10
+
11
+ }
12
+
13
+ const MultiSelectHelper = (props: HelperProps) => {
14
+ const { id, treeData, onChange, treeMode } = props
15
+
16
+
17
+ return (
18
+ <DropdownTreeSelect
19
+ data={treeData}
20
+ id={id}
21
+ keepOpenOnSelect
22
+ keepTreeOnSearch
23
+ keepChildrenOnSearch
24
+ onChange={onChange}
25
+ texts={{ placeholder: "Select..." }}
26
+ mode={treeMode ? 'hierarchical' : 'multiSelect'}
27
+ />
28
+ )
29
+ }
30
+
31
+ export default MultiSelectHelper
@@ -64,9 +64,9 @@
64
64
  }] %>
65
65
 
66
66
 
67
- <%= pb_rails("multi_level_select", props: {
68
- id: "default-multi-level-select",
69
- tree_data:treeData
70
- }) %>
67
+ <%= pb_rails("multi_level_select", props: {
68
+ id: "default-multi-level-select",
69
+ tree_data:treeData
70
+ }) %>
71
71
 
72
72
 
@@ -2,4 +2,4 @@ The MultiLevelSelect kit renders a multi leveled select dropdown based on data f
2
2
 
3
3
  For the React version of the kit, the `onSelect` prop returns an array of all checked items, irrespective of whether it is a parent, child or grandchild. Open the console on this example and check and uncheck checkboxes to see this is action!
4
4
 
5
- For the Rails version, the array of checked items is attached to the DOM in a data attribute titled `data-tree` on the wrapping div around the MultiLevelSelect.
5
+ For the Rails version, the array of checked items is attached to the DOM in a data attribute titled `data-tree` on the wrapping div around the MultiLevelSelect.
@@ -3,7 +3,6 @@
3
3
  value: "Power Home Remodeling",
4
4
  id: "powerhome1",
5
5
  expanded: true,
6
-
7
6
  children: [
8
7
  {
9
8
  label: "People",
@@ -0,0 +1,72 @@
1
+ <%= pb_form_with(scope: :example, url: "", method: :get) do |form| %>
2
+
3
+ <% treeData = [{
4
+ label: "Power Home Remodeling",
5
+ value: "Power Home Remodeling",
6
+ id: "powerhome1",
7
+ expanded: true,
8
+ children: [
9
+ {
10
+ label: "People",
11
+ value: "People",
12
+ id: "people1",
13
+ children: [
14
+ {
15
+ label: "Talent Acquisition",
16
+ value: "Talent Acquisition",
17
+ id: "talent1",
18
+ },
19
+ {
20
+ label: "Business Affairs",
21
+ value: "Business Affairs",
22
+ id: "business1",
23
+ children: [
24
+ {
25
+ label: "Initiatives",
26
+ value: "Initiatives",
27
+ id: "initiative1",
28
+ },
29
+ {
30
+ label: "Learning & Development",
31
+ value: "Learning & Development",
32
+ id: "development1",
33
+ },
34
+ ],
35
+ },
36
+ {
37
+ label: "People Experience",
38
+ value: "People Experience",
39
+ id: "experience1",
40
+ },
41
+ ],
42
+ },
43
+ {
44
+ label: "Contact Center",
45
+ value: "Contact Center",
46
+ id: "contact1",
47
+ children: [
48
+ {
49
+ label: "Appointment Management",
50
+ value: "Appointment Management",
51
+ id: "appointment1",
52
+ },
53
+ {
54
+ label: "Customer Service",
55
+ value: "Customer Service",
56
+ id: "customer1",
57
+ },
58
+ {
59
+ label: "Energy",
60
+ value: "Energy",
61
+ id: "energy1",
62
+ },
63
+ ],
64
+ },
65
+ ],
66
+ }] %>
67
+
68
+ <%= form.multi_level_select :example, props: {id: "with-form-multi-level-select", tree_data: treeData, return_all_selected: true } %>
69
+ <%= form.actions do |action| %>
70
+ <%= action.button props: { type: "submit", text: "Submit", variant: "primary", margin_top: "lg" } %>
71
+ <% end %>
72
+ <% end %>
@@ -2,6 +2,7 @@ examples:
2
2
  rails:
3
3
  - multi_level_select_default: Default
4
4
  - multi_level_select_return_all_selected: Return All Selected
5
+ - multi_level_select_with_form: With Form
5
6
 
6
7
  react:
7
8
  - multi_level_select_default: Default