@authhero/widget 0.7.2 → 0.8.1

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.js CHANGED
@@ -5616,8 +5616,43 @@ class AuthheroWidget {
5616
5616
  /**
5617
5617
  * API endpoint to fetch the initial screen from.
5618
5618
  * If provided, the widget will fetch the screen on load.
5619
+ * Can include {screenId} placeholder which will be replaced with the current screen.
5620
+ * Example: "/u2/screen/{screenId}" or "https://auth.example.com/u2/screen/{screenId}"
5619
5621
  */
5620
5622
  apiUrl;
5623
+ /**
5624
+ * Base URL for all API calls. Used when widget is embedded on a different domain.
5625
+ * If not provided, relative URLs are used.
5626
+ * Example: "https://auth.example.com"
5627
+ */
5628
+ baseUrl;
5629
+ /**
5630
+ * Login session state token. Required for social login and maintaining session.
5631
+ */
5632
+ state;
5633
+ /**
5634
+ * Current screen ID. Used with apiUrl to fetch screen configuration.
5635
+ * When statePersistence is 'url', this is synced with the URL.
5636
+ */
5637
+ screenId;
5638
+ /**
5639
+ * OAuth/OIDC parameters for social login redirects.
5640
+ * Can be passed as a JSON string or object.
5641
+ */
5642
+ authParams;
5643
+ /**
5644
+ * Where to persist state and screen ID.
5645
+ * - 'url': Updates URL path/query (default for standalone pages)
5646
+ * - 'session': Uses sessionStorage (for embedded widgets)
5647
+ * - 'memory': No persistence, state only in memory
5648
+ * @default 'memory'
5649
+ */
5650
+ statePersistence = "memory";
5651
+ /**
5652
+ * Storage key prefix for session/local storage persistence.
5653
+ * @default 'authhero_widget'
5654
+ */
5655
+ storageKey = "authhero_widget";
5621
5656
  /**
5622
5657
  * Branding configuration from AuthHero API.
5623
5658
  * Controls logo, primary color, and page background.
@@ -5642,10 +5677,21 @@ class AuthheroWidget {
5642
5677
  * @default false
5643
5678
  */
5644
5679
  autoSubmit = false;
5680
+ /**
5681
+ * Whether the widget should handle navigation automatically.
5682
+ * When true, social login buttons redirect, links navigate, etc.
5683
+ * When false, only events are emitted.
5684
+ * @default false (same as autoSubmit when not specified)
5685
+ */
5686
+ autoNavigate;
5645
5687
  /**
5646
5688
  * Internal parsed screen state.
5647
5689
  */
5648
5690
  _screen;
5691
+ /**
5692
+ * Internal parsed auth params state.
5693
+ */
5694
+ _authParams;
5649
5695
  /**
5650
5696
  * Internal parsed branding state.
5651
5697
  */
@@ -5692,12 +5738,12 @@ class AuthheroWidget {
5692
5738
  */
5693
5739
  screenChange;
5694
5740
  watchScreen(newValue) {
5695
- if (typeof newValue === 'string') {
5741
+ if (typeof newValue === "string") {
5696
5742
  try {
5697
5743
  this._screen = JSON.parse(newValue);
5698
5744
  }
5699
5745
  catch {
5700
- console.error('Failed to parse screen JSON');
5746
+ console.error("Failed to parse screen JSON");
5701
5747
  }
5702
5748
  }
5703
5749
  else {
@@ -5708,12 +5754,12 @@ class AuthheroWidget {
5708
5754
  }
5709
5755
  }
5710
5756
  watchBranding(newValue) {
5711
- if (typeof newValue === 'string') {
5757
+ if (typeof newValue === "string") {
5712
5758
  try {
5713
5759
  this._branding = JSON.parse(newValue);
5714
5760
  }
5715
5761
  catch {
5716
- console.error('Failed to parse branding JSON');
5762
+ console.error("Failed to parse branding JSON");
5717
5763
  }
5718
5764
  }
5719
5765
  else {
@@ -5722,12 +5768,12 @@ class AuthheroWidget {
5722
5768
  this.applyThemeStyles();
5723
5769
  }
5724
5770
  watchTheme(newValue) {
5725
- if (typeof newValue === 'string') {
5771
+ if (typeof newValue === "string") {
5726
5772
  try {
5727
5773
  this._theme = JSON.parse(newValue);
5728
5774
  }
5729
5775
  catch {
5730
- console.error('Failed to parse theme JSON');
5776
+ console.error("Failed to parse theme JSON");
5731
5777
  }
5732
5778
  }
5733
5779
  else {
@@ -5735,6 +5781,19 @@ class AuthheroWidget {
5735
5781
  }
5736
5782
  this.applyThemeStyles();
5737
5783
  }
5784
+ watchAuthParams(newValue) {
5785
+ if (typeof newValue === "string") {
5786
+ try {
5787
+ this._authParams = JSON.parse(newValue);
5788
+ }
5789
+ catch {
5790
+ console.error("Failed to parse authParams JSON");
5791
+ }
5792
+ }
5793
+ else {
5794
+ this._authParams = newValue;
5795
+ }
5796
+ }
5738
5797
  /**
5739
5798
  * Apply branding and theme as CSS custom properties
5740
5799
  */
@@ -5742,36 +5801,164 @@ class AuthheroWidget {
5742
5801
  const vars = mergeThemeVars(this._branding, this._theme);
5743
5802
  applyCssVars(this.el, vars);
5744
5803
  }
5804
+ /**
5805
+ * Get the effective autoNavigate value (defaults to autoSubmit if not set)
5806
+ */
5807
+ get shouldAutoNavigate() {
5808
+ return this.autoNavigate ?? this.autoSubmit;
5809
+ }
5810
+ /**
5811
+ * Build the full URL for API calls
5812
+ */
5813
+ buildUrl(path) {
5814
+ if (this.baseUrl) {
5815
+ return new URL(path, this.baseUrl).toString();
5816
+ }
5817
+ return path;
5818
+ }
5819
+ /**
5820
+ * Load state from URL or storage based on statePersistence setting
5821
+ */
5822
+ loadPersistedState() {
5823
+ if (this.statePersistence === "url") {
5824
+ const url = new URL(window.location.href);
5825
+ const stateParam = url.searchParams.get("state");
5826
+ if (stateParam && !this.state) {
5827
+ this.state = stateParam;
5828
+ }
5829
+ }
5830
+ else if (this.statePersistence === "session") {
5831
+ try {
5832
+ const stored = sessionStorage.getItem(`${this.storageKey}_state`);
5833
+ if (stored && !this.state) {
5834
+ this.state = stored;
5835
+ }
5836
+ const storedScreenId = sessionStorage.getItem(`${this.storageKey}_screenId`);
5837
+ if (storedScreenId && !this.screenId) {
5838
+ this.screenId = storedScreenId;
5839
+ }
5840
+ }
5841
+ catch {
5842
+ // sessionStorage not available
5843
+ }
5844
+ }
5845
+ }
5846
+ /**
5847
+ * Save state to URL or storage based on statePersistence setting
5848
+ */
5849
+ persistState() {
5850
+ if (this.statePersistence === "url") {
5851
+ const url = new URL(window.location.href);
5852
+ if (this.state) {
5853
+ url.searchParams.set("state", this.state);
5854
+ }
5855
+ if (this.screenId) {
5856
+ url.searchParams.set("screen", this.screenId);
5857
+ }
5858
+ window.history.replaceState({}, "", url.toString());
5859
+ }
5860
+ else if (this.statePersistence === "session") {
5861
+ try {
5862
+ if (this.state) {
5863
+ sessionStorage.setItem(`${this.storageKey}_state`, this.state);
5864
+ }
5865
+ if (this.screenId) {
5866
+ sessionStorage.setItem(`${this.storageKey}_screenId`, this.screenId);
5867
+ }
5868
+ }
5869
+ catch {
5870
+ // sessionStorage not available
5871
+ }
5872
+ }
5873
+ }
5745
5874
  async componentWillLoad() {
5746
5875
  // Parse initial props
5747
5876
  this.watchScreen(this.screen);
5748
5877
  this.watchBranding(this.branding);
5749
5878
  this.watchTheme(this.theme);
5879
+ this.watchAuthParams(this.authParams);
5880
+ // Load persisted state if available
5881
+ this.loadPersistedState();
5750
5882
  // Fetch screen from API if URL provided and no screen prop
5751
5883
  if (this.apiUrl && !this._screen) {
5752
- await this.fetchScreen();
5884
+ await this.fetchScreen(this.screenId);
5753
5885
  }
5754
5886
  }
5755
- async fetchScreen() {
5887
+ /**
5888
+ * Fetch screen configuration from the API
5889
+ * @param screenIdOverride Optional screen ID to fetch (overrides this.screenId)
5890
+ * @param nodeId Optional node ID for flow navigation
5891
+ */
5892
+ async fetchScreen(screenIdOverride, nodeId) {
5756
5893
  if (!this.apiUrl)
5757
5894
  return;
5895
+ const currentScreenId = screenIdOverride || this.screenId;
5896
+ // Build the API URL, replacing {screenId} placeholder if present
5897
+ let url = this.apiUrl;
5898
+ if (currentScreenId && url.includes("{screenId}")) {
5899
+ url = url.replace("{screenId}", encodeURIComponent(currentScreenId));
5900
+ }
5901
+ // Add state and nodeId as query params
5902
+ const urlObj = new URL(url, this.baseUrl || window.location.origin);
5903
+ if (this.state) {
5904
+ urlObj.searchParams.set("state", this.state);
5905
+ }
5906
+ if (nodeId) {
5907
+ urlObj.searchParams.set("nodeId", nodeId);
5908
+ }
5758
5909
  this.loading = true;
5759
5910
  try {
5760
- const response = await fetch(this.apiUrl, {
5761
- credentials: 'include',
5911
+ const response = await fetch(this.buildUrl(urlObj.pathname + urlObj.search), {
5912
+ credentials: "include",
5762
5913
  headers: {
5763
- Accept: 'application/json',
5914
+ Accept: "application/json",
5764
5915
  },
5765
5916
  });
5766
5917
  if (response.ok) {
5767
- this._screen = await response.json();
5918
+ const data = await response.json();
5919
+ // Handle different response formats
5920
+ if (data.screen) {
5921
+ this._screen = data.screen;
5922
+ if (data.branding) {
5923
+ this._branding = data.branding;
5924
+ this.applyThemeStyles();
5925
+ }
5926
+ // Update state if returned
5927
+ if (data.state) {
5928
+ this.state = data.state;
5929
+ }
5930
+ // Update screenId if returned in response
5931
+ if (data.screenId) {
5932
+ this.screenId = data.screenId;
5933
+ }
5934
+ }
5935
+ else {
5936
+ // Response is the screen itself
5937
+ this._screen = data;
5938
+ }
5768
5939
  if (this._screen) {
5940
+ // If we fetched with a screenId override, update our stored screenId
5941
+ if (currentScreenId && currentScreenId !== this.screenId) {
5942
+ this.screenId = currentScreenId;
5943
+ }
5769
5944
  this.screenChange.emit(this._screen);
5945
+ this.persistState();
5770
5946
  }
5771
5947
  }
5948
+ else {
5949
+ const error = await response
5950
+ .json()
5951
+ .catch(() => ({ message: "Failed to load screen" }));
5952
+ this.flowError.emit({
5953
+ message: error.message || "Failed to load screen",
5954
+ });
5955
+ }
5772
5956
  }
5773
5957
  catch (error) {
5774
- console.error('Failed to fetch screen:', error);
5958
+ console.error("Failed to fetch screen:", error);
5959
+ this.flowError.emit({
5960
+ message: error instanceof Error ? error.message : "Failed to fetch screen",
5961
+ });
5775
5962
  }
5776
5963
  finally {
5777
5964
  this.loading = false;
@@ -5799,17 +5986,17 @@ class AuthheroWidget {
5799
5986
  // Submit to the server
5800
5987
  this.loading = true;
5801
5988
  try {
5802
- const response = await fetch(this._screen.action, {
5989
+ const response = await fetch(this.buildUrl(this._screen.action), {
5803
5990
  method: this._screen.method,
5804
- credentials: 'include',
5991
+ credentials: "include",
5805
5992
  headers: {
5806
- 'Content-Type': 'application/json',
5807
- Accept: 'application/json',
5993
+ "Content-Type": "application/json",
5994
+ Accept: "application/json",
5808
5995
  },
5809
5996
  body: JSON.stringify({ data: this.formData }),
5810
5997
  });
5811
- const contentType = response.headers.get('content-type');
5812
- if (contentType?.includes('application/json')) {
5998
+ const contentType = response.headers.get("content-type");
5999
+ if (contentType?.includes("application/json")) {
5813
6000
  const result = await response.json();
5814
6001
  // Handle different response types
5815
6002
  if (result.redirect) {
@@ -5817,17 +6004,31 @@ class AuthheroWidget {
5817
6004
  this.flowComplete.emit({ redirectUrl: result.redirect });
5818
6005
  // Also emit navigate for backwards compatibility
5819
6006
  this.navigate.emit({ url: result.redirect });
6007
+ // Auto-navigate if enabled
6008
+ if (this.shouldAutoNavigate) {
6009
+ window.location.href = result.redirect;
6010
+ }
5820
6011
  }
5821
6012
  else if (result.screen) {
5822
6013
  // Next screen
5823
6014
  this._screen = result.screen;
5824
6015
  this.formData = {};
5825
6016
  this.screenChange.emit(result.screen);
6017
+ // Update screenId if returned in response
6018
+ if (result.screenId) {
6019
+ this.screenId = result.screenId;
6020
+ }
6021
+ this.persistState();
5826
6022
  // Apply branding if included
5827
6023
  if (result.branding) {
5828
6024
  this._branding = result.branding;
5829
6025
  this.applyThemeStyles();
5830
6026
  }
6027
+ // Update state if returned
6028
+ if (result.state) {
6029
+ this.state = result.state;
6030
+ this.persistState();
6031
+ }
5831
6032
  }
5832
6033
  else if (result.complete) {
5833
6034
  // Flow complete without redirect
@@ -5841,9 +6042,9 @@ class AuthheroWidget {
5841
6042
  }
5842
6043
  }
5843
6044
  catch (err) {
5844
- console.error('Form submission failed:', err);
6045
+ console.error("Form submission failed:", err);
5845
6046
  this.flowError.emit({
5846
- message: err instanceof Error ? err.message : 'Form submission failed',
6047
+ message: err instanceof Error ? err.message : "Form submission failed",
5847
6048
  });
5848
6049
  }
5849
6050
  finally {
@@ -5852,14 +6053,79 @@ class AuthheroWidget {
5852
6053
  };
5853
6054
  handleButtonClick = (detail) => {
5854
6055
  // If this is a submit button click, trigger form submission
5855
- if (detail.type === 'submit') {
6056
+ if (detail.type === "submit") {
5856
6057
  // Create a synthetic submit event and call handleSubmit
5857
6058
  const syntheticEvent = { preventDefault: () => { } };
5858
6059
  this.handleSubmit(syntheticEvent);
5859
6060
  return;
5860
6061
  }
6062
+ // Always emit the event
5861
6063
  this.buttonClick.emit(detail);
6064
+ // Handle social login if autoNavigate is enabled
6065
+ if (detail.type === "SOCIAL" && detail.value && this.shouldAutoNavigate) {
6066
+ this.handleSocialLogin(detail.value);
6067
+ return;
6068
+ }
6069
+ // Handle resend button
6070
+ if (detail.type === "RESEND_BUTTON" && this.shouldAutoNavigate) {
6071
+ this.handleResend();
6072
+ return;
6073
+ }
5862
6074
  };
6075
+ /**
6076
+ * Handle social login redirect
6077
+ */
6078
+ handleSocialLogin(connection) {
6079
+ const params = this._authParams || {};
6080
+ const queryParams = {
6081
+ connection,
6082
+ };
6083
+ // Add state
6084
+ if (this.state) {
6085
+ queryParams.state = this.state;
6086
+ }
6087
+ else if (params.state) {
6088
+ queryParams.state = params.state;
6089
+ }
6090
+ // Add client_id
6091
+ if (params.client_id) {
6092
+ queryParams.client_id = params.client_id;
6093
+ }
6094
+ // Add optional params
6095
+ if (params.redirect_uri)
6096
+ queryParams.redirect_uri = params.redirect_uri;
6097
+ if (params.scope)
6098
+ queryParams.scope = params.scope;
6099
+ if (params.audience)
6100
+ queryParams.audience = params.audience;
6101
+ if (params.nonce)
6102
+ queryParams.nonce = params.nonce;
6103
+ if (params.response_type)
6104
+ queryParams.response_type = params.response_type;
6105
+ const socialUrl = this.buildUrl("/authorize?" + new URLSearchParams(queryParams).toString());
6106
+ // Emit navigate event and redirect
6107
+ this.navigate.emit({ url: socialUrl });
6108
+ window.location.href = socialUrl;
6109
+ }
6110
+ /**
6111
+ * Handle resend button click (e.g., resend OTP code)
6112
+ */
6113
+ async handleResend() {
6114
+ if (!this._screen?.action)
6115
+ return;
6116
+ try {
6117
+ const url = this._screen.action +
6118
+ (this._screen.action.includes("?") ? "&" : "?") +
6119
+ "action=resend";
6120
+ await fetch(this.buildUrl(url), {
6121
+ method: "POST",
6122
+ credentials: "include",
6123
+ });
6124
+ }
6125
+ catch (error) {
6126
+ console.error("Resend failed:", error);
6127
+ }
6128
+ }
5863
6129
  handleLinkClick = (e, link) => {
5864
6130
  // Emit the event so the consuming app can handle it
5865
6131
  this.linkClick.emit({
@@ -5867,9 +6133,9 @@ class AuthheroWidget {
5867
6133
  href: link.href,
5868
6134
  text: link.text,
5869
6135
  });
5870
- // If autoSubmit is enabled, let the browser handle the navigation
6136
+ // If autoNavigate is enabled, let the browser handle the navigation
5871
6137
  // Otherwise, prevent default and let the app decide
5872
- if (!this.autoSubmit) {
6138
+ if (!this.shouldAutoNavigate) {
5873
6139
  e.preventDefault();
5874
6140
  }
5875
6141
  };
@@ -5877,13 +6143,13 @@ class AuthheroWidget {
5877
6143
  * Get error messages from the screen-level messages array.
5878
6144
  */
5879
6145
  getScreenErrors() {
5880
- return this._screen?.messages?.filter((m) => m.type === 'error') || [];
6146
+ return this._screen?.messages?.filter((m) => m.type === "error") || [];
5881
6147
  }
5882
6148
  /**
5883
6149
  * Get success messages from the screen-level messages array.
5884
6150
  */
5885
6151
  getScreenSuccesses() {
5886
- return this._screen?.messages?.filter((m) => m.type === 'success') || [];
6152
+ return this._screen?.messages?.filter((m) => m.type === "success") || [];
5887
6153
  }
5888
6154
  /**
5889
6155
  * Sort components by order.
@@ -5901,13 +6167,13 @@ class AuthheroWidget {
5901
6167
  isSocialComponent(component) {
5902
6168
  // Check the type property directly - FormComponent has a 'type' field
5903
6169
  // SocialField has type 'SOCIAL'
5904
- return component.type === 'SOCIAL';
6170
+ return component.type === "SOCIAL";
5905
6171
  }
5906
6172
  /**
5907
6173
  * Check if a component is a divider.
5908
6174
  */
5909
6175
  isDividerComponent(component) {
5910
- return component.type === 'DIVIDER';
6176
+ return component.type === "DIVIDER";
5911
6177
  }
5912
6178
  render() {
5913
6179
  if (this.loading && !this._screen) {
@@ -5920,12 +6186,22 @@ class AuthheroWidget {
5920
6186
  const screenSuccesses = this.getScreenSuccesses();
5921
6187
  const components = this.getOrderedComponents();
5922
6188
  // Separate social, divider, and field components for layout ordering
5923
- const socialComponents = components.filter(c => this.isSocialComponent(c));
5924
- const fieldComponents = components.filter(c => !this.isSocialComponent(c) && !this.isDividerComponent(c));
5925
- const hasDivider = components.some(c => this.isDividerComponent(c));
6189
+ const socialComponents = components.filter((c) => this.isSocialComponent(c));
6190
+ const fieldComponents = components.filter((c) => !this.isSocialComponent(c) && !this.isDividerComponent(c));
6191
+ const hasDivider = components.some((c) => this.isDividerComponent(c));
5926
6192
  // Get logo URL from theme.widget (takes precedence) or branding
5927
6193
  const logoUrl = this._theme?.widget?.logo_url || this._branding?.logo_url;
5928
- return (hAsync("div", { class: "widget-container", part: "container" }, 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" }))), this._screen.title && (hAsync("h1", { class: "title", part: "title" }, this._screen.title)), this._screen.description && (hAsync("p", { class: "description", part: "description" }, this._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, part: "form" }, 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, 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 && fieldComponents.length > 0 && hasDivider && (hAsync("div", { class: "divider", part: "divider" }, hAsync("span", { class: "divider-text" }, "Or"))), hAsync("div", { class: "fields-section", part: "fields-section" }, fieldComponents.map((component) => (hAsync("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 && (hAsync("div", { class: "links", part: "links" }, this._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, { id: link.id, href: link.href, text: link.linkText || link.text }) }, link.linkText))) : (hAsync("a", { href: link.href, class: "link", part: "link", onClick: (e) => this.handleLinkClick(e, { id: link.id, href: link.href, text: link.text }) }, link.text))))))))));
6194
+ return (hAsync("div", { class: "widget-container", part: "container" }, 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" }))), this._screen.title && (hAsync("h1", { class: "title", part: "title" }, this._screen.title)), this._screen.description && (hAsync("p", { class: "description", part: "description" }, this._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, part: "form" }, 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, 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 &&
6195
+ fieldComponents.length > 0 &&
6196
+ hasDivider && (hAsync("div", { class: "divider", part: "divider" }, hAsync("span", { class: "divider-text" }, "Or"))), hAsync("div", { class: "fields-section", part: "fields-section" }, fieldComponents.map((component) => (hAsync("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 && (hAsync("div", { class: "links", part: "links" }, this._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, {
6197
+ id: link.id,
6198
+ href: link.href,
6199
+ text: link.linkText || link.text,
6200
+ }) }, link.linkText))) : (hAsync("a", { href: link.href, class: "link", part: "link", onClick: (e) => this.handleLinkClick(e, {
6201
+ id: link.id,
6202
+ href: link.href,
6203
+ text: link.text,
6204
+ }) }, link.text))))))))));
5929
6205
  }
5930
6206
  static get watchers() { return {
5931
6207
  "screen": [{
@@ -5936,6 +6212,9 @@ class AuthheroWidget {
5936
6212
  }],
5937
6213
  "theme": [{
5938
6214
  "watchTheme": 0
6215
+ }],
6216
+ "authParams": [{
6217
+ "watchAuthParams": 0
5939
6218
  }]
5940
6219
  }; }
5941
6220
  static get style() { return authheroWidgetCss(); }
@@ -5945,11 +6224,19 @@ class AuthheroWidget {
5945
6224
  "$members$": {
5946
6225
  "screen": [1],
5947
6226
  "apiUrl": [1, "api-url"],
6227
+ "baseUrl": [1, "base-url"],
6228
+ "state": [1025],
6229
+ "screenId": [1025, "screen-id"],
6230
+ "authParams": [1, "auth-params"],
6231
+ "statePersistence": [1, "state-persistence"],
6232
+ "storageKey": [1, "storage-key"],
5948
6233
  "branding": [1],
5949
6234
  "theme": [1],
5950
6235
  "loading": [1028],
5951
6236
  "autoSubmit": [4, "auto-submit"],
6237
+ "autoNavigate": [4, "auto-navigate"],
5952
6238
  "_screen": [32],
6239
+ "_authParams": [32],
5953
6240
  "_branding": [32],
5954
6241
  "_theme": [32],
5955
6242
  "formData": [32]