@authhero/widget 0.32.41 → 0.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authhero-widget/authhero-widget.esm.js +1 -1
- package/dist/authhero-widget/{p-aa120307.entry.js → p-1fc7fcdb.entry.js} +1 -1
- package/dist/authhero-widget/p-5a319adc.entry.js +1 -0
- package/dist/cjs/authhero-node.cjs.entry.js +1 -1
- package/dist/cjs/authhero-widget.cjs.entry.js +174 -39
- package/dist/collection/components/authhero-node/authhero-node.css +27 -24
- package/dist/collection/components/authhero-widget/authhero-widget.css +8 -5
- package/dist/collection/components/authhero-widget/authhero-widget.js +171 -35
- package/dist/collection/utils/branding.js +2 -3
- package/dist/components/authhero-node.js +1 -1
- package/dist/components/authhero-widget.js +1 -1
- package/dist/components/{p-Bwng5l4l.js → p-BzbxtmOP.js} +1 -1
- package/dist/esm/authhero-node.entry.js +1 -1
- package/dist/esm/authhero-widget.entry.js +174 -39
- package/dist/types/components/authhero-widget/authhero-widget.d.ts +39 -0
- package/hydrate/index.js +175 -40
- package/hydrate/index.mjs +175 -40
- package/package.json +1 -1
- package/dist/authhero-widget/p-35c8b265.entry.js +0 -1
package/hydrate/index.js
CHANGED
|
@@ -5500,7 +5500,7 @@ function getCountryByCode(code) {
|
|
|
5500
5500
|
countries.find((c) => c.code === "US"));
|
|
5501
5501
|
}
|
|
5502
5502
|
|
|
5503
|
-
const authheroNodeCss = () => `:host{display:block}.input-wrapper{display:flex;flex-direction:column;position:relative;margin-top:8px;margin-bottom:16px}.input-container{position:relative;width:100%}.input-label{position:absolute;left:16px;top:50%;transform:translateY(-50%);font-size:16px;font-weight:var(--ah-font-weight-label, 400);color:var(--ah-color-text-muted, #65676e);pointer-events:none;transition:all 0.15s ease-out;background-color:transparent;padding:0;z-index:1}.input-label.floating,.input-field:focus+.input-label,.input-field:not(:placeholder-shown)+.input-label,select.input-field+.input-label,input[type="date"].input-field+.input-label{top:-8px;transform:translateY(0);font-size:12px;background-color:var(--ah-color-bg, #ffffff);padding:0 4px;left:12px;color:var(--ah-color-text-muted, #65676e)}.input-field:focus+.input-label{color:var(--ah-color-primary, #635dff)}.required{color:var(--ah-color-error, #d03c38);margin-left:2px}.input-field{width:100%;padding:16px;font-size:16px;font-family:inherit;color:var(--ah-color-text, #1e212a);background-color:var(--ah-color-input-bg, #ffffff);border:1px solid var(--ah-color-border, #c9cace);border-radius:var(--ah-input-radius, 3px);outline:none;transition:border-color 0.15s ease-out, box-shadow 0.15s ease-out;box-sizing:border-box}.input-field::placeholder{color:transparent}.input-field:hover{border-color:var(--ah-color-border-hover, #65676e)}.input-field:focus{border-color:var(--ah-color-primary, #635dff);box-shadow:inset 0 0 0 1px var(--ah-color-primary, #635dff)}.input-field.has-error{border-color:var(--ah-color-error, #d03c38)}.input-field.has-error:focus{box-shadow:inset 0 0 0 1px var(--ah-color-error, #d03c38)}.input-field:disabled{background-color:var(--ah-color-bg-disabled, #f5f5f5);border-color:var(--ah-color-border-disabled, #e0e1e3);cursor:not-allowed;opacity:0.7}.password-container{position:relative;display:flex;align-items:center}.password-container .input-field{padding-right:48px}.password-toggle{position:absolute;right:12px;top:50%;transform:translateY(-50%);background:none;border:none;cursor:pointer;padding:4px;display:flex;align-items:center;justify-content:center;color:var(--ah-color-text-muted, #65676e);transition:color 0.15s ease}.password-toggle:hover{color:var(--ah-color-text, #1e212a)}.password-toggle svg{width:20px;height:20px}.error-text{font-size:12px;color:var(--ah-color-error, #d03c38);margin-top:4px;line-height:1.4}.helper-text{font-size:12px;color:var(--ah-color-text-muted, #65676e);margin-top:4px;line-height:1.4}.field-link{display:block;text-align:left;margin-top:8px;margin-bottom:16px}.field-link a{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:14px;font-weight:var(--ah-font-weight-link, 400)}.field-link a:hover{text-decoration:underline}.checkbox-wrapper{display:flex;align-items:flex-start;gap:10px;cursor:pointer;margin-bottom:16px}.checkbox-wrapper input[type="checkbox"]{width:18px;height:18px;margin:0;accent-color:var(--ah-color-primary, #635dff);cursor:pointer;flex-shrink:0}.checkbox-label{font-size:14px;color:var(--ah-color-text, #1e212a);line-height:1.5}.btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;width:100%;padding:14px 20px;font-size:16px;font-weight:var(--ah-font-weight-btn, 400);font-family:inherit;line-height:1.25;text-align:center;text-decoration:none;border:none;border-radius:var(--ah-btn-radius, 3px);cursor:pointer;transition:background-color 0.15s ease, border-color 0.15s ease, transform 0.1s ease;box-sizing:border-box}.btn:disabled{opacity:0.6;cursor:not-allowed}.btn:not(:disabled):active{transform:scale(0.98)}.btn:focus-visible{outline:2px solid var(--ah-color-primary, #635dff);outline-offset:2px}.btn-primary{background-color:var(--ah-color-primary, #635dff);color:var(--ah-color-text-on-primary, #ffffff);margin-top:12px}.btn-primary:not(:disabled):hover{
|
|
5503
|
+
const authheroNodeCss = () => `:host{display:block}.input-wrapper{display:flex;flex-direction:column;position:relative;margin-top:8px;margin-bottom:16px}.input-container{position:relative;width:100%}.input-label{position:absolute;left:16px;top:50%;transform:translateY(-50%);font-size:var(--ah-font-size-label, 16px);font-weight:var(--ah-font-weight-label, 400);color:var(--ah-color-text-muted, #65676e);pointer-events:none;transition:all 0.15s ease-out;background-color:transparent;padding:0;z-index:1}.input-label.floating,.input-field:focus+.input-label,.input-field:not(:placeholder-shown)+.input-label,select.input-field+.input-label,input[type="date"].input-field+.input-label{top:-8px;transform:translateY(0);font-size:12px;background-color:var(--ah-color-bg, #ffffff);padding:0 4px;left:12px;color:var(--ah-color-text-muted, #65676e)}.input-field:focus+.input-label{color:var(--ah-color-primary, #635dff)}.required{color:var(--ah-color-error, #d03c38);margin-left:2px}.input-field{width:100%;padding:16px;font-size:16px;font-family:inherit;color:var(--ah-color-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;transition:border-color 0.15s ease-out, box-shadow 0.15s ease-out;box-sizing:border-box}.input-field::placeholder{color:transparent}.input-field:hover{border-color:var(--ah-color-border-hover, #65676e)}.input-field:focus{border-color:var(--ah-color-primary, #635dff);box-shadow:inset 0 0 0 1px var(--ah-color-primary, #635dff)}.input-field.has-error{border-color:var(--ah-color-error, #d03c38)}.input-field.has-error:focus{box-shadow:inset 0 0 0 1px var(--ah-color-error, #d03c38)}.input-field:disabled{background-color:var(--ah-color-bg-disabled, #f5f5f5);border-color:var(--ah-color-border-disabled, #e0e1e3);cursor:not-allowed;opacity:0.7}.password-container{position:relative;display:flex;align-items:center}.password-container .input-field{padding-right:48px}.password-toggle{position:absolute;right:12px;top:50%;transform:translateY(-50%);background:none;border:none;cursor:pointer;padding:4px;display:flex;align-items:center;justify-content:center;color:var(--ah-color-icon, var(--ah-color-text-muted, #65676e));transition:color 0.15s ease}.password-toggle:hover{color:var(--ah-color-icon, var(--ah-color-text, #1e212a))}.password-toggle svg{width:20px;height:20px}.error-text{font-size:12px;color:var(--ah-color-error, #d03c38);margin-top:4px;line-height:1.4}.helper-text{font-size:12px;color:var(--ah-color-text-muted, #65676e);margin-top:4px;line-height:1.4}.field-link{display:block;text-align:left;margin-top:8px;margin-bottom:16px}.field-link a{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:var(--ah-font-size-link, 14px);font-weight:var(--ah-font-weight-link, 400)}.field-link a:hover{text-decoration:underline}.checkbox-wrapper{display:flex;align-items:flex-start;gap:10px;cursor:pointer;margin-bottom:16px}.checkbox-wrapper input[type="checkbox"]{width:18px;height:18px;margin:0;accent-color:var(--ah-color-primary, #635dff);cursor:pointer;flex-shrink:0}.checkbox-label{font-size:var(--ah-font-size-body, 14px);font-weight:var(--ah-font-weight-body, 400);color:var(--ah-color-text, #1e212a);line-height:1.5}.btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;width:100%;padding:14px 20px;font-size:var(--ah-font-size-btn, 16px);font-weight:var(--ah-font-weight-btn, 400);font-family:inherit;line-height:1.25;text-align:center;text-decoration:none;border:none;border-radius:var(--ah-btn-radius, 3px);cursor:pointer;transition:background-color 0.15s ease, border-color 0.15s ease, transform 0.1s ease;box-sizing:border-box}.btn:disabled{opacity:0.6;cursor:not-allowed}.btn:not(:disabled):active{transform:scale(0.98)}.btn:focus-visible{outline:2px solid var(--ah-color-focus-ring, var(--ah-color-primary, #635dff));outline-offset:2px}.btn-primary{background-color:var(--ah-color-primary, #635dff);color:var(--ah-color-text-on-primary, #ffffff);margin-top:12px}.btn-primary:not(:disabled):hover{background-color:var(--ah-color-primary-hover, color-mix(in srgb, var(--ah-color-primary, #635dff) 85%, black))}.btn-secondary{background-color:var(--ah-color-bg, #ffffff);color:var(--ah-btn-secondary-text, var(--ah-color-text, #1e212a));border:var(--ah-btn-border-width, 1px) solid var(--ah-btn-secondary-border, var(--ah-color-border, #c9cace))}.btn-secondary:not(:disabled):hover{background-color:var(--ah-color-bg-hover, #f5f5f5);border-color:var(--ah-color-border-hover, #65676e)}.btn-link{background:none;border:none;color:var(--ah-color-link, #635dff);padding:8px 0;font-weight:var(--ah-font-weight-link, 400);text-decoration:none}.btn-link:hover{text-decoration:underline}.phone-input-wrapper{display:flex;align-items:stretch;gap:0;width:100%}.country-select{flex-shrink:0;width:auto;padding:12px 8px;font-size:var(--ah-font-size-body, 16px);font-family:var(--ah-font-family, inherit);border:var(--ah-input-border-width, 1px) solid var(--ah-color-border, #c9cace);border-right:none;border-radius:var(--ah-input-radius, 4px) 0 0 var(--ah-input-radius, 4px);background-color:var(--ah-color-input-bg, var(--ah-color-surface, #fff));color:var(--ah-color-input-text, var(--ah-color-text, #1e212a));cursor:pointer;appearance:none;-webkit-appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 6px center;padding-right:22px}.country-select:focus{outline:none;border-color:var(--ah-color-primary, #635dff);box-shadow:0 0 0 1px var(--ah-color-primary, #635dff)}.country-select:disabled{opacity:0.5;cursor:not-allowed}.phone-input-wrapper .input-container{flex:1;min-width:0}.phone-input-wrapper .input-field{border-radius:0 var(--ah-input-radius, 4px) var(--ah-input-radius, 4px) 0}.phone-input-wrapper .input-label.floating,.phone-input-wrapper .input-field:focus+.input-label,.phone-input-wrapper .input-field:not(:placeholder-shown)+.input-label{left:8px}.social-buttons{display:flex;flex-direction:column;gap:12px}.btn-social{display:flex;align-items:center;justify-content:center;gap:12px}.btn-social-content{display:flex;flex-direction:column;align-items:center;text-align:center}.btn-social-subtitle{font-size:12px;font-style:italic;opacity:0.8;margin-top:2px}.btn-social-subtitle:empty{display:none}.social-icon{width:20px;height:20px;flex-shrink:0}@media (max-width: 480px){.social-buttons:has(.btn-social:nth-child(3)){flex-direction:row;flex-wrap:nowrap;justify-content:stretch;gap:8px}.social-buttons:has(.btn-social:nth-child(3)) .btn-social{width:auto;min-width:0;padding:12px;flex:1 1 0}.social-buttons:has(.btn-social:nth-child(3)) .btn-social span{display:none}.social-buttons:has(.btn-social:nth-child(3)) .social-icon{width:24px;height:24px}}.btn-icon{width:20px;height:20px;flex-shrink:0}.btn-icon img{width:100%;height:100%;object-fit:contain}.text-title{font-size:var(--ah-font-size-title, 20px);font-weight:var(--ah-font-weight-title, 400);color:var(--ah-color-text-header, var(--ah-color-header, #1e212a));margin:8px 0;line-height:1.3}.text-title.text-success{color:var(--ah-color-success, #13a769)}.text-description{font-size:var(--ah-font-size-subtitle, 14px);font-weight:var(--ah-font-weight-subtitle, 400);color:var(--ah-color-text-muted, #65676e);margin:4px 0;line-height:1.5}.image{display:block;max-width:100%;height:auto;border-radius:4px}.image-centered{margin:0 auto 16px;width:52px;height:52px;object-fit:contain}.link{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:var(--ah-font-size-link, 14px);transition:color 0.15s 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}.node-error{padding:12px 16px;background-color:var(--ah-color-error-bg, #ffeaea);color:var(--ah-color-error, #d03c38);border-left:3px solid var(--ah-color-error, #d03c38);border-radius:0;font-size:14px;margin-bottom:16px}.node-success{padding:12px 16px;background-color:var(--ah-color-success-bg, #e6f9f1);color:var(--ah-color-success, #13a769);border-left:3px solid var(--ah-color-success, #13a769);border-radius:0;font-size:14px;margin-bottom:16px}.divider{display:flex;align-items:center;text-align:center;margin:16px 0}.divider::before,.divider::after{content:"";flex:1;border-bottom:1px solid var(--ah-color-border-muted, #c9cace)}.divider-text{padding:0 10px;font-size:12px;font-weight:400;color:var(--ah-color-text-muted, #65676e);text-transform:uppercase;letter-spacing:0.5px}.rich-text{font-size:var(--ah-font-size-body, 14px);font-weight:var(--ah-font-weight-body, 400);line-height:1.5;color:var(--ah-color-text, #1e212a)}.rich-text a{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);transition:color 0.15s ease}.rich-text a:hover{text-decoration:underline}.rich-text .terms-text{margin-top:16px;text-align:center;font-size:12px;color:var(--ah-color-text-muted, #65676e)}.rich-text .terms-text a{font-size:12px}.rich-text .forgot-password-link{text-align:right;font-size:13px;margin-top:4px}.rich-text .forgot-password-link a{font-size:13px;color:var(--ah-color-link, #635dff)}.rich-text .passwordless-link{margin-top:16px;text-align:center;font-size:14px}.rich-text .passwordless-link a{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none)}.rich-text .passwordless-link a:hover{text-decoration:underline}.rich-text .signup-link{margin-top:16px;text-align:center;font-size:14px;color:var(--ah-color-text, #1e212a)}`;
|
|
5504
5504
|
|
|
5505
5505
|
class AuthheroNode {
|
|
5506
5506
|
constructor(hostRef) {
|
|
@@ -6208,8 +6208,8 @@ function brandingToCssVars(branding) {
|
|
|
6208
6208
|
// Primary color
|
|
6209
6209
|
if (branding.colors?.primary) {
|
|
6210
6210
|
vars["--ah-color-primary"] = branding.colors.primary;
|
|
6211
|
-
//
|
|
6212
|
-
|
|
6211
|
+
// Hover variant is derived in CSS (color-mix darken) unless the theme
|
|
6212
|
+
// sets an explicit base_hover_color; don't pin it to the base color here.
|
|
6213
6213
|
}
|
|
6214
6214
|
// Page background
|
|
6215
6215
|
if (branding.colors?.page_background) {
|
|
@@ -6276,7 +6276,6 @@ function themeToCssVars(theme) {
|
|
|
6276
6276
|
// Primary button
|
|
6277
6277
|
if (c.primary_button) {
|
|
6278
6278
|
vars["--ah-color-primary"] = c.primary_button;
|
|
6279
|
-
vars["--ah-color-primary-hover"] = c.primary_button;
|
|
6280
6279
|
// Honor explicit primary_button_label when set; otherwise auto-pick.
|
|
6281
6280
|
if (c.primary_button_label) {
|
|
6282
6281
|
vars["--ah-color-text-on-primary"] = c.primary_button_label;
|
|
@@ -6620,7 +6619,7 @@ function escapeAttr(value) {
|
|
|
6620
6619
|
.replace(/>/g, ">");
|
|
6621
6620
|
}
|
|
6622
6621
|
|
|
6623
|
-
const authheroWidgetCss = () => `:host{display:block;font-family:var(--ah-font-family, 'ulp-font', -apple-system, BlinkMacSystemFont, Roboto, Helvetica, sans-serif);font-size:var(--ah-font-size-base, 16px);line-height:var(--ah-line-height-base, 1.5);color:var(--ah-color-text, #1e212a);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.widget-container{width:var(--ah-widget-max-width, 400px);margin:0 auto;background-color:var(--ah-color-bg, #ffffff);border-radius:var(--ah-widget-radius, 5px);box-shadow:var(--ah-widget-shadow, 0 4px 22px 0 rgba(0, 0, 0, 0.11));box-sizing:border-box}.widget-header{padding:var(--ah-header-padding, 40px 48px 24px)}.widget-body{padding:var(--ah-body-padding, 0 48px 40px)}.logo-wrapper{display:var(--ah-logo-display, flex);justify-content:var(--ah-logo-align, center);margin-bottom:8px}.logo{display:block;height:var(--ah-logo-height, 52px);max-width:100%;width:auto;object-fit:contain}.title{font-size:var(--ah-font-size-title, 24px);font-weight:var(--ah-font-weight-title, 700);text-align:var(--ah-title-align, center);margin:var(--ah-title-margin, 24px 0 24px);color:var(--ah-color-header, #1e212a);line-height:1.2}.description{font-size:var(--ah-font-size-subtitle, 16px);text-align:var(--ah-title-align, center);margin:var(--ah-description-margin, 0 0 8px);color:var(--ah-color-text, #1e212a);line-height:1.5}.message{padding:12px 16px;border-radius:4px;margin-bottom:16px;font-size:14px;line-height:1.5}.message-error{background-color:var(--ah-color-error-bg, #ffeaea);color:var(--ah-color-error, #d03c38);border-left:3px solid var(--ah-color-error, #d03c38)}.message-success{background-color:var(--ah-color-success-bg, #e6f9f1);color:var(--ah-color-success, #13a769);border-left:3px solid var(--ah-color-success, #13a769)}form{display:flex;flex-direction:column}.form-content{display:flex;flex-direction:column}.social-section{display:flex;flex-direction:column;gap:8px;order:var(--ah-social-order, 2)}.fields-section{display:flex;flex-direction:column;order:var(--ah-fields-order, 0)}.divider{display:flex;align-items:center;text-align:center;margin:16px 0;order:var(--ah-divider-order, 1)}.divider::before,.divider::after{content:'';flex:1;border-bottom:1px solid var(--ah-color-border-muted, #c9cace)}.divider-text{padding:0 10px;font-size:12px;font-weight:400;color:var(--ah-color-text-muted, #65676e);text-transform:uppercase;letter-spacing:0}.links{display:flex;flex-direction:column;align-items:center;gap:8px;margin-top:16px}.link-wrapper{font-size:14px;color:var(--ah-color-text, #1e212a)}.link{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:14px;font-weight:var(--ah-font-weight-link, 400);transition:color 150ms ease}.link:hover{text-decoration:underline}.link:focus-visible{outline:2px solid var(--ah-color-link, #635dff);outline-offset:2px;border-radius:2px}.widget-footer{margin-top:16px;text-align:center;font-size:12px;color:var(--ah-color-text-muted, #65676e)}.widget-footer a{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:12px;transition:color 150ms ease}.widget-footer a:hover{text-decoration:underline}.widget-footer a:focus-visible{outline:2px solid var(--ah-color-link, #635dff);outline-offset:2px;border-radius:2px}.loading-spinner{width:32px;height:32px;margin:24px auto;border:3px solid var(--ah-color-border-muted, #e0e1e3);border-top-color:var(--ah-color-primary, #635dff);border-radius:50%;animation:spin 0.8s linear infinite}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.error-message{text-align:center;color:var(--ah-color-error, #d03c38);padding:16px;font-size:14px}@media (max-width: 480px){:host{display:block;width:100%;min-height:100vh;background-color:var(--ah-color-bg, #ffffff)}.widget-container{box-shadow:none;border-radius:0;width:100%;margin:0}.widget-header{padding:24px 16px 16px}.widget-body{padding:0 16px 24px}}`;
|
|
6622
|
+
const authheroWidgetCss = () => `:host{display:block;font-family:var(--ah-font-family, 'ulp-font', -apple-system, BlinkMacSystemFont, Roboto, Helvetica, sans-serif);font-size:var(--ah-font-size-base, 16px);line-height:var(--ah-line-height-base, 1.5);color:var(--ah-color-text, #1e212a);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.widget-container{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)}.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{display:block;width:100%;min-height:100vh;background-color:var(--ah-color-bg, #ffffff)}.widget-container{box-shadow:none;border-radius:0;width:100%;margin:0}.widget-header{padding:24px 16px 16px}.widget-body{padding:0 16px 24px}}`;
|
|
6624
6623
|
|
|
6625
6624
|
class AuthheroWidget {
|
|
6626
6625
|
constructor(hostRef) {
|
|
@@ -6739,6 +6738,11 @@ class AuthheroWidget {
|
|
|
6739
6738
|
* Aborted on screen change or component disconnect.
|
|
6740
6739
|
*/
|
|
6741
6740
|
conditionalMediationAbort;
|
|
6741
|
+
/**
|
|
6742
|
+
* URL of the custom font stylesheet currently injected into the document
|
|
6743
|
+
* head, tracked so it can be removed when the theme/branding changes.
|
|
6744
|
+
*/
|
|
6745
|
+
loadedFontUrl;
|
|
6742
6746
|
/**
|
|
6743
6747
|
* Emitted when the form is submitted.
|
|
6744
6748
|
* The consuming application should handle the submission unless autoSubmit is true.
|
|
@@ -6896,6 +6900,39 @@ class AuthheroWidget {
|
|
|
6896
6900
|
applyThemeStyles() {
|
|
6897
6901
|
const vars = mergeThemeVars(this._branding, this._theme);
|
|
6898
6902
|
applyCssVars(this.el, vars);
|
|
6903
|
+
this.loadCustomFont();
|
|
6904
|
+
}
|
|
6905
|
+
/**
|
|
6906
|
+
* Load the custom font stylesheet referenced by the theme/branding.
|
|
6907
|
+
* The stylesheet is expected to define the `ulp-font` family (Auth0
|
|
6908
|
+
* convention), which the component CSS already falls back to. @font-face
|
|
6909
|
+
* rules must live in the document (not the shadow DOM) to take effect, so
|
|
6910
|
+
* the <link> is injected into the document head, de-duplicated by href.
|
|
6911
|
+
*/
|
|
6912
|
+
loadCustomFont() {
|
|
6913
|
+
if (typeof document === "undefined") {
|
|
6914
|
+
return;
|
|
6915
|
+
}
|
|
6916
|
+
const fontUrl = this._theme?.fonts?.font_url || this._branding?.font?.url;
|
|
6917
|
+
if (fontUrl === this.loadedFontUrl) {
|
|
6918
|
+
return;
|
|
6919
|
+
}
|
|
6920
|
+
// Remove any previously injected font stylesheet so old fonts don't
|
|
6921
|
+
// persist across tenant/theme switches. Match by dataset attribute
|
|
6922
|
+
// rather than interpolating the URL into a selector string.
|
|
6923
|
+
for (const link of Array.from(document.head.querySelectorAll("link[data-authhero-font]"))) {
|
|
6924
|
+
link.remove();
|
|
6925
|
+
}
|
|
6926
|
+
this.loadedFontUrl = undefined;
|
|
6927
|
+
if (!fontUrl) {
|
|
6928
|
+
return;
|
|
6929
|
+
}
|
|
6930
|
+
const link = document.createElement("link");
|
|
6931
|
+
link.rel = "stylesheet";
|
|
6932
|
+
link.href = fontUrl;
|
|
6933
|
+
link.setAttribute("data-authhero-font", fontUrl);
|
|
6934
|
+
document.head.appendChild(link);
|
|
6935
|
+
this.loadedFontUrl = fontUrl;
|
|
6899
6936
|
}
|
|
6900
6937
|
/**
|
|
6901
6938
|
* Focus the first input field in the form.
|
|
@@ -6921,6 +6958,94 @@ class AuthheroWidget {
|
|
|
6921
6958
|
}
|
|
6922
6959
|
});
|
|
6923
6960
|
}
|
|
6961
|
+
/**
|
|
6962
|
+
* Pending resolvers awaiting the next render, flushed by
|
|
6963
|
+
* `componentDidRender`. Lets `swapScreen` wait until the new screen is
|
|
6964
|
+
* actually in the DOM before measuring its height.
|
|
6965
|
+
*/
|
|
6966
|
+
pendingRenderResolvers = [];
|
|
6967
|
+
componentDidRender() {
|
|
6968
|
+
if (this.pendingRenderResolvers.length === 0)
|
|
6969
|
+
return;
|
|
6970
|
+
const resolvers = this.pendingRenderResolvers;
|
|
6971
|
+
this.pendingRenderResolvers = [];
|
|
6972
|
+
resolvers.forEach((resolve) => resolve());
|
|
6973
|
+
}
|
|
6974
|
+
/**
|
|
6975
|
+
* Resolves after Stencil flushes the next render, so `swapScreen` waits for
|
|
6976
|
+
* the new screen to be in the DOM before measuring its height.
|
|
6977
|
+
*/
|
|
6978
|
+
nextRender() {
|
|
6979
|
+
return new Promise((resolve) => {
|
|
6980
|
+
let settled = false;
|
|
6981
|
+
const done = () => {
|
|
6982
|
+
if (settled)
|
|
6983
|
+
return;
|
|
6984
|
+
settled = true;
|
|
6985
|
+
resolve();
|
|
6986
|
+
};
|
|
6987
|
+
this.pendingRenderResolvers.push(done);
|
|
6988
|
+
// Safety net: a screen swap always triggers a render here, but never
|
|
6989
|
+
// hang the swap if one somehow doesn't fire — resolve after a couple of
|
|
6990
|
+
// frames at the latest.
|
|
6991
|
+
requestAnimationFrame(() => requestAnimationFrame(done));
|
|
6992
|
+
});
|
|
6993
|
+
}
|
|
6994
|
+
/**
|
|
6995
|
+
* Apply a screen swap, animating the widget card's height to the next
|
|
6996
|
+
* screen's size (Stripe-style): lock the current height, swap the content,
|
|
6997
|
+
* measure the new natural height, then animate between them. The content
|
|
6998
|
+
* itself doesn't fade — the card just resizes.
|
|
6999
|
+
*
|
|
7000
|
+
* The card (.widget-container) is animated rather than the host because it
|
|
7001
|
+
* carries the background, so its resize is visible; clipping its content
|
|
7002
|
+
* (not the host) also keeps the card's drop-shadow intact.
|
|
7003
|
+
*
|
|
7004
|
+
* Degrades to an immediate swap when the Web Animations API is unavailable
|
|
7005
|
+
* or the user prefers reduced motion.
|
|
7006
|
+
*/
|
|
7007
|
+
async swapScreen(apply) {
|
|
7008
|
+
const card = this.el.shadowRoot?.querySelector(".widget-container");
|
|
7009
|
+
const prefersReducedMotion = typeof window.matchMedia === "function" &&
|
|
7010
|
+
window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
7011
|
+
if (!card || typeof card.animate !== "function" || prefersReducedMotion) {
|
|
7012
|
+
apply();
|
|
7013
|
+
return;
|
|
7014
|
+
}
|
|
7015
|
+
// Lock the current height and clip, so swapping the content doesn't jump
|
|
7016
|
+
// before the animation runs.
|
|
7017
|
+
const startHeight = card.getBoundingClientRect().height;
|
|
7018
|
+
card.style.height = `${startHeight}px`;
|
|
7019
|
+
card.style.overflow = "hidden";
|
|
7020
|
+
apply();
|
|
7021
|
+
// Wait for the new screen to render before measuring its height.
|
|
7022
|
+
await this.nextRender();
|
|
7023
|
+
const cleanup = () => {
|
|
7024
|
+
card.style.height = "";
|
|
7025
|
+
card.style.overflow = "";
|
|
7026
|
+
};
|
|
7027
|
+
// Measure the new content's natural height without painting: toggle to
|
|
7028
|
+
// auto, read, restore — all synchronous, so there's no visible jump.
|
|
7029
|
+
card.style.height = "auto";
|
|
7030
|
+
const endHeight = card.getBoundingClientRect().height;
|
|
7031
|
+
card.style.height = `${startHeight}px`;
|
|
7032
|
+
card.getBoundingClientRect(); // force reflow from startHeight
|
|
7033
|
+
if (Math.abs(endHeight - startHeight) < 1) {
|
|
7034
|
+
cleanup();
|
|
7035
|
+
return;
|
|
7036
|
+
}
|
|
7037
|
+
const animation = card.animate([{ height: `${startHeight}px` }, { height: `${endHeight}px` }], { duration: 520, easing: "cubic-bezier(0.22, 1, 0.36, 1)" });
|
|
7038
|
+
try {
|
|
7039
|
+
await animation.finished;
|
|
7040
|
+
}
|
|
7041
|
+
catch {
|
|
7042
|
+
// Animation cancelled (e.g. superseded by a newer swap); the final
|
|
7043
|
+
// DOM state is already correct, so just fall through to cleanup.
|
|
7044
|
+
}
|
|
7045
|
+
finally {
|
|
7046
|
+
cleanup();
|
|
7047
|
+
}
|
|
7048
|
+
}
|
|
6924
7049
|
/**
|
|
6925
7050
|
* Get the effective autoNavigate value (defaults to autoSubmit if not set)
|
|
6926
7051
|
*/
|
|
@@ -7223,45 +7348,55 @@ class AuthheroWidget {
|
|
|
7223
7348
|
}
|
|
7224
7349
|
else if (!response.ok && result.screen) {
|
|
7225
7350
|
// Handle validation errors (400 response) — preserve user input
|
|
7226
|
-
this.
|
|
7227
|
-
|
|
7228
|
-
|
|
7229
|
-
|
|
7230
|
-
|
|
7351
|
+
await this.swapScreen(() => {
|
|
7352
|
+
// Clear loading first so the captured "after" snapshot doesn't
|
|
7353
|
+
// freeze a disabled button into the cross-fade.
|
|
7354
|
+
this.loading = false;
|
|
7355
|
+
this._screen = result.screen;
|
|
7356
|
+
this.initFormDataFromDefaults(result.screen);
|
|
7357
|
+
this.screenChange.emit(result.screen);
|
|
7358
|
+
this.updateDataScreenAttribute();
|
|
7359
|
+
this.focusFirstInput();
|
|
7360
|
+
});
|
|
7231
7361
|
}
|
|
7232
7362
|
else if (result.screen) {
|
|
7233
7363
|
// Next screen (success)
|
|
7234
|
-
this.
|
|
7235
|
-
|
|
7236
|
-
|
|
7237
|
-
|
|
7238
|
-
|
|
7239
|
-
|
|
7240
|
-
|
|
7241
|
-
this.
|
|
7242
|
-
|
|
7243
|
-
|
|
7244
|
-
|
|
7245
|
-
|
|
7246
|
-
|
|
7247
|
-
|
|
7248
|
-
}
|
|
7249
|
-
// Apply branding if included
|
|
7250
|
-
if (result.branding) {
|
|
7251
|
-
this._branding = result.branding;
|
|
7252
|
-
this.applyThemeStyles();
|
|
7253
|
-
}
|
|
7254
|
-
// Update state if returned
|
|
7255
|
-
if (result.state) {
|
|
7256
|
-
this.state = result.state;
|
|
7364
|
+
await this.swapScreen(() => {
|
|
7365
|
+
// Clear loading first so the captured "after" snapshot doesn't
|
|
7366
|
+
// freeze a disabled button into the cross-fade.
|
|
7367
|
+
this.loading = false;
|
|
7368
|
+
this._screen = result.screen;
|
|
7369
|
+
this.formData = {};
|
|
7370
|
+
this.initFormDataFromDefaults(result.screen);
|
|
7371
|
+
this.screenChange.emit(result.screen);
|
|
7372
|
+
this.updateDataScreenAttribute();
|
|
7373
|
+
// Update screenId if returned in response
|
|
7374
|
+
if (result.screenId) {
|
|
7375
|
+
this.screenId = result.screenId;
|
|
7376
|
+
}
|
|
7377
|
+
// Persist state (especially for session storage mode)
|
|
7257
7378
|
this.persistState();
|
|
7258
|
-
|
|
7259
|
-
|
|
7260
|
-
|
|
7261
|
-
|
|
7262
|
-
|
|
7263
|
-
|
|
7264
|
-
|
|
7379
|
+
// Update URL path if navigateUrl is provided (client-side navigation)
|
|
7380
|
+
if (result.navigateUrl && this.shouldAutoNavigate) {
|
|
7381
|
+
window.history.pushState({ screen: result.screenId, state: this.state }, "", result.navigateUrl);
|
|
7382
|
+
}
|
|
7383
|
+
// Apply branding if included
|
|
7384
|
+
if (result.branding) {
|
|
7385
|
+
this._branding = result.branding;
|
|
7386
|
+
this.applyThemeStyles();
|
|
7387
|
+
}
|
|
7388
|
+
// Update state if returned
|
|
7389
|
+
if (result.state) {
|
|
7390
|
+
this.state = result.state;
|
|
7391
|
+
this.persistState();
|
|
7392
|
+
}
|
|
7393
|
+
// Perform WebAuthn ceremony if present (structured data, not script)
|
|
7394
|
+
if (result.ceremony) {
|
|
7395
|
+
this.performWebAuthnCeremony(result.ceremony);
|
|
7396
|
+
}
|
|
7397
|
+
// Focus first input on new screen
|
|
7398
|
+
this.focusFirstInput();
|
|
7399
|
+
});
|
|
7265
7400
|
}
|
|
7266
7401
|
else if (result.complete) {
|
|
7267
7402
|
// Flow complete without redirect
|