@luminaryworks/auth-react 0.5.0 → 0.6.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/index.js CHANGED
@@ -1,4 +1,4 @@
1
- (function(){if(typeof document==="undefined")return;var id="lw-auth-react-headless-login";if(document.getElementById(id))return;var s=document.createElement("style");s.id=id;s.textContent="/* src/HeadlessLoginPanel.module.scss */\n.HeadlessLoginPanel_module_panel {\n --lw-auth-theme: #1677ff;\n --lw-auth-theme-deep: color-mix(in srgb, var(--lw-auth-theme) 72%, #000);\n width: min(100%, 400px);\n padding: 28px 28px 22px;\n border-radius: 16px;\n background: rgba(255, 255, 255, 0.96);\n color: #14212b;\n box-shadow: 0 24px 64px rgba(15, 23, 42, 0.28);\n font-family:\n \"Segoe UI\",\n \"PingFang SC\",\n \"Noto Sans SC\",\n sans-serif;\n}\n.HeadlessLoginPanel_module_brand {\n display: flex;\n gap: 14px;\n align-items: center;\n margin-bottom: 12px;\n}\n.HeadlessLoginPanel_module_logo {\n border-radius: 12px;\n display: block;\n}\n.HeadlessLoginPanel_module_product {\n margin: 0;\n font-size: 13px;\n font-weight: 650;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--lw-auth-theme);\n}\n.HeadlessLoginPanel_module_title {\n margin: 2px 0 0;\n font-size: 22px;\n font-weight: 700;\n line-height: 1.25;\n}\n.HeadlessLoginPanel_module_subtitle {\n margin: 0 0 18px;\n font-size: 14px;\n line-height: 1.5;\n color: #4b5c68;\n}\n.HeadlessLoginPanel_module_form {\n display: grid;\n gap: 10px;\n}\n.HeadlessLoginPanel_module_channelTabs {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 6px;\n margin-bottom: 2px;\n}\n.HeadlessLoginPanel_module_channelTab {\n border: 1px solid #c9d5de;\n border-radius: 10px;\n padding: 8px 10px;\n font-size: 13px;\n font-weight: 650;\n cursor: pointer;\n color: #4b5c68;\n background: #f7fafc;\n}\n.HeadlessLoginPanel_module_channelTab:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_channelTabActive {\n color: var(--lw-auth-theme-deep);\n border-color: var(--lw-auth-theme);\n background: color-mix(in srgb, var(--lw-auth-theme) 10%, #fff);\n}\n.HeadlessLoginPanel_module_codeRow {\n display: grid;\n grid-template-columns: 1fr auto;\n gap: 8px;\n align-items: stretch;\n}\n.HeadlessLoginPanel_module_codeInput {\n min-width: 0;\n}\n.HeadlessLoginPanel_module_secondaryBtn {\n border: 1px solid #b7c9d4;\n border-radius: 10px;\n padding: 0 12px;\n font-size: 13px;\n font-weight: 650;\n cursor: pointer;\n color: #14212b;\n background: #fff;\n white-space: nowrap;\n}\n.HeadlessLoginPanel_module_secondaryBtn:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_socialStack {\n display: flex;\n flex-wrap: wrap;\n gap: 10px;\n font-size: 12px;\n}\n.HeadlessLoginPanel_module_input {\n width: 100%;\n box-sizing: border-box;\n border: 1px solid #c9d5de;\n border-radius: 10px;\n padding: 10px 12px;\n font-size: 14px;\n outline: none;\n background: #f7fafc;\n}\n.HeadlessLoginPanel_module_input:focus {\n border-color: var(--lw-auth-theme);\n}\n.HeadlessLoginPanel_module_input:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_passwordField {\n position: relative;\n display: flex;\n align-items: center;\n}\n.HeadlessLoginPanel_module_passwordInput {\n padding-right: 42px;\n}\n.HeadlessLoginPanel_module_passwordToggle {\n position: absolute;\n right: 4px;\n top: 50%;\n transform: translateY(-50%);\n z-index: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border: none;\n border-radius: 4px;\n padding: 0;\n color: #5a6b76;\n background: transparent;\n cursor: pointer;\n}\n.HeadlessLoginPanel_module_passwordToggle:hover:not(:disabled) {\n color: var(--lw-auth-theme);\n background: color-mix(in srgb, var(--lw-auth-theme) 12%, transparent);\n}\n.HeadlessLoginPanel_module_passwordToggle:focus-visible {\n outline: 2px solid var(--lw-auth-theme);\n outline-offset: 1px;\n}\n.HeadlessLoginPanel_module_passwordToggle:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_primaryBtn {\n border: none;\n border-radius: 10px;\n padding: 11px 14px;\n font-size: 14px;\n font-weight: 650;\n cursor: pointer;\n color: #fff;\n background:\n linear-gradient(\n 135deg,\n var(--lw-auth-theme) 0%,\n var(--lw-auth-theme-deep) 100%);\n}\n.HeadlessLoginPanel_module_primaryBtn:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_socialBtn {\n flex: 1 1 calc(50% - 5px);\n min-width: min(140px, 100%);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n border: 1px solid #b7c9d4;\n border-radius: 10px;\n padding: 11px 10px;\n font-size: 14px;\n font-weight: 650;\n cursor: pointer;\n color: #14212b;\n background: #fff;\n}\n.HeadlessLoginPanel_module_socialBtn:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_socialLogo {\n flex-shrink: 0;\n display: block;\n}\n.HeadlessLoginPanel_module_logoFallback {\n width: 18px;\n height: 18px;\n border-radius: 4px;\n background: color-mix(in srgb, var(--lw-auth-theme) 14%, #fff);\n color: var(--lw-auth-theme-deep);\n font-size: 11px;\n font-weight: 700;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n.HeadlessLoginPanel_module_cancelBtn {\n margin-top: 10px;\n width: 100%;\n border: none;\n background: transparent;\n color: #5a6b76;\n font-size: 13px;\n cursor: pointer;\n padding: 8px;\n}\n.HeadlessLoginPanel_module_cancelBtn:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_divider {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 14px 0;\n color: #90a0ab;\n}\n.HeadlessLoginPanel_module_dividerLine {\n flex: 1;\n height: 1px;\n background: #d5e0e7;\n}\n.HeadlessLoginPanel_module_dividerText {\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n}\n.HeadlessLoginPanel_module_hint {\n margin: 10px 0 0;\n font-size: 12px;\n color: #6b7c87;\n line-height: 1.45;\n}\n.HeadlessLoginPanel_module_domainsHint {\n margin: -2px 0 0;\n font-size: 12px;\n line-height: 1.45;\n color: #4b5c68;\n word-break: break-word;\n}\n.HeadlessLoginPanel_module_switchMode {\n margin: 12px 0 0;\n text-align: center;\n}\n.HeadlessLoginPanel_module_switchModeBtn {\n border: none;\n background: transparent;\n color: var(--lw-auth-theme);\n font-size: 13px;\n font-weight: 650;\n cursor: pointer;\n padding: 4px 8px;\n text-decoration: underline;\n text-underline-offset: 3px;\n}\n.HeadlessLoginPanel_module_switchModeBtn:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_error {\n margin: 12px 0 0;\n font-size: 13px;\n color: #b42318;\n line-height: 1.4;\n}\n.HeadlessLoginPanel_module_footer {\n margin-top: 18px;\n padding-top: 12px;\n border-top: 1px solid #e4ebf0;\n font-size: 12px;\n color: #6b7c87;\n display: flex;\n gap: 8px;\n justify-content: center;\n}\n/*# sourceMappingURL=index.css.map */";document.head.appendChild(s);})();
1
+ (function(){if(typeof document==="undefined")return;var id="lw-auth-react-headless-login";if(document.getElementById(id))return;var s=document.createElement("style");s.id=id;s.textContent="/* src/HeadlessLoginPanel.module.scss */\n.HeadlessLoginPanel_module_panel {\n --lw-auth-theme: #1677ff;\n --lw-auth-theme-deep: color-mix(in srgb, var(--lw-auth-theme) 72%, #000);\n width: min(100%, 400px);\n padding: 28px 28px 22px;\n border-radius: 16px;\n background: rgba(255, 255, 255, 0.96);\n color: #14212b;\n box-shadow: 0 24px 64px rgba(15, 23, 42, 0.28);\n font-family:\n \"Segoe UI\",\n \"PingFang SC\",\n \"Noto Sans SC\",\n sans-serif;\n}\n.HeadlessLoginPanel_module_brand {\n display: flex;\n gap: 14px;\n align-items: center;\n margin-bottom: 12px;\n}\n.HeadlessLoginPanel_module_logo {\n border-radius: 12px;\n display: block;\n}\n.HeadlessLoginPanel_module_product {\n margin: 0;\n font-size: 13px;\n font-weight: 650;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--lw-auth-theme);\n}\n.HeadlessLoginPanel_module_title {\n margin: 2px 0 0;\n font-size: 22px;\n font-weight: 700;\n line-height: 1.25;\n}\n.HeadlessLoginPanel_module_subtitle {\n margin: 0 0 18px;\n font-size: 14px;\n line-height: 1.5;\n color: #4b5c68;\n}\n.HeadlessLoginPanel_module_form {\n display: grid;\n gap: 10px;\n}\n.HeadlessLoginPanel_module_channelTabs {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 6px;\n margin-bottom: 2px;\n}\n.HeadlessLoginPanel_module_channelTab {\n border: 1px solid #c9d5de;\n border-radius: 10px;\n padding: 8px 10px;\n font-size: 13px;\n font-weight: 650;\n cursor: pointer;\n color: #4b5c68;\n background: #f7fafc;\n}\n.HeadlessLoginPanel_module_channelTab:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_channelTabActive {\n color: var(--lw-auth-theme-deep);\n border-color: var(--lw-auth-theme);\n background: color-mix(in srgb, var(--lw-auth-theme) 10%, #fff);\n}\n.HeadlessLoginPanel_module_codeRow {\n display: grid;\n grid-template-columns: 1fr auto;\n gap: 8px;\n align-items: stretch;\n}\n.HeadlessLoginPanel_module_codeInput {\n min-width: 0;\n}\n.HeadlessLoginPanel_module_secondaryBtn {\n border: 1px solid #b7c9d4;\n border-radius: 10px;\n padding: 0 12px;\n font-size: 13px;\n font-weight: 650;\n cursor: pointer;\n color: #14212b;\n background: #fff;\n white-space: nowrap;\n}\n.HeadlessLoginPanel_module_secondaryBtn:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_socialStack {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 10px;\n font-size: 12px;\n}\n.HeadlessLoginPanel_module_input {\n width: 100%;\n box-sizing: border-box;\n border: 1px solid #c9d5de;\n border-radius: 10px;\n padding: 10px 12px;\n font-size: 14px;\n outline: none;\n background: #f7fafc;\n}\n.HeadlessLoginPanel_module_input:focus {\n border-color: var(--lw-auth-theme);\n}\n.HeadlessLoginPanel_module_input:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_passwordField {\n position: relative;\n display: flex;\n align-items: center;\n}\n.HeadlessLoginPanel_module_passwordInput {\n padding-right: 42px;\n}\n.HeadlessLoginPanel_module_passwordToggle {\n position: absolute;\n right: 4px;\n top: 50%;\n transform: translateY(-50%);\n z-index: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border: none;\n border-radius: 4px;\n padding: 0;\n color: #5a6b76;\n background: transparent;\n cursor: pointer;\n}\n.HeadlessLoginPanel_module_passwordToggle:hover:not(:disabled) {\n color: var(--lw-auth-theme);\n background: color-mix(in srgb, var(--lw-auth-theme) 12%, transparent);\n}\n.HeadlessLoginPanel_module_passwordToggle:focus-visible {\n outline: 2px solid var(--lw-auth-theme);\n outline-offset: 1px;\n}\n.HeadlessLoginPanel_module_passwordToggle:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_primaryBtn {\n border: none;\n border-radius: 10px;\n padding: 11px 14px;\n font-size: 14px;\n font-weight: 650;\n cursor: pointer;\n color: #fff;\n background:\n linear-gradient(\n 135deg,\n var(--lw-auth-theme) 0%,\n var(--lw-auth-theme-deep) 100%);\n}\n.HeadlessLoginPanel_module_primaryBtn:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_socialBtn {\n width: 100%;\n min-width: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n border: 1px solid #b7c9d4;\n border-radius: 10px;\n padding: 11px 10px;\n font-size: 14px;\n font-weight: 650;\n cursor: pointer;\n color: #14212b;\n background: #fff;\n}\n.HeadlessLoginPanel_module_socialBtn:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_socialLogo {\n flex-shrink: 0;\n display: block;\n}\n.HeadlessLoginPanel_module_logoFallback {\n width: 18px;\n height: 18px;\n border-radius: 4px;\n background: color-mix(in srgb, var(--lw-auth-theme) 14%, #fff);\n color: var(--lw-auth-theme-deep);\n font-size: 11px;\n font-weight: 700;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n.HeadlessLoginPanel_module_cancelBtn {\n margin-top: 10px;\n width: 100%;\n border: none;\n background: transparent;\n color: #5a6b76;\n font-size: 13px;\n cursor: pointer;\n padding: 8px;\n}\n.HeadlessLoginPanel_module_cancelBtn:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_divider {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 14px 0;\n color: #90a0ab;\n}\n.HeadlessLoginPanel_module_dividerLine {\n flex: 1;\n height: 1px;\n background: #d5e0e7;\n}\n.HeadlessLoginPanel_module_dividerText {\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n}\n.HeadlessLoginPanel_module_hint {\n margin: 10px 0 0;\n font-size: 12px;\n color: #6b7c87;\n line-height: 1.45;\n}\n.HeadlessLoginPanel_module_domainsHint {\n margin: -2px 0 0;\n font-size: 12px;\n line-height: 1.45;\n color: #4b5c68;\n word-break: break-word;\n}\n.HeadlessLoginPanel_module_switchMode {\n margin: 12px 0 0;\n text-align: center;\n}\n.HeadlessLoginPanel_module_switchModeBtn {\n border: none;\n background: transparent;\n color: var(--lw-auth-theme);\n font-size: 13px;\n font-weight: 650;\n cursor: pointer;\n padding: 4px 8px;\n text-decoration: underline;\n text-underline-offset: 3px;\n}\n.HeadlessLoginPanel_module_switchModeBtn:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_error {\n margin: 12px 0 0;\n font-size: 13px;\n color: #b42318;\n line-height: 1.4;\n}\n.HeadlessLoginPanel_module_footer {\n margin-top: 18px;\n padding-top: 12px;\n border-top: 1px solid #e4ebf0;\n font-size: 12px;\n color: #6b7c87;\n display: flex;\n gap: 8px;\n justify-content: center;\n}\n\n/* src/LoginLanguageSwitcher.module.scss */\n.LoginLanguageSwitcher_module_switch {\n position: relative;\n display: inline-flex;\n}\n.LoginLanguageSwitcher_module_trigger {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n height: 32px;\n padding: 0 10px 0 8px;\n border: 1px solid rgba(15, 23, 42, 0.12);\n border-radius: 999px;\n background: rgba(255, 255, 255, 0.86);\n color: #243044;\n font: inherit;\n font-size: 13px;\n line-height: 1;\n cursor: pointer;\n backdrop-filter: blur(8px);\n}\n.LoginLanguageSwitcher_module_trigger:hover,\n.LoginLanguageSwitcher_module_trigger[aria-expanded=true] {\n border-color: var(--lw-login-accent, #1677ff);\n color: #0f172a;\n}\n.LoginLanguageSwitcher_module_icon {\n width: 14px;\n height: 14px;\n display: block;\n}\n.LoginLanguageSwitcher_module_caret {\n width: 10px;\n height: 10px;\n opacity: 0.65;\n}\n.LoginLanguageSwitcher_module_menu {\n position: absolute;\n top: calc(100% + 6px);\n right: 0;\n z-index: 20;\n min-width: 168px;\n margin: 0;\n padding: 6px;\n list-style: none;\n border-radius: 12px;\n background: #fff;\n box-shadow: 0 12px 40px rgba(15, 23, 42, 0.16);\n}\n.LoginLanguageSwitcher_module_item {\n display: block;\n width: 100%;\n border: 0;\n border-radius: 8px;\n padding: 8px 10px;\n background: transparent;\n color: #1f2937;\n font: inherit;\n font-size: 14px;\n text-align: left;\n cursor: pointer;\n}\n.LoginLanguageSwitcher_module_item:hover {\n background: #f3f6fb;\n}\n.LoginLanguageSwitcher_module_itemActive {\n background: color-mix(in srgb, var(--lw-login-accent, #1677ff) 14%, #fff);\n color: var(--lw-login-accent, #1677ff);\n font-weight: 650;\n}\n.LoginLanguageSwitcher_module_onDark {\n border-color: rgba(255, 255, 255, 0.22);\n background: rgba(15, 23, 42, 0.28);\n color: rgba(255, 255, 255, 0.92);\n}\n.LoginLanguageSwitcher_module_onDark:hover,\n.LoginLanguageSwitcher_module_onDark[aria-expanded=true] {\n border-color: rgba(255, 255, 255, 0.55);\n color: #fff;\n}\n\n/* src/LoginCanvas.module.scss */\n.LoginCanvas_module_canvas {\n --lw-login-accent: #1677ff;\n position: relative;\n min-height: 100dvh;\n display: grid;\n place-items: center;\n padding: 56px 20px 24px;\n overflow: hidden;\n background:\n radial-gradient(\n 900px 480px at 8% -8%,\n color-mix(in srgb, var(--lw-login-accent) 28%, transparent),\n transparent 58%),\n radial-gradient(\n 720px 420px at 100% 12%,\n color-mix(in srgb, var(--lw-login-accent) 16%, transparent),\n transparent 52%),\n linear-gradient(\n 165deg,\n var(--lw-login-bg-a, #f4f7fb) 0%,\n var(--lw-login-bg-b, #e7eef6) 100%);\n color: var(--lw-login-ink, #122033);\n}\n.LoginCanvas_module_canvas[data-tone=console] {\n --lw-login-accent: #7eb6ff;\n --lw-login-bg-a: #0e1726;\n --lw-login-bg-b: #1a2740;\n --lw-login-ink: #e8eef8;\n --lw-login-grid: rgba(255, 255, 255, 0.05);\n}\n.LoginCanvas_module_canvas[data-tone=vista] {\n --lw-login-accent: #1677ff;\n --lw-login-bg-a: #f4f7fb;\n --lw-login-bg-b: #dde7f0;\n --lw-login-grid: rgba(11, 18, 32, 0.045);\n}\n.LoginCanvas_module_canvas[data-tone=data] {\n --lw-login-accent: #5aa2ff;\n --lw-login-bg-a: #070b14;\n --lw-login-bg-b: #12203a;\n --lw-login-ink: #e8eefc;\n --lw-login-grid: rgba(255, 255, 255, 0.045);\n}\n.LoginCanvas_module_canvas[data-tone=edu] {\n --lw-login-accent: #f59e0b;\n --lw-login-bg-a: #fff7ed;\n --lw-login-bg-b: #e0e7ff;\n --lw-login-grid: rgba(67, 56, 202, 0.06);\n}\n.LoginCanvas_module_grid {\n position: absolute;\n inset: 0;\n pointer-events: none;\n background-image:\n linear-gradient(var(--lw-login-grid, rgba(15, 23, 42, 0.04)) 1px, transparent 1px),\n linear-gradient(\n 90deg,\n var(--lw-login-grid, rgba(15, 23, 42, 0.04)) 1px,\n transparent 1px);\n background-size: 48px 48px;\n mask-image:\n radial-gradient(\n ellipse at center,\n #000 18%,\n transparent 74%);\n}\n.LoginCanvas_module_lang {\n position: fixed;\n top: 14px;\n right: 16px;\n z-index: 5;\n}\n.LoginCanvas_module_decor {\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 0;\n}\n.LoginCanvas_module_slot {\n position: relative;\n z-index: 1;\n width: min(440px, 100%);\n}\n.LoginCanvas_module_slotFill {\n width: min(1120px, 100%);\n}\n/*# sourceMappingURL=index.css.map */";document.head.appendChild(s);})();
2
2
  'use strict';
3
3
 
4
4
  var oidcClientTs = require('oidc-client-ts');
@@ -920,6 +920,138 @@ function useLuminaryAuth() {
920
920
  return ctx;
921
921
  }
922
922
 
923
+ // src/login-labels.ts
924
+ var DEFAULT_LOGIN_LOCALES = [
925
+ { code: "en", label: "English", short: "EN" },
926
+ { code: "zh-CN", label: "\u7B80\u4F53\u4E2D\u6587", short: "\u7B80" },
927
+ { code: "zh-TW", label: "\u7E41\u9AD4\u4E2D\u6587", short: "\u7E41" },
928
+ { code: "es", label: "Espa\xF1ol", short: "ES" }
929
+ ];
930
+ var ZH_CN = {
931
+ title: "\u767B\u5F55",
932
+ subtitle: "\u4F7F\u7528 LuminaryWorks \u7EDF\u4E00\u8D26\u53F7",
933
+ identifierPlaceholder: "\u90AE\u7BB1\u6216\u7528\u6237\u540D",
934
+ registerIdentifierPlaceholder: "\u7528\u6237\u540D",
935
+ passwordPlaceholder: "\u5BC6\u7801",
936
+ confirmPasswordPlaceholder: "\u786E\u8BA4\u5BC6\u7801",
937
+ submitPassword: "\u5BC6\u7801\u767B\u5F55",
938
+ submitRegister: "\u521B\u5EFA\u8D26\u53F7",
939
+ submitSso: "\u4F7F\u7528\u7EDF\u4E00\u8D26\u53F7\u7EE7\u7EED",
940
+ submitGoogle: "Google",
941
+ submitGithub: "GitHub",
942
+ socialDivider: "\u6216",
943
+ hint: "\u793E\u4EA4\u8D26\u53F7\u4F1A\u76F4\u63A5\u6253\u5F00\u5BF9\u5E94\u670D\u52A1\u3002\u5BC6\u7801\u767B\u5F55\u4F7F\u7528\u4F60\u7684 LuminaryWorks \u8D26\u53F7\u3002",
944
+ registerHint: "\u90AE\u7BB1\u6CE8\u518C\u9700\u8981\u9A8C\u8BC1\u7801\u3002\u4E5F\u53EF\u4EE5\u7528\u7528\u6237\u540D\u6CE8\u518C\uFF0C\u6216\u6539\u7528\u793E\u4EA4\u8D26\u53F7\u4E00\u952E\u767B\u5F55\u3002",
945
+ cancel: "\u53D6\u6D88",
946
+ experienceUnavailable: "\u5BC6\u7801\u767B\u5F55\u6682\u4E0D\u53EF\u7528\uFF0C\u8BF7\u6539\u7528\u793E\u4EA4\u8D26\u53F7\u3002",
947
+ showPassword: "\u663E\u793A\u5BC6\u7801",
948
+ hidePassword: "\u9690\u85CF\u5BC6\u7801",
949
+ registerLink: "\u521B\u5EFA\u8D26\u53F7",
950
+ loginLink: "\u5DF2\u6709\u8D26\u53F7\uFF1F\u53BB\u767B\u5F55",
951
+ passwordMismatch: "\u4E24\u6B21\u5BC6\u7801\u4E0D\u4E00\u81F4",
952
+ registerTitle: "\u521B\u5EFA\u8D26\u53F7",
953
+ registerSubtitle: "\u521B\u5EFA LuminaryWorks \u7EDF\u4E00\u8D26\u53F7",
954
+ registerWithEmail: "\u90AE\u7BB1",
955
+ registerWithUsername: "\u7528\u6237\u540D",
956
+ emailPlaceholder: "\u90AE\u7BB1",
957
+ verificationCodePlaceholder: "\u9A8C\u8BC1\u7801",
958
+ sendCode: "\u53D1\u9001\u9A8C\u8BC1\u7801",
959
+ resendCode: "\u91CD\u65B0\u53D1\u9001",
960
+ allowedDomainsPrefix: "\u5141\u8BB8\u7684\u90AE\u7BB1\u57DF\u540D",
961
+ allowedDomainsOpen: "\u5927\u591A\u6570\u90AE\u7BB1\u90FD\u53EF\u4EE5\u6CE8\u518C\u3002",
962
+ allowedDomainsBlocklist: "\u5927\u591A\u6570\u90AE\u7BB1\u53EF\u7528\u3002\u4E34\u65F6\u90AE\u7BB1\u4F1A\u88AB\u62D2\u7EDD\u3002",
963
+ waitingExternalBrowser: "\u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u5B8C\u6210\u767B\u5F55\uFF0C\u7136\u540E\u56DE\u5230\u672C\u5E94\u7528\u3002"
964
+ };
965
+ var ZH_TW = {
966
+ title: "\u767B\u5165",
967
+ subtitle: "\u4F7F\u7528 LuminaryWorks \u7D71\u4E00\u5E33\u865F",
968
+ identifierPlaceholder: "\u96FB\u5B50\u90F5\u4EF6\u6216\u4F7F\u7528\u8005\u540D\u7A31",
969
+ registerIdentifierPlaceholder: "\u4F7F\u7528\u8005\u540D\u7A31",
970
+ passwordPlaceholder: "\u5BC6\u78BC",
971
+ confirmPasswordPlaceholder: "\u78BA\u8A8D\u5BC6\u78BC",
972
+ submitPassword: "\u5BC6\u78BC\u767B\u5165",
973
+ submitRegister: "\u5EFA\u7ACB\u5E33\u865F",
974
+ submitSso: "\u4F7F\u7528\u7D71\u4E00\u5E33\u865F\u7E7C\u7E8C",
975
+ submitGoogle: "Google",
976
+ submitGithub: "GitHub",
977
+ socialDivider: "\u6216",
978
+ hint: "\u793E\u4EA4\u5E33\u865F\u6703\u76F4\u63A5\u958B\u555F\u5C0D\u61C9\u670D\u52D9\u3002\u5BC6\u78BC\u767B\u5165\u4F7F\u7528\u4F60\u7684 LuminaryWorks \u5E33\u865F\u3002",
979
+ registerHint: "\u96FB\u5B50\u90F5\u4EF6\u8A3B\u518A\u9700\u8981\u9A57\u8B49\u78BC\u3002\u4E5F\u53EF\u4EE5\u7528\u4F7F\u7528\u8005\u540D\u7A31\u8A3B\u518A\uFF0C\u6216\u6539\u7528\u793E\u4EA4\u5E33\u865F\u3002",
980
+ cancel: "\u53D6\u6D88",
981
+ experienceUnavailable: "\u5BC6\u78BC\u767B\u5165\u66AB\u4E0D\u53EF\u7528\uFF0C\u8ACB\u6539\u7528\u793E\u4EA4\u5E33\u865F\u3002",
982
+ showPassword: "\u986F\u793A\u5BC6\u78BC",
983
+ hidePassword: "\u96B1\u85CF\u5BC6\u78BC",
984
+ registerLink: "\u5EFA\u7ACB\u5E33\u865F",
985
+ loginLink: "\u5DF2\u6709\u5E33\u865F\uFF1F\u53BB\u767B\u5165",
986
+ passwordMismatch: "\u5169\u6B21\u5BC6\u78BC\u4E0D\u4E00\u81F4",
987
+ registerTitle: "\u5EFA\u7ACB\u5E33\u865F",
988
+ registerSubtitle: "\u5EFA\u7ACB LuminaryWorks \u7D71\u4E00\u5E33\u865F",
989
+ registerWithEmail: "\u96FB\u5B50\u90F5\u4EF6",
990
+ registerWithUsername: "\u4F7F\u7528\u8005\u540D\u7A31",
991
+ emailPlaceholder: "\u96FB\u5B50\u90F5\u4EF6",
992
+ verificationCodePlaceholder: "\u9A57\u8B49\u78BC",
993
+ sendCode: "\u767C\u9001\u9A57\u8B49\u78BC",
994
+ resendCode: "\u91CD\u65B0\u767C\u9001",
995
+ allowedDomainsPrefix: "\u5141\u8A31\u7684\u96FB\u5B50\u90F5\u4EF6\u7DB2\u57DF",
996
+ allowedDomainsOpen: "\u5927\u591A\u6578\u96FB\u5B50\u90F5\u4EF6\u90FD\u53EF\u4EE5\u8A3B\u518A\u3002",
997
+ allowedDomainsBlocklist: "\u5927\u591A\u6578\u96FB\u5B50\u90F5\u4EF6\u53EF\u7528\u3002\u81E8\u6642\u4FE1\u7BB1\u6703\u88AB\u62D2\u7D55\u3002",
998
+ waitingExternalBrowser: "\u8ACB\u5728\u700F\u89BD\u5668\u4E2D\u5B8C\u6210\u767B\u5165\uFF0C\u7136\u5F8C\u56DE\u5230\u672C\u61C9\u7528\u3002"
999
+ };
1000
+ var ES = {
1001
+ title: "Iniciar sesi\xF3n",
1002
+ subtitle: "Usa tu cuenta unificada de LuminaryWorks",
1003
+ identifierPlaceholder: "Correo o usuario",
1004
+ registerIdentifierPlaceholder: "Usuario",
1005
+ passwordPlaceholder: "Contrase\xF1a",
1006
+ confirmPasswordPlaceholder: "Confirmar contrase\xF1a",
1007
+ submitPassword: "Entrar con contrase\xF1a",
1008
+ submitRegister: "Crear cuenta",
1009
+ submitSso: "Continuar con la cuenta unificada",
1010
+ submitGoogle: "Google",
1011
+ submitGithub: "GitHub",
1012
+ socialDivider: "o",
1013
+ hint: "Las redes abren el proveedor directamente. La contrase\xF1a usa tu cuenta LuminaryWorks.",
1014
+ registerHint: "El registro por correo pide un c\xF3digo. Tambi\xE9n puedes usar un nombre de usuario o una red social.",
1015
+ cancel: "Cancelar",
1016
+ experienceUnavailable: "El inicio con contrase\xF1a no est\xE1 disponible. Usa una red social.",
1017
+ showPassword: "Mostrar contrase\xF1a",
1018
+ hidePassword: "Ocultar contrase\xF1a",
1019
+ registerLink: "Crear una cuenta",
1020
+ loginLink: "\xBFYa tienes cuenta? Inicia sesi\xF3n",
1021
+ passwordMismatch: "Las contrase\xF1as no coinciden",
1022
+ registerTitle: "Crear cuenta",
1023
+ registerSubtitle: "Crea tu cuenta unificada de LuminaryWorks",
1024
+ registerWithEmail: "Correo",
1025
+ registerWithUsername: "Usuario",
1026
+ emailPlaceholder: "Correo",
1027
+ verificationCodePlaceholder: "C\xF3digo",
1028
+ sendCode: "Enviar c\xF3digo",
1029
+ resendCode: "Reenviar",
1030
+ allowedDomainsPrefix: "Dominios de correo permitidos",
1031
+ allowedDomainsOpen: "El registro por correo est\xE1 abierto para la mayor\xEDa de proveedores.",
1032
+ allowedDomainsBlocklist: "Se aceptan la mayor\xEDa de correos. Se bloquean direcciones temporales.",
1033
+ waitingExternalBrowser: "Termina el inicio de sesi\xF3n en el navegador y vuelve a esta app."
1034
+ };
1035
+ var BY_LOCALE = {
1036
+ en: void 0,
1037
+ "zh-CN": ZH_CN,
1038
+ "zh-TW": ZH_TW,
1039
+ es: ES
1040
+ };
1041
+ function normalizeLoginLocale(locale) {
1042
+ const raw = (locale ?? "en").trim().toLowerCase();
1043
+ if (raw === "zh" || raw === "zh-cn" || raw === "zh-hans" || raw.startsWith("zh-cn")) {
1044
+ return "zh-CN";
1045
+ }
1046
+ if (raw === "zh-tw" || raw === "zh-hant" || raw.startsWith("zh-tw")) return "zh-TW";
1047
+ if (raw === "es" || raw.startsWith("es-")) return "es";
1048
+ if (raw === "en" || raw.startsWith("en-")) return "en";
1049
+ return "en";
1050
+ }
1051
+ function loginLabels(locale) {
1052
+ return BY_LOCALE[normalizeLoginLocale(locale)] ?? {};
1053
+ }
1054
+
923
1055
  // src/HeadlessLoginPanel.module.scss
924
1056
  var HeadlessLoginPanel_module_default = {
925
1057
  panel: "HeadlessLoginPanel_module_panel",
@@ -1016,6 +1148,7 @@ function HeadlessLoginPanel({
1016
1148
  productName,
1017
1149
  logoSrc,
1018
1150
  labels: labelsProp,
1151
+ locale,
1019
1152
  returnUrl,
1020
1153
  mode = "popup",
1021
1154
  openExternalUrl,
@@ -1073,7 +1206,7 @@ function HeadlessLoginPanel({
1073
1206
  experienceAdapter.emailPolicy = emailPolicy;
1074
1207
  }
1075
1208
  }, [emailPolicy, experienceAdapter]);
1076
- const labels = { ...defaults, ...labelsProp };
1209
+ const labels = { ...defaults, ...loginLabels(locale), ...labelsProp };
1077
1210
  const configured = isIdpConfigured(config);
1078
1211
  const [panelMode, setPanelMode] = react.useState("sign-in");
1079
1212
  const [registerChannel, setRegisterChannel] = react.useState("email");
@@ -1678,6 +1811,124 @@ function useAuthGateOptional() {
1678
1811
  return react.useContext(AuthGateContext);
1679
1812
  }
1680
1813
 
1814
+ // src/LoginLanguageSwitcher.module.scss
1815
+ var LoginLanguageSwitcher_module_default = {
1816
+ switch: "LoginLanguageSwitcher_module_switch",
1817
+ trigger: "LoginLanguageSwitcher_module_trigger",
1818
+ icon: "LoginLanguageSwitcher_module_icon",
1819
+ caret: "LoginLanguageSwitcher_module_caret",
1820
+ menu: "LoginLanguageSwitcher_module_menu",
1821
+ item: "LoginLanguageSwitcher_module_item",
1822
+ itemActive: "LoginLanguageSwitcher_module_itemActive",
1823
+ onDark: "LoginLanguageSwitcher_module_onDark"
1824
+ };
1825
+ function GlobeIcon() {
1826
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: LoginLanguageSwitcher_module_default.icon, viewBox: "0 0 24 24", "aria-hidden": "true", children: [
1827
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "9", fill: "none", stroke: "currentColor", strokeWidth: "1.6" }),
1828
+ /* @__PURE__ */ jsxRuntime.jsx("ellipse", { cx: "12", cy: "12", rx: "4", ry: "9", fill: "none", stroke: "currentColor", strokeWidth: "1.6" }),
1829
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3 12h18M5 8h14M5 16h14", fill: "none", stroke: "currentColor", strokeWidth: "1.6" })
1830
+ ] });
1831
+ }
1832
+ function LoginLanguageSwitcher({
1833
+ locale,
1834
+ onChange,
1835
+ locales = DEFAULT_LOGIN_LOCALES,
1836
+ label = "Language",
1837
+ variant = "default"
1838
+ }) {
1839
+ const [open, setOpen] = react.useState(false);
1840
+ const rootRef = react.useRef(null);
1841
+ const menuId = react.useId();
1842
+ const current = locales.find((item) => item.code === locale) ?? locales.find((item) => normalizeLoginLocale(item.code) === normalizeLoginLocale(locale)) ?? locales[0];
1843
+ react.useEffect(() => {
1844
+ if (!open) return;
1845
+ const onPointer = (event) => {
1846
+ if (!rootRef.current?.contains(event.target)) setOpen(false);
1847
+ };
1848
+ const onKey = (event) => {
1849
+ if (event.key === "Escape") setOpen(false);
1850
+ };
1851
+ document.addEventListener("mousedown", onPointer);
1852
+ document.addEventListener("keydown", onKey);
1853
+ return () => {
1854
+ document.removeEventListener("mousedown", onPointer);
1855
+ document.removeEventListener("keydown", onKey);
1856
+ };
1857
+ }, [open]);
1858
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: LoginLanguageSwitcher_module_default.switch, ref: rootRef, children: [
1859
+ /* @__PURE__ */ jsxRuntime.jsxs(
1860
+ "button",
1861
+ {
1862
+ type: "button",
1863
+ className: variant === "onDark" ? `${LoginLanguageSwitcher_module_default.trigger} ${LoginLanguageSwitcher_module_default.onDark}` : LoginLanguageSwitcher_module_default.trigger,
1864
+ "aria-label": label,
1865
+ "aria-haspopup": "listbox",
1866
+ "aria-expanded": open,
1867
+ "aria-controls": menuId,
1868
+ onClick: () => setOpen((value) => !value),
1869
+ children: [
1870
+ /* @__PURE__ */ jsxRuntime.jsx(GlobeIcon, {}),
1871
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: current?.short ?? "EN" }),
1872
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: LoginLanguageSwitcher_module_default.caret, viewBox: "0 0 12 12", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M2.5 4.5 6 8l3.5-3.5", fill: "none", stroke: "currentColor", strokeWidth: "1.4" }) })
1873
+ ]
1874
+ }
1875
+ ),
1876
+ open ? /* @__PURE__ */ jsxRuntime.jsx("ul", { className: LoginLanguageSwitcher_module_default.menu, id: menuId, role: "listbox", "aria-label": label, children: locales.map((item) => {
1877
+ const active = item.code === current?.code;
1878
+ return /* @__PURE__ */ jsxRuntime.jsx("li", { role: "presentation", children: /* @__PURE__ */ jsxRuntime.jsx(
1879
+ "button",
1880
+ {
1881
+ type: "button",
1882
+ role: "option",
1883
+ "aria-selected": active,
1884
+ className: active ? `${LoginLanguageSwitcher_module_default.item} ${LoginLanguageSwitcher_module_default.itemActive}` : LoginLanguageSwitcher_module_default.item,
1885
+ onClick: () => {
1886
+ onChange(item.code);
1887
+ setOpen(false);
1888
+ },
1889
+ children: item.label
1890
+ }
1891
+ ) }, item.code);
1892
+ }) }) : null
1893
+ ] });
1894
+ }
1895
+
1896
+ // src/LoginCanvas.module.scss
1897
+ var LoginCanvas_module_default = {
1898
+ canvas: "LoginCanvas_module_canvas",
1899
+ grid: "LoginCanvas_module_grid",
1900
+ lang: "LoginCanvas_module_lang",
1901
+ decor: "LoginCanvas_module_decor",
1902
+ slot: "LoginCanvas_module_slot",
1903
+ slotFill: "LoginCanvas_module_slotFill"
1904
+ };
1905
+ function LoginCanvas({
1906
+ tone,
1907
+ locale,
1908
+ onLocaleChange,
1909
+ locales,
1910
+ languageLabel,
1911
+ fill = false,
1912
+ decor,
1913
+ children
1914
+ }) {
1915
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: LoginCanvas_module_default.canvas, "data-tone": tone, children: [
1916
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: LoginCanvas_module_default.grid, "aria-hidden": "true" }),
1917
+ decor ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: LoginCanvas_module_default.decor, children: decor }) : null,
1918
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: LoginCanvas_module_default.lang, children: /* @__PURE__ */ jsxRuntime.jsx(
1919
+ LoginLanguageSwitcher,
1920
+ {
1921
+ locale,
1922
+ onChange: onLocaleChange,
1923
+ locales,
1924
+ label: languageLabel,
1925
+ variant: tone === "console" || tone === "data" ? "onDark" : "default"
1926
+ }
1927
+ ) }),
1928
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: fill ? `${LoginCanvas_module_default.slot} ${LoginCanvas_module_default.slotFill}` : LoginCanvas_module_default.slot, children })
1929
+ ] });
1930
+ }
1931
+
1681
1932
  // src/post-login-path.ts
1682
1933
  var DEFAULT_UNSAFE = ["/login", "/auth", "/exception"];
1683
1934
  function normalizeAppPath(path, fallback) {
@@ -1730,11 +1981,14 @@ function createPostLoginPathHelpers(options) {
1730
1981
 
1731
1982
  exports.AuthGateProvider = AuthGateProvider;
1732
1983
  exports.DEFAULT_DISPOSABLE_EMAIL_BLOCKLIST = DEFAULT_DISPOSABLE_EMAIL_BLOCKLIST;
1984
+ exports.DEFAULT_LOGIN_LOCALES = DEFAULT_LOGIN_LOCALES;
1733
1985
  exports.DEFAULT_LOGIN_THEME_COLOR = DEFAULT_LOGIN_THEME_COLOR;
1734
1986
  exports.DEFAULT_REGISTER_EMAIL_ALLOWLIST = DEFAULT_REGISTER_EMAIL_ALLOWLIST;
1735
1987
  exports.HeadlessLoginPanel = HeadlessLoginPanel;
1736
1988
  exports.HostedOidcExperienceAdapter = HostedOidcExperienceAdapter;
1737
1989
  exports.LOGIN_EXPERIENCE_CAPABILITIES = LOGIN_EXPERIENCE_CAPABILITIES;
1990
+ exports.LoginCanvas = LoginCanvas;
1991
+ exports.LoginLanguageSwitcher = LoginLanguageSwitcher;
1738
1992
  exports.LogtoExperienceAdapter = LogtoExperienceAdapter;
1739
1993
  exports.LuminaryAuthProvider = LuminaryAuthProvider;
1740
1994
  exports.ReauthOverlay = ReauthOverlay;
@@ -1758,6 +2012,8 @@ exports.isIdpConfigured = isIdpConfigured;
1758
2012
  exports.isLogtoRegisterUsername = isLogtoRegisterUsername;
1759
2013
  exports.isOidcPopupWindow = isOidcPopupWindow;
1760
2014
  exports.isValidEmailShape = isValidEmailShape;
2015
+ exports.loginLabels = loginLabels;
2016
+ exports.normalizeLoginLocale = normalizeLoginLocale;
1761
2017
  exports.normalizeRegisterEmailMode = normalizeRegisterEmailMode;
1762
2018
  exports.prepareSignInRequestUrl = prepareSignInRequestUrl;
1763
2019
  exports.readIdpConfigFromEnv = readIdpConfigFromEnv;