playbook_ui 14.5.0.pre.alpha.PLAY1510railsformloading3977 → 14.5.0.pre.alpha.PLAY1548intltelinputupdatelatest4028

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_loading.html.erb +7 -30
  3. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_loading.md +2 -0
  4. data/app/pb_kits/playbook/pb_form/docs/example.yml +0 -1
  5. data/app/pb_kits/playbook/pb_form/form.rb +0 -2
  6. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +195 -228
  7. data/app/pb_kits/playbook/pb_multi_level_select/context/index.tsx +5 -0
  8. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_default.jsx +1 -1
  9. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_with_children.jsx +105 -0
  10. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_with_children.md +1 -0
  11. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_with_children_with_radios.jsx +106 -0
  12. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_with_children_with_radios.md +1 -0
  13. data/app/pb_kits/playbook/pb_multi_level_select/docs/example.yml +3 -0
  14. data/app/pb_kits/playbook/pb_multi_level_select/docs/index.js +2 -0
  15. data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select_options.tsx +149 -0
  16. data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.scss +45 -11
  17. data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +6 -4
  18. data/dist/chunks/_typeahead-BgSfpf21.js +22 -0
  19. data/dist/chunks/{_weekday_stacked-DnNh3oJT.js → _weekday_stacked-CU-r3k4h.js} +1 -1
  20. data/dist/chunks/{lib-C9Somihj.js → lib-CEpcaI8y.js} +1 -1
  21. data/dist/chunks/{pb_form_validation-C8U7gqcT.js → pb_form_validation-D9zkwt2b.js} +1 -1
  22. data/dist/chunks/vendor.js +1 -1
  23. data/dist/playbook-doc.js +1 -1
  24. data/dist/playbook-rails-react-bindings.js +1 -1
  25. data/dist/playbook-rails.js +1 -1
  26. data/dist/playbook.css +1 -1
  27. data/lib/playbook/pb_forms_helper.rb +1 -3
  28. data/lib/playbook/version.rb +1 -1
  29. metadata +12 -9
  30. data/app/pb_kits/playbook/pb_form/docs/_form_form_with_loading.html.erb +0 -8
  31. data/app/pb_kits/playbook/pb_form/docs/_form_form_with_loading.md +0 -1
  32. data/app/pb_kits/playbook/pb_form/formHelper.js +0 -39
  33. data/dist/chunks/_typeahead-CbSMQAjp.js +0 -22
@@ -0,0 +1,105 @@
1
+ import React from "react";
2
+ import MultiLevelSelect from "../_multi_level_select";
3
+ import Badge from "../../pb_badge/_badge";
4
+
5
+ const treeData = [
6
+ {
7
+ label: "Power Home Remodeling",
8
+ value: "Power Home Remodeling",
9
+ id: "powerhome1",
10
+ expanded: true,
11
+ children: [
12
+ {
13
+ label: "People",
14
+ value: "People",
15
+ id: "people1",
16
+ expanded: true,
17
+ status: "active",
18
+ children: [
19
+ {
20
+ label: "Talent Acquisition",
21
+ value: "Talent Acquisition",
22
+ id: "talent1",
23
+ },
24
+ {
25
+ label: "Business Affairs",
26
+ value: "Business Affairs",
27
+ id: "business1",
28
+ status: "active",
29
+ variant: "primary",
30
+
31
+ children: [
32
+ {
33
+ label: "Initiatives",
34
+ value: "Initiatives",
35
+ id: "initiative1",
36
+ },
37
+ {
38
+ label: "Learning & Development",
39
+ value: "Learning & Development",
40
+ id: "development1",
41
+ status: "Inactive",
42
+ },
43
+ ],
44
+ },
45
+ {
46
+ label: "People Experience",
47
+ value: "People Experience",
48
+ id: "experience1",
49
+ },
50
+ ],
51
+ },
52
+ {
53
+ label: "Contact Center",
54
+ value: "Contact Center",
55
+ id: "contact1",
56
+ status: "Inactive",
57
+ variant: "error",
58
+ children: [
59
+ {
60
+ label: "Appointment Management",
61
+ value: "Appointment Management",
62
+ id: "appointment1",
63
+ },
64
+ {
65
+ label: "Customer Service",
66
+ value: "Customer Service",
67
+ id: "customer1",
68
+ },
69
+ {
70
+ label: "Energy",
71
+ value: "Energy",
72
+ id: "energy1",
73
+ },
74
+ ],
75
+ },
76
+ ],
77
+ },
78
+ ];
79
+
80
+ const MultiLevelSelectWithChildren = (props) => {
81
+ return (
82
+ <div>
83
+ <MultiLevelSelect
84
+ id="multiselect-with-children"
85
+ onSelect={(selectedNodes) =>
86
+ console.log("Selected Items", selectedNodes)
87
+ }
88
+ treeData={treeData}
89
+ {...props}
90
+ >
91
+ <MultiLevelSelect.Options>
92
+ {(item) => (
93
+ <Badge
94
+ marginLeft="sm"
95
+ text={item.status}
96
+ variant={item.status === "active" ? "success" : "warning"}
97
+ />
98
+ )}
99
+ </MultiLevelSelect.Options>
100
+ </MultiLevelSelect>
101
+ </div>
102
+ );
103
+ };
104
+
105
+ export default MultiLevelSelectWithChildren;
@@ -0,0 +1 @@
1
+ The MultiLevelSelect also provides a subcomponent structure which can be used to render children to the right of the Checkboxes and their labels. As seen in the code snippet below, these children have access to the current item being iterated over which can be used for conditional rendering.
@@ -0,0 +1,106 @@
1
+ import React from "react";
2
+ import MultiLevelSelect from "../_multi_level_select";
3
+ import Badge from "../../pb_badge/_badge";
4
+
5
+ const treeData = [
6
+ {
7
+ label: "Power Home Remodeling",
8
+ value: "Power Home Remodeling",
9
+ id: "powerhome1",
10
+ expanded: true,
11
+ children: [
12
+ {
13
+ label: "People",
14
+ value: "People",
15
+ id: "people1",
16
+ expanded: true,
17
+ status: "active",
18
+ children: [
19
+ {
20
+ label: "Talent Acquisition",
21
+ value: "Talent Acquisition",
22
+ id: "talent1",
23
+ },
24
+ {
25
+ label: "Business Affairs",
26
+ value: "Business Affairs",
27
+ id: "business1",
28
+ status: "active",
29
+ variant: "primary",
30
+
31
+ children: [
32
+ {
33
+ label: "Initiatives",
34
+ value: "Initiatives",
35
+ id: "initiative1",
36
+ },
37
+ {
38
+ label: "Learning & Development",
39
+ value: "Learning & Development",
40
+ id: "development1",
41
+ status: "Inactive",
42
+ },
43
+ ],
44
+ },
45
+ {
46
+ label: "People Experience",
47
+ value: "People Experience",
48
+ id: "experience1",
49
+ },
50
+ ],
51
+ },
52
+ {
53
+ label: "Contact Center",
54
+ value: "Contact Center",
55
+ id: "contact1",
56
+ status: "Inactive",
57
+ variant: "error",
58
+ children: [
59
+ {
60
+ label: "Appointment Management",
61
+ value: "Appointment Management",
62
+ id: "appointment1",
63
+ },
64
+ {
65
+ label: "Customer Service",
66
+ value: "Customer Service",
67
+ id: "customer1",
68
+ },
69
+ {
70
+ label: "Energy",
71
+ value: "Energy",
72
+ id: "energy1",
73
+ },
74
+ ],
75
+ },
76
+ ],
77
+ },
78
+ ];
79
+
80
+ const MultiLevelSelectWithChildrenWithRadios = (props) => {
81
+ return (
82
+ <div>
83
+ <MultiLevelSelect
84
+ id="multiselect-with-children"
85
+ onSelect={(selectedNodes) =>
86
+ console.log("Selected Items", selectedNodes)
87
+ }
88
+ treeData={treeData}
89
+ variant="single"
90
+ {...props}
91
+ >
92
+ <MultiLevelSelect.Options>
93
+ {(item) => (
94
+ <Badge
95
+ marginLeft="sm"
96
+ text={item.status}
97
+ variant={item.status === "active" ? "success" : "warning"}
98
+ />
99
+ )}
100
+ </MultiLevelSelect.Options>
101
+ </MultiLevelSelect>
102
+ </div>
103
+ );
104
+ };
105
+
106
+ export default MultiLevelSelectWithChildrenWithRadios;
@@ -0,0 +1 @@
1
+ The MultiLevelSelect subcomponent structure is also available in the 'Single Select' variant. In this variant, the children will be rendered to the right of the Radios and their labels.
@@ -15,3 +15,6 @@ examples:
15
15
  - multi_level_select_return_all_selected: Return All Selected
16
16
  - multi_level_select_selected_ids_react: Selected Ids
17
17
  - multi_level_select_color: With Pills (Custom Color)
18
+ - multi_level_select_with_children: Checkboxes With Children
19
+ - multi_level_select_with_children_with_radios: Single Select With Children
20
+
@@ -4,3 +4,5 @@ export { default as MultiLevelSelectSingleChildrenOnly } from './_multi_level_se
4
4
  export { default as MultiLevelSelectReturnAllSelected } from './_multi_level_select_return_all_selected.jsx'
5
5
  export { default as MultiLevelSelectSelectedIdsReact } from "./_multi_level_select_selected_ids_react.jsx"
6
6
  export { default as MultiLevelSelectColor } from './_multi_level_select_color.jsx'
7
+ export { default as MultiLevelSelectWithChildren } from './_multi_level_select_with_children.jsx'
8
+ export { default as MultiLevelSelectWithChildrenWithRadios } from './_multi_level_select_with_children_with_radios.jsx'
@@ -0,0 +1,149 @@
1
+ import React, {useContext} from "react";
2
+ import classnames from "classnames";
3
+ import MultiLevelSelectContext from "./context";
4
+ import { globalProps, GlobalProps } from "../utilities/globalProps";
5
+ import {
6
+ buildAriaProps,
7
+ buildCss,
8
+ buildDataProps,
9
+ buildHtmlProps,
10
+ } from "../utilities/props";
11
+ import Checkbox from "../pb_checkbox/_checkbox";
12
+ import Radio from "../pb_radio/_radio";
13
+ import CircleIconButton from "../pb_circle_icon_button/_circle_icon_button";
14
+ import Body from "../pb_body/_body";
15
+
16
+ type MultiLevelSelectOptionsProps = {
17
+ aria?: { [key: string]: string },
18
+ children?: React.ReactNode | ((item: any) => React.ReactNode),
19
+ className?: string,
20
+ dark?: boolean,
21
+ data?: { [key: string]: string },
22
+ htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
23
+ } & GlobalProps;
24
+
25
+ const MultiLevelSelectOptions = ({
26
+ children,
27
+ items,
28
+ ...props
29
+ }: MultiLevelSelectOptionsProps) => {
30
+ const {
31
+ variant,
32
+ inputName,
33
+ renderNestedOptions,
34
+ isTreeRowExpanded,
35
+ handleToggleClick,
36
+ handleRadioButtonClick,
37
+ handledropdownItemClick,
38
+ filterItem,
39
+ } = useContext(MultiLevelSelectContext)
40
+
41
+ const {
42
+ aria = {},
43
+ className,
44
+ data = {},
45
+ htmlOptions = {},
46
+ } = props;
47
+
48
+ const ariaProps = buildAriaProps(aria);
49
+ const dataProps = buildDataProps(data);
50
+ const htmlProps = buildHtmlProps(htmlOptions);
51
+ const classes = classnames(
52
+ buildCss("pb_multi_level_select_options"),
53
+ globalProps(props),
54
+ className
55
+ );
56
+
57
+ return (
58
+ <ul
59
+ {...ariaProps}
60
+ {...dataProps}
61
+ {...htmlProps}
62
+ className={classes}
63
+ >
64
+ {Array.isArray(items) &&
65
+ items.map((item: { [key: string]: any }) => {
66
+ return (
67
+ <div key={item.id}>
68
+ <li className={"dropdown_item"}
69
+ data-name={item.id}
70
+ >
71
+ <div className="dropdown_item_checkbox_row">
72
+ {!item.parent_id && !item.children ? null : (
73
+ <div
74
+ key={
75
+ isTreeRowExpanded(item)
76
+ ? "chevron-down"
77
+ : "chevron-right"
78
+ }
79
+ >
80
+ <CircleIconButton
81
+ className={
82
+ item.children && item.children.length > 0
83
+ ? ""
84
+ : "toggle_icon"
85
+ }
86
+ icon={
87
+ isTreeRowExpanded(item)
88
+ ? "chevron-down"
89
+ : "chevron-right"
90
+ }
91
+ onClick={(event: React.MouseEvent) =>
92
+ handleToggleClick(item.id, event)
93
+ }
94
+ variant="link"
95
+ />
96
+ </div>
97
+ )}
98
+ {variant === "single" ? (
99
+ item.hideRadio ? (
100
+ <Body>{item.label}</Body>
101
+ ) : (
102
+ <Radio
103
+ checked={item.checked}
104
+ id={`${item.id}-${item.label}`}
105
+ label={item.label}
106
+ name={inputName}
107
+ onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
108
+ handleRadioButtonClick(e)
109
+ }
110
+ padding={item.children ? "none" : "xs"}
111
+ type="radio"
112
+ value={item.label}
113
+ />
114
+ )
115
+ ) : (
116
+ <Checkbox id={item.id}
117
+ text={item.label}
118
+ >
119
+ <input
120
+ checked={item.checked}
121
+ name={item.label}
122
+ onChange={(e) => {
123
+ handledropdownItemClick(e, !item.checked);
124
+ }}
125
+ type="checkbox"
126
+ value={item.label}
127
+ />
128
+ </Checkbox>
129
+ )}
130
+ {/* Render children next to the checkbox */}
131
+ {children && (
132
+ typeof children === "function" ? children(item) : children
133
+ )}
134
+ </div>
135
+ {isTreeRowExpanded(item) &&
136
+ item.children &&
137
+ item.children.length > 0 &&
138
+ (variant === "single" || !filterItem) && (
139
+ <div>{renderNestedOptions(item.children)}</div>
140
+ )}
141
+ </li>
142
+ </div>
143
+ );
144
+ })}
145
+ </ul>
146
+ );
147
+ };
148
+
149
+ export default MultiLevelSelectOptions;
@@ -6,6 +6,18 @@ $dropdown-min-width: 340px;
6
6
  $flag-min-resolution: 192dpi;
7
7
 
8
8
  .pb_phone_number_input {
9
+ .iti {
10
+ width: 100%;
11
+ }
12
+
13
+ .iti__flag {
14
+ margin-right: 6px;
15
+ }
16
+
17
+ .iti__a11y-text {
18
+ display: none;
19
+ }
20
+
9
21
  input::placeholder {
10
22
  color: $focus_input_light;
11
23
  }
@@ -15,7 +27,7 @@ $flag-min-resolution: 192dpi;
15
27
  border-color: $primary !important;
16
28
  }
17
29
 
18
- .iti__selected-flag:focus-visible {
30
+ .iti__selected-country:focus-visible {
19
31
  outline-style: none;
20
32
  }
21
33
  }
@@ -29,7 +41,23 @@ $flag-min-resolution: 192dpi;
29
41
  border-bottom: 1px solid $border_light !important;
30
42
  }
31
43
 
32
- .iti__selected-flag {
44
+ .iti__selected-country-primary {
45
+ display: flex;
46
+ justify-content: center;
47
+ align-items: center;
48
+ margin-right: 10px;
49
+ }
50
+
51
+ .iti__selected-country {
52
+ position: absolute;
53
+ z-index: 2;
54
+ top: 0;
55
+ display: flex;
56
+ height: 100%;
57
+ justify-content: center;
58
+ align-items: center;
59
+ border-width: 0;
60
+
33
61
  padding: 0 $space_xxs 0 $space_sm;
34
62
  border-radius: $space_xxs;
35
63
 
@@ -51,11 +79,11 @@ $flag-min-resolution: 192dpi;
51
79
  }
52
80
  }
53
81
 
54
- .iti--allow-dropdown .iti__flag-container:hover .iti__selected-flag {
82
+ .iti--allow-dropdown .iti__country-container:hover .iti__selected-country {
55
83
  background-color: $focus_input_light;
56
84
  }
57
85
 
58
- .iti__flag-container:hover + .text_input {
86
+ .iti__country-container:hover + .text_input {
59
87
  background-color: $focus_input_light;
60
88
  }
61
89
 
@@ -64,11 +92,14 @@ $flag-min-resolution: 192dpi;
64
92
  border-radius: 1px;
65
93
  }
66
94
 
67
- .iti--separate-dial-code {
68
- width: 100%;
95
+ .iti__flag.iti__globe {
96
+ background-image: url("https://unpkg.com/intl-tel-input@21.1.4/build/img/globe.png");
97
+ background-position: center;
98
+ height: 20px;
99
+ background-size: 20px 20px;
69
100
  }
70
101
 
71
- .iti--separate-dial-code .iti__selected-flag {
102
+ .iti--show-flags .iti__selected-country {
72
103
  background-color: rgba($white, $opacity_1);
73
104
  }
74
105
 
@@ -95,7 +126,7 @@ $flag-min-resolution: 192dpi;
95
126
  position: relative;
96
127
  vertical-align: top;
97
128
  width: $space_xxs + 1px;
98
- top: $space_xs + 2px;
129
+ top: $space_xs - 1px;
99
130
  transform: rotate($transform-rotate-deg);
100
131
  color: $slate;
101
132
  }
@@ -136,10 +167,13 @@ $flag-min-resolution: 192dpi;
136
167
  .iti__dropdown-content {
137
168
  border-radius: $space_xs;
138
169
  border: 1px solid $border_light !important;
170
+ position: absolute;
171
+ z-index: 2;
172
+ top: 100%;
139
173
  }
140
174
 
141
175
  &.dark {
142
- .iti--allow-dropdown .iti__flag-container {
176
+ .iti--allow-dropdown .iti__country-container {
143
177
  background-color: rgba($white, 0);
144
178
 
145
179
  &:hover {
@@ -149,13 +183,13 @@ $flag-min-resolution: 192dpi;
149
183
  background-color: rgba($white, 0.15);
150
184
  }
151
185
 
152
- .iti__selected-flag {
186
+ .iti__selected-country {
153
187
  background-color: rgba($white, 0);
154
188
  }
155
189
  }
156
190
  }
157
191
 
158
- .iti__selected-flag {
192
+ .iti__selected-country {
159
193
  background-color: rgba($white, 0);
160
194
  color: $white;
161
195
  }
@@ -1,7 +1,7 @@
1
1
  import React, { forwardRef, useEffect, useRef, useState, useImperativeHandle } from 'react'
2
2
  import classnames from 'classnames'
3
3
 
4
- import intlTelInput from 'intl-tel-input'
4
+ import intlTelInput from 'intl-tel-input/intlTelInputWithUtils'
5
5
  import 'intl-tel-input/build/js/utils.js'
6
6
 
7
7
  import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
@@ -50,7 +50,7 @@ const formatToGlobalCountryName = (countryName: string) => {
50
50
  }
51
51
 
52
52
  const formatAllCountries = () => {
53
- const countryData = window.intlTelInputGlobals.getCountryData()
53
+ const countryData = intlTelInput.getCountryData()
54
54
 
55
55
  for (let i = 0; i < countryData.length; i++) {
56
56
  const country = countryData[i]
@@ -217,11 +217,13 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.MutableRefOb
217
217
  useEffect(() => {
218
218
  const telInputInit = intlTelInput(inputRef.current, {
219
219
  separateDialCode: true,
220
- preferredCountries,
220
+ countryOrder: preferredCountries,
221
221
  allowDropdown: !disabled,
222
222
  autoInsertDialCode: false,
223
223
  initialCountry,
224
- onlyCountries
224
+ onlyCountries,
225
+ countrySearch: false,
226
+ fixDropdownWidth: false,
225
227
  })
226
228
 
227
229
  inputRef.current.addEventListener("countrychange", (evt: Event) => {