@authhero/widget 0.32.42 → 0.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authhero-widget/authhero-widget.esm.js +1 -1
- package/dist/authhero-widget/index.esm.js +1 -1
- package/dist/authhero-widget/{p-5f7b7943.entry.js → p-5a319adc.entry.js} +1 -1
- package/dist/authhero-widget/p-f6babd26.entry.js +1 -0
- package/dist/cjs/authhero-node.cjs.entry.js +82 -5
- package/dist/cjs/authhero-widget.cjs.entry.js +133 -35
- package/dist/cjs/index.cjs.js +1 -1
- package/dist/collection/components/authhero-node/authhero-node.css +116 -1
- package/dist/collection/components/authhero-node/authhero-node.js +84 -2
- package/dist/collection/components/authhero-widget/authhero-widget.js +135 -37
- package/dist/components/authhero-node.js +1 -1
- package/dist/components/authhero-widget.js +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/p-BqdJX4cC.js +1 -0
- package/dist/esm/authhero-node.entry.js +83 -6
- package/dist/esm/authhero-widget.entry.js +133 -35
- package/dist/esm/index.js +1 -1
- package/dist/types/components/authhero-node/authhero-node.d.ts +12 -0
- package/dist/types/components/authhero-widget/authhero-widget.d.ts +26 -0
- package/dist/types/components.d.ts +0 -6
- package/dist/types/types/components.d.ts +1 -1
- package/hydrate/index.js +215 -40
- package/hydrate/index.mjs +215 -40
- package/package.json +2 -2
- package/dist/authhero-widget/p-1fc7fcdb.entry.js +0 -1
- package/dist/components/p-BzbxtmOP.js +0 -1
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
* Re-exported from @authhero/adapter-interfaces for consistency.
|
|
5
5
|
* @see https://auth0.com/docs/customize/forms/forms-schema
|
|
6
6
|
*/
|
|
7
|
-
export type { ComponentMessage, FormNodeComponent as FormComponent, RuntimeComponent, BlockComponent, WidgetComponent, FieldComponent, DividerComponent, HtmlComponent, ImageComponent, JumpButtonComponent, ResendButtonComponent, NextButtonComponent, PreviousButtonComponent, RichTextComponent, VerifiableCredentialsWidget, GmapsAddressWidget, RecaptchaWidget, BooleanField, CardsField, ChoiceField, CountryField, CustomField, DateField, DropdownField, EmailField, FileField, LegalField, NumberField, PasswordField, PaymentField, SocialField, TelField, TextField, UrlField, ScreenLink, UiScreen, } from "@authhero/adapter-interfaces";
|
|
7
|
+
export type { ComponentMessage, FormNodeComponent as FormComponent, RuntimeComponent, BlockComponent, WidgetComponent, FieldComponent, DividerComponent, HtmlComponent, ImageComponent, JumpButtonComponent, ResendButtonComponent, NextButtonComponent, PreviousButtonComponent, RichTextComponent, VerifiableCredentialsWidget, GmapsAddressWidget, RecaptchaWidget, BooleanField, CardsField, ChoiceField, CodeField, CountryField, CustomField, DateField, DropdownField, EmailField, FileField, LegalField, NumberField, PasswordField, PaymentField, SocialField, TelField, TextField, UrlField, ScreenLink, UiScreen, } from "@authhero/adapter-interfaces";
|
|
8
8
|
export { isBlockComponent, isWidgetComponent, isFieldComponent, } from "@authhero/adapter-interfaces";
|
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: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)}`;
|
|
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)}.code-field{position:relative}.code-input{position:absolute;inset:0;width:100%;height:100%;margin:0;padding:0;border:none;background:transparent;color:transparent;caret-color:transparent;font-family:inherit;letter-spacing:0;outline:none;cursor:text;-webkit-text-fill-color:transparent}.code-boxes{display:flex;align-items:center;gap:var(--ah-code-group-gap, 12px);justify-content:center}.code-group{display:flex;gap:0}.code-separator{color:var(--ah-color-text-muted, #65676e);font-size:var(--ah-code-font-size, 24px);user-select:none}.code-box-placeholder{color:var(--ah-color-text-muted, #65676e);opacity:0.4}.code-box{position:relative;flex:0 0 auto;width:var(--ah-code-box-width, 48px);height:var(--ah-code-box-height, 56px);display:flex;align-items:center;justify-content:center;font-size:var(--ah-code-font-size, 24px);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:0;transition:border-color 0.15s ease-out, box-shadow 0.15s ease-out;box-sizing:border-box}.code-box+.code-box{margin-left:calc(-1 * var(--ah-input-border-width, 1px))}.code-group .code-box:first-child{border-top-left-radius:var(--ah-input-radius, 3px);border-bottom-left-radius:var(--ah-input-radius, 3px)}.code-group .code-box:last-child{border-top-right-radius:var(--ah-input-radius, 3px);border-bottom-right-radius:var(--ah-input-radius, 3px)}.code-field:focus-within .code-box.is-active{z-index:1;border-color:var(--ah-color-primary, #635dff);box-shadow:inset 0 0 0 1px var(--ah-color-primary, #635dff)}.code-field.has-error .code-box{border-color:var(--ah-color-error, #d03c38)}.code-input:disabled{cursor:not-allowed}.code-input:disabled~.code-boxes .code-box{background-color:var(--ah-color-bg-disabled, #f5f5f5);border-color:var(--ah-color-border-disabled, #e0e1e3)}`;
|
|
5504
5504
|
|
|
5505
5505
|
class AuthheroNode {
|
|
5506
5506
|
constructor(hostRef) {
|
|
@@ -5508,10 +5508,7 @@ class AuthheroNode {
|
|
|
5508
5508
|
this.fieldChange = createEvent(this, "fieldChange");
|
|
5509
5509
|
this.buttonClick = createEvent(this, "buttonClick");
|
|
5510
5510
|
}
|
|
5511
|
-
|
|
5512
|
-
* The component configuration to render.
|
|
5513
|
-
* Follows Auth0 Forms component schema.
|
|
5514
|
-
*/
|
|
5511
|
+
get host() { return getElement(this); }
|
|
5515
5512
|
component;
|
|
5516
5513
|
/**
|
|
5517
5514
|
* Current value for field components.
|
|
@@ -5561,6 +5558,16 @@ class AuthheroNode {
|
|
|
5561
5558
|
this.initCountryFromConfig();
|
|
5562
5559
|
this.initTelValue();
|
|
5563
5560
|
}
|
|
5561
|
+
componentDidLoad() {
|
|
5562
|
+
// Auto-focus a code field so the caret starts in the first (leftmost) box.
|
|
5563
|
+
if (this.component?.type === "CODE" && !this.disabled) {
|
|
5564
|
+
const value = this.getEffectiveValue() ?? "";
|
|
5565
|
+
if (value.length === 0) {
|
|
5566
|
+
const input = this.host.shadowRoot?.querySelector("input.code-input");
|
|
5567
|
+
input?.focus();
|
|
5568
|
+
}
|
|
5569
|
+
}
|
|
5570
|
+
}
|
|
5564
5571
|
initCountryFromConfig() {
|
|
5565
5572
|
if (this.component?.type === "TEL") {
|
|
5566
5573
|
const config = this.component.config;
|
|
@@ -5719,6 +5726,20 @@ class AuthheroNode {
|
|
|
5719
5726
|
}
|
|
5720
5727
|
}
|
|
5721
5728
|
};
|
|
5729
|
+
handleCodeInput = (e, length, mode, autoSubmit) => {
|
|
5730
|
+
const target = e.target;
|
|
5731
|
+
const disallowed = mode === "alphanumeric" ? /[^a-zA-Z0-9]/g : /\D/g;
|
|
5732
|
+
const cleaned = target.value.replace(disallowed, "").slice(0, length);
|
|
5733
|
+
// Reflect the sanitized value back so the visible boxes never show
|
|
5734
|
+
// characters we stripped (e.g. a pasted "123-456").
|
|
5735
|
+
if (cleaned !== target.value) {
|
|
5736
|
+
target.value = cleaned;
|
|
5737
|
+
}
|
|
5738
|
+
this.fieldChange.emit({ id: this.component.id, value: cleaned });
|
|
5739
|
+
if (autoSubmit && cleaned.length === length) {
|
|
5740
|
+
this.buttonClick.emit({ id: "submit", type: "submit", value: "next" });
|
|
5741
|
+
}
|
|
5742
|
+
};
|
|
5722
5743
|
handleCheckbox = (e) => {
|
|
5723
5744
|
const target = e.target;
|
|
5724
5745
|
this.fieldChange.emit({
|
|
@@ -5865,6 +5886,60 @@ class AuthheroNode {
|
|
|
5865
5886
|
}
|
|
5866
5887
|
return (hAsync("div", { class: "input-wrapper", part: "input-wrapper" }, hAsync("div", { class: "input-container" }, hAsync("input", { id: inputId, class: this.getInputFieldClass(errors.length > 0), part: "input", type: component.sensitive ? "password" : "text", name: component.id, "data-input-name": component.id, value: effectiveValue ?? "", placeholder: " ", required: component.required, disabled: this.disabled, maxLength: max_length, autoComplete: autocomplete, onInput: this.handleInput, onKeyDown: this.handleKeyDown }), this.renderFloatingLabel(component.label, inputId, component.required, hasValue)), this.renderErrors(), errors.length === 0 && this.renderHint(component.hint)));
|
|
5867
5888
|
}
|
|
5889
|
+
/**
|
|
5890
|
+
* Segmented one-time-code input (e.g. SMS/email verification codes).
|
|
5891
|
+
*
|
|
5892
|
+
* Rendered as a SINGLE real <input> overlaid (transparent) on a row of
|
|
5893
|
+
* presentational boxes. This keeps native paste, iOS/Android SMS autofill
|
|
5894
|
+
* (`autocomplete="one-time-code"`) and screen-reader behaviour working —
|
|
5895
|
+
* all of which break when using one <input> per digit.
|
|
5896
|
+
*/
|
|
5897
|
+
renderCodeField(component) {
|
|
5898
|
+
const inputId = `input-${component.id}`;
|
|
5899
|
+
const errors = this.getErrors();
|
|
5900
|
+
const hasError = errors.length > 0;
|
|
5901
|
+
const config = (component.config ?? {});
|
|
5902
|
+
const length = config.length ?? 6;
|
|
5903
|
+
const mode = config.mode ?? "numeric";
|
|
5904
|
+
const autoSubmit = config.auto_submit !== false;
|
|
5905
|
+
const groupSize = config.group_size ?? 3;
|
|
5906
|
+
const separator = config.separator ?? "-";
|
|
5907
|
+
const placeholder = config.placeholder;
|
|
5908
|
+
// Apply the same mode sanitization used on input (handleCodeInput) so a
|
|
5909
|
+
// persisted/default value with invalid characters (e.g. "12-3a" in numeric
|
|
5910
|
+
// mode) doesn't render until edited.
|
|
5911
|
+
const disallowed = mode === "alphanumeric" ? /[^a-zA-Z0-9]/g : /\D/g;
|
|
5912
|
+
const value = (this.getEffectiveValue() ?? "")
|
|
5913
|
+
.replace(disallowed, "")
|
|
5914
|
+
.slice(0, length);
|
|
5915
|
+
const boxClass = (i) => {
|
|
5916
|
+
let cls = "code-box";
|
|
5917
|
+
if (i < value.length)
|
|
5918
|
+
cls += " is-filled";
|
|
5919
|
+
// Highlight the next empty box as the "caret" position while focused.
|
|
5920
|
+
if (!this.disabled && i === value.length)
|
|
5921
|
+
cls += " is-active";
|
|
5922
|
+
return cls;
|
|
5923
|
+
};
|
|
5924
|
+
const renderBox = (i) => (hAsync("div", { class: boxClass(i), part: "code-box" }, value[i] ??
|
|
5925
|
+
(placeholder ? (hAsync("span", { class: "code-box-placeholder" }, placeholder)) : (""))));
|
|
5926
|
+
// Split into groups of `groupSize` (e.g. 3 → "123 - 456"); a non-positive
|
|
5927
|
+
// or >= length size means a single ungrouped row.
|
|
5928
|
+
const useGroups = groupSize > 0 && groupSize < length;
|
|
5929
|
+
const groups = [];
|
|
5930
|
+
if (useGroups) {
|
|
5931
|
+
for (let start = 0; start < length; start += groupSize) {
|
|
5932
|
+
groups.push(Array.from({ length: Math.min(groupSize, length - start) }, (_, j) => start + j));
|
|
5933
|
+
}
|
|
5934
|
+
}
|
|
5935
|
+
else {
|
|
5936
|
+
groups.push(Array.from({ length }, (_, i) => i));
|
|
5937
|
+
}
|
|
5938
|
+
return (hAsync("div", { class: "input-wrapper", part: "input-wrapper" }, hAsync("div", { class: hasError ? "code-field has-error" : "code-field", part: "code-field" }, hAsync("input", { id: inputId, class: "code-input", part: "input code-input", type: "text", name: component.id, "data-input-name": component.id, value: value, inputMode: mode === "numeric" ? "numeric" : "text", autoComplete: "one-time-code", autoCapitalize: "off", autoCorrect: "off", spellcheck: false, maxLength: length, required: component.required, disabled: this.disabled, "aria-label": component.label, "aria-invalid": hasError ? "true" : "false", onInput: (e) => this.handleCodeInput(e, length, mode, autoSubmit), onKeyDown: this.handleKeyDown }), hAsync("div", { class: "code-boxes", part: "code-boxes", "aria-hidden": "true" }, groups.map((group, gi) => [
|
|
5939
|
+
gi > 0 && separator ? (hAsync("span", { class: "code-separator", part: "code-separator" }, separator)) : null,
|
|
5940
|
+
hAsync("div", { class: "code-group", part: "code-group" }, group.map((i) => renderBox(i))),
|
|
5941
|
+
]))), this.renderErrors(), errors.length === 0 && this.renderHint(component.hint)));
|
|
5942
|
+
}
|
|
5868
5943
|
renderEmailField(component) {
|
|
5869
5944
|
const inputId = `input-${component.id}`;
|
|
5870
5945
|
const errors = this.getErrors();
|
|
@@ -6037,6 +6112,8 @@ class AuthheroNode {
|
|
|
6037
6112
|
return this.renderTextField(this.component);
|
|
6038
6113
|
case "EMAIL":
|
|
6039
6114
|
return this.renderEmailField(this.component);
|
|
6115
|
+
case "CODE":
|
|
6116
|
+
return this.renderCodeField(this.component);
|
|
6040
6117
|
case "PASSWORD":
|
|
6041
6118
|
return this.renderPasswordField(this.component);
|
|
6042
6119
|
case "NUMBER":
|
|
@@ -6958,6 +7035,94 @@ class AuthheroWidget {
|
|
|
6958
7035
|
}
|
|
6959
7036
|
});
|
|
6960
7037
|
}
|
|
7038
|
+
/**
|
|
7039
|
+
* Pending resolvers awaiting the next render, flushed by
|
|
7040
|
+
* `componentDidRender`. Lets `swapScreen` wait until the new screen is
|
|
7041
|
+
* actually in the DOM before measuring its height.
|
|
7042
|
+
*/
|
|
7043
|
+
pendingRenderResolvers = [];
|
|
7044
|
+
componentDidRender() {
|
|
7045
|
+
if (this.pendingRenderResolvers.length === 0)
|
|
7046
|
+
return;
|
|
7047
|
+
const resolvers = this.pendingRenderResolvers;
|
|
7048
|
+
this.pendingRenderResolvers = [];
|
|
7049
|
+
resolvers.forEach((resolve) => resolve());
|
|
7050
|
+
}
|
|
7051
|
+
/**
|
|
7052
|
+
* Resolves after Stencil flushes the next render, so `swapScreen` waits for
|
|
7053
|
+
* the new screen to be in the DOM before measuring its height.
|
|
7054
|
+
*/
|
|
7055
|
+
nextRender() {
|
|
7056
|
+
return new Promise((resolve) => {
|
|
7057
|
+
let settled = false;
|
|
7058
|
+
const done = () => {
|
|
7059
|
+
if (settled)
|
|
7060
|
+
return;
|
|
7061
|
+
settled = true;
|
|
7062
|
+
resolve();
|
|
7063
|
+
};
|
|
7064
|
+
this.pendingRenderResolvers.push(done);
|
|
7065
|
+
// Safety net: a screen swap always triggers a render here, but never
|
|
7066
|
+
// hang the swap if one somehow doesn't fire — resolve after a couple of
|
|
7067
|
+
// frames at the latest.
|
|
7068
|
+
requestAnimationFrame(() => requestAnimationFrame(done));
|
|
7069
|
+
});
|
|
7070
|
+
}
|
|
7071
|
+
/**
|
|
7072
|
+
* Apply a screen swap, animating the widget card's height to the next
|
|
7073
|
+
* screen's size (Stripe-style): lock the current height, swap the content,
|
|
7074
|
+
* measure the new natural height, then animate between them. The content
|
|
7075
|
+
* itself doesn't fade — the card just resizes.
|
|
7076
|
+
*
|
|
7077
|
+
* The card (.widget-container) is animated rather than the host because it
|
|
7078
|
+
* carries the background, so its resize is visible; clipping its content
|
|
7079
|
+
* (not the host) also keeps the card's drop-shadow intact.
|
|
7080
|
+
*
|
|
7081
|
+
* Degrades to an immediate swap when the Web Animations API is unavailable
|
|
7082
|
+
* or the user prefers reduced motion.
|
|
7083
|
+
*/
|
|
7084
|
+
async swapScreen(apply) {
|
|
7085
|
+
const card = this.el.shadowRoot?.querySelector(".widget-container");
|
|
7086
|
+
const prefersReducedMotion = typeof window.matchMedia === "function" &&
|
|
7087
|
+
window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
7088
|
+
if (!card || typeof card.animate !== "function" || prefersReducedMotion) {
|
|
7089
|
+
apply();
|
|
7090
|
+
return;
|
|
7091
|
+
}
|
|
7092
|
+
// Lock the current height and clip, so swapping the content doesn't jump
|
|
7093
|
+
// before the animation runs.
|
|
7094
|
+
const startHeight = card.getBoundingClientRect().height;
|
|
7095
|
+
card.style.height = `${startHeight}px`;
|
|
7096
|
+
card.style.overflow = "hidden";
|
|
7097
|
+
apply();
|
|
7098
|
+
// Wait for the new screen to render before measuring its height.
|
|
7099
|
+
await this.nextRender();
|
|
7100
|
+
const cleanup = () => {
|
|
7101
|
+
card.style.height = "";
|
|
7102
|
+
card.style.overflow = "";
|
|
7103
|
+
};
|
|
7104
|
+
// Measure the new content's natural height without painting: toggle to
|
|
7105
|
+
// auto, read, restore — all synchronous, so there's no visible jump.
|
|
7106
|
+
card.style.height = "auto";
|
|
7107
|
+
const endHeight = card.getBoundingClientRect().height;
|
|
7108
|
+
card.style.height = `${startHeight}px`;
|
|
7109
|
+
card.getBoundingClientRect(); // force reflow from startHeight
|
|
7110
|
+
if (Math.abs(endHeight - startHeight) < 1) {
|
|
7111
|
+
cleanup();
|
|
7112
|
+
return;
|
|
7113
|
+
}
|
|
7114
|
+
const animation = card.animate([{ height: `${startHeight}px` }, { height: `${endHeight}px` }], { duration: 520, easing: "cubic-bezier(0.22, 1, 0.36, 1)" });
|
|
7115
|
+
try {
|
|
7116
|
+
await animation.finished;
|
|
7117
|
+
}
|
|
7118
|
+
catch {
|
|
7119
|
+
// Animation cancelled (e.g. superseded by a newer swap); the final
|
|
7120
|
+
// DOM state is already correct, so just fall through to cleanup.
|
|
7121
|
+
}
|
|
7122
|
+
finally {
|
|
7123
|
+
cleanup();
|
|
7124
|
+
}
|
|
7125
|
+
}
|
|
6961
7126
|
/**
|
|
6962
7127
|
* Get the effective autoNavigate value (defaults to autoSubmit if not set)
|
|
6963
7128
|
*/
|
|
@@ -7260,45 +7425,55 @@ class AuthheroWidget {
|
|
|
7260
7425
|
}
|
|
7261
7426
|
else if (!response.ok && result.screen) {
|
|
7262
7427
|
// Handle validation errors (400 response) — preserve user input
|
|
7263
|
-
this.
|
|
7264
|
-
|
|
7265
|
-
|
|
7266
|
-
|
|
7267
|
-
|
|
7428
|
+
await this.swapScreen(() => {
|
|
7429
|
+
// Clear loading first so the captured "after" snapshot doesn't
|
|
7430
|
+
// freeze a disabled button into the cross-fade.
|
|
7431
|
+
this.loading = false;
|
|
7432
|
+
this._screen = result.screen;
|
|
7433
|
+
this.initFormDataFromDefaults(result.screen);
|
|
7434
|
+
this.screenChange.emit(result.screen);
|
|
7435
|
+
this.updateDataScreenAttribute();
|
|
7436
|
+
this.focusFirstInput();
|
|
7437
|
+
});
|
|
7268
7438
|
}
|
|
7269
7439
|
else if (result.screen) {
|
|
7270
7440
|
// Next screen (success)
|
|
7271
|
-
this.
|
|
7272
|
-
|
|
7273
|
-
|
|
7274
|
-
|
|
7275
|
-
|
|
7276
|
-
|
|
7277
|
-
|
|
7278
|
-
this.
|
|
7279
|
-
|
|
7280
|
-
|
|
7281
|
-
|
|
7282
|
-
|
|
7283
|
-
|
|
7284
|
-
|
|
7285
|
-
}
|
|
7286
|
-
// Apply branding if included
|
|
7287
|
-
if (result.branding) {
|
|
7288
|
-
this._branding = result.branding;
|
|
7289
|
-
this.applyThemeStyles();
|
|
7290
|
-
}
|
|
7291
|
-
// Update state if returned
|
|
7292
|
-
if (result.state) {
|
|
7293
|
-
this.state = result.state;
|
|
7441
|
+
await this.swapScreen(() => {
|
|
7442
|
+
// Clear loading first so the captured "after" snapshot doesn't
|
|
7443
|
+
// freeze a disabled button into the cross-fade.
|
|
7444
|
+
this.loading = false;
|
|
7445
|
+
this._screen = result.screen;
|
|
7446
|
+
this.formData = {};
|
|
7447
|
+
this.initFormDataFromDefaults(result.screen);
|
|
7448
|
+
this.screenChange.emit(result.screen);
|
|
7449
|
+
this.updateDataScreenAttribute();
|
|
7450
|
+
// Update screenId if returned in response
|
|
7451
|
+
if (result.screenId) {
|
|
7452
|
+
this.screenId = result.screenId;
|
|
7453
|
+
}
|
|
7454
|
+
// Persist state (especially for session storage mode)
|
|
7294
7455
|
this.persistState();
|
|
7295
|
-
|
|
7296
|
-
|
|
7297
|
-
|
|
7298
|
-
|
|
7299
|
-
|
|
7300
|
-
|
|
7301
|
-
|
|
7456
|
+
// Update URL path if navigateUrl is provided (client-side navigation)
|
|
7457
|
+
if (result.navigateUrl && this.shouldAutoNavigate) {
|
|
7458
|
+
window.history.pushState({ screen: result.screenId, state: this.state }, "", result.navigateUrl);
|
|
7459
|
+
}
|
|
7460
|
+
// Apply branding if included
|
|
7461
|
+
if (result.branding) {
|
|
7462
|
+
this._branding = result.branding;
|
|
7463
|
+
this.applyThemeStyles();
|
|
7464
|
+
}
|
|
7465
|
+
// Update state if returned
|
|
7466
|
+
if (result.state) {
|
|
7467
|
+
this.state = result.state;
|
|
7468
|
+
this.persistState();
|
|
7469
|
+
}
|
|
7470
|
+
// Perform WebAuthn ceremony if present (structured data, not script)
|
|
7471
|
+
if (result.ceremony) {
|
|
7472
|
+
this.performWebAuthnCeremony(result.ceremony);
|
|
7473
|
+
}
|
|
7474
|
+
// Focus first input on new screen
|
|
7475
|
+
this.focusFirstInput();
|
|
7476
|
+
});
|
|
7302
7477
|
}
|
|
7303
7478
|
else if (result.complete) {
|
|
7304
7479
|
// Flow complete without redirect
|