playbook_ui 14.11.0.pre.rc.12 → 14.11.0.pre.rc.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_beta_subrow_headers.html.erb +1 -1
  3. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_beta_subrow_headers.md +1 -1
  4. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +1 -1
  5. data/app/pb_kits/playbook/pb_advanced_table/index.js +53 -8
  6. data/app/pb_kits/playbook/pb_advanced_table/table_body.rb +23 -18
  7. data/app/pb_kits/playbook/pb_advanced_table/table_row.rb +6 -0
  8. data/app/pb_kits/playbook/pb_advanced_table/table_subrow_header.html.erb +2 -2
  9. data/app/pb_kits/playbook/pb_advanced_table/table_subrow_header.rb +6 -4
  10. data/app/pb_kits/playbook/pb_avatar_action_button/_avatar_action_button.scss +11 -9
  11. data/app/pb_kits/playbook/pb_badge/_badge.scss +4 -2
  12. data/app/pb_kits/playbook/pb_bread_crumbs/_bread_crumbs.scss +3 -1
  13. data/app/pb_kits/playbook/pb_button/_button.scss +3 -1
  14. data/app/pb_kits/playbook/pb_circle_icon_button/_circle_icon_button.scss +4 -2
  15. data/app/pb_kits/playbook/pb_date_picker/sass_partials/_input_styles.scss +3 -1
  16. data/app/pb_kits/playbook/pb_date_picker/sass_partials/_overrides.scss +5 -3
  17. data/app/pb_kits/playbook/pb_date_range_inline/_date_range_inline.scss +6 -4
  18. data/app/pb_kits/playbook/pb_date_time_stacked/_date_time_stacked.scss +4 -2
  19. data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +10 -8
  20. data/app/pb_kits/playbook/pb_form_pill/_form_pill.scss +6 -4
  21. data/app/pb_kits/playbook/pb_icon_circle/_icon_circle.scss +3 -1
  22. data/app/pb_kits/playbook/pb_label_value/_label_value.scss +4 -2
  23. data/app/pb_kits/playbook/pb_message/_message_mixins.scss +3 -1
  24. data/app/pb_kits/playbook/pb_multiple_users/_multiple_users.scss +3 -1
  25. data/app/pb_kits/playbook/pb_passphrase/_passphrase.scss +5 -3
  26. data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.scss +10 -8
  27. data/app/pb_kits/playbook/pb_pill/_pill.scss +4 -2
  28. data/app/pb_kits/playbook/pb_progress_simple/_progress_simple.scss +4 -2
  29. data/app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.scss +4 -2
  30. data/app/pb_kits/playbook/pb_select/_select.scss +5 -3
  31. data/app/pb_kits/playbook/pb_selectable_card/_selectable_card.scss +5 -3
  32. data/app/pb_kits/playbook/pb_text_input/_text_input.scss +3 -1
  33. data/app/pb_kits/playbook/pb_text_input/docs/_text_input_mask.jsx +18 -0
  34. data/app/pb_kits/playbook/pb_text_input/inputMask.ts +22 -1
  35. data/app/pb_kits/playbook/pb_text_input/text_input.test.js +80 -0
  36. data/app/pb_kits/playbook/pb_textarea/_textarea.scss +3 -1
  37. data/app/pb_kits/playbook/pb_time_range_inline/_time_range_inline.scss +5 -4
  38. data/app/pb_kits/playbook/pb_timeline/_timeline.scss +4 -2
  39. data/app/pb_kits/playbook/pb_toggle/_toggle.scss +5 -3
  40. data/dist/chunks/{_typeahead-DhQHv7TA.js → _typeahead-DPsPSYxe.js} +1 -1
  41. data/dist/chunks/{_weekday_stacked-BImEPKQq.js → _weekday_stacked-KhE_lsdt.js} +1 -1
  42. data/dist/chunks/vendor.js +1 -1
  43. data/dist/playbook-doc.js +1 -1
  44. data/dist/playbook-rails-react-bindings.js +1 -1
  45. data/dist/playbook-rails.js +1 -1
  46. data/lib/playbook/version.rb +1 -1
  47. metadata +3 -3
@@ -1,3 +1,5 @@
1
+ @use "sass:math";
2
+
1
3
  @import "./intlTelInput";
2
4
  @import "../tokens/colors";
3
5
 
@@ -39,7 +41,7 @@ $flag-min-resolution: 192dpi;
39
41
  color: $charcoal;
40
42
  }
41
43
 
42
- // iti-spacer-horizontal's default is 8px, or $space_xs
44
+ // iti-spacer-horizontal's default is 8px, or $space_xs
43
45
  .iti__country-list .iti__flag, .iti__country-name {
44
46
  margin-right: $space_xs;
45
47
  }
@@ -73,7 +75,7 @@ $flag-min-resolution: 192dpi;
73
75
  }
74
76
 
75
77
  .iti__divider {
76
- border-bottom: 1px solid $border_light !important;
78
+ border-bottom: 1px solid $border_light !important;
77
79
  }
78
80
 
79
81
  .iti__selected-country-primary {
@@ -93,7 +95,7 @@ $flag-min-resolution: 192dpi;
93
95
  justify-content: center;
94
96
  align-items: center;
95
97
  border-width: 0;
96
- border-radius: $space_xxs;
98
+ border-radius: $space_xxs;
97
99
 
98
100
  &[aria-expanded="true"] {
99
101
  color: $primary_action;
@@ -163,7 +165,7 @@ $flag-min-resolution: 192dpi;
163
165
  }
164
166
 
165
167
  .iti__arrow.iti__arrow--up::before {
166
- transform: rotate(-($transform-rotate-deg/3));
168
+ transform: rotate(-(math.div($transform-rotate-deg, 3)));
167
169
  top: $space_xs + 4px;
168
170
  color: $primary_action;
169
171
  }
@@ -196,7 +198,7 @@ $flag-min-resolution: 192dpi;
196
198
  }
197
199
 
198
200
  .iti__dropdown-content {
199
- border-radius: $space_xs;
201
+ border-radius: $space_xs;
200
202
  border: 1px solid $border_light !important;
201
203
  position: absolute;
202
204
  top: 100%;
@@ -225,12 +227,12 @@ $flag-min-resolution: 192dpi;
225
227
  }
226
228
 
227
229
  .iti__dropdown-content {
228
- border-radius: $space_xs;
230
+ border-radius: $space_xs;
229
231
  border: 1px solid $border_dark !important;
230
232
  }
231
233
 
232
234
  .iti__divider {
233
- border-bottom: 1px solid $border_dark !important;
235
+ border-bottom: 1px solid $border_dark !important;
234
236
  }
235
237
 
236
238
  .iti__country-list {
@@ -265,7 +267,7 @@ $flag-min-resolution: 192dpi;
265
267
  color: $white;
266
268
  }
267
269
  }
268
-
270
+
269
271
  @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: $flag-min-resolution) {
270
272
  .iti__flag {
271
273
  background-image: url("https://unpkg.com/intl-tel-input@24.6.0/build/img/flags@2x.png");
@@ -1,3 +1,5 @@
1
+ @use "sass:math";
2
+
1
3
  @import "../tokens/spacing";
2
4
  @import "../tokens/colors";
3
5
  @import "../tokens/opacity";
@@ -9,9 +11,9 @@ $pb_pill_height: 22px;
9
11
  display: inline-flex;
10
12
  justify-content: center;
11
13
  align-items: center;
12
- padding: 0 $space-sm/1.8;
14
+ padding: 0 math.div($space-sm, 1.8);
13
15
  height: $pb_pill_height;
14
- border-radius: $pb_pill_height/2;
16
+ border-radius: math.div($pb_pill_height, 2);
15
17
  white-space: nowrap;
16
18
 
17
19
  &[class*=lowercase] {
@@ -1,3 +1,5 @@
1
+ @use "sass:math";
2
+
1
3
  @import "../tokens/colors";
2
4
  @import "../tokens/opacity";
3
5
  @import "../tokens/colors";
@@ -21,7 +23,7 @@ $pb_progress_simple_height: 4px;
21
23
  [class^=pb_progress_simple_kit] {
22
24
  width: 100%;
23
25
  height: $pb_progress_simple_height;
24
- border-radius: $pb_progress_simple_height/2;
26
+ border-radius: math.div($pb_progress_simple_height, 2);
25
27
  background: rgba($primary, $opacity-1);
26
28
  &[class*=_positive] {
27
29
  .progress_simple_value {
@@ -42,7 +44,7 @@ $pb_progress_simple_height: 4px;
42
44
  [class^=progress_simple_value] {
43
45
  width: 0%;
44
46
  height: 100%;
45
- border-radius: $pb_progress_simple_height/2;
47
+ border-radius: math.div($pb_progress_simple_height, 2);
46
48
  background: $primary;
47
49
  }
48
50
 
@@ -1,3 +1,5 @@
1
+ @use "sass:math";
2
+
1
3
  @import "../pb_textarea/textarea_mixin";
2
4
  @import "../pb_button/_button_mixins";
3
5
  @import "../tokens/border_radius";
@@ -94,7 +96,7 @@
94
96
  .trix-button--icon {
95
97
  height: $space_lg;
96
98
  width: $space_lg;
97
- margin: $space_xs / 2;
99
+ margin: math.div($space_xs, 2);
98
100
  border-radius: $border_rad_heavier;
99
101
  &::before {
100
102
  background-size: auto;
@@ -104,7 +106,7 @@
104
106
  background: $white;
105
107
  border: 1px solid #E4E8F0;
106
108
  border-bottom: none;
107
- padding: $space_xs / 2;
109
+ padding: math.div($space_xs, 2);
108
110
  border-top-left-radius: $border_rad_heavier;
109
111
  border-top-right-radius: $border_rad_heavier;
110
112
  .trix-button-group {
@@ -1,3 +1,5 @@
1
+ @use "sass:math";
2
+
1
3
  @import "../pb_body/body_mixins";
2
4
  @import "../pb_textarea/textarea_mixin";
3
5
  @import "../tokens/titles";
@@ -81,7 +83,7 @@
81
83
  display: block;
82
84
  &.error {
83
85
  [class*=pb_body_kit] {
84
- margin-top: $space_xs / 2;
86
+ margin-top: math.div($space_xs, 2);
85
87
  }
86
88
  > select:first-child {
87
89
  border-color: $error;
@@ -133,7 +135,7 @@
133
135
  box-shadow: none;
134
136
  border-color: transparent;
135
137
  padding: 4px 8px;
136
- padding-right: $space_lg;
138
+ padding-right: $space_lg;
137
139
  border-radius: 4px;
138
140
  option {
139
141
  background-color: $white;
@@ -240,7 +242,7 @@
240
242
  border-color: transparent;
241
243
  background: transparent;
242
244
  padding: 4px 8px;
243
- padding-right: $space_lg;
245
+ padding-right: $space_lg;
244
246
  border-radius: 4px;
245
247
  option {
246
248
  background-color: $white;
@@ -1,3 +1,5 @@
1
+ @use "sass:math";
2
+
1
3
  @import "../tokens/animation-curves";
2
4
  @import "../tokens/colors";
3
5
  @import "../tokens/opacity";
@@ -60,7 +62,7 @@ $pb_selectable_paddings: (
60
62
  align-items: center;
61
63
  height: $pb_selectable_card_indicator_size;
62
64
  width: $pb_selectable_card_indicator_size;
63
- border-radius: $pb_selectable_card_indicator_size/2 + $pb_selectable_card_border/2;
65
+ border-radius: (math.div($pb_selectable_card_indicator_size, 2)) + (math.div($pb_selectable_card_border, 2));
64
66
  border-width: $pb_selectable_card_border;
65
67
  border-style: solid;
66
68
  border-color: $white;
@@ -69,8 +71,8 @@ $pb_selectable_paddings: (
69
71
  font-size: $font_smaller;
70
72
  text-align: center;
71
73
  position: absolute;
72
- top: -($pb_selectable_card_indicator_size/2);
73
- right: -($pb_selectable_card_indicator_size/2);
74
+ top: -(math.div($pb_selectable_card_indicator_size, 2));
75
+ right: -(math.div($pb_selectable_card_indicator_size, 2));
74
76
  opacity: 0;
75
77
  }
76
78
  }
@@ -1,3 +1,5 @@
1
+ @use "sass:math";
2
+
1
3
  @import "../pb_textarea/textarea_mixin";
2
4
  @import "../tokens/titles";
3
5
  @import "../tokens/colors";
@@ -100,7 +102,7 @@
100
102
  &.error {
101
103
  .text_input_wrapper {
102
104
  [class*="pb_body_kit"] {
103
- margin-top: $space_xs / 2;
105
+ margin-top: math.div($space_xs, 2);
104
106
  }
105
107
  input,
106
108
  .text_input {
@@ -16,6 +16,8 @@ const TextInputMask = (props) => {
16
16
  zipCode: '',
17
17
  postalCode: '',
18
18
  ssn: '',
19
+ creditCard: '',
20
+ cvv: ''
19
21
  })
20
22
 
21
23
  const handleOnChangeFormField = ({ target }) => {
@@ -57,6 +59,22 @@ const TextInputMask = (props) => {
57
59
  value={formFields.ssn}
58
60
  {...props}
59
61
  />
62
+ <TextInput
63
+ label="Credit Card"
64
+ mask="creditCard"
65
+ name="creditCard"
66
+ onChange={handleOnChangeFormField}
67
+ value={formFields.creditCard}
68
+ {...props}
69
+ />
70
+ <TextInput
71
+ label="CVV"
72
+ mask="cvv"
73
+ name="cvv"
74
+ onChange={handleOnChangeFormField}
75
+ value={formFields.cvv}
76
+ {...props}
77
+ />
60
78
 
61
79
  <br />
62
80
  <br />
@@ -6,7 +6,7 @@ type InputMask = {
6
6
  }
7
7
 
8
8
  type InputMaskDictionary = {
9
- [key in 'currency' | 'zipCode' | 'postalCode' | 'ssn']: InputMask
9
+ [key in 'currency' | 'zipCode' | 'postalCode' | 'ssn' | 'creditCard' | 'cvv']: InputMask
10
10
  }
11
11
 
12
12
  const formatCurrencyDefaultValue = (value: string): string => {
@@ -58,6 +58,15 @@ const formatSSN = (value: string): string => {
58
58
  .replace(/(\d{3})(?=\d)/, '$1-')
59
59
  }
60
60
 
61
+ const formatCreditCard = (value: string): string => {
62
+ const cleaned = value.replace(/\D/g, '').slice(0, 16)
63
+ return cleaned.replace(/(\d{4})(?=\d)/g, '$1 ')
64
+ }
65
+
66
+ const formatCVV = (value: string): string => {
67
+ return value.replace(/\D/g, '').slice(0, 4)
68
+ }
69
+
61
70
  export const INPUTMASKS: InputMaskDictionary = {
62
71
  currency: {
63
72
  format: formatCurrency,
@@ -84,4 +93,16 @@ export const INPUTMASKS: InputMaskDictionary = {
84
93
  pattern: '\\d{3}-\\d{2}-\\d{4}',
85
94
  placeholder: '123-45-6789',
86
95
  },
96
+ creditCard: {
97
+ format: formatCreditCard,
98
+ formatDefaultValue: formatCreditCard,
99
+ pattern: '\\d{4} \\d{4} \\d{4} \\d{4}',
100
+ placeholder: '1234 5678 9012 3456',
101
+ },
102
+ cvv: {
103
+ format: formatCVV,
104
+ formatDefaultValue: formatCVV,
105
+ pattern: '\\d{3,4}',
106
+ placeholder: '123',
107
+ },
87
108
  }
@@ -226,3 +226,83 @@ test('returns masked ssn value', () => {
226
226
 
227
227
  expect(input.value).toBe('123-45-6789')
228
228
  })
229
+
230
+ const TextInputCreditCardMask = (props) => {
231
+ const [creditCard, setValue] = useState('')
232
+ const handleOnChange = ({ target }) => {
233
+ setValue(target.value)
234
+ }
235
+
236
+ return (
237
+ <TextInput
238
+ mask="creditCard"
239
+ onChange={handleOnChange}
240
+ value={creditCard}
241
+ {...props}
242
+ />
243
+ )
244
+ }
245
+
246
+ test('returns masked credit card value', () => {
247
+ render(
248
+ <TextInputCreditCardMask
249
+ data={{ testid: testId }}
250
+ />
251
+ )
252
+
253
+ const kit = screen.getByTestId(testId)
254
+
255
+ const input = within(kit).getByRole('textbox')
256
+
257
+ fireEvent.change(input, { target: { value: '1234567890123456' } })
258
+
259
+ expect(input.value).toBe('1234 5678 9012 3456')
260
+
261
+ fireEvent.change(input, { target: { value: '1234' } })
262
+
263
+ expect(input.value).toBe('1234')
264
+
265
+ fireEvent.change(input, { target: { value: '' } })
266
+
267
+ expect(input.value).toBe('')
268
+ })
269
+
270
+ const TextInputCVVMask = (props) => {
271
+ const [cvv, setValue] = useState('')
272
+ const handleOnChange = ({ target }) => {
273
+ setValue(target.value)
274
+ }
275
+
276
+ return (
277
+ <TextInput
278
+ mask="cvv"
279
+ onChange={handleOnChange}
280
+ value={cvv}
281
+ {...props}
282
+ />
283
+ )
284
+ }
285
+
286
+ test('returns masked CVV value', () => {
287
+ render(
288
+ <TextInputCVVMask
289
+ data={{ testid: testId }}
290
+ />
291
+ )
292
+
293
+ const kit = screen.getByTestId(testId)
294
+
295
+ const input = within(kit).getByRole('textbox')
296
+
297
+ fireEvent.change(input, { target: { value: '1234' } })
298
+
299
+ expect(input.value).toBe('1234')
300
+
301
+ fireEvent.change(input, { target: { value: '123' } })
302
+
303
+ expect(input.value).toBe('123')
304
+
305
+ fireEvent.change(input, { target: { value: '' } })
306
+
307
+ expect(input.value).toBe('')
308
+ })
@@ -1,3 +1,5 @@
1
+ @use "sass:math";
2
+
1
3
  @import "../pb_body/body_mixins";
2
4
  @import "./textarea_mixin";
3
5
  @import "../tokens/spacing";
@@ -60,7 +62,7 @@
60
62
 
61
63
  &.error {
62
64
  [class*=pb_body_kit] {
63
- margin-top: $space_xs / 2;
65
+ margin-top: math.div($space_xs, 2);
64
66
  }
65
67
  textarea {
66
68
  border-color: $error;
@@ -1,3 +1,4 @@
1
+ @use "sass:math";
1
2
 
2
3
  [class^=pb_time_range_inline_kit] {
3
4
  &[class*=_center] {
@@ -22,14 +23,14 @@
22
23
  display: flex;
23
24
  align-items: center;
24
25
  [class*=pb_time_range_inline_arrow] {
25
- margin-left: $space_xs/2;
26
- margin-right: $space_xs/2;
26
+ margin-left: math.div($space_xs, 2);
27
+ margin-right:math.div($space_xs, 2);
27
28
  }
28
29
  [class*=pb_time_range_inline_timezone] {
29
- margin-left: $space_xs/2;
30
+ margin-left: math.div($space_xs, 2);
30
31
  }
31
32
  [class*=pb_time_range_inline_icon] {
32
- margin-right: $space_xs/2;
33
+ margin-right: math.div($space_xs, 2);
33
34
  }
34
35
  }
35
36
  }
@@ -1,12 +1,14 @@
1
+ @use "sass:math";
2
+
1
3
  @import "../tokens/colors";
2
4
  @import "../tokens/spacing";
3
5
  @import "../tokens/opacity";
4
6
  @import "../tokens/typography";
5
7
 
6
8
  $connector_width: 2px;
7
- $icon_margin: $space_xs/2;
9
+ $icon_margin: math.div($space_xs, 2);
8
10
  $icon_height: 28px;
9
- $height_from_top: $icon_height/2 - $connector_width/2;
11
+ $height_from_top: (math.div($icon_height, 2)) - (math.div($connector_width, 2));
10
12
 
11
13
  // Add gap variables
12
14
  $gap_xs: $height_from_top + $space_xs;
@@ -1,3 +1,5 @@
1
+ @use "sass:math";
2
+
1
3
  @import "../tokens/colors";
2
4
 
3
5
  $color_checkbox_success: $data_1;
@@ -8,7 +10,7 @@ $transition: .2s ease-in-out;
8
10
  [class^=pb_toggle_kit] {
9
11
  position: relative;
10
12
  $width: 44px;
11
- $height: $width / 2;
13
+ $height: math.div($width, 2);
12
14
  $border_success: 3px solid $color_checkbox_success;
13
15
  $border_default: 3px solid $color_checkbox_default;
14
16
 
@@ -27,7 +29,7 @@ $transition: .2s ease-in-out;
27
29
  &:after {
28
30
  transition: $transition;
29
31
  content: "";
30
- width: $width / 2 - 4px;
32
+ width: math.div($width, 2) - 4px;
31
33
  height: $height - 4px;
32
34
  background-color: $color_checkbox_default;
33
35
  border-radius: 50%;
@@ -68,7 +70,7 @@ $transition: .2s ease-in-out;
68
70
  background-color: $color_checkbox_success;
69
71
 
70
72
  &:after {
71
- left: $width / 2 + 2px;
73
+ left: math.div($width, 2) + 2px;
72
74
  background-color: $white;
73
75
  }
74
76
  }