@authhero/widget 0.40.1 → 0.40.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authhero-widget/authhero-widget.esm.js +1 -1
- package/dist/authhero-widget/p-dc0662ad.entry.js +1 -0
- package/dist/cjs/authhero-widget.cjs.entry.js +80 -0
- package/dist/collection/components/authhero-widget/authhero-widget.js +81 -1
- package/dist/components/authhero-widget.js +1 -1
- package/dist/esm/authhero-widget.entry.js +80 -0
- package/dist/types/components/authhero-widget/authhero-widget.d.ts +17 -0
- package/hydrate/index.js +74 -0
- package/hydrate/index.mjs +74 -0
- package/package.json +2 -2
- package/dist/authhero-widget/p-36898e2d.entry.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{p as e,b as a}from"./p-FUW5zvoZ.js";export{s as setNonce}from"./p-FUW5zvoZ.js";import{g as t}from"./p-DQuL1Twl.js";(()=>{const a=import.meta.url,t={};return""!==a&&(t.resourcesUrl=new URL(".",a).href),e(t)})().then((async e=>(await t(),a([["p-c6ec4c36",[[513,"authhero-node",{component:[16],value:[1],disabled:[4],locale:[1],passwordVisible:[32],selectedCountry:[32],localPhoneNumber:[32],countryDropdownOpen:[32],telEmailMode:[32],dateSegments:[32]},null,{component:[{componentChanged:0}],value:[{valueChanged:0}]}]]],["p-
|
|
1
|
+
import{p as e,b as a}from"./p-FUW5zvoZ.js";export{s as setNonce}from"./p-FUW5zvoZ.js";import{g as t}from"./p-DQuL1Twl.js";(()=>{const a=import.meta.url,t={};return""!==a&&(t.resourcesUrl=new URL(".",a).href),e(t)})().then((async e=>(await t(),a([["p-c6ec4c36",[[513,"authhero-node",{component:[16],value:[1],disabled:[4],locale:[1],passwordVisible:[32],selectedCountry:[32],localPhoneNumber:[32],countryDropdownOpen:[32],telEmailMode:[32],dateSegments:[32]},null,{component:[{componentChanged:0}],value:[{valueChanged:0}]}]]],["p-dc0662ad",[[513,"authhero-widget",{screen:[1],apiUrl:[1,"api-url"],baseUrl:[1,"base-url"],state:[1025],screenId:[1025,"screen-id"],authParams:[1,"auth-params"],statePersistence:[1,"state-persistence"],storageKey:[1,"storage-key"],branding:[1],theme:[1],loading:[1028],autoSubmit:[4,"auto-submit"],autoNavigate:[4,"auto-navigate"],locale:[1],_screen:[32],_authParams:[32],_branding:[32],_theme:[32],formData:[32],listFilter:[32]},null,{screenId:[{watchScreenId:0}],screen:[{watchScreen:0}],branding:[{watchBranding:0}],theme:[{watchTheme:0}],authParams:[{watchAuthParams:0}]}]]]],e))));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as t,c as e,g as i,h as o}from"./p-FUW5zvoZ.js";import{s as n}from"./p-Che3Wd7J.js";function s(t){const e=t.match(/^#([0-9a-f]{3})$/i)||t.match(/^#([0-9a-f]{6})$/i);if(!e)return null;let i=e[1];3===i.length&&(i=i[0]+i[0]+i[1]+i[1]+i[2]+i[2]);const o=parseInt(i,16);return[o>>16&255,o>>8&255,255&o]}function r(t){const e=s(t);if(!e)return NaN;const[i,o,n]=e.map((t=>{const e=t/255;return e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)}));return.2126*i+.7152*o+.0722*n}function a(t,e){const i=r(t),o=r(e);return isNaN(i)||isNaN(o)?NaN:(Math.max(i,o)+.05)/(Math.min(i,o)+.05)}function c(t,e="light"){const i=a(t,"#000000"),o=a(t,"#ffffff");return"light"===e?i>1.35*o?"#000000":"#ffffff":1.35*i>o?"#000000":"#ffffff"}function h(t,e){const i=s(t);if(!i)return t;const[o,n,r]=i,a=t=>Math.max(0,Math.round(t*(1-e))).toString(16).padStart(2,"0");return`#${a(o)}${a(n)}${a(r)}`}function l(t,e){const i=s(t);if(!i)return t;const[o,n,r]=i,a=t=>Math.min(255,Math.round(t+(255-t)*e)).toString(16).padStart(2,"0");return`#${a(o)}${a(n)}${a(r)}`}function d(t,e,i=4.5){if(a(t,e)>=i)return t;const o=r(e)>.5;let n=t;for(let s=1;s<=10;s++)if(n=o?h(t,.1*s):l(t,.1*s),a(n,e)>=i)return n;return o?"#000000":"#ffffff"}function f(t,e){if(void 0!==e)return`${e}px`;switch(t){case"pill":return"9999px";case"rounded":return"8px";case"sharp":return"0";default:return}}function u(t){if(!t)return{};const e={};if(t.colors?.primary&&(e["--ah-color-primary"]=t.colors.primary),t.colors?.page_background){const i=t.colors.page_background;"solid"===i.type&&i.start?e["--ah-page-bg"]=i.start:"gradient"===i.type&&i.start&&i.end&&(e["--ah-page-bg"]=`linear-gradient(${i.angle_deg??180}deg, ${i.start}, ${i.end})`)}return t.logo_url&&(e["--ah-logo-url"]=`url(${t.logo_url})`),t.font?.url&&(e["--ah-font-url"]=t.font.url),e}function p(t){if(!t)return{};const e={};if(t.borders){const i=t.borders;void 0!==i.widget_corner_radius&&(e["--ah-widget-radius"]=`${i.widget_corner_radius}px`),void 0!==i.widget_border_weight&&(e["--ah-widget-border-width"]=`${i.widget_border_weight}px`),!1===i.show_widget_shadow&&(e["--ah-widget-shadow"]="none");const o=f(i.buttons_style,i.button_border_radius);o&&(e["--ah-btn-radius"]=o),void 0!==i.button_border_weight&&(e["--ah-btn-border-width"]=`${i.button_border_weight}px`);const n=f(i.inputs_style,i.input_border_radius);n&&(e["--ah-input-radius"]=n),void 0!==i.input_border_weight&&(e["--ah-input-border-width"]=`${i.input_border_weight}px`)}if(t.colors){const i=t.colors;if(i.primary_button)if(e["--ah-color-primary"]=i.primary_button,i.primary_button_label)e["--ah-color-text-on-primary"]=i.primary_button_label;else{e["--ah-color-text-on-primary"]=c(i.primary_button,"light");const t=c(i.primary_button,"dark");t!==e["--ah-color-text-on-primary"]&&(e["--ah-color-text-on-primary-dark"]=t)}else i.primary_button_label&&(e["--ah-color-text-on-primary"]=i.primary_button_label);i.secondary_button_border&&(e["--ah-btn-secondary-border"]=i.secondary_button_border),i.secondary_button_label&&(e["--ah-btn-secondary-text"]=i.secondary_button_label),i.body_text&&(e["--ah-color-text"]=i.body_text),i.header&&(e["--ah-color-text-header"]=i.header),i.input_labels_placeholders&&(e["--ah-color-text-label"]=i.input_labels_placeholders,e["--ah-color-text-muted"]=i.input_labels_placeholders),i.input_filled_text&&(e["--ah-color-input-text"]=i.input_filled_text),i.widget_background&&(e["--ah-color-bg"]=i.widget_background),i.input_background&&(e["--ah-color-input-bg"]=i.input_background),i.widget_border&&(e["--ah-widget-border-color"]=i.widget_border),i.input_border&&(e["--ah-color-border"]=i.input_border),i.links_focused_components&&(e["--ah-color-link"]=d(i.links_focused_components,i.widget_background||"#ffffff")),i.base_focus_color&&(e["--ah-color-focus-ring"]=i.base_focus_color),i.base_hover_color&&(e["--ah-color-primary-hover"]=i.base_hover_color),i.error&&(e["--ah-color-error"]=i.error),i.success&&(e["--ah-color-success"]=i.success),i.icons&&(e["--ah-color-icon"]=i.icons);const o=i.widget_background||"#ffffff",n=i.input_background||o,s=e["--ah-color-border"]||i.input_border||"#c9cace",r=a(s,o),h=a(s,n);Math.min(r,h)<3&&(e["--ah-color-border"]=d(s,r<h?o:n,3))}if(t.fonts){const i=t.fonts,o=i.reference_text_size||16,n=t=>t>=50?Math.round(t/100*o):t;i.font_url&&(e["--ah-font-url"]=i.font_url),i.reference_text_size&&(e["--ah-font-size-base"]=`${i.reference_text_size}px`),i.title?.size&&(e["--ah-font-size-title"]=`${n(i.title.size)}px`),i.subtitle?.size&&(e["--ah-font-size-subtitle"]=`${n(i.subtitle.size)}px`),i.body_text?.size&&(e["--ah-font-size-body"]=`${n(i.body_text.size)}px`),i.input_labels?.size&&(e["--ah-font-size-label"]=`${n(i.input_labels.size)}px`),i.buttons_text?.size&&(e["--ah-font-size-btn"]=`${n(i.buttons_text.size)}px`),i.links?.size&&(e["--ah-font-size-link"]=`${n(i.links.size)}px`),"underlined"===i.links_style&&(e["--ah-link-decoration"]="underline"),void 0!==i.title?.bold&&(e["--ah-font-weight-title"]=i.title.bold?"700":"400"),void 0!==i.subtitle?.bold&&(e["--ah-font-weight-subtitle"]=i.subtitle.bold?"700":"400"),void 0!==i.body_text?.bold&&(e["--ah-font-weight-body"]=i.body_text.bold?"700":"400"),void 0!==i.input_labels?.bold&&(e["--ah-font-weight-label"]=i.input_labels.bold?"700":"400"),void 0!==i.buttons_text?.bold&&(e["--ah-font-weight-btn"]=i.buttons_text.bold?"600":"400"),void 0!==i.links?.bold&&(e["--ah-font-weight-link"]=i.links.bold?"700":"400")}if(t.widget){const i=t.widget;if(i.header_text_alignment&&(e["--ah-title-align"]=i.header_text_alignment),i.logo_height&&(e["--ah-logo-height"]=`${i.logo_height}px`),i.logo_position){const t={center:"center",left:"flex-start",right:"flex-end"};"none"===i.logo_position?e["--ah-logo-display"]="none":e["--ah-logo-align"]=t[i.logo_position]??"center"}i.social_buttons_layout&&("top"===i.social_buttons_layout?(e["--ah-social-order"]="0",e["--ah-divider-order"]="1",e["--ah-fields-order"]="2"):(e["--ah-social-order"]="2",e["--ah-divider-order"]="1",e["--ah-fields-order"]="0"))}if(t.page_background){const i=t.page_background;i.background_color&&(e["--ah-page-bg"]=i.background_color),i.background_image_url&&(e["--ah-page-bg-image"]=`url(${i.background_image_url})`)}return e}const g={br:[],em:[],i:[],strong:[],b:[],u:[],span:["class"],a:["href","class"]};function m(t){if(!t)return"";if(!t.includes("<"))return t;let e=t;e=e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'");for(const[t,i]of Object.entries(g)){if("br"===t){e=e.replace(/<br\s*\/?>/gi,"<br>");continue}const o=new RegExp(`<${t}((?:\\s+[a-z-]+(?:="[^&]*"|='[^&]*')?)*)\\s*>`,"gi");e=e.replace(o,((e,o)=>{const n=[];if(o){const t=o.replace(/"/g,'"').replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),e=/([a-z-]+)=["']([^"']*)["']/gi;let s;for(;null!==(s=e.exec(t));){const[,t,e]=s;t&&i.includes(t.toLowerCase())&&("href"===t.toLowerCase()?b(e||"")&&n.push(`${t}="${w(e||"")}"`):n.push(`${t}="${w(e||"")}"`))}}"a"===t&&(n.push('target="_blank"'),n.push('rel="noopener noreferrer"'));const s=n.length?" "+n.join(" "):"";return`<${t}${s}>`}));const n=new RegExp(`</${t}>`,"gi");e=e.replace(n,`</${t}>`)}return e}function b(t){if(!t)return!1;if(t.startsWith("/")||t.startsWith("#")||t.startsWith("?"))return!0;try{const e=new URL(t,"https://example.com");return"http:"===e.protocol||"https:"===e.protocol}catch{return!1}}function w(t){return t.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}const x=new Set(["TEXT","EMAIL","CODE","PASSWORD","NUMBER","URL"]),v=new Set(["TEXT","EMAIL","CODE","PASSWORD","NUMBER","TEL","URL","DATE","BOOLEAN","LEGAL","COUNTRY","DROPDOWN","CHOICE"]),y=class{constructor(i){t(this,i),this.formSubmit=e(this,"formSubmit"),this.buttonClick=e(this,"buttonClick"),this.linkClick=e(this,"linkClick"),this.navigate=e(this,"navigate"),this.flowComplete=e(this,"flowComplete"),this.flowError=e(this,"flowError"),this.screenChange=e(this,"screenChange")}get el(){return i(this)}screen;apiUrl;baseUrl;state;screenId;watchScreenId(){this.updateDataScreenAttribute()}authParams;statePersistence="memory";storageKey="authhero_widget";branding;theme;loading=!1;autoSubmit=!1;autoNavigate;locale;_screen;_authParams;_branding;_theme;formData={};listFilter="";conditionalMediationAbort;loadedFontUrl;formSubmit;buttonClick;linkClick;navigate;flowComplete;flowError;screenChange;watchScreen(t){if(this.conditionalMediationAbort?.abort(),this.conditionalMediationAbort=void 0,"string"==typeof t)try{this._screen=JSON.parse(t)}catch{console.error("Failed to parse screen JSON")}else this._screen=t;this._screen&&(this.formData={},this.listFilter="",this.initFormDataFromDefaults(this._screen),this.screenChange.emit(this._screen),this.updateDataScreenAttribute())}initFormDataFromDefaults(t){const e={};for(const i of t.components||[]){if(!("config"in i)||!i.config)continue;if(!("default_value"in i.config))continue;const t=i.config.default_value;"string"==typeof t&&""!==t?e[i.id]=t:"boolean"==typeof t&&(e[i.id]=t?"true":"false")}Object.keys(e).length>0&&(this.formData={...e,...this.formData})}updateDataScreenAttribute(){const t=this._screen?.name||this.screenId;t?this.el.setAttribute("data-screen",t):this.el.removeAttribute("data-screen");const e=this.el.closest("[data-authhero-widget-container]");e&&(t?e.setAttribute("data-screen",t):e.removeAttribute("data-screen"))}watchBranding(t){if("string"==typeof t)try{this._branding=JSON.parse(t)}catch{console.error("Failed to parse branding JSON")}else this._branding=t;this.applyThemeStyles()}watchTheme(t){if("string"==typeof t)try{this._theme=JSON.parse(t)}catch{console.error("Failed to parse theme JSON")}else this._theme=t;this.applyThemeStyles()}watchAuthParams(t){if("string"==typeof t)try{this._authParams=JSON.parse(t)}catch{console.error("Failed to parse authParams JSON")}else this._authParams=t}applyThemeStyles(){const t=(e=this._theme,{...u(this._branding),...p(e)});var e;!function(t,e){Object.entries(e).forEach((([e,i])=>{t.style.setProperty(e,i)}))}(this.el,t),this.loadCustomFont()}loadCustomFont(){if("undefined"==typeof document)return;const t=this._theme?.fonts?.font_url||this._branding?.font?.url;if(t===this.loadedFontUrl)return;for(const t of Array.from(document.head.querySelectorAll("link[data-authhero-font]")))t.remove();if(this.loadedFontUrl=void 0,!t)return;const e=document.createElement("link");e.rel="stylesheet",e.href=t,e.setAttribute("data-authhero-font",t),document.head.appendChild(e),this.loadedFontUrl=t}focusFirstInput(){requestAnimationFrame((()=>{const t=this.el.shadowRoot;if(!t)return;const e=t.querySelectorAll("authhero-node");for(const t of Array.from(e)){const e=t.shadowRoot;if(e){const t=e.querySelector('input:not([type="hidden"]):not([type="checkbox"]):not([disabled]), textarea:not([disabled])');if(t)return void t.focus()}}}))}pendingRenderResolvers=[];activeSwaps=0;updateReadyAttribute(){this.el.toggleAttribute("data-ready",!this.loading&&0===this.activeSwaps)}componentDidRender(){if(this.updateReadyAttribute(),0===this.pendingRenderResolvers.length)return;const t=this.pendingRenderResolvers;this.pendingRenderResolvers=[],t.forEach((t=>t()))}nextRender(){return new Promise((t=>{let e=!1;const i=()=>{e||(e=!0,t())};this.pendingRenderResolvers.push(i),requestAnimationFrame((()=>requestAnimationFrame(i)))}))}async swapScreen(t){const e=this.el.shadowRoot?.querySelector(".widget-container"),i="function"==typeof window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches;if(e&&"function"==typeof e.animate&&!i){this.activeSwaps++;try{await this.animateSwap(e,t)}finally{this.activeSwaps--,this.updateReadyAttribute()}}else t()}async animateSwap(t,e){const i=t.getBoundingClientRect().height;t.style.height=`${i}px`,t.style.overflow="hidden",e(),await this.nextRender();const o=()=>{t.style.height="",t.style.overflow=""};t.style.height="auto";const n=t.getBoundingClientRect().height;if(t.style.height=`${i}px`,t.getBoundingClientRect(),Math.abs(n-i)<1)return void o();const s=t.animate([{height:`${i}px`},{height:`${n}px`}],{duration:520,easing:"cubic-bezier(0.22, 1, 0.36, 1)"});try{await s.finished}catch{}finally{o()}}get shouldAutoNavigate(){return this.autoNavigate??this.autoSubmit}buildUrl(t){return this.baseUrl?new URL(t,this.baseUrl).toString():t}loadPersistedState(){if("url"===this.statePersistence){const t=new URL(window.location.href).searchParams.get("state");t&&!this.state&&(this.state=t)}else if("session"===this.statePersistence)try{const t=sessionStorage.getItem(`${this.storageKey}_state`);t&&!this.state&&(this.state=t);const e=sessionStorage.getItem(`${this.storageKey}_screenId`);e&&!this.screenId&&(this.screenId=e)}catch{}}persistState(){if("url"===this.statePersistence){const t=new URL(window.location.href);this.state&&t.searchParams.set("state",this.state),this.screenId&&t.searchParams.set("screen",this.screenId),window.history.replaceState({},"",t.toString())}else if("session"===this.statePersistence)try{this.state&&sessionStorage.setItem(`${this.storageKey}_state`,this.state),this.screenId&&sessionStorage.setItem(`${this.storageKey}_screenId`,this.screenId)}catch{}}handlePopState=t=>{if(!this.apiUrl)return;t.state?.state&&(this.state=t.state.state);const e=t.state?.screen??this.extractScreenIdFromHref(location.href);e&&this.fetchScreen(e)};connectedCallback(){window.addEventListener("popstate",this.handlePopState)}disconnectedCallback(){window.removeEventListener("popstate",this.handlePopState),this.conditionalMediationAbort?.abort(),this.conditionalMediationAbort=void 0}readJsonScript(t){if(!this.el)return;const e=this.el.querySelector(`script[type="application/json"][data-authhero="${t}"]`);return e?.textContent??void 0}async componentWillLoad(){if(!this._screen){const t=this.screen||this.readJsonScript("screen")||this.el?.getAttribute("screen");t&&this.watchScreen(t)}this._branding||this.watchBranding(this.branding??this.readJsonScript("branding")),this._theme||this.watchTheme(this.theme??this.readJsonScript("theme")),this._authParams||this.watchAuthParams(this.authParams??this.readJsonScript("auth-params")),this._screen&&this.adoptPrehydrationValues(this._screen),this.loadPersistedState(),this.apiUrl&&!this._screen&&await this.fetchScreen(this.screenId)}adoptPrehydrationValues(t){const e=this.el.shadowRoot;if(!e)return;const i=[e];e.querySelectorAll("authhero-node").forEach((t=>{t.shadowRoot&&i.push(t.shadowRoot)}));const o={};for(const e of t.components??[])if(x.has(e.type))for(const t of i){const i=Array.from(t.querySelectorAll("input[name]")).find((t=>t.name===e.id&&"hidden"!==t.type));if(i){o[e.id]=i.value;break}}Object.keys(o).length>0&&(this.formData={...this.formData,...o})}async fetchScreen(t,e){if(!this.apiUrl)return!1;const i=t||this.screenId;let o=this.apiUrl;i&&o.includes("{screenId}")&&(o=o.replace("{screenId}",encodeURIComponent(i)));const n=new URL(o,this.baseUrl||window.location.origin);this.state&&n.searchParams.set("state",this.state),e&&n.searchParams.set("nodeId",e),this.loading=!0;try{const t=await fetch(this.buildUrl(n.pathname+n.search),{credentials:"include",headers:{Accept:"application/json"}});if(t.ok){const e=await t.json();if(e.screen?(this._screen=e.screen,e.branding&&(this._branding=e.branding,this.applyThemeStyles()),e.state&&(this.state=e.state),e.screenId&&(this.screenId=e.screenId)):this._screen=e,this._screen)return this.listFilter="",i&&i!==this.screenId&&(this.screenId=i),this.initFormDataFromDefaults(this._screen),this.screenChange.emit(this._screen),this.updateDataScreenAttribute(),this.persistState(),this.focusFirstInput(),e.ceremony&&this.performWebAuthnCeremony(e.ceremony),!0}else{const e=await t.json().catch((()=>({message:"Failed to load screen"})));this.flowError.emit({message:e.message||"Failed to load screen"})}}catch(t){console.error("Failed to fetch screen:",t),this.flowError.emit({message:t instanceof Error?t.message:"Failed to fetch screen"})}finally{this.loading=!1}return!1}handleInputChange=(t,e)=>{this.formData={...this.formData,[t]:e}};handleSubmit=async(t,e)=>{if(t.preventDefault(),!this._screen||this.loading)return;let i={...this.formData,...e||{}};const o=this.el.shadowRoot?.querySelector("form");if(o&&o.querySelectorAll('input[type="hidden"]').forEach((t=>{t.name&&t.value&&(i[t.name]=t.value)})),this.formSubmit.emit({screen:this._screen,data:i}),this.autoSubmit)if(this._screen.method&&"GET"!==this._screen.method.toUpperCase()){this.loading=!0;try{const t=await fetch(this.buildUrl(this._screen.action),{method:this._screen.method,credentials:"include",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({data:i})}),e=t.headers.get("content-type");if(e?.includes("text/html")){const e=await t.text();return document.open(),document.write(e),void document.close()}if(e?.includes("application/json")){const e=await t.json();if(e.redirect){this.flowComplete.emit({redirectUrl:e.redirect});const t=this.navigate.emit({url:e.redirect});this.shouldAutoNavigate&&!t.defaultPrevented&&(window.location.href=e.redirect)}else!t.ok&&e.screen?await this.swapScreen((()=>{this.loading=!1,this._screen=e.screen,this.listFilter="",this.initFormDataFromDefaults(e.screen),this.screenChange.emit(e.screen),this.updateDataScreenAttribute(),this.focusFirstInput()})):e.screen?await this.swapScreen((()=>{this.loading=!1,this._screen=e.screen,this.listFilter="",this.formData={},this.initFormDataFromDefaults(e.screen),this.screenChange.emit(e.screen),this.updateDataScreenAttribute(),e.screenId&&(this.screenId=e.screenId),this.persistState(),e.navigateUrl&&this.shouldAutoNavigate&&window.history.pushState({screen:e.screenId,state:this.state},"",e.navigateUrl),e.branding&&(this._branding=e.branding,this.applyThemeStyles()),e.state&&(this.state=e.state,this.persistState()),e.ceremony&&this.performWebAuthnCeremony(e.ceremony),this.focusFirstInput()})):e.complete?this.flowComplete.emit({}):!t.ok&&e.error&&(this._screen&&(this._screen={...this._screen,messages:[...this._screen.messages||[],{text:e.error,type:"error"}]}),this.flowError.emit({message:e.error}))}}catch(t){console.error("Form submission failed:",t),this.flowError.emit({message:t instanceof Error?t.message:"Form submission failed"})}finally{this.loading=!1}}else window.location.href=this.buildUrl(this._screen.action)};overrideFormSubmit(){const t=this.el.shadowRoot;if(!t)return;const e=t.querySelector("form");e&&(e.submit=()=>{const t=new FormData(e),i={};t.forEach(((t,e)=>{"string"==typeof t&&(i[e]=t)})),this.handleSubmit({preventDefault:()=>{}},i)})}performWebAuthnCeremony(t){this.isValidWebAuthnCeremony(t)?"webauthn-authentication-conditional"!==t.type?requestAnimationFrame((()=>{this.overrideFormSubmit(),"webauthn-authentication"===t.type?this.executeWebAuthnAuthentication(t):this.executeWebAuthnRegistration(t)})):this.executeWebAuthnConditionalMediation(t):console.error("Invalid WebAuthn ceremony payload",t)}isValidWebAuthnCeremony(t){if("object"!=typeof t||null===t)return!1;const e=t;if("string"!=typeof e.successAction)return!1;const i=e.options;if("object"!=typeof i||null===i)return!1;if("string"!=typeof i.challenge)return!1;if("webauthn-registration"===e.type){const t=i.rp;if("object"!=typeof t||null===t)return!1;if("string"!=typeof t.id||"string"!=typeof t.name)return!1;const e=i.user;return"object"==typeof e&&null!==e&&("string"==typeof e.id&&"string"==typeof e.name&&"string"==typeof e.displayName&&!!Array.isArray(i.pubKeyCredParams))}return"webauthn-authentication"===e.type||"webauthn-authentication-conditional"===e.type}async executeWebAuthnRegistration(t){const e=t.options,i=t=>{for(t=t.replace(/-/g,"+").replace(/_/g,"/");t.length%4;)t+="=";const e=atob(t),i=new Uint8Array(e.length);for(let t=0;t<e.length;t++)i[t]=e.charCodeAt(t);return i.buffer},o=t=>{const e=new Uint8Array(t);let i="";for(let t=0;t<e.length;t++)i+=String.fromCharCode(e[t]);return btoa(i).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")},n=()=>{const t=this.el?.shadowRoot;if(t){const e=t.querySelector("form");if(e)return e}return document.querySelector("form")};try{const s={challenge:i(e.challenge),rp:{id:e.rp.id,name:e.rp.name},user:{id:i(e.user.id),name:e.user.name,displayName:e.user.displayName},pubKeyCredParams:e.pubKeyCredParams.map((t=>({alg:t.alg,type:t.type}))),timeout:e.timeout,attestation:e.attestation||"none",authenticatorSelection:e.authenticatorSelection?{residentKey:e.authenticatorSelection.residentKey||"preferred",userVerification:e.authenticatorSelection.userVerification||"preferred"}:void 0};e.excludeCredentials?.length&&(s.excludeCredentials=e.excludeCredentials.map((t=>({id:i(t.id),type:t.type,transports:t.transports||[]}))));const r=await navigator.credentials.create({publicKey:s}),a=r.response,c={id:r.id,rawId:o(r.rawId),type:r.type,response:{attestationObject:o(a.attestationObject),clientDataJSON:o(a.clientDataJSON)},clientExtensionResults:r.getClientExtensionResults(),authenticatorAttachment:r.authenticatorAttachment||void 0};"function"==typeof a.getTransports&&(c.response.transports=a.getTransports());const h=n();if(h){const e=h.querySelector('[name="credential-field"]')||h.querySelector("#credential-field"),i=h.querySelector('[name="action-field"]')||h.querySelector("#action-field");e&&(e.value=JSON.stringify(c)),i&&(i.value=t.successAction),h.submit()}}catch(t){console.error("WebAuthn registration error:",t);const e=n();if(e){const t=e.querySelector('[name="action-field"]')||e.querySelector("#action-field");t&&(t.value="error"),e.submit()}}}async executeWebAuthnAuthentication(t){const e=t.options,i=t=>{for(t=t.replace(/-/g,"+").replace(/_/g,"/");t.length%4;)t+="=";const e=atob(t),i=new Uint8Array(e.length);for(let t=0;t<e.length;t++)i[t]=e.charCodeAt(t);return i.buffer},o=t=>{const e=new Uint8Array(t);let i="";for(let t=0;t<e.length;t++)i+=String.fromCharCode(e[t]);return btoa(i).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")},n=()=>{const t=this.el?.shadowRoot;if(t){const e=t.querySelector("form");if(e)return e}return document.querySelector("form")};try{const s={challenge:i(e.challenge),rpId:e.rpId,timeout:e.timeout,userVerification:e.userVerification||"preferred"};e.allowCredentials?.length&&(s.allowCredentials=e.allowCredentials.map((t=>({id:i(t.id),type:t.type,transports:t.transports||[]}))));const r=await navigator.credentials.get({publicKey:s}),a=r.response,c={id:r.id,rawId:o(r.rawId),type:r.type,response:{authenticatorData:o(a.authenticatorData),clientDataJSON:o(a.clientDataJSON),signature:o(a.signature)},clientExtensionResults:r.getClientExtensionResults(),authenticatorAttachment:r.authenticatorAttachment||void 0};a.userHandle&&(c.response.userHandle=o(a.userHandle));const h=n();if(h){const e=h.querySelector('[name="credential-field"]')||h.querySelector("#credential-field"),i=h.querySelector('[name="action-field"]')||h.querySelector("#action-field");e&&(e.value=JSON.stringify(c)),i&&(i.value=t.successAction),h.submit()}}catch(t){console.error("WebAuthn authentication error:",t);const e=n();if(e){const t=e.querySelector('[name="action-field"]')||e.querySelector("#action-field");t&&(t.value="error"),e.submit()}}}async executeWebAuthnConditionalMediation(t){if(!window.PublicKeyCredential||!PublicKeyCredential.isConditionalMediationAvailable)return;if(!await PublicKeyCredential.isConditionalMediationAvailable())return;this.conditionalMediationAbort?.abort();const e=new AbortController;this.conditionalMediationAbort=e;const i=t.options,o=t=>{for(t=t.replace(/-/g,"+").replace(/_/g,"/");t.length%4;)t+="=";const e=atob(t),i=new Uint8Array(e.length);for(let t=0;t<e.length;t++)i[t]=e.charCodeAt(t);return i.buffer},n=t=>{const e=new Uint8Array(t);let i="";for(let t=0;t<e.length;t++)i+=String.fromCharCode(e[t]);return btoa(i).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")};try{const s=await navigator.credentials.get({mediation:"conditional",signal:e.signal,publicKey:{challenge:o(i.challenge),rpId:i.rpId,timeout:i.timeout,userVerification:i.userVerification||"preferred"}}),r=s.response,a={id:s.id,rawId:n(s.rawId),type:s.type,response:{authenticatorData:n(r.authenticatorData),clientDataJSON:n(r.clientDataJSON),signature:n(r.signature)},clientExtensionResults:s.getClientExtensionResults(),authenticatorAttachment:s.authenticatorAttachment||void 0};r.userHandle&&(a.response.userHandle=n(r.userHandle)),this.formData["credential-field"]=JSON.stringify(a),this.formData["action-field"]=t.successAction,this.overrideFormSubmit();const c=this.el?.shadowRoot,h=c?.querySelector("form");if(h){const e=h.querySelector('[name="credential-field"]')||h.querySelector("#credential-field"),i=h.querySelector('[name="action-field"]')||h.querySelector("#action-field");e&&(e.value=JSON.stringify(a)),i&&(i.value=t.successAction),h.submit()}}catch(t){if("AbortError"===t?.name||"NotAllowedError"===t?.name)return;console.error("Conditional mediation error:",t)}}handleButtonClick=t=>{if("submit"!==t.type)if(this.buttonClick.emit(t),"SOCIAL"===t.type&&t.value&&this.shouldAutoNavigate){const e=this.getProviderHref(t.value);if(e){const t=this.extractScreenIdFromHref(e);return void(t&&this.apiUrl?this.navigateToScreen(t,e):window.location.href=e)}this.handleSocialLogin(t.value)}else"RESEND_BUTTON"===t.type&&this.shouldAutoNavigate&&this.handleResend();else{const e=this._screen?.components?.find((e=>e.id===t.id));if(this._screen&&("NEXT_BUTTON"!==e?.type||!0!==e.config?.skip_validation)&&this.hasUnfilledRequiredFields(this._screen))return;if((!this._screen?.method||"GET"===this._screen.method.toUpperCase())&&this._screen?.action)return void(window.location.href=this.buildUrl(this._screen.action));const i={...this.formData,[t.id]:"true"};this.formData=i,this.handleSubmit({preventDefault:()=>{}},i)}};handleSocialLogin(t){const e=this._authParams||{},i={connection:t};this.state?i.state=this.state:e.state&&(i.state=e.state),e.client_id&&(i.client_id=e.client_id),e.redirect_uri&&(i.redirect_uri=e.redirect_uri),e.scope&&(i.scope=e.scope),e.audience&&(i.audience=e.audience),e.nonce&&(i.nonce=e.nonce),e.response_type&&(i.response_type=e.response_type);const o=this.buildUrl("/authorize?"+new URLSearchParams(i).toString());this.navigate.emit({url:o}).defaultPrevented||(window.location.href=o)}async handleResend(){if(this._screen?.action)try{const t=this._screen.action+(this._screen.action.includes("?")?"&":"?")+"action=resend";await fetch(this.buildUrl(t),{method:"POST",credentials:"include"})}catch(t){console.error("Resend failed:",t)}}extractScreenIdFromHref(t){try{const e=new URL(t,window.location.origin).pathname,i=e.match(/\/u2\/login\/([^/]+)$/);if(i)return i[1];const o=e.match(/\/u2\/([^/]+)$/);return o&&"login"!==o[1]&&"screen"!==o[1]?o[1]:null}catch{return null}}handleLinkClick=(t,e)=>{if(this.linkClick.emit({id:e.id,href:e.href,text:e.text}),!this.shouldAutoNavigate)return void t.preventDefault();const i=this.extractScreenIdFromHref(e.href);return i&&this.apiUrl?(t.preventDefault(),void this.navigateToScreen(i,e.href)):void 0};async navigateToScreen(t,e){await this.fetchScreen(t)?window.history.pushState({screen:t,state:this.state},"",e):window.location.href=e}getProviderHref(t){if(!this._screen)return null;for(const e of this._screen.components){const i=e;if("SOCIAL"===i.type&&i.config?.provider_details){const e=i.config.provider_details.find((e=>e.name===t));if(e?.href)return e.href}}return null}isSocialComponent(t){return"SOCIAL"===t.type}isDividerComponent(t){return"DIVIDER"===t.type}isRequiredFieldFilled(t){const e=this.formData[t.id];return"BOOLEAN"===t.type||"LEGAL"===t.type?"true"===e:"string"==typeof e&&""!==e.trim()}hasUnfilledRequiredFields(t){return(t.components??[]).some((t=>!1!==t.visible&&"required"in t&&!0===t.required&&v.has(t.type)&&!this.isRequiredFieldFilled(t)))}getChoiceButtonText(t){const e=t.config;return e?.text??""}render(){const t=this._screen;if(this.loading&&!t)return o("div",{class:"widget-container"},o("div",{class:"loading-spinner"}));if(!t)return o("div",{class:"widget-container"},o("div",{class:"error-message"},"No screen configuration provided"));const e=t.messages?.filter((t=>"error"===t.type))||[],i=t.messages?.filter((t=>"success"===t.type))||[],s=[...t.components??[]],r=s.filter((t=>!1!==t.visible)).sort(((t,e)=>(t.order??0)-(e.order??0))),a=s.filter((t=>!1===t.visible)),c=r.filter((t=>this.isSocialComponent(t))),h=c.length>0?r.find((t=>this.isDividerComponent(t))):void 0,l=r.filter((t=>!this.isSocialComponent(t)&&t!==h)),d=!!h,f=h?.config?.text||"Or",u=l.filter((t=>"NEXT_BUTTON"===t.type)),p=u.length===l.length&&u.length>5,g=this.hasUnfilledRequiredFields(t),b=this.listFilter.trim().toLowerCase(),w=p&&b?u.filter((t=>this.getChoiceButtonText(t).toLowerCase().includes(b))):u,x=t=>{const e=t.config;return["social-buttons","button","button-secondary","button-social","button-social-content","button-social-text","button-social-text-short","button-social-subtitle","button-social-badge","social-icon",...(e?.providers??[]).flatMap((t=>{const e=n(t);return[`button-social-${e}`,`button-social-content-${e}`,`button-social-text-${e}`,`button-social-text-short-${e}`,`button-social-subtitle-${e}`,`button-social-badge-${e}`,`social-icon-${e}`]}))].join(", ")},v=this._theme?.widget?.logo_url||this._branding?.logo_url;return o("div",{class:"widget-container",part:"container","data-authstack-container":!0},o("header",{class:"widget-header",part:"header"},v&&o("div",{class:"logo-wrapper",part:"logo-wrapper"},o("img",{class:"logo",part:"logo",src:v,alt:"Logo"})),t.title&&o("h1",{class:"title",part:"title",innerHTML:m(t.title)}),t.description&&o("p",{class:"description",part:"description",innerHTML:m(t.description)})),o("div",{class:"widget-body",part:"body"},e.map((t=>o("div",{class:"message message-error",part:"message message-error",key:t.id??t.text},t.text))),i.map((t=>o("div",{class:"message message-success",part:"message message-success",key:t.id??t.text},t.text))),o("form",{onSubmit:this.handleSubmit,action:t.action,method:t.method||"POST",part:"form"},a.map((t=>o("input",{type:"hidden",name:t.id,id:t.id,key:t.id,value:this.formData[t.id]||""}))),o("div",{class:"form-content"},c.length>0&&o("div",{class:"social-section",part:"social-section"},c.map((t=>o("authhero-node",{key:t.id,component:t,locale:this.locale,value:this.formData[t.id],onFieldChange:t=>this.handleInputChange(t.detail.id,t.detail.value),onButtonClick:t=>this.handleButtonClick(t.detail),disabled:this.loading,exportparts:x(t)})))),c.length>0&&l.length>0&&d&&o("div",{class:"divider",part:"divider"},o("span",{class:"divider-text"},f)),o("div",{class:"fields-section",part:"fields-section"},p&&o("input",{type:"text",class:"choice-list-search",part:"choice-list-search",placeholder:"Search","aria-label":"Search",autocomplete:"off",value:this.listFilter,onInput:t=>this.listFilter=t.target.value,onKeyDown:t=>{"Enter"===t.key&&t.preventDefault()}}),o("div",{class:p?"fields-list fields-list-scroll":"fields-list",part:p?"fields-list fields-list-scroll":"fields-list"},(p?w:l).map((t=>o("authhero-node",{key:t.id,component:t,locale:this.locale,value:this.formData[t.id],onFieldChange:t=>this.handleInputChange(t.detail.id,t.detail.value),onButtonClick:t=>this.handleButtonClick(t.detail),disabled:this.loading||"NEXT_BUTTON"===t.type&&!0!==t.config?.skip_validation&&g}))),p&&0===w.length&&o("div",{class:"choice-list-empty",part:"choice-list-empty"},"No matches"))))),t.links&&t.links.length>0&&o("div",{class:"links",part:"links"},t.links.map((t=>o("span",{class:"link-wrapper",part:"link-wrapper",key:t.id??t.href},t.linkText?o("span",null,t.text," ",o("a",{href:t.href,class:"link",part:"link",onClick:e=>this.handleLinkClick(e,{id:t.id,href:t.href,text:t.linkText||t.text})},t.linkText)):o("a",{href:t.href,class:"link",part:"link",onClick:e=>this.handleLinkClick(e,{id:t.id,href:t.href,text:t.text})},t.text))))),t.footer&&o("div",{class:"widget-footer",part:"footer",innerHTML:m(t.footer)})))}static get watchers(){return{screenId:[{watchScreenId:0}],screen:[{watchScreen:0}],branding:[{watchBranding:0}],theme:[{watchTheme:0}],authParams:[{watchAuthParams:0}]}}};y.style=':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{width:var(--ah-widget-max-width, 400px);margin:0 auto;background-color:var(--ah-color-bg, #ffffff);border-radius:var(--ah-widget-radius, 5px);border:var(--ah-widget-border-width, 0) solid var(--ah-widget-border-color, transparent);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-text-header, var(--ah-color-header, #1e212a));line-height:1.2}.description{font-size:var(--ah-font-size-subtitle, 16px);font-weight:var(--ah-font-weight-subtitle, 400);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)}.fields-list{display:flex;flex-direction:column}.fields-list-scroll{max-height:var(--ah-choice-list-max-height, 320px);overflow-y:auto;gap:var(--ah-choice-list-gap, 8px);padding-right:4px}.choice-list-search{width:100%;padding:16px;margin-bottom:12px;font-size:16px;font-family:inherit;color:var(--ah-color-input-text, var(--ah-color-text, #1e212a));background-color:var(--ah-color-input-bg, #ffffff);border:var(--ah-input-border-width, 1px) solid var(--ah-color-border, #c9cace);border-radius:var(--ah-input-radius, 3px);outline:none;box-sizing:border-box;transition:border-color 0.15s ease-out, box-shadow 0.15s ease-out}.choice-list-search:hover{border-color:var(--ah-color-border-hover, #65676e)}.choice-list-search:focus{border-color:var(--ah-color-primary, var(--ah-color-link, #635dff))}.choice-list-empty{padding:16px;text-align:center;font-size:14px;color:var(--ah-color-text-muted, #65676e)}.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:var(--ah-font-size-body, 14px);font-weight:var(--ah-font-weight-body, 400);color:var(--ah-color-text, #1e212a)}.link{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:var(--ah-font-size-link, 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-focus-ring, 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-focus-ring, 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(:not([floating])){display:block;width:100%;min-height:100vh;background-color:var(--ah-color-bg, #ffffff)}:host(:not([floating])) .widget-container{box-shadow:none;border-radius:0;border:0;width:100%;margin:0}:host([floating]) .widget-container{width:100%;margin:0}.widget-header{padding:24px 16px 16px}.widget-body{padding:0 16px 24px}}';export{y as authhero_widget}
|
|
@@ -532,6 +532,19 @@ const CHOICE_LIST_SEARCH_THRESHOLD = 5;
|
|
|
532
532
|
* (CARDS, FILE, RECAPTCHA, …) can carry `required` in the schema too, and
|
|
533
533
|
* gating on them would leave Continue disabled with no way to satisfy it.
|
|
534
534
|
*/
|
|
535
|
+
/**
|
|
536
|
+
* Field types rendered as a single plain text input whose value maps 1:1 to
|
|
537
|
+
* formData. Composite fields (TEL, DATE) and choice/checkbox fields keep
|
|
538
|
+
* internal state, so they're not adopted from pre-hydration markup.
|
|
539
|
+
*/
|
|
540
|
+
const PREHYDRATION_TEXT_TYPES = new Set([
|
|
541
|
+
"TEXT",
|
|
542
|
+
"EMAIL",
|
|
543
|
+
"CODE",
|
|
544
|
+
"PASSWORD",
|
|
545
|
+
"NUMBER",
|
|
546
|
+
"URL",
|
|
547
|
+
]);
|
|
535
548
|
const FILLABLE_FIELD_TYPES = new Set([
|
|
536
549
|
"TEXT",
|
|
537
550
|
"EMAIL",
|
|
@@ -912,7 +925,24 @@ const AuthheroWidget = class {
|
|
|
912
925
|
* actually in the DOM before measuring its height.
|
|
913
926
|
*/
|
|
914
927
|
pendingRenderResolvers = [];
|
|
928
|
+
/**
|
|
929
|
+
* Number of `swapScreen` calls still running (rendering or animating the
|
|
930
|
+
* card height). A counter rather than a flag because a newer swap can start
|
|
931
|
+
* before a superseded one has settled.
|
|
932
|
+
*/
|
|
933
|
+
activeSwaps = 0;
|
|
934
|
+
updateReadyAttribute() {
|
|
935
|
+
{
|
|
936
|
+
this.el.toggleAttribute("data-ready", !this.loading && this.activeSwaps === 0);
|
|
937
|
+
}
|
|
938
|
+
}
|
|
915
939
|
componentDidRender() {
|
|
940
|
+
// `data-ready` marks the widget as interactive: hydrated in the browser
|
|
941
|
+
// (the SSR markup already carries Stencil's `hydrated` class, so that
|
|
942
|
+
// can't tell server and client apart) and not mid-submit or mid-swap.
|
|
943
|
+
// Stencil defers this hook until child nodes have rendered, so the
|
|
944
|
+
// fields are live too. E2E tests wait on `authhero-widget[data-ready]`.
|
|
945
|
+
this.updateReadyAttribute();
|
|
916
946
|
if (this.pendingRenderResolvers.length === 0)
|
|
917
947
|
return;
|
|
918
948
|
const resolvers = this.pendingRenderResolvers;
|
|
@@ -960,6 +990,18 @@ const AuthheroWidget = class {
|
|
|
960
990
|
apply();
|
|
961
991
|
return;
|
|
962
992
|
}
|
|
993
|
+
// Hold `data-ready` off until the new screen has rendered and the height
|
|
994
|
+
// animation has finished; `apply()` clears `loading` before either.
|
|
995
|
+
this.activeSwaps++;
|
|
996
|
+
try {
|
|
997
|
+
await this.animateSwap(card, apply);
|
|
998
|
+
}
|
|
999
|
+
finally {
|
|
1000
|
+
this.activeSwaps--;
|
|
1001
|
+
this.updateReadyAttribute();
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
async animateSwap(card, apply) {
|
|
963
1005
|
// Lock the current height and clip, so swapping the content doesn't jump
|
|
964
1006
|
// before the animation runs.
|
|
965
1007
|
const startHeight = card.getBoundingClientRect().height;
|
|
@@ -1124,6 +1166,9 @@ const AuthheroWidget = class {
|
|
|
1124
1166
|
if (!this._authParams) {
|
|
1125
1167
|
this.watchAuthParams(this.authParams ?? this.readJsonScript("auth-params"));
|
|
1126
1168
|
}
|
|
1169
|
+
if (this._screen) {
|
|
1170
|
+
this.adoptPrehydrationValues(this._screen);
|
|
1171
|
+
}
|
|
1127
1172
|
// Load persisted state if available
|
|
1128
1173
|
this.loadPersistedState();
|
|
1129
1174
|
// Fetch screen from API if URL provided and no screen prop
|
|
@@ -1131,6 +1176,41 @@ const AuthheroWidget = class {
|
|
|
1131
1176
|
await this.fetchScreen(this.screenId);
|
|
1132
1177
|
}
|
|
1133
1178
|
}
|
|
1179
|
+
/**
|
|
1180
|
+
* Carry over text the user (or a password manager, or a test driver) put
|
|
1181
|
+
* into the server-rendered inputs before the client bundle loaded. Those
|
|
1182
|
+
* inputs had no `onInput` handler yet, so `formData` never saw the value:
|
|
1183
|
+
* the first client render would reset them to "" and keep the submit
|
|
1184
|
+
* button disabled. The declarative shadow roots are still the SSR ones
|
|
1185
|
+
* here — `componentWillLoad` runs before the first client render.
|
|
1186
|
+
*/
|
|
1187
|
+
adoptPrehydrationValues(screen) {
|
|
1188
|
+
const root = this.el.shadowRoot;
|
|
1189
|
+
if (!root)
|
|
1190
|
+
return;
|
|
1191
|
+
const roots = [root];
|
|
1192
|
+
root.querySelectorAll("authhero-node").forEach((node) => {
|
|
1193
|
+
if (node.shadowRoot)
|
|
1194
|
+
roots.push(node.shadowRoot);
|
|
1195
|
+
});
|
|
1196
|
+
const adopted = {};
|
|
1197
|
+
for (const component of screen.components ?? []) {
|
|
1198
|
+
if (!PREHYDRATION_TEXT_TYPES.has(component.type))
|
|
1199
|
+
continue;
|
|
1200
|
+
for (const r of roots) {
|
|
1201
|
+
const input = Array.from(r.querySelectorAll("input[name]")).find((el) => el.name === component.id && el.type !== "hidden");
|
|
1202
|
+
// Adopt "" too: a prefilled default the user cleared before
|
|
1203
|
+
// hydration must not be restored by the client render.
|
|
1204
|
+
if (input) {
|
|
1205
|
+
adopted[component.id] = input.value;
|
|
1206
|
+
break;
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
if (Object.keys(adopted).length > 0) {
|
|
1211
|
+
this.formData = { ...this.formData, ...adopted };
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1134
1214
|
/**
|
|
1135
1215
|
* Fetch screen configuration from the API
|
|
1136
1216
|
* @param screenIdOverride Optional screen ID to fetch (overrides this.screenId)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { h, } from "@stencil/core";
|
|
1
|
+
import { h, Build, } from "@stencil/core";
|
|
2
2
|
import { mergeThemeVars, applyCssVars } from "../../utils/branding";
|
|
3
3
|
import { sanitizeHtml } from "../../utils/sanitize-html";
|
|
4
4
|
import { sanitizeForCssToken } from "../../utils/css-token";
|
|
@@ -15,6 +15,19 @@ const CHOICE_LIST_SEARCH_THRESHOLD = 5;
|
|
|
15
15
|
* (CARDS, FILE, RECAPTCHA, …) can carry `required` in the schema too, and
|
|
16
16
|
* gating on them would leave Continue disabled with no way to satisfy it.
|
|
17
17
|
*/
|
|
18
|
+
/**
|
|
19
|
+
* Field types rendered as a single plain text input whose value maps 1:1 to
|
|
20
|
+
* formData. Composite fields (TEL, DATE) and choice/checkbox fields keep
|
|
21
|
+
* internal state, so they're not adopted from pre-hydration markup.
|
|
22
|
+
*/
|
|
23
|
+
const PREHYDRATION_TEXT_TYPES = new Set([
|
|
24
|
+
"TEXT",
|
|
25
|
+
"EMAIL",
|
|
26
|
+
"CODE",
|
|
27
|
+
"PASSWORD",
|
|
28
|
+
"NUMBER",
|
|
29
|
+
"URL",
|
|
30
|
+
]);
|
|
18
31
|
const FILLABLE_FIELD_TYPES = new Set([
|
|
19
32
|
"TEXT",
|
|
20
33
|
"EMAIL",
|
|
@@ -385,7 +398,24 @@ export class AuthheroWidget {
|
|
|
385
398
|
* actually in the DOM before measuring its height.
|
|
386
399
|
*/
|
|
387
400
|
pendingRenderResolvers = [];
|
|
401
|
+
/**
|
|
402
|
+
* Number of `swapScreen` calls still running (rendering or animating the
|
|
403
|
+
* card height). A counter rather than a flag because a newer swap can start
|
|
404
|
+
* before a superseded one has settled.
|
|
405
|
+
*/
|
|
406
|
+
activeSwaps = 0;
|
|
407
|
+
updateReadyAttribute() {
|
|
408
|
+
if (Build.isBrowser) {
|
|
409
|
+
this.el.toggleAttribute("data-ready", !this.loading && this.activeSwaps === 0);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
388
412
|
componentDidRender() {
|
|
413
|
+
// `data-ready` marks the widget as interactive: hydrated in the browser
|
|
414
|
+
// (the SSR markup already carries Stencil's `hydrated` class, so that
|
|
415
|
+
// can't tell server and client apart) and not mid-submit or mid-swap.
|
|
416
|
+
// Stencil defers this hook until child nodes have rendered, so the
|
|
417
|
+
// fields are live too. E2E tests wait on `authhero-widget[data-ready]`.
|
|
418
|
+
this.updateReadyAttribute();
|
|
389
419
|
if (this.pendingRenderResolvers.length === 0)
|
|
390
420
|
return;
|
|
391
421
|
const resolvers = this.pendingRenderResolvers;
|
|
@@ -433,6 +463,18 @@ export class AuthheroWidget {
|
|
|
433
463
|
apply();
|
|
434
464
|
return;
|
|
435
465
|
}
|
|
466
|
+
// Hold `data-ready` off until the new screen has rendered and the height
|
|
467
|
+
// animation has finished; `apply()` clears `loading` before either.
|
|
468
|
+
this.activeSwaps++;
|
|
469
|
+
try {
|
|
470
|
+
await this.animateSwap(card, apply);
|
|
471
|
+
}
|
|
472
|
+
finally {
|
|
473
|
+
this.activeSwaps--;
|
|
474
|
+
this.updateReadyAttribute();
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
async animateSwap(card, apply) {
|
|
436
478
|
// Lock the current height and clip, so swapping the content doesn't jump
|
|
437
479
|
// before the animation runs.
|
|
438
480
|
const startHeight = card.getBoundingClientRect().height;
|
|
@@ -597,6 +639,9 @@ export class AuthheroWidget {
|
|
|
597
639
|
if (!this._authParams) {
|
|
598
640
|
this.watchAuthParams(this.authParams ?? this.readJsonScript("auth-params"));
|
|
599
641
|
}
|
|
642
|
+
if (Build.isBrowser && this._screen) {
|
|
643
|
+
this.adoptPrehydrationValues(this._screen);
|
|
644
|
+
}
|
|
600
645
|
// Load persisted state if available
|
|
601
646
|
this.loadPersistedState();
|
|
602
647
|
// Fetch screen from API if URL provided and no screen prop
|
|
@@ -604,6 +649,41 @@ export class AuthheroWidget {
|
|
|
604
649
|
await this.fetchScreen(this.screenId);
|
|
605
650
|
}
|
|
606
651
|
}
|
|
652
|
+
/**
|
|
653
|
+
* Carry over text the user (or a password manager, or a test driver) put
|
|
654
|
+
* into the server-rendered inputs before the client bundle loaded. Those
|
|
655
|
+
* inputs had no `onInput` handler yet, so `formData` never saw the value:
|
|
656
|
+
* the first client render would reset them to "" and keep the submit
|
|
657
|
+
* button disabled. The declarative shadow roots are still the SSR ones
|
|
658
|
+
* here — `componentWillLoad` runs before the first client render.
|
|
659
|
+
*/
|
|
660
|
+
adoptPrehydrationValues(screen) {
|
|
661
|
+
const root = this.el.shadowRoot;
|
|
662
|
+
if (!root)
|
|
663
|
+
return;
|
|
664
|
+
const roots = [root];
|
|
665
|
+
root.querySelectorAll("authhero-node").forEach((node) => {
|
|
666
|
+
if (node.shadowRoot)
|
|
667
|
+
roots.push(node.shadowRoot);
|
|
668
|
+
});
|
|
669
|
+
const adopted = {};
|
|
670
|
+
for (const component of screen.components ?? []) {
|
|
671
|
+
if (!PREHYDRATION_TEXT_TYPES.has(component.type))
|
|
672
|
+
continue;
|
|
673
|
+
for (const r of roots) {
|
|
674
|
+
const input = Array.from(r.querySelectorAll("input[name]")).find((el) => el.name === component.id && el.type !== "hidden");
|
|
675
|
+
// Adopt "" too: a prefilled default the user cleared before
|
|
676
|
+
// hydration must not be restored by the client render.
|
|
677
|
+
if (input) {
|
|
678
|
+
adopted[component.id] = input.value;
|
|
679
|
+
break;
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
if (Object.keys(adopted).length > 0) {
|
|
684
|
+
this.formData = { ...this.formData, ...adopted };
|
|
685
|
+
}
|
|
686
|
+
}
|
|
607
687
|
/**
|
|
608
688
|
* Fetch screen configuration from the API
|
|
609
689
|
* @param screenIdOverride Optional screen ID to fetch (overrides this.screenId)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t,p as e,H as i,c as o,h as n}from"./p-cKZ5hFj1.js";import{d as r,s}from"./p-ClmWOjQ0.js";function a(t){const e=t.match(/^#([0-9a-f]{3})$/i)||t.match(/^#([0-9a-f]{6})$/i);if(!e)return null;let i=e[1];3===i.length&&(i=i[0]+i[0]+i[1]+i[1]+i[2]+i[2]);const o=parseInt(i,16);return[o>>16&255,o>>8&255,255&o]}function c(t){const e=a(t);if(!e)return NaN;const[i,o,n]=e.map((t=>{const e=t/255;return e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)}));return.2126*i+.7152*o+.0722*n}function h(t,e){const i=c(t),o=c(e);return isNaN(i)||isNaN(o)?NaN:(Math.max(i,o)+.05)/(Math.min(i,o)+.05)}function l(t,e="light"){const i=h(t,"#000000"),o=h(t,"#ffffff");return"light"===e?i>1.35*o?"#000000":"#ffffff":1.35*i>o?"#000000":"#ffffff"}function d(t,e){const i=a(t);if(!i)return t;const[o,n,r]=i,s=t=>Math.max(0,Math.round(t*(1-e))).toString(16).padStart(2,"0");return`#${s(o)}${s(n)}${s(r)}`}function f(t,e){const i=a(t);if(!i)return t;const[o,n,r]=i,s=t=>Math.min(255,Math.round(t+(255-t)*e)).toString(16).padStart(2,"0");return`#${s(o)}${s(n)}${s(r)}`}function u(t,e,i=4.5){if(h(t,e)>=i)return t;const o=c(e)>.5;let n=t;for(let r=1;r<=10;r++)if(n=o?d(t,.1*r):f(t,.1*r),h(n,e)>=i)return n;return o?"#000000":"#ffffff"}function p(t,e){if(void 0!==e)return e+"px";switch(t){case"pill":return"9999px";case"rounded":return"8px";case"sharp":return"0";default:return}}function g(t){if(!t)return{};const e={};if(t.colors?.primary&&(e["--ah-color-primary"]=t.colors.primary),t.colors?.page_background){const i=t.colors.page_background;"solid"===i.type&&i.start?e["--ah-page-bg"]=i.start:"gradient"===i.type&&i.start&&i.end&&(e["--ah-page-bg"]=`linear-gradient(${i.angle_deg??180}deg, ${i.start}, ${i.end})`)}return t.logo_url&&(e["--ah-logo-url"]=`url(${t.logo_url})`),t.font?.url&&(e["--ah-font-url"]=t.font.url),e}function m(t){if(!t)return{};const e={};if(t.borders){const i=t.borders;void 0!==i.widget_corner_radius&&(e["--ah-widget-radius"]=i.widget_corner_radius+"px"),void 0!==i.widget_border_weight&&(e["--ah-widget-border-width"]=i.widget_border_weight+"px"),!1===i.show_widget_shadow&&(e["--ah-widget-shadow"]="none");const o=p(i.buttons_style,i.button_border_radius);o&&(e["--ah-btn-radius"]=o),void 0!==i.button_border_weight&&(e["--ah-btn-border-width"]=i.button_border_weight+"px");const n=p(i.inputs_style,i.input_border_radius);n&&(e["--ah-input-radius"]=n),void 0!==i.input_border_weight&&(e["--ah-input-border-width"]=i.input_border_weight+"px")}if(t.colors){const i=t.colors;if(i.primary_button)if(e["--ah-color-primary"]=i.primary_button,i.primary_button_label)e["--ah-color-text-on-primary"]=i.primary_button_label;else{e["--ah-color-text-on-primary"]=l(i.primary_button,"light");const t=l(i.primary_button,"dark");t!==e["--ah-color-text-on-primary"]&&(e["--ah-color-text-on-primary-dark"]=t)}else i.primary_button_label&&(e["--ah-color-text-on-primary"]=i.primary_button_label);i.secondary_button_border&&(e["--ah-btn-secondary-border"]=i.secondary_button_border),i.secondary_button_label&&(e["--ah-btn-secondary-text"]=i.secondary_button_label),i.body_text&&(e["--ah-color-text"]=i.body_text),i.header&&(e["--ah-color-text-header"]=i.header),i.input_labels_placeholders&&(e["--ah-color-text-label"]=i.input_labels_placeholders,e["--ah-color-text-muted"]=i.input_labels_placeholders),i.input_filled_text&&(e["--ah-color-input-text"]=i.input_filled_text),i.widget_background&&(e["--ah-color-bg"]=i.widget_background),i.input_background&&(e["--ah-color-input-bg"]=i.input_background),i.widget_border&&(e["--ah-widget-border-color"]=i.widget_border),i.input_border&&(e["--ah-color-border"]=i.input_border),i.links_focused_components&&(e["--ah-color-link"]=u(i.links_focused_components,i.widget_background||"#ffffff")),i.base_focus_color&&(e["--ah-color-focus-ring"]=i.base_focus_color),i.base_hover_color&&(e["--ah-color-primary-hover"]=i.base_hover_color),i.error&&(e["--ah-color-error"]=i.error),i.success&&(e["--ah-color-success"]=i.success),i.icons&&(e["--ah-color-icon"]=i.icons);const o=i.widget_background||"#ffffff",n=i.input_background||o,r=e["--ah-color-border"]||i.input_border||"#c9cace",s=h(r,o),a=h(r,n);Math.min(s,a)<3&&(e["--ah-color-border"]=u(r,s<a?o:n,3))}if(t.fonts){const i=t.fonts,o=i.reference_text_size||16,n=t=>t>=50?Math.round(t/100*o):t;i.font_url&&(e["--ah-font-url"]=i.font_url),i.reference_text_size&&(e["--ah-font-size-base"]=i.reference_text_size+"px"),i.title?.size&&(e["--ah-font-size-title"]=n(i.title.size)+"px"),i.subtitle?.size&&(e["--ah-font-size-subtitle"]=n(i.subtitle.size)+"px"),i.body_text?.size&&(e["--ah-font-size-body"]=n(i.body_text.size)+"px"),i.input_labels?.size&&(e["--ah-font-size-label"]=n(i.input_labels.size)+"px"),i.buttons_text?.size&&(e["--ah-font-size-btn"]=n(i.buttons_text.size)+"px"),i.links?.size&&(e["--ah-font-size-link"]=n(i.links.size)+"px"),"underlined"===i.links_style&&(e["--ah-link-decoration"]="underline"),void 0!==i.title?.bold&&(e["--ah-font-weight-title"]=i.title.bold?"700":"400"),void 0!==i.subtitle?.bold&&(e["--ah-font-weight-subtitle"]=i.subtitle.bold?"700":"400"),void 0!==i.body_text?.bold&&(e["--ah-font-weight-body"]=i.body_text.bold?"700":"400"),void 0!==i.input_labels?.bold&&(e["--ah-font-weight-label"]=i.input_labels.bold?"700":"400"),void 0!==i.buttons_text?.bold&&(e["--ah-font-weight-btn"]=i.buttons_text.bold?"600":"400"),void 0!==i.links?.bold&&(e["--ah-font-weight-link"]=i.links.bold?"700":"400")}if(t.widget){const i=t.widget;if(i.header_text_alignment&&(e["--ah-title-align"]=i.header_text_alignment),i.logo_height&&(e["--ah-logo-height"]=i.logo_height+"px"),i.logo_position){const t={center:"center",left:"flex-start",right:"flex-end"};"none"===i.logo_position?e["--ah-logo-display"]="none":e["--ah-logo-align"]=t[i.logo_position]??"center"}i.social_buttons_layout&&("top"===i.social_buttons_layout?(e["--ah-social-order"]="0",e["--ah-divider-order"]="1",e["--ah-fields-order"]="2"):(e["--ah-social-order"]="2",e["--ah-divider-order"]="1",e["--ah-fields-order"]="0"))}if(t.page_background){const i=t.page_background;i.background_color&&(e["--ah-page-bg"]=i.background_color),i.background_image_url&&(e["--ah-page-bg-image"]=`url(${i.background_image_url})`)}return e}const b={br:[],em:[],i:[],strong:[],b:[],u:[],span:["class"],a:["href","class"]};function w(t){if(!t)return"";if(!t.includes("<"))return t;let e=t;e=e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'");for(const[t,i]of Object.entries(b)){if("br"===t){e=e.replace(/<br\s*\/?>/gi,"<br>");continue}const o=RegExp(`<${t}((?:\\s+[a-z-]+(?:="[^&]*"|='[^&]*')?)*)\\s*>`,"gi");e=e.replace(o,((e,o)=>{const n=[];if(o){const t=o.replace(/"/g,'"').replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),e=/([a-z-]+)=["']([^"']*)["']/gi;let r;for(;null!==(r=e.exec(t));){const[,t,e]=r;t&&i.includes(t.toLowerCase())&&("href"===t.toLowerCase()?x(e||"")&&n.push(`${t}="${v(e||"")}"`):n.push(`${t}="${v(e||"")}"`))}}"a"===t&&(n.push('target="_blank"'),n.push('rel="noopener noreferrer"'));const r=n.length?" "+n.join(" "):"";return`<${t}${r}>`}));const n=RegExp(`</${t}>`,"gi");e=e.replace(n,`</${t}>`)}return e}function x(t){if(!t)return!1;if(t.startsWith("/")||t.startsWith("#")||t.startsWith("?"))return!0;try{const e=new URL(t,"https://example.com");return"http:"===e.protocol||"https:"===e.protocol}catch{return!1}}function v(t){return t.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}const y=new Set(["TEXT","EMAIL","CODE","PASSWORD","NUMBER","TEL","URL","DATE","BOOLEAN","LEGAL","COUNTRY","DROPDOWN","CHOICE"]),k=e(class extends i{constructor(t){super(),!1!==t&&this.__registerHost(),this.__attachShadow(),this.formSubmit=o(this,"formSubmit"),this.buttonClick=o(this,"buttonClick"),this.linkClick=o(this,"linkClick"),this.navigate=o(this,"navigate"),this.flowComplete=o(this,"flowComplete"),this.flowError=o(this,"flowError"),this.screenChange=o(this,"screenChange")}get el(){return this}screen;apiUrl;baseUrl;state;screenId;watchScreenId(){this.updateDataScreenAttribute()}authParams;statePersistence="memory";storageKey="authhero_widget";branding;theme;loading=!1;autoSubmit=!1;autoNavigate;locale;_screen;_authParams;_branding;_theme;formData={};listFilter="";conditionalMediationAbort;loadedFontUrl;formSubmit;buttonClick;linkClick;navigate;flowComplete;flowError;screenChange;watchScreen(t){if(this.conditionalMediationAbort?.abort(),this.conditionalMediationAbort=void 0,"string"==typeof t)try{this._screen=JSON.parse(t)}catch{console.error("Failed to parse screen JSON")}else this._screen=t;this._screen&&(this.formData={},this.listFilter="",this.initFormDataFromDefaults(this._screen),this.screenChange.emit(this._screen),this.updateDataScreenAttribute())}initFormDataFromDefaults(t){const e={};for(const i of t.components||[]){if(!("config"in i)||!i.config)continue;if(!("default_value"in i.config))continue;const t=i.config.default_value;"string"==typeof t&&""!==t?e[i.id]=t:"boolean"==typeof t&&(e[i.id]=t?"true":"false")}Object.keys(e).length>0&&(this.formData={...e,...this.formData})}updateDataScreenAttribute(){const t=this._screen?.name||this.screenId;t?this.el.setAttribute("data-screen",t):this.el.removeAttribute("data-screen");const e=this.el.closest("[data-authhero-widget-container]");e&&(t?e.setAttribute("data-screen",t):e.removeAttribute("data-screen"))}watchBranding(t){if("string"==typeof t)try{this._branding=JSON.parse(t)}catch{console.error("Failed to parse branding JSON")}else this._branding=t;this.applyThemeStyles()}watchTheme(t){if("string"==typeof t)try{this._theme=JSON.parse(t)}catch{console.error("Failed to parse theme JSON")}else this._theme=t;this.applyThemeStyles()}watchAuthParams(t){if("string"==typeof t)try{this._authParams=JSON.parse(t)}catch{console.error("Failed to parse authParams JSON")}else this._authParams=t}applyThemeStyles(){const t=function(t,e){return{...g(t),...m(e)}}(this._branding,this._theme);!function(t,e){Object.entries(e).forEach((([e,i])=>{t.style.setProperty(e,i)}))}(this.el,t),this.loadCustomFont()}loadCustomFont(){if("undefined"==typeof document)return;const t=this._theme?.fonts?.font_url||this._branding?.font?.url;if(t===this.loadedFontUrl)return;for(const t of Array.from(document.head.querySelectorAll("link[data-authhero-font]")))t.remove();if(this.loadedFontUrl=void 0,!t)return;const e=document.createElement("link");e.rel="stylesheet",e.href=t,e.setAttribute("data-authhero-font",t),document.head.appendChild(e),this.loadedFontUrl=t}focusFirstInput(){requestAnimationFrame((()=>{const t=this.el.shadowRoot;if(!t)return;const e=t.querySelectorAll("authhero-node");for(const t of Array.from(e)){const e=t.shadowRoot;if(e){const t=e.querySelector('input:not([type="hidden"]):not([type="checkbox"]):not([disabled]), textarea:not([disabled])');if(t)return void t.focus()}}}))}pendingRenderResolvers=[];componentDidRender(){if(0===this.pendingRenderResolvers.length)return;const t=this.pendingRenderResolvers;this.pendingRenderResolvers=[],t.forEach((t=>t()))}nextRender(){return new Promise((t=>{let e=!1;const i=()=>{e||(e=!0,t())};this.pendingRenderResolvers.push(i),requestAnimationFrame((()=>requestAnimationFrame(i)))}))}async swapScreen(t){const e=this.el.shadowRoot?.querySelector(".widget-container"),i="function"==typeof window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches;if(!e||"function"!=typeof e.animate||i)return void t();const o=e.getBoundingClientRect().height;e.style.height=o+"px",e.style.overflow="hidden",t(),await this.nextRender();const n=()=>{e.style.height="",e.style.overflow=""};e.style.height="auto";const r=e.getBoundingClientRect().height;if(e.style.height=o+"px",e.getBoundingClientRect(),Math.abs(r-o)<1)return void n();const s=e.animate([{height:o+"px"},{height:r+"px"}],{duration:520,easing:"cubic-bezier(0.22, 1, 0.36, 1)"});try{await s.finished}catch{}finally{n()}}get shouldAutoNavigate(){return this.autoNavigate??this.autoSubmit}buildUrl(t){return this.baseUrl?""+new URL(t,this.baseUrl):t}loadPersistedState(){if("url"===this.statePersistence){const t=new URL(window.location.href).searchParams.get("state");t&&!this.state&&(this.state=t)}else if("session"===this.statePersistence)try{const t=sessionStorage.getItem(this.storageKey+"_state");t&&!this.state&&(this.state=t);const e=sessionStorage.getItem(this.storageKey+"_screenId");e&&!this.screenId&&(this.screenId=e)}catch{}}persistState(){if("url"===this.statePersistence){const t=new URL(window.location.href);this.state&&t.searchParams.set("state",this.state),this.screenId&&t.searchParams.set("screen",this.screenId),window.history.replaceState({},"",""+t)}else if("session"===this.statePersistence)try{this.state&&sessionStorage.setItem(this.storageKey+"_state",this.state),this.screenId&&sessionStorage.setItem(this.storageKey+"_screenId",this.screenId)}catch{}}handlePopState=t=>{if(!this.apiUrl)return;t.state?.state&&(this.state=t.state.state);const e=t.state?.screen??this.extractScreenIdFromHref(location.href);e&&this.fetchScreen(e)};connectedCallback(){window.addEventListener("popstate",this.handlePopState)}disconnectedCallback(){window.removeEventListener("popstate",this.handlePopState),this.conditionalMediationAbort?.abort(),this.conditionalMediationAbort=void 0}readJsonScript(t){if(!this.el)return;const e=this.el.querySelector(`script[type="application/json"][data-authhero="${t}"]`);return e?.textContent??void 0}async componentWillLoad(){if(!this._screen){const t=this.screen||this.readJsonScript("screen")||this.el?.getAttribute("screen");t&&this.watchScreen(t)}this._branding||this.watchBranding(this.branding??this.readJsonScript("branding")),this._theme||this.watchTheme(this.theme??this.readJsonScript("theme")),this._authParams||this.watchAuthParams(this.authParams??this.readJsonScript("auth-params")),this.loadPersistedState(),this.apiUrl&&!this._screen&&await this.fetchScreen(this.screenId)}async fetchScreen(t,e){if(!this.apiUrl)return!1;const i=t||this.screenId;let o=this.apiUrl;i&&o.includes("{screenId}")&&(o=o.replace("{screenId}",encodeURIComponent(i)));const n=new URL(o,this.baseUrl||window.location.origin);this.state&&n.searchParams.set("state",this.state),e&&n.searchParams.set("nodeId",e),this.loading=!0;try{const t=await fetch(this.buildUrl(n.pathname+n.search),{credentials:"include",headers:{Accept:"application/json"}});if(t.ok){const e=await t.json();if(e.screen?(this._screen=e.screen,e.branding&&(this._branding=e.branding,this.applyThemeStyles()),e.state&&(this.state=e.state),e.screenId&&(this.screenId=e.screenId)):this._screen=e,this._screen)return this.listFilter="",i&&i!==this.screenId&&(this.screenId=i),this.initFormDataFromDefaults(this._screen),this.screenChange.emit(this._screen),this.updateDataScreenAttribute(),this.persistState(),this.focusFirstInput(),e.ceremony&&this.performWebAuthnCeremony(e.ceremony),!0}else{const e=await t.json().catch((()=>({message:"Failed to load screen"})));this.flowError.emit({message:e.message||"Failed to load screen"})}}catch(t){console.error("Failed to fetch screen:",t),this.flowError.emit({message:t instanceof Error?t.message:"Failed to fetch screen"})}finally{this.loading=!1}return!1}handleInputChange=(t,e)=>{this.formData={...this.formData,[t]:e}};handleSubmit=async(t,e)=>{if(t.preventDefault(),!this._screen||this.loading)return;let i={...this.formData,...e||{}};const o=this.el.shadowRoot?.querySelector("form");if(o&&o.querySelectorAll('input[type="hidden"]').forEach((t=>{t.name&&t.value&&(i[t.name]=t.value)})),this.formSubmit.emit({screen:this._screen,data:i}),this.autoSubmit)if(this._screen.method&&"GET"!==this._screen.method.toUpperCase()){this.loading=!0;try{const t=await fetch(this.buildUrl(this._screen.action),{method:this._screen.method,credentials:"include",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({data:i})}),e=t.headers.get("content-type");if(e?.includes("text/html")){const e=await t.text();return document.open(),document.write(e),void document.close()}if(e?.includes("application/json")){const e=await t.json();if(e.redirect){this.flowComplete.emit({redirectUrl:e.redirect});const t=this.navigate.emit({url:e.redirect});this.shouldAutoNavigate&&!t.defaultPrevented&&(window.location.href=e.redirect)}else!t.ok&&e.screen?await this.swapScreen((()=>{this.loading=!1,this._screen=e.screen,this.listFilter="",this.initFormDataFromDefaults(e.screen),this.screenChange.emit(e.screen),this.updateDataScreenAttribute(),this.focusFirstInput()})):e.screen?await this.swapScreen((()=>{this.loading=!1,this._screen=e.screen,this.listFilter="",this.formData={},this.initFormDataFromDefaults(e.screen),this.screenChange.emit(e.screen),this.updateDataScreenAttribute(),e.screenId&&(this.screenId=e.screenId),this.persistState(),e.navigateUrl&&this.shouldAutoNavigate&&window.history.pushState({screen:e.screenId,state:this.state},"",e.navigateUrl),e.branding&&(this._branding=e.branding,this.applyThemeStyles()),e.state&&(this.state=e.state,this.persistState()),e.ceremony&&this.performWebAuthnCeremony(e.ceremony),this.focusFirstInput()})):e.complete?this.flowComplete.emit({}):!t.ok&&e.error&&(this._screen&&(this._screen={...this._screen,messages:[...this._screen.messages||[],{text:e.error,type:"error"}]}),this.flowError.emit({message:e.error}))}}catch(t){console.error("Form submission failed:",t),this.flowError.emit({message:t instanceof Error?t.message:"Form submission failed"})}finally{this.loading=!1}}else window.location.href=this.buildUrl(this._screen.action)};overrideFormSubmit(){const t=this.el.shadowRoot;if(!t)return;const e=t.querySelector("form");e&&(e.submit=()=>{const t=new FormData(e),i={};t.forEach(((t,e)=>{"string"==typeof t&&(i[e]=t)})),this.handleSubmit({preventDefault:()=>{}},i)})}performWebAuthnCeremony(t){this.isValidWebAuthnCeremony(t)?"webauthn-authentication-conditional"!==t.type?requestAnimationFrame((()=>{this.overrideFormSubmit(),"webauthn-authentication"===t.type?this.executeWebAuthnAuthentication(t):this.executeWebAuthnRegistration(t)})):this.executeWebAuthnConditionalMediation(t):console.error("Invalid WebAuthn ceremony payload",t)}isValidWebAuthnCeremony(t){if("object"!=typeof t||null===t)return!1;const e=t;if("string"!=typeof e.successAction)return!1;const i=e.options;if("object"!=typeof i||null===i)return!1;if("string"!=typeof i.challenge)return!1;if("webauthn-registration"===e.type){const t=i.rp;if("object"!=typeof t||null===t)return!1;if("string"!=typeof t.id||"string"!=typeof t.name)return!1;const e=i.user;return"object"==typeof e&&null!==e&&("string"==typeof e.id&&"string"==typeof e.name&&"string"==typeof e.displayName&&!!Array.isArray(i.pubKeyCredParams))}return"webauthn-authentication"===e.type||"webauthn-authentication-conditional"===e.type}async executeWebAuthnRegistration(t){const e=t.options,i=t=>{for(t=t.replace(/-/g,"+").replace(/_/g,"/");t.length%4;)t+="=";const e=atob(t),i=new Uint8Array(e.length);for(let t=0;t<e.length;t++)i[t]=e.charCodeAt(t);return i.buffer},o=t=>{const e=new Uint8Array(t);let i="";for(let t=0;t<e.length;t++)i+=String.fromCharCode(e[t]);return btoa(i).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")},n=()=>{const t=this.el?.shadowRoot;if(t){const e=t.querySelector("form");if(e)return e}return document.querySelector("form")};try{const r={challenge:i(e.challenge),rp:{id:e.rp.id,name:e.rp.name},user:{id:i(e.user.id),name:e.user.name,displayName:e.user.displayName},pubKeyCredParams:e.pubKeyCredParams.map((t=>({alg:t.alg,type:t.type}))),timeout:e.timeout,attestation:e.attestation||"none",authenticatorSelection:e.authenticatorSelection?{residentKey:e.authenticatorSelection.residentKey||"preferred",userVerification:e.authenticatorSelection.userVerification||"preferred"}:void 0};e.excludeCredentials?.length&&(r.excludeCredentials=e.excludeCredentials.map((t=>({id:i(t.id),type:t.type,transports:t.transports||[]}))));const s=await navigator.credentials.create({publicKey:r}),a=s.response,c={id:s.id,rawId:o(s.rawId),type:s.type,response:{attestationObject:o(a.attestationObject),clientDataJSON:o(a.clientDataJSON)},clientExtensionResults:s.getClientExtensionResults(),authenticatorAttachment:s.authenticatorAttachment||void 0};"function"==typeof a.getTransports&&(c.response.transports=a.getTransports());const h=n();if(h){const e=h.querySelector('[name="credential-field"]')||h.querySelector("#credential-field"),i=h.querySelector('[name="action-field"]')||h.querySelector("#action-field");e&&(e.value=JSON.stringify(c)),i&&(i.value=t.successAction),h.submit()}}catch(t){console.error("WebAuthn registration error:",t);const e=n();if(e){const t=e.querySelector('[name="action-field"]')||e.querySelector("#action-field");t&&(t.value="error"),e.submit()}}}async executeWebAuthnAuthentication(t){const e=t.options,i=t=>{for(t=t.replace(/-/g,"+").replace(/_/g,"/");t.length%4;)t+="=";const e=atob(t),i=new Uint8Array(e.length);for(let t=0;t<e.length;t++)i[t]=e.charCodeAt(t);return i.buffer},o=t=>{const e=new Uint8Array(t);let i="";for(let t=0;t<e.length;t++)i+=String.fromCharCode(e[t]);return btoa(i).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")},n=()=>{const t=this.el?.shadowRoot;if(t){const e=t.querySelector("form");if(e)return e}return document.querySelector("form")};try{const r={challenge:i(e.challenge),rpId:e.rpId,timeout:e.timeout,userVerification:e.userVerification||"preferred"};e.allowCredentials?.length&&(r.allowCredentials=e.allowCredentials.map((t=>({id:i(t.id),type:t.type,transports:t.transports||[]}))));const s=await navigator.credentials.get({publicKey:r}),a=s.response,c={id:s.id,rawId:o(s.rawId),type:s.type,response:{authenticatorData:o(a.authenticatorData),clientDataJSON:o(a.clientDataJSON),signature:o(a.signature)},clientExtensionResults:s.getClientExtensionResults(),authenticatorAttachment:s.authenticatorAttachment||void 0};a.userHandle&&(c.response.userHandle=o(a.userHandle));const h=n();if(h){const e=h.querySelector('[name="credential-field"]')||h.querySelector("#credential-field"),i=h.querySelector('[name="action-field"]')||h.querySelector("#action-field");e&&(e.value=JSON.stringify(c)),i&&(i.value=t.successAction),h.submit()}}catch(t){console.error("WebAuthn authentication error:",t);const e=n();if(e){const t=e.querySelector('[name="action-field"]')||e.querySelector("#action-field");t&&(t.value="error"),e.submit()}}}async executeWebAuthnConditionalMediation(t){if(!window.PublicKeyCredential||!PublicKeyCredential.isConditionalMediationAvailable)return;if(!await PublicKeyCredential.isConditionalMediationAvailable())return;this.conditionalMediationAbort?.abort();const e=new AbortController;this.conditionalMediationAbort=e;const i=t.options,o=t=>{for(t=t.replace(/-/g,"+").replace(/_/g,"/");t.length%4;)t+="=";const e=atob(t),i=new Uint8Array(e.length);for(let t=0;t<e.length;t++)i[t]=e.charCodeAt(t);return i.buffer},n=t=>{const e=new Uint8Array(t);let i="";for(let t=0;t<e.length;t++)i+=String.fromCharCode(e[t]);return btoa(i).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")};try{const r=await navigator.credentials.get({mediation:"conditional",signal:e.signal,publicKey:{challenge:o(i.challenge),rpId:i.rpId,timeout:i.timeout,userVerification:i.userVerification||"preferred"}}),s=r.response,a={id:r.id,rawId:n(r.rawId),type:r.type,response:{authenticatorData:n(s.authenticatorData),clientDataJSON:n(s.clientDataJSON),signature:n(s.signature)},clientExtensionResults:r.getClientExtensionResults(),authenticatorAttachment:r.authenticatorAttachment||void 0};s.userHandle&&(a.response.userHandle=n(s.userHandle)),this.formData["credential-field"]=JSON.stringify(a),this.formData["action-field"]=t.successAction,this.overrideFormSubmit();const c=this.el?.shadowRoot,h=c?.querySelector("form");if(h){const e=h.querySelector('[name="credential-field"]')||h.querySelector("#credential-field"),i=h.querySelector('[name="action-field"]')||h.querySelector("#action-field");e&&(e.value=JSON.stringify(a)),i&&(i.value=t.successAction),h.submit()}}catch(t){if("AbortError"===t?.name||"NotAllowedError"===t?.name)return;console.error("Conditional mediation error:",t)}}handleButtonClick=t=>{if("submit"!==t.type)if(this.buttonClick.emit(t),"SOCIAL"===t.type&&t.value&&this.shouldAutoNavigate){const e=this.getProviderHref(t.value);if(e){const t=this.extractScreenIdFromHref(e);return void(t&&this.apiUrl?this.navigateToScreen(t,e):window.location.href=e)}this.handleSocialLogin(t.value)}else"RESEND_BUTTON"===t.type&&this.shouldAutoNavigate&&this.handleResend();else{const e=this._screen?.components?.find((e=>e.id===t.id));if(this._screen&&("NEXT_BUTTON"!==e?.type||!0!==e.config?.skip_validation)&&this.hasUnfilledRequiredFields(this._screen))return;if((!this._screen?.method||"GET"===this._screen.method.toUpperCase())&&this._screen?.action)return void(window.location.href=this.buildUrl(this._screen.action));const i={...this.formData,[t.id]:"true"};this.formData=i,this.handleSubmit({preventDefault:()=>{}},i)}};handleSocialLogin(t){const e=this._authParams||{},i={connection:t};this.state?i.state=this.state:e.state&&(i.state=e.state),e.client_id&&(i.client_id=e.client_id),e.redirect_uri&&(i.redirect_uri=e.redirect_uri),e.scope&&(i.scope=e.scope),e.audience&&(i.audience=e.audience),e.nonce&&(i.nonce=e.nonce),e.response_type&&(i.response_type=e.response_type);const o=this.buildUrl("/authorize?"+new URLSearchParams(i));this.navigate.emit({url:o}).defaultPrevented||(window.location.href=o)}async handleResend(){if(this._screen?.action)try{const t=this._screen.action+(this._screen.action.includes("?")?"&":"?")+"action=resend";await fetch(this.buildUrl(t),{method:"POST",credentials:"include"})}catch(t){console.error("Resend failed:",t)}}extractScreenIdFromHref(t){try{const e=new URL(t,window.location.origin).pathname,i=e.match(/\/u2\/login\/([^/]+)$/);if(i)return i[1];const o=e.match(/\/u2\/([^/]+)$/);return o&&"login"!==o[1]&&"screen"!==o[1]?o[1]:null}catch{return null}}handleLinkClick=(t,e)=>{if(this.linkClick.emit({id:e.id,href:e.href,text:e.text}),!this.shouldAutoNavigate)return void t.preventDefault();const i=this.extractScreenIdFromHref(e.href);return i&&this.apiUrl?(t.preventDefault(),void this.navigateToScreen(i,e.href)):void 0};async navigateToScreen(t,e){await this.fetchScreen(t)?window.history.pushState({screen:t,state:this.state},"",e):window.location.href=e}getProviderHref(t){if(!this._screen)return null;for(const e of this._screen.components){const i=e;if("SOCIAL"===i.type&&i.config?.provider_details){const e=i.config.provider_details.find((e=>e.name===t));if(e?.href)return e.href}}return null}isSocialComponent(t){return"SOCIAL"===t.type}isDividerComponent(t){return"DIVIDER"===t.type}isRequiredFieldFilled(t){const e=this.formData[t.id];return"BOOLEAN"===t.type||"LEGAL"===t.type?"true"===e:"string"==typeof e&&""!==e.trim()}hasUnfilledRequiredFields(t){return(t.components??[]).some((t=>!1!==t.visible&&"required"in t&&!0===t.required&&y.has(t.type)&&!this.isRequiredFieldFilled(t)))}getChoiceButtonText(t){const e=t.config;return e?.text??""}render(){const t=this._screen;if(this.loading&&!t)return n("div",{class:"widget-container"},n("div",{class:"loading-spinner"}));if(!t)return n("div",{class:"widget-container"},n("div",{class:"error-message"},"No screen configuration provided"));const e=t.messages?.filter((t=>"error"===t.type))||[],i=t.messages?.filter((t=>"success"===t.type))||[],o=[...t.components??[]],r=o.filter((t=>!1!==t.visible)).sort(((t,e)=>(t.order??0)-(e.order??0))),a=o.filter((t=>!1===t.visible)),c=r.filter((t=>this.isSocialComponent(t))),h=c.length>0?r.find((t=>this.isDividerComponent(t))):void 0,l=r.filter((t=>!this.isSocialComponent(t)&&t!==h)),d=!!h,f=h?.config?.text||"Or",u=l.filter((t=>"NEXT_BUTTON"===t.type)),p=u.length===l.length&&u.length>5,g=this.hasUnfilledRequiredFields(t),m=this.listFilter.trim().toLowerCase(),b=p&&m?u.filter((t=>this.getChoiceButtonText(t).toLowerCase().includes(m))):u,x=t=>{const e=t.config;return["social-buttons","button","button-secondary","button-social","button-social-content","button-social-text","button-social-text-short","button-social-subtitle","button-social-badge","social-icon",...(e?.providers??[]).flatMap((t=>{const e=s(t);return["button-social-"+e,"button-social-content-"+e,"button-social-text-"+e,"button-social-text-short-"+e,"button-social-subtitle-"+e,"button-social-badge-"+e,"social-icon-"+e]}))].join(", ")},v=this._theme?.widget?.logo_url||this._branding?.logo_url;return n("div",{class:"widget-container",part:"container","data-authstack-container":!0},n("header",{class:"widget-header",part:"header"},v&&n("div",{class:"logo-wrapper",part:"logo-wrapper"},n("img",{class:"logo",part:"logo",src:v,alt:"Logo"})),t.title&&n("h1",{class:"title",part:"title",innerHTML:w(t.title)}),t.description&&n("p",{class:"description",part:"description",innerHTML:w(t.description)})),n("div",{class:"widget-body",part:"body"},e.map((t=>n("div",{class:"message message-error",part:"message message-error",key:t.id??t.text},t.text))),i.map((t=>n("div",{class:"message message-success",part:"message message-success",key:t.id??t.text},t.text))),n("form",{onSubmit:this.handleSubmit,action:t.action,method:t.method||"POST",part:"form"},a.map((t=>n("input",{type:"hidden",name:t.id,id:t.id,key:t.id,value:this.formData[t.id]||""}))),n("div",{class:"form-content"},c.length>0&&n("div",{class:"social-section",part:"social-section"},c.map((t=>n("authhero-node",{key:t.id,component:t,locale:this.locale,value:this.formData[t.id],onFieldChange:t=>this.handleInputChange(t.detail.id,t.detail.value),onButtonClick:t=>this.handleButtonClick(t.detail),disabled:this.loading,exportparts:x(t)})))),c.length>0&&l.length>0&&d&&n("div",{class:"divider",part:"divider"},n("span",{class:"divider-text"},f)),n("div",{class:"fields-section",part:"fields-section"},p&&n("input",{type:"text",class:"choice-list-search",part:"choice-list-search",placeholder:"Search","aria-label":"Search",autocomplete:"off",value:this.listFilter,onInput:t=>this.listFilter=t.target.value,onKeyDown:t=>{"Enter"===t.key&&t.preventDefault()}}),n("div",{class:p?"fields-list fields-list-scroll":"fields-list",part:p?"fields-list fields-list-scroll":"fields-list"},(p?b:l).map((t=>n("authhero-node",{key:t.id,component:t,locale:this.locale,value:this.formData[t.id],onFieldChange:t=>this.handleInputChange(t.detail.id,t.detail.value),onButtonClick:t=>this.handleButtonClick(t.detail),disabled:this.loading||"NEXT_BUTTON"===t.type&&!0!==t.config?.skip_validation&&g}))),p&&0===b.length&&n("div",{class:"choice-list-empty",part:"choice-list-empty"},"No matches"))))),t.links&&t.links.length>0&&n("div",{class:"links",part:"links"},t.links.map((t=>n("span",{class:"link-wrapper",part:"link-wrapper",key:t.id??t.href},t.linkText?n("span",null,t.text," ",n("a",{href:t.href,class:"link",part:"link",onClick:e=>this.handleLinkClick(e,{id:t.id,href:t.href,text:t.linkText||t.text})},t.linkText)):n("a",{href:t.href,class:"link",part:"link",onClick:e=>this.handleLinkClick(e,{id:t.id,href:t.href,text:t.text})},t.text))))),t.footer&&n("div",{class:"widget-footer",part:"footer",innerHTML:w(t.footer)})))}static get watchers(){return{screenId:[{watchScreenId:0}],screen:[{watchScreen:0}],branding:[{watchBranding:0}],theme:[{watchTheme:0}],authParams:[{watchAuthParams:0}]}}static get style(){return':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{width:var(--ah-widget-max-width, 400px);margin:0 auto;background-color:var(--ah-color-bg, #ffffff);border-radius:var(--ah-widget-radius, 5px);border:var(--ah-widget-border-width, 0) solid var(--ah-widget-border-color, transparent);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-text-header, var(--ah-color-header, #1e212a));line-height:1.2}.description{font-size:var(--ah-font-size-subtitle, 16px);font-weight:var(--ah-font-weight-subtitle, 400);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)}.fields-list{display:flex;flex-direction:column}.fields-list-scroll{max-height:var(--ah-choice-list-max-height, 320px);overflow-y:auto;gap:var(--ah-choice-list-gap, 8px);padding-right:4px}.choice-list-search{width:100%;padding:16px;margin-bottom:12px;font-size:16px;font-family:inherit;color:var(--ah-color-input-text, var(--ah-color-text, #1e212a));background-color:var(--ah-color-input-bg, #ffffff);border:var(--ah-input-border-width, 1px) solid var(--ah-color-border, #c9cace);border-radius:var(--ah-input-radius, 3px);outline:none;box-sizing:border-box;transition:border-color 0.15s ease-out, box-shadow 0.15s ease-out}.choice-list-search:hover{border-color:var(--ah-color-border-hover, #65676e)}.choice-list-search:focus{border-color:var(--ah-color-primary, var(--ah-color-link, #635dff))}.choice-list-empty{padding:16px;text-align:center;font-size:14px;color:var(--ah-color-text-muted, #65676e)}.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:var(--ah-font-size-body, 14px);font-weight:var(--ah-font-weight-body, 400);color:var(--ah-color-text, #1e212a)}.link{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:var(--ah-font-size-link, 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-focus-ring, 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-focus-ring, 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(:not([floating])){display:block;width:100%;min-height:100vh;background-color:var(--ah-color-bg, #ffffff)}:host(:not([floating])) .widget-container{box-shadow:none;border-radius:0;border:0;width:100%;margin:0}:host([floating]) .widget-container{width:100%;margin:0}.widget-header{padding:24px 16px 16px}.widget-body{padding:0 16px 24px}}'}},[513,"authhero-widget",{screen:[1],apiUrl:[1,"api-url"],baseUrl:[1,"base-url"],state:[1025],screenId:[1025,"screen-id"],authParams:[1,"auth-params"],statePersistence:[1,"state-persistence"],storageKey:[1,"storage-key"],branding:[1],theme:[1],loading:[1028],autoSubmit:[4,"auto-submit"],autoNavigate:[4,"auto-navigate"],locale:[1],_screen:[32],_authParams:[32],_branding:[32],_theme:[32],formData:[32],listFilter:[32]},void 0,{screenId:[{watchScreenId:0}],screen:[{watchScreen:0}],branding:[{watchBranding:0}],theme:[{watchTheme:0}],authParams:[{watchAuthParams:0}]}]);function S(){"undefined"!=typeof customElements&&["authhero-widget","authhero-node"].forEach((e=>{switch(e){case"authhero-widget":customElements.get(t(e))||customElements.define(t(e),k);break;case"authhero-node":customElements.get(t(e))||r()}}))}S();const A=k,N=S;export{A as AuthheroWidget,N as defineCustomElement}
|
|
1
|
+
import{t,p as e,H as i,c as o,h as n}from"./p-cKZ5hFj1.js";import{d as s,s as r}from"./p-ClmWOjQ0.js";function a(t){const e=t.match(/^#([0-9a-f]{3})$/i)||t.match(/^#([0-9a-f]{6})$/i);if(!e)return null;let i=e[1];3===i.length&&(i=i[0]+i[0]+i[1]+i[1]+i[2]+i[2]);const o=parseInt(i,16);return[o>>16&255,o>>8&255,255&o]}function c(t){const e=a(t);if(!e)return NaN;const[i,o,n]=e.map((t=>{const e=t/255;return e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)}));return.2126*i+.7152*o+.0722*n}function h(t,e){const i=c(t),o=c(e);return isNaN(i)||isNaN(o)?NaN:(Math.max(i,o)+.05)/(Math.min(i,o)+.05)}function l(t,e="light"){const i=h(t,"#000000"),o=h(t,"#ffffff");return"light"===e?i>1.35*o?"#000000":"#ffffff":1.35*i>o?"#000000":"#ffffff"}function d(t,e){const i=a(t);if(!i)return t;const[o,n,s]=i,r=t=>Math.max(0,Math.round(t*(1-e))).toString(16).padStart(2,"0");return`#${r(o)}${r(n)}${r(s)}`}function f(t,e){const i=a(t);if(!i)return t;const[o,n,s]=i,r=t=>Math.min(255,Math.round(t+(255-t)*e)).toString(16).padStart(2,"0");return`#${r(o)}${r(n)}${r(s)}`}function u(t,e,i=4.5){if(h(t,e)>=i)return t;const o=c(e)>.5;let n=t;for(let s=1;s<=10;s++)if(n=o?d(t,.1*s):f(t,.1*s),h(n,e)>=i)return n;return o?"#000000":"#ffffff"}function p(t,e){if(void 0!==e)return e+"px";switch(t){case"pill":return"9999px";case"rounded":return"8px";case"sharp":return"0";default:return}}function g(t){if(!t)return{};const e={};if(t.colors?.primary&&(e["--ah-color-primary"]=t.colors.primary),t.colors?.page_background){const i=t.colors.page_background;"solid"===i.type&&i.start?e["--ah-page-bg"]=i.start:"gradient"===i.type&&i.start&&i.end&&(e["--ah-page-bg"]=`linear-gradient(${i.angle_deg??180}deg, ${i.start}, ${i.end})`)}return t.logo_url&&(e["--ah-logo-url"]=`url(${t.logo_url})`),t.font?.url&&(e["--ah-font-url"]=t.font.url),e}function m(t){if(!t)return{};const e={};if(t.borders){const i=t.borders;void 0!==i.widget_corner_radius&&(e["--ah-widget-radius"]=i.widget_corner_radius+"px"),void 0!==i.widget_border_weight&&(e["--ah-widget-border-width"]=i.widget_border_weight+"px"),!1===i.show_widget_shadow&&(e["--ah-widget-shadow"]="none");const o=p(i.buttons_style,i.button_border_radius);o&&(e["--ah-btn-radius"]=o),void 0!==i.button_border_weight&&(e["--ah-btn-border-width"]=i.button_border_weight+"px");const n=p(i.inputs_style,i.input_border_radius);n&&(e["--ah-input-radius"]=n),void 0!==i.input_border_weight&&(e["--ah-input-border-width"]=i.input_border_weight+"px")}if(t.colors){const i=t.colors;if(i.primary_button)if(e["--ah-color-primary"]=i.primary_button,i.primary_button_label)e["--ah-color-text-on-primary"]=i.primary_button_label;else{e["--ah-color-text-on-primary"]=l(i.primary_button,"light");const t=l(i.primary_button,"dark");t!==e["--ah-color-text-on-primary"]&&(e["--ah-color-text-on-primary-dark"]=t)}else i.primary_button_label&&(e["--ah-color-text-on-primary"]=i.primary_button_label);i.secondary_button_border&&(e["--ah-btn-secondary-border"]=i.secondary_button_border),i.secondary_button_label&&(e["--ah-btn-secondary-text"]=i.secondary_button_label),i.body_text&&(e["--ah-color-text"]=i.body_text),i.header&&(e["--ah-color-text-header"]=i.header),i.input_labels_placeholders&&(e["--ah-color-text-label"]=i.input_labels_placeholders,e["--ah-color-text-muted"]=i.input_labels_placeholders),i.input_filled_text&&(e["--ah-color-input-text"]=i.input_filled_text),i.widget_background&&(e["--ah-color-bg"]=i.widget_background),i.input_background&&(e["--ah-color-input-bg"]=i.input_background),i.widget_border&&(e["--ah-widget-border-color"]=i.widget_border),i.input_border&&(e["--ah-color-border"]=i.input_border),i.links_focused_components&&(e["--ah-color-link"]=u(i.links_focused_components,i.widget_background||"#ffffff")),i.base_focus_color&&(e["--ah-color-focus-ring"]=i.base_focus_color),i.base_hover_color&&(e["--ah-color-primary-hover"]=i.base_hover_color),i.error&&(e["--ah-color-error"]=i.error),i.success&&(e["--ah-color-success"]=i.success),i.icons&&(e["--ah-color-icon"]=i.icons);const o=i.widget_background||"#ffffff",n=i.input_background||o,s=e["--ah-color-border"]||i.input_border||"#c9cace",r=h(s,o),a=h(s,n);Math.min(r,a)<3&&(e["--ah-color-border"]=u(s,r<a?o:n,3))}if(t.fonts){const i=t.fonts,o=i.reference_text_size||16,n=t=>t>=50?Math.round(t/100*o):t;i.font_url&&(e["--ah-font-url"]=i.font_url),i.reference_text_size&&(e["--ah-font-size-base"]=i.reference_text_size+"px"),i.title?.size&&(e["--ah-font-size-title"]=n(i.title.size)+"px"),i.subtitle?.size&&(e["--ah-font-size-subtitle"]=n(i.subtitle.size)+"px"),i.body_text?.size&&(e["--ah-font-size-body"]=n(i.body_text.size)+"px"),i.input_labels?.size&&(e["--ah-font-size-label"]=n(i.input_labels.size)+"px"),i.buttons_text?.size&&(e["--ah-font-size-btn"]=n(i.buttons_text.size)+"px"),i.links?.size&&(e["--ah-font-size-link"]=n(i.links.size)+"px"),"underlined"===i.links_style&&(e["--ah-link-decoration"]="underline"),void 0!==i.title?.bold&&(e["--ah-font-weight-title"]=i.title.bold?"700":"400"),void 0!==i.subtitle?.bold&&(e["--ah-font-weight-subtitle"]=i.subtitle.bold?"700":"400"),void 0!==i.body_text?.bold&&(e["--ah-font-weight-body"]=i.body_text.bold?"700":"400"),void 0!==i.input_labels?.bold&&(e["--ah-font-weight-label"]=i.input_labels.bold?"700":"400"),void 0!==i.buttons_text?.bold&&(e["--ah-font-weight-btn"]=i.buttons_text.bold?"600":"400"),void 0!==i.links?.bold&&(e["--ah-font-weight-link"]=i.links.bold?"700":"400")}if(t.widget){const i=t.widget;if(i.header_text_alignment&&(e["--ah-title-align"]=i.header_text_alignment),i.logo_height&&(e["--ah-logo-height"]=i.logo_height+"px"),i.logo_position){const t={center:"center",left:"flex-start",right:"flex-end"};"none"===i.logo_position?e["--ah-logo-display"]="none":e["--ah-logo-align"]=t[i.logo_position]??"center"}i.social_buttons_layout&&("top"===i.social_buttons_layout?(e["--ah-social-order"]="0",e["--ah-divider-order"]="1",e["--ah-fields-order"]="2"):(e["--ah-social-order"]="2",e["--ah-divider-order"]="1",e["--ah-fields-order"]="0"))}if(t.page_background){const i=t.page_background;i.background_color&&(e["--ah-page-bg"]=i.background_color),i.background_image_url&&(e["--ah-page-bg-image"]=`url(${i.background_image_url})`)}return e}const b={br:[],em:[],i:[],strong:[],b:[],u:[],span:["class"],a:["href","class"]};function w(t){if(!t)return"";if(!t.includes("<"))return t;let e=t;e=e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'");for(const[t,i]of Object.entries(b)){if("br"===t){e=e.replace(/<br\s*\/?>/gi,"<br>");continue}const o=RegExp(`<${t}((?:\\s+[a-z-]+(?:="[^&]*"|='[^&]*')?)*)\\s*>`,"gi");e=e.replace(o,((e,o)=>{const n=[];if(o){const t=o.replace(/"/g,'"').replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),e=/([a-z-]+)=["']([^"']*)["']/gi;let s;for(;null!==(s=e.exec(t));){const[,t,e]=s;t&&i.includes(t.toLowerCase())&&("href"===t.toLowerCase()?x(e||"")&&n.push(`${t}="${v(e||"")}"`):n.push(`${t}="${v(e||"")}"`))}}"a"===t&&(n.push('target="_blank"'),n.push('rel="noopener noreferrer"'));const s=n.length?" "+n.join(" "):"";return`<${t}${s}>`}));const n=RegExp(`</${t}>`,"gi");e=e.replace(n,`</${t}>`)}return e}function x(t){if(!t)return!1;if(t.startsWith("/")||t.startsWith("#")||t.startsWith("?"))return!0;try{const e=new URL(t,"https://example.com");return"http:"===e.protocol||"https:"===e.protocol}catch{return!1}}function v(t){return t.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}const y=new Set(["TEXT","EMAIL","CODE","PASSWORD","NUMBER","URL"]),S=new Set(["TEXT","EMAIL","CODE","PASSWORD","NUMBER","TEL","URL","DATE","BOOLEAN","LEGAL","COUNTRY","DROPDOWN","CHOICE"]),k=e(class extends i{constructor(t){super(),!1!==t&&this.__registerHost(),this.__attachShadow(),this.formSubmit=o(this,"formSubmit"),this.buttonClick=o(this,"buttonClick"),this.linkClick=o(this,"linkClick"),this.navigate=o(this,"navigate"),this.flowComplete=o(this,"flowComplete"),this.flowError=o(this,"flowError"),this.screenChange=o(this,"screenChange")}get el(){return this}screen;apiUrl;baseUrl;state;screenId;watchScreenId(){this.updateDataScreenAttribute()}authParams;statePersistence="memory";storageKey="authhero_widget";branding;theme;loading=!1;autoSubmit=!1;autoNavigate;locale;_screen;_authParams;_branding;_theme;formData={};listFilter="";conditionalMediationAbort;loadedFontUrl;formSubmit;buttonClick;linkClick;navigate;flowComplete;flowError;screenChange;watchScreen(t){if(this.conditionalMediationAbort?.abort(),this.conditionalMediationAbort=void 0,"string"==typeof t)try{this._screen=JSON.parse(t)}catch{console.error("Failed to parse screen JSON")}else this._screen=t;this._screen&&(this.formData={},this.listFilter="",this.initFormDataFromDefaults(this._screen),this.screenChange.emit(this._screen),this.updateDataScreenAttribute())}initFormDataFromDefaults(t){const e={};for(const i of t.components||[]){if(!("config"in i)||!i.config)continue;if(!("default_value"in i.config))continue;const t=i.config.default_value;"string"==typeof t&&""!==t?e[i.id]=t:"boolean"==typeof t&&(e[i.id]=t?"true":"false")}Object.keys(e).length>0&&(this.formData={...e,...this.formData})}updateDataScreenAttribute(){const t=this._screen?.name||this.screenId;t?this.el.setAttribute("data-screen",t):this.el.removeAttribute("data-screen");const e=this.el.closest("[data-authhero-widget-container]");e&&(t?e.setAttribute("data-screen",t):e.removeAttribute("data-screen"))}watchBranding(t){if("string"==typeof t)try{this._branding=JSON.parse(t)}catch{console.error("Failed to parse branding JSON")}else this._branding=t;this.applyThemeStyles()}watchTheme(t){if("string"==typeof t)try{this._theme=JSON.parse(t)}catch{console.error("Failed to parse theme JSON")}else this._theme=t;this.applyThemeStyles()}watchAuthParams(t){if("string"==typeof t)try{this._authParams=JSON.parse(t)}catch{console.error("Failed to parse authParams JSON")}else this._authParams=t}applyThemeStyles(){const t=function(t,e){return{...g(t),...m(e)}}(this._branding,this._theme);!function(t,e){Object.entries(e).forEach((([e,i])=>{t.style.setProperty(e,i)}))}(this.el,t),this.loadCustomFont()}loadCustomFont(){if("undefined"==typeof document)return;const t=this._theme?.fonts?.font_url||this._branding?.font?.url;if(t===this.loadedFontUrl)return;for(const t of Array.from(document.head.querySelectorAll("link[data-authhero-font]")))t.remove();if(this.loadedFontUrl=void 0,!t)return;const e=document.createElement("link");e.rel="stylesheet",e.href=t,e.setAttribute("data-authhero-font",t),document.head.appendChild(e),this.loadedFontUrl=t}focusFirstInput(){requestAnimationFrame((()=>{const t=this.el.shadowRoot;if(!t)return;const e=t.querySelectorAll("authhero-node");for(const t of Array.from(e)){const e=t.shadowRoot;if(e){const t=e.querySelector('input:not([type="hidden"]):not([type="checkbox"]):not([disabled]), textarea:not([disabled])');if(t)return void t.focus()}}}))}pendingRenderResolvers=[];activeSwaps=0;updateReadyAttribute(){this.el.toggleAttribute("data-ready",!this.loading&&0===this.activeSwaps)}componentDidRender(){if(this.updateReadyAttribute(),0===this.pendingRenderResolvers.length)return;const t=this.pendingRenderResolvers;this.pendingRenderResolvers=[],t.forEach((t=>t()))}nextRender(){return new Promise((t=>{let e=!1;const i=()=>{e||(e=!0,t())};this.pendingRenderResolvers.push(i),requestAnimationFrame((()=>requestAnimationFrame(i)))}))}async swapScreen(t){const e=this.el.shadowRoot?.querySelector(".widget-container"),i="function"==typeof window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches;if(e&&"function"==typeof e.animate&&!i){this.activeSwaps++;try{await this.animateSwap(e,t)}finally{this.activeSwaps--,this.updateReadyAttribute()}}else t()}async animateSwap(t,e){const i=t.getBoundingClientRect().height;t.style.height=i+"px",t.style.overflow="hidden",e(),await this.nextRender();const o=()=>{t.style.height="",t.style.overflow=""};t.style.height="auto";const n=t.getBoundingClientRect().height;if(t.style.height=i+"px",t.getBoundingClientRect(),Math.abs(n-i)<1)return void o();const s=t.animate([{height:i+"px"},{height:n+"px"}],{duration:520,easing:"cubic-bezier(0.22, 1, 0.36, 1)"});try{await s.finished}catch{}finally{o()}}get shouldAutoNavigate(){return this.autoNavigate??this.autoSubmit}buildUrl(t){return this.baseUrl?""+new URL(t,this.baseUrl):t}loadPersistedState(){if("url"===this.statePersistence){const t=new URL(window.location.href).searchParams.get("state");t&&!this.state&&(this.state=t)}else if("session"===this.statePersistence)try{const t=sessionStorage.getItem(this.storageKey+"_state");t&&!this.state&&(this.state=t);const e=sessionStorage.getItem(this.storageKey+"_screenId");e&&!this.screenId&&(this.screenId=e)}catch{}}persistState(){if("url"===this.statePersistence){const t=new URL(window.location.href);this.state&&t.searchParams.set("state",this.state),this.screenId&&t.searchParams.set("screen",this.screenId),window.history.replaceState({},"",""+t)}else if("session"===this.statePersistence)try{this.state&&sessionStorage.setItem(this.storageKey+"_state",this.state),this.screenId&&sessionStorage.setItem(this.storageKey+"_screenId",this.screenId)}catch{}}handlePopState=t=>{if(!this.apiUrl)return;t.state?.state&&(this.state=t.state.state);const e=t.state?.screen??this.extractScreenIdFromHref(location.href);e&&this.fetchScreen(e)};connectedCallback(){window.addEventListener("popstate",this.handlePopState)}disconnectedCallback(){window.removeEventListener("popstate",this.handlePopState),this.conditionalMediationAbort?.abort(),this.conditionalMediationAbort=void 0}readJsonScript(t){if(!this.el)return;const e=this.el.querySelector(`script[type="application/json"][data-authhero="${t}"]`);return e?.textContent??void 0}async componentWillLoad(){if(!this._screen){const t=this.screen||this.readJsonScript("screen")||this.el?.getAttribute("screen");t&&this.watchScreen(t)}this._branding||this.watchBranding(this.branding??this.readJsonScript("branding")),this._theme||this.watchTheme(this.theme??this.readJsonScript("theme")),this._authParams||this.watchAuthParams(this.authParams??this.readJsonScript("auth-params")),this._screen&&this.adoptPrehydrationValues(this._screen),this.loadPersistedState(),this.apiUrl&&!this._screen&&await this.fetchScreen(this.screenId)}adoptPrehydrationValues(t){const e=this.el.shadowRoot;if(!e)return;const i=[e];e.querySelectorAll("authhero-node").forEach((t=>{t.shadowRoot&&i.push(t.shadowRoot)}));const o={};for(const e of t.components??[])if(y.has(e.type))for(const t of i){const i=Array.from(t.querySelectorAll("input[name]")).find((t=>t.name===e.id&&"hidden"!==t.type));if(i){o[e.id]=i.value;break}}Object.keys(o).length>0&&(this.formData={...this.formData,...o})}async fetchScreen(t,e){if(!this.apiUrl)return!1;const i=t||this.screenId;let o=this.apiUrl;i&&o.includes("{screenId}")&&(o=o.replace("{screenId}",encodeURIComponent(i)));const n=new URL(o,this.baseUrl||window.location.origin);this.state&&n.searchParams.set("state",this.state),e&&n.searchParams.set("nodeId",e),this.loading=!0;try{const t=await fetch(this.buildUrl(n.pathname+n.search),{credentials:"include",headers:{Accept:"application/json"}});if(t.ok){const e=await t.json();if(e.screen?(this._screen=e.screen,e.branding&&(this._branding=e.branding,this.applyThemeStyles()),e.state&&(this.state=e.state),e.screenId&&(this.screenId=e.screenId)):this._screen=e,this._screen)return this.listFilter="",i&&i!==this.screenId&&(this.screenId=i),this.initFormDataFromDefaults(this._screen),this.screenChange.emit(this._screen),this.updateDataScreenAttribute(),this.persistState(),this.focusFirstInput(),e.ceremony&&this.performWebAuthnCeremony(e.ceremony),!0}else{const e=await t.json().catch((()=>({message:"Failed to load screen"})));this.flowError.emit({message:e.message||"Failed to load screen"})}}catch(t){console.error("Failed to fetch screen:",t),this.flowError.emit({message:t instanceof Error?t.message:"Failed to fetch screen"})}finally{this.loading=!1}return!1}handleInputChange=(t,e)=>{this.formData={...this.formData,[t]:e}};handleSubmit=async(t,e)=>{if(t.preventDefault(),!this._screen||this.loading)return;let i={...this.formData,...e||{}};const o=this.el.shadowRoot?.querySelector("form");if(o&&o.querySelectorAll('input[type="hidden"]').forEach((t=>{t.name&&t.value&&(i[t.name]=t.value)})),this.formSubmit.emit({screen:this._screen,data:i}),this.autoSubmit)if(this._screen.method&&"GET"!==this._screen.method.toUpperCase()){this.loading=!0;try{const t=await fetch(this.buildUrl(this._screen.action),{method:this._screen.method,credentials:"include",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({data:i})}),e=t.headers.get("content-type");if(e?.includes("text/html")){const e=await t.text();return document.open(),document.write(e),void document.close()}if(e?.includes("application/json")){const e=await t.json();if(e.redirect){this.flowComplete.emit({redirectUrl:e.redirect});const t=this.navigate.emit({url:e.redirect});this.shouldAutoNavigate&&!t.defaultPrevented&&(window.location.href=e.redirect)}else!t.ok&&e.screen?await this.swapScreen((()=>{this.loading=!1,this._screen=e.screen,this.listFilter="",this.initFormDataFromDefaults(e.screen),this.screenChange.emit(e.screen),this.updateDataScreenAttribute(),this.focusFirstInput()})):e.screen?await this.swapScreen((()=>{this.loading=!1,this._screen=e.screen,this.listFilter="",this.formData={},this.initFormDataFromDefaults(e.screen),this.screenChange.emit(e.screen),this.updateDataScreenAttribute(),e.screenId&&(this.screenId=e.screenId),this.persistState(),e.navigateUrl&&this.shouldAutoNavigate&&window.history.pushState({screen:e.screenId,state:this.state},"",e.navigateUrl),e.branding&&(this._branding=e.branding,this.applyThemeStyles()),e.state&&(this.state=e.state,this.persistState()),e.ceremony&&this.performWebAuthnCeremony(e.ceremony),this.focusFirstInput()})):e.complete?this.flowComplete.emit({}):!t.ok&&e.error&&(this._screen&&(this._screen={...this._screen,messages:[...this._screen.messages||[],{text:e.error,type:"error"}]}),this.flowError.emit({message:e.error}))}}catch(t){console.error("Form submission failed:",t),this.flowError.emit({message:t instanceof Error?t.message:"Form submission failed"})}finally{this.loading=!1}}else window.location.href=this.buildUrl(this._screen.action)};overrideFormSubmit(){const t=this.el.shadowRoot;if(!t)return;const e=t.querySelector("form");e&&(e.submit=()=>{const t=new FormData(e),i={};t.forEach(((t,e)=>{"string"==typeof t&&(i[e]=t)})),this.handleSubmit({preventDefault:()=>{}},i)})}performWebAuthnCeremony(t){this.isValidWebAuthnCeremony(t)?"webauthn-authentication-conditional"!==t.type?requestAnimationFrame((()=>{this.overrideFormSubmit(),"webauthn-authentication"===t.type?this.executeWebAuthnAuthentication(t):this.executeWebAuthnRegistration(t)})):this.executeWebAuthnConditionalMediation(t):console.error("Invalid WebAuthn ceremony payload",t)}isValidWebAuthnCeremony(t){if("object"!=typeof t||null===t)return!1;const e=t;if("string"!=typeof e.successAction)return!1;const i=e.options;if("object"!=typeof i||null===i)return!1;if("string"!=typeof i.challenge)return!1;if("webauthn-registration"===e.type){const t=i.rp;if("object"!=typeof t||null===t)return!1;if("string"!=typeof t.id||"string"!=typeof t.name)return!1;const e=i.user;return"object"==typeof e&&null!==e&&("string"==typeof e.id&&"string"==typeof e.name&&"string"==typeof e.displayName&&!!Array.isArray(i.pubKeyCredParams))}return"webauthn-authentication"===e.type||"webauthn-authentication-conditional"===e.type}async executeWebAuthnRegistration(t){const e=t.options,i=t=>{for(t=t.replace(/-/g,"+").replace(/_/g,"/");t.length%4;)t+="=";const e=atob(t),i=new Uint8Array(e.length);for(let t=0;t<e.length;t++)i[t]=e.charCodeAt(t);return i.buffer},o=t=>{const e=new Uint8Array(t);let i="";for(let t=0;t<e.length;t++)i+=String.fromCharCode(e[t]);return btoa(i).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")},n=()=>{const t=this.el?.shadowRoot;if(t){const e=t.querySelector("form");if(e)return e}return document.querySelector("form")};try{const s={challenge:i(e.challenge),rp:{id:e.rp.id,name:e.rp.name},user:{id:i(e.user.id),name:e.user.name,displayName:e.user.displayName},pubKeyCredParams:e.pubKeyCredParams.map((t=>({alg:t.alg,type:t.type}))),timeout:e.timeout,attestation:e.attestation||"none",authenticatorSelection:e.authenticatorSelection?{residentKey:e.authenticatorSelection.residentKey||"preferred",userVerification:e.authenticatorSelection.userVerification||"preferred"}:void 0};e.excludeCredentials?.length&&(s.excludeCredentials=e.excludeCredentials.map((t=>({id:i(t.id),type:t.type,transports:t.transports||[]}))));const r=await navigator.credentials.create({publicKey:s}),a=r.response,c={id:r.id,rawId:o(r.rawId),type:r.type,response:{attestationObject:o(a.attestationObject),clientDataJSON:o(a.clientDataJSON)},clientExtensionResults:r.getClientExtensionResults(),authenticatorAttachment:r.authenticatorAttachment||void 0};"function"==typeof a.getTransports&&(c.response.transports=a.getTransports());const h=n();if(h){const e=h.querySelector('[name="credential-field"]')||h.querySelector("#credential-field"),i=h.querySelector('[name="action-field"]')||h.querySelector("#action-field");e&&(e.value=JSON.stringify(c)),i&&(i.value=t.successAction),h.submit()}}catch(t){console.error("WebAuthn registration error:",t);const e=n();if(e){const t=e.querySelector('[name="action-field"]')||e.querySelector("#action-field");t&&(t.value="error"),e.submit()}}}async executeWebAuthnAuthentication(t){const e=t.options,i=t=>{for(t=t.replace(/-/g,"+").replace(/_/g,"/");t.length%4;)t+="=";const e=atob(t),i=new Uint8Array(e.length);for(let t=0;t<e.length;t++)i[t]=e.charCodeAt(t);return i.buffer},o=t=>{const e=new Uint8Array(t);let i="";for(let t=0;t<e.length;t++)i+=String.fromCharCode(e[t]);return btoa(i).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")},n=()=>{const t=this.el?.shadowRoot;if(t){const e=t.querySelector("form");if(e)return e}return document.querySelector("form")};try{const s={challenge:i(e.challenge),rpId:e.rpId,timeout:e.timeout,userVerification:e.userVerification||"preferred"};e.allowCredentials?.length&&(s.allowCredentials=e.allowCredentials.map((t=>({id:i(t.id),type:t.type,transports:t.transports||[]}))));const r=await navigator.credentials.get({publicKey:s}),a=r.response,c={id:r.id,rawId:o(r.rawId),type:r.type,response:{authenticatorData:o(a.authenticatorData),clientDataJSON:o(a.clientDataJSON),signature:o(a.signature)},clientExtensionResults:r.getClientExtensionResults(),authenticatorAttachment:r.authenticatorAttachment||void 0};a.userHandle&&(c.response.userHandle=o(a.userHandle));const h=n();if(h){const e=h.querySelector('[name="credential-field"]')||h.querySelector("#credential-field"),i=h.querySelector('[name="action-field"]')||h.querySelector("#action-field");e&&(e.value=JSON.stringify(c)),i&&(i.value=t.successAction),h.submit()}}catch(t){console.error("WebAuthn authentication error:",t);const e=n();if(e){const t=e.querySelector('[name="action-field"]')||e.querySelector("#action-field");t&&(t.value="error"),e.submit()}}}async executeWebAuthnConditionalMediation(t){if(!window.PublicKeyCredential||!PublicKeyCredential.isConditionalMediationAvailable)return;if(!await PublicKeyCredential.isConditionalMediationAvailable())return;this.conditionalMediationAbort?.abort();const e=new AbortController;this.conditionalMediationAbort=e;const i=t.options,o=t=>{for(t=t.replace(/-/g,"+").replace(/_/g,"/");t.length%4;)t+="=";const e=atob(t),i=new Uint8Array(e.length);for(let t=0;t<e.length;t++)i[t]=e.charCodeAt(t);return i.buffer},n=t=>{const e=new Uint8Array(t);let i="";for(let t=0;t<e.length;t++)i+=String.fromCharCode(e[t]);return btoa(i).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")};try{const s=await navigator.credentials.get({mediation:"conditional",signal:e.signal,publicKey:{challenge:o(i.challenge),rpId:i.rpId,timeout:i.timeout,userVerification:i.userVerification||"preferred"}}),r=s.response,a={id:s.id,rawId:n(s.rawId),type:s.type,response:{authenticatorData:n(r.authenticatorData),clientDataJSON:n(r.clientDataJSON),signature:n(r.signature)},clientExtensionResults:s.getClientExtensionResults(),authenticatorAttachment:s.authenticatorAttachment||void 0};r.userHandle&&(a.response.userHandle=n(r.userHandle)),this.formData["credential-field"]=JSON.stringify(a),this.formData["action-field"]=t.successAction,this.overrideFormSubmit();const c=this.el?.shadowRoot,h=c?.querySelector("form");if(h){const e=h.querySelector('[name="credential-field"]')||h.querySelector("#credential-field"),i=h.querySelector('[name="action-field"]')||h.querySelector("#action-field");e&&(e.value=JSON.stringify(a)),i&&(i.value=t.successAction),h.submit()}}catch(t){if("AbortError"===t?.name||"NotAllowedError"===t?.name)return;console.error("Conditional mediation error:",t)}}handleButtonClick=t=>{if("submit"!==t.type)if(this.buttonClick.emit(t),"SOCIAL"===t.type&&t.value&&this.shouldAutoNavigate){const e=this.getProviderHref(t.value);if(e){const t=this.extractScreenIdFromHref(e);return void(t&&this.apiUrl?this.navigateToScreen(t,e):window.location.href=e)}this.handleSocialLogin(t.value)}else"RESEND_BUTTON"===t.type&&this.shouldAutoNavigate&&this.handleResend();else{const e=this._screen?.components?.find((e=>e.id===t.id));if(this._screen&&("NEXT_BUTTON"!==e?.type||!0!==e.config?.skip_validation)&&this.hasUnfilledRequiredFields(this._screen))return;if((!this._screen?.method||"GET"===this._screen.method.toUpperCase())&&this._screen?.action)return void(window.location.href=this.buildUrl(this._screen.action));const i={...this.formData,[t.id]:"true"};this.formData=i,this.handleSubmit({preventDefault:()=>{}},i)}};handleSocialLogin(t){const e=this._authParams||{},i={connection:t};this.state?i.state=this.state:e.state&&(i.state=e.state),e.client_id&&(i.client_id=e.client_id),e.redirect_uri&&(i.redirect_uri=e.redirect_uri),e.scope&&(i.scope=e.scope),e.audience&&(i.audience=e.audience),e.nonce&&(i.nonce=e.nonce),e.response_type&&(i.response_type=e.response_type);const o=this.buildUrl("/authorize?"+new URLSearchParams(i));this.navigate.emit({url:o}).defaultPrevented||(window.location.href=o)}async handleResend(){if(this._screen?.action)try{const t=this._screen.action+(this._screen.action.includes("?")?"&":"?")+"action=resend";await fetch(this.buildUrl(t),{method:"POST",credentials:"include"})}catch(t){console.error("Resend failed:",t)}}extractScreenIdFromHref(t){try{const e=new URL(t,window.location.origin).pathname,i=e.match(/\/u2\/login\/([^/]+)$/);if(i)return i[1];const o=e.match(/\/u2\/([^/]+)$/);return o&&"login"!==o[1]&&"screen"!==o[1]?o[1]:null}catch{return null}}handleLinkClick=(t,e)=>{if(this.linkClick.emit({id:e.id,href:e.href,text:e.text}),!this.shouldAutoNavigate)return void t.preventDefault();const i=this.extractScreenIdFromHref(e.href);return i&&this.apiUrl?(t.preventDefault(),void this.navigateToScreen(i,e.href)):void 0};async navigateToScreen(t,e){await this.fetchScreen(t)?window.history.pushState({screen:t,state:this.state},"",e):window.location.href=e}getProviderHref(t){if(!this._screen)return null;for(const e of this._screen.components){const i=e;if("SOCIAL"===i.type&&i.config?.provider_details){const e=i.config.provider_details.find((e=>e.name===t));if(e?.href)return e.href}}return null}isSocialComponent(t){return"SOCIAL"===t.type}isDividerComponent(t){return"DIVIDER"===t.type}isRequiredFieldFilled(t){const e=this.formData[t.id];return"BOOLEAN"===t.type||"LEGAL"===t.type?"true"===e:"string"==typeof e&&""!==e.trim()}hasUnfilledRequiredFields(t){return(t.components??[]).some((t=>!1!==t.visible&&"required"in t&&!0===t.required&&S.has(t.type)&&!this.isRequiredFieldFilled(t)))}getChoiceButtonText(t){const e=t.config;return e?.text??""}render(){const t=this._screen;if(this.loading&&!t)return n("div",{class:"widget-container"},n("div",{class:"loading-spinner"}));if(!t)return n("div",{class:"widget-container"},n("div",{class:"error-message"},"No screen configuration provided"));const e=t.messages?.filter((t=>"error"===t.type))||[],i=t.messages?.filter((t=>"success"===t.type))||[],o=[...t.components??[]],s=o.filter((t=>!1!==t.visible)).sort(((t,e)=>(t.order??0)-(e.order??0))),a=o.filter((t=>!1===t.visible)),c=s.filter((t=>this.isSocialComponent(t))),h=c.length>0?s.find((t=>this.isDividerComponent(t))):void 0,l=s.filter((t=>!this.isSocialComponent(t)&&t!==h)),d=!!h,f=h?.config?.text||"Or",u=l.filter((t=>"NEXT_BUTTON"===t.type)),p=u.length===l.length&&u.length>5,g=this.hasUnfilledRequiredFields(t),m=this.listFilter.trim().toLowerCase(),b=p&&m?u.filter((t=>this.getChoiceButtonText(t).toLowerCase().includes(m))):u,x=t=>{const e=t.config;return["social-buttons","button","button-secondary","button-social","button-social-content","button-social-text","button-social-text-short","button-social-subtitle","button-social-badge","social-icon",...(e?.providers??[]).flatMap((t=>{const e=r(t);return["button-social-"+e,"button-social-content-"+e,"button-social-text-"+e,"button-social-text-short-"+e,"button-social-subtitle-"+e,"button-social-badge-"+e,"social-icon-"+e]}))].join(", ")},v=this._theme?.widget?.logo_url||this._branding?.logo_url;return n("div",{class:"widget-container",part:"container","data-authstack-container":!0},n("header",{class:"widget-header",part:"header"},v&&n("div",{class:"logo-wrapper",part:"logo-wrapper"},n("img",{class:"logo",part:"logo",src:v,alt:"Logo"})),t.title&&n("h1",{class:"title",part:"title",innerHTML:w(t.title)}),t.description&&n("p",{class:"description",part:"description",innerHTML:w(t.description)})),n("div",{class:"widget-body",part:"body"},e.map((t=>n("div",{class:"message message-error",part:"message message-error",key:t.id??t.text},t.text))),i.map((t=>n("div",{class:"message message-success",part:"message message-success",key:t.id??t.text},t.text))),n("form",{onSubmit:this.handleSubmit,action:t.action,method:t.method||"POST",part:"form"},a.map((t=>n("input",{type:"hidden",name:t.id,id:t.id,key:t.id,value:this.formData[t.id]||""}))),n("div",{class:"form-content"},c.length>0&&n("div",{class:"social-section",part:"social-section"},c.map((t=>n("authhero-node",{key:t.id,component:t,locale:this.locale,value:this.formData[t.id],onFieldChange:t=>this.handleInputChange(t.detail.id,t.detail.value),onButtonClick:t=>this.handleButtonClick(t.detail),disabled:this.loading,exportparts:x(t)})))),c.length>0&&l.length>0&&d&&n("div",{class:"divider",part:"divider"},n("span",{class:"divider-text"},f)),n("div",{class:"fields-section",part:"fields-section"},p&&n("input",{type:"text",class:"choice-list-search",part:"choice-list-search",placeholder:"Search","aria-label":"Search",autocomplete:"off",value:this.listFilter,onInput:t=>this.listFilter=t.target.value,onKeyDown:t=>{"Enter"===t.key&&t.preventDefault()}}),n("div",{class:p?"fields-list fields-list-scroll":"fields-list",part:p?"fields-list fields-list-scroll":"fields-list"},(p?b:l).map((t=>n("authhero-node",{key:t.id,component:t,locale:this.locale,value:this.formData[t.id],onFieldChange:t=>this.handleInputChange(t.detail.id,t.detail.value),onButtonClick:t=>this.handleButtonClick(t.detail),disabled:this.loading||"NEXT_BUTTON"===t.type&&!0!==t.config?.skip_validation&&g}))),p&&0===b.length&&n("div",{class:"choice-list-empty",part:"choice-list-empty"},"No matches"))))),t.links&&t.links.length>0&&n("div",{class:"links",part:"links"},t.links.map((t=>n("span",{class:"link-wrapper",part:"link-wrapper",key:t.id??t.href},t.linkText?n("span",null,t.text," ",n("a",{href:t.href,class:"link",part:"link",onClick:e=>this.handleLinkClick(e,{id:t.id,href:t.href,text:t.linkText||t.text})},t.linkText)):n("a",{href:t.href,class:"link",part:"link",onClick:e=>this.handleLinkClick(e,{id:t.id,href:t.href,text:t.text})},t.text))))),t.footer&&n("div",{class:"widget-footer",part:"footer",innerHTML:w(t.footer)})))}static get watchers(){return{screenId:[{watchScreenId:0}],screen:[{watchScreen:0}],branding:[{watchBranding:0}],theme:[{watchTheme:0}],authParams:[{watchAuthParams:0}]}}static get style(){return':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{width:var(--ah-widget-max-width, 400px);margin:0 auto;background-color:var(--ah-color-bg, #ffffff);border-radius:var(--ah-widget-radius, 5px);border:var(--ah-widget-border-width, 0) solid var(--ah-widget-border-color, transparent);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-text-header, var(--ah-color-header, #1e212a));line-height:1.2}.description{font-size:var(--ah-font-size-subtitle, 16px);font-weight:var(--ah-font-weight-subtitle, 400);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)}.fields-list{display:flex;flex-direction:column}.fields-list-scroll{max-height:var(--ah-choice-list-max-height, 320px);overflow-y:auto;gap:var(--ah-choice-list-gap, 8px);padding-right:4px}.choice-list-search{width:100%;padding:16px;margin-bottom:12px;font-size:16px;font-family:inherit;color:var(--ah-color-input-text, var(--ah-color-text, #1e212a));background-color:var(--ah-color-input-bg, #ffffff);border:var(--ah-input-border-width, 1px) solid var(--ah-color-border, #c9cace);border-radius:var(--ah-input-radius, 3px);outline:none;box-sizing:border-box;transition:border-color 0.15s ease-out, box-shadow 0.15s ease-out}.choice-list-search:hover{border-color:var(--ah-color-border-hover, #65676e)}.choice-list-search:focus{border-color:var(--ah-color-primary, var(--ah-color-link, #635dff))}.choice-list-empty{padding:16px;text-align:center;font-size:14px;color:var(--ah-color-text-muted, #65676e)}.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:var(--ah-font-size-body, 14px);font-weight:var(--ah-font-weight-body, 400);color:var(--ah-color-text, #1e212a)}.link{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:var(--ah-font-size-link, 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-focus-ring, 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-focus-ring, 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(:not([floating])){display:block;width:100%;min-height:100vh;background-color:var(--ah-color-bg, #ffffff)}:host(:not([floating])) .widget-container{box-shadow:none;border-radius:0;border:0;width:100%;margin:0}:host([floating]) .widget-container{width:100%;margin:0}.widget-header{padding:24px 16px 16px}.widget-body{padding:0 16px 24px}}'}},[513,"authhero-widget",{screen:[1],apiUrl:[1,"api-url"],baseUrl:[1,"base-url"],state:[1025],screenId:[1025,"screen-id"],authParams:[1,"auth-params"],statePersistence:[1,"state-persistence"],storageKey:[1,"storage-key"],branding:[1],theme:[1],loading:[1028],autoSubmit:[4,"auto-submit"],autoNavigate:[4,"auto-navigate"],locale:[1],_screen:[32],_authParams:[32],_branding:[32],_theme:[32],formData:[32],listFilter:[32]},void 0,{screenId:[{watchScreenId:0}],screen:[{watchScreen:0}],branding:[{watchBranding:0}],theme:[{watchTheme:0}],authParams:[{watchAuthParams:0}]}]);function A(){"undefined"!=typeof customElements&&["authhero-widget","authhero-node"].forEach((e=>{switch(e){case"authhero-widget":customElements.get(t(e))||customElements.define(t(e),k);break;case"authhero-node":customElements.get(t(e))||s()}}))}A();const N=k,O=A;export{N as AuthheroWidget,O as defineCustomElement}
|
|
@@ -530,6 +530,19 @@ const CHOICE_LIST_SEARCH_THRESHOLD = 5;
|
|
|
530
530
|
* (CARDS, FILE, RECAPTCHA, …) can carry `required` in the schema too, and
|
|
531
531
|
* gating on them would leave Continue disabled with no way to satisfy it.
|
|
532
532
|
*/
|
|
533
|
+
/**
|
|
534
|
+
* Field types rendered as a single plain text input whose value maps 1:1 to
|
|
535
|
+
* formData. Composite fields (TEL, DATE) and choice/checkbox fields keep
|
|
536
|
+
* internal state, so they're not adopted from pre-hydration markup.
|
|
537
|
+
*/
|
|
538
|
+
const PREHYDRATION_TEXT_TYPES = new Set([
|
|
539
|
+
"TEXT",
|
|
540
|
+
"EMAIL",
|
|
541
|
+
"CODE",
|
|
542
|
+
"PASSWORD",
|
|
543
|
+
"NUMBER",
|
|
544
|
+
"URL",
|
|
545
|
+
]);
|
|
533
546
|
const FILLABLE_FIELD_TYPES = new Set([
|
|
534
547
|
"TEXT",
|
|
535
548
|
"EMAIL",
|
|
@@ -910,7 +923,24 @@ const AuthheroWidget = class {
|
|
|
910
923
|
* actually in the DOM before measuring its height.
|
|
911
924
|
*/
|
|
912
925
|
pendingRenderResolvers = [];
|
|
926
|
+
/**
|
|
927
|
+
* Number of `swapScreen` calls still running (rendering or animating the
|
|
928
|
+
* card height). A counter rather than a flag because a newer swap can start
|
|
929
|
+
* before a superseded one has settled.
|
|
930
|
+
*/
|
|
931
|
+
activeSwaps = 0;
|
|
932
|
+
updateReadyAttribute() {
|
|
933
|
+
{
|
|
934
|
+
this.el.toggleAttribute("data-ready", !this.loading && this.activeSwaps === 0);
|
|
935
|
+
}
|
|
936
|
+
}
|
|
913
937
|
componentDidRender() {
|
|
938
|
+
// `data-ready` marks the widget as interactive: hydrated in the browser
|
|
939
|
+
// (the SSR markup already carries Stencil's `hydrated` class, so that
|
|
940
|
+
// can't tell server and client apart) and not mid-submit or mid-swap.
|
|
941
|
+
// Stencil defers this hook until child nodes have rendered, so the
|
|
942
|
+
// fields are live too. E2E tests wait on `authhero-widget[data-ready]`.
|
|
943
|
+
this.updateReadyAttribute();
|
|
914
944
|
if (this.pendingRenderResolvers.length === 0)
|
|
915
945
|
return;
|
|
916
946
|
const resolvers = this.pendingRenderResolvers;
|
|
@@ -958,6 +988,18 @@ const AuthheroWidget = class {
|
|
|
958
988
|
apply();
|
|
959
989
|
return;
|
|
960
990
|
}
|
|
991
|
+
// Hold `data-ready` off until the new screen has rendered and the height
|
|
992
|
+
// animation has finished; `apply()` clears `loading` before either.
|
|
993
|
+
this.activeSwaps++;
|
|
994
|
+
try {
|
|
995
|
+
await this.animateSwap(card, apply);
|
|
996
|
+
}
|
|
997
|
+
finally {
|
|
998
|
+
this.activeSwaps--;
|
|
999
|
+
this.updateReadyAttribute();
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
async animateSwap(card, apply) {
|
|
961
1003
|
// Lock the current height and clip, so swapping the content doesn't jump
|
|
962
1004
|
// before the animation runs.
|
|
963
1005
|
const startHeight = card.getBoundingClientRect().height;
|
|
@@ -1122,6 +1164,9 @@ const AuthheroWidget = class {
|
|
|
1122
1164
|
if (!this._authParams) {
|
|
1123
1165
|
this.watchAuthParams(this.authParams ?? this.readJsonScript("auth-params"));
|
|
1124
1166
|
}
|
|
1167
|
+
if (this._screen) {
|
|
1168
|
+
this.adoptPrehydrationValues(this._screen);
|
|
1169
|
+
}
|
|
1125
1170
|
// Load persisted state if available
|
|
1126
1171
|
this.loadPersistedState();
|
|
1127
1172
|
// Fetch screen from API if URL provided and no screen prop
|
|
@@ -1129,6 +1174,41 @@ const AuthheroWidget = class {
|
|
|
1129
1174
|
await this.fetchScreen(this.screenId);
|
|
1130
1175
|
}
|
|
1131
1176
|
}
|
|
1177
|
+
/**
|
|
1178
|
+
* Carry over text the user (or a password manager, or a test driver) put
|
|
1179
|
+
* into the server-rendered inputs before the client bundle loaded. Those
|
|
1180
|
+
* inputs had no `onInput` handler yet, so `formData` never saw the value:
|
|
1181
|
+
* the first client render would reset them to "" and keep the submit
|
|
1182
|
+
* button disabled. The declarative shadow roots are still the SSR ones
|
|
1183
|
+
* here — `componentWillLoad` runs before the first client render.
|
|
1184
|
+
*/
|
|
1185
|
+
adoptPrehydrationValues(screen) {
|
|
1186
|
+
const root = this.el.shadowRoot;
|
|
1187
|
+
if (!root)
|
|
1188
|
+
return;
|
|
1189
|
+
const roots = [root];
|
|
1190
|
+
root.querySelectorAll("authhero-node").forEach((node) => {
|
|
1191
|
+
if (node.shadowRoot)
|
|
1192
|
+
roots.push(node.shadowRoot);
|
|
1193
|
+
});
|
|
1194
|
+
const adopted = {};
|
|
1195
|
+
for (const component of screen.components ?? []) {
|
|
1196
|
+
if (!PREHYDRATION_TEXT_TYPES.has(component.type))
|
|
1197
|
+
continue;
|
|
1198
|
+
for (const r of roots) {
|
|
1199
|
+
const input = Array.from(r.querySelectorAll("input[name]")).find((el) => el.name === component.id && el.type !== "hidden");
|
|
1200
|
+
// Adopt "" too: a prefilled default the user cleared before
|
|
1201
|
+
// hydration must not be restored by the client render.
|
|
1202
|
+
if (input) {
|
|
1203
|
+
adopted[component.id] = input.value;
|
|
1204
|
+
break;
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
if (Object.keys(adopted).length > 0) {
|
|
1209
|
+
this.formData = { ...this.formData, ...adopted };
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1132
1212
|
/**
|
|
1133
1213
|
* Fetch screen configuration from the API
|
|
1134
1214
|
* @param screenIdOverride Optional screen ID to fetch (overrides this.screenId)
|
|
@@ -272,6 +272,13 @@ export declare class AuthheroWidget {
|
|
|
272
272
|
* actually in the DOM before measuring its height.
|
|
273
273
|
*/
|
|
274
274
|
private pendingRenderResolvers;
|
|
275
|
+
/**
|
|
276
|
+
* Number of `swapScreen` calls still running (rendering or animating the
|
|
277
|
+
* card height). A counter rather than a flag because a newer swap can start
|
|
278
|
+
* before a superseded one has settled.
|
|
279
|
+
*/
|
|
280
|
+
private activeSwaps;
|
|
281
|
+
private updateReadyAttribute;
|
|
275
282
|
componentDidRender(): void;
|
|
276
283
|
/**
|
|
277
284
|
* Resolves after Stencil flushes the next render, so `swapScreen` waits for
|
|
@@ -292,6 +299,7 @@ export declare class AuthheroWidget {
|
|
|
292
299
|
* or the user prefers reduced motion.
|
|
293
300
|
*/
|
|
294
301
|
private swapScreen;
|
|
302
|
+
private animateSwap;
|
|
295
303
|
/**
|
|
296
304
|
* Get the effective autoNavigate value (defaults to autoSubmit if not set)
|
|
297
305
|
*/
|
|
@@ -320,6 +328,15 @@ export declare class AuthheroWidget {
|
|
|
320
328
|
*/
|
|
321
329
|
private readJsonScript;
|
|
322
330
|
componentWillLoad(): Promise<void>;
|
|
331
|
+
/**
|
|
332
|
+
* Carry over text the user (or a password manager, or a test driver) put
|
|
333
|
+
* into the server-rendered inputs before the client bundle loaded. Those
|
|
334
|
+
* inputs had no `onInput` handler yet, so `formData` never saw the value:
|
|
335
|
+
* the first client render would reset them to "" and keep the submit
|
|
336
|
+
* button disabled. The declarative shadow roots are still the SSR ones
|
|
337
|
+
* here — `componentWillLoad` runs before the first client render.
|
|
338
|
+
*/
|
|
339
|
+
private adoptPrehydrationValues;
|
|
323
340
|
/**
|
|
324
341
|
* Fetch screen configuration from the API
|
|
325
342
|
* @param screenIdOverride Optional screen ID to fetch (overrides this.screenId)
|
package/hydrate/index.js
CHANGED
|
@@ -7251,6 +7251,19 @@ const CHOICE_LIST_SEARCH_THRESHOLD = 5;
|
|
|
7251
7251
|
* (CARDS, FILE, RECAPTCHA, …) can carry `required` in the schema too, and
|
|
7252
7252
|
* gating on them would leave Continue disabled with no way to satisfy it.
|
|
7253
7253
|
*/
|
|
7254
|
+
/**
|
|
7255
|
+
* Field types rendered as a single plain text input whose value maps 1:1 to
|
|
7256
|
+
* formData. Composite fields (TEL, DATE) and choice/checkbox fields keep
|
|
7257
|
+
* internal state, so they're not adopted from pre-hydration markup.
|
|
7258
|
+
*/
|
|
7259
|
+
const PREHYDRATION_TEXT_TYPES = new Set([
|
|
7260
|
+
"TEXT",
|
|
7261
|
+
"EMAIL",
|
|
7262
|
+
"CODE",
|
|
7263
|
+
"PASSWORD",
|
|
7264
|
+
"NUMBER",
|
|
7265
|
+
"URL",
|
|
7266
|
+
]);
|
|
7254
7267
|
const FILLABLE_FIELD_TYPES = new Set([
|
|
7255
7268
|
"TEXT",
|
|
7256
7269
|
"EMAIL",
|
|
@@ -7631,7 +7644,21 @@ class AuthheroWidget {
|
|
|
7631
7644
|
* actually in the DOM before measuring its height.
|
|
7632
7645
|
*/
|
|
7633
7646
|
pendingRenderResolvers = [];
|
|
7647
|
+
/**
|
|
7648
|
+
* Number of `swapScreen` calls still running (rendering or animating the
|
|
7649
|
+
* card height). A counter rather than a flag because a newer swap can start
|
|
7650
|
+
* before a superseded one has settled.
|
|
7651
|
+
*/
|
|
7652
|
+
activeSwaps = 0;
|
|
7653
|
+
updateReadyAttribute() {
|
|
7654
|
+
}
|
|
7634
7655
|
componentDidRender() {
|
|
7656
|
+
// `data-ready` marks the widget as interactive: hydrated in the browser
|
|
7657
|
+
// (the SSR markup already carries Stencil's `hydrated` class, so that
|
|
7658
|
+
// can't tell server and client apart) and not mid-submit or mid-swap.
|
|
7659
|
+
// Stencil defers this hook until child nodes have rendered, so the
|
|
7660
|
+
// fields are live too. E2E tests wait on `authhero-widget[data-ready]`.
|
|
7661
|
+
this.updateReadyAttribute();
|
|
7635
7662
|
if (this.pendingRenderResolvers.length === 0)
|
|
7636
7663
|
return;
|
|
7637
7664
|
const resolvers = this.pendingRenderResolvers;
|
|
@@ -7679,6 +7706,18 @@ class AuthheroWidget {
|
|
|
7679
7706
|
apply();
|
|
7680
7707
|
return;
|
|
7681
7708
|
}
|
|
7709
|
+
// Hold `data-ready` off until the new screen has rendered and the height
|
|
7710
|
+
// animation has finished; `apply()` clears `loading` before either.
|
|
7711
|
+
this.activeSwaps++;
|
|
7712
|
+
try {
|
|
7713
|
+
await this.animateSwap(card, apply);
|
|
7714
|
+
}
|
|
7715
|
+
finally {
|
|
7716
|
+
this.activeSwaps--;
|
|
7717
|
+
this.updateReadyAttribute();
|
|
7718
|
+
}
|
|
7719
|
+
}
|
|
7720
|
+
async animateSwap(card, apply) {
|
|
7682
7721
|
// Lock the current height and clip, so swapping the content doesn't jump
|
|
7683
7722
|
// before the animation runs.
|
|
7684
7723
|
const startHeight = card.getBoundingClientRect().height;
|
|
@@ -7850,6 +7889,41 @@ class AuthheroWidget {
|
|
|
7850
7889
|
await this.fetchScreen(this.screenId);
|
|
7851
7890
|
}
|
|
7852
7891
|
}
|
|
7892
|
+
/**
|
|
7893
|
+
* Carry over text the user (or a password manager, or a test driver) put
|
|
7894
|
+
* into the server-rendered inputs before the client bundle loaded. Those
|
|
7895
|
+
* inputs had no `onInput` handler yet, so `formData` never saw the value:
|
|
7896
|
+
* the first client render would reset them to "" and keep the submit
|
|
7897
|
+
* button disabled. The declarative shadow roots are still the SSR ones
|
|
7898
|
+
* here — `componentWillLoad` runs before the first client render.
|
|
7899
|
+
*/
|
|
7900
|
+
adoptPrehydrationValues(screen) {
|
|
7901
|
+
const root = this.el.shadowRoot;
|
|
7902
|
+
if (!root)
|
|
7903
|
+
return;
|
|
7904
|
+
const roots = [root];
|
|
7905
|
+
root.querySelectorAll("authhero-node").forEach((node) => {
|
|
7906
|
+
if (node.shadowRoot)
|
|
7907
|
+
roots.push(node.shadowRoot);
|
|
7908
|
+
});
|
|
7909
|
+
const adopted = {};
|
|
7910
|
+
for (const component of screen.components ?? []) {
|
|
7911
|
+
if (!PREHYDRATION_TEXT_TYPES.has(component.type))
|
|
7912
|
+
continue;
|
|
7913
|
+
for (const r of roots) {
|
|
7914
|
+
const input = Array.from(r.querySelectorAll("input[name]")).find((el) => el.name === component.id && el.type !== "hidden");
|
|
7915
|
+
// Adopt "" too: a prefilled default the user cleared before
|
|
7916
|
+
// hydration must not be restored by the client render.
|
|
7917
|
+
if (input) {
|
|
7918
|
+
adopted[component.id] = input.value;
|
|
7919
|
+
break;
|
|
7920
|
+
}
|
|
7921
|
+
}
|
|
7922
|
+
}
|
|
7923
|
+
if (Object.keys(adopted).length > 0) {
|
|
7924
|
+
this.formData = { ...this.formData, ...adopted };
|
|
7925
|
+
}
|
|
7926
|
+
}
|
|
7853
7927
|
/**
|
|
7854
7928
|
* Fetch screen configuration from the API
|
|
7855
7929
|
* @param screenIdOverride Optional screen ID to fetch (overrides this.screenId)
|
package/hydrate/index.mjs
CHANGED
|
@@ -7249,6 +7249,19 @@ const CHOICE_LIST_SEARCH_THRESHOLD = 5;
|
|
|
7249
7249
|
* (CARDS, FILE, RECAPTCHA, …) can carry `required` in the schema too, and
|
|
7250
7250
|
* gating on them would leave Continue disabled with no way to satisfy it.
|
|
7251
7251
|
*/
|
|
7252
|
+
/**
|
|
7253
|
+
* Field types rendered as a single plain text input whose value maps 1:1 to
|
|
7254
|
+
* formData. Composite fields (TEL, DATE) and choice/checkbox fields keep
|
|
7255
|
+
* internal state, so they're not adopted from pre-hydration markup.
|
|
7256
|
+
*/
|
|
7257
|
+
const PREHYDRATION_TEXT_TYPES = new Set([
|
|
7258
|
+
"TEXT",
|
|
7259
|
+
"EMAIL",
|
|
7260
|
+
"CODE",
|
|
7261
|
+
"PASSWORD",
|
|
7262
|
+
"NUMBER",
|
|
7263
|
+
"URL",
|
|
7264
|
+
]);
|
|
7252
7265
|
const FILLABLE_FIELD_TYPES = new Set([
|
|
7253
7266
|
"TEXT",
|
|
7254
7267
|
"EMAIL",
|
|
@@ -7629,7 +7642,21 @@ class AuthheroWidget {
|
|
|
7629
7642
|
* actually in the DOM before measuring its height.
|
|
7630
7643
|
*/
|
|
7631
7644
|
pendingRenderResolvers = [];
|
|
7645
|
+
/**
|
|
7646
|
+
* Number of `swapScreen` calls still running (rendering or animating the
|
|
7647
|
+
* card height). A counter rather than a flag because a newer swap can start
|
|
7648
|
+
* before a superseded one has settled.
|
|
7649
|
+
*/
|
|
7650
|
+
activeSwaps = 0;
|
|
7651
|
+
updateReadyAttribute() {
|
|
7652
|
+
}
|
|
7632
7653
|
componentDidRender() {
|
|
7654
|
+
// `data-ready` marks the widget as interactive: hydrated in the browser
|
|
7655
|
+
// (the SSR markup already carries Stencil's `hydrated` class, so that
|
|
7656
|
+
// can't tell server and client apart) and not mid-submit or mid-swap.
|
|
7657
|
+
// Stencil defers this hook until child nodes have rendered, so the
|
|
7658
|
+
// fields are live too. E2E tests wait on `authhero-widget[data-ready]`.
|
|
7659
|
+
this.updateReadyAttribute();
|
|
7633
7660
|
if (this.pendingRenderResolvers.length === 0)
|
|
7634
7661
|
return;
|
|
7635
7662
|
const resolvers = this.pendingRenderResolvers;
|
|
@@ -7677,6 +7704,18 @@ class AuthheroWidget {
|
|
|
7677
7704
|
apply();
|
|
7678
7705
|
return;
|
|
7679
7706
|
}
|
|
7707
|
+
// Hold `data-ready` off until the new screen has rendered and the height
|
|
7708
|
+
// animation has finished; `apply()` clears `loading` before either.
|
|
7709
|
+
this.activeSwaps++;
|
|
7710
|
+
try {
|
|
7711
|
+
await this.animateSwap(card, apply);
|
|
7712
|
+
}
|
|
7713
|
+
finally {
|
|
7714
|
+
this.activeSwaps--;
|
|
7715
|
+
this.updateReadyAttribute();
|
|
7716
|
+
}
|
|
7717
|
+
}
|
|
7718
|
+
async animateSwap(card, apply) {
|
|
7680
7719
|
// Lock the current height and clip, so swapping the content doesn't jump
|
|
7681
7720
|
// before the animation runs.
|
|
7682
7721
|
const startHeight = card.getBoundingClientRect().height;
|
|
@@ -7848,6 +7887,41 @@ class AuthheroWidget {
|
|
|
7848
7887
|
await this.fetchScreen(this.screenId);
|
|
7849
7888
|
}
|
|
7850
7889
|
}
|
|
7890
|
+
/**
|
|
7891
|
+
* Carry over text the user (or a password manager, or a test driver) put
|
|
7892
|
+
* into the server-rendered inputs before the client bundle loaded. Those
|
|
7893
|
+
* inputs had no `onInput` handler yet, so `formData` never saw the value:
|
|
7894
|
+
* the first client render would reset them to "" and keep the submit
|
|
7895
|
+
* button disabled. The declarative shadow roots are still the SSR ones
|
|
7896
|
+
* here — `componentWillLoad` runs before the first client render.
|
|
7897
|
+
*/
|
|
7898
|
+
adoptPrehydrationValues(screen) {
|
|
7899
|
+
const root = this.el.shadowRoot;
|
|
7900
|
+
if (!root)
|
|
7901
|
+
return;
|
|
7902
|
+
const roots = [root];
|
|
7903
|
+
root.querySelectorAll("authhero-node").forEach((node) => {
|
|
7904
|
+
if (node.shadowRoot)
|
|
7905
|
+
roots.push(node.shadowRoot);
|
|
7906
|
+
});
|
|
7907
|
+
const adopted = {};
|
|
7908
|
+
for (const component of screen.components ?? []) {
|
|
7909
|
+
if (!PREHYDRATION_TEXT_TYPES.has(component.type))
|
|
7910
|
+
continue;
|
|
7911
|
+
for (const r of roots) {
|
|
7912
|
+
const input = Array.from(r.querySelectorAll("input[name]")).find((el) => el.name === component.id && el.type !== "hidden");
|
|
7913
|
+
// Adopt "" too: a prefilled default the user cleared before
|
|
7914
|
+
// hydration must not be restored by the client render.
|
|
7915
|
+
if (input) {
|
|
7916
|
+
adopted[component.id] = input.value;
|
|
7917
|
+
break;
|
|
7918
|
+
}
|
|
7919
|
+
}
|
|
7920
|
+
}
|
|
7921
|
+
if (Object.keys(adopted).length > 0) {
|
|
7922
|
+
this.formData = { ...this.formData, ...adopted };
|
|
7923
|
+
}
|
|
7924
|
+
}
|
|
7851
7925
|
/**
|
|
7852
7926
|
* Fetch screen configuration from the API
|
|
7853
7927
|
* @param screenIdOverride Optional screen ID to fetch (overrides this.screenId)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@authhero/widget",
|
|
3
|
-
"version": "0.40.
|
|
3
|
+
"version": "0.40.3",
|
|
4
4
|
"description": "Server-Driven UI widget for AuthHero authentication flows",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"country-list": "^2.4.1",
|
|
45
|
-
"@authhero/adapter-interfaces": "4.
|
|
45
|
+
"@authhero/adapter-interfaces": "4.19.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@hono/node-server": "^1.19.14",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as t,c as e,g as i,h as o}from"./p-FUW5zvoZ.js";import{s as n}from"./p-Che3Wd7J.js";function r(t){const e=t.match(/^#([0-9a-f]{3})$/i)||t.match(/^#([0-9a-f]{6})$/i);if(!e)return null;let i=e[1];3===i.length&&(i=i[0]+i[0]+i[1]+i[1]+i[2]+i[2]);const o=parseInt(i,16);return[o>>16&255,o>>8&255,255&o]}function s(t){const e=r(t);if(!e)return NaN;const[i,o,n]=e.map((t=>{const e=t/255;return e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)}));return.2126*i+.7152*o+.0722*n}function a(t,e){const i=s(t),o=s(e);return isNaN(i)||isNaN(o)?NaN:(Math.max(i,o)+.05)/(Math.min(i,o)+.05)}function c(t,e="light"){const i=a(t,"#000000"),o=a(t,"#ffffff");return"light"===e?i>1.35*o?"#000000":"#ffffff":1.35*i>o?"#000000":"#ffffff"}function h(t,e){const i=r(t);if(!i)return t;const[o,n,s]=i,a=t=>Math.max(0,Math.round(t*(1-e))).toString(16).padStart(2,"0");return`#${a(o)}${a(n)}${a(s)}`}function l(t,e){const i=r(t);if(!i)return t;const[o,n,s]=i,a=t=>Math.min(255,Math.round(t+(255-t)*e)).toString(16).padStart(2,"0");return`#${a(o)}${a(n)}${a(s)}`}function d(t,e,i=4.5){if(a(t,e)>=i)return t;const o=s(e)>.5;let n=t;for(let r=1;r<=10;r++)if(n=o?h(t,.1*r):l(t,.1*r),a(n,e)>=i)return n;return o?"#000000":"#ffffff"}function f(t,e){if(void 0!==e)return`${e}px`;switch(t){case"pill":return"9999px";case"rounded":return"8px";case"sharp":return"0";default:return}}function u(t){if(!t)return{};const e={};if(t.colors?.primary&&(e["--ah-color-primary"]=t.colors.primary),t.colors?.page_background){const i=t.colors.page_background;"solid"===i.type&&i.start?e["--ah-page-bg"]=i.start:"gradient"===i.type&&i.start&&i.end&&(e["--ah-page-bg"]=`linear-gradient(${i.angle_deg??180}deg, ${i.start}, ${i.end})`)}return t.logo_url&&(e["--ah-logo-url"]=`url(${t.logo_url})`),t.font?.url&&(e["--ah-font-url"]=t.font.url),e}function p(t){if(!t)return{};const e={};if(t.borders){const i=t.borders;void 0!==i.widget_corner_radius&&(e["--ah-widget-radius"]=`${i.widget_corner_radius}px`),void 0!==i.widget_border_weight&&(e["--ah-widget-border-width"]=`${i.widget_border_weight}px`),!1===i.show_widget_shadow&&(e["--ah-widget-shadow"]="none");const o=f(i.buttons_style,i.button_border_radius);o&&(e["--ah-btn-radius"]=o),void 0!==i.button_border_weight&&(e["--ah-btn-border-width"]=`${i.button_border_weight}px`);const n=f(i.inputs_style,i.input_border_radius);n&&(e["--ah-input-radius"]=n),void 0!==i.input_border_weight&&(e["--ah-input-border-width"]=`${i.input_border_weight}px`)}if(t.colors){const i=t.colors;if(i.primary_button)if(e["--ah-color-primary"]=i.primary_button,i.primary_button_label)e["--ah-color-text-on-primary"]=i.primary_button_label;else{e["--ah-color-text-on-primary"]=c(i.primary_button,"light");const t=c(i.primary_button,"dark");t!==e["--ah-color-text-on-primary"]&&(e["--ah-color-text-on-primary-dark"]=t)}else i.primary_button_label&&(e["--ah-color-text-on-primary"]=i.primary_button_label);i.secondary_button_border&&(e["--ah-btn-secondary-border"]=i.secondary_button_border),i.secondary_button_label&&(e["--ah-btn-secondary-text"]=i.secondary_button_label),i.body_text&&(e["--ah-color-text"]=i.body_text),i.header&&(e["--ah-color-text-header"]=i.header),i.input_labels_placeholders&&(e["--ah-color-text-label"]=i.input_labels_placeholders,e["--ah-color-text-muted"]=i.input_labels_placeholders),i.input_filled_text&&(e["--ah-color-input-text"]=i.input_filled_text),i.widget_background&&(e["--ah-color-bg"]=i.widget_background),i.input_background&&(e["--ah-color-input-bg"]=i.input_background),i.widget_border&&(e["--ah-widget-border-color"]=i.widget_border),i.input_border&&(e["--ah-color-border"]=i.input_border),i.links_focused_components&&(e["--ah-color-link"]=d(i.links_focused_components,i.widget_background||"#ffffff")),i.base_focus_color&&(e["--ah-color-focus-ring"]=i.base_focus_color),i.base_hover_color&&(e["--ah-color-primary-hover"]=i.base_hover_color),i.error&&(e["--ah-color-error"]=i.error),i.success&&(e["--ah-color-success"]=i.success),i.icons&&(e["--ah-color-icon"]=i.icons);const o=i.widget_background||"#ffffff",n=i.input_background||o,r=e["--ah-color-border"]||i.input_border||"#c9cace",s=a(r,o),h=a(r,n);Math.min(s,h)<3&&(e["--ah-color-border"]=d(r,s<h?o:n,3))}if(t.fonts){const i=t.fonts,o=i.reference_text_size||16,n=t=>t>=50?Math.round(t/100*o):t;i.font_url&&(e["--ah-font-url"]=i.font_url),i.reference_text_size&&(e["--ah-font-size-base"]=`${i.reference_text_size}px`),i.title?.size&&(e["--ah-font-size-title"]=`${n(i.title.size)}px`),i.subtitle?.size&&(e["--ah-font-size-subtitle"]=`${n(i.subtitle.size)}px`),i.body_text?.size&&(e["--ah-font-size-body"]=`${n(i.body_text.size)}px`),i.input_labels?.size&&(e["--ah-font-size-label"]=`${n(i.input_labels.size)}px`),i.buttons_text?.size&&(e["--ah-font-size-btn"]=`${n(i.buttons_text.size)}px`),i.links?.size&&(e["--ah-font-size-link"]=`${n(i.links.size)}px`),"underlined"===i.links_style&&(e["--ah-link-decoration"]="underline"),void 0!==i.title?.bold&&(e["--ah-font-weight-title"]=i.title.bold?"700":"400"),void 0!==i.subtitle?.bold&&(e["--ah-font-weight-subtitle"]=i.subtitle.bold?"700":"400"),void 0!==i.body_text?.bold&&(e["--ah-font-weight-body"]=i.body_text.bold?"700":"400"),void 0!==i.input_labels?.bold&&(e["--ah-font-weight-label"]=i.input_labels.bold?"700":"400"),void 0!==i.buttons_text?.bold&&(e["--ah-font-weight-btn"]=i.buttons_text.bold?"600":"400"),void 0!==i.links?.bold&&(e["--ah-font-weight-link"]=i.links.bold?"700":"400")}if(t.widget){const i=t.widget;if(i.header_text_alignment&&(e["--ah-title-align"]=i.header_text_alignment),i.logo_height&&(e["--ah-logo-height"]=`${i.logo_height}px`),i.logo_position){const t={center:"center",left:"flex-start",right:"flex-end"};"none"===i.logo_position?e["--ah-logo-display"]="none":e["--ah-logo-align"]=t[i.logo_position]??"center"}i.social_buttons_layout&&("top"===i.social_buttons_layout?(e["--ah-social-order"]="0",e["--ah-divider-order"]="1",e["--ah-fields-order"]="2"):(e["--ah-social-order"]="2",e["--ah-divider-order"]="1",e["--ah-fields-order"]="0"))}if(t.page_background){const i=t.page_background;i.background_color&&(e["--ah-page-bg"]=i.background_color),i.background_image_url&&(e["--ah-page-bg-image"]=`url(${i.background_image_url})`)}return e}const g={br:[],em:[],i:[],strong:[],b:[],u:[],span:["class"],a:["href","class"]};function m(t){if(!t)return"";if(!t.includes("<"))return t;let e=t;e=e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'");for(const[t,i]of Object.entries(g)){if("br"===t){e=e.replace(/<br\s*\/?>/gi,"<br>");continue}const o=new RegExp(`<${t}((?:\\s+[a-z-]+(?:="[^&]*"|='[^&]*')?)*)\\s*>`,"gi");e=e.replace(o,((e,o)=>{const n=[];if(o){const t=o.replace(/"/g,'"').replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),e=/([a-z-]+)=["']([^"']*)["']/gi;let r;for(;null!==(r=e.exec(t));){const[,t,e]=r;t&&i.includes(t.toLowerCase())&&("href"===t.toLowerCase()?b(e||"")&&n.push(`${t}="${x(e||"")}"`):n.push(`${t}="${x(e||"")}"`))}}"a"===t&&(n.push('target="_blank"'),n.push('rel="noopener noreferrer"'));const r=n.length?" "+n.join(" "):"";return`<${t}${r}>`}));const n=new RegExp(`</${t}>`,"gi");e=e.replace(n,`</${t}>`)}return e}function b(t){if(!t)return!1;if(t.startsWith("/")||t.startsWith("#")||t.startsWith("?"))return!0;try{const e=new URL(t,"https://example.com");return"http:"===e.protocol||"https:"===e.protocol}catch{return!1}}function x(t){return t.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}const w=new Set(["TEXT","EMAIL","CODE","PASSWORD","NUMBER","TEL","URL","DATE","BOOLEAN","LEGAL","COUNTRY","DROPDOWN","CHOICE"]),v=class{constructor(i){t(this,i),this.formSubmit=e(this,"formSubmit"),this.buttonClick=e(this,"buttonClick"),this.linkClick=e(this,"linkClick"),this.navigate=e(this,"navigate"),this.flowComplete=e(this,"flowComplete"),this.flowError=e(this,"flowError"),this.screenChange=e(this,"screenChange")}get el(){return i(this)}screen;apiUrl;baseUrl;state;screenId;watchScreenId(){this.updateDataScreenAttribute()}authParams;statePersistence="memory";storageKey="authhero_widget";branding;theme;loading=!1;autoSubmit=!1;autoNavigate;locale;_screen;_authParams;_branding;_theme;formData={};listFilter="";conditionalMediationAbort;loadedFontUrl;formSubmit;buttonClick;linkClick;navigate;flowComplete;flowError;screenChange;watchScreen(t){if(this.conditionalMediationAbort?.abort(),this.conditionalMediationAbort=void 0,"string"==typeof t)try{this._screen=JSON.parse(t)}catch{console.error("Failed to parse screen JSON")}else this._screen=t;this._screen&&(this.formData={},this.listFilter="",this.initFormDataFromDefaults(this._screen),this.screenChange.emit(this._screen),this.updateDataScreenAttribute())}initFormDataFromDefaults(t){const e={};for(const i of t.components||[]){if(!("config"in i)||!i.config)continue;if(!("default_value"in i.config))continue;const t=i.config.default_value;"string"==typeof t&&""!==t?e[i.id]=t:"boolean"==typeof t&&(e[i.id]=t?"true":"false")}Object.keys(e).length>0&&(this.formData={...e,...this.formData})}updateDataScreenAttribute(){const t=this._screen?.name||this.screenId;t?this.el.setAttribute("data-screen",t):this.el.removeAttribute("data-screen");const e=this.el.closest("[data-authhero-widget-container]");e&&(t?e.setAttribute("data-screen",t):e.removeAttribute("data-screen"))}watchBranding(t){if("string"==typeof t)try{this._branding=JSON.parse(t)}catch{console.error("Failed to parse branding JSON")}else this._branding=t;this.applyThemeStyles()}watchTheme(t){if("string"==typeof t)try{this._theme=JSON.parse(t)}catch{console.error("Failed to parse theme JSON")}else this._theme=t;this.applyThemeStyles()}watchAuthParams(t){if("string"==typeof t)try{this._authParams=JSON.parse(t)}catch{console.error("Failed to parse authParams JSON")}else this._authParams=t}applyThemeStyles(){const t=(e=this._theme,{...u(this._branding),...p(e)});var e;!function(t,e){Object.entries(e).forEach((([e,i])=>{t.style.setProperty(e,i)}))}(this.el,t),this.loadCustomFont()}loadCustomFont(){if("undefined"==typeof document)return;const t=this._theme?.fonts?.font_url||this._branding?.font?.url;if(t===this.loadedFontUrl)return;for(const t of Array.from(document.head.querySelectorAll("link[data-authhero-font]")))t.remove();if(this.loadedFontUrl=void 0,!t)return;const e=document.createElement("link");e.rel="stylesheet",e.href=t,e.setAttribute("data-authhero-font",t),document.head.appendChild(e),this.loadedFontUrl=t}focusFirstInput(){requestAnimationFrame((()=>{const t=this.el.shadowRoot;if(!t)return;const e=t.querySelectorAll("authhero-node");for(const t of Array.from(e)){const e=t.shadowRoot;if(e){const t=e.querySelector('input:not([type="hidden"]):not([type="checkbox"]):not([disabled]), textarea:not([disabled])');if(t)return void t.focus()}}}))}pendingRenderResolvers=[];componentDidRender(){if(0===this.pendingRenderResolvers.length)return;const t=this.pendingRenderResolvers;this.pendingRenderResolvers=[],t.forEach((t=>t()))}nextRender(){return new Promise((t=>{let e=!1;const i=()=>{e||(e=!0,t())};this.pendingRenderResolvers.push(i),requestAnimationFrame((()=>requestAnimationFrame(i)))}))}async swapScreen(t){const e=this.el.shadowRoot?.querySelector(".widget-container"),i="function"==typeof window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches;if(!e||"function"!=typeof e.animate||i)return void t();const o=e.getBoundingClientRect().height;e.style.height=`${o}px`,e.style.overflow="hidden",t(),await this.nextRender();const n=()=>{e.style.height="",e.style.overflow=""};e.style.height="auto";const r=e.getBoundingClientRect().height;if(e.style.height=`${o}px`,e.getBoundingClientRect(),Math.abs(r-o)<1)return void n();const s=e.animate([{height:`${o}px`},{height:`${r}px`}],{duration:520,easing:"cubic-bezier(0.22, 1, 0.36, 1)"});try{await s.finished}catch{}finally{n()}}get shouldAutoNavigate(){return this.autoNavigate??this.autoSubmit}buildUrl(t){return this.baseUrl?new URL(t,this.baseUrl).toString():t}loadPersistedState(){if("url"===this.statePersistence){const t=new URL(window.location.href).searchParams.get("state");t&&!this.state&&(this.state=t)}else if("session"===this.statePersistence)try{const t=sessionStorage.getItem(`${this.storageKey}_state`);t&&!this.state&&(this.state=t);const e=sessionStorage.getItem(`${this.storageKey}_screenId`);e&&!this.screenId&&(this.screenId=e)}catch{}}persistState(){if("url"===this.statePersistence){const t=new URL(window.location.href);this.state&&t.searchParams.set("state",this.state),this.screenId&&t.searchParams.set("screen",this.screenId),window.history.replaceState({},"",t.toString())}else if("session"===this.statePersistence)try{this.state&&sessionStorage.setItem(`${this.storageKey}_state`,this.state),this.screenId&&sessionStorage.setItem(`${this.storageKey}_screenId`,this.screenId)}catch{}}handlePopState=t=>{if(!this.apiUrl)return;t.state?.state&&(this.state=t.state.state);const e=t.state?.screen??this.extractScreenIdFromHref(location.href);e&&this.fetchScreen(e)};connectedCallback(){window.addEventListener("popstate",this.handlePopState)}disconnectedCallback(){window.removeEventListener("popstate",this.handlePopState),this.conditionalMediationAbort?.abort(),this.conditionalMediationAbort=void 0}readJsonScript(t){if(!this.el)return;const e=this.el.querySelector(`script[type="application/json"][data-authhero="${t}"]`);return e?.textContent??void 0}async componentWillLoad(){if(!this._screen){const t=this.screen||this.readJsonScript("screen")||this.el?.getAttribute("screen");t&&this.watchScreen(t)}this._branding||this.watchBranding(this.branding??this.readJsonScript("branding")),this._theme||this.watchTheme(this.theme??this.readJsonScript("theme")),this._authParams||this.watchAuthParams(this.authParams??this.readJsonScript("auth-params")),this.loadPersistedState(),this.apiUrl&&!this._screen&&await this.fetchScreen(this.screenId)}async fetchScreen(t,e){if(!this.apiUrl)return!1;const i=t||this.screenId;let o=this.apiUrl;i&&o.includes("{screenId}")&&(o=o.replace("{screenId}",encodeURIComponent(i)));const n=new URL(o,this.baseUrl||window.location.origin);this.state&&n.searchParams.set("state",this.state),e&&n.searchParams.set("nodeId",e),this.loading=!0;try{const t=await fetch(this.buildUrl(n.pathname+n.search),{credentials:"include",headers:{Accept:"application/json"}});if(t.ok){const e=await t.json();if(e.screen?(this._screen=e.screen,e.branding&&(this._branding=e.branding,this.applyThemeStyles()),e.state&&(this.state=e.state),e.screenId&&(this.screenId=e.screenId)):this._screen=e,this._screen)return this.listFilter="",i&&i!==this.screenId&&(this.screenId=i),this.initFormDataFromDefaults(this._screen),this.screenChange.emit(this._screen),this.updateDataScreenAttribute(),this.persistState(),this.focusFirstInput(),e.ceremony&&this.performWebAuthnCeremony(e.ceremony),!0}else{const e=await t.json().catch((()=>({message:"Failed to load screen"})));this.flowError.emit({message:e.message||"Failed to load screen"})}}catch(t){console.error("Failed to fetch screen:",t),this.flowError.emit({message:t instanceof Error?t.message:"Failed to fetch screen"})}finally{this.loading=!1}return!1}handleInputChange=(t,e)=>{this.formData={...this.formData,[t]:e}};handleSubmit=async(t,e)=>{if(t.preventDefault(),!this._screen||this.loading)return;let i={...this.formData,...e||{}};const o=this.el.shadowRoot?.querySelector("form");if(o&&o.querySelectorAll('input[type="hidden"]').forEach((t=>{t.name&&t.value&&(i[t.name]=t.value)})),this.formSubmit.emit({screen:this._screen,data:i}),this.autoSubmit)if(this._screen.method&&"GET"!==this._screen.method.toUpperCase()){this.loading=!0;try{const t=await fetch(this.buildUrl(this._screen.action),{method:this._screen.method,credentials:"include",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({data:i})}),e=t.headers.get("content-type");if(e?.includes("text/html")){const e=await t.text();return document.open(),document.write(e),void document.close()}if(e?.includes("application/json")){const e=await t.json();if(e.redirect){this.flowComplete.emit({redirectUrl:e.redirect});const t=this.navigate.emit({url:e.redirect});this.shouldAutoNavigate&&!t.defaultPrevented&&(window.location.href=e.redirect)}else!t.ok&&e.screen?await this.swapScreen((()=>{this.loading=!1,this._screen=e.screen,this.listFilter="",this.initFormDataFromDefaults(e.screen),this.screenChange.emit(e.screen),this.updateDataScreenAttribute(),this.focusFirstInput()})):e.screen?await this.swapScreen((()=>{this.loading=!1,this._screen=e.screen,this.listFilter="",this.formData={},this.initFormDataFromDefaults(e.screen),this.screenChange.emit(e.screen),this.updateDataScreenAttribute(),e.screenId&&(this.screenId=e.screenId),this.persistState(),e.navigateUrl&&this.shouldAutoNavigate&&window.history.pushState({screen:e.screenId,state:this.state},"",e.navigateUrl),e.branding&&(this._branding=e.branding,this.applyThemeStyles()),e.state&&(this.state=e.state,this.persistState()),e.ceremony&&this.performWebAuthnCeremony(e.ceremony),this.focusFirstInput()})):e.complete?this.flowComplete.emit({}):!t.ok&&e.error&&(this._screen&&(this._screen={...this._screen,messages:[...this._screen.messages||[],{text:e.error,type:"error"}]}),this.flowError.emit({message:e.error}))}}catch(t){console.error("Form submission failed:",t),this.flowError.emit({message:t instanceof Error?t.message:"Form submission failed"})}finally{this.loading=!1}}else window.location.href=this.buildUrl(this._screen.action)};overrideFormSubmit(){const t=this.el.shadowRoot;if(!t)return;const e=t.querySelector("form");e&&(e.submit=()=>{const t=new FormData(e),i={};t.forEach(((t,e)=>{"string"==typeof t&&(i[e]=t)})),this.handleSubmit({preventDefault:()=>{}},i)})}performWebAuthnCeremony(t){this.isValidWebAuthnCeremony(t)?"webauthn-authentication-conditional"!==t.type?requestAnimationFrame((()=>{this.overrideFormSubmit(),"webauthn-authentication"===t.type?this.executeWebAuthnAuthentication(t):this.executeWebAuthnRegistration(t)})):this.executeWebAuthnConditionalMediation(t):console.error("Invalid WebAuthn ceremony payload",t)}isValidWebAuthnCeremony(t){if("object"!=typeof t||null===t)return!1;const e=t;if("string"!=typeof e.successAction)return!1;const i=e.options;if("object"!=typeof i||null===i)return!1;if("string"!=typeof i.challenge)return!1;if("webauthn-registration"===e.type){const t=i.rp;if("object"!=typeof t||null===t)return!1;if("string"!=typeof t.id||"string"!=typeof t.name)return!1;const e=i.user;return"object"==typeof e&&null!==e&&("string"==typeof e.id&&"string"==typeof e.name&&"string"==typeof e.displayName&&!!Array.isArray(i.pubKeyCredParams))}return"webauthn-authentication"===e.type||"webauthn-authentication-conditional"===e.type}async executeWebAuthnRegistration(t){const e=t.options,i=t=>{for(t=t.replace(/-/g,"+").replace(/_/g,"/");t.length%4;)t+="=";const e=atob(t),i=new Uint8Array(e.length);for(let t=0;t<e.length;t++)i[t]=e.charCodeAt(t);return i.buffer},o=t=>{const e=new Uint8Array(t);let i="";for(let t=0;t<e.length;t++)i+=String.fromCharCode(e[t]);return btoa(i).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")},n=()=>{const t=this.el?.shadowRoot;if(t){const e=t.querySelector("form");if(e)return e}return document.querySelector("form")};try{const r={challenge:i(e.challenge),rp:{id:e.rp.id,name:e.rp.name},user:{id:i(e.user.id),name:e.user.name,displayName:e.user.displayName},pubKeyCredParams:e.pubKeyCredParams.map((t=>({alg:t.alg,type:t.type}))),timeout:e.timeout,attestation:e.attestation||"none",authenticatorSelection:e.authenticatorSelection?{residentKey:e.authenticatorSelection.residentKey||"preferred",userVerification:e.authenticatorSelection.userVerification||"preferred"}:void 0};e.excludeCredentials?.length&&(r.excludeCredentials=e.excludeCredentials.map((t=>({id:i(t.id),type:t.type,transports:t.transports||[]}))));const s=await navigator.credentials.create({publicKey:r}),a=s.response,c={id:s.id,rawId:o(s.rawId),type:s.type,response:{attestationObject:o(a.attestationObject),clientDataJSON:o(a.clientDataJSON)},clientExtensionResults:s.getClientExtensionResults(),authenticatorAttachment:s.authenticatorAttachment||void 0};"function"==typeof a.getTransports&&(c.response.transports=a.getTransports());const h=n();if(h){const e=h.querySelector('[name="credential-field"]')||h.querySelector("#credential-field"),i=h.querySelector('[name="action-field"]')||h.querySelector("#action-field");e&&(e.value=JSON.stringify(c)),i&&(i.value=t.successAction),h.submit()}}catch(t){console.error("WebAuthn registration error:",t);const e=n();if(e){const t=e.querySelector('[name="action-field"]')||e.querySelector("#action-field");t&&(t.value="error"),e.submit()}}}async executeWebAuthnAuthentication(t){const e=t.options,i=t=>{for(t=t.replace(/-/g,"+").replace(/_/g,"/");t.length%4;)t+="=";const e=atob(t),i=new Uint8Array(e.length);for(let t=0;t<e.length;t++)i[t]=e.charCodeAt(t);return i.buffer},o=t=>{const e=new Uint8Array(t);let i="";for(let t=0;t<e.length;t++)i+=String.fromCharCode(e[t]);return btoa(i).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")},n=()=>{const t=this.el?.shadowRoot;if(t){const e=t.querySelector("form");if(e)return e}return document.querySelector("form")};try{const r={challenge:i(e.challenge),rpId:e.rpId,timeout:e.timeout,userVerification:e.userVerification||"preferred"};e.allowCredentials?.length&&(r.allowCredentials=e.allowCredentials.map((t=>({id:i(t.id),type:t.type,transports:t.transports||[]}))));const s=await navigator.credentials.get({publicKey:r}),a=s.response,c={id:s.id,rawId:o(s.rawId),type:s.type,response:{authenticatorData:o(a.authenticatorData),clientDataJSON:o(a.clientDataJSON),signature:o(a.signature)},clientExtensionResults:s.getClientExtensionResults(),authenticatorAttachment:s.authenticatorAttachment||void 0};a.userHandle&&(c.response.userHandle=o(a.userHandle));const h=n();if(h){const e=h.querySelector('[name="credential-field"]')||h.querySelector("#credential-field"),i=h.querySelector('[name="action-field"]')||h.querySelector("#action-field");e&&(e.value=JSON.stringify(c)),i&&(i.value=t.successAction),h.submit()}}catch(t){console.error("WebAuthn authentication error:",t);const e=n();if(e){const t=e.querySelector('[name="action-field"]')||e.querySelector("#action-field");t&&(t.value="error"),e.submit()}}}async executeWebAuthnConditionalMediation(t){if(!window.PublicKeyCredential||!PublicKeyCredential.isConditionalMediationAvailable)return;if(!await PublicKeyCredential.isConditionalMediationAvailable())return;this.conditionalMediationAbort?.abort();const e=new AbortController;this.conditionalMediationAbort=e;const i=t.options,o=t=>{for(t=t.replace(/-/g,"+").replace(/_/g,"/");t.length%4;)t+="=";const e=atob(t),i=new Uint8Array(e.length);for(let t=0;t<e.length;t++)i[t]=e.charCodeAt(t);return i.buffer},n=t=>{const e=new Uint8Array(t);let i="";for(let t=0;t<e.length;t++)i+=String.fromCharCode(e[t]);return btoa(i).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")};try{const r=await navigator.credentials.get({mediation:"conditional",signal:e.signal,publicKey:{challenge:o(i.challenge),rpId:i.rpId,timeout:i.timeout,userVerification:i.userVerification||"preferred"}}),s=r.response,a={id:r.id,rawId:n(r.rawId),type:r.type,response:{authenticatorData:n(s.authenticatorData),clientDataJSON:n(s.clientDataJSON),signature:n(s.signature)},clientExtensionResults:r.getClientExtensionResults(),authenticatorAttachment:r.authenticatorAttachment||void 0};s.userHandle&&(a.response.userHandle=n(s.userHandle)),this.formData["credential-field"]=JSON.stringify(a),this.formData["action-field"]=t.successAction,this.overrideFormSubmit();const c=this.el?.shadowRoot,h=c?.querySelector("form");if(h){const e=h.querySelector('[name="credential-field"]')||h.querySelector("#credential-field"),i=h.querySelector('[name="action-field"]')||h.querySelector("#action-field");e&&(e.value=JSON.stringify(a)),i&&(i.value=t.successAction),h.submit()}}catch(t){if("AbortError"===t?.name||"NotAllowedError"===t?.name)return;console.error("Conditional mediation error:",t)}}handleButtonClick=t=>{if("submit"!==t.type)if(this.buttonClick.emit(t),"SOCIAL"===t.type&&t.value&&this.shouldAutoNavigate){const e=this.getProviderHref(t.value);if(e){const t=this.extractScreenIdFromHref(e);return void(t&&this.apiUrl?this.navigateToScreen(t,e):window.location.href=e)}this.handleSocialLogin(t.value)}else"RESEND_BUTTON"===t.type&&this.shouldAutoNavigate&&this.handleResend();else{const e=this._screen?.components?.find((e=>e.id===t.id));if(this._screen&&("NEXT_BUTTON"!==e?.type||!0!==e.config?.skip_validation)&&this.hasUnfilledRequiredFields(this._screen))return;if((!this._screen?.method||"GET"===this._screen.method.toUpperCase())&&this._screen?.action)return void(window.location.href=this.buildUrl(this._screen.action));const i={...this.formData,[t.id]:"true"};this.formData=i,this.handleSubmit({preventDefault:()=>{}},i)}};handleSocialLogin(t){const e=this._authParams||{},i={connection:t};this.state?i.state=this.state:e.state&&(i.state=e.state),e.client_id&&(i.client_id=e.client_id),e.redirect_uri&&(i.redirect_uri=e.redirect_uri),e.scope&&(i.scope=e.scope),e.audience&&(i.audience=e.audience),e.nonce&&(i.nonce=e.nonce),e.response_type&&(i.response_type=e.response_type);const o=this.buildUrl("/authorize?"+new URLSearchParams(i).toString());this.navigate.emit({url:o}).defaultPrevented||(window.location.href=o)}async handleResend(){if(this._screen?.action)try{const t=this._screen.action+(this._screen.action.includes("?")?"&":"?")+"action=resend";await fetch(this.buildUrl(t),{method:"POST",credentials:"include"})}catch(t){console.error("Resend failed:",t)}}extractScreenIdFromHref(t){try{const e=new URL(t,window.location.origin).pathname,i=e.match(/\/u2\/login\/([^/]+)$/);if(i)return i[1];const o=e.match(/\/u2\/([^/]+)$/);return o&&"login"!==o[1]&&"screen"!==o[1]?o[1]:null}catch{return null}}handleLinkClick=(t,e)=>{if(this.linkClick.emit({id:e.id,href:e.href,text:e.text}),!this.shouldAutoNavigate)return void t.preventDefault();const i=this.extractScreenIdFromHref(e.href);return i&&this.apiUrl?(t.preventDefault(),void this.navigateToScreen(i,e.href)):void 0};async navigateToScreen(t,e){await this.fetchScreen(t)?window.history.pushState({screen:t,state:this.state},"",e):window.location.href=e}getProviderHref(t){if(!this._screen)return null;for(const e of this._screen.components){const i=e;if("SOCIAL"===i.type&&i.config?.provider_details){const e=i.config.provider_details.find((e=>e.name===t));if(e?.href)return e.href}}return null}isSocialComponent(t){return"SOCIAL"===t.type}isDividerComponent(t){return"DIVIDER"===t.type}isRequiredFieldFilled(t){const e=this.formData[t.id];return"BOOLEAN"===t.type||"LEGAL"===t.type?"true"===e:"string"==typeof e&&""!==e.trim()}hasUnfilledRequiredFields(t){return(t.components??[]).some((t=>!1!==t.visible&&"required"in t&&!0===t.required&&w.has(t.type)&&!this.isRequiredFieldFilled(t)))}getChoiceButtonText(t){const e=t.config;return e?.text??""}render(){const t=this._screen;if(this.loading&&!t)return o("div",{class:"widget-container"},o("div",{class:"loading-spinner"}));if(!t)return o("div",{class:"widget-container"},o("div",{class:"error-message"},"No screen configuration provided"));const e=t.messages?.filter((t=>"error"===t.type))||[],i=t.messages?.filter((t=>"success"===t.type))||[],r=[...t.components??[]],s=r.filter((t=>!1!==t.visible)).sort(((t,e)=>(t.order??0)-(e.order??0))),a=r.filter((t=>!1===t.visible)),c=s.filter((t=>this.isSocialComponent(t))),h=c.length>0?s.find((t=>this.isDividerComponent(t))):void 0,l=s.filter((t=>!this.isSocialComponent(t)&&t!==h)),d=!!h,f=h?.config?.text||"Or",u=l.filter((t=>"NEXT_BUTTON"===t.type)),p=u.length===l.length&&u.length>5,g=this.hasUnfilledRequiredFields(t),b=this.listFilter.trim().toLowerCase(),x=p&&b?u.filter((t=>this.getChoiceButtonText(t).toLowerCase().includes(b))):u,w=t=>{const e=t.config;return["social-buttons","button","button-secondary","button-social","button-social-content","button-social-text","button-social-text-short","button-social-subtitle","button-social-badge","social-icon",...(e?.providers??[]).flatMap((t=>{const e=n(t);return[`button-social-${e}`,`button-social-content-${e}`,`button-social-text-${e}`,`button-social-text-short-${e}`,`button-social-subtitle-${e}`,`button-social-badge-${e}`,`social-icon-${e}`]}))].join(", ")},v=this._theme?.widget?.logo_url||this._branding?.logo_url;return o("div",{class:"widget-container",part:"container","data-authstack-container":!0},o("header",{class:"widget-header",part:"header"},v&&o("div",{class:"logo-wrapper",part:"logo-wrapper"},o("img",{class:"logo",part:"logo",src:v,alt:"Logo"})),t.title&&o("h1",{class:"title",part:"title",innerHTML:m(t.title)}),t.description&&o("p",{class:"description",part:"description",innerHTML:m(t.description)})),o("div",{class:"widget-body",part:"body"},e.map((t=>o("div",{class:"message message-error",part:"message message-error",key:t.id??t.text},t.text))),i.map((t=>o("div",{class:"message message-success",part:"message message-success",key:t.id??t.text},t.text))),o("form",{onSubmit:this.handleSubmit,action:t.action,method:t.method||"POST",part:"form"},a.map((t=>o("input",{type:"hidden",name:t.id,id:t.id,key:t.id,value:this.formData[t.id]||""}))),o("div",{class:"form-content"},c.length>0&&o("div",{class:"social-section",part:"social-section"},c.map((t=>o("authhero-node",{key:t.id,component:t,locale:this.locale,value:this.formData[t.id],onFieldChange:t=>this.handleInputChange(t.detail.id,t.detail.value),onButtonClick:t=>this.handleButtonClick(t.detail),disabled:this.loading,exportparts:w(t)})))),c.length>0&&l.length>0&&d&&o("div",{class:"divider",part:"divider"},o("span",{class:"divider-text"},f)),o("div",{class:"fields-section",part:"fields-section"},p&&o("input",{type:"text",class:"choice-list-search",part:"choice-list-search",placeholder:"Search","aria-label":"Search",autocomplete:"off",value:this.listFilter,onInput:t=>this.listFilter=t.target.value,onKeyDown:t=>{"Enter"===t.key&&t.preventDefault()}}),o("div",{class:p?"fields-list fields-list-scroll":"fields-list",part:p?"fields-list fields-list-scroll":"fields-list"},(p?x:l).map((t=>o("authhero-node",{key:t.id,component:t,locale:this.locale,value:this.formData[t.id],onFieldChange:t=>this.handleInputChange(t.detail.id,t.detail.value),onButtonClick:t=>this.handleButtonClick(t.detail),disabled:this.loading||"NEXT_BUTTON"===t.type&&!0!==t.config?.skip_validation&&g}))),p&&0===x.length&&o("div",{class:"choice-list-empty",part:"choice-list-empty"},"No matches"))))),t.links&&t.links.length>0&&o("div",{class:"links",part:"links"},t.links.map((t=>o("span",{class:"link-wrapper",part:"link-wrapper",key:t.id??t.href},t.linkText?o("span",null,t.text," ",o("a",{href:t.href,class:"link",part:"link",onClick:e=>this.handleLinkClick(e,{id:t.id,href:t.href,text:t.linkText||t.text})},t.linkText)):o("a",{href:t.href,class:"link",part:"link",onClick:e=>this.handleLinkClick(e,{id:t.id,href:t.href,text:t.text})},t.text))))),t.footer&&o("div",{class:"widget-footer",part:"footer",innerHTML:m(t.footer)})))}static get watchers(){return{screenId:[{watchScreenId:0}],screen:[{watchScreen:0}],branding:[{watchBranding:0}],theme:[{watchTheme:0}],authParams:[{watchAuthParams:0}]}}};v.style=':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{width:var(--ah-widget-max-width, 400px);margin:0 auto;background-color:var(--ah-color-bg, #ffffff);border-radius:var(--ah-widget-radius, 5px);border:var(--ah-widget-border-width, 0) solid var(--ah-widget-border-color, transparent);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-text-header, var(--ah-color-header, #1e212a));line-height:1.2}.description{font-size:var(--ah-font-size-subtitle, 16px);font-weight:var(--ah-font-weight-subtitle, 400);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)}.fields-list{display:flex;flex-direction:column}.fields-list-scroll{max-height:var(--ah-choice-list-max-height, 320px);overflow-y:auto;gap:var(--ah-choice-list-gap, 8px);padding-right:4px}.choice-list-search{width:100%;padding:16px;margin-bottom:12px;font-size:16px;font-family:inherit;color:var(--ah-color-input-text, var(--ah-color-text, #1e212a));background-color:var(--ah-color-input-bg, #ffffff);border:var(--ah-input-border-width, 1px) solid var(--ah-color-border, #c9cace);border-radius:var(--ah-input-radius, 3px);outline:none;box-sizing:border-box;transition:border-color 0.15s ease-out, box-shadow 0.15s ease-out}.choice-list-search:hover{border-color:var(--ah-color-border-hover, #65676e)}.choice-list-search:focus{border-color:var(--ah-color-primary, var(--ah-color-link, #635dff))}.choice-list-empty{padding:16px;text-align:center;font-size:14px;color:var(--ah-color-text-muted, #65676e)}.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:var(--ah-font-size-body, 14px);font-weight:var(--ah-font-weight-body, 400);color:var(--ah-color-text, #1e212a)}.link{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:var(--ah-font-size-link, 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-focus-ring, 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-focus-ring, 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(:not([floating])){display:block;width:100%;min-height:100vh;background-color:var(--ah-color-bg, #ffffff)}:host(:not([floating])) .widget-container{box-shadow:none;border-radius:0;border:0;width:100%;margin:0}:host([floating]) .widget-container{width:100%;margin:0}.widget-header{padding:24px 16px 16px}.widget-body{padding:0 16px 24px}}';export{v as authhero_widget}
|