@authhero/widget 0.40.2 → 0.41.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/hydrate/index.mjs CHANGED
@@ -7234,7 +7234,7 @@ function escapeAttr(value) {
7234
7234
  .replace(/>/g, ">");
7235
7235
  }
7236
7236
 
7237
- 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)}.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}}`;
7237
+ 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-footer,.secondary-actions,.prompt-partial{display:flex;flex-direction:column}.prompt-partial .ulp-field{display:flex;flex-direction:column;gap:6px;position:relative;margin-top:8px;margin-bottom:16px}.prompt-partial label{font-size:var(--ah-font-size-label, 14px);font-weight:var(--ah-font-weight-label, 400);color:var(--ah-color-text, #1e212a)}.prompt-partial .ulp-error input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]),.prompt-partial .ulp-error select,.prompt-partial .ulp-error textarea{border-color:var(--ah-color-error, #d03c38)}.prompt-partial .ulp-error input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):focus,.prompt-partial .ulp-error select:focus,.prompt-partial .ulp-error textarea:focus{box-shadow:inset 0 0 0 1px var(--ah-color-error, #d03c38)}.prompt-partial .ulp-error-info{font-size:12px;color:var(--ah-color-error, #d03c38);margin-top:-2px;line-height:1.4}.prompt-partial .required{color:var(--ah-color-error, #d03c38);margin-left:2px}.prompt-partial .ulp-field>input+label,.prompt-partial .ulp-field>select+label,.prompt-partial .ulp-field>textarea+label{position:absolute;left:16px;top:50%;z-index:1;padding:0;background-color:transparent;color:var(--ah-color-text-muted, #65676e);pointer-events:none;transform:translateY(-50%);transition:all 0.15s ease-out}.prompt-partial .ulp-field>input:focus+label,.prompt-partial .ulp-field>input:not(:placeholder-shown)+label,.prompt-partial .ulp-field>select+label,.prompt-partial .ulp-field>textarea:focus+label,.prompt-partial .ulp-field>textarea:not(:placeholder-shown)+label{top:-8px;left:12px;padding:0 4px;background-color:var(--ah-color-bg, #ffffff);color:var(--ah-color-text-muted, #65676e);font-size:12px;transform:translateY(0)}.prompt-partial .ulp-field>input:focus+label,.prompt-partial .ulp-field>select:focus+label,.prompt-partial .ulp-field>textarea:focus+label{color:var(--ah-color-primary, #635dff)}.prompt-partial input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]),.prompt-partial select,.prompt-partial textarea{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;box-sizing:border-box;transition:border-color 0.15s ease-out, box-shadow 0.15s ease-out}.prompt-partial input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):hover,.prompt-partial select:hover,.prompt-partial textarea:hover{border-color:var(--ah-color-border-hover, #65676e)}.prompt-partial input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):focus,.prompt-partial select:focus,.prompt-partial textarea:focus{border-color:var(--ah-color-primary, #635dff);box-shadow:inset 0 0 0 1px var(--ah-color-primary, #635dff)}.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}}`;
7238
7238
 
7239
7239
  /**
7240
7240
  * When a screen's field section is made up entirely of choice buttons
@@ -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)
@@ -7949,14 +8023,44 @@ class AuthheroWidget {
7949
8023
  e.preventDefault();
7950
8024
  if (!this._screen || this.loading)
7951
8025
  return;
7952
- let submitData = { ...this.formData, ...(overrideData || {}) };
7953
- // Merge hidden input values from DOM (may have been set programmatically
7954
- // by inline scripts, e.g. passkey management buttons)
7955
8026
  const form = this.el.shadowRoot?.querySelector("form");
8027
+ if (this._screen.partials &&
8028
+ form?.reportValidity &&
8029
+ !form.reportValidity()) {
8030
+ return;
8031
+ }
8032
+ const submitData = {
8033
+ ...this.formData,
8034
+ ...(overrideData || {}),
8035
+ };
8036
+ // Native fields in prompt partials are direct descendants of this form,
8037
+ // unlike authhero-node inputs in nested shadow roots. Read them through
8038
+ // FormData so standard HTML controls and successful-control semantics are
8039
+ // preserved (disabled controls are skipped, repeated names are kept as
8040
+ // arrays). FormData also covers enabled hidden inputs for ulp-* names.
8041
+ const nativeNames = new Set();
8042
+ if (form && this._screen.partials) {
8043
+ const nativeValues = {};
8044
+ new FormData(form).forEach((value, key) => {
8045
+ if (typeof value === "string" && key.startsWith("ulp-")) {
8046
+ (nativeValues[key] ??= []).push(value);
8047
+ }
8048
+ });
8049
+ for (const [key, values] of Object.entries(nativeValues)) {
8050
+ nativeNames.add(key);
8051
+ submitData[key] = values.length > 1 ? values : values[0];
8052
+ }
8053
+ }
8054
+ // Legacy behaviour for inline scripts that fill hidden inputs: merge
8055
+ // enabled ones, but never overwrite what FormData already collected.
7956
8056
  if (form) {
7957
- const hiddenInputs = form.querySelectorAll('input[type="hidden"]');
7958
- hiddenInputs.forEach((input) => {
7959
- if (input.name && input.value) {
8057
+ form
8058
+ .querySelectorAll('input[type="hidden"]')
8059
+ .forEach((input) => {
8060
+ if (input.name &&
8061
+ input.value &&
8062
+ !input.disabled &&
8063
+ !nativeNames.has(input.name)) {
7960
8064
  submitData[input.name] = input.value;
7961
8065
  }
7962
8066
  });
@@ -8110,6 +8214,11 @@ class AuthheroWidget {
8110
8214
  if (!form)
8111
8215
  return;
8112
8216
  form.submit = () => {
8217
+ if (this._screen?.partials &&
8218
+ form.reportValidity &&
8219
+ !form.reportValidity()) {
8220
+ return;
8221
+ }
8113
8222
  const formData = new FormData(form);
8114
8223
  const data = {};
8115
8224
  formData.forEach((value, key) => {
@@ -8714,6 +8823,27 @@ class AuthheroWidget {
8714
8823
  const config = component.config;
8715
8824
  return config?.text ?? "";
8716
8825
  }
8826
+ renderPromptPartial(screen, insertionPoint) {
8827
+ const html = screen.partials?.[insertionPoint];
8828
+ if (!html)
8829
+ return null;
8830
+ // Prompt partials intentionally contain tenant-authored form controls, so
8831
+ // the widget must keep their input attributes intact.
8832
+ return (hAsync("div", { class: `prompt-partial prompt-partial-${insertionPoint}`, part: `prompt-partial prompt-partial-${insertionPoint}`, "data-insertion-point": insertionPoint, innerHTML: html }));
8833
+ }
8834
+ renderScreenLinks(screen) {
8835
+ if (!screen.links?.length)
8836
+ return null;
8837
+ return (hAsync("div", { class: "links", part: "links" }, screen.links.map((link) => (hAsync("span", { class: "link-wrapper", part: "link-wrapper", key: link.id ?? link.href }, link.linkText ? (hAsync("span", null, link.text, " ", hAsync("a", { href: link.href, class: "link", part: "link", onClick: (e) => this.handleLinkClick(e, {
8838
+ id: link.id,
8839
+ href: link.href,
8840
+ text: link.linkText || link.text,
8841
+ }) }, link.linkText))) : (hAsync("a", { href: link.href, class: "link", part: "link", onClick: (e) => this.handleLinkClick(e, {
8842
+ id: link.id,
8843
+ href: link.href,
8844
+ text: link.text,
8845
+ }) }, link.text)))))));
8846
+ }
8717
8847
  render() {
8718
8848
  const screen = this._screen;
8719
8849
  if (this.loading && !screen) {
@@ -8740,13 +8870,20 @@ class AuthheroWidget {
8740
8870
  ? components.find((c) => this.isDividerComponent(c))
8741
8871
  : undefined;
8742
8872
  const fieldComponents = components.filter((c) => !this.isSocialComponent(c) && c !== dividerComponent);
8873
+ const hasPromptPartials = Object.values(screen.partials ?? {}).some((html) => !!html);
8874
+ const footerComponents = hasPromptPartials
8875
+ ? fieldComponents.filter((component) => component.id === "submit" && component.type === "NEXT_BUTTON")
8876
+ : [];
8877
+ const contentFieldComponents = hasPromptPartials
8878
+ ? fieldComponents.filter((component) => !footerComponents.includes(component))
8879
+ : fieldComponents;
8743
8880
  const hasDivider = !!dividerComponent;
8744
8881
  const dividerText = dividerComponent?.config?.text || "Or";
8745
8882
  // A "choice list" screen is one whose entire field section is pick-one
8746
8883
  // buttons (e.g. tenant selection). When the list is long, render it as a
8747
8884
  // searchable, scrollable list instead of a tall column of buttons.
8748
- const choiceButtons = fieldComponents.filter((c) => c.type === "NEXT_BUTTON");
8749
- const isSearchableChoiceList = choiceButtons.length === fieldComponents.length &&
8885
+ const choiceButtons = contentFieldComponents.filter((c) => c.type === "NEXT_BUTTON");
8886
+ const isSearchableChoiceList = choiceButtons.length === contentFieldComponents.length &&
8750
8887
  choiceButtons.length > CHOICE_LIST_SEARCH_THRESHOLD;
8751
8888
  // Hold the primary action button disabled until every required field has
8752
8889
  // a value.
@@ -8787,7 +8924,7 @@ class AuthheroWidget {
8787
8924
  };
8788
8925
  // Get logo URL from theme.widget (takes precedence) or branding
8789
8926
  const logoUrl = this._theme?.widget?.logo_url || this._branding?.logo_url;
8790
- return (hAsync("div", { class: "widget-container", part: "container", "data-authstack-container": true }, hAsync("header", { class: "widget-header", part: "header" }, logoUrl && (hAsync("div", { class: "logo-wrapper", part: "logo-wrapper" }, hAsync("img", { class: "logo", part: "logo", src: logoUrl, alt: "Logo" }))), screen.title && (hAsync("h1", { class: "title", part: "title", innerHTML: sanitizeHtml(screen.title) })), screen.description && (hAsync("p", { class: "description", part: "description", innerHTML: sanitizeHtml(screen.description) }))), hAsync("div", { class: "widget-body", part: "body" }, screenErrors.map((err) => (hAsync("div", { class: "message message-error", part: "message message-error", key: err.id ?? err.text }, err.text))), screenSuccesses.map((msg) => (hAsync("div", { class: "message message-success", part: "message message-success", key: msg.id ?? msg.text }, msg.text))), hAsync("form", { onSubmit: this.handleSubmit, action: screen.action, method: screen.method || "POST", part: "form" }, hiddenComponents.map((c) => (hAsync("input", { type: "hidden", name: c.id, id: c.id, key: c.id, value: this.formData[c.id] || "" }))), hAsync("div", { class: "form-content" }, socialComponents.length > 0 && (hAsync("div", { class: "social-section", part: "social-section" }, socialComponents.map((component) => (hAsync("authhero-node", { key: component.id, component: component, locale: this.locale, value: this.formData[component.id], onFieldChange: (e) => this.handleInputChange(e.detail.id, e.detail.value), onButtonClick: (e) => this.handleButtonClick(e.detail), disabled: this.loading, exportparts: getExportParts(component) }))))), socialComponents.length > 0 &&
8927
+ return (hAsync("div", { class: "widget-container", part: "container", "data-authstack-container": true }, hAsync("header", { class: "widget-header", part: "header" }, logoUrl && (hAsync("div", { class: "logo-wrapper", part: "logo-wrapper" }, hAsync("img", { class: "logo", part: "logo", src: logoUrl, alt: "Logo" }))), screen.title && (hAsync("h1", { class: "title", part: "title", innerHTML: sanitizeHtml(screen.title) })), screen.description && (hAsync("p", { class: "description", part: "description", innerHTML: sanitizeHtml(screen.description) }))), hAsync("div", { class: "widget-body", part: "body" }, screenErrors.map((err) => (hAsync("div", { class: "message message-error", part: "message message-error", key: err.id ?? err.text }, err.text))), screenSuccesses.map((msg) => (hAsync("div", { class: "message message-success", part: "message message-success", key: msg.id ?? msg.text }, msg.text))), hAsync("form", { onSubmit: this.handleSubmit, action: screen.action, method: screen.method || "POST", part: "form" }, hiddenComponents.map((c) => (hAsync("input", { type: "hidden", name: c.id, id: c.id, key: c.id, value: this.formData[c.id] || "" }))), hAsync("div", { class: "form-content" }, this.renderPromptPartial(screen, "form-content-start"), socialComponents.length > 0 && (hAsync("div", { class: "social-section", part: "social-section" }, socialComponents.map((component) => (hAsync("authhero-node", { key: component.id, component: component, locale: this.locale, value: this.formData[component.id], onFieldChange: (e) => this.handleInputChange(e.detail.id, e.detail.value), onButtonClick: (e) => this.handleButtonClick(e.detail), disabled: this.loading, exportparts: getExportParts(component) }))))), socialComponents.length > 0 &&
8791
8928
  fieldComponents.length > 0 &&
8792
8929
  hasDivider && (hAsync("div", { class: "divider", part: "divider" }, hAsync("span", { class: "divider-text" }, dividerText))), hAsync("div", { class: "fields-section", part: "fields-section" }, isSearchableChoiceList && (hAsync("input", { type: "text", class: "choice-list-search", part: "choice-list-search", placeholder: "Search", "aria-label": "Search", autocomplete: "off", value: this.listFilter, onInput: (e) => (this.listFilter = e.target.value), onKeyDown: (e) => {
8793
8930
  // The search box lives inside the form; Enter would
@@ -8800,19 +8937,14 @@ class AuthheroWidget {
8800
8937
  ? "fields-list fields-list-scroll"
8801
8938
  : "fields-list" }, (isSearchableChoiceList
8802
8939
  ? visibleChoiceButtons
8803
- : fieldComponents).map((component) => (hAsync("authhero-node", { key: component.id, component: component, locale: this.locale, value: this.formData[component.id], onFieldChange: (e) => this.handleInputChange(e.detail.id, e.detail.value), onButtonClick: (e) => this.handleButtonClick(e.detail), disabled: this.loading ||
8940
+ : contentFieldComponents).map((component) => (hAsync("authhero-node", { key: component.id, component: component, locale: this.locale, value: this.formData[component.id], onFieldChange: (e) => this.handleInputChange(e.detail.id, e.detail.value), onButtonClick: (e) => this.handleButtonClick(e.detail), disabled: this.loading ||
8804
8941
  (component.type === "NEXT_BUTTON" &&
8805
8942
  component.config?.skip_validation !== true &&
8806
8943
  requiredFieldsMissing) }))), isSearchableChoiceList &&
8807
- visibleChoiceButtons.length === 0 && (hAsync("div", { class: "choice-list-empty", part: "choice-list-empty" }, "No matches")))))), screen.links && screen.links.length > 0 && (hAsync("div", { class: "links", part: "links" }, screen.links.map((link) => (hAsync("span", { class: "link-wrapper", part: "link-wrapper", key: link.id ?? link.href }, link.linkText ? (hAsync("span", null, link.text, " ", hAsync("a", { href: link.href, class: "link", part: "link", onClick: (e) => this.handleLinkClick(e, {
8808
- id: link.id,
8809
- href: link.href,
8810
- text: link.linkText || link.text,
8811
- }) }, link.linkText))) : (hAsync("a", { href: link.href, class: "link", part: "link", onClick: (e) => this.handleLinkClick(e, {
8812
- id: link.id,
8813
- href: link.href,
8814
- text: link.text,
8815
- }) }, link.text))))))), screen.footer && (hAsync("div", { class: "widget-footer", part: "footer", innerHTML: sanitizeHtml(screen.footer) })))));
8944
+ visibleChoiceButtons.length === 0 && (hAsync("div", { class: "choice-list-empty", part: "choice-list-empty" }, "No matches")))), this.renderPromptPartial(screen, "form-content-end"), hasPromptPartials && (hAsync("div", { class: "form-footer", part: "form-footer" }, this.renderPromptPartial(screen, "form-footer-start"), footerComponents.map((component) => (hAsync("authhero-node", { key: component.id, component: component, locale: this.locale, value: this.formData[component.id], onFieldChange: (e) => this.handleInputChange(e.detail.id, e.detail.value), onButtonClick: (e) => this.handleButtonClick(e.detail), disabled: this.loading ||
8945
+ (component.type === "NEXT_BUTTON" &&
8946
+ component.config?.skip_validation !== true &&
8947
+ requiredFieldsMissing) }))), this.renderPromptPartial(screen, "form-footer-end")))), hasPromptPartials && (hAsync("div", { class: "secondary-actions", part: "secondary-actions" }, this.renderPromptPartial(screen, "secondary-actions-start"), this.renderScreenLinks(screen), this.renderPromptPartial(screen, "secondary-actions-end")))), !hasPromptPartials && this.renderScreenLinks(screen), screen.footer && (hAsync("div", { class: "widget-footer", part: "footer", innerHTML: sanitizeHtml(screen.footer) })))));
8816
8948
  }
8817
8949
  static get watchers() { return {
8818
8950
  "screenId": [{
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@authhero/widget",
3
- "version": "0.40.2",
3
+ "version": "0.41.0",
4
4
  "description": "Server-Driven UI widget for AuthHero authentication flows",
5
5
  "repository": {
6
6
  "type": "git",
7
- "url": "https://github.com/markusahlstrand/authhero",
7
+ "url": "https://github.com/sesamyab/authhero",
8
8
  "directory": "packages/ui-widget"
9
9
  },
10
10
  "files": [
@@ -42,7 +42,7 @@
42
42
  },
43
43
  "dependencies": {
44
44
  "country-list": "^2.4.1",
45
- "@authhero/adapter-interfaces": "4.18.0"
45
+ "@authhero/adapter-interfaces": "4.20.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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;");for(const[t,i]of Object.entries(g)){if("br"===t){e=e.replace(/&lt;br\s*\/?&gt;/gi,"<br>");continue}const o=new RegExp(`&lt;${t}((?:\\s+[a-z-]+(?:=&quot;[^&]*&quot;|=&#39;[^&]*&#39;)?)*)\\s*&gt;`,"gi");e=e.replace(o,((e,o)=>{const n=[];if(o){const t=o.replace(/&quot;/g,'"').replace(/&#39;/g,"'").replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/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(`&lt;/${t}&gt;`,"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,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}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}