playbook_ui 15.1.0.pre.alpha.PLAY251810942 → 15.1.0.pre.alpha.alphaforaudiences151011003

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ea9f5c8acfb10e8fb3d40fea187b82854b1fb068361853c9b032f91fca4685ad
4
- data.tar.gz: ff8472f9f4055f5b24cb17583c02c37fa5cc022f37bf7d36869cb4d2dc06feaf
3
+ metadata.gz: 13e5f87e165b0dcfc403adda62603bb65d2fb64886b8bc2679942e7e4bdc7f5c
4
+ data.tar.gz: f6f18d67170ed7138efde9063cd407e4ed8e877357bb8a1d649051cabe68280c
5
5
  SHA512:
6
- metadata.gz: a7a3df82c8d6bb097dc840c452b3658a4751f3ecb1efde791db7043328cca7a1450adb4d56b0b1d52e13ebd7e75163573105a2910bd01faeca49c05937086f83
7
- data.tar.gz: 869e0b7510f081c28a277b0f77f1c96e2f63dccfc5955913140a00952741545f79e728370a234ded1cedba4fde080bbd396650e357a37b24ede37ac55428bfff
6
+ metadata.gz: 4d6196ae55a24472fa7edd4da8e49801d844333ceb9d6f06dc89260cc33be34bba29d22d4abdacbdb5df1186d0bacabaa208e6698f4449379a16942c8a57fed4
7
+ data.tar.gz: 487f5286be5ef212eb82a5d12831c3fd7efaf39f00b106a4b783bd13119c56d656dc845bb5a024afbe485513c031735685dc5e677a6c74b2c74336b4f9c19122
@@ -146,8 +146,6 @@ export function useTableState({
146
146
 
147
147
  // Pagination configuration
148
148
  const paginationInitializer = useMemo(() => {
149
- if (!pagination) return {};
150
-
151
149
  return {
152
150
  getPaginationRowModel: getPaginationRowModel(),
153
151
  paginateExpandedRows: false,
@@ -19,6 +19,10 @@
19
19
  @import "./sass_partials/calendar_input_icon";
20
20
  }
21
21
 
22
+ label {
23
+ display: block !important;
24
+ }
25
+
22
26
  &:focus,
23
27
  :focus-within {
24
28
  div.cal_icon_wrapper,
@@ -3,12 +3,12 @@
3
3
  <%= pb_rails("button", props: { text: "Delete Status", data: {"open-dialog": "dialog-stacked-delete"}, margin_right: "md" }) %>
4
4
 
5
5
 
6
- <%= pb_rails("dialog", props: {
7
- id:"dialog-stacked-default",
6
+ <%= pb_rails("dialog", props: {
7
+ id:"dialog-stacked-default",
8
8
  status: "default",
9
- size: "sm",
10
- title: "Are you sure?",
11
- text: "Text explaining why there is an alert",
9
+ size: "sm",
10
+ title: "Are you sure?",
11
+ text: "Text explaining why there is an alert",
12
12
  }) do %>
13
13
  <%= pb_rails("dialog/dialog_footer") do %>
14
14
  <%= pb_rails("flex", props: { orientation: "column", padding_x:"md", padding: "sm" }) do %>
@@ -18,12 +18,12 @@
18
18
  <% end %>
19
19
  <% end %>
20
20
 
21
- <%= pb_rails("dialog", props: {
22
- id:"dialog-stacked-caution",
21
+ <%= pb_rails("dialog", props: {
22
+ id:"dialog-stacked-caution",
23
23
  status: "caution",
24
- size: "sm",
25
- title: "Are you sure?",
26
- text: "This is the action you will be taking",
24
+ size: "sm",
25
+ title: "Are you sure?",
26
+ text: "This is the action you will be taking",
27
27
  }) do %>
28
28
  <%= pb_rails("dialog/dialog_footer") do %>
29
29
  <%= pb_rails("flex", props: { orientation: "column", padding_x:"md", padding: "sm" }) do %>
@@ -33,16 +33,16 @@
33
33
  <% end %>
34
34
  <% end %>
35
35
 
36
- <%= pb_rails("dialog", props: {
37
- id:"dialog-stacked-delete",
36
+ <%= pb_rails("dialog", props: {
37
+ id:"dialog-stacked-delete",
38
38
  status: "delete",
39
- size: "sm",
40
- title: "Delete",
41
- text: "You are about to delete ...",
39
+ size: "sm",
40
+ title: "Delete",
41
+ text: "You are about to delete ...",
42
42
  }) do %>
43
43
  <%= pb_rails("dialog/dialog_footer") do %>
44
44
  <%= pb_rails("flex", props: { orientation: "column", padding_x:"md", padding: "sm" }) do %>
45
- <%= pb_rails("button", props: { text: "Yes, Action", full_width: true }) %>
45
+ <%= pb_rails("button", props: { text: "Yes, Action", variant: "danger", full_width: true }) %>
46
46
  <%= pb_rails("button", props: { text: "No, Cancel", variant: "secondary", full_width: true, margin_top: "sm", data: {"close-dialog": "dialog-stacked-delete" } }) %>
47
47
  <% end %>
48
48
  <% end %>
@@ -51,7 +51,7 @@ const DialogStackedAlert = () => {
51
51
  return (
52
52
  <div>
53
53
  <Flex
54
- rowGap="xs"
54
+ rowGap="xs"
55
55
  wrap
56
56
  >
57
57
  <Button
@@ -93,6 +93,7 @@ const DialogStackedAlert = () => {
93
93
  <Button
94
94
  fullWidth
95
95
  onClick={dialog.toggle}
96
+ variant= {dialog.status == "delete" ? "danger" : "primary"}
96
97
  >
97
98
  {dialog.buttonOneText}
98
99
  </Button>
@@ -8,12 +8,12 @@
8
8
  <%= pb_rails("button", props: { text: "Success Status", data: {"open-dialog": "dialog-status-success"}, margin_right: "md" }) %>
9
9
  <% end %>
10
10
 
11
- <%= pb_rails("dialog", props: {
12
- id:"dialog-status-default",
11
+ <%= pb_rails("dialog", props: {
12
+ id:"dialog-status-default",
13
13
  status: "default",
14
- size: "status_size",
15
- title: "Are you sure?",
16
- text: "Text explaining why there is an alert",
14
+ size: "status_size",
15
+ title: "Are you sure?",
16
+ text: "Text explaining why there is an alert",
17
17
  }) do %>
18
18
  <%= pb_rails("dialog/dialog_footer") do %>
19
19
  <%= pb_rails("flex", props: { spacing:"between", padding_x:"md", padding_bottom:"md", padding: "sm" }) do %>
@@ -23,12 +23,12 @@
23
23
  <% end %>
24
24
  <% end %>
25
25
 
26
- <%= pb_rails("dialog", props: {
27
- id:"dialog-status-info",
26
+ <%= pb_rails("dialog", props: {
27
+ id:"dialog-status-info",
28
28
  status: "info",
29
- size: "status_size",
30
- title: "Information",
31
- text: "Text explaining why there is an alert",
29
+ size: "status_size",
30
+ title: "Information",
31
+ text: "Text explaining why there is an alert",
32
32
  }) do %>
33
33
  <%= pb_rails("dialog/dialog_footer") do %>
34
34
  <%= pb_rails("flex", props: { spacing:"between", padding_x:"md", padding_bottom:"md", padding: "sm" }) do %>
@@ -37,12 +37,12 @@
37
37
  <% end %>
38
38
  <% end %>
39
39
 
40
- <%= pb_rails("dialog", props: {
41
- id:"dialog-status-caution",
40
+ <%= pb_rails("dialog", props: {
41
+ id:"dialog-status-caution",
42
42
  status: "caution",
43
- size: "status_size",
44
- title: "Are you Sure?",
45
- text: "This is the action you will be taking",
43
+ size: "status_size",
44
+ title: "Are you Sure?",
45
+ text: "This is the action you will be taking",
46
46
  }) do %>
47
47
  <%= pb_rails("dialog/dialog_footer") do %>
48
48
  <%= pb_rails("flex", props: { spacing:"between", padding_x:"md", padding_bottom:"md", padding: "sm" }) do %>
@@ -52,27 +52,27 @@
52
52
  <% end %>
53
53
  <% end %>
54
54
 
55
- <%= pb_rails("dialog", props: {
56
- id:"dialog-status-delete",
55
+ <%= pb_rails("dialog", props: {
56
+ id:"dialog-status-delete",
57
57
  status: "delete",
58
- size: "status_size",
59
- title: "Delete",
60
- text: "You are about to delete ...",
58
+ size: "status_size",
59
+ title: "Delete",
60
+ text: "You are about to delete ...",
61
61
  }) do %>
62
62
  <%= pb_rails("dialog/dialog_footer") do %>
63
63
  <%= pb_rails("flex", props: { spacing:"between", padding_x:"md", padding_bottom:"md", padding: "sm" }) do %>
64
- <%= pb_rails("button", props: { text: "Yes, Delete" }) %>
64
+ <%= pb_rails("button", props: { text: "Yes, Delete", variant: "danger" }) %>
65
65
  <%= pb_rails("button", props: { text: "No, Cancel", variant: "secondary", data: {"close-dialog": "dialog-status-delete" } }) %>
66
66
  <% end %>
67
67
  <% end %>
68
68
  <% end %>
69
69
 
70
- <%= pb_rails("dialog", props: {
71
- id:"dialog-status-error",
70
+ <%= pb_rails("dialog", props: {
71
+ id:"dialog-status-error",
72
72
  status: "error",
73
- size: "status_size",
74
- title: "Error Message",
75
- text: "Text explaining the error",
73
+ size: "status_size",
74
+ title: "Error Message",
75
+ text: "Text explaining the error",
76
76
  }) do %>
77
77
  <%= pb_rails("dialog/dialog_footer") do %>
78
78
  <%= pb_rails("flex", props: { spacing:"between", padding_x:"md", padding_bottom:"md", padding: "sm" }) do %>
@@ -81,12 +81,12 @@
81
81
  <% end %>
82
82
  <% end %>
83
83
 
84
- <%= pb_rails("dialog", props: {
85
- id:"dialog-status-success",
84
+ <%= pb_rails("dialog", props: {
85
+ id:"dialog-status-success",
86
86
  status: "success",
87
- size: "status_size",
88
- title: "Success!",
89
- text: "Text explaining what is successful",
87
+ size: "status_size",
88
+ title: "Success!",
89
+ text: "Text explaining what is successful",
90
90
  }) do %>
91
91
  <%= pb_rails("dialog/dialog_footer") do %>
92
92
  <%= pb_rails("flex", props: { spacing:"between", padding_x:"md", padding_bottom:"md", padding: "sm" }) do %>
@@ -83,8 +83,8 @@ const DialogStatus = () => {
83
83
 
84
84
  return (
85
85
  <div>
86
- <Flex
87
- rowGap="xs"
86
+ <Flex
87
+ rowGap="xs"
88
88
  wrap
89
89
  >
90
90
  <Button
@@ -117,7 +117,7 @@ const DialogStatus = () => {
117
117
  >
118
118
  {"Success Status"}
119
119
  </Button>
120
- <Button
120
+ <Button
121
121
  marginRight="md"
122
122
  onClick={toggleErrorAlert}
123
123
  >
@@ -152,6 +152,7 @@ const DialogStatus = () => {
152
152
  <Button
153
153
  onClick={dialog.toggle}
154
154
  paddingRight="xl"
155
+ variant={dialog.status == "delete" ? "danger" : "primary"}
155
156
  >
156
157
  {dialog.buttonOneText}
157
158
  </Button>
@@ -10,15 +10,9 @@
10
10
  @import "./scss_partials/dropdown_animation";
11
11
  @import "dropdown_mixin";
12
12
 
13
- .pb_dropdown_default,
14
- .pb_dropdown_subtle,
15
- .pb_dropdown_default_separators_hidden,
16
- .pb_dropdown_subtle_separators_hidden {
13
+ [class*="pb_dropdown"] {
17
14
  .dropdown_wrapper {
18
- .dropdown_trigger_wrapper,
19
- .dropdown_trigger_wrapper_focus,
20
- .dropdown_trigger_wrapper_focus_select_only,
21
- .dropdown_trigger_wrapper_select_only {
15
+ [class*="dropdown_trigger_wrapper"] {
22
16
  @include pb_body;
23
17
  border: 1px solid $border_light;
24
18
  background-color: $white;
@@ -54,11 +48,11 @@
54
48
  transition: box-shadow 0.15s ease-in-out;
55
49
  }
56
50
 
57
- &.dropdown_trigger_wrapper_select_only {
51
+ &[class*="_select_only"] {
58
52
  box-shadow: inset 0 -11px 20px rgba($primary, 0.05);
59
53
  }
60
54
 
61
- &.dropdown_trigger_wrapper_focus {
55
+ &[class*="_focus"] {
62
56
  box-shadow: 0px 0px 0 1px $primary !important;
63
57
  transition: box-shadow 0.1s ease-in-out;
64
58
  }
@@ -75,12 +69,7 @@
75
69
  z-index: $z_1;
76
70
  width: 100%;
77
71
 
78
- .pb_dropdown_option,
79
- .pb_dropdown_option_list,
80
- .pb_dropdown_option_selected,
81
- .pb_dropdown_option_focused,
82
- .pb_dropdown_option_list_focused,
83
- .pb_dropdown_option_selected_focused {
72
+ [class*="pb_dropdown_option"] {
84
73
  padding-left: $space_sm;
85
74
  padding-right: $space_sm;
86
75
  padding-top: $space_xs;
@@ -90,14 +79,11 @@
90
79
  background-color: $bg_light;
91
80
  }
92
81
 
93
- &.pb_dropdown_option_focused,
94
- &.pb_dropdown_option_list_focused,
95
- &.pb_dropdown_option_selected_focused {
82
+ &[class*="_focused"] {
96
83
  background-color: $bg_light;
97
84
  }
98
85
 
99
- &.pb_dropdown_option_list,
100
- &.pb_dropdown_option_list_focused {
86
+ &[class*="_list"] {
101
87
  border-bottom: 1px solid $border_light;
102
88
 
103
89
  &:hover, &:focus {
@@ -106,8 +92,7 @@
106
92
  }
107
93
  }
108
94
  }
109
- &.pb_dropdown_option_selected,
110
- &.pb_dropdown_option_selected_focused {
95
+ &[class*="selected"] {
111
96
  background-color: $primary;
112
97
  color: $white;
113
98
  [class^="pb_body"],
@@ -156,66 +141,41 @@
156
141
  }
157
142
 
158
143
  &.error {
159
- .pb_body_kit_negative {
144
+ [class*=pb_body_kit] {
160
145
  margin-top: $space_xs / 2;
161
146
  }
162
147
 
163
- .dropdown_trigger_wrapper,
164
- .dropdown_trigger_wrapper_focus,
165
- .dropdown_trigger_wrapper_focus_select_only,
166
- .dropdown_trigger_wrapper_select_only {
148
+ [class*="dropdown_trigger_wrapper"] {
167
149
  border-color: $error;
168
150
  box-shadow: none !important;
169
151
  }
170
152
  }
171
153
  }
172
154
 
173
- &.pb_dropdown_default_separators_hidden,
174
- &.pb_dropdown_subtle_separators_hidden {
155
+ &[class*="separators_hidden"] {
175
156
  .dropdown_wrapper {
176
157
  .pb_dropdown_container {
177
158
 
178
- .pb_dropdown_option,
179
- .pb_dropdown_option_list,
180
- .pb_dropdown_option_selected,
181
- .pb_dropdown_option_focused,
182
- .pb_dropdown_option_list_focused,
183
- .pb_dropdown_option_selected_focused {
159
+ [class*="pb_dropdown_option"] {
184
160
  border: none;
185
161
  }
186
162
  }
187
163
  }
188
164
  }
189
165
 
190
- &.pb_dropdown_subtle,
191
- &.pb_dropdown_subtle_separators_hidden {
166
+ &[class*="subtle"] {
192
167
  .dropdown_wrapper {
193
168
  .pb_dropdown_container {
194
169
 
195
- .pb_dropdown_option:first-child,
196
- .pb_dropdown_option_list:first-child,
197
- .pb_dropdown_option_selected:first-child,
198
- .pb_dropdown_option_focused:first-child,
199
- .pb_dropdown_option_list_focused:first-child,
200
- .pb_dropdown_option_selected_focused:first-child {
170
+ [class*="pb_dropdown_option"]:first-child {
201
171
  margin-top: $space_xs;
202
172
  }
203
173
 
204
- .pb_dropdown_option:last-child,
205
- .pb_dropdown_option_list:last-child,
206
- .pb_dropdown_option_selected:last-child,
207
- .pb_dropdown_option_focused:last-child,
208
- .pb_dropdown_option_list_focused:last-child,
209
- .pb_dropdown_option_selected_focused:last-child {
174
+ [class*="pb_dropdown_option"]:last-child {
210
175
  margin-bottom: $space_xs;
211
176
  }
212
177
 
213
- .pb_dropdown_option,
214
- .pb_dropdown_option_list,
215
- .pb_dropdown_option_selected,
216
- .pb_dropdown_option_focused,
217
- .pb_dropdown_option_list_focused,
218
- .pb_dropdown_option_selected_focused {
178
+ [class*="pb_dropdown_option"] {
219
179
  margin: $space_xs;
220
180
  padding: $space_xs;
221
181
  border-radius: $border_radius_md;
@@ -233,44 +193,24 @@
233
193
  }
234
194
  }
235
195
 
236
- .pb_dropdown_option:last-child::after,
237
- .pb_dropdown_option_list:last-child::after,
238
- .pb_dropdown_option_selected:last-child::after,
239
- .pb_dropdown_option_focused:last-child::after,
240
- .pb_dropdown_option_list_focused:last-child::after,
241
- .pb_dropdown_option_selected_focused:last-child::after {
196
+ [class*="pb_dropdown_option"]:last-child::after {
242
197
  display: none;
243
198
  }
244
199
  }
245
200
  }
246
201
 
247
- &.pb_dropdown_subtle_separators_hidden {
202
+ &[class*="separators_hidden"] {
248
203
  .dropdown_wrapper {
249
204
  .pb_dropdown_container {
250
- .pb_dropdown_option:first-child,
251
- .pb_dropdown_option_list:first-child,
252
- .pb_dropdown_option_selected:first-child,
253
- .pb_dropdown_option_focused:first-child,
254
- .pb_dropdown_option_list_focused:first-child,
255
- .pb_dropdown_option_selected_focused:first-child {
205
+ [class*="pb_dropdown_option"]:first-child {
256
206
  margin-top: $space_xs;
257
207
  }
258
208
 
259
- .pb_dropdown_option:last-child,
260
- .pb_dropdown_option_list:last-child,
261
- .pb_dropdown_option_selected:last-child,
262
- .pb_dropdown_option_focused:last-child,
263
- .pb_dropdown_option_list_focused:last-child,
264
- .pb_dropdown_option_selected_focused:last-child {
209
+ [class*="pb_dropdown_option"]:last-child {
265
210
  margin-bottom: $space_xs;
266
211
  }
267
212
 
268
- .pb_dropdown_option,
269
- .pb_dropdown_option_list,
270
- .pb_dropdown_option_selected,
271
- .pb_dropdown_option_focused,
272
- .pb_dropdown_option_list_focused,
273
- .pb_dropdown_option_selected_focused {
213
+ [class*="pb_dropdown_option"] {
274
214
  padding: $space_xxs $space_xs;
275
215
  margin: $space_xxs $space_xs;
276
216
 
@@ -278,8 +218,7 @@
278
218
  height: 0px;
279
219
  }
280
220
 
281
- &.pb_dropdown_option_selected,
282
- &.pb_dropdown_option_selected_focused {
221
+ &[class*="selected"] {
283
222
  border-bottom: none;
284
223
  }
285
224
  }
@@ -290,10 +229,7 @@
290
229
 
291
230
  &.dark {
292
231
  .dropdown_wrapper {
293
- .dropdown_trigger_wrapper,
294
- .dropdown_trigger_wrapper_focus,
295
- .dropdown_trigger_wrapper_focus_select_only,
296
- .dropdown_trigger_wrapper_select_only {
232
+ [class*="dropdown_trigger_wrapper"] {
297
233
  @include pb_body_light_dark;
298
234
  background-color: rgba($white, 0.1) !important;
299
235
  background: none;
@@ -308,7 +244,7 @@
308
244
  [class^="pb_body"] {
309
245
  color: $white;
310
246
  }
311
- &.dropdown_trigger_wrapper_select_only {
247
+ &[class*="_select_only"] {
312
248
  box-shadow: inset 0 -11px 20px rgba($white, 0.05);
313
249
  }
314
250
  .dropdown_input {
@@ -318,10 +254,7 @@
318
254
  }
319
255
 
320
256
  &.error {
321
- .dropdown_trigger_wrapper,
322
- .dropdown_trigger_wrapper_focus,
323
- .dropdown_trigger_wrapper_focus_select_only,
324
- .dropdown_trigger_wrapper_select_only {
257
+ [class*="dropdown_trigger_wrapper"] {
325
258
  border-color: $error_dark;
326
259
  }
327
260
  }
@@ -335,28 +268,19 @@
335
268
  color: $white !important;
336
269
  }
337
270
 
338
- .pb_dropdown_option,
339
- .pb_dropdown_option_list,
340
- .pb_dropdown_option_selected,
341
- .pb_dropdown_option_focused,
342
- .pb_dropdown_option_list_focused,
343
- .pb_dropdown_option_selected_focused {
271
+ [class*="pb_dropdown_option"] {
344
272
  &:hover {
345
273
  background-color: $hover_dark;
346
274
  }
347
275
 
348
- &.pb_dropdown_option_focused,
349
- &.pb_dropdown_option_list_focused,
350
- &.pb_dropdown_option_selected_focused {
276
+ &[class*="_focused"] {
351
277
  background-color: $hover_dark;
352
278
  }
353
279
 
354
- &.pb_dropdown_option_list,
355
- &.pb_dropdown_option_list_focused {
280
+ &[class*="_list"] {
356
281
  border-color: rgba($white, 0.15);
357
282
  }
358
- &.pb_dropdown_option_selected,
359
- &.pb_dropdown_option_selected_focused {
283
+ &[class*="selected"] {
360
284
  background-color: $primary;
361
285
  border-bottom: rgba($white, 0.15);
362
286
  }
@@ -140,10 +140,14 @@ const TextInput = (props: TextInputProps, ref: React.LegacyRef<HTMLInputElement>
140
140
  formattedValue = value
141
141
  }
142
142
 
143
+ const errorId = error ? `${id}-error` : undefined
144
+
143
145
  const textInput = (
144
146
  childInput ? React.cloneElement(children, { className: "text_input" }) :
145
147
  (<input
146
148
  {...domSafeProps(props)}
149
+ aria-describedby={errorId}
150
+ aria-invalid={!!error}
147
151
  autoComplete={typeof autoComplete === "string" ? autoComplete : ( autoComplete ? undefined : "off" )}
148
152
  className="text_input"
149
153
  disabled={disabled}
@@ -202,16 +206,20 @@ const TextInput = (props: TextInputProps, ref: React.LegacyRef<HTMLInputElement>
202
206
  {...htmlProps}
203
207
  className={css}
204
208
  >
205
- {label &&
206
- <Caption
207
- className="pb_text_input_kit_label"
208
- text={label}
209
- />
210
- }
209
+ {label && (
210
+ <label htmlFor={id}>
211
+ <Caption className="pb_text_input_kit_label"
212
+ text={label}
213
+ />
214
+ </label>
215
+ )}
211
216
  <div className={`${addOnCss} text_input_wrapper`}>
212
217
  {render}
213
218
 
214
219
  {error && <Body
220
+ aria={{ atomic: "true", live: "polite" }}
221
+ htmlOptions={{ role: "alert" }}
222
+ id={errorId}
215
223
  status="negative"
216
224
  text={error}
217
225
  variant={null}
@@ -9,23 +9,27 @@
9
9
 
10
10
  <%= pb_rails("text_input", props: {
11
11
  label: "Last Name",
12
- placeholder: "Enter last name"
12
+ placeholder: "Enter last name",
13
+ id: "last-name"
13
14
  }) %>
14
15
 
15
16
  <%= pb_rails("text_input", props: {
16
17
  label: "Phone Number",
17
18
  type: "phone",
18
- placeholder: "Enter phone number"
19
+ placeholder: "Enter phone number",
20
+ id: "phone"
19
21
  }) %>
20
22
 
21
23
  <%= pb_rails("text_input", props: {
22
24
  label: "Email Address",
23
25
  type: "email",
24
- placeholder: "Enter email address"
26
+ placeholder: "Enter email address",
27
+ id: "email"
25
28
  }) %>
26
29
 
27
30
  <%= pb_rails("text_input", props: {
28
31
  label: "Zip Code",
29
32
  type: "number",
30
- placeholder: "Enter zip code"
33
+ placeholder: "Enter zip code",
34
+ id: "zip"
31
35
  }) %>
@@ -38,6 +38,7 @@ const TextInputDefault = (props) => {
38
38
  {...props}
39
39
  />
40
40
  <TextInput
41
+ id="last-name"
41
42
  label="Last Name"
42
43
  name="lastName"
43
44
  onChange={handleOnChangeFormField}
@@ -46,6 +47,7 @@ const TextInputDefault = (props) => {
46
47
  {...props}
47
48
  />
48
49
  <TextInput
50
+ id="phone"
49
51
  label="Phone Number"
50
52
  name="phone"
51
53
  onChange={handleOnChangeFormField}
@@ -55,6 +57,7 @@ const TextInputDefault = (props) => {
55
57
  {...props}
56
58
  />
57
59
  <TextInput
60
+ id="email"
58
61
  label="Email Address"
59
62
  name="email"
60
63
  onChange={handleOnChangeFormField}
@@ -64,6 +67,7 @@ const TextInputDefault = (props) => {
64
67
  {...props}
65
68
  />
66
69
  <TextInput
70
+ id="zip"
67
71
  label="Zip Code"
68
72
  name="zip"
69
73
  onChange={handleOnChangeFormField}
@@ -84,6 +88,7 @@ const TextInputDefault = (props) => {
84
88
  <br />
85
89
 
86
90
  <TextInput
91
+ id="first-name"
87
92
  label="First Name"
88
93
  onChange={handleOnChangeFirstName}
89
94
  placeholder="Enter first name"
@@ -0,0 +1 @@
1
+ Add an `id` to your Text Input so that clicking the label will move focus directly to the input.
@@ -1,6 +1,8 @@
1
1
  <%= pb_content_tag(:div, id: nil ) do %>
2
2
  <% if object.label.present? %>
3
+ <label for="<%= object.input_options[:id] || object.id %>" >
3
4
  <%= pb_rails("caption", props: { text: object.label, dark: object.dark, classname: "pb_text_input_kit_label" }) %>
5
+ </label>
4
6
  <% end %>
5
7
  <%= content_tag(:div, class: "#{add_on_class} text_input_wrapper") do %>
6
8
  <% if content.present? %>
@@ -15,7 +17,7 @@
15
17
  <% else %>
16
18
  <%= input_tag %>
17
19
  <% end %>
18
- <%= pb_rails("body", props: {dark: object.dark, status: "negative", text: object.error}) if object.error %>
20
+ <%= pb_rails("body", props: {dark: object.dark, status: "negative", text: object.error, id: object.error_id, aria: { atomic: "true", live: "polite" }, html_options: { role: "alert" }}) if object.error %>
19
21
  <% end %>
20
22
  <% end %>
21
23
 
@@ -64,10 +64,16 @@ module Playbook
64
64
  "#{object.id}-sanitized" if id.present?
65
65
  end
66
66
 
67
+ def error_id
68
+ "#{id}-error" if error.present?
69
+ end
70
+
67
71
  private
68
72
 
69
73
  def all_input_options
70
74
  {
75
+ 'aria-describedby': error.present? ? error_id : nil,
76
+ 'aria-invalid': error.present?,
71
77
  autocomplete: autocomplete == true ? nil : (autocomplete.presence || "off"),
72
78
  class: "text_input #{input_options.dig(:classname) || ''}",
73
79
  data: validation_data,