@authhero/widget 0.11.0 → 0.13.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.
Files changed (39) hide show
  1. package/dist/authhero-widget/authhero-widget.esm.js +1 -1
  2. package/dist/authhero-widget/index.esm.js +1 -1
  3. package/dist/authhero-widget/p-1107d60e.entry.js +1 -0
  4. package/dist/authhero-widget/p-5hZ8Vbm9.js +2 -0
  5. package/dist/authhero-widget/p-b2d3d319.entry.js +1 -0
  6. package/dist/cjs/authhero-node.cjs.entry.js +28 -15
  7. package/dist/cjs/authhero-widget.cjs.entry.js +107 -37
  8. package/dist/cjs/authhero-widget.cjs.js +3 -3
  9. package/dist/cjs/{index-I1frl4Am.js → index-vX5cgLV-.js} +1803 -166
  10. package/dist/cjs/index.cjs.js +5 -3
  11. package/dist/cjs/loader.cjs.js +2 -2
  12. package/dist/collection/collection-manifest.json +1 -1
  13. package/dist/collection/components/authhero-node/authhero-node.css +62 -0
  14. package/dist/collection/components/authhero-node/authhero-node.js +28 -17
  15. package/dist/collection/components/authhero-widget/authhero-widget.css +29 -0
  16. package/dist/collection/components/authhero-widget/authhero-widget.js +111 -45
  17. package/dist/components/authhero-node.js +1 -1
  18. package/dist/components/authhero-widget.js +1 -1
  19. package/dist/components/index.js +1 -1
  20. package/dist/components/p-CWVARG2s.js +1 -0
  21. package/dist/components/p-EokuR0qI.js +1 -0
  22. package/dist/esm/authhero-node.entry.js +28 -15
  23. package/dist/esm/authhero-widget.entry.js +107 -37
  24. package/dist/esm/authhero-widget.js +4 -4
  25. package/dist/esm/{index-ARKBiJrR.js → index-5hZ8Vbm9.js} +1803 -166
  26. package/dist/esm/index.js +5 -3
  27. package/dist/esm/loader.js +3 -3
  28. package/dist/types/components/authhero-node/authhero-node.d.ts +1 -0
  29. package/dist/types/components/authhero-widget/authhero-widget.d.ts +11 -12
  30. package/dist/types/components.d.ts +6 -27
  31. package/dist/types/stencil-public-runtime.d.ts +2 -54
  32. package/hydrate/index.js +20577 -20632
  33. package/hydrate/index.mjs +20577 -20632
  34. package/package.json +3 -3
  35. package/dist/authhero-widget/p-145b5ecd.entry.js +0 -1
  36. package/dist/authhero-widget/p-695138d6.entry.js +0 -1
  37. package/dist/authhero-widget/p-ARKBiJrR.js +0 -2
  38. package/dist/components/p-BMoS6Gag.js +0 -1
  39. package/dist/components/p-BbVVe_wV.js +0 -1
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-I1frl4Am.js');
3
+ var index = require('./index-vX5cgLV-.js');
4
4
 
5
5
  /**
6
6
  * AuthHero Widget - Branding Utilities
@@ -423,7 +423,7 @@ function escapeAttr(value) {
423
423
  .replace(/>/g, ">");
424
424
  }
425
425
 
426
- 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, 14px);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{max-width:var(--ah-widget-max-width, 400px);width:100%;margin:0 auto;background-color:var(--ah-color-bg, #ffffff);border-radius:var(--ah-widget-radius, 5px);box-shadow:var(--ah-widget-shadow, 0 4px 22px 0 rgba(0, 0, 0, 0.11));box-sizing:border-box}.widget-header{padding:var(--ah-header-padding, 40px 48px 24px)}.widget-body{padding:var(--ah-body-padding, 0 48px 40px)}.logo-wrapper{display:var(--ah-logo-display, flex);justify-content:var(--ah-logo-align, center);margin-bottom:8px}.logo{display:block;height:var(--ah-logo-height, 52px);max-width:100%;width:auto;object-fit:contain}.title{font-size:var(--ah-font-size-title, 24px);font-weight:var(--ah-font-weight-title, 700);text-align:var(--ah-title-align, center);margin:var(--ah-title-margin, 24px 0 8px);color:var(--ah-color-header, #1e212a);line-height:1.2}.description{font-size:var(--ah-font-size-description, 14px);text-align:var(--ah-title-align, center);margin:var(--ah-description-margin, 0 0 8px);color:var(--ah-color-text, #1e212a);line-height:1.5}.message{padding:12px 16px;border-radius:4px;margin-bottom:16px;font-size:14px;line-height:1.5}.message-error{background-color:var(--ah-color-error-bg, #ffeaea);color:var(--ah-color-error, #d03c38);border-left:3px solid var(--ah-color-error, #d03c38)}.message-success{background-color:var(--ah-color-success-bg, #e6f9f1);color:var(--ah-color-success, #13a769);border-left:3px solid var(--ah-color-success, #13a769)}form{display:flex;flex-direction:column}.form-content{display:flex;flex-direction:column}.social-section{display:flex;flex-direction:column;gap:8px;order:var(--ah-social-order, 2)}.fields-section{display:flex;flex-direction:column;order:var(--ah-fields-order, 0)}.divider{display:flex;align-items:center;text-align:center;margin:16px 0;order:var(--ah-divider-order, 1)}.divider::before,.divider::after{content:'';flex:1;border-bottom:1px solid var(--ah-color-border-muted, #c9cace)}.divider-text{padding:0 10px;font-size:12px;font-weight:400;color:var(--ah-color-text-muted, #65676e);text-transform:uppercase;letter-spacing:0}.links{display:flex;flex-direction:column;align-items:center;gap:8px;margin-top:16px}.link-wrapper{font-size:14px;color:var(--ah-color-text, #1e212a)}.link{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:14px;font-weight:var(--ah-font-weight-link, 400);transition:color 150ms ease}.link:hover{text-decoration:underline}.link:focus-visible{outline:2px solid var(--ah-color-link, #635dff);outline-offset:2px;border-radius:2px}.loading-spinner{width:32px;height:32px;margin:24px auto;border:3px solid var(--ah-color-border-muted, #e0e1e3);border-top-color:var(--ah-color-primary, #635dff);border-radius:50%;animation:spin 0.8s linear infinite}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.error-message{text-align:center;color:var(--ah-color-error, #d03c38);padding:16px;font-size:14px}@media (max-width: 480px){:host{display:block;width:100%;min-height:100vh;background-color:var(--ah-color-bg, #ffffff)}.widget-container{box-shadow:none;border-radius:0;max-width:none;width:100%;margin:0}.widget-header{padding:24px 16px 16px}.widget-body{padding:0 16px 24px}}`;
426
+ 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, 14px);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{max-width:var(--ah-widget-max-width, 400px);width:100%;margin:0 auto;background-color:var(--ah-color-bg, #ffffff);border-radius:var(--ah-widget-radius, 5px);box-shadow:var(--ah-widget-shadow, 0 4px 22px 0 rgba(0, 0, 0, 0.11));box-sizing:border-box}.widget-header{padding:var(--ah-header-padding, 40px 48px 24px)}.widget-body{padding:var(--ah-body-padding, 0 48px 40px)}.logo-wrapper{display:var(--ah-logo-display, flex);justify-content:var(--ah-logo-align, center);margin-bottom:8px}.logo{display:block;height:var(--ah-logo-height, 52px);max-width:100%;width:auto;object-fit:contain}.title{font-size:var(--ah-font-size-title, 24px);font-weight:var(--ah-font-weight-title, 700);text-align:var(--ah-title-align, center);margin:var(--ah-title-margin, 24px 0 8px);color:var(--ah-color-header, #1e212a);line-height:1.2}.description{font-size:var(--ah-font-size-description, 14px);text-align:var(--ah-title-align, center);margin:var(--ah-description-margin, 0 0 8px);color:var(--ah-color-text, #1e212a);line-height:1.5}.message{padding:12px 16px;border-radius:4px;margin-bottom:16px;font-size:14px;line-height:1.5}.message-error{background-color:var(--ah-color-error-bg, #ffeaea);color:var(--ah-color-error, #d03c38);border-left:3px solid var(--ah-color-error, #d03c38)}.message-success{background-color:var(--ah-color-success-bg, #e6f9f1);color:var(--ah-color-success, #13a769);border-left:3px solid var(--ah-color-success, #13a769)}form{display:flex;flex-direction:column}.form-content{display:flex;flex-direction:column}.social-section{display:flex;flex-direction:column;gap:8px;order:var(--ah-social-order, 2)}.fields-section{display:flex;flex-direction:column;order:var(--ah-fields-order, 0)}.divider{display:flex;align-items:center;text-align:center;margin:16px 0;order:var(--ah-divider-order, 1)}.divider::before,.divider::after{content:'';flex:1;border-bottom:1px solid var(--ah-color-border-muted, #c9cace)}.divider-text{padding:0 10px;font-size:12px;font-weight:400;color:var(--ah-color-text-muted, #65676e);text-transform:uppercase;letter-spacing:0}.links{display:flex;flex-direction:column;align-items:center;gap:8px;margin-top:16px}.link-wrapper{font-size:14px;color:var(--ah-color-text, #1e212a)}.link{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:14px;font-weight:var(--ah-font-weight-link, 400);transition:color 150ms ease}.link:hover{text-decoration:underline}.link:focus-visible{outline:2px solid var(--ah-color-link, #635dff);outline-offset:2px;border-radius:2px}.widget-footer{margin-top:16px;text-align:center;font-size:12px;color:var(--ah-color-text-muted, #65676e)}.widget-footer a{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:12px;transition:color 150ms ease}.widget-footer a:hover{text-decoration:underline}.widget-footer a:focus-visible{outline:2px solid var(--ah-color-link, #635dff);outline-offset:2px;border-radius:2px}.loading-spinner{width:32px;height:32px;margin:24px auto;border:3px solid var(--ah-color-border-muted, #e0e1e3);border-top-color:var(--ah-color-primary, #635dff);border-radius:50%;animation:spin 0.8s linear infinite}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.error-message{text-align:center;color:var(--ah-color-error, #d03c38);padding:16px;font-size:14px}@media (max-width: 480px){:host{display:block;width:100%;min-height:100vh;background-color:var(--ah-color-bg, #ffffff)}.widget-container{box-shadow:none;border-radius:0;max-width:none;width:100%;margin:0}.widget-header{padding:24px 16px 16px}.widget-body{padding:0 16px 24px}}`;
427
427
 
428
428
  const AuthheroWidget = class {
429
429
  constructor(hostRef) {
@@ -465,6 +465,9 @@ const AuthheroWidget = class {
465
465
  * When statePersistence is 'url', this is synced with the URL.
466
466
  */
467
467
  screenId;
468
+ watchScreenId() {
469
+ this.updateDataScreenAttribute();
470
+ }
468
471
  /**
469
472
  * OAuth/OIDC parameters for social login redirects.
470
473
  * Can be passed as a JSON string or object.
@@ -581,6 +584,19 @@ const AuthheroWidget = class {
581
584
  }
582
585
  if (this._screen) {
583
586
  this.screenChange.emit(this._screen);
587
+ this.updateDataScreenAttribute();
588
+ }
589
+ }
590
+ /**
591
+ * Updates the data-screen attribute on the host element.
592
+ * This allows external CSS to target different screens using attribute selectors.
593
+ */
594
+ updateDataScreenAttribute() {
595
+ if (this.screenId) {
596
+ this.el.setAttribute("data-screen", this.screenId);
597
+ }
598
+ else {
599
+ this.el.removeAttribute("data-screen");
584
600
  }
585
601
  }
586
602
  watchBranding(newValue) {
@@ -631,6 +647,30 @@ const AuthheroWidget = class {
631
647
  const vars = mergeThemeVars(this._branding, this._theme);
632
648
  applyCssVars(this.el, vars);
633
649
  }
650
+ /**
651
+ * Focus the first input field in the form.
652
+ * Called after screen changes to ensure keyboard navigation works properly.
653
+ */
654
+ focusFirstInput() {
655
+ // Use requestAnimationFrame to ensure DOM has updated
656
+ requestAnimationFrame(() => {
657
+ const shadowRoot = this.el.shadowRoot;
658
+ if (!shadowRoot)
659
+ return;
660
+ // Find all authhero-node components and look for inputs in their shadow DOMs
661
+ const nodes = shadowRoot.querySelectorAll("authhero-node");
662
+ for (const node of Array.from(nodes)) {
663
+ const nodeShadow = node.shadowRoot;
664
+ if (nodeShadow) {
665
+ const input = nodeShadow.querySelector('input:not([type="hidden"]):not([type="checkbox"]):not([disabled]), textarea:not([disabled])');
666
+ if (input) {
667
+ input.focus();
668
+ return;
669
+ }
670
+ }
671
+ }
672
+ });
673
+ }
634
674
  /**
635
675
  * Get the effective autoNavigate value (defaults to autoSubmit if not set)
636
676
  */
@@ -702,11 +742,23 @@ const AuthheroWidget = class {
702
742
  }
703
743
  }
704
744
  async componentWillLoad() {
705
- // Parse initial props
706
- this.watchScreen(this.screen);
707
- this.watchBranding(this.branding);
708
- this.watchTheme(this.theme);
709
- this.watchAuthParams(this.authParams);
745
+ // Parse initial props - this prevents unnecessary state changes during hydration that cause flashes
746
+ // Also check the element attribute as a fallback for hydration scenarios
747
+ if (!this._screen) {
748
+ const screenValue = this.screen || this.el?.getAttribute("screen");
749
+ if (screenValue) {
750
+ this.watchScreen(screenValue);
751
+ }
752
+ }
753
+ if (!this._branding) {
754
+ this.watchBranding(this.branding);
755
+ }
756
+ if (!this._theme) {
757
+ this.watchTheme(this.theme);
758
+ }
759
+ if (!this._authParams) {
760
+ this.watchAuthParams(this.authParams);
761
+ }
710
762
  // Load persisted state if available
711
763
  this.loadPersistedState();
712
764
  // Fetch screen from API if URL provided and no screen prop
@@ -772,7 +824,9 @@ const AuthheroWidget = class {
772
824
  this.screenId = currentScreenId;
773
825
  }
774
826
  this.screenChange.emit(this._screen);
827
+ this.updateDataScreenAttribute();
775
828
  this.persistState();
829
+ this.focusFirstInput();
776
830
  }
777
831
  }
778
832
  else {
@@ -844,6 +898,7 @@ const AuthheroWidget = class {
844
898
  this._screen = result.screen;
845
899
  this.formData = {};
846
900
  this.screenChange.emit(result.screen);
901
+ this.updateDataScreenAttribute();
847
902
  // Update screenId if returned in response
848
903
  if (result.screenId) {
849
904
  this.screenId = result.screenId;
@@ -864,6 +919,8 @@ const AuthheroWidget = class {
864
919
  this.state = result.state;
865
920
  this.persistState();
866
921
  }
922
+ // Focus first input on new screen
923
+ this.focusFirstInput();
867
924
  }
868
925
  else if (result.complete) {
869
926
  // Flow complete without redirect
@@ -873,6 +930,8 @@ const AuthheroWidget = class {
873
930
  if (!response.ok && result.screen) {
874
931
  this._screen = result.screen;
875
932
  this.screenChange.emit(result.screen);
933
+ this.updateDataScreenAttribute();
934
+ this.focusFirstInput();
876
935
  }
877
936
  }
878
937
  }
@@ -974,28 +1033,6 @@ const AuthheroWidget = class {
974
1033
  e.preventDefault();
975
1034
  }
976
1035
  };
977
- /**
978
- * Get error messages from the screen-level messages array.
979
- */
980
- getScreenErrors() {
981
- return this._screen?.messages?.filter((m) => m.type === "error") || [];
982
- }
983
- /**
984
- * Get success messages from the screen-level messages array.
985
- */
986
- getScreenSuccesses() {
987
- return this._screen?.messages?.filter((m) => m.type === "success") || [];
988
- }
989
- /**
990
- * Sort components by order.
991
- */
992
- getOrderedComponents() {
993
- if (!this._screen)
994
- return [];
995
- return [...this._screen.components]
996
- .filter((c) => c.visible !== false)
997
- .sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
998
- }
999
1036
  /**
1000
1037
  * Check if a component is a social button.
1001
1038
  */
@@ -1011,24 +1048,54 @@ const AuthheroWidget = class {
1011
1048
  return component.type === "DIVIDER";
1012
1049
  }
1013
1050
  render() {
1014
- if (this.loading && !this._screen) {
1051
+ const screen = this._screen;
1052
+ if (this.loading && !screen) {
1015
1053
  return (index.h("div", { class: "widget-container" }, index.h("div", { class: "loading-spinner" })));
1016
1054
  }
1017
- if (!this._screen) {
1055
+ if (!screen) {
1018
1056
  return (index.h("div", { class: "widget-container" }, index.h("div", { class: "error-message" }, "No screen configuration provided")));
1019
1057
  }
1020
- const screenErrors = this.getScreenErrors();
1021
- const screenSuccesses = this.getScreenSuccesses();
1022
- const components = this.getOrderedComponents();
1058
+ // Use the local screen variable for all rendering
1059
+ const screenErrors = screen.messages?.filter((m) => m.type === "error") || [];
1060
+ const screenSuccesses = screen.messages?.filter((m) => m.type === "success") || [];
1061
+ const components = [...(screen.components ?? [])]
1062
+ .filter((c) => c.visible !== false)
1063
+ .sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
1023
1064
  // Separate social, divider, and field components for layout ordering
1024
1065
  const socialComponents = components.filter((c) => this.isSocialComponent(c));
1025
1066
  const fieldComponents = components.filter((c) => !this.isSocialComponent(c) && !this.isDividerComponent(c));
1026
1067
  const hasDivider = components.some((c) => this.isDividerComponent(c));
1068
+ // Build dynamic exportparts for social buttons including provider-specific parts
1069
+ const getExportParts = (component) => {
1070
+ const baseParts = [
1071
+ "social-buttons",
1072
+ "button",
1073
+ "button-secondary",
1074
+ "button-social",
1075
+ "button-social-content",
1076
+ "button-social-text",
1077
+ "button-social-subtitle",
1078
+ "social-icon",
1079
+ ];
1080
+ const config = component.config;
1081
+ const providers = config?.providers ?? [];
1082
+ const providerParts = providers.flatMap((p) => {
1083
+ const safe = p.replace(/[^a-zA-Z0-9-]/g, "-");
1084
+ return [
1085
+ `button-social-${safe}`,
1086
+ `button-social-content-${safe}`,
1087
+ `button-social-text-${safe}`,
1088
+ `button-social-subtitle-${safe}`,
1089
+ `social-icon-${safe}`,
1090
+ ];
1091
+ });
1092
+ return [...baseParts, ...providerParts].join(", ");
1093
+ };
1027
1094
  // Get logo URL from theme.widget (takes precedence) or branding
1028
1095
  const logoUrl = this._theme?.widget?.logo_url || this._branding?.logo_url;
1029
- return (index.h("div", { class: "widget-container", part: "container" }, index.h("header", { class: "widget-header", part: "header" }, logoUrl && (index.h("div", { class: "logo-wrapper", part: "logo-wrapper" }, index.h("img", { class: "logo", part: "logo", src: logoUrl, alt: "Logo" }))), this._screen.title && (index.h("h1", { class: "title", part: "title", innerHTML: sanitizeHtml(this._screen.title) })), this._screen.description && (index.h("p", { class: "description", part: "description", innerHTML: sanitizeHtml(this._screen.description) }))), index.h("div", { class: "widget-body", part: "body" }, screenErrors.map((err) => (index.h("div", { class: "message message-error", part: "message message-error", key: err.id ?? err.text }, err.text))), screenSuccesses.map((msg) => (index.h("div", { class: "message message-success", part: "message message-success", key: msg.id ?? msg.text }, msg.text))), index.h("form", { onSubmit: this.handleSubmit, part: "form" }, index.h("div", { class: "form-content" }, socialComponents.length > 0 && (index.h("div", { class: "social-section", part: "social-section" }, socialComponents.map((component) => (index.h("authhero-node", { key: component.id, component: component, value: this.formData[component.id], onFieldChange: (e) => this.handleInputChange(e.detail.id, e.detail.value), onButtonClick: (e) => this.handleButtonClick(e.detail), disabled: this.loading }))))), socialComponents.length > 0 &&
1096
+ return (index.h("div", { class: "widget-container", part: "container", "data-authstack-container": true }, index.h("header", { class: "widget-header", part: "header" }, logoUrl && (index.h("div", { class: "logo-wrapper", part: "logo-wrapper" }, index.h("img", { class: "logo", part: "logo", src: logoUrl, alt: "Logo" }))), screen.title && (index.h("h1", { class: "title", part: "title", innerHTML: sanitizeHtml(screen.title) })), screen.description && (index.h("p", { class: "description", part: "description", innerHTML: sanitizeHtml(screen.description) }))), index.h("div", { class: "widget-body", part: "body" }, screenErrors.map((err) => (index.h("div", { class: "message message-error", part: "message message-error", key: err.id ?? err.text }, err.text))), screenSuccesses.map((msg) => (index.h("div", { class: "message message-success", part: "message message-success", key: msg.id ?? msg.text }, msg.text))), index.h("form", { onSubmit: this.handleSubmit, part: "form" }, index.h("div", { class: "form-content" }, socialComponents.length > 0 && (index.h("div", { class: "social-section", part: "social-section" }, socialComponents.map((component) => (index.h("authhero-node", { key: component.id, component: component, value: this.formData[component.id], onFieldChange: (e) => this.handleInputChange(e.detail.id, e.detail.value), onButtonClick: (e) => this.handleButtonClick(e.detail), disabled: this.loading, exportparts: getExportParts(component) }))))), socialComponents.length > 0 &&
1030
1097
  fieldComponents.length > 0 &&
1031
- hasDivider && (index.h("div", { class: "divider", part: "divider" }, index.h("span", { class: "divider-text" }, "Or"))), index.h("div", { class: "fields-section", part: "fields-section" }, fieldComponents.map((component) => (index.h("authhero-node", { key: component.id, component: component, value: this.formData[component.id], onFieldChange: (e) => this.handleInputChange(e.detail.id, e.detail.value), onButtonClick: (e) => this.handleButtonClick(e.detail), disabled: this.loading })))))), this._screen.links && this._screen.links.length > 0 && (index.h("div", { class: "links", part: "links" }, this._screen.links.map((link) => (index.h("span", { class: "link-wrapper", part: "link-wrapper", key: link.id ?? link.href }, link.linkText ? (index.h("span", null, link.text, " ", index.h("a", { href: link.href, class: "link", part: "link", onClick: (e) => this.handleLinkClick(e, {
1098
+ hasDivider && (index.h("div", { class: "divider", part: "divider" }, index.h("span", { class: "divider-text" }, "Or"))), index.h("div", { class: "fields-section", part: "fields-section" }, fieldComponents.map((component) => (index.h("authhero-node", { key: component.id, component: component, value: this.formData[component.id], onFieldChange: (e) => this.handleInputChange(e.detail.id, e.detail.value), onButtonClick: (e) => this.handleButtonClick(e.detail), disabled: this.loading })))))), screen.links && screen.links.length > 0 && (index.h("div", { class: "links", part: "links" }, screen.links.map((link) => (index.h("span", { class: "link-wrapper", part: "link-wrapper", key: link.id ?? link.href }, link.linkText ? (index.h("span", null, link.text, " ", index.h("a", { href: link.href, class: "link", part: "link", onClick: (e) => this.handleLinkClick(e, {
1032
1099
  id: link.id,
1033
1100
  href: link.href,
1034
1101
  text: link.linkText || link.text,
@@ -1036,9 +1103,12 @@ const AuthheroWidget = class {
1036
1103
  id: link.id,
1037
1104
  href: link.href,
1038
1105
  text: link.text,
1039
- }) }, link.text))))))))));
1106
+ }) }, link.text))))))), screen.footer && (index.h("div", { class: "widget-footer", part: "footer", innerHTML: sanitizeHtml(screen.footer) })))));
1040
1107
  }
1041
1108
  static get watchers() { return {
1109
+ "screenId": [{
1110
+ "watchScreenId": 0
1111
+ }],
1042
1112
  "screen": [{
1043
1113
  "watchScreen": 0
1044
1114
  }],
@@ -1,11 +1,11 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-I1frl4Am.js');
3
+ var index = require('./index-vX5cgLV-.js');
4
4
  var appGlobals = require('./app-globals-V2Kpy_OQ.js');
5
5
 
6
6
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
7
7
  /*
8
- Stencil Client Patch Browser v4.42.0 | MIT Licensed | https://stenciljs.com
8
+ Stencil Client Patch Browser v4.40.1 | MIT Licensed | https://stenciljs.com
9
9
  */
10
10
 
11
11
  var patchBrowser = () => {
@@ -19,7 +19,7 @@ var patchBrowser = () => {
19
19
 
20
20
  patchBrowser().then(async (options) => {
21
21
  await appGlobals.globalScripts();
22
- return index.bootstrapLazy([["authhero-node.cjs",[[513,"authhero-node",{"component":[16],"value":[1],"disabled":[4],"passwordVisible":[32]}]]],["authhero-widget.cjs",[[513,"authhero-widget",{"screen":[1],"apiUrl":[1,"api-url"],"baseUrl":[1,"base-url"],"state":[1025],"screenId":[1025,"screen-id"],"authParams":[1,"auth-params"],"statePersistence":[1,"state-persistence"],"storageKey":[1,"storage-key"],"branding":[1],"theme":[1],"loading":[1028],"autoSubmit":[4,"auto-submit"],"autoNavigate":[4,"auto-navigate"],"_screen":[32],"_authParams":[32],"_branding":[32],"_theme":[32],"formData":[32]},null,{"screen":[{"watchScreen":0}],"branding":[{"watchBranding":0}],"theme":[{"watchTheme":0}],"authParams":[{"watchAuthParams":0}]}]]]], options);
22
+ return index.bootstrapLazy([["authhero-node.cjs",[[513,"authhero-node",{"component":[16],"value":[1],"disabled":[4],"passwordVisible":[32]}]]],["authhero-widget.cjs",[[513,"authhero-widget",{"screen":[1],"apiUrl":[1,"api-url"],"baseUrl":[1,"base-url"],"state":[1025],"screenId":[1025,"screen-id"],"authParams":[1,"auth-params"],"statePersistence":[1,"state-persistence"],"storageKey":[1,"storage-key"],"branding":[1],"theme":[1],"loading":[1028],"autoSubmit":[4,"auto-submit"],"autoNavigate":[4,"auto-navigate"],"_screen":[32],"_authParams":[32],"_branding":[32],"_theme":[32],"formData":[32]},null,{"screenId":[{"watchScreenId":0}],"screen":[{"watchScreen":0}],"branding":[{"watchBranding":0}],"theme":[{"watchTheme":0}],"authParams":[{"watchAuthParams":0}]}]]]], options);
23
23
  });
24
24
 
25
25
  exports.setNonce = index.setNonce;