@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.
Files changed (36) hide show
  1. package/dist/authhero-widget/authhero-widget.esm.js +1 -1
  2. package/dist/authhero-widget/index.esm.js +1 -1
  3. package/dist/authhero-widget/p-59cbb196.entry.js +1 -0
  4. package/dist/authhero-widget/{p-5hZ8Vbm9.js → p-BFP_5sHV.js} +1 -1
  5. package/dist/authhero-widget/p-a92fa18e.entry.js +1 -0
  6. package/dist/cjs/authhero-node.cjs.entry.js +431 -4
  7. package/dist/cjs/authhero-widget.cjs.entry.js +73 -5
  8. package/dist/cjs/authhero-widget.cjs.js +2 -2
  9. package/dist/cjs/{index-vX5cgLV-.js → index-CUBT14z-.js} +21 -0
  10. package/dist/cjs/index.cjs.js +1 -1
  11. package/dist/cjs/loader.cjs.js +2 -2
  12. package/dist/collection/components/authhero-node/authhero-node.css +74 -0
  13. package/dist/collection/components/authhero-node/authhero-node.js +201 -4
  14. package/dist/collection/components/authhero-widget/authhero-widget.css +2 -2
  15. package/dist/collection/components/authhero-widget/authhero-widget.js +73 -5
  16. package/dist/collection/utils/country-data.js +235 -0
  17. package/dist/components/authhero-node.js +1 -1
  18. package/dist/components/authhero-widget.js +1 -1
  19. package/dist/components/index.js +1 -1
  20. package/dist/components/{p-EokuR0qI.js → p-DpfoRsj0.js} +1 -1
  21. package/dist/components/p-_nTdqfom.js +1 -0
  22. package/dist/esm/authhero-node.entry.js +431 -4
  23. package/dist/esm/authhero-widget.entry.js +73 -5
  24. package/dist/esm/authhero-widget.js +3 -3
  25. package/dist/esm/{index-5hZ8Vbm9.js → index-BFP_5sHV.js} +21 -0
  26. package/dist/esm/index.js +1 -1
  27. package/dist/esm/loader.js +3 -3
  28. package/dist/types/components/authhero-node/authhero-node.d.ts +36 -0
  29. package/dist/types/components/authhero-widget/authhero-widget.d.ts +15 -1
  30. package/dist/types/utils/country-data.d.ts +23 -0
  31. package/hydrate/index.js +524 -8
  32. package/hydrate/index.mjs +524 -8
  33. package/package.json +2 -2
  34. package/dist/authhero-widget/p-18d0a438.entry.js +0 -1
  35. package/dist/authhero-widget/p-bb3657ce.entry.js +0 -1
  36. package/dist/components/p-NKUIiiOq.js +0 -1
@@ -1,6 +1,242 @@
1
- import { r as registerInstance, c as createEvent, h } from './index-5hZ8Vbm9.js';
1
+ import { r as registerInstance, c as createEvent, h } from './index-BFP_5sHV.js';
2
2
 
3
- 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}.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 .signup-link{margin-top:16px;text-align:center;font-size:14px;color:var(--ah-color-text, #1e212a)}`;
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 effectiveValue = this.getEffectiveValue();
218
- return (h("div", { class: "input-wrapper", part: "input-wrapper" }, this.renderLabel(component.label, inputId, component.required), h("input", { id: inputId, class: this.getInputFieldClass(errors.length > 0), part: "input", type: "tel", name: component.id, value: effectiveValue ?? "", placeholder: component.config?.placeholder, required: component.required, disabled: this.disabled, autocomplete: "tel", onInput: this.handleInput, onKeyDown: this.handleKeyDown }), this.renderErrors(), errors.length === 0 && this.renderHint(component.hint)));
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-5hZ8Vbm9.js';
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, 14px);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-description, 14px);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}}`;
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, let the browser handle the navigation
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
  */