playbook_ui 15.1.0.pre.alpha.multipleusersstackedscss11047 → 15.1.0.pre.alpha.play252710946
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 +4 -4
- data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableState.ts +2 -0
- data/app/pb_kits/playbook/pb_date_picker/_date_picker.scss +0 -4
- data/app/pb_kits/playbook/pb_dialog/docs/_dialog_stacked_alert.html.erb +16 -16
- data/app/pb_kits/playbook/pb_dialog/docs/_dialog_stacked_alert.jsx +1 -2
- data/app/pb_kits/playbook/pb_dialog/docs/_dialog_status.html.erb +31 -31
- data/app/pb_kits/playbook/pb_dialog/docs/_dialog_status.jsx +3 -4
- data/app/pb_kits/playbook/pb_form/docs/_form_form_with_validate.html.erb +12 -1
- data/app/pb_kits/playbook/pb_multiple_users_stacked/_multiple_users_stacked.scss +9 -36
- data/app/pb_kits/playbook/pb_text_input/_text_input.tsx +6 -14
- data/app/pb_kits/playbook/pb_text_input/docs/_text_input_default.html.erb +4 -8
- data/app/pb_kits/playbook/pb_text_input/docs/_text_input_default.jsx +0 -5
- data/app/pb_kits/playbook/pb_text_input/text_input.html.erb +1 -3
- data/app/pb_kits/playbook/pb_text_input/text_input.rb +0 -6
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +39 -1
- data/app/pb_kits/playbook/pb_typeahead/typeahead.rb +2 -0
- data/dist/chunks/{_line_graph-BnK1i7QI.js → _line_graph-DwC5jqYQ.js} +1 -1
- data/dist/chunks/{_typeahead-pbS3fEzb.js → _typeahead-4Ud3FHDA.js} +1 -1
- data/dist/chunks/{_weekday_stacked-OOFiMFSs.js → _weekday_stacked-CygSRiZe.js} +2 -2
- data/dist/chunks/vendor.js +1 -1
- data/dist/playbook-doc.js +2 -2
- data/dist/playbook-rails-react-bindings.js +1 -1
- data/dist/playbook-rails.js +1 -1
- data/dist/playbook.css +1 -1
- data/lib/playbook/version.rb +1 -1
- metadata +5 -6
- data/app/pb_kits/playbook/pb_text_input/docs/_text_input_default.md +0 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1356285c2892298ab0d74134116ab03ac8559495657fddba5c09715c495b8f8b
|
|
4
|
+
data.tar.gz: e780800f41ea2ca322b7cfb5e15b1e0b8ca1b58ff949e196771987b45a659b79
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '0930a43f3351acff7849b6eee6c89b565d5454d59a7b81aa4e6b08571d353203c9d47894c4c1cbeb1c3f17d0106fcbe1e7f77a6958cc176ce5f1a2143393aef6'
|
|
7
|
+
data.tar.gz: ae3b1306ae43c73b5a86f949cccd21cead3e2c74b81f59caee59f80b8b53509fe791ef4bc54000580526f29d82f77cf82e11eccf23f69d8173ac8174b675fd2e
|
|
@@ -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",
|
|
45
|
+
<%= pb_rails("button", props: { text: "Yes, Action", 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,7 +93,6 @@ const DialogStackedAlert = () => {
|
|
|
93
93
|
<Button
|
|
94
94
|
fullWidth
|
|
95
95
|
onClick={dialog.toggle}
|
|
96
|
-
variant= {dialog.status == "delete" ? "danger" : "primary"}
|
|
97
96
|
>
|
|
98
97
|
{dialog.buttonOneText}
|
|
99
98
|
</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" }) %>
|
|
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,7 +152,6 @@ const DialogStatus = () => {
|
|
|
152
152
|
<Button
|
|
153
153
|
onClick={dialog.toggle}
|
|
154
154
|
paddingRight="xl"
|
|
155
|
-
variant={dialog.status == "delete" ? "danger" : "primary"}
|
|
156
155
|
>
|
|
157
156
|
{dialog.buttonOneText}
|
|
158
157
|
</Button>
|
|
@@ -21,6 +21,15 @@
|
|
|
21
21
|
]
|
|
22
22
|
%>
|
|
23
23
|
|
|
24
|
+
<%
|
|
25
|
+
example_typeahead_options = [
|
|
26
|
+
{ label: 'Orange', value: '#FFA500' },
|
|
27
|
+
{ label: 'Red', value: '#FF0000' },
|
|
28
|
+
{ label: 'Green', value: '#00FF00' },
|
|
29
|
+
{ label: 'Blue', value: '#0000FF' },
|
|
30
|
+
]
|
|
31
|
+
%>
|
|
32
|
+
|
|
24
33
|
<% treeData = [{
|
|
25
34
|
label: "Power Home Remodeling",
|
|
26
35
|
value: "Power Home Remodeling",
|
|
@@ -88,7 +97,9 @@
|
|
|
88
97
|
}] %>
|
|
89
98
|
|
|
90
99
|
<%= pb_form_with(scope: :example, method: :get, url: "", validate: true) do |form| %>
|
|
91
|
-
<%= form.typeahead :
|
|
100
|
+
<%= form.typeahead :example_typeahead_validation_rails, props: { data: { typeahead_example2: true, user: {} }, label: true, placeholder: "Search for a user", required: true, validation: { message: "Please select a user." } } %>
|
|
101
|
+
<%= form.typeahead :example_typeahead_validation, props: { options: example_typeahead_options, pills: true, label: "Example Typeahead (React Rendered)", placeholder: "Search for a user", required: true, validation: { message: "Please select a color." } } %>
|
|
102
|
+
<%= form.typeahead :example_typeahead_validation_2, props: { options: example_typeahead_options, pills: true, label: "Example Typeahead 2 (React Rendered)", placeholder: "Search for a user", required: true } %>
|
|
92
103
|
<%= form.text_field :example_text_field_validation, props: { label: true, required: true } %>
|
|
93
104
|
<%= form.phone_number_field :example_phone_number_field_validation, props: { label: "Example phone field", hidden_inputs: true } %>
|
|
94
105
|
<%= form.email_field :example_email_field_validation, props: { label: true, required: true } %>
|
|
@@ -89,18 +89,7 @@ $positions: (
|
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
.pb_multiple_users_stacked_kit_single,
|
|
94
|
-
.pb_multiple_users_stacked_kit_bubble,
|
|
95
|
-
.pb_multiple_users_stacked_kit_single_bubble,
|
|
96
|
-
.pb_multiple_users_stacked_kit_bubble_size_sm,
|
|
97
|
-
.pb_multiple_users_stacked_kit_bubble_size_md,
|
|
98
|
-
.pb_multiple_users_stacked_kit_bubble_size_lg,
|
|
99
|
-
.pb_multiple_users_stacked_kit_bubble_size_xl,
|
|
100
|
-
.pb_multiple_users_stacked_kit_single_bubble_size_sm,
|
|
101
|
-
.pb_multiple_users_stacked_kit_single_bubble_size_md,
|
|
102
|
-
.pb_multiple_users_stacked_kit_single_bubble_size_lg,
|
|
103
|
-
.pb_multiple_users_stacked_kit_single_bubble_size_xl {
|
|
92
|
+
[class^=pb_multiple_users_stacked_kit] {
|
|
104
93
|
$container_size: map-get($avatar-sizes, "xs");
|
|
105
94
|
$bubble_container_size: map-get($avatar-sizes, "sm");
|
|
106
95
|
$overlap: -15px;
|
|
@@ -114,8 +103,7 @@ $positions: (
|
|
|
114
103
|
position: relative;
|
|
115
104
|
flex-shrink: 0;
|
|
116
105
|
flex-grow: 0;
|
|
117
|
-
.
|
|
118
|
-
.pb_avatar_kit_size_md.pb_multiple_users_stacked_item {
|
|
106
|
+
[class^=pb_avatar_kit].pb_multiple_users_stacked_item {
|
|
119
107
|
@include avatar-size($stacked_size);
|
|
120
108
|
&.dark {
|
|
121
109
|
.avatar_wrapper {
|
|
@@ -129,17 +117,10 @@ $positions: (
|
|
|
129
117
|
}
|
|
130
118
|
}
|
|
131
119
|
}
|
|
132
|
-
|
|
133
|
-
&.pb_multiple_users_stacked_kit_single_bubble .pb_multiple_users_stacked_item,
|
|
134
|
-
&.pb_multiple_users_stacked_kit_single_bubble_size_sm .pb_multiple_users_stacked_item,
|
|
135
|
-
&.pb_multiple_users_stacked_kit_single_bubble_size_md .pb_multiple_users_stacked_item,
|
|
136
|
-
&.pb_multiple_users_stacked_kit_single_bubble_size_lg .pb_multiple_users_stacked_item,
|
|
137
|
-
&.pb_multiple_users_stacked_kit_single_bubble_size_xl .pb_multiple_users_stacked_item {
|
|
120
|
+
&[class*=_single] .pb_multiple_users_stacked_item {
|
|
138
121
|
@include avatar-size(28px);
|
|
139
122
|
}
|
|
140
|
-
.
|
|
141
|
-
.pb_avatar_kit_size_md.second_item,
|
|
142
|
-
.pb_badge_kit_primary_rounded.second_item {
|
|
123
|
+
[class^=pb_avatar_kit].second_item, [class^=pb_badge_kit].second_item {
|
|
143
124
|
@include position((bottom: 0, right: 0));
|
|
144
125
|
z-index: 2;
|
|
145
126
|
background: tint($primary, 90%);
|
|
@@ -162,8 +143,7 @@ $positions: (
|
|
|
162
143
|
|
|
163
144
|
// Iterate over each size to adjust the bubble container only when class contains "_bubble_"
|
|
164
145
|
@each $size_name, $size_value in $avatar-sizes {
|
|
165
|
-
|
|
166
|
-
&.pb_multiple_users_stacked_kit_single_bubble_size_#{$size_name} {
|
|
146
|
+
&[class*=_bubble_][class*=_size_#{$size_name}] {
|
|
167
147
|
// Set bubble container size based on the class
|
|
168
148
|
$bubble_container_size: $size_value;
|
|
169
149
|
$container_size: $size_value;
|
|
@@ -181,8 +161,7 @@ $positions: (
|
|
|
181
161
|
background-color: $card_dark;
|
|
182
162
|
}
|
|
183
163
|
|
|
184
|
-
.
|
|
185
|
-
.pb_avatar_kit_size_md.pb_multiple_users_stacked_item {
|
|
164
|
+
[class^=pb_avatar_kit].pb_multiple_users_stacked_item {
|
|
186
165
|
@include avatar-size($bubble_container_size * 0.45); // Adjust the size of stacked avatars
|
|
187
166
|
|
|
188
167
|
&.dark {
|
|
@@ -196,8 +175,7 @@ $positions: (
|
|
|
196
175
|
}
|
|
197
176
|
}
|
|
198
177
|
|
|
199
|
-
|
|
200
|
-
.pb_avatar_kit_size_md {
|
|
178
|
+
[class^=pb_avatar_kit] {
|
|
201
179
|
// First Item
|
|
202
180
|
&.first_item {
|
|
203
181
|
@include position(map-get(map-get($positions, 'first-item-double'), $size_name));
|
|
@@ -257,13 +235,8 @@ $positions: (
|
|
|
257
235
|
}
|
|
258
236
|
}
|
|
259
237
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
&.pb_multiple_users_stacked_kit_single_bubble_size_md,
|
|
263
|
-
&.pb_multiple_users_stacked_kit_single_bubble_size_lg,
|
|
264
|
-
&.pb_multiple_users_stacked_kit_single_bubble_size_xl {
|
|
265
|
-
.pb_avatar_kit_size_xs.first_item,
|
|
266
|
-
.pb_avatar_kit_size_md.first_item {
|
|
238
|
+
&[class*=_single_bubble] {
|
|
239
|
+
[class^=pb_avatar_kit].first_item {
|
|
267
240
|
@include position((top: 0, left: 0));
|
|
268
241
|
@include avatar-size($bubble_container_size);
|
|
269
242
|
}
|
|
@@ -140,14 +140,10 @@ const TextInput = (props: TextInputProps, ref: React.LegacyRef<HTMLInputElement>
|
|
|
140
140
|
formattedValue = value
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
-
const errorId = error ? `${id}-error` : undefined
|
|
144
|
-
|
|
145
143
|
const textInput = (
|
|
146
144
|
childInput ? React.cloneElement(children, { className: "text_input" }) :
|
|
147
145
|
(<input
|
|
148
146
|
{...domSafeProps(props)}
|
|
149
|
-
aria-describedby={errorId}
|
|
150
|
-
aria-invalid={!!error}
|
|
151
147
|
autoComplete={typeof autoComplete === "string" ? autoComplete : ( autoComplete ? undefined : "off" )}
|
|
152
148
|
className="text_input"
|
|
153
149
|
disabled={disabled}
|
|
@@ -206,20 +202,16 @@ const TextInput = (props: TextInputProps, ref: React.LegacyRef<HTMLInputElement>
|
|
|
206
202
|
{...htmlProps}
|
|
207
203
|
className={css}
|
|
208
204
|
>
|
|
209
|
-
{label &&
|
|
210
|
-
<
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
)}
|
|
205
|
+
{label &&
|
|
206
|
+
<Caption
|
|
207
|
+
className="pb_text_input_kit_label"
|
|
208
|
+
text={label}
|
|
209
|
+
/>
|
|
210
|
+
}
|
|
216
211
|
<div className={`${addOnCss} text_input_wrapper`}>
|
|
217
212
|
{render}
|
|
218
213
|
|
|
219
214
|
{error && <Body
|
|
220
|
-
aria={{ atomic: "true", live: "polite" }}
|
|
221
|
-
htmlOptions={{ role: "alert" }}
|
|
222
|
-
id={errorId}
|
|
223
215
|
status="negative"
|
|
224
216
|
text={error}
|
|
225
217
|
variant={null}
|
|
@@ -9,27 +9,23 @@
|
|
|
9
9
|
|
|
10
10
|
<%= pb_rails("text_input", props: {
|
|
11
11
|
label: "Last Name",
|
|
12
|
-
placeholder: "Enter last name"
|
|
13
|
-
id: "last-name"
|
|
12
|
+
placeholder: "Enter last name"
|
|
14
13
|
}) %>
|
|
15
14
|
|
|
16
15
|
<%= pb_rails("text_input", props: {
|
|
17
16
|
label: "Phone Number",
|
|
18
17
|
type: "phone",
|
|
19
|
-
placeholder: "Enter phone number"
|
|
20
|
-
id: "phone"
|
|
18
|
+
placeholder: "Enter phone number"
|
|
21
19
|
}) %>
|
|
22
20
|
|
|
23
21
|
<%= pb_rails("text_input", props: {
|
|
24
22
|
label: "Email Address",
|
|
25
23
|
type: "email",
|
|
26
|
-
placeholder: "Enter email address"
|
|
27
|
-
id: "email"
|
|
24
|
+
placeholder: "Enter email address"
|
|
28
25
|
}) %>
|
|
29
26
|
|
|
30
27
|
<%= pb_rails("text_input", props: {
|
|
31
28
|
label: "Zip Code",
|
|
32
29
|
type: "number",
|
|
33
|
-
placeholder: "Enter zip code"
|
|
34
|
-
id: "zip"
|
|
30
|
+
placeholder: "Enter zip code"
|
|
35
31
|
}) %>
|
|
@@ -38,7 +38,6 @@ const TextInputDefault = (props) => {
|
|
|
38
38
|
{...props}
|
|
39
39
|
/>
|
|
40
40
|
<TextInput
|
|
41
|
-
id="last-name"
|
|
42
41
|
label="Last Name"
|
|
43
42
|
name="lastName"
|
|
44
43
|
onChange={handleOnChangeFormField}
|
|
@@ -47,7 +46,6 @@ const TextInputDefault = (props) => {
|
|
|
47
46
|
{...props}
|
|
48
47
|
/>
|
|
49
48
|
<TextInput
|
|
50
|
-
id="phone"
|
|
51
49
|
label="Phone Number"
|
|
52
50
|
name="phone"
|
|
53
51
|
onChange={handleOnChangeFormField}
|
|
@@ -57,7 +55,6 @@ const TextInputDefault = (props) => {
|
|
|
57
55
|
{...props}
|
|
58
56
|
/>
|
|
59
57
|
<TextInput
|
|
60
|
-
id="email"
|
|
61
58
|
label="Email Address"
|
|
62
59
|
name="email"
|
|
63
60
|
onChange={handleOnChangeFormField}
|
|
@@ -67,7 +64,6 @@ const TextInputDefault = (props) => {
|
|
|
67
64
|
{...props}
|
|
68
65
|
/>
|
|
69
66
|
<TextInput
|
|
70
|
-
id="zip"
|
|
71
67
|
label="Zip Code"
|
|
72
68
|
name="zip"
|
|
73
69
|
onChange={handleOnChangeFormField}
|
|
@@ -88,7 +84,6 @@ const TextInputDefault = (props) => {
|
|
|
88
84
|
<br />
|
|
89
85
|
|
|
90
86
|
<TextInput
|
|
91
|
-
id="first-name"
|
|
92
87
|
label="First Name"
|
|
93
88
|
onChange={handleOnChangeFirstName}
|
|
94
89
|
placeholder="Enter first name"
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
<%= pb_content_tag(:div, id: nil ) do %>
|
|
2
2
|
<% if object.label.present? %>
|
|
3
|
-
<label for="<%= object.input_options[:id] || object.id %>" >
|
|
4
3
|
<%= pb_rails("caption", props: { text: object.label, dark: object.dark, classname: "pb_text_input_kit_label" }) %>
|
|
5
|
-
</label>
|
|
6
4
|
<% end %>
|
|
7
5
|
<%= content_tag(:div, class: "#{add_on_class} text_input_wrapper") do %>
|
|
8
6
|
<% if content.present? %>
|
|
@@ -17,7 +15,7 @@
|
|
|
17
15
|
<% else %>
|
|
18
16
|
<%= input_tag %>
|
|
19
17
|
<% end %>
|
|
20
|
-
<%= pb_rails("body", props: {dark: object.dark, status: "negative", text: object.error
|
|
18
|
+
<%= pb_rails("body", props: {dark: object.dark, status: "negative", text: object.error}) if object.error %>
|
|
21
19
|
<% end %>
|
|
22
20
|
<% end %>
|
|
23
21
|
|
|
@@ -64,16 +64,10 @@ 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
|
-
|
|
71
67
|
private
|
|
72
68
|
|
|
73
69
|
def all_input_options
|
|
74
70
|
{
|
|
75
|
-
'aria-describedby': error.present? ? error_id : nil,
|
|
76
|
-
'aria-invalid': error.present?,
|
|
77
71
|
autocomplete: autocomplete == true ? nil : (autocomplete.presence || "off"),
|
|
78
72
|
class: "text_input #{input_options.dig(:classname) || ''}",
|
|
79
73
|
data: validation_data,
|
|
@@ -53,6 +53,8 @@ type TypeaheadProps = {
|
|
|
53
53
|
pillColor?: "primary" | "neutral" | "success" | "warning" | "error" | "info" | "data_1" | "data_2" | "data_3" | "data_4" | "data_5" | "data_6" | "data_7" | "data_8" | "windows" | "siding" | "roofing" | "doors" | "gutters" | "solar" | "insulation" | "accessories",
|
|
54
54
|
onChange?: any,
|
|
55
55
|
optionsByContext?: Record<string, Array<{ label: string; value?: string }>>
|
|
56
|
+
required?: boolean,
|
|
57
|
+
validation?: { message: string },
|
|
56
58
|
searchContextSelector?: string,
|
|
57
59
|
clearOnContextChange?: boolean,
|
|
58
60
|
preserveSearchInput?: boolean,
|
|
@@ -94,12 +96,16 @@ const Typeahead = forwardRef<HTMLInputElement, TypeaheadProps>(({
|
|
|
94
96
|
onChange,
|
|
95
97
|
optionsByContext = {},
|
|
96
98
|
searchContextSelector,
|
|
99
|
+
required = false,
|
|
100
|
+
validation,
|
|
97
101
|
clearOnContextChange = false,
|
|
98
102
|
preserveSearchInput = false, // Default to false to maintain backward compatibility
|
|
99
103
|
...props
|
|
100
104
|
}: TypeaheadProps) => {
|
|
101
105
|
// State to manage the input value when preserveSearchInput is true
|
|
102
106
|
const [inputValue, setInputValue] = useState("")
|
|
107
|
+
// State to track if form has been submitted to control validation display for react rendered rails kit
|
|
108
|
+
const [formSubmitted, setFormSubmitted] = useState(false)
|
|
103
109
|
|
|
104
110
|
// If preserveSearchInput is true, we need to control the input value
|
|
105
111
|
const handleInputChange = preserveSearchInput
|
|
@@ -135,6 +141,7 @@ const Typeahead = forwardRef<HTMLInputElement, TypeaheadProps>(({
|
|
|
135
141
|
|
|
136
142
|
const selectProps = {
|
|
137
143
|
cacheOptions: true,
|
|
144
|
+
required,
|
|
138
145
|
components: {
|
|
139
146
|
Control,
|
|
140
147
|
ClearIndicator,
|
|
@@ -170,6 +177,27 @@ const Typeahead = forwardRef<HTMLInputElement, TypeaheadProps>(({
|
|
|
170
177
|
|
|
171
178
|
const [contextValue, setContextValue] = useState("")
|
|
172
179
|
|
|
180
|
+
// Add listener for form validation to track when validation should be shown (needed for react rendered rails kit)
|
|
181
|
+
useEffect(() => {
|
|
182
|
+
const handleInvalid = (event: Event) => {
|
|
183
|
+
const target = event.target as HTMLInputElement
|
|
184
|
+
const typeaheadContainer = target.closest('[data-pb-react-component="Typeahead"]')
|
|
185
|
+
|
|
186
|
+
if (typeaheadContainer) {
|
|
187
|
+
// Check if this invalid event is specifically for our typeahead by comparing names so we do not have to require ids
|
|
188
|
+
const invalidInputName = target.name || target.getAttribute('name')
|
|
189
|
+
if (invalidInputName === name) {
|
|
190
|
+
setFormSubmitted(true)
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
document.addEventListener('invalid', handleInvalid, true)
|
|
195
|
+
|
|
196
|
+
return () => {
|
|
197
|
+
document.removeEventListener('invalid', handleInvalid, true)
|
|
198
|
+
}
|
|
199
|
+
}, [name])
|
|
200
|
+
|
|
173
201
|
// Add listener for clearing
|
|
174
202
|
useEffect(() => {
|
|
175
203
|
const handleClear = () => {
|
|
@@ -230,6 +258,11 @@ const Typeahead = forwardRef<HTMLInputElement, TypeaheadProps>(({
|
|
|
230
258
|
}
|
|
231
259
|
}
|
|
232
260
|
|
|
261
|
+
// Reset form submitted state when a selection is made (this is all for react rendered rails kit)
|
|
262
|
+
if (action === 'select-option') {
|
|
263
|
+
setFormSubmitted(false)
|
|
264
|
+
}
|
|
265
|
+
|
|
233
266
|
// If a value is selected and we're preserving input on blur, clear the input
|
|
234
267
|
if (action === 'select-option' && preserveSearchInput) {
|
|
235
268
|
setInputValue('')
|
|
@@ -268,6 +301,11 @@ const Typeahead = forwardRef<HTMLInputElement, TypeaheadProps>(({
|
|
|
268
301
|
|
|
269
302
|
const inlineClass = selectProps.inline ? 'inline' : null
|
|
270
303
|
|
|
304
|
+
const shouldShowValidationError = required &&
|
|
305
|
+
formSubmitted
|
|
306
|
+
|
|
307
|
+
const errorDisplay = error || (shouldShowValidationError ? validation?.message || "Please fill out this field." : "")
|
|
308
|
+
|
|
271
309
|
return (
|
|
272
310
|
<div
|
|
273
311
|
{...dataProps}
|
|
@@ -276,7 +314,7 @@ const Typeahead = forwardRef<HTMLInputElement, TypeaheadProps>(({
|
|
|
276
314
|
>
|
|
277
315
|
<Tag
|
|
278
316
|
classNamePrefix="typeahead-kit-select"
|
|
279
|
-
error={
|
|
317
|
+
error={errorDisplay}
|
|
280
318
|
isDisabled={disabled}
|
|
281
319
|
onChange={handleOnChange}
|
|
282
320
|
{...selectProps}
|
|
@@ -101,6 +101,8 @@ module Playbook
|
|
|
101
101
|
plusIcon: plus_icon,
|
|
102
102
|
truncate: truncate,
|
|
103
103
|
wrapped: wrapped,
|
|
104
|
+
required: required,
|
|
105
|
+
validation: validation,
|
|
104
106
|
searchContextSelector: search_context_selector,
|
|
105
107
|
optionsByContext: options_by_context,
|
|
106
108
|
clearOnContextChange: clear_on_context_change,
|