@authhero/widget 0.29.1 → 0.30.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.
@@ -0,0 +1 @@
1
+ import{t as e,p as a,H as o,c as t,h as i}from"./p-DpfoRsj0.js";const n=[{code:"US",dialCode:"+1",name:"United States"},{code:"CA",dialCode:"+1",name:"Canada"},{code:"AG",dialCode:"+1",name:"Antigua and Barbuda"},{code:"BS",dialCode:"+1",name:"Bahamas"},{code:"BB",dialCode:"+1",name:"Barbados"},{code:"DM",dialCode:"+1",name:"Dominica"},{code:"DO",dialCode:"+1",name:"Dominican Republic"},{code:"GD",dialCode:"+1",name:"Grenada"},{code:"JM",dialCode:"+1",name:"Jamaica"},{code:"KN",dialCode:"+1",name:"Saint Kitts and Nevis"},{code:"LC",dialCode:"+1",name:"Saint Lucia"},{code:"VC",dialCode:"+1",name:"Saint Vincent and the Grenadines"},{code:"TT",dialCode:"+1",name:"Trinidad and Tobago"},{code:"PR",dialCode:"+1",name:"Puerto Rico"},{code:"KZ",dialCode:"+7",name:"Kazakhstan"},{code:"RU",dialCode:"+7",name:"Russia"},{code:"EG",dialCode:"+20",name:"Egypt"},{code:"ZA",dialCode:"+27",name:"South Africa"},{code:"GR",dialCode:"+30",name:"Greece"},{code:"NL",dialCode:"+31",name:"Netherlands"},{code:"BE",dialCode:"+32",name:"Belgium"},{code:"FR",dialCode:"+33",name:"France"},{code:"ES",dialCode:"+34",name:"Spain"},{code:"HU",dialCode:"+36",name:"Hungary"},{code:"IT",dialCode:"+39",name:"Italy"},{code:"RO",dialCode:"+40",name:"Romania"},{code:"CH",dialCode:"+41",name:"Switzerland"},{code:"AT",dialCode:"+43",name:"Austria"},{code:"GB",dialCode:"+44",name:"United Kingdom"},{code:"DK",dialCode:"+45",name:"Denmark"},{code:"SE",dialCode:"+46",name:"Sweden"},{code:"NO",dialCode:"+47",name:"Norway"},{code:"PL",dialCode:"+48",name:"Poland"},{code:"DE",dialCode:"+49",name:"Germany"},{code:"PE",dialCode:"+51",name:"Peru"},{code:"MX",dialCode:"+52",name:"Mexico"},{code:"CU",dialCode:"+53",name:"Cuba"},{code:"AR",dialCode:"+54",name:"Argentina"},{code:"BR",dialCode:"+55",name:"Brazil"},{code:"CL",dialCode:"+56",name:"Chile"},{code:"CO",dialCode:"+57",name:"Colombia"},{code:"VE",dialCode:"+58",name:"Venezuela"},{code:"MY",dialCode:"+60",name:"Malaysia"},{code:"AU",dialCode:"+61",name:"Australia"},{code:"ID",dialCode:"+62",name:"Indonesia"},{code:"PH",dialCode:"+63",name:"Philippines"},{code:"NZ",dialCode:"+64",name:"New Zealand"},{code:"SG",dialCode:"+65",name:"Singapore"},{code:"TH",dialCode:"+66",name:"Thailand"},{code:"JP",dialCode:"+81",name:"Japan"},{code:"KR",dialCode:"+82",name:"South Korea"},{code:"VN",dialCode:"+84",name:"Vietnam"},{code:"CN",dialCode:"+86",name:"China"},{code:"TR",dialCode:"+90",name:"Turkey"},{code:"IN",dialCode:"+91",name:"India"},{code:"PK",dialCode:"+92",name:"Pakistan"},{code:"AF",dialCode:"+93",name:"Afghanistan"},{code:"LK",dialCode:"+94",name:"Sri Lanka"},{code:"MM",dialCode:"+95",name:"Myanmar"},{code:"IR",dialCode:"+98",name:"Iran"},{code:"SS",dialCode:"+211",name:"South Sudan"},{code:"MA",dialCode:"+212",name:"Morocco"},{code:"DZ",dialCode:"+213",name:"Algeria"},{code:"TN",dialCode:"+216",name:"Tunisia"},{code:"LY",dialCode:"+218",name:"Libya"},{code:"GM",dialCode:"+220",name:"Gambia"},{code:"SN",dialCode:"+221",name:"Senegal"},{code:"MR",dialCode:"+222",name:"Mauritania"},{code:"ML",dialCode:"+223",name:"Mali"},{code:"GN",dialCode:"+224",name:"Guinea"},{code:"CI",dialCode:"+225",name:"Ivory Coast"},{code:"BF",dialCode:"+226",name:"Burkina Faso"},{code:"NE",dialCode:"+227",name:"Niger"},{code:"TG",dialCode:"+228",name:"Togo"},{code:"BJ",dialCode:"+229",name:"Benin"},{code:"MU",dialCode:"+230",name:"Mauritius"},{code:"LR",dialCode:"+231",name:"Liberia"},{code:"SL",dialCode:"+232",name:"Sierra Leone"},{code:"GH",dialCode:"+233",name:"Ghana"},{code:"NG",dialCode:"+234",name:"Nigeria"},{code:"TD",dialCode:"+235",name:"Chad"},{code:"CF",dialCode:"+236",name:"Central African Republic"},{code:"CM",dialCode:"+237",name:"Cameroon"},{code:"CV",dialCode:"+238",name:"Cape Verde"},{code:"ST",dialCode:"+239",name:"São Tomé and Príncipe"},{code:"GQ",dialCode:"+240",name:"Equatorial Guinea"},{code:"GA",dialCode:"+241",name:"Gabon"},{code:"CG",dialCode:"+242",name:"Congo"},{code:"CD",dialCode:"+243",name:"Congo (DRC)"},{code:"AO",dialCode:"+244",name:"Angola"},{code:"GW",dialCode:"+245",name:"Guinea-Bissau"},{code:"SC",dialCode:"+248",name:"Seychelles"},{code:"SD",dialCode:"+249",name:"Sudan"},{code:"RW",dialCode:"+250",name:"Rwanda"},{code:"ET",dialCode:"+251",name:"Ethiopia"},{code:"SO",dialCode:"+252",name:"Somalia"},{code:"DJ",dialCode:"+253",name:"Djibouti"},{code:"KE",dialCode:"+254",name:"Kenya"},{code:"TZ",dialCode:"+255",name:"Tanzania"},{code:"UG",dialCode:"+256",name:"Uganda"},{code:"BI",dialCode:"+257",name:"Burundi"},{code:"MZ",dialCode:"+258",name:"Mozambique"},{code:"ZM",dialCode:"+260",name:"Zambia"},{code:"MG",dialCode:"+261",name:"Madagascar"},{code:"RE",dialCode:"+262",name:"Réunion"},{code:"ZW",dialCode:"+263",name:"Zimbabwe"},{code:"NA",dialCode:"+264",name:"Namibia"},{code:"MW",dialCode:"+265",name:"Malawi"},{code:"LS",dialCode:"+266",name:"Lesotho"},{code:"BW",dialCode:"+267",name:"Botswana"},{code:"SZ",dialCode:"+268",name:"Eswatini"},{code:"KM",dialCode:"+269",name:"Comoros"},{code:"ER",dialCode:"+291",name:"Eritrea"},{code:"PT",dialCode:"+351",name:"Portugal"},{code:"LU",dialCode:"+352",name:"Luxembourg"},{code:"IE",dialCode:"+353",name:"Ireland"},{code:"IS",dialCode:"+354",name:"Iceland"},{code:"AL",dialCode:"+355",name:"Albania"},{code:"MT",dialCode:"+356",name:"Malta"},{code:"CY",dialCode:"+357",name:"Cyprus"},{code:"FI",dialCode:"+358",name:"Finland"},{code:"BG",dialCode:"+359",name:"Bulgaria"},{code:"LT",dialCode:"+370",name:"Lithuania"},{code:"LV",dialCode:"+371",name:"Latvia"},{code:"EE",dialCode:"+372",name:"Estonia"},{code:"MD",dialCode:"+373",name:"Moldova"},{code:"AM",dialCode:"+374",name:"Armenia"},{code:"BY",dialCode:"+375",name:"Belarus"},{code:"AD",dialCode:"+376",name:"Andorra"},{code:"MC",dialCode:"+377",name:"Monaco"},{code:"SM",dialCode:"+378",name:"San Marino"},{code:"UA",dialCode:"+380",name:"Ukraine"},{code:"RS",dialCode:"+381",name:"Serbia"},{code:"ME",dialCode:"+382",name:"Montenegro"},{code:"XK",dialCode:"+383",name:"Kosovo"},{code:"HR",dialCode:"+385",name:"Croatia"},{code:"SI",dialCode:"+386",name:"Slovenia"},{code:"BA",dialCode:"+387",name:"Bosnia and Herzegovina"},{code:"MK",dialCode:"+389",name:"North Macedonia"},{code:"CZ",dialCode:"+420",name:"Czech Republic"},{code:"SK",dialCode:"+421",name:"Slovakia"},{code:"LI",dialCode:"+423",name:"Liechtenstein"},{code:"FK",dialCode:"+500",name:"Falkland Islands"},{code:"BZ",dialCode:"+501",name:"Belize"},{code:"GT",dialCode:"+502",name:"Guatemala"},{code:"SV",dialCode:"+503",name:"El Salvador"},{code:"HN",dialCode:"+504",name:"Honduras"},{code:"NI",dialCode:"+505",name:"Nicaragua"},{code:"CR",dialCode:"+506",name:"Costa Rica"},{code:"PA",dialCode:"+507",name:"Panama"},{code:"HT",dialCode:"+509",name:"Haiti"},{code:"GP",dialCode:"+590",name:"Guadeloupe"},{code:"BO",dialCode:"+591",name:"Bolivia"},{code:"GY",dialCode:"+592",name:"Guyana"},{code:"EC",dialCode:"+593",name:"Ecuador"},{code:"GF",dialCode:"+594",name:"French Guiana"},{code:"PY",dialCode:"+595",name:"Paraguay"},{code:"MQ",dialCode:"+596",name:"Martinique"},{code:"SR",dialCode:"+597",name:"Suriname"},{code:"UY",dialCode:"+598",name:"Uruguay"},{code:"TL",dialCode:"+670",name:"Timor-Leste"},{code:"BN",dialCode:"+673",name:"Brunei"},{code:"NR",dialCode:"+674",name:"Nauru"},{code:"PG",dialCode:"+675",name:"Papua New Guinea"},{code:"TO",dialCode:"+676",name:"Tonga"},{code:"SB",dialCode:"+677",name:"Solomon Islands"},{code:"VU",dialCode:"+678",name:"Vanuatu"},{code:"FJ",dialCode:"+679",name:"Fiji"},{code:"PW",dialCode:"+680",name:"Palau"},{code:"WS",dialCode:"+685",name:"Samoa"},{code:"KI",dialCode:"+686",name:"Kiribati"},{code:"FM",dialCode:"+691",name:"Micronesia"},{code:"MH",dialCode:"+692",name:"Marshall Islands"},{code:"KP",dialCode:"+850",name:"North Korea"},{code:"HK",dialCode:"+852",name:"Hong Kong"},{code:"MO",dialCode:"+853",name:"Macau"},{code:"KH",dialCode:"+855",name:"Cambodia"},{code:"LA",dialCode:"+856",name:"Laos"},{code:"BD",dialCode:"+880",name:"Bangladesh"},{code:"TW",dialCode:"+886",name:"Taiwan"},{code:"MV",dialCode:"+960",name:"Maldives"},{code:"LB",dialCode:"+961",name:"Lebanon"},{code:"JO",dialCode:"+962",name:"Jordan"},{code:"SY",dialCode:"+963",name:"Syria"},{code:"IQ",dialCode:"+964",name:"Iraq"},{code:"KW",dialCode:"+965",name:"Kuwait"},{code:"SA",dialCode:"+966",name:"Saudi Arabia"},{code:"YE",dialCode:"+967",name:"Yemen"},{code:"OM",dialCode:"+968",name:"Oman"},{code:"PS",dialCode:"+970",name:"Palestine"},{code:"AE",dialCode:"+971",name:"United Arab Emirates"},{code:"IL",dialCode:"+972",name:"Israel"},{code:"BH",dialCode:"+973",name:"Bahrain"},{code:"QA",dialCode:"+974",name:"Qatar"},{code:"BT",dialCode:"+975",name:"Bhutan"},{code:"MN",dialCode:"+976",name:"Mongolia"},{code:"NP",dialCode:"+977",name:"Nepal"},{code:"TJ",dialCode:"+992",name:"Tajikistan"},{code:"TM",dialCode:"+993",name:"Turkmenistan"},{code:"AZ",dialCode:"+994",name:"Azerbaijan"},{code:"GE",dialCode:"+995",name:"Georgia"},{code:"KG",dialCode:"+996",name:"Kyrgyzstan"},{code:"UZ",dialCode:"+998",name:"Uzbekistan"}].map((e=>{return{...e,flag:(a=e.code,String.fromCodePoint(...a.toUpperCase().split("").map((e=>127397+e.charCodeAt(0)))))};var a}));function d(e){const a=e.toUpperCase();return n.find((e=>e.code===a))||n.find((e=>"US"===e.code))}const r=a(class extends o{constructor(e){super(),!1!==e&&this.__registerHost(),this.__attachShadow(),this.fieldChange=t(this,"fieldChange"),this.buttonClick=t(this,"buttonClick")}component;value;disabled=!1;passwordVisible=!1;selectedCountry=d("US");localPhoneNumber="";countryDropdownOpen=!1;telEmailMode=!1;fieldChange;buttonClick;componentChanged(){this.initCountryFromConfig(),this.initTelValue()}valueChanged(){this.initTelValue()}componentWillLoad(){this.initCountryFromConfig(),this.initTelValue()}initCountryFromConfig(){if("TEL"===this.component?.type){const e=this.component.config,a=e?.default_country;a&&(this.selectedCountry=d(a)),!0===e?.allow_email&&(this.telEmailMode=!0)}}initTelValue(){if("TEL"!==this.component?.type)return;const e=this.component.config,a=!0===e?.allow_email,o=this.getEffectiveValue();if(!o)return this.localPhoneNumber="",void(a&&(this.telEmailMode=!0));if(o.startsWith("+")){const e=[...n].sort(((e,a)=>a.dialCode.length-e.dialCode.length));for(const t of e)if(o.startsWith(t.dialCode))return this.selectedCountry=t,this.localPhoneNumber=o.slice(t.dialCode.length),void(a&&(this.telEmailMode=!1))}if(this.localPhoneNumber=o,a){const e=/^[+\d]/.test(o);this.telEmailMode=!e}}handleCountryChange=e=>{this.selectedCountry=d(e.target.value),this.fieldChange.emit({id:this.component.id,value:this.localPhoneNumber?`${this.selectedCountry.dialCode}${this.localPhoneNumber}`:""})};detectDialCodeFromInput(e){const a=e.startsWith("00")?"+"+e.slice(2):e;if(!a.startsWith("+"))return null;const o=[...n].sort(((e,a)=>a.dialCode.length-e.dialCode.length));for(const e of o)if(a.startsWith(e.dialCode))return this.selectedCountry=e,a.slice(e.dialCode.length);return null}processPhoneInput(e,a,o){const t=this.detectDialCodeFromInput(a);if(null!==t){const a=o?t.replace(/[^+\d\s\-()]/g,"").replace(/\+/g,""):t.replace(/[^\d\s\-()]/g,"");e.value=a,this.localPhoneNumber=a,this.fieldChange.emit({id:this.component.id,value:`${this.selectedCountry.dialCode}${a}`})}else{const t=o?a.replace(/[^+\d\s\-()]/g,"").replace(/\+/g,""):a.replace(/[^\d\s\-()]/g,"");t!==a&&(e.value=t),this.localPhoneNumber=t,this.fieldChange.emit({id:this.component.id,value:t?`${this.selectedCountry.dialCode}${t}`:""})}}handlePhoneInput=e=>{const a=e.target,o=a.value,t=this.component.config;if(!0===t?.allow_email){const e=o.length>0&&/^[+\d]/.test(o)&&!o.includes("@");return this.telEmailMode=!e,void(this.telEmailMode?(this.localPhoneNumber=o,this.fieldChange.emit({id:this.component.id,value:o})):this.processPhoneInput(a,o,!0))}this.processPhoneInput(a,o,!1)};handleInput=e=>{this.fieldChange.emit({id:this.component.id,value:e.target.value})};handleKeyDown=e=>{if("Enter"===e.key&&(e.preventDefault(),this.buttonClick.emit({id:"submit",type:"submit",value:"next"})),"Backspace"===e.key&&!this.telEmailMode){const a=e.target,o=this.component.config;!0===o?.allow_email&&0===a.value.length&&(this.telEmailMode=!0,this.localPhoneNumber="",this.fieldChange.emit({id:this.component.id,value:""}))}};handleCheckbox=e=>{this.fieldChange.emit({id:this.component.id,value:e.target.checked?"true":"false"})};getEffectiveValue(){if(null!=this.value)return this.value;const e=this.component;if(e.config&&"default_value"in e.config){const a=e.config.default_value;if("string"==typeof a&&""!==a)return a}}sanitizeForCssToken(e){return e.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")}handleButtonClick=(e,a,o)=>{e.preventDefault(),this.buttonClick.emit({id:this.component.id,type:a,value:o})};togglePasswordVisibility=()=>{this.passwordVisible=!this.passwordVisible};getErrors(){const e=this.component;return e.messages?.filter((e=>"error"===e.type))||[]}renderFloatingLabel(e,a,o,t){return e?i("label",{class:t?"input-label floating":"input-label",part:"label",htmlFor:a},e,o&&i("span",{class:"required"},"*")):null}renderLabel(e,a,o){return e?i("label",{class:"input-label",part:"label",htmlFor:a},e,o&&i("span",{class:"required"},"*")):null}getInputFieldClass(e){return e?"input-field has-error":"input-field"}renderPasswordToggle(){return this.passwordVisible?i("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},i("path",{d:"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"}),i("line",{x1:"1",y1:"1",x2:"23",y2:"23"})):i("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},i("path",{d:"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"}),i("circle",{cx:"12",cy:"12",r:"3"}))}renderErrors(){return this.getErrors().map((e=>i("span",{class:"error-text",part:"error-text",key:e.id??e.text},e.text)))}renderHint(e){return e?i("span",{class:"helper-text",part:"helper-text"},e):null}renderDivider(){return i("hr",{class:"divider",part:"divider"})}renderHtml(e){return i("div",{class:"html-content",part:"html-content",innerHTML:e.config?.content??""})}renderImage(e){const{src:a,alt:o,width:t,height:n}=e.config??{};return a?i("img",{class:"image",part:"image",src:a,alt:o??"",width:t,height:n,loading:"lazy"}):null}renderRichText(e){return i("div",{class:"rich-text",part:"rich-text",innerHTML:e.config?.content??""})}renderNextButton(e){return i("button",{type:"submit",class:"btn btn-primary",part:"button button-primary","data-primary-action-button":!0,disabled:this.disabled,onClick:e=>this.handleButtonClick(e,"submit","next")},e.config.text??"Continue")}renderPreviousButton(e){return i("button",{type:"button",class:"btn btn-secondary",part:"button button-secondary",disabled:this.disabled,onClick:e=>this.handleButtonClick(e,"previous","back")},e.config.text??"Back")}renderJumpButton(e){return i("button",{type:"button",class:"btn btn-link",part:"button button-link",disabled:this.disabled,onClick:a=>this.handleButtonClick(a,"jump",e.config.target_step)},e.config.text??"Go")}renderResendButton(e){return i("button",{type:"button",class:"btn btn-link",part:"button button-link",disabled:this.disabled,onClick:a=>this.handleButtonClick(a,"resend",e.config.resend_action)},e.config.text??"Resend")}renderTextField(e){const a=`input-${e.id}`,o=this.getErrors(),{multiline:t,max_length:n,autocomplete:d}=e.config??{},r=this.getEffectiveValue(),l=!!(r&&r.length>0);return t?i("div",{class:"input-wrapper",part:"input-wrapper"},this.renderLabel(e.label,a,e.required),i("textarea",{id:a,class:this.getInputFieldClass(o.length>0),part:"input textarea",name:e.id,placeholder:" ",required:e.required,disabled:this.disabled,maxLength:n,onInput:this.handleInput},r??""),this.renderErrors(),0===o.length&&this.renderHint(e.hint)):i("div",{class:"input-wrapper",part:"input-wrapper"},i("div",{class:"input-container"},i("input",{id:a,class:this.getInputFieldClass(o.length>0),part:"input",type:e.sensitive?"password":"text",name:e.id,"data-input-name":e.id,value:r??"",placeholder:" ",required:e.required,disabled:this.disabled,maxLength:n,autoComplete:d,onInput:this.handleInput,onKeyDown:this.handleKeyDown}),this.renderFloatingLabel(e.label,a,e.required,l)),this.renderErrors(),0===o.length&&this.renderHint(e.hint))}renderEmailField(e){const a=`input-${e.id}`,o=this.getErrors(),t=this.getEffectiveValue(),n=!!(t&&t.length>0),{autocomplete:d}=e.config??{};return i("div",{class:"input-wrapper",part:"input-wrapper"},i("div",{class:"input-container"},i("input",{id:a,class:this.getInputFieldClass(o.length>0),part:"input",type:"email",name:e.id,"data-input-name":e.id,value:t??"",placeholder:" ",required:e.required,disabled:this.disabled,autocomplete:d||"email",onInput:this.handleInput,onKeyDown:this.handleKeyDown}),this.renderFloatingLabel(e.label,a,e.required,n)),this.renderErrors(),0===o.length&&this.renderHint(e.hint))}renderPasswordField(e){const a=`input-${e.id}`,o=this.getErrors(),t=this.getEffectiveValue(),n=!!(t&&t.length>0),d=e.config?.forgot_password_link;return i("div",{class:"input-wrapper",part:"input-wrapper"},i("div",{class:"input-container password-container"},i("input",{id:a,class:this.getInputFieldClass(o.length>0),part:"input",type:this.passwordVisible?"text":"password",name:e.id,"data-input-name":e.id,value:t??"",placeholder:" ",required:e.required,disabled:this.disabled,minLength:e.config?.min_length,autocomplete:"current-password",onInput:this.handleInput,onKeyDown:this.handleKeyDown}),this.renderFloatingLabel(e.label,a,e.required,n),i("button",{type:"button",class:"password-toggle",part:"password-toggle",onClick:this.togglePasswordVisibility,"aria-label":"Toggle password visibility","aria-pressed":this.passwordVisible?"true":"false"},this.renderPasswordToggle())),this.renderErrors(),0===o.length&&this.renderHint(e.hint),d&&i("div",{class:"field-link",part:"field-link"},i("a",{href:d,class:"link",part:"link"},"Forgot password?")))}renderNumberField(e){const a=`input-${e.id}`,o=this.getErrors(),{placeholder:t,min:n,max:d,step:r}=e.config??{},l=this.getEffectiveValue();return i("div",{class:"input-wrapper",part:"input-wrapper"},this.renderLabel(e.label,a,e.required),i("input",{id:a,class:this.getInputFieldClass(o.length>0),part:"input",type:"number",name:e.id,value:l??"",placeholder:t,required:e.required,disabled:this.disabled,min:n,max:d,step:r,onInput:this.handleInput,onKeyDown:this.handleKeyDown}),this.renderErrors(),0===o.length&&this.renderHint(e.hint))}renderTelField(e){const a=`input-${e.id}`,o=this.getErrors(),t=e.config,d=!0===t?.allow_email,r=this.localPhoneNumber.length>0,l=!d||!this.telEmailMode,s=l?i("select",{class:"country-select",part:"country-select",style:{width:`${`${this.selectedCountry.flag} ${this.selectedCountry.dialCode}`.length+1}ch`,minWidth:"0"},onChange:this.handleCountryChange,disabled:this.disabled,"aria-label":"Country code"},n.map((e=>i("option",{value:e.code,selected:this.selectedCountry.code===e.code,key:e.code},`${e.flag} ${e.dialCode}`)))):null,c=d&&this.telEmailMode?"text":"tel";return i("div",{class:"input-wrapper",part:"input-wrapper"},i("div",{class:l?"phone-input-wrapper":"",part:"phone-input-wrapper"},s,i("div",{class:"input-container"},i("input",{id:a,class:this.getInputFieldClass(o.length>0),part:"input",type:c,name:e.id,"data-input-name":e.id,value:this.localPhoneNumber,placeholder:" ",required:e.required,disabled:this.disabled,autocomplete:d&&this.telEmailMode?"email":"tel-national",onInput:this.handlePhoneInput,onKeyDown:this.handleKeyDown}),this.renderFloatingLabel(e.label,a,e.required,r))),this.renderErrors(),0===o.length&&this.renderHint(e.hint))}renderUrlField(e){const a=`input-${e.id}`,o=this.getErrors(),t=this.getEffectiveValue();return i("div",{class:"input-wrapper",part:"input-wrapper"},this.renderLabel(e.label,a,e.required),i("input",{id:a,class:this.getInputFieldClass(o.length>0),part:"input",type:"url",name:e.id,value:t??"",placeholder:e.config?.placeholder,required:e.required,disabled:this.disabled,onInput:this.handleInput,onKeyDown:this.handleKeyDown}),this.renderErrors(),0===o.length&&this.renderHint(e.hint))}renderDateField(e){const a=`input-${e.id}`,o=this.getErrors(),{min:t,max:n}=e.config??{},d=this.getEffectiveValue();return i("div",{class:"input-wrapper",part:"input-wrapper"},i("div",{class:"input-container"},i("input",{id:a,class:this.getInputFieldClass(o.length>0),part:"input",type:"date",name:e.id,"data-input-name":e.id,value:d??"",placeholder:" ",required:e.required,disabled:this.disabled,min:t,max:n,onInput:this.handleInput,onKeyDown:this.handleKeyDown}),this.renderFloatingLabel(e.label,a,e.required,!0)),this.renderErrors(),0===o.length&&this.renderHint(e.hint))}renderBooleanField(e){return i("label",{class:"checkbox-wrapper",part:"checkbox-wrapper"},i("input",{type:"checkbox",part:"checkbox",name:e.id,checked:"true"===this.value||!0===e.config?.default_value,required:e.required,disabled:this.disabled,onChange:this.handleCheckbox}),i("span",{class:"checkbox-label",part:"checkbox-label"},e.label))}renderLegalField(e){const a=e.config?.text??e.label??"",o=!0===e.config?.html;return i("label",{class:"checkbox-wrapper",part:"checkbox-wrapper"},i("input",{type:"checkbox",part:"checkbox",name:e.id,checked:"true"===this.value,required:e.required,disabled:this.disabled,onChange:this.handleCheckbox}),o?i("span",{class:"checkbox-label",part:"checkbox-label",innerHTML:a}):i("span",{class:"checkbox-label",part:"checkbox-label"},a))}renderCountryField(e){const a=`input-${e.id}`,o=this.getErrors(),{placeholder:t}=e.config??{},d=this.getEffectiveValue();return i("div",{class:"input-wrapper",part:"input-wrapper"},i("div",{class:"input-container"},i("select",{id:a,class:this.getInputFieldClass(o.length>0),part:"input select",name:e.id,required:e.required,disabled:this.disabled,onChange:this.handleInput},t&&i("option",{value:"",disabled:!0,selected:!d},t),n.map((e=>i("option",{value:e.code,selected:d===e.code,key:e.code},e.flag," ",e.name)))),this.renderFloatingLabel(e.label,a,e.required,!0)),this.renderErrors(),0===o.length&&this.renderHint(e.hint))}renderDropdownField(e){const a=`input-${e.id}`,o=this.getErrors(),{options:t,placeholder:n}=e.config??{},d=this.getEffectiveValue();return i("div",{class:"input-wrapper",part:"input-wrapper"},i("div",{class:"input-container"},i("select",{id:a,class:this.getInputFieldClass(o.length>0),part:"input select",name:e.id,required:e.required,disabled:this.disabled,onChange:this.handleInput},n&&i("option",{value:"",disabled:!0,selected:!d},n),t?.map((e=>i("option",{value:e.value,selected:d===e.value,key:e.value},e.label)))),this.renderFloatingLabel(e.label,a,e.required,!0)),this.renderErrors(),0===o.length&&this.renderHint(e.hint))}renderChoiceField(e){const a=this.getErrors(),{options:o,display:t}=e.config??{},n="checkbox"===t,d=n?"checkbox":"radio";return i("div",{class:"choice-wrapper",part:"choice-wrapper"},e.label&&i("span",{class:"choice-label",part:"choice-label"},e.label,e.required&&i("span",{class:"required"},"*")),i("div",{class:"choice-options",part:"choice-options"},o?.map((a=>i("label",{class:"choice-option",part:"choice-option",key:a.value},i("input",{type:d,part:d,name:e.id,value:a.value,checked:this.getEffectiveValue()===a.value,required:e.required&&!n,disabled:this.disabled,onChange:this.handleInput}),i("span",null,a.label))))),this.renderErrors(),0===a.length&&this.renderHint(e.hint))}renderSocialField(e){const a=e.config?.providers??[],o=e.config?.provider_details,t=new Map(o?.map((e=>[e.name,e]))??[]),n=e=>{const a=t.get(e);return a?.display_name?a.display_name:e.split("-").map((e=>e.charAt(0).toUpperCase()+e.slice(1))).join(" ")},d=e=>{const a=t.get(e),o=this.sanitizeForCssToken(e);return a?.icon_url?i("img",{class:"social-icon",part:`social-icon social-icon-${o}`,src:a.icon_url,alt:a.display_name||e}):null};return i("div",{class:"social-buttons",part:"social-buttons"},a.map((e=>{const a=this.sanitizeForCssToken(e),o=(e=>{const a=t.get(e);return a?.strategy??e})(e),r=d(e),l=t.get(e),s=`btn btn-secondary btn-social btn-social-${a}${r?"":" no-icon"}`,c=`button button-secondary button-social button-social-${a}`,p=[r,i("span",{class:"btn-social-content",part:`button-social-content button-social-content-${a}`},i("span",{part:`button-social-text button-social-text-${a}`},n(e)),i("span",{class:"btn-social-subtitle",part:`button-social-subtitle button-social-subtitle-${a}`}))];return l?.href?i("a",{href:this.disabled?void 0:l.href,class:s,part:c,"data-connection-name":e,"data-strategy":o,key:e,"aria-disabled":this.disabled?"true":void 0,tabindex:this.disabled?-1:void 0,onClick:e=>{this.disabled&&e.preventDefault()}},p):i("button",{type:"button",class:s,part:c,"data-connection-name":e,"data-strategy":o,disabled:this.disabled,onClick:a=>this.handleButtonClick(a,"SOCIAL",e),key:e},p)})))}render(){if(!this.component)return null;if(!1===this.component.visible)return null;switch(this.component.type){case"DIVIDER":return this.renderDivider();case"HTML":return this.renderHtml(this.component);case"IMAGE":return this.renderImage(this.component);case"RICH_TEXT":return this.renderRichText(this.component);case"NEXT_BUTTON":return this.renderNextButton(this.component);case"PREVIOUS_BUTTON":return this.renderPreviousButton(this.component);case"JUMP_BUTTON":return this.renderJumpButton(this.component);case"RESEND_BUTTON":return this.renderResendButton(this.component);case"TEXT":return this.renderTextField(this.component);case"EMAIL":return this.renderEmailField(this.component);case"PASSWORD":return this.renderPasswordField(this.component);case"NUMBER":return this.renderNumberField(this.component);case"TEL":return this.renderTelField(this.component);case"URL":return this.renderUrlField(this.component);case"DATE":return this.renderDateField(this.component);case"BOOLEAN":return this.renderBooleanField(this.component);case"LEGAL":return this.renderLegalField(this.component);case"COUNTRY":return this.renderCountryField(this.component);case"DROPDOWN":return this.renderDropdownField(this.component);case"CHOICE":return this.renderChoiceField(this.component);case"SOCIAL":return this.renderSocialField(this.component);case"AUTH0_VERIFIABLE_CREDENTIALS":case"GMAPS_ADDRESS":case"RECAPTCHA":return console.warn(`Widget component "${this.component.type}" not yet implemented`),null;case"CARDS":case"CUSTOM":case"FILE":case"PAYMENT":return console.warn(`Component "${this.component.type}" not yet implemented`),null;default:return console.warn(`Unknown component type: ${this.component.type}`),null}}static get watchers(){return{component:[{componentChanged:0}],value:[{valueChanged:0}]}}static get style(){return":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)}"}},[513,"authhero-node",{component:[16],value:[1],disabled:[4],passwordVisible:[32],selectedCountry:[32],localPhoneNumber:[32],countryDropdownOpen:[32],telEmailMode:[32]},void 0,{component:[{componentChanged:0}],value:[{valueChanged:0}]}]);function l(){"undefined"!=typeof customElements&&["authhero-node"].forEach((a=>{"authhero-node"===a&&(customElements.get(e(a))||customElements.define(e(a),r))}))}l();export{r as A,l as d}
@@ -379,6 +379,38 @@ const AuthheroNode = class {
379
379
  }
380
380
  return null;
381
381
  }
382
+ /**
383
+ * Shared phone-input cleaning logic. Detects dial codes, strips non-phone
384
+ * characters, updates the input value, and emits the full number.
385
+ * @param allowPlus When true, uses a two-pass clean that first keeps '+'
386
+ * then strips it (for combined tel+email fields). When false, strips '+'
387
+ * in a single pass (phone-only fields where the picker provides the prefix).
388
+ */
389
+ processPhoneInput(target, value, allowPlus) {
390
+ const dialLocal = this.detectDialCodeFromInput(value);
391
+ if (dialLocal !== null) {
392
+ const cleanedLocal = allowPlus
393
+ ? dialLocal.replace(/[^+\d\s\-()]/g, "").replace(/\+/g, "")
394
+ : dialLocal.replace(/[^\d\s\-()]/g, "");
395
+ target.value = cleanedLocal;
396
+ this.localPhoneNumber = cleanedLocal;
397
+ const fullNumber = `${this.selectedCountry.dialCode}${cleanedLocal}`;
398
+ this.fieldChange.emit({ id: this.component.id, value: fullNumber });
399
+ }
400
+ else {
401
+ const cleaned = allowPlus
402
+ ? value.replace(/[^+\d\s\-()]/g, "").replace(/\+/g, "")
403
+ : value.replace(/[^\d\s\-()]/g, "");
404
+ if (cleaned !== value) {
405
+ target.value = cleaned;
406
+ }
407
+ this.localPhoneNumber = cleaned;
408
+ const fullNumber = cleaned
409
+ ? `${this.selectedCountry.dialCode}${cleaned}`
410
+ : "";
411
+ this.fieldChange.emit({ id: this.component.id, value: fullNumber });
412
+ }
413
+ }
382
414
  handlePhoneInput = (e) => {
383
415
  const target = e.target;
384
416
  const value = target.value;
@@ -391,31 +423,7 @@ const AuthheroNode = class {
391
423
  const looksLikePhone = value.length > 0 && /^[+\d]/.test(value) && !value.includes("@");
392
424
  this.telEmailMode = !looksLikePhone;
393
425
  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
400
- .replace(/[^+\d\s\-()]/g, "")
401
- .replace(/\+/g, "");
402
- target.value = cleanedLocal;
403
- this.localPhoneNumber = cleanedLocal;
404
- const fullNumber = `${this.selectedCountry.dialCode}${cleanedLocal}`;
405
- this.fieldChange.emit({ id: this.component.id, value: fullNumber });
406
- }
407
- else {
408
- // No dial code — strip non-phone chars and '+' (picker provides the prefix)
409
- const cleaned = value.replace(/[^+\d\s\-()]/g, "").replace(/\+/g, "");
410
- if (cleaned !== value) {
411
- target.value = cleaned;
412
- }
413
- this.localPhoneNumber = cleaned;
414
- const fullNumber = cleaned
415
- ? `${this.selectedCountry.dialCode}${cleaned}`
416
- : "";
417
- this.fieldChange.emit({ id: this.component.id, value: fullNumber });
418
- }
426
+ this.processPhoneInput(target, value, true);
419
427
  }
420
428
  else {
421
429
  // Email or text — emit as-is
@@ -424,16 +432,8 @@ const AuthheroNode = class {
424
432
  }
425
433
  return;
426
434
  }
427
- // Standard phone-only mode — strip '+' since the picker provides the prefix
428
- const cleaned = value.replace(/[^\d\s\-()]/g, "");
429
- if (cleaned !== value) {
430
- target.value = cleaned;
431
- }
432
- this.localPhoneNumber = cleaned;
433
- const fullNumber = cleaned
434
- ? `${this.selectedCountry.dialCode}${cleaned}`
435
- : "";
436
- this.fieldChange.emit({ id: this.component.id, value: fullNumber });
435
+ // Standard phone-only mode
436
+ this.processPhoneInput(target, value, false);
437
437
  };
438
438
  handleInput = (e) => {
439
439
  const target = e.target;
@@ -593,20 +593,21 @@ const AuthheroNode = class {
593
593
  renderTextField(component) {
594
594
  const inputId = `input-${component.id}`;
595
595
  const errors = this.getErrors();
596
- const { multiline, max_length } = component.config ?? {};
596
+ const { multiline, max_length, autocomplete } = component.config ?? {};
597
597
  const effectiveValue = this.getEffectiveValue();
598
598
  const hasValue = !!(effectiveValue && effectiveValue.length > 0);
599
599
  if (multiline) {
600
600
  return (h("div", { class: "input-wrapper", part: "input-wrapper" }, this.renderLabel(component.label, inputId, component.required), h("textarea", { id: inputId, class: this.getInputFieldClass(errors.length > 0), part: "input textarea", name: component.id, placeholder: " ", required: component.required, disabled: this.disabled, maxLength: max_length, onInput: this.handleInput }, effectiveValue ?? ""), this.renderErrors(), errors.length === 0 && this.renderHint(component.hint)));
601
601
  }
602
- return (h("div", { class: "input-wrapper", part: "input-wrapper" }, h("div", { class: "input-container" }, h("input", { id: inputId, class: this.getInputFieldClass(errors.length > 0), part: "input", type: component.sensitive ? "password" : "text", name: component.id, "data-input-name": component.id, value: effectiveValue ?? "", placeholder: " ", required: component.required, disabled: this.disabled, maxLength: max_length, onInput: this.handleInput, onKeyDown: this.handleKeyDown }), this.renderFloatingLabel(component.label, inputId, component.required, hasValue)), this.renderErrors(), errors.length === 0 && this.renderHint(component.hint)));
602
+ return (h("div", { class: "input-wrapper", part: "input-wrapper" }, h("div", { class: "input-container" }, h("input", { id: inputId, class: this.getInputFieldClass(errors.length > 0), part: "input", type: component.sensitive ? "password" : "text", name: component.id, "data-input-name": component.id, value: effectiveValue ?? "", placeholder: " ", required: component.required, disabled: this.disabled, maxLength: max_length, autoComplete: autocomplete, onInput: this.handleInput, onKeyDown: this.handleKeyDown }), this.renderFloatingLabel(component.label, inputId, component.required, hasValue)), this.renderErrors(), errors.length === 0 && this.renderHint(component.hint)));
603
603
  }
604
604
  renderEmailField(component) {
605
605
  const inputId = `input-${component.id}`;
606
606
  const errors = this.getErrors();
607
607
  const effectiveValue = this.getEffectiveValue();
608
608
  const hasValue = !!(effectiveValue && effectiveValue.length > 0);
609
- return (h("div", { class: "input-wrapper", part: "input-wrapper" }, h("div", { class: "input-container" }, h("input", { id: inputId, class: this.getInputFieldClass(errors.length > 0), part: "input", type: "email", name: component.id, "data-input-name": component.id, value: effectiveValue ?? "", placeholder: " ", required: component.required, disabled: this.disabled, autocomplete: "email", onInput: this.handleInput, onKeyDown: this.handleKeyDown }), this.renderFloatingLabel(component.label, inputId, component.required, hasValue)), this.renderErrors(), errors.length === 0 && this.renderHint(component.hint)));
609
+ const { autocomplete } = (component.config ?? {});
610
+ return (h("div", { class: "input-wrapper", part: "input-wrapper" }, h("div", { class: "input-container" }, h("input", { id: inputId, class: this.getInputFieldClass(errors.length > 0), part: "input", type: "email", name: component.id, "data-input-name": component.id, value: effectiveValue ?? "", placeholder: " ", required: component.required, disabled: this.disabled, autocomplete: autocomplete || "email", onInput: this.handleInput, onKeyDown: this.handleKeyDown }), this.renderFloatingLabel(component.label, inputId, component.required, hasValue)), this.renderErrors(), errors.length === 0 && this.renderHint(component.hint)));
610
611
  }
611
612
  renderPasswordField(component) {
612
613
  const inputId = `input-${component.id}`;
@@ -631,6 +631,11 @@ const AuthheroWidget = class {
631
631
  * Form data collected from inputs.
632
632
  */
633
633
  formData = {};
634
+ /**
635
+ * AbortController for an in-flight conditional mediation request.
636
+ * Aborted on screen change or component disconnect.
637
+ */
638
+ conditionalMediationAbort;
634
639
  /**
635
640
  * Emitted when the form is submitted.
636
641
  * The consuming application should handle the submission unless autoSubmit is true.
@@ -665,6 +670,9 @@ const AuthheroWidget = class {
665
670
  */
666
671
  screenChange;
667
672
  watchScreen(newValue) {
673
+ // Abort any in-flight conditional mediation when screen changes
674
+ this.conditionalMediationAbort?.abort();
675
+ this.conditionalMediationAbort = undefined;
668
676
  if (typeof newValue === "string") {
669
677
  try {
670
678
  this._screen = JSON.parse(newValue);
@@ -898,6 +906,8 @@ const AuthheroWidget = class {
898
906
  }
899
907
  disconnectedCallback() {
900
908
  window.removeEventListener("popstate", this.handlePopState);
909
+ this.conditionalMediationAbort?.abort();
910
+ this.conditionalMediationAbort = undefined;
901
911
  }
902
912
  async componentWillLoad() {
903
913
  // Parse initial props - this prevents unnecessary state changes during hydration that cause flashes
@@ -986,6 +996,10 @@ const AuthheroWidget = class {
986
996
  this.updateDataScreenAttribute();
987
997
  this.persistState();
988
998
  this.focusFirstInput();
999
+ // Start WebAuthn ceremony if returned with the screen (e.g. conditional mediation)
1000
+ if (data.ceremony) {
1001
+ this.performWebAuthnCeremony(data.ceremony);
1002
+ }
989
1003
  return true;
990
1004
  }
991
1005
  }
@@ -1177,9 +1191,19 @@ const AuthheroWidget = class {
1177
1191
  console.error("Invalid WebAuthn ceremony payload", ceremony);
1178
1192
  return;
1179
1193
  }
1194
+ if (ceremony.type === "webauthn-authentication-conditional") {
1195
+ // Conditional mediation runs in the background, no requestAnimationFrame needed
1196
+ this.executeWebAuthnConditionalMediation(ceremony);
1197
+ return;
1198
+ }
1180
1199
  requestAnimationFrame(() => {
1181
1200
  this.overrideFormSubmit();
1182
- this.executeWebAuthnRegistration(ceremony);
1201
+ if (ceremony.type === "webauthn-authentication") {
1202
+ this.executeWebAuthnAuthentication(ceremony);
1203
+ }
1204
+ else {
1205
+ this.executeWebAuthnRegistration(ceremony);
1206
+ }
1183
1207
  });
1184
1208
  }
1185
1209
  /**
@@ -1190,8 +1214,6 @@ const AuthheroWidget = class {
1190
1214
  if (typeof data !== "object" || data === null)
1191
1215
  return false;
1192
1216
  const obj = data;
1193
- if (obj.type !== "webauthn-registration")
1194
- return false;
1195
1217
  if (typeof obj.successAction !== "string")
1196
1218
  return false;
1197
1219
  const opts = obj.options;
@@ -1200,23 +1222,30 @@ const AuthheroWidget = class {
1200
1222
  const o = opts;
1201
1223
  if (typeof o.challenge !== "string")
1202
1224
  return false;
1203
- const rp = o.rp;
1204
- if (typeof rp !== "object" || rp === null)
1205
- return false;
1206
- if (typeof rp.id !== "string" ||
1207
- typeof rp.name !== "string")
1208
- return false;
1209
- const user = o.user;
1210
- if (typeof user !== "object" || user === null)
1211
- return false;
1212
- const u = user;
1213
- if (typeof u.id !== "string" ||
1214
- typeof u.name !== "string" ||
1215
- typeof u.displayName !== "string")
1216
- return false;
1217
- if (!Array.isArray(o.pubKeyCredParams))
1218
- return false;
1219
- return true;
1225
+ if (obj.type === "webauthn-registration") {
1226
+ const rp = o.rp;
1227
+ if (typeof rp !== "object" || rp === null)
1228
+ return false;
1229
+ if (typeof rp.id !== "string" ||
1230
+ typeof rp.name !== "string")
1231
+ return false;
1232
+ const user = o.user;
1233
+ if (typeof user !== "object" || user === null)
1234
+ return false;
1235
+ const u = user;
1236
+ if (typeof u.id !== "string" ||
1237
+ typeof u.name !== "string" ||
1238
+ typeof u.displayName !== "string")
1239
+ return false;
1240
+ if (!Array.isArray(o.pubKeyCredParams))
1241
+ return false;
1242
+ return true;
1243
+ }
1244
+ if (obj.type === "webauthn-authentication" ||
1245
+ obj.type === "webauthn-authentication-conditional") {
1246
+ return true;
1247
+ }
1248
+ return false;
1220
1249
  }
1221
1250
  /**
1222
1251
  * Perform the WebAuthn navigator.credentials.create() ceremony and submit
@@ -1329,6 +1358,193 @@ const AuthheroWidget = class {
1329
1358
  }
1330
1359
  }
1331
1360
  }
1361
+ /**
1362
+ * Perform the WebAuthn navigator.credentials.get() ceremony (explicit modal)
1363
+ * and submit the credential result via the form.
1364
+ */
1365
+ async executeWebAuthnAuthentication(ceremony) {
1366
+ const opts = ceremony.options;
1367
+ const b64uToBuf = (s) => {
1368
+ s = s.replace(/-/g, "+").replace(/_/g, "/");
1369
+ while (s.length % 4)
1370
+ s += "=";
1371
+ const b = atob(s);
1372
+ const a = new Uint8Array(b.length);
1373
+ for (let i = 0; i < b.length; i++)
1374
+ a[i] = b.charCodeAt(i);
1375
+ return a.buffer;
1376
+ };
1377
+ const bufToB64u = (b) => {
1378
+ const a = new Uint8Array(b);
1379
+ let s = "";
1380
+ for (let i = 0; i < a.length; i++)
1381
+ s += String.fromCharCode(a[i]);
1382
+ return btoa(s)
1383
+ .replace(/\+/g, "-")
1384
+ .replace(/\//g, "_")
1385
+ .replace(/=+$/, "");
1386
+ };
1387
+ const findForm = () => {
1388
+ const shadowRoot = this.el?.shadowRoot;
1389
+ if (shadowRoot) {
1390
+ const f = shadowRoot.querySelector("form");
1391
+ if (f)
1392
+ return f;
1393
+ }
1394
+ return document.querySelector("form");
1395
+ };
1396
+ try {
1397
+ const publicKey = {
1398
+ challenge: b64uToBuf(opts.challenge),
1399
+ rpId: opts.rpId,
1400
+ timeout: opts.timeout,
1401
+ userVerification: opts.userVerification || "preferred",
1402
+ };
1403
+ if (opts.allowCredentials?.length) {
1404
+ publicKey.allowCredentials = opts.allowCredentials.map((c) => ({
1405
+ id: b64uToBuf(c.id),
1406
+ type: c.type,
1407
+ transports: (c.transports || []),
1408
+ }));
1409
+ }
1410
+ const cred = (await navigator.credentials.get({
1411
+ publicKey,
1412
+ }));
1413
+ const response = cred.response;
1414
+ const resp = {
1415
+ id: cred.id,
1416
+ rawId: bufToB64u(cred.rawId),
1417
+ type: cred.type,
1418
+ response: {
1419
+ authenticatorData: bufToB64u(response.authenticatorData),
1420
+ clientDataJSON: bufToB64u(response.clientDataJSON),
1421
+ signature: bufToB64u(response.signature),
1422
+ },
1423
+ clientExtensionResults: cred.getClientExtensionResults(),
1424
+ authenticatorAttachment: cred.authenticatorAttachment || undefined,
1425
+ };
1426
+ if (response.userHandle) {
1427
+ resp.response.userHandle = bufToB64u(response.userHandle);
1428
+ }
1429
+ const form = findForm();
1430
+ if (form) {
1431
+ const cf = form.querySelector('[name="credential-field"]') ||
1432
+ form.querySelector("#credential-field");
1433
+ const af = form.querySelector('[name="action-field"]') ||
1434
+ form.querySelector("#action-field");
1435
+ if (cf)
1436
+ cf.value = JSON.stringify(resp);
1437
+ if (af)
1438
+ af.value = ceremony.successAction;
1439
+ form.submit();
1440
+ }
1441
+ }
1442
+ catch (e) {
1443
+ console.error("WebAuthn authentication error:", e);
1444
+ const form = findForm();
1445
+ if (form) {
1446
+ const af = form.querySelector('[name="action-field"]') ||
1447
+ form.querySelector("#action-field");
1448
+ if (af)
1449
+ af.value = "error";
1450
+ form.submit();
1451
+ }
1452
+ }
1453
+ }
1454
+ /**
1455
+ * Execute WebAuthn conditional mediation (autofill-assisted passkeys).
1456
+ * Runs in the background — the browser shows passkey suggestions in the
1457
+ * username field's autofill dropdown. Silently ignored if unsupported.
1458
+ */
1459
+ async executeWebAuthnConditionalMediation(ceremony) {
1460
+ // Feature detection
1461
+ if (!window.PublicKeyCredential ||
1462
+ !PublicKeyCredential.isConditionalMediationAvailable) {
1463
+ return;
1464
+ }
1465
+ const available = await PublicKeyCredential.isConditionalMediationAvailable();
1466
+ if (!available)
1467
+ return;
1468
+ // Abort any previous conditional mediation request
1469
+ this.conditionalMediationAbort?.abort();
1470
+ const abortController = new AbortController();
1471
+ this.conditionalMediationAbort = abortController;
1472
+ const opts = ceremony.options;
1473
+ const b64uToBuf = (s) => {
1474
+ s = s.replace(/-/g, "+").replace(/_/g, "/");
1475
+ while (s.length % 4)
1476
+ s += "=";
1477
+ const b = atob(s);
1478
+ const a = new Uint8Array(b.length);
1479
+ for (let i = 0; i < b.length; i++)
1480
+ a[i] = b.charCodeAt(i);
1481
+ return a.buffer;
1482
+ };
1483
+ const bufToB64u = (b) => {
1484
+ const a = new Uint8Array(b);
1485
+ let s = "";
1486
+ for (let i = 0; i < a.length; i++)
1487
+ s += String.fromCharCode(a[i]);
1488
+ return btoa(s)
1489
+ .replace(/\+/g, "-")
1490
+ .replace(/\//g, "_")
1491
+ .replace(/=+$/, "");
1492
+ };
1493
+ try {
1494
+ const cred = (await navigator.credentials.get({
1495
+ mediation: "conditional",
1496
+ signal: abortController.signal,
1497
+ publicKey: {
1498
+ challenge: b64uToBuf(opts.challenge),
1499
+ rpId: opts.rpId,
1500
+ timeout: opts.timeout,
1501
+ userVerification: opts.userVerification ||
1502
+ "preferred",
1503
+ },
1504
+ }));
1505
+ const response = cred.response;
1506
+ const resp = {
1507
+ id: cred.id,
1508
+ rawId: bufToB64u(cred.rawId),
1509
+ type: cred.type,
1510
+ response: {
1511
+ authenticatorData: bufToB64u(response.authenticatorData),
1512
+ clientDataJSON: bufToB64u(response.clientDataJSON),
1513
+ signature: bufToB64u(response.signature),
1514
+ },
1515
+ clientExtensionResults: cred.getClientExtensionResults(),
1516
+ authenticatorAttachment: cred.authenticatorAttachment || undefined,
1517
+ };
1518
+ if (response.userHandle) {
1519
+ resp.response.userHandle = bufToB64u(response.userHandle);
1520
+ }
1521
+ // Submit via the widget's form handling
1522
+ this.formData["credential-field"] = JSON.stringify(resp);
1523
+ this.formData["action-field"] = ceremony.successAction;
1524
+ // Ensure form submit override is set up, then submit
1525
+ this.overrideFormSubmit();
1526
+ const shadowRoot = this.el?.shadowRoot;
1527
+ const form = shadowRoot?.querySelector("form");
1528
+ if (form) {
1529
+ // Set the hidden input values directly
1530
+ const cf = form.querySelector('[name="credential-field"]') ||
1531
+ form.querySelector("#credential-field");
1532
+ const af = form.querySelector('[name="action-field"]') ||
1533
+ form.querySelector("#action-field");
1534
+ if (cf)
1535
+ cf.value = JSON.stringify(resp);
1536
+ if (af)
1537
+ af.value = ceremony.successAction;
1538
+ form.submit();
1539
+ }
1540
+ }
1541
+ catch (e) {
1542
+ // Silently ignore AbortError and NotAllowedError
1543
+ if (e?.name === "AbortError" || e?.name === "NotAllowedError")
1544
+ return;
1545
+ console.error("Conditional mediation error:", e);
1546
+ }
1547
+ }
1332
1548
  handleButtonClick = (detail) => {
1333
1549
  // If this is a submit button click, trigger form submission
1334
1550
  if (detail.type === "submit") {
@@ -1570,7 +1786,7 @@ const AuthheroWidget = class {
1570
1786
  };
1571
1787
  // Get logo URL from theme.widget (takes precedence) or branding
1572
1788
  const logoUrl = this._theme?.widget?.logo_url || this._branding?.logo_url;
1573
- return (h("div", { class: "widget-container", part: "container", "data-authstack-container": true }, h("header", { class: "widget-header", part: "header" }, logoUrl && (h("div", { class: "logo-wrapper", part: "logo-wrapper" }, h("img", { class: "logo", part: "logo", src: logoUrl, alt: "Logo" }))), screen.title && (h("h1", { class: "title", part: "title", innerHTML: sanitizeHtml(screen.title) })), screen.description && (h("p", { class: "description", part: "description", innerHTML: sanitizeHtml(screen.description) }))), h("div", { class: "widget-body", part: "body" }, screenErrors.map((err) => (h("div", { class: "message message-error", part: "message message-error", key: err.id ?? err.text }, err.text))), screenSuccesses.map((msg) => (h("div", { class: "message message-success", part: "message message-success", key: msg.id ?? msg.text }, msg.text))), h("form", { onSubmit: this.handleSubmit, part: "form" }, hiddenComponents.map((c) => (h("input", { type: "hidden", name: c.id, id: c.id, key: c.id, value: this.formData[c.id] || "" }))), h("div", { class: "form-content" }, socialComponents.length > 0 && (h("div", { class: "social-section", part: "social-section" }, socialComponents.map((component) => (h("authhero-node", { key: component.id, component: component, value: this.formData[component.id], onFieldChange: (e) => this.handleInputChange(e.detail.id, e.detail.value), onButtonClick: (e) => this.handleButtonClick(e.detail), disabled: this.loading, exportparts: getExportParts(component) }))))), socialComponents.length > 0 &&
1789
+ return (h("div", { class: "widget-container", part: "container", "data-authstack-container": true }, h("header", { class: "widget-header", part: "header" }, logoUrl && (h("div", { class: "logo-wrapper", part: "logo-wrapper" }, h("img", { class: "logo", part: "logo", src: logoUrl, alt: "Logo" }))), screen.title && (h("h1", { class: "title", part: "title", innerHTML: sanitizeHtml(screen.title) })), screen.description && (h("p", { class: "description", part: "description", innerHTML: sanitizeHtml(screen.description) }))), h("div", { class: "widget-body", part: "body" }, screenErrors.map((err) => (h("div", { class: "message message-error", part: "message message-error", key: err.id ?? err.text }, err.text))), screenSuccesses.map((msg) => (h("div", { class: "message message-success", part: "message message-success", key: msg.id ?? msg.text }, msg.text))), h("form", { onSubmit: this.handleSubmit, action: screen.action, method: screen.method || "POST", part: "form" }, hiddenComponents.map((c) => (h("input", { type: "hidden", name: c.id, id: c.id, key: c.id, value: this.formData[c.id] || "" }))), h("div", { class: "form-content" }, socialComponents.length > 0 && (h("div", { class: "social-section", part: "social-section" }, socialComponents.map((component) => (h("authhero-node", { key: component.id, component: component, value: this.formData[component.id], onFieldChange: (e) => this.handleInputChange(e.detail.id, e.detail.value), onButtonClick: (e) => this.handleButtonClick(e.detail), disabled: this.loading, exportparts: getExportParts(component) }))))), socialComponents.length > 0 &&
1574
1790
  fieldComponents.length > 0 &&
1575
1791
  hasDivider && (h("div", { class: "divider", part: "divider" }, h("span", { class: "divider-text" }, dividerText))), h("div", { class: "fields-section", part: "fields-section" }, fieldComponents.map((component) => (h("authhero-node", { key: component.id, component: component, value: this.formData[component.id], onFieldChange: (e) => this.handleInputChange(e.detail.id, e.detail.value), onButtonClick: (e) => this.handleButtonClick(e.detail), disabled: this.loading })))))), screen.links && screen.links.length > 0 && (h("div", { class: "links", part: "links" }, screen.links.map((link) => (h("span", { class: "link-wrapper", part: "link-wrapper", key: link.id ?? link.href }, link.linkText ? (h("span", null, link.text, " ", h("a", { href: link.href, class: "link", part: "link", onClick: (e) => this.handleLinkClick(e, {
1576
1792
  id: link.id,