@authhero/widget 0.19.2 → 0.20.0
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.
- package/dist/authhero-widget/authhero-widget.esm.js +1 -1
- package/dist/authhero-widget/index.esm.js +1 -1
- package/dist/authhero-widget/p-59cbb196.entry.js +1 -0
- package/dist/authhero-widget/{p-5hZ8Vbm9.js → p-BFP_5sHV.js} +1 -1
- package/dist/authhero-widget/p-a92fa18e.entry.js +1 -0
- package/dist/cjs/authhero-node.cjs.entry.js +431 -4
- package/dist/cjs/authhero-widget.cjs.entry.js +73 -5
- package/dist/cjs/authhero-widget.cjs.js +2 -2
- package/dist/cjs/{index-vX5cgLV-.js → index-CUBT14z-.js} +21 -0
- package/dist/cjs/index.cjs.js +1 -1
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/collection/components/authhero-node/authhero-node.css +74 -0
- package/dist/collection/components/authhero-node/authhero-node.js +201 -4
- package/dist/collection/components/authhero-widget/authhero-widget.css +2 -2
- package/dist/collection/components/authhero-widget/authhero-widget.js +73 -5
- package/dist/collection/utils/country-data.js +235 -0
- package/dist/components/authhero-node.js +1 -1
- package/dist/components/authhero-widget.js +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/{p-EokuR0qI.js → p-DpfoRsj0.js} +1 -1
- package/dist/components/p-_nTdqfom.js +1 -0
- package/dist/esm/authhero-node.entry.js +431 -4
- package/dist/esm/authhero-widget.entry.js +73 -5
- package/dist/esm/authhero-widget.js +3 -3
- package/dist/esm/{index-5hZ8Vbm9.js → index-BFP_5sHV.js} +21 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/loader.js +3 -3
- package/dist/types/components/authhero-node/authhero-node.d.ts +36 -0
- package/dist/types/components/authhero-widget/authhero-widget.d.ts +15 -1
- package/dist/types/utils/country-data.d.ts +23 -0
- package/hydrate/index.js +524 -8
- package/hydrate/index.mjs +524 -8
- package/package.json +2 -2
- package/dist/authhero-widget/p-18d0a438.entry.js +0 -1
- package/dist/authhero-widget/p-bb3657ce.entry.js +0 -1
- package/dist/components/p-NKUIiiOq.js +0 -1
|
@@ -1,6 +1,242 @@
|
|
|
1
|
-
import { r as registerInstance, c as createEvent, h } from './index-
|
|
1
|
+
import { r as registerInstance, c as createEvent, h } from './index-BFP_5sHV.js';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Country data for phone number input with country code selector.
|
|
5
|
+
* Each entry contains:
|
|
6
|
+
* - code: ISO 3166-1 alpha-2 country code
|
|
7
|
+
* - dialCode: International dialing prefix
|
|
8
|
+
* - flag: Unicode flag emoji
|
|
9
|
+
* - name: Country name in English
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Get flag emoji from ISO 3166-1 alpha-2 country code.
|
|
13
|
+
* Uses Unicode Regional Indicator Symbol Letters.
|
|
14
|
+
*/
|
|
15
|
+
function flagEmoji(code) {
|
|
16
|
+
return String.fromCodePoint(...code
|
|
17
|
+
.toUpperCase()
|
|
18
|
+
.split("")
|
|
19
|
+
.map((c) => 0x1f1e6 - 65 + c.charCodeAt(0)));
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Full list of countries with dial codes, sorted by dial code (numerically)
|
|
23
|
+
* with secondary sort by country code for ties.
|
|
24
|
+
*/
|
|
25
|
+
const countries = [
|
|
26
|
+
{ code: "US", dialCode: "+1", name: "United States" },
|
|
27
|
+
{ code: "CA", dialCode: "+1", name: "Canada" },
|
|
28
|
+
{ code: "AG", dialCode: "+1", name: "Antigua and Barbuda" },
|
|
29
|
+
{ code: "BS", dialCode: "+1", name: "Bahamas" },
|
|
30
|
+
{ code: "BB", dialCode: "+1", name: "Barbados" },
|
|
31
|
+
{ code: "DM", dialCode: "+1", name: "Dominica" },
|
|
32
|
+
{ code: "DO", dialCode: "+1", name: "Dominican Republic" },
|
|
33
|
+
{ code: "GD", dialCode: "+1", name: "Grenada" },
|
|
34
|
+
{ code: "JM", dialCode: "+1", name: "Jamaica" },
|
|
35
|
+
{ code: "KN", dialCode: "+1", name: "Saint Kitts and Nevis" },
|
|
36
|
+
{ code: "LC", dialCode: "+1", name: "Saint Lucia" },
|
|
37
|
+
{ code: "VC", dialCode: "+1", name: "Saint Vincent and the Grenadines" },
|
|
38
|
+
{ code: "TT", dialCode: "+1", name: "Trinidad and Tobago" },
|
|
39
|
+
{ code: "PR", dialCode: "+1", name: "Puerto Rico" },
|
|
40
|
+
{ code: "KZ", dialCode: "+7", name: "Kazakhstan" },
|
|
41
|
+
{ code: "RU", dialCode: "+7", name: "Russia" },
|
|
42
|
+
{ code: "EG", dialCode: "+20", name: "Egypt" },
|
|
43
|
+
{ code: "ZA", dialCode: "+27", name: "South Africa" },
|
|
44
|
+
{ code: "GR", dialCode: "+30", name: "Greece" },
|
|
45
|
+
{ code: "NL", dialCode: "+31", name: "Netherlands" },
|
|
46
|
+
{ code: "BE", dialCode: "+32", name: "Belgium" },
|
|
47
|
+
{ code: "FR", dialCode: "+33", name: "France" },
|
|
48
|
+
{ code: "ES", dialCode: "+34", name: "Spain" },
|
|
49
|
+
{ code: "HU", dialCode: "+36", name: "Hungary" },
|
|
50
|
+
{ code: "IT", dialCode: "+39", name: "Italy" },
|
|
51
|
+
{ code: "RO", dialCode: "+40", name: "Romania" },
|
|
52
|
+
{ code: "CH", dialCode: "+41", name: "Switzerland" },
|
|
53
|
+
{ code: "AT", dialCode: "+43", name: "Austria" },
|
|
54
|
+
{ code: "GB", dialCode: "+44", name: "United Kingdom" },
|
|
55
|
+
{ code: "DK", dialCode: "+45", name: "Denmark" },
|
|
56
|
+
{ code: "SE", dialCode: "+46", name: "Sweden" },
|
|
57
|
+
{ code: "NO", dialCode: "+47", name: "Norway" },
|
|
58
|
+
{ code: "PL", dialCode: "+48", name: "Poland" },
|
|
59
|
+
{ code: "DE", dialCode: "+49", name: "Germany" },
|
|
60
|
+
{ code: "PE", dialCode: "+51", name: "Peru" },
|
|
61
|
+
{ code: "MX", dialCode: "+52", name: "Mexico" },
|
|
62
|
+
{ code: "CU", dialCode: "+53", name: "Cuba" },
|
|
63
|
+
{ code: "AR", dialCode: "+54", name: "Argentina" },
|
|
64
|
+
{ code: "BR", dialCode: "+55", name: "Brazil" },
|
|
65
|
+
{ code: "CL", dialCode: "+56", name: "Chile" },
|
|
66
|
+
{ code: "CO", dialCode: "+57", name: "Colombia" },
|
|
67
|
+
{ code: "VE", dialCode: "+58", name: "Venezuela" },
|
|
68
|
+
{ code: "MY", dialCode: "+60", name: "Malaysia" },
|
|
69
|
+
{ code: "AU", dialCode: "+61", name: "Australia" },
|
|
70
|
+
{ code: "ID", dialCode: "+62", name: "Indonesia" },
|
|
71
|
+
{ code: "PH", dialCode: "+63", name: "Philippines" },
|
|
72
|
+
{ code: "NZ", dialCode: "+64", name: "New Zealand" },
|
|
73
|
+
{ code: "SG", dialCode: "+65", name: "Singapore" },
|
|
74
|
+
{ code: "TH", dialCode: "+66", name: "Thailand" },
|
|
75
|
+
{ code: "JP", dialCode: "+81", name: "Japan" },
|
|
76
|
+
{ code: "KR", dialCode: "+82", name: "South Korea" },
|
|
77
|
+
{ code: "VN", dialCode: "+84", name: "Vietnam" },
|
|
78
|
+
{ code: "CN", dialCode: "+86", name: "China" },
|
|
79
|
+
{ code: "TR", dialCode: "+90", name: "Turkey" },
|
|
80
|
+
{ code: "IN", dialCode: "+91", name: "India" },
|
|
81
|
+
{ code: "PK", dialCode: "+92", name: "Pakistan" },
|
|
82
|
+
{ code: "AF", dialCode: "+93", name: "Afghanistan" },
|
|
83
|
+
{ code: "LK", dialCode: "+94", name: "Sri Lanka" },
|
|
84
|
+
{ code: "MM", dialCode: "+95", name: "Myanmar" },
|
|
85
|
+
{ code: "IR", dialCode: "+98", name: "Iran" },
|
|
86
|
+
{ code: "SS", dialCode: "+211", name: "South Sudan" },
|
|
87
|
+
{ code: "MA", dialCode: "+212", name: "Morocco" },
|
|
88
|
+
{ code: "DZ", dialCode: "+213", name: "Algeria" },
|
|
89
|
+
{ code: "TN", dialCode: "+216", name: "Tunisia" },
|
|
90
|
+
{ code: "LY", dialCode: "+218", name: "Libya" },
|
|
91
|
+
{ code: "GM", dialCode: "+220", name: "Gambia" },
|
|
92
|
+
{ code: "SN", dialCode: "+221", name: "Senegal" },
|
|
93
|
+
{ code: "MR", dialCode: "+222", name: "Mauritania" },
|
|
94
|
+
{ code: "ML", dialCode: "+223", name: "Mali" },
|
|
95
|
+
{ code: "GN", dialCode: "+224", name: "Guinea" },
|
|
96
|
+
{ code: "CI", dialCode: "+225", name: "Ivory Coast" },
|
|
97
|
+
{ code: "BF", dialCode: "+226", name: "Burkina Faso" },
|
|
98
|
+
{ code: "NE", dialCode: "+227", name: "Niger" },
|
|
99
|
+
{ code: "TG", dialCode: "+228", name: "Togo" },
|
|
100
|
+
{ code: "BJ", dialCode: "+229", name: "Benin" },
|
|
101
|
+
{ code: "MU", dialCode: "+230", name: "Mauritius" },
|
|
102
|
+
{ code: "LR", dialCode: "+231", name: "Liberia" },
|
|
103
|
+
{ code: "SL", dialCode: "+232", name: "Sierra Leone" },
|
|
104
|
+
{ code: "GH", dialCode: "+233", name: "Ghana" },
|
|
105
|
+
{ code: "NG", dialCode: "+234", name: "Nigeria" },
|
|
106
|
+
{ code: "TD", dialCode: "+235", name: "Chad" },
|
|
107
|
+
{ code: "CF", dialCode: "+236", name: "Central African Republic" },
|
|
108
|
+
{ code: "CM", dialCode: "+237", name: "Cameroon" },
|
|
109
|
+
{ code: "CV", dialCode: "+238", name: "Cape Verde" },
|
|
110
|
+
{ code: "ST", dialCode: "+239", name: "São Tomé and Príncipe" },
|
|
111
|
+
{ code: "GQ", dialCode: "+240", name: "Equatorial Guinea" },
|
|
112
|
+
{ code: "GA", dialCode: "+241", name: "Gabon" },
|
|
113
|
+
{ code: "CG", dialCode: "+242", name: "Congo" },
|
|
114
|
+
{ code: "CD", dialCode: "+243", name: "Congo (DRC)" },
|
|
115
|
+
{ code: "AO", dialCode: "+244", name: "Angola" },
|
|
116
|
+
{ code: "GW", dialCode: "+245", name: "Guinea-Bissau" },
|
|
117
|
+
{ code: "SC", dialCode: "+248", name: "Seychelles" },
|
|
118
|
+
{ code: "SD", dialCode: "+249", name: "Sudan" },
|
|
119
|
+
{ code: "RW", dialCode: "+250", name: "Rwanda" },
|
|
120
|
+
{ code: "ET", dialCode: "+251", name: "Ethiopia" },
|
|
121
|
+
{ code: "SO", dialCode: "+252", name: "Somalia" },
|
|
122
|
+
{ code: "DJ", dialCode: "+253", name: "Djibouti" },
|
|
123
|
+
{ code: "KE", dialCode: "+254", name: "Kenya" },
|
|
124
|
+
{ code: "TZ", dialCode: "+255", name: "Tanzania" },
|
|
125
|
+
{ code: "UG", dialCode: "+256", name: "Uganda" },
|
|
126
|
+
{ code: "BI", dialCode: "+257", name: "Burundi" },
|
|
127
|
+
{ code: "MZ", dialCode: "+258", name: "Mozambique" },
|
|
128
|
+
{ code: "ZM", dialCode: "+260", name: "Zambia" },
|
|
129
|
+
{ code: "MG", dialCode: "+261", name: "Madagascar" },
|
|
130
|
+
{ code: "RE", dialCode: "+262", name: "Réunion" },
|
|
131
|
+
{ code: "ZW", dialCode: "+263", name: "Zimbabwe" },
|
|
132
|
+
{ code: "NA", dialCode: "+264", name: "Namibia" },
|
|
133
|
+
{ code: "MW", dialCode: "+265", name: "Malawi" },
|
|
134
|
+
{ code: "LS", dialCode: "+266", name: "Lesotho" },
|
|
135
|
+
{ code: "BW", dialCode: "+267", name: "Botswana" },
|
|
136
|
+
{ code: "SZ", dialCode: "+268", name: "Eswatini" },
|
|
137
|
+
{ code: "KM", dialCode: "+269", name: "Comoros" },
|
|
138
|
+
{ code: "ER", dialCode: "+291", name: "Eritrea" },
|
|
139
|
+
{ code: "PT", dialCode: "+351", name: "Portugal" },
|
|
140
|
+
{ code: "LU", dialCode: "+352", name: "Luxembourg" },
|
|
141
|
+
{ code: "IE", dialCode: "+353", name: "Ireland" },
|
|
142
|
+
{ code: "IS", dialCode: "+354", name: "Iceland" },
|
|
143
|
+
{ code: "AL", dialCode: "+355", name: "Albania" },
|
|
144
|
+
{ code: "MT", dialCode: "+356", name: "Malta" },
|
|
145
|
+
{ code: "CY", dialCode: "+357", name: "Cyprus" },
|
|
146
|
+
{ code: "FI", dialCode: "+358", name: "Finland" },
|
|
147
|
+
{ code: "BG", dialCode: "+359", name: "Bulgaria" },
|
|
148
|
+
{ code: "LT", dialCode: "+370", name: "Lithuania" },
|
|
149
|
+
{ code: "LV", dialCode: "+371", name: "Latvia" },
|
|
150
|
+
{ code: "EE", dialCode: "+372", name: "Estonia" },
|
|
151
|
+
{ code: "MD", dialCode: "+373", name: "Moldova" },
|
|
152
|
+
{ code: "AM", dialCode: "+374", name: "Armenia" },
|
|
153
|
+
{ code: "BY", dialCode: "+375", name: "Belarus" },
|
|
154
|
+
{ code: "AD", dialCode: "+376", name: "Andorra" },
|
|
155
|
+
{ code: "MC", dialCode: "+377", name: "Monaco" },
|
|
156
|
+
{ code: "SM", dialCode: "+378", name: "San Marino" },
|
|
157
|
+
{ code: "UA", dialCode: "+380", name: "Ukraine" },
|
|
158
|
+
{ code: "RS", dialCode: "+381", name: "Serbia" },
|
|
159
|
+
{ code: "ME", dialCode: "+382", name: "Montenegro" },
|
|
160
|
+
{ code: "XK", dialCode: "+383", name: "Kosovo" },
|
|
161
|
+
{ code: "HR", dialCode: "+385", name: "Croatia" },
|
|
162
|
+
{ code: "SI", dialCode: "+386", name: "Slovenia" },
|
|
163
|
+
{ code: "BA", dialCode: "+387", name: "Bosnia and Herzegovina" },
|
|
164
|
+
{ code: "MK", dialCode: "+389", name: "North Macedonia" },
|
|
165
|
+
{ code: "CZ", dialCode: "+420", name: "Czech Republic" },
|
|
166
|
+
{ code: "SK", dialCode: "+421", name: "Slovakia" },
|
|
167
|
+
{ code: "LI", dialCode: "+423", name: "Liechtenstein" },
|
|
168
|
+
{ code: "FK", dialCode: "+500", name: "Falkland Islands" },
|
|
169
|
+
{ code: "BZ", dialCode: "+501", name: "Belize" },
|
|
170
|
+
{ code: "GT", dialCode: "+502", name: "Guatemala" },
|
|
171
|
+
{ code: "SV", dialCode: "+503", name: "El Salvador" },
|
|
172
|
+
{ code: "HN", dialCode: "+504", name: "Honduras" },
|
|
173
|
+
{ code: "NI", dialCode: "+505", name: "Nicaragua" },
|
|
174
|
+
{ code: "CR", dialCode: "+506", name: "Costa Rica" },
|
|
175
|
+
{ code: "PA", dialCode: "+507", name: "Panama" },
|
|
176
|
+
{ code: "HT", dialCode: "+509", name: "Haiti" },
|
|
177
|
+
{ code: "GP", dialCode: "+590", name: "Guadeloupe" },
|
|
178
|
+
{ code: "BO", dialCode: "+591", name: "Bolivia" },
|
|
179
|
+
{ code: "GY", dialCode: "+592", name: "Guyana" },
|
|
180
|
+
{ code: "EC", dialCode: "+593", name: "Ecuador" },
|
|
181
|
+
{ code: "GF", dialCode: "+594", name: "French Guiana" },
|
|
182
|
+
{ code: "PY", dialCode: "+595", name: "Paraguay" },
|
|
183
|
+
{ code: "MQ", dialCode: "+596", name: "Martinique" },
|
|
184
|
+
{ code: "SR", dialCode: "+597", name: "Suriname" },
|
|
185
|
+
{ code: "UY", dialCode: "+598", name: "Uruguay" },
|
|
186
|
+
{ code: "TL", dialCode: "+670", name: "Timor-Leste" },
|
|
187
|
+
{ code: "BN", dialCode: "+673", name: "Brunei" },
|
|
188
|
+
{ code: "NR", dialCode: "+674", name: "Nauru" },
|
|
189
|
+
{ code: "PG", dialCode: "+675", name: "Papua New Guinea" },
|
|
190
|
+
{ code: "TO", dialCode: "+676", name: "Tonga" },
|
|
191
|
+
{ code: "SB", dialCode: "+677", name: "Solomon Islands" },
|
|
192
|
+
{ code: "VU", dialCode: "+678", name: "Vanuatu" },
|
|
193
|
+
{ code: "FJ", dialCode: "+679", name: "Fiji" },
|
|
194
|
+
{ code: "PW", dialCode: "+680", name: "Palau" },
|
|
195
|
+
{ code: "WS", dialCode: "+685", name: "Samoa" },
|
|
196
|
+
{ code: "KI", dialCode: "+686", name: "Kiribati" },
|
|
197
|
+
{ code: "FM", dialCode: "+691", name: "Micronesia" },
|
|
198
|
+
{ code: "MH", dialCode: "+692", name: "Marshall Islands" },
|
|
199
|
+
{ code: "KP", dialCode: "+850", name: "North Korea" },
|
|
200
|
+
{ code: "HK", dialCode: "+852", name: "Hong Kong" },
|
|
201
|
+
{ code: "MO", dialCode: "+853", name: "Macau" },
|
|
202
|
+
{ code: "KH", dialCode: "+855", name: "Cambodia" },
|
|
203
|
+
{ code: "LA", dialCode: "+856", name: "Laos" },
|
|
204
|
+
{ code: "BD", dialCode: "+880", name: "Bangladesh" },
|
|
205
|
+
{ code: "TW", dialCode: "+886", name: "Taiwan" },
|
|
206
|
+
{ code: "MV", dialCode: "+960", name: "Maldives" },
|
|
207
|
+
{ code: "LB", dialCode: "+961", name: "Lebanon" },
|
|
208
|
+
{ code: "JO", dialCode: "+962", name: "Jordan" },
|
|
209
|
+
{ code: "SY", dialCode: "+963", name: "Syria" },
|
|
210
|
+
{ code: "IQ", dialCode: "+964", name: "Iraq" },
|
|
211
|
+
{ code: "KW", dialCode: "+965", name: "Kuwait" },
|
|
212
|
+
{ code: "SA", dialCode: "+966", name: "Saudi Arabia" },
|
|
213
|
+
{ code: "YE", dialCode: "+967", name: "Yemen" },
|
|
214
|
+
{ code: "OM", dialCode: "+968", name: "Oman" },
|
|
215
|
+
{ code: "PS", dialCode: "+970", name: "Palestine" },
|
|
216
|
+
{ code: "AE", dialCode: "+971", name: "United Arab Emirates" },
|
|
217
|
+
{ code: "IL", dialCode: "+972", name: "Israel" },
|
|
218
|
+
{ code: "BH", dialCode: "+973", name: "Bahrain" },
|
|
219
|
+
{ code: "QA", dialCode: "+974", name: "Qatar" },
|
|
220
|
+
{ code: "BT", dialCode: "+975", name: "Bhutan" },
|
|
221
|
+
{ code: "MN", dialCode: "+976", name: "Mongolia" },
|
|
222
|
+
{ code: "NP", dialCode: "+977", name: "Nepal" },
|
|
223
|
+
{ code: "TJ", dialCode: "+992", name: "Tajikistan" },
|
|
224
|
+
{ code: "TM", dialCode: "+993", name: "Turkmenistan" },
|
|
225
|
+
{ code: "AZ", dialCode: "+994", name: "Azerbaijan" },
|
|
226
|
+
{ code: "GE", dialCode: "+995", name: "Georgia" },
|
|
227
|
+
{ code: "KG", dialCode: "+996", name: "Kyrgyzstan" },
|
|
228
|
+
{ code: "UZ", dialCode: "+998", name: "Uzbekistan" },
|
|
229
|
+
].map((c) => ({ ...c, flag: flagEmoji(c.code) }));
|
|
230
|
+
/**
|
|
231
|
+
* Find a country by its ISO code, defaulting to US.
|
|
232
|
+
*/
|
|
233
|
+
function getCountryByCode(code) {
|
|
234
|
+
const upper = code.toUpperCase();
|
|
235
|
+
return (countries.find((c) => c.code === upper) ||
|
|
236
|
+
countries.find((c) => c.code === "US"));
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const authheroNodeCss = () => `:host{display:block}.input-wrapper{display:flex;flex-direction:column;position:relative;margin-top:8px;margin-bottom:16px}.input-container{position:relative;width:100%}.input-label{position:absolute;left:16px;top:50%;transform:translateY(-50%);font-size:16px;font-weight:var(--ah-font-weight-label, 400);color:var(--ah-color-text-muted, #65676e);pointer-events:none;transition:all 0.15s ease-out;background-color:transparent;padding:0;z-index:1}.input-label.floating,.input-field:focus+.input-label,.input-field:not(:placeholder-shown)+.input-label,select.input-field+.input-label,input[type="date"].input-field+.input-label{top:-8px;transform:translateY(0);font-size:12px;background-color:var(--ah-color-bg, #ffffff);padding:0 4px;left:12px;color:var(--ah-color-text-muted, #65676e)}.input-field:focus+.input-label{color:var(--ah-color-primary, #635dff)}.required{color:var(--ah-color-error, #d03c38);margin-left:2px}.input-field{width:100%;padding:16px;font-size:16px;font-family:inherit;color:var(--ah-color-text, #1e212a);background-color:var(--ah-color-input-bg, #ffffff);border:1px solid var(--ah-color-border, #c9cace);border-radius:var(--ah-input-radius, 3px);outline:none;transition:border-color 0.15s ease-out,\\n box-shadow 0.15s ease-out;box-sizing:border-box}.input-field::placeholder{color:transparent}.input-field:hover{border-color:var(--ah-color-border-hover, #65676e)}.input-field:focus{border-color:var(--ah-color-primary, #635dff);box-shadow:inset 0 0 0 1px var(--ah-color-primary, #635dff)}.input-field.has-error{border-color:var(--ah-color-error, #d03c38)}.input-field.has-error:focus{box-shadow:inset 0 0 0 1px var(--ah-color-error, #d03c38)}.input-field:disabled{background-color:var(--ah-color-bg-disabled, #f5f5f5);border-color:var(--ah-color-border-disabled, #e0e1e3);cursor:not-allowed;opacity:0.7}.password-container{position:relative;display:flex;align-items:center}.password-container .input-field{padding-right:48px}.password-toggle{position:absolute;right:12px;top:50%;transform:translateY(-50%);background:none;border:none;cursor:pointer;padding:4px;display:flex;align-items:center;justify-content:center;color:var(--ah-color-text-muted, #65676e);transition:color 0.15s ease}.password-toggle:hover{color:var(--ah-color-text, #1e212a)}.password-toggle svg{width:20px;height:20px}.error-text{font-size:12px;color:var(--ah-color-error, #d03c38);margin-top:4px;line-height:1.4}.helper-text{font-size:12px;color:var(--ah-color-text-muted, #65676e);margin-top:4px;line-height:1.4}.field-link{display:block;text-align:left;margin-top:8px;margin-bottom:16px}.field-link a{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:14px;font-weight:var(--ah-font-weight-link, 400)}.field-link a:hover{text-decoration:underline}.checkbox-wrapper{display:flex;align-items:flex-start;gap:10px;cursor:pointer;margin-bottom:16px}.checkbox-wrapper input[type="checkbox"]{width:18px;height:18px;margin:0;accent-color:var(--ah-color-primary, #635dff);cursor:pointer;flex-shrink:0}.checkbox-label{font-size:14px;color:var(--ah-color-text, #1e212a);line-height:1.5}.btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;width:100%;padding:14px 20px;font-size:16px;font-weight:var(--ah-font-weight-btn, 400);font-family:inherit;line-height:1.25;text-align:center;text-decoration:none;border:none;border-radius:var(--ah-btn-radius, 3px);cursor:pointer;transition:background-color 0.15s ease,\\n border-color 0.15s ease,\\n transform 0.1s ease;box-sizing:border-box}.btn:disabled{opacity:0.6;cursor:not-allowed}.btn:not(:disabled):active{transform:scale(0.98)}.btn:focus-visible{outline:2px solid var(--ah-color-primary, #635dff);outline-offset:2px}.btn-primary{background-color:var(--ah-color-primary, #635dff);color:var(--ah-color-text-on-primary, #ffffff);margin-top:12px}.btn-primary:not(:disabled):hover{filter:brightness(0.85)}.btn-secondary{background-color:var(--ah-color-bg, #ffffff);color:var(--ah-color-text, #1e212a);border:1px solid var(--ah-color-border, #c9cace)}.btn-secondary:not(:disabled):hover{background-color:var(--ah-color-bg-hover, #f5f5f5);border-color:var(--ah-color-border-hover, #65676e)}.btn-link{background:none;border:none;color:var(--ah-color-link, #635dff);padding:8px 0;font-weight:var(--ah-font-weight-link, 400);text-decoration:none}.btn-link:hover{text-decoration:underline}.phone-input-wrapper{display:flex;align-items:stretch;gap:0;width:100%}.country-select{flex-shrink:0;width:auto;padding:12px 8px;font-size:var(--ah-font-size-body, 16px);font-family:var(--ah-font-family, inherit);border:1px solid var(--ah-color-border, #c9cace);border-right:none;border-radius:var(--ah-border-radius-input, 4px) 0 0 var(--ah-border-radius-input, 4px);background-color:var(--ah-color-surface, #fff);color:var(--ah-color-text, #1e212a);cursor:pointer;appearance:none;-webkit-appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 6px center;padding-right:22px}.country-select:focus{outline:none;border-color:var(--ah-color-primary, #635dff);box-shadow:0 0 0 1px var(--ah-color-primary, #635dff)}.country-select:disabled{opacity:0.5;cursor:not-allowed}.phone-input-wrapper .input-container{flex:1;min-width:0}.phone-input-wrapper .input-field{border-radius:0 var(--ah-border-radius-input, 4px) var(--ah-border-radius-input, 4px) 0}.phone-input-wrapper .input-label.floating,.phone-input-wrapper .input-field:focus+.input-label,.phone-input-wrapper .input-field:not(:placeholder-shown)+.input-label{left:8px}.social-buttons{display:flex;flex-direction:column;gap:12px}.btn-social{display:flex;align-items:center;justify-content:center;gap:12px}.btn-social-content{display:flex;flex-direction:column;align-items:center;text-align:center}.btn-social-subtitle{font-size:12px;font-style:italic;opacity:0.8;margin-top:2px}.btn-social-subtitle:empty{display:none}.social-icon{width:20px;height:20px;flex-shrink:0}@media (max-width: 480px){.social-buttons:has(.btn-social:nth-child(3)){flex-direction:row;flex-wrap:nowrap;justify-content:stretch;gap:8px}.social-buttons:has(.btn-social:nth-child(3)) .btn-social{width:auto;min-width:0;padding:12px;flex:1 1 0}.social-buttons:has(.btn-social:nth-child(3)) .btn-social span{display:none}.social-buttons:has(.btn-social:nth-child(3)) .social-icon{width:24px;height:24px}}.btn-icon{width:20px;height:20px;flex-shrink:0}.btn-icon img{width:100%;height:100%;object-fit:contain}.text-title{font-size:20px;font-weight:400;color:var(--ah-color-text, #1e212a);margin:8px 0;line-height:1.3}.text-title.text-success{color:var(--ah-color-success, #13a769)}.text-description{font-size:14px;color:var(--ah-color-text-muted, #65676e);margin:4px 0;line-height:1.5}.image{display:block;max-width:100%;height:auto;border-radius:4px}.image-centered{margin:0 auto 16px;width:52px;height:52px;object-fit:contain}.link{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:14px;transition:color 0.15s ease}.link:hover{text-decoration:underline}.link:focus-visible{outline:2px solid var(--ah-color-link, #635dff);outline-offset:2px;border-radius:2px}.node-error{padding:12px 16px;background-color:var(--ah-color-error-bg, #ffeaea);color:var(--ah-color-error, #d03c38);border-left:3px solid var(--ah-color-error, #d03c38);border-radius:0;font-size:14px;margin-bottom:16px}.node-success{padding:12px 16px;background-color:var(--ah-color-success-bg, #e6f9f1);color:var(--ah-color-success, #13a769);border-left:3px solid var(--ah-color-success, #13a769);border-radius:0;font-size:14px;margin-bottom:16px}.divider{display:flex;align-items:center;text-align:center;margin:16px 0}.divider::before,.divider::after{content:"";flex:1;border-bottom:1px solid var(--ah-color-border-muted, #c9cace)}.divider-text{padding:0 10px;font-size:12px;font-weight:400;color:var(--ah-color-text-muted, #65676e);text-transform:uppercase;letter-spacing:0.5px}.rich-text{font-size:14px;line-height:1.5;color:var(--ah-color-text, #1e212a)}.rich-text a{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);transition:color 0.15s ease}.rich-text a:hover{text-decoration:underline}.rich-text .terms-text{margin-top:16px;text-align:center;font-size:12px;color:var(--ah-color-text-muted, #65676e)}.rich-text .terms-text a{font-size:12px}.rich-text .forgot-password-link{text-align:right;font-size:13px;margin-top:4px}.rich-text .forgot-password-link a{font-size:13px;color:var(--ah-color-link, #635dff)}.rich-text .passwordless-link{margin-top:16px;text-align:center;font-size:14px}.rich-text .passwordless-link a{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none)}.rich-text .passwordless-link a:hover{text-decoration:underline}.rich-text .signup-link{margin-top:16px;text-align:center;font-size:14px;color:var(--ah-color-text, #1e212a)}`;
|
|
4
240
|
|
|
5
241
|
const AuthheroNode = class {
|
|
6
242
|
constructor(hostRef) {
|
|
@@ -25,6 +261,23 @@ const AuthheroNode = class {
|
|
|
25
261
|
* Whether the password field is visible.
|
|
26
262
|
*/
|
|
27
263
|
passwordVisible = false;
|
|
264
|
+
/**
|
|
265
|
+
* Selected country for TEL input with country selector.
|
|
266
|
+
*/
|
|
267
|
+
selectedCountry = getCountryByCode("US");
|
|
268
|
+
/**
|
|
269
|
+
* Local phone number (without dial code) for TEL input.
|
|
270
|
+
*/
|
|
271
|
+
localPhoneNumber = "";
|
|
272
|
+
/**
|
|
273
|
+
* Whether the country dropdown is open.
|
|
274
|
+
*/
|
|
275
|
+
countryDropdownOpen = false;
|
|
276
|
+
/**
|
|
277
|
+
* Whether the TEL field is currently in email mode (allow_email config).
|
|
278
|
+
* When true, the value is emitted as-is without dial code prefix.
|
|
279
|
+
*/
|
|
280
|
+
telEmailMode = false;
|
|
28
281
|
/**
|
|
29
282
|
* Emitted when a field value changes.
|
|
30
283
|
*/
|
|
@@ -33,6 +286,153 @@ const AuthheroNode = class {
|
|
|
33
286
|
* Emitted when a button is clicked.
|
|
34
287
|
*/
|
|
35
288
|
buttonClick;
|
|
289
|
+
componentChanged() {
|
|
290
|
+
this.initCountryFromConfig();
|
|
291
|
+
this.initTelValue();
|
|
292
|
+
}
|
|
293
|
+
valueChanged() {
|
|
294
|
+
this.initTelValue();
|
|
295
|
+
}
|
|
296
|
+
componentWillLoad() {
|
|
297
|
+
this.initCountryFromConfig();
|
|
298
|
+
this.initTelValue();
|
|
299
|
+
}
|
|
300
|
+
initCountryFromConfig() {
|
|
301
|
+
if (this.component?.type === "TEL") {
|
|
302
|
+
const config = this.component.config;
|
|
303
|
+
const defaultCountry = config?.default_country;
|
|
304
|
+
if (defaultCountry) {
|
|
305
|
+
this.selectedCountry = getCountryByCode(defaultCountry);
|
|
306
|
+
}
|
|
307
|
+
// For allow_email mode, start in email/text mode (no country picker)
|
|
308
|
+
// until the user starts typing digits
|
|
309
|
+
if (config?.allow_email === true) {
|
|
310
|
+
this.telEmailMode = true;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Hydrate localPhoneNumber (and selectedCountry) from the effective value
|
|
316
|
+
* for TEL fields. The full value is stored as `{dialCode}{localNumber}`,
|
|
317
|
+
* e.g. "+15551234567".
|
|
318
|
+
*/
|
|
319
|
+
initTelValue() {
|
|
320
|
+
if (this.component?.type !== "TEL")
|
|
321
|
+
return;
|
|
322
|
+
const config = this.component.config;
|
|
323
|
+
const allowEmail = config?.allow_email === true;
|
|
324
|
+
const fullValue = this.getEffectiveValue();
|
|
325
|
+
if (!fullValue) {
|
|
326
|
+
this.localPhoneNumber = "";
|
|
327
|
+
if (allowEmail) {
|
|
328
|
+
this.telEmailMode = true;
|
|
329
|
+
}
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
// Try to match a country by dial code (longest match first)
|
|
333
|
+
if (fullValue.startsWith("+")) {
|
|
334
|
+
const sorted = [...countries].sort((a, b) => b.dialCode.length - a.dialCode.length);
|
|
335
|
+
for (const country of sorted) {
|
|
336
|
+
if (fullValue.startsWith(country.dialCode)) {
|
|
337
|
+
this.selectedCountry = country;
|
|
338
|
+
this.localPhoneNumber = fullValue.slice(country.dialCode.length);
|
|
339
|
+
if (allowEmail) {
|
|
340
|
+
this.telEmailMode = false;
|
|
341
|
+
}
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
// No dial code match — check if it looks like an email or a phone number
|
|
347
|
+
this.localPhoneNumber = fullValue;
|
|
348
|
+
if (allowEmail) {
|
|
349
|
+
const looksLikePhone = /^[+\d]/.test(fullValue);
|
|
350
|
+
this.telEmailMode = !looksLikePhone;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
handleCountryChange = (e) => {
|
|
354
|
+
const target = e.target;
|
|
355
|
+
this.selectedCountry = getCountryByCode(target.value);
|
|
356
|
+
// Re-emit the full phone number with new dial code
|
|
357
|
+
const fullNumber = this.localPhoneNumber
|
|
358
|
+
? `${this.selectedCountry.dialCode}${this.localPhoneNumber}`
|
|
359
|
+
: "";
|
|
360
|
+
this.fieldChange.emit({ id: this.component.id, value: fullNumber });
|
|
361
|
+
};
|
|
362
|
+
/**
|
|
363
|
+
* Try to detect a dial code prefix in the raw input (e.g. "+46", "0046")
|
|
364
|
+
* and update selectedCountry accordingly. Returns the local number portion
|
|
365
|
+
* (after the dial code) if a match was found, or null if no match.
|
|
366
|
+
*/
|
|
367
|
+
detectDialCodeFromInput(raw) {
|
|
368
|
+
// Normalise "00" international prefix to "+"
|
|
369
|
+
const normalized = raw.startsWith("00") ? "+" + raw.slice(2) : raw;
|
|
370
|
+
if (!normalized.startsWith("+"))
|
|
371
|
+
return null;
|
|
372
|
+
// Match longest dial code first
|
|
373
|
+
const sorted = [...countries].sort((a, b) => b.dialCode.length - a.dialCode.length);
|
|
374
|
+
for (const country of sorted) {
|
|
375
|
+
if (normalized.startsWith(country.dialCode)) {
|
|
376
|
+
this.selectedCountry = country;
|
|
377
|
+
return normalized.slice(country.dialCode.length);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
return null;
|
|
381
|
+
}
|
|
382
|
+
handlePhoneInput = (e) => {
|
|
383
|
+
const target = e.target;
|
|
384
|
+
const value = target.value;
|
|
385
|
+
const config = this.component.config;
|
|
386
|
+
const allowEmail = config?.allow_email === true;
|
|
387
|
+
if (allowEmail) {
|
|
388
|
+
// Detect phone mode: value starts with digit or '+', and no '@'.
|
|
389
|
+
// When the field is empty, revert to neutral (email) mode so the
|
|
390
|
+
// country picker disappears and the user can start fresh.
|
|
391
|
+
const looksLikePhone = value.length > 0 && /^[+\d]/.test(value) && !value.includes("@");
|
|
392
|
+
this.telEmailMode = !looksLikePhone;
|
|
393
|
+
if (!this.telEmailMode) {
|
|
394
|
+
// Phone mode — first try dial code detection before stripping '+'
|
|
395
|
+
// so that typing +46 or 0046 can match a country
|
|
396
|
+
const dialLocal = this.detectDialCodeFromInput(value);
|
|
397
|
+
if (dialLocal !== null) {
|
|
398
|
+
// Dial code matched — strip it from the input and show only local part
|
|
399
|
+
const cleanedLocal = dialLocal.replace(/[^+\d\s\-()]/g, "").replace(/\+/g, "");
|
|
400
|
+
target.value = cleanedLocal;
|
|
401
|
+
this.localPhoneNumber = cleanedLocal;
|
|
402
|
+
const fullNumber = `${this.selectedCountry.dialCode}${cleanedLocal}`;
|
|
403
|
+
this.fieldChange.emit({ id: this.component.id, value: fullNumber });
|
|
404
|
+
}
|
|
405
|
+
else {
|
|
406
|
+
// No dial code — strip non-phone chars and '+' (picker provides the prefix)
|
|
407
|
+
const cleaned = value.replace(/[^+\d\s\-()]/g, "").replace(/\+/g, "");
|
|
408
|
+
if (cleaned !== value) {
|
|
409
|
+
target.value = cleaned;
|
|
410
|
+
}
|
|
411
|
+
this.localPhoneNumber = cleaned;
|
|
412
|
+
const fullNumber = cleaned
|
|
413
|
+
? `${this.selectedCountry.dialCode}${cleaned}`
|
|
414
|
+
: "";
|
|
415
|
+
this.fieldChange.emit({ id: this.component.id, value: fullNumber });
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
else {
|
|
419
|
+
// Email or text — emit as-is
|
|
420
|
+
this.localPhoneNumber = value;
|
|
421
|
+
this.fieldChange.emit({ id: this.component.id, value });
|
|
422
|
+
}
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
// Standard phone-only mode — strip '+' since the picker provides the prefix
|
|
426
|
+
const cleaned = value.replace(/[^\d\s\-()]/g, "");
|
|
427
|
+
if (cleaned !== value) {
|
|
428
|
+
target.value = cleaned;
|
|
429
|
+
}
|
|
430
|
+
this.localPhoneNumber = cleaned;
|
|
431
|
+
const fullNumber = cleaned
|
|
432
|
+
? `${this.selectedCountry.dialCode}${cleaned}`
|
|
433
|
+
: "";
|
|
434
|
+
this.fieldChange.emit({ id: this.component.id, value: fullNumber });
|
|
435
|
+
};
|
|
36
436
|
handleInput = (e) => {
|
|
37
437
|
const target = e.target;
|
|
38
438
|
this.fieldChange.emit({ id: this.component.id, value: target.value });
|
|
@@ -42,6 +442,16 @@ const AuthheroNode = class {
|
|
|
42
442
|
e.preventDefault();
|
|
43
443
|
this.buttonClick.emit({ id: "submit", type: "submit", value: "next" });
|
|
44
444
|
}
|
|
445
|
+
// In combined TEL+email mode, backspace on an empty field exits phone mode
|
|
446
|
+
if (e.key === "Backspace" && !this.telEmailMode) {
|
|
447
|
+
const target = e.target;
|
|
448
|
+
const config = this.component.config;
|
|
449
|
+
if (config?.allow_email === true && target.value.length === 0) {
|
|
450
|
+
this.telEmailMode = true;
|
|
451
|
+
this.localPhoneNumber = "";
|
|
452
|
+
this.fieldChange.emit({ id: this.component.id, value: "" });
|
|
453
|
+
}
|
|
454
|
+
}
|
|
45
455
|
};
|
|
46
456
|
handleCheckbox = (e) => {
|
|
47
457
|
const target = e.target;
|
|
@@ -214,8 +624,17 @@ const AuthheroNode = class {
|
|
|
214
624
|
renderTelField(component) {
|
|
215
625
|
const inputId = `input-${component.id}`;
|
|
216
626
|
const errors = this.getErrors();
|
|
217
|
-
const
|
|
218
|
-
|
|
627
|
+
const config = component.config;
|
|
628
|
+
const allowEmail = config?.allow_email === true;
|
|
629
|
+
const hasValue = this.localPhoneNumber.length > 0;
|
|
630
|
+
// In allow_email mode, show the country picker only when the user is typing a phone number
|
|
631
|
+
const showCountryPicker = allowEmail ? !this.telEmailMode : true;
|
|
632
|
+
// Calculate dynamic width: flag + space + dial code + small padding for dropdown arrow
|
|
633
|
+
const selectedText = `${this.selectedCountry.flag} ${this.selectedCountry.dialCode}`;
|
|
634
|
+
const selectWidth = `${selectedText.length + 1}ch`;
|
|
635
|
+
const countrySelect = showCountryPicker ? (h("select", { class: "country-select", part: "country-select", style: { width: selectWidth, minWidth: "0" }, onChange: this.handleCountryChange, disabled: this.disabled, "aria-label": "Country code" }, countries.map((country) => (h("option", { value: country.code, selected: this.selectedCountry.code === country.code, key: country.code }, country.flag, " ", country.dialCode))))) : null;
|
|
636
|
+
const inputType = allowEmail && this.telEmailMode ? "text" : "tel";
|
|
637
|
+
return (h("div", { class: "input-wrapper", part: "input-wrapper" }, h("div", { class: showCountryPicker ? "phone-input-wrapper" : "", part: "phone-input-wrapper" }, countrySelect, h("div", { class: "input-container" }, h("input", { id: inputId, class: this.getInputFieldClass(errors.length > 0), part: "input", type: inputType, name: component.id, "data-input-name": component.id, value: this.localPhoneNumber, placeholder: " ", required: component.required, disabled: this.disabled, autocomplete: allowEmail && this.telEmailMode ? "email" : "tel-national", onInput: this.handlePhoneInput, onKeyDown: this.handleKeyDown }), this.renderFloatingLabel(component.label, inputId, component.required, hasValue))), this.renderErrors(), errors.length === 0 && this.renderHint(component.hint)));
|
|
219
638
|
}
|
|
220
639
|
renderUrlField(component) {
|
|
221
640
|
const inputId = `input-${component.id}`;
|
|
@@ -367,6 +786,14 @@ const AuthheroNode = class {
|
|
|
367
786
|
return null;
|
|
368
787
|
}
|
|
369
788
|
}
|
|
789
|
+
static get watchers() { return {
|
|
790
|
+
"component": [{
|
|
791
|
+
"componentChanged": 0
|
|
792
|
+
}],
|
|
793
|
+
"value": [{
|
|
794
|
+
"valueChanged": 0
|
|
795
|
+
}]
|
|
796
|
+
}; }
|
|
370
797
|
};
|
|
371
798
|
AuthheroNode.style = authheroNodeCss();
|
|
372
799
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as registerInstance, c as createEvent, g as getElement, h } from './index-
|
|
1
|
+
import { r as registerInstance, c as createEvent, g as getElement, h } from './index-BFP_5sHV.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* AuthHero Widget - Branding Utilities
|
|
@@ -422,7 +422,7 @@ function escapeAttr(value) {
|
|
|
422
422
|
.replace(/>/g, ">");
|
|
423
423
|
}
|
|
424
424
|
|
|
425
|
-
const authheroWidgetCss = () => `:host{display:block;font-family:var(--ah-font-family, 'ulp-font', -apple-system, BlinkMacSystemFont, Roboto, Helvetica, sans-serif);font-size:var(--ah-font-size-base,
|
|
425
|
+
const authheroWidgetCss = () => `:host{display:block;font-family:var(--ah-font-family, 'ulp-font', -apple-system, BlinkMacSystemFont, Roboto, Helvetica, sans-serif);font-size:var(--ah-font-size-base, 16px);line-height:var(--ah-line-height-base, 1.5);color:var(--ah-color-text, #1e212a);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.widget-container{max-width:var(--ah-widget-max-width, 400px);width:100%;margin:0 auto;background-color:var(--ah-color-bg, #ffffff);border-radius:var(--ah-widget-radius, 5px);box-shadow:var(--ah-widget-shadow, 0 4px 22px 0 rgba(0, 0, 0, 0.11));box-sizing:border-box}.widget-header{padding:var(--ah-header-padding, 40px 48px 24px)}.widget-body{padding:var(--ah-body-padding, 0 48px 40px)}.logo-wrapper{display:var(--ah-logo-display, flex);justify-content:var(--ah-logo-align, center);margin-bottom:8px}.logo{display:block;height:var(--ah-logo-height, 52px);max-width:100%;width:auto;object-fit:contain}.title{font-size:var(--ah-font-size-title, 24px);font-weight:var(--ah-font-weight-title, 700);text-align:var(--ah-title-align, center);margin:var(--ah-title-margin, 24px 0 24px);color:var(--ah-color-header, #1e212a);line-height:1.2}.description{font-size:var(--ah-font-size-subtitle, 16px);text-align:var(--ah-title-align, center);margin:var(--ah-description-margin, 0 0 8px);color:var(--ah-color-text, #1e212a);line-height:1.5}.message{padding:12px 16px;border-radius:4px;margin-bottom:16px;font-size:14px;line-height:1.5}.message-error{background-color:var(--ah-color-error-bg, #ffeaea);color:var(--ah-color-error, #d03c38);border-left:3px solid var(--ah-color-error, #d03c38)}.message-success{background-color:var(--ah-color-success-bg, #e6f9f1);color:var(--ah-color-success, #13a769);border-left:3px solid var(--ah-color-success, #13a769)}form{display:flex;flex-direction:column}.form-content{display:flex;flex-direction:column}.social-section{display:flex;flex-direction:column;gap:8px;order:var(--ah-social-order, 2)}.fields-section{display:flex;flex-direction:column;order:var(--ah-fields-order, 0)}.divider{display:flex;align-items:center;text-align:center;margin:16px 0;order:var(--ah-divider-order, 1)}.divider::before,.divider::after{content:'';flex:1;border-bottom:1px solid var(--ah-color-border-muted, #c9cace)}.divider-text{padding:0 10px;font-size:12px;font-weight:400;color:var(--ah-color-text-muted, #65676e);text-transform:uppercase;letter-spacing:0}.links{display:flex;flex-direction:column;align-items:center;gap:8px;margin-top:16px}.link-wrapper{font-size:14px;color:var(--ah-color-text, #1e212a)}.link{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:14px;font-weight:var(--ah-font-weight-link, 400);transition:color 150ms ease}.link:hover{text-decoration:underline}.link:focus-visible{outline:2px solid var(--ah-color-link, #635dff);outline-offset:2px;border-radius:2px}.widget-footer{margin-top:16px;text-align:center;font-size:12px;color:var(--ah-color-text-muted, #65676e)}.widget-footer a{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:12px;transition:color 150ms ease}.widget-footer a:hover{text-decoration:underline}.widget-footer a:focus-visible{outline:2px solid var(--ah-color-link, #635dff);outline-offset:2px;border-radius:2px}.loading-spinner{width:32px;height:32px;margin:24px auto;border:3px solid var(--ah-color-border-muted, #e0e1e3);border-top-color:var(--ah-color-primary, #635dff);border-radius:50%;animation:spin 0.8s linear infinite}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.error-message{text-align:center;color:var(--ah-color-error, #d03c38);padding:16px;font-size:14px}@media (max-width: 480px){:host{display:block;width:100%;min-height:100vh;background-color:var(--ah-color-bg, #ffffff)}.widget-container{box-shadow:none;border-radius:0;max-width:none;width:100%;margin:0}.widget-header{padding:24px 16px 16px}.widget-body{padding:0 16px 24px}}`;
|
|
426
426
|
|
|
427
427
|
const AuthheroWidget = class {
|
|
428
428
|
constructor(hostRef) {
|
|
@@ -785,6 +785,25 @@ const AuthheroWidget = class {
|
|
|
785
785
|
}
|
|
786
786
|
}
|
|
787
787
|
}
|
|
788
|
+
handlePopState = (event) => {
|
|
789
|
+
if (!this.apiUrl)
|
|
790
|
+
return;
|
|
791
|
+
// Restore the widget state token from history if present
|
|
792
|
+
if (event.state?.state) {
|
|
793
|
+
this.state = event.state.state;
|
|
794
|
+
}
|
|
795
|
+
// Derive screen from history state or from the current URL
|
|
796
|
+
const screen = event.state?.screen ?? this.extractScreenIdFromHref(location.href);
|
|
797
|
+
if (screen) {
|
|
798
|
+
this.fetchScreen(screen);
|
|
799
|
+
}
|
|
800
|
+
};
|
|
801
|
+
connectedCallback() {
|
|
802
|
+
window.addEventListener("popstate", this.handlePopState);
|
|
803
|
+
}
|
|
804
|
+
disconnectedCallback() {
|
|
805
|
+
window.removeEventListener("popstate", this.handlePopState);
|
|
806
|
+
}
|
|
788
807
|
async componentWillLoad() {
|
|
789
808
|
// Parse initial props - this prevents unnecessary state changes during hydration that cause flashes
|
|
790
809
|
// Also check the element attribute as a fallback for hydration scenarios
|
|
@@ -817,7 +836,7 @@ const AuthheroWidget = class {
|
|
|
817
836
|
*/
|
|
818
837
|
async fetchScreen(screenIdOverride, nodeId) {
|
|
819
838
|
if (!this.apiUrl)
|
|
820
|
-
return;
|
|
839
|
+
return false;
|
|
821
840
|
const currentScreenId = screenIdOverride || this.screenId;
|
|
822
841
|
// Build the API URL, replacing {screenId} placeholder if present
|
|
823
842
|
let url = this.apiUrl;
|
|
@@ -872,6 +891,7 @@ const AuthheroWidget = class {
|
|
|
872
891
|
this.updateDataScreenAttribute();
|
|
873
892
|
this.persistState();
|
|
874
893
|
this.focusFirstInput();
|
|
894
|
+
return true;
|
|
875
895
|
}
|
|
876
896
|
}
|
|
877
897
|
else {
|
|
@@ -892,6 +912,7 @@ const AuthheroWidget = class {
|
|
|
892
912
|
finally {
|
|
893
913
|
this.loading = false;
|
|
894
914
|
}
|
|
915
|
+
return false;
|
|
895
916
|
}
|
|
896
917
|
handleInputChange = (name, value) => {
|
|
897
918
|
this.formData = {
|
|
@@ -1067,6 +1088,30 @@ const AuthheroWidget = class {
|
|
|
1067
1088
|
console.error("Resend failed:", error);
|
|
1068
1089
|
}
|
|
1069
1090
|
}
|
|
1091
|
+
/**
|
|
1092
|
+
* Extract screen ID from a u2 link href.
|
|
1093
|
+
* Handles patterns like /u2/login/{screenId}?state=... and /u2/{screenId}?state=...
|
|
1094
|
+
* Returns the screen ID or null if the href doesn't match a known pattern.
|
|
1095
|
+
*/
|
|
1096
|
+
extractScreenIdFromHref(href) {
|
|
1097
|
+
try {
|
|
1098
|
+
const url = new URL(href, window.location.origin);
|
|
1099
|
+
const path = url.pathname;
|
|
1100
|
+
// Match /u2/login/{screenId} (e.g., /u2/login/identifier)
|
|
1101
|
+
const loginMatch = path.match(/\/u2\/login\/([^/]+)$/);
|
|
1102
|
+
if (loginMatch)
|
|
1103
|
+
return loginMatch[1];
|
|
1104
|
+
// Match /u2/{screenId} (e.g., /u2/signup, /u2/enter-password)
|
|
1105
|
+
const u2Match = path.match(/\/u2\/([^/]+)$/);
|
|
1106
|
+
if (u2Match && u2Match[1] !== "login" && u2Match[1] !== "screen") {
|
|
1107
|
+
return u2Match[1];
|
|
1108
|
+
}
|
|
1109
|
+
return null;
|
|
1110
|
+
}
|
|
1111
|
+
catch {
|
|
1112
|
+
return null;
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1070
1115
|
handleLinkClick = (e, link) => {
|
|
1071
1116
|
// Emit the event so the consuming app can handle it
|
|
1072
1117
|
this.linkClick.emit({
|
|
@@ -1074,12 +1119,35 @@ const AuthheroWidget = class {
|
|
|
1074
1119
|
href: link.href,
|
|
1075
1120
|
text: link.text,
|
|
1076
1121
|
});
|
|
1077
|
-
// If autoNavigate is enabled,
|
|
1078
|
-
// Otherwise, prevent default and let the app decide
|
|
1122
|
+
// If autoNavigate is not enabled, prevent default and let the app decide
|
|
1079
1123
|
if (!this.shouldAutoNavigate) {
|
|
1080
1124
|
e.preventDefault();
|
|
1125
|
+
return;
|
|
1126
|
+
}
|
|
1127
|
+
// Try client-side navigation: extract screen ID and fetch via API
|
|
1128
|
+
const screenId = this.extractScreenIdFromHref(link.href);
|
|
1129
|
+
if (screenId && this.apiUrl) {
|
|
1130
|
+
e.preventDefault();
|
|
1131
|
+
this.navigateToScreen(screenId, link.href);
|
|
1132
|
+
return;
|
|
1081
1133
|
}
|
|
1134
|
+
// Fall back to browser navigation for non-u2 links
|
|
1082
1135
|
};
|
|
1136
|
+
/**
|
|
1137
|
+
* Navigate to a screen client-side by fetching it from the API.
|
|
1138
|
+
* Updates the widget state and browser URL without a full page reload.
|
|
1139
|
+
*/
|
|
1140
|
+
async navigateToScreen(screenId, displayUrl) {
|
|
1141
|
+
const success = await this.fetchScreen(screenId);
|
|
1142
|
+
if (success) {
|
|
1143
|
+
// Push browser history so back/forward works
|
|
1144
|
+
window.history.pushState({ screen: screenId, state: this.state }, "", displayUrl);
|
|
1145
|
+
}
|
|
1146
|
+
else {
|
|
1147
|
+
// On failure, fall back to hard navigation
|
|
1148
|
+
window.location.href = displayUrl;
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1083
1151
|
/**
|
|
1084
1152
|
* Check if a component is a social button.
|
|
1085
1153
|
*/
|