@authhero/widget 0.10.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authhero-widget/authhero-widget.esm.js +1 -1
- package/dist/authhero-widget/p-130714cc.entry.js +1 -0
- package/dist/authhero-widget/p-2c7cceee.entry.js +1 -0
- package/dist/cjs/authhero-node.cjs.entry.js +25 -102
- package/dist/cjs/authhero-widget.cjs.entry.js +54 -1
- package/dist/cjs/authhero-widget.cjs.js +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/collection/components/authhero-node/authhero-node.css +21 -0
- package/dist/collection/components/authhero-node/authhero-node.js +24 -101
- package/dist/collection/components/authhero-widget/authhero-widget.js +54 -1
- package/dist/components/authhero-node.js +1 -1
- package/dist/components/authhero-widget.js +1 -1
- package/dist/components/p-DCgjvHcp.js +1 -0
- package/dist/esm/authhero-node.entry.js +25 -102
- package/dist/esm/authhero-widget.entry.js +54 -1
- package/dist/esm/authhero-widget.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/types/components/authhero-widget/authhero-widget.d.ts +6 -0
- package/hydrate/index.js +79 -103
- package/hydrate/index.mjs +79 -103
- package/package.json +1 -1
- package/dist/authhero-widget/p-1625b214.entry.js +0 -1
- package/dist/authhero-widget/p-55e6c943.entry.js +0 -1
- package/dist/components/p-Cuu5Lfc5.js +0 -1
package/hydrate/index.js
CHANGED
|
@@ -4971,7 +4971,7 @@ var setScopedSSR = (opts) => {
|
|
|
4971
4971
|
var needsScopedSSR = () => scopedSSR;
|
|
4972
4972
|
var scopedSSR = false;
|
|
4973
4973
|
|
|
4974
|
-
const authheroNodeCss = () => `:host{display:block}.input-wrapper{display:flex;flex-direction:column;position:relative;margin-bottom:16px}.input-container{position:relative;width:100%}.input-label{position:absolute;left:16px;top:50%;transform:translateY(-50%);font-size:16px;font-weight:var(--ah-font-weight-label, 400);color:var(--ah-color-text-muted, #65676e);pointer-events:none;transition:all 0.15s ease-out;background-color:transparent;padding:0;z-index:1}.input-label.floating,.input-field:focus+.input-label,.input-field:not(:placeholder-shown)+.input-label{top:-8px;transform:translateY(0);font-size:12px;background-color:var(--ah-color-bg, #ffffff);padding:0 4px;left:12px;color:var(--ah-color-text-muted, #65676e)}.input-field:focus+.input-label{color:var(--ah-color-primary, #635dff)}.required{color:var(--ah-color-error, #d03c38);margin-left:2px}.input-field{width:100%;padding:16px;font-size:16px;font-family:inherit;color:var(--ah-color-text, #1e212a);background-color:var(--ah-color-input-bg, #ffffff);border:1px solid var(--ah-color-border, #c9cace);border-radius:var(--ah-input-radius, 3px);outline:none;transition:border-color 0.15s ease-out, box-shadow 0.15s ease-out;box-sizing:border-box}.input-field::placeholder{color:transparent}.input-field:hover{border-color:var(--ah-color-border-hover, #65676e)}.input-field:focus{border-color:var(--ah-color-primary, #635dff);box-shadow:inset 0 0 0 1px var(--ah-color-primary, #635dff)}.input-field.has-error{border-color:var(--ah-color-error, #d03c38)}.input-field.has-error:focus{box-shadow:inset 0 0 0 1px var(--ah-color-error, #d03c38)}.input-field:disabled{background-color:var(--ah-color-bg-disabled, #f5f5f5);border-color:var(--ah-color-border-disabled, #e0e1e3);cursor:not-allowed;opacity:0.7}.password-container{position:relative;display:flex;align-items:center}.password-container .input-field{padding-right:48px}.password-toggle{position:absolute;right:12px;top:50%;transform:translateY(-50%);background:none;border:none;cursor:pointer;padding:4px;display:flex;align-items:center;justify-content:center;color:var(--ah-color-text-muted, #65676e);transition:color 0.15s ease}.password-toggle:hover{color:var(--ah-color-text, #1e212a)}.password-toggle svg{width:20px;height:20px}.error-text{font-size:12px;color:var(--ah-color-error, #d03c38);margin-top:4px;line-height:1.4}.helper-text{font-size:12px;color:var(--ah-color-text-muted, #65676e);margin-top:4px;line-height:1.4}.field-link{display:block;text-align:left;margin-top:8px;margin-bottom:16px}.field-link a{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:14px;font-weight:var(--ah-font-weight-link, 400)}.field-link a:hover{text-decoration:underline}.checkbox-wrapper{display:flex;align-items:flex-start;gap:10px;cursor:pointer;margin-bottom:16px}.checkbox-wrapper input[type="checkbox"]{width:18px;height:18px;margin:0;accent-color:var(--ah-color-primary, #635dff);cursor:pointer;flex-shrink:0}.checkbox-label{font-size:14px;color:var(--ah-color-text, #1e212a);line-height:1.5}.btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;width:100%;padding:14px 20px;font-size:16px;font-weight:var(--ah-font-weight-btn, 400);font-family:inherit;line-height:1.25;text-align:center;text-decoration:none;border:none;border-radius:var(--ah-btn-radius, 3px);cursor:pointer;transition:background-color 0.15s ease, border-color 0.15s ease, transform 0.1s ease;box-sizing:border-box}.btn:disabled{opacity:0.6;cursor:not-allowed}.btn:not(:disabled):active{transform:scale(0.98)}.btn:focus-visible{outline:2px solid var(--ah-color-primary, #635dff);outline-offset:2px}.btn-primary{background-color:var(--ah-color-primary, #635dff);color:var(--ah-color-text-on-primary, #ffffff);margin-top:12px}.btn-primary:not(:disabled):hover{filter:brightness(0.85)}.btn-secondary{background-color:var(--ah-color-bg, #ffffff);color:var(--ah-color-text, #1e212a);border:1px solid var(--ah-color-border, #c9cace)}.btn-secondary:not(:disabled):hover{background-color:var(--ah-color-bg-hover, #f5f5f5);border-color:var(--ah-color-border-hover, #65676e)}.btn-link{background:none;border:none;color:var(--ah-color-link, #635dff);padding:8px 0;font-weight:var(--ah-font-weight-link, 400);text-decoration:none}.btn-link:hover{text-decoration:underline}.social-buttons{display:flex;flex-direction:column;gap:12px}.btn-social{display:flex;align-items:center;justify-content:center;gap:12px}.social-icon{width:20px;height:20px;flex-shrink:0}@media (max-width: 480px){.social-buttons:has(.btn-social:nth-child(3)){flex-direction:row;flex-wrap:nowrap;justify-content:stretch;gap:8px}.social-buttons:has(.btn-social:nth-child(3)) .btn-social{width:auto;min-width:0;padding:12px;flex:1 1 0}.social-buttons:has(.btn-social:nth-child(3)) .btn-social span{display:none}.social-buttons:has(.btn-social:nth-child(3)) .social-icon{width:24px;height:24px}}.btn-icon{width:20px;height:20px;flex-shrink:0}.btn-icon img{width:100%;height:100%;object-fit:contain}.text-title{font-size:20px;font-weight:400;color:var(--ah-color-text, #1e212a);margin:8px 0;line-height:1.3}.text-title.text-success{color:var(--ah-color-success, #13a769)}.text-description{font-size:14px;color:var(--ah-color-text-muted, #65676e);margin:4px 0;line-height:1.5}.image{display:block;max-width:100%;height:auto;border-radius:4px}.image-centered{margin:0 auto 16px;width:52px;height:52px;object-fit:contain}.link{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:14px;transition:color 0.15s ease}.link:hover{text-decoration:underline}.link:focus-visible{outline:2px solid var(--ah-color-link, #635dff);outline-offset:2px;border-radius:2px}.node-error{padding:12px 16px;background-color:var(--ah-color-error-bg, #ffeaea);color:var(--ah-color-error, #d03c38);border-left:3px solid var(--ah-color-error, #d03c38);border-radius:0;font-size:14px;margin-bottom:16px}.node-success{padding:12px 16px;background-color:var(--ah-color-success-bg, #e6f9f1);color:var(--ah-color-success, #13a769);border-left:3px solid var(--ah-color-success, #13a769);border-radius:0;font-size:14px;margin-bottom:16px}.divider{display:flex;align-items:center;text-align:center;margin:16px 0}.divider::before,.divider::after{content:"";flex:1;border-bottom:1px solid var(--ah-color-border-muted, #c9cace)}.divider-text{padding:0 10px;font-size:12px;font-weight:400;color:var(--ah-color-text-muted, #65676e);text-transform:uppercase;letter-spacing:0.5px}`;
|
|
4974
|
+
const authheroNodeCss = () => `:host{display:block}.input-wrapper{display:flex;flex-direction:column;position:relative;margin-bottom:16px}.input-container{position:relative;width:100%}.input-label{position:absolute;left:16px;top:50%;transform:translateY(-50%);font-size:16px;font-weight:var(--ah-font-weight-label, 400);color:var(--ah-color-text-muted, #65676e);pointer-events:none;transition:all 0.15s ease-out;background-color:transparent;padding:0;z-index:1}.input-label.floating,.input-field:focus+.input-label,.input-field:not(:placeholder-shown)+.input-label{top:-8px;transform:translateY(0);font-size:12px;background-color:var(--ah-color-bg, #ffffff);padding:0 4px;left:12px;color:var(--ah-color-text-muted, #65676e)}.input-field:focus+.input-label{color:var(--ah-color-primary, #635dff)}.required{color:var(--ah-color-error, #d03c38);margin-left:2px}.input-field{width:100%;padding:16px;font-size:16px;font-family:inherit;color:var(--ah-color-text, #1e212a);background-color:var(--ah-color-input-bg, #ffffff);border:1px solid var(--ah-color-border, #c9cace);border-radius:var(--ah-input-radius, 3px);outline:none;transition:border-color 0.15s ease-out, box-shadow 0.15s ease-out;box-sizing:border-box}.input-field::placeholder{color:transparent}.input-field:hover{border-color:var(--ah-color-border-hover, #65676e)}.input-field:focus{border-color:var(--ah-color-primary, #635dff);box-shadow:inset 0 0 0 1px var(--ah-color-primary, #635dff)}.input-field.has-error{border-color:var(--ah-color-error, #d03c38)}.input-field.has-error:focus{box-shadow:inset 0 0 0 1px var(--ah-color-error, #d03c38)}.input-field:disabled{background-color:var(--ah-color-bg-disabled, #f5f5f5);border-color:var(--ah-color-border-disabled, #e0e1e3);cursor:not-allowed;opacity:0.7}.password-container{position:relative;display:flex;align-items:center}.password-container .input-field{padding-right:48px}.password-toggle{position:absolute;right:12px;top:50%;transform:translateY(-50%);background:none;border:none;cursor:pointer;padding:4px;display:flex;align-items:center;justify-content:center;color:var(--ah-color-text-muted, #65676e);transition:color 0.15s ease}.password-toggle:hover{color:var(--ah-color-text, #1e212a)}.password-toggle svg{width:20px;height:20px}.error-text{font-size:12px;color:var(--ah-color-error, #d03c38);margin-top:4px;line-height:1.4}.helper-text{font-size:12px;color:var(--ah-color-text-muted, #65676e);margin-top:4px;line-height:1.4}.field-link{display:block;text-align:left;margin-top:8px;margin-bottom:16px}.field-link a{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:14px;font-weight:var(--ah-font-weight-link, 400)}.field-link a:hover{text-decoration:underline}.checkbox-wrapper{display:flex;align-items:flex-start;gap:10px;cursor:pointer;margin-bottom:16px}.checkbox-wrapper input[type="checkbox"]{width:18px;height:18px;margin:0;accent-color:var(--ah-color-primary, #635dff);cursor:pointer;flex-shrink:0}.checkbox-label{font-size:14px;color:var(--ah-color-text, #1e212a);line-height:1.5}.btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;width:100%;padding:14px 20px;font-size:16px;font-weight:var(--ah-font-weight-btn, 400);font-family:inherit;line-height:1.25;text-align:center;text-decoration:none;border:none;border-radius:var(--ah-btn-radius, 3px);cursor:pointer;transition:background-color 0.15s ease, border-color 0.15s ease, transform 0.1s ease;box-sizing:border-box}.btn:disabled{opacity:0.6;cursor:not-allowed}.btn:not(:disabled):active{transform:scale(0.98)}.btn:focus-visible{outline:2px solid var(--ah-color-primary, #635dff);outline-offset:2px}.btn-primary{background-color:var(--ah-color-primary, #635dff);color:var(--ah-color-text-on-primary, #ffffff);margin-top:12px}.btn-primary:not(:disabled):hover{filter:brightness(0.85)}.btn-secondary{background-color:var(--ah-color-bg, #ffffff);color:var(--ah-color-text, #1e212a);border:1px solid var(--ah-color-border, #c9cace)}.btn-secondary:not(:disabled):hover{background-color:var(--ah-color-bg-hover, #f5f5f5);border-color:var(--ah-color-border-hover, #65676e)}.btn-link{background:none;border:none;color:var(--ah-color-link, #635dff);padding:8px 0;font-weight:var(--ah-font-weight-link, 400);text-decoration:none}.btn-link:hover{text-decoration:underline}.social-buttons{display:flex;flex-direction:column;gap:12px}.btn-social{display:flex;align-items:center;justify-content:center;gap:12px}.btn-social-content{display:flex;flex-direction:column;align-items:center;text-align:center}.btn-social-subtitle{font-size:12px;font-style:italic;opacity:0.8;margin-top:2px}.btn-social-subtitle:empty{display:none}.social-icon{width:20px;height:20px;flex-shrink:0}@media (max-width: 480px){.social-buttons:has(.btn-social:nth-child(3)){flex-direction:row;flex-wrap:nowrap;justify-content:stretch;gap:8px}.social-buttons:has(.btn-social:nth-child(3)) .btn-social{width:auto;min-width:0;padding:12px;flex:1 1 0}.social-buttons:has(.btn-social:nth-child(3)) .btn-social span{display:none}.social-buttons:has(.btn-social:nth-child(3)) .social-icon{width:24px;height:24px}}.btn-icon{width:20px;height:20px;flex-shrink:0}.btn-icon img{width:100%;height:100%;object-fit:contain}.text-title{font-size:20px;font-weight:400;color:var(--ah-color-text, #1e212a);margin:8px 0;line-height:1.3}.text-title.text-success{color:var(--ah-color-success, #13a769)}.text-description{font-size:14px;color:var(--ah-color-text-muted, #65676e);margin:4px 0;line-height:1.5}.image{display:block;max-width:100%;height:auto;border-radius:4px}.image-centered{margin:0 auto 16px;width:52px;height:52px;object-fit:contain}.link{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:14px;transition:color 0.15s ease}.link:hover{text-decoration:underline}.link:focus-visible{outline:2px solid var(--ah-color-link, #635dff);outline-offset:2px;border-radius:2px}.node-error{padding:12px 16px;background-color:var(--ah-color-error-bg, #ffeaea);color:var(--ah-color-error, #d03c38);border-left:3px solid var(--ah-color-error, #d03c38);border-radius:0;font-size:14px;margin-bottom:16px}.node-success{padding:12px 16px;background-color:var(--ah-color-success-bg, #e6f9f1);color:var(--ah-color-success, #13a769);border-left:3px solid var(--ah-color-success, #13a769);border-radius:0;font-size:14px;margin-bottom:16px}.divider{display:flex;align-items:center;text-align:center;margin:16px 0}.divider::before,.divider::after{content:"";flex:1;border-bottom:1px solid var(--ah-color-border-muted, #c9cace)}.divider-text{padding:0 10px;font-size:12px;font-weight:400;color:var(--ah-color-text-muted, #65676e);text-transform:uppercase;letter-spacing:0.5px}`;
|
|
4975
4975
|
|
|
4976
4976
|
class AuthheroNode {
|
|
4977
4977
|
constructor(hostRef) {
|
|
@@ -5103,7 +5103,7 @@ class AuthheroNode {
|
|
|
5103
5103
|
return (hAsync("div", { class: "rich-text", part: "rich-text", innerHTML: component.config?.content ?? "" }));
|
|
5104
5104
|
}
|
|
5105
5105
|
renderNextButton(component) {
|
|
5106
|
-
return (hAsync("button", { type: "submit", class: "btn btn-primary", part: "button button-primary", disabled: this.disabled, onClick: (e) => this.handleButtonClick(e, "submit", "next") }, component.config.text ?? "Continue"));
|
|
5106
|
+
return (hAsync("button", { type: "submit", class: "btn btn-primary", part: "button button-primary", "data-primary-action-button": true, disabled: this.disabled, onClick: (e) => this.handleButtonClick(e, "submit", "next") }, component.config.text ?? "Continue"));
|
|
5107
5107
|
}
|
|
5108
5108
|
renderPreviousButton(component) {
|
|
5109
5109
|
return (hAsync("button", { type: "button", class: "btn btn-secondary", part: "button button-secondary", disabled: this.disabled, onClick: (e) => this.handleButtonClick(e, "previous", "back") }, component.config.text ?? "Back"));
|
|
@@ -5125,20 +5125,20 @@ class AuthheroNode {
|
|
|
5125
5125
|
if (multiline) {
|
|
5126
5126
|
return (hAsync("div", { class: "input-wrapper", part: "input-wrapper" }, this.renderLabel(component.label, inputId, component.required), hAsync("textarea", { id: inputId, class: { "input-field": true, "has-error": errors.length > 0 }, part: "input textarea", name: component.id, placeholder: " ", required: component.required, disabled: this.disabled, maxLength: max_length, onInput: this.handleInput }, this.value ?? ""), this.renderErrors(), errors.length === 0 && this.renderHint(component.hint)));
|
|
5127
5127
|
}
|
|
5128
|
-
return (hAsync("div", { class: "input-wrapper", part: "input-wrapper" }, hAsync("div", { class: "input-container" }, hAsync("input", { id: inputId, class: { "input-field": true, "has-error": errors.length > 0 }, part: "input", type: component.sensitive ? "password" : "text", name: component.id, value: this.value ?? "", placeholder: " ", required: component.required, disabled: this.disabled, maxLength: max_length, onInput: this.handleInput }), this.renderFloatingLabel(component.label, inputId, component.required, hasValue)), this.renderErrors(), errors.length === 0 && this.renderHint(component.hint)));
|
|
5128
|
+
return (hAsync("div", { class: "input-wrapper", part: "input-wrapper" }, hAsync("div", { class: "input-container" }, hAsync("input", { id: inputId, class: { "input-field": true, "has-error": errors.length > 0 }, part: "input", type: component.sensitive ? "password" : "text", name: component.id, "data-input-name": component.id, value: this.value ?? "", placeholder: " ", required: component.required, disabled: this.disabled, maxLength: max_length, onInput: this.handleInput }), this.renderFloatingLabel(component.label, inputId, component.required, hasValue)), this.renderErrors(), errors.length === 0 && this.renderHint(component.hint)));
|
|
5129
5129
|
}
|
|
5130
5130
|
renderEmailField(component) {
|
|
5131
5131
|
const inputId = `input-${component.id}`;
|
|
5132
5132
|
const errors = this.getErrors();
|
|
5133
5133
|
const hasValue = !!(this.value && this.value.length > 0);
|
|
5134
|
-
return (hAsync("div", { class: "input-wrapper", part: "input-wrapper" }, hAsync("div", { class: "input-container" }, hAsync("input", { id: inputId, class: { "input-field": true, "has-error": errors.length > 0 }, part: "input", type: "email", name: component.id, value: this.value ?? "", placeholder: " ", required: component.required, disabled: this.disabled, autocomplete: "email", onInput: this.handleInput }), this.renderFloatingLabel(component.label, inputId, component.required, hasValue)), this.renderErrors(), errors.length === 0 && this.renderHint(component.hint)));
|
|
5134
|
+
return (hAsync("div", { class: "input-wrapper", part: "input-wrapper" }, hAsync("div", { class: "input-container" }, hAsync("input", { id: inputId, class: { "input-field": true, "has-error": errors.length > 0 }, part: "input", type: "email", name: component.id, "data-input-name": component.id, value: this.value ?? "", placeholder: " ", required: component.required, disabled: this.disabled, autocomplete: "email", onInput: this.handleInput }), this.renderFloatingLabel(component.label, inputId, component.required, hasValue)), this.renderErrors(), errors.length === 0 && this.renderHint(component.hint)));
|
|
5135
5135
|
}
|
|
5136
5136
|
renderPasswordField(component) {
|
|
5137
5137
|
const inputId = `input-${component.id}`;
|
|
5138
5138
|
const errors = this.getErrors();
|
|
5139
5139
|
const hasValue = !!(this.value && this.value.length > 0);
|
|
5140
5140
|
const forgotPasswordLink = component.config?.forgot_password_link;
|
|
5141
|
-
return (hAsync("div", { class: "input-wrapper", part: "input-wrapper" }, hAsync("div", { class: "input-container password-container" }, hAsync("input", { id: inputId, class: { "input-field": true, "has-error": errors.length > 0 }, part: "input", type: this.passwordVisible ? "text" : "password", name: component.id, value: this.value ?? "", placeholder: " ", required: component.required, disabled: this.disabled, minLength: component.config?.min_length, autocomplete: "current-password", onInput: this.handleInput }), this.renderFloatingLabel(component.label, inputId, component.required, hasValue), hAsync("button", { type: "button", class: "password-toggle", part: "password-toggle", onClick: this.togglePasswordVisibility, "aria-label": "Toggle password visibility", "aria-pressed": this.passwordVisible ? "true" : "false" }, this.renderPasswordToggle())), this.renderErrors(), errors.length === 0 && this.renderHint(component.hint), forgotPasswordLink && (hAsync("div", { class: "field-link", part: "field-link" }, hAsync("a", { href: forgotPasswordLink, class: "link", part: "link" }, "Forgot password?")))));
|
|
5141
|
+
return (hAsync("div", { class: "input-wrapper", part: "input-wrapper" }, hAsync("div", { class: "input-container password-container" }, hAsync("input", { id: inputId, class: { "input-field": true, "has-error": errors.length > 0 }, part: "input", type: this.passwordVisible ? "text" : "password", name: component.id, "data-input-name": component.id, value: this.value ?? "", placeholder: " ", required: component.required, disabled: this.disabled, minLength: component.config?.min_length, autocomplete: "current-password", onInput: this.handleInput }), this.renderFloatingLabel(component.label, inputId, component.required, hasValue), hAsync("button", { type: "button", class: "password-toggle", part: "password-toggle", onClick: this.togglePasswordVisibility, "aria-label": "Toggle password visibility", "aria-pressed": this.passwordVisible ? "true" : "false" }, this.renderPasswordToggle())), this.renderErrors(), errors.length === 0 && this.renderHint(component.hint), forgotPasswordLink && (hAsync("div", { class: "field-link", part: "field-link" }, hAsync("a", { href: forgotPasswordLink, class: "link", part: "link" }, "Forgot password?")))));
|
|
5142
5142
|
}
|
|
5143
5143
|
renderNumberField(component) {
|
|
5144
5144
|
const inputId = `input-${component.id}`;
|
|
@@ -5188,115 +5188,38 @@ class AuthheroNode {
|
|
|
5188
5188
|
const providerDetails = component.config?.provider_details;
|
|
5189
5189
|
// Create a map of provider details for quick lookup
|
|
5190
5190
|
const detailsMap = new Map(providerDetails?.map((d) => [d.name, d]) ?? []);
|
|
5191
|
-
//
|
|
5192
|
-
const
|
|
5193
|
-
"google-oauth2",
|
|
5194
|
-
"google",
|
|
5195
|
-
"facebook",
|
|
5196
|
-
"apple",
|
|
5197
|
-
"github",
|
|
5198
|
-
"microsoft",
|
|
5199
|
-
"windowslive",
|
|
5200
|
-
"linkedin",
|
|
5201
|
-
"vipps",
|
|
5202
|
-
];
|
|
5203
|
-
// Find matching known provider from name or strategy
|
|
5204
|
-
const findKnownProvider = (name, strategy) => {
|
|
5205
|
-
const nameLower = name.toLowerCase();
|
|
5206
|
-
const strategyLower = strategy?.toLowerCase();
|
|
5207
|
-
// First check exact match on strategy
|
|
5208
|
-
if (strategyLower && knownProviders.includes(strategyLower)) {
|
|
5209
|
-
return strategyLower;
|
|
5210
|
-
}
|
|
5211
|
-
// Then check exact match on name
|
|
5212
|
-
if (knownProviders.includes(nameLower)) {
|
|
5213
|
-
return nameLower;
|
|
5214
|
-
}
|
|
5215
|
-
// Check if name contains a known provider (e.g., "Vipps Login" contains "vipps")
|
|
5216
|
-
for (const known of knownProviders) {
|
|
5217
|
-
if (nameLower.includes(known)) {
|
|
5218
|
-
return known;
|
|
5219
|
-
}
|
|
5220
|
-
}
|
|
5221
|
-
return null;
|
|
5222
|
-
};
|
|
5223
|
-
// Map provider IDs to display names
|
|
5224
|
-
const getProviderDisplayName = (provider) => {
|
|
5225
|
-
// First check provider_details
|
|
5191
|
+
// Get button text from provider_details (already contains the full button text from server)
|
|
5192
|
+
const getButtonText = (provider) => {
|
|
5226
5193
|
const details = detailsMap.get(provider);
|
|
5227
5194
|
if (details?.display_name) {
|
|
5228
5195
|
return details.display_name;
|
|
5229
5196
|
}
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
linkedin: "LinkedIn",
|
|
5236
|
-
apple: "Apple",
|
|
5237
|
-
microsoft: "Microsoft",
|
|
5238
|
-
windowslive: "Microsoft",
|
|
5239
|
-
amazon: "Amazon",
|
|
5240
|
-
dropbox: "Dropbox",
|
|
5241
|
-
bitbucket: "Bitbucket",
|
|
5242
|
-
spotify: "Spotify",
|
|
5243
|
-
slack: "Slack",
|
|
5244
|
-
discord: "Discord",
|
|
5245
|
-
twitch: "Twitch",
|
|
5246
|
-
line: "LINE",
|
|
5247
|
-
shopify: "Shopify",
|
|
5248
|
-
paypal: "PayPal",
|
|
5249
|
-
"paypal-sandbox": "PayPal",
|
|
5250
|
-
box: "Box",
|
|
5251
|
-
salesforce: "Salesforce",
|
|
5252
|
-
"salesforce-sandbox": "Salesforce",
|
|
5253
|
-
yahoo: "Yahoo",
|
|
5254
|
-
auth0: "Auth0",
|
|
5255
|
-
vipps: "Vipps",
|
|
5256
|
-
};
|
|
5257
|
-
return (displayNames[provider.toLowerCase()] ||
|
|
5258
|
-
provider
|
|
5259
|
-
.split("-")
|
|
5260
|
-
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
5261
|
-
.join(" "));
|
|
5197
|
+
// Fallback: use provider name with basic formatting
|
|
5198
|
+
return provider
|
|
5199
|
+
.split("-")
|
|
5200
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
5201
|
+
.join(" ");
|
|
5262
5202
|
};
|
|
5263
|
-
// Get provider icon
|
|
5203
|
+
// Get provider icon from provider_details icon_url
|
|
5264
5204
|
const getProviderIcon = (provider) => {
|
|
5265
|
-
// First check if we have a custom icon URL from provider_details
|
|
5266
5205
|
const details = detailsMap.get(provider);
|
|
5206
|
+
const safeProvider = this.sanitizeForCssToken(provider);
|
|
5267
5207
|
if (details?.icon_url) {
|
|
5268
|
-
return (hAsync("img", { class: "social-icon", src: details.icon_url, alt: details.display_name || provider }));
|
|
5269
|
-
}
|
|
5270
|
-
// Try to find a known provider from name or strategy
|
|
5271
|
-
const knownProvider = findKnownProvider(provider, details?.strategy);
|
|
5272
|
-
const p = knownProvider || provider.toLowerCase();
|
|
5273
|
-
if (p === "google-oauth2" || p === "google") {
|
|
5274
|
-
return (hAsync("svg", { class: "social-icon", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, hAsync("path", { d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z", fill: "#4285F4" }), hAsync("path", { d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z", fill: "#34A853" }), hAsync("path", { d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z", fill: "#FBBC05" }), hAsync("path", { d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z", fill: "#EA4335" })));
|
|
5275
|
-
}
|
|
5276
|
-
if (p === "facebook") {
|
|
5277
|
-
return (hAsync("svg", { class: "social-icon", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, hAsync("path", { d: "M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z", fill: "#1877F2" })));
|
|
5278
|
-
}
|
|
5279
|
-
if (p === "apple") {
|
|
5280
|
-
return (hAsync("svg", { class: "social-icon", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, hAsync("path", { d: "M17.05 20.28c-.98.95-2.05.8-3.08.35-1.09-.46-2.09-.48-3.24 0-1.44.62-2.2.44-3.06-.35C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09l.01-.01zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z", fill: "#000000" })));
|
|
5281
|
-
}
|
|
5282
|
-
if (p === "github") {
|
|
5283
|
-
return (hAsync("svg", { class: "social-icon", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, hAsync("path", { d: "M12 0C5.374 0 0 5.373 0 12c0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23A11.509 11.509 0 0112 5.803c1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576C20.566 21.797 24 17.3 24 12c0-6.627-5.373-12-12-12z", fill: "#181717" })));
|
|
5284
|
-
}
|
|
5285
|
-
if (p === "microsoft" || p === "windowslive") {
|
|
5286
|
-
return (hAsync("svg", { class: "social-icon", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, hAsync("path", { d: "M0 0h11.377v11.372H0V0z", fill: "#f25022" }), hAsync("path", { d: "M12.623 0H24v11.372H12.623V0z", fill: "#7fba00" }), hAsync("path", { d: "M0 12.623h11.377V24H0v-11.377z", fill: "#00a4ef" }), hAsync("path", { d: "M12.623 12.623H24V24H12.623v-11.377z", fill: "#ffb900" })));
|
|
5287
|
-
}
|
|
5288
|
-
if (p === "linkedin") {
|
|
5289
|
-
return (hAsync("svg", { class: "social-icon", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, hAsync("path", { d: "M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z", fill: "#0A66C2" })));
|
|
5290
|
-
}
|
|
5291
|
-
if (p === "vipps") {
|
|
5292
|
-
return (hAsync("svg", { class: "social-icon", viewBox: "0 0 48 48", xmlns: "http://www.w3.org/2000/svg" }, hAsync("path", { fill: "#FF5B24", d: "M3.5,8h41c1.9,0,3.5,1.6,3.5,3.5v25c0,1.9-1.6,3.5-3.5,3.5h-41C1.6,40,0,38.4,0,36.5v-25C0,9.6,1.6,8,3.5,8z" }), hAsync("path", { fill: "#FFFFFF", d: "M27.9,20.3c1.4,0,2.6-1,2.6-2.5c0-1.5-1.2-2.5-2.6-2.5c-1.4,0-2.6,1-2.6,2.5C25.3,19.2,26.5,20.3,27.9,20.3z" }), hAsync("path", { fill: "#FFFFFF", d: "M31.2,24.4c-1.7,2.2-3.5,3.8-6.7,3.8c-3.2,0-5.8-2-7.7-4.8c-0.8-1.2-2-1.4-2.9-0.8c-0.8,0.6-1,1.8-0.3,2.9c2.7,4.1,6.5,6.6,10.9,6.6c4,0,7.2-2,9.6-5.2c0.9-1.2,0.9-2.5,0-3.1C33.3,22.9,32.1,23.2,31.2,24.4z" })));
|
|
5208
|
+
return (hAsync("img", { class: "social-icon", part: `social-icon social-icon-${safeProvider}`, src: details.icon_url, alt: details.display_name || provider }));
|
|
5293
5209
|
}
|
|
5294
|
-
//
|
|
5295
|
-
return
|
|
5210
|
+
// No icon provided - return null (button will just show text)
|
|
5211
|
+
return null;
|
|
5212
|
+
};
|
|
5213
|
+
// Get strategy from provider details
|
|
5214
|
+
const getProviderStrategy = (provider) => {
|
|
5215
|
+
const details = detailsMap.get(provider);
|
|
5216
|
+
return details?.strategy ?? provider;
|
|
5296
5217
|
};
|
|
5297
5218
|
return (hAsync("div", { class: "social-buttons", part: "social-buttons" }, providers.map((provider) => {
|
|
5298
5219
|
const safeProvider = this.sanitizeForCssToken(provider);
|
|
5299
|
-
|
|
5220
|
+
const strategy = getProviderStrategy(provider);
|
|
5221
|
+
const icon = getProviderIcon(provider);
|
|
5222
|
+
return (hAsync("button", { type: "button", class: `btn btn-secondary btn-social btn-social-${safeProvider}${icon ? "" : " no-icon"}`, part: `button button-secondary button-social button-social-${safeProvider}`, "data-connection-name": provider, "data-strategy": strategy, disabled: this.disabled, onClick: (e) => this.handleButtonClick(e, "SOCIAL", provider), key: provider }, icon, hAsync("span", { class: "btn-social-content", part: `button-social-content button-social-content-${safeProvider}` }, hAsync("span", { part: `button-social-text button-social-text-${safeProvider}` }, getButtonText(provider)), hAsync("span", { class: "btn-social-subtitle", part: `button-social-subtitle button-social-subtitle-${safeProvider}` }))));
|
|
5300
5223
|
})));
|
|
5301
5224
|
}
|
|
5302
5225
|
// ===========================================================================
|
|
@@ -5850,6 +5773,9 @@ class AuthheroWidget {
|
|
|
5850
5773
|
* When statePersistence is 'url', this is synced with the URL.
|
|
5851
5774
|
*/
|
|
5852
5775
|
screenId;
|
|
5776
|
+
watchScreenId() {
|
|
5777
|
+
this.updateDataScreenAttribute();
|
|
5778
|
+
}
|
|
5853
5779
|
/**
|
|
5854
5780
|
* OAuth/OIDC parameters for social login redirects.
|
|
5855
5781
|
* Can be passed as a JSON string or object.
|
|
@@ -5966,6 +5892,19 @@ class AuthheroWidget {
|
|
|
5966
5892
|
}
|
|
5967
5893
|
if (this._screen) {
|
|
5968
5894
|
this.screenChange.emit(this._screen);
|
|
5895
|
+
this.updateDataScreenAttribute();
|
|
5896
|
+
}
|
|
5897
|
+
}
|
|
5898
|
+
/**
|
|
5899
|
+
* Updates the data-screen attribute on the host element.
|
|
5900
|
+
* This allows external CSS to target different screens using attribute selectors.
|
|
5901
|
+
*/
|
|
5902
|
+
updateDataScreenAttribute() {
|
|
5903
|
+
if (this.screenId) {
|
|
5904
|
+
this.el.setAttribute("data-screen", this.screenId);
|
|
5905
|
+
}
|
|
5906
|
+
else {
|
|
5907
|
+
this.el.removeAttribute("data-screen");
|
|
5969
5908
|
}
|
|
5970
5909
|
}
|
|
5971
5910
|
watchBranding(newValue) {
|
|
@@ -6157,6 +6096,7 @@ class AuthheroWidget {
|
|
|
6157
6096
|
this.screenId = currentScreenId;
|
|
6158
6097
|
}
|
|
6159
6098
|
this.screenChange.emit(this._screen);
|
|
6099
|
+
this.updateDataScreenAttribute();
|
|
6160
6100
|
this.persistState();
|
|
6161
6101
|
}
|
|
6162
6102
|
}
|
|
@@ -6229,11 +6169,17 @@ class AuthheroWidget {
|
|
|
6229
6169
|
this._screen = result.screen;
|
|
6230
6170
|
this.formData = {};
|
|
6231
6171
|
this.screenChange.emit(result.screen);
|
|
6172
|
+
this.updateDataScreenAttribute();
|
|
6232
6173
|
// Update screenId if returned in response
|
|
6233
6174
|
if (result.screenId) {
|
|
6234
6175
|
this.screenId = result.screenId;
|
|
6235
6176
|
}
|
|
6177
|
+
// Persist state (especially for session storage mode)
|
|
6236
6178
|
this.persistState();
|
|
6179
|
+
// Update URL path if navigateUrl is provided (client-side navigation)
|
|
6180
|
+
if (result.navigateUrl && this.shouldAutoNavigate) {
|
|
6181
|
+
window.history.pushState({ screen: result.screenId, state: this.state }, "", result.navigateUrl);
|
|
6182
|
+
}
|
|
6237
6183
|
// Apply branding if included
|
|
6238
6184
|
if (result.branding) {
|
|
6239
6185
|
this._branding = result.branding;
|
|
@@ -6253,6 +6199,7 @@ class AuthheroWidget {
|
|
|
6253
6199
|
if (!response.ok && result.screen) {
|
|
6254
6200
|
this._screen = result.screen;
|
|
6255
6201
|
this.screenChange.emit(result.screen);
|
|
6202
|
+
this.updateDataScreenAttribute();
|
|
6256
6203
|
}
|
|
6257
6204
|
}
|
|
6258
6205
|
}
|
|
@@ -6404,9 +6351,35 @@ class AuthheroWidget {
|
|
|
6404
6351
|
const socialComponents = components.filter((c) => this.isSocialComponent(c));
|
|
6405
6352
|
const fieldComponents = components.filter((c) => !this.isSocialComponent(c) && !this.isDividerComponent(c));
|
|
6406
6353
|
const hasDivider = components.some((c) => this.isDividerComponent(c));
|
|
6354
|
+
// Build dynamic exportparts for social buttons including provider-specific parts
|
|
6355
|
+
const getExportParts = (component) => {
|
|
6356
|
+
const baseParts = [
|
|
6357
|
+
"social-buttons",
|
|
6358
|
+
"button",
|
|
6359
|
+
"button-secondary",
|
|
6360
|
+
"button-social",
|
|
6361
|
+
"button-social-content",
|
|
6362
|
+
"button-social-text",
|
|
6363
|
+
"button-social-subtitle",
|
|
6364
|
+
"social-icon",
|
|
6365
|
+
];
|
|
6366
|
+
const config = component.config;
|
|
6367
|
+
const providers = config?.providers ?? [];
|
|
6368
|
+
const providerParts = providers.flatMap((p) => {
|
|
6369
|
+
const safe = p.replace(/[^a-zA-Z0-9-]/g, "-");
|
|
6370
|
+
return [
|
|
6371
|
+
`button-social-${safe}`,
|
|
6372
|
+
`button-social-content-${safe}`,
|
|
6373
|
+
`button-social-text-${safe}`,
|
|
6374
|
+
`button-social-subtitle-${safe}`,
|
|
6375
|
+
`social-icon-${safe}`,
|
|
6376
|
+
];
|
|
6377
|
+
});
|
|
6378
|
+
return [...baseParts, ...providerParts].join(", ");
|
|
6379
|
+
};
|
|
6407
6380
|
// Get logo URL from theme.widget (takes precedence) or branding
|
|
6408
6381
|
const logoUrl = this._theme?.widget?.logo_url || this._branding?.logo_url;
|
|
6409
|
-
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", innerHTML: sanitizeHtml(this._screen.title) })), this._screen.description && (hAsync("p", { class: "description", part: "description", innerHTML: sanitizeHtml(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 &&
|
|
6382
|
+
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" }))), this._screen.title && (hAsync("h1", { class: "title", part: "title", innerHTML: sanitizeHtml(this._screen.title) })), this._screen.description && (hAsync("p", { class: "description", part: "description", innerHTML: sanitizeHtml(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, exportparts: getExportParts(component) }))))), socialComponents.length > 0 &&
|
|
6410
6383
|
fieldComponents.length > 0 &&
|
|
6411
6384
|
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, {
|
|
6412
6385
|
id: link.id,
|
|
@@ -6419,6 +6392,9 @@ class AuthheroWidget {
|
|
|
6419
6392
|
}) }, link.text))))))))));
|
|
6420
6393
|
}
|
|
6421
6394
|
static get watchers() { return {
|
|
6395
|
+
"screenId": [{
|
|
6396
|
+
"watchScreenId": 0
|
|
6397
|
+
}],
|
|
6422
6398
|
"screen": [{
|
|
6423
6399
|
"watchScreen": 0
|
|
6424
6400
|
}],
|