web-mojo 2.1.1044 → 2.1.1087
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/admin.cjs.js +1 -1
- package/dist/admin.cjs.js.map +1 -1
- package/dist/admin.es.js +14 -14
- package/dist/admin.es.js.map +1 -1
- package/dist/auth.cjs.js +1 -1
- package/dist/auth.es.js +1 -1
- package/dist/charts.cjs.js +1 -1
- package/dist/charts.cjs.js.map +1 -1
- package/dist/charts.css +319 -0
- package/dist/charts.es.js +555 -3
- package/dist/charts.es.js.map +1 -1
- package/dist/chunks/{ChatView-Bvkdj-lq.js → ChatView-BnC15uoD.js} +2 -2
- package/dist/chunks/{ChatView-Bvkdj-lq.js.map → ChatView-BnC15uoD.js.map} +1 -1
- package/dist/chunks/{ChatView-DBgQzOyI.js → ChatView-D-5lHZ5H.js} +7 -7
- package/dist/chunks/{ChatView-DBgQzOyI.js.map → ChatView-D-5lHZ5H.js.map} +1 -1
- package/dist/chunks/{Collection-DD1_31eh.js → Collection-B64LJ92k.js} +2 -2
- package/dist/chunks/{Collection-DD1_31eh.js.map → Collection-B64LJ92k.js.map} +1 -1
- package/dist/chunks/{Collection-DaTm-2LH.js → Collection-CsAk0UhA.js} +2 -2
- package/dist/chunks/{Collection-DaTm-2LH.js.map → Collection-CsAk0UhA.js.map} +1 -1
- package/dist/chunks/{ContextMenu-snx9Dd1s.js → ContextMenu-CfMAB33c.js} +2 -2
- package/dist/chunks/{ContextMenu-snx9Dd1s.js.map → ContextMenu-CfMAB33c.js.map} +1 -1
- package/dist/chunks/{ContextMenu-hQH_6Pyi.js → ContextMenu-Cvls3QC_.js} +3 -3
- package/dist/chunks/{ContextMenu-hQH_6Pyi.js.map → ContextMenu-Cvls3QC_.js.map} +1 -1
- package/dist/chunks/{DataView-D7j4IWyS.js → DataView-DESqBxT-.js} +2 -2
- package/dist/chunks/{DataView-D7j4IWyS.js.map → DataView-DESqBxT-.js.map} +1 -1
- package/dist/chunks/{DataView-CWejLV3B.js → DataView-QXyfcg2M.js} +2 -2
- package/dist/chunks/{DataView-CWejLV3B.js.map → DataView-QXyfcg2M.js.map} +1 -1
- package/dist/chunks/Dialog-BfXN-fFA.js +2 -0
- package/dist/chunks/Dialog-BfXN-fFA.js.map +1 -0
- package/dist/chunks/{Dialog-BcJG5Vta.js → Dialog-DHUsZ92-.js} +20 -6
- package/dist/chunks/Dialog-DHUsZ92-.js.map +1 -0
- package/dist/chunks/{FormView-BClEkzmE.js → FormView-DGRmcKUG.js} +282 -123
- package/dist/chunks/FormView-DGRmcKUG.js.map +1 -0
- package/dist/chunks/FormView-KGvr68ju.js +3 -0
- package/dist/chunks/FormView-KGvr68ju.js.map +1 -0
- package/dist/chunks/{ListView-BrsQ26R6.js → ListView-BGJG4GYH.js} +3 -3
- package/dist/chunks/{ListView-BrsQ26R6.js.map → ListView-BGJG4GYH.js.map} +1 -1
- package/dist/chunks/{ListView-BRGiITfD.js → ListView-BpGEatee.js} +2 -2
- package/dist/chunks/{ListView-BRGiITfD.js.map → ListView-BpGEatee.js.map} +1 -1
- package/dist/chunks/{MetricsMiniChartWidget-DALWxrzu.js → MetricsMiniChartWidget-BKbFGvXG.js} +4 -4
- package/dist/chunks/{MetricsMiniChartWidget-DALWxrzu.js.map → MetricsMiniChartWidget-BKbFGvXG.js.map} +1 -1
- package/dist/chunks/{MetricsMiniChartWidget-CN1HPnWf.js → MetricsMiniChartWidget-BNdGuSZV.js} +2 -2
- package/dist/chunks/{MetricsMiniChartWidget-CN1HPnWf.js.map → MetricsMiniChartWidget-BNdGuSZV.js.map} +1 -1
- package/dist/chunks/{PDFViewer-CgdSGU1n.js → PDFViewer-BIBNhuWY.js} +3 -3
- package/dist/chunks/{PDFViewer-CgdSGU1n.js.map → PDFViewer-BIBNhuWY.js.map} +1 -1
- package/dist/chunks/{PDFViewer-DtJIlPXi.js → PDFViewer-nZAQQScE.js} +2 -2
- package/dist/chunks/{PDFViewer-DtJIlPXi.js.map → PDFViewer-nZAQQScE.js.map} +1 -1
- package/dist/chunks/Rest-BpDyhFfG.js +2 -0
- package/dist/chunks/Rest-BpDyhFfG.js.map +1 -0
- package/dist/chunks/{Rest-CS4jRCAs.js → Rest-DpbPbmra.js} +96 -5
- package/dist/chunks/Rest-DpbPbmra.js.map +1 -0
- package/dist/chunks/{TokenManager-DIEFCQ3B.js → TokenManager-BWc_pRpg.js} +2 -2
- package/dist/chunks/{TokenManager-DIEFCQ3B.js.map → TokenManager-BWc_pRpg.js.map} +1 -1
- package/dist/chunks/{TokenManager-BanwFrq7.js → TokenManager-N3e5wDu1.js} +5 -5
- package/dist/chunks/{TokenManager-BanwFrq7.js.map → TokenManager-N3e5wDu1.js.map} +1 -1
- package/dist/chunks/{WebSocketClient-D-5DJoMX.js → WebSocketClient-DghNkEyO.js} +2 -2
- package/dist/chunks/{WebSocketClient-D-5DJoMX.js.map → WebSocketClient-DghNkEyO.js.map} +1 -1
- package/dist/chunks/{WebSocketClient-DzcqAmho.js → WebSocketClient-E08hfP5f.js} +2 -2
- package/dist/chunks/{WebSocketClient-DzcqAmho.js.map → WebSocketClient-E08hfP5f.js.map} +1 -1
- package/dist/chunks/{version-WMgX72-y.js → version-CKPqwcQJ.js} +2 -2
- package/dist/chunks/{version-WMgX72-y.js.map → version-CKPqwcQJ.js.map} +1 -1
- package/dist/chunks/{version-BaFu2yii.js → version-Dtwh-YkD.js} +4 -4
- package/dist/chunks/{version-BaFu2yii.js.map → version-Dtwh-YkD.js.map} +1 -1
- package/dist/css/web-mojo.css +1 -1
- package/dist/docit.cjs.js +1 -1
- package/dist/docit.es.js +6 -6
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +15 -15
- package/dist/lightbox.cjs.js +1 -1
- package/dist/lightbox.es.js +5 -5
- package/dist/map.cjs.js +1 -1
- package/dist/map.cjs.js.map +1 -1
- package/dist/map.es.js +82 -3
- package/dist/map.es.js.map +1 -1
- package/dist/timeline.cjs.js +1 -1
- package/dist/timeline.es.js +4 -4
- package/package.json +1 -1
- package/dist/chunks/Dialog-7T8ENHYD.js +0 -2
- package/dist/chunks/Dialog-7T8ENHYD.js.map +0 -1
- package/dist/chunks/Dialog-BcJG5Vta.js.map +0 -1
- package/dist/chunks/FormView-BClEkzmE.js.map +0 -1
- package/dist/chunks/FormView-nulck4nL.js +0 -3
- package/dist/chunks/FormView-nulck4nL.js.map +0 -1
- package/dist/chunks/Rest-BNYqGlnP.js +0 -2
- package/dist/chunks/Rest-BNYqGlnP.js.map +0 -1
- package/dist/chunks/Rest-CS4jRCAs.js.map +0 -1
package/dist/auth.cjs.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./chunks/version-WMgX72-y.js");function s({baseURL:e,fetchImpl:s=("undefined"!=typeof fetch?fetch.bind(window):null),storage:t=("undefined"!=typeof localStorage?localStorage:null),endpoints:n={}}={}){if(!e)throw new Error("createAuthClient: baseURL is required");if(!s)throw new Error("createAuthClient: fetch implementation is not available in this environment");if(!t)throw new Error("createAuthClient: storage (localStorage) is not available in this environment");const o="access_token",r="refresh_token",a="user",i={login:"/login",forgot:"/auth/forgot",resetCode:"/auth/password/reset/code",resetToken:"/auth/password/reset/token",...n};async function l(t,n){const o=await s(`${e}${t}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n||{})});let r={};try{r=await o.json()}catch(a){}if(!o.ok)throw r||{message:`Request failed with status ${o.status}`};return r}function d(e){return e&&e.data&&e.data.data||e&&e.data||e}function c(e){const s=d(e);if(!s||!s.access_token)throw new Error("No access_token in response.");t.setItem(o,s.access_token),s.refresh_token&&t.setItem(r,s.refresh_token),s.user&&t.setItem(a,JSON.stringify(s.user))}return{async login(e,s){const t=await l(i.login,{username:e,password:s});return c(t),d(t)},forgot:async({email:e,method:s})=>l(i.forgot,{email:e,method:s}),async resetWithCode({email:e,code:s,newPassword:t}){const n=await l(i.resetCode,{email:e,code:s,new_password:t});return c(n),d(n)},async resetWithToken({token:e,newPassword:s}){const t=await l(i.resetToken,{token:e,new_password:s});return c(t),d(t)},logout(){t.removeItem(o),t.removeItem(r),t.removeItem(a)},isAuthenticated:()=>!!t.getItem(o),getToken:()=>t.getItem(o),getUser(){const e=t.getItem(a);try{return e?JSON.parse(e):null}catch{return null}},getAuthHeader(){const e=t.getItem(o);return e?`Bearer ${e}`:null},getErrorMessage:function(e){return e?.message||e?.error||Array.isArray(e?.errors)&&e.errors[0]?.message||"An error occurred. Please try again."},parseResponse:d}}function t(e,t={}){if(!(e&&e instanceof Element))throw new Error("mountAuth: container must be a DOM Element");const{baseURL:n,onSuccessRedirect:o,allowRedirectOrigins:r,branding:a={},theme:i,endpoints:l,providers:d,texts:c={}}=t;if(!n)throw new Error("mountAuth: baseURL is required");const u=new URLSearchParams(window.location.search),m=u.get("redirect")||u.get("next")||u.get("returnTo"),p=String(o||m||"/");function g(){!function(e){if(!r||0===r.length)return!0;try{const s=new URL(e,window.location.origin);return r.includes(s.origin)}catch{return!1}}(p)?window.location.href="/":window.location.href=p.startsWith("http")?p:new URL(p,window.location.origin).href}const w=s({baseURL:n,endpoints:l}),b=a.title||"Sign In",f=a.subtitle||"Sign in to your account",h=a.logoUrl||"",y={emailOrUsername:c.emailOrUsername||"Email or Username",password:c.password||"Password",signIn:c.signIn||"Sign In",forgotPassword:c.forgotPassword||"Forgot password?",resetYourPassword:c.resetYourPassword||"Reset Your Password",emailAddress:c.emailAddress||"Email Address",resetMethod:c.resetMethod||"Reset Method",emailCode:c.emailCode||"Email me a code",emailLink:c.emailLink||"Email me a magic link",sendReset:c.sendReset||"Send Reset",back:c.back||"Back",enterResetCode:c.enterResetCode||"Enter Reset Code",weSentCodeTo:c.weSentCodeTo||"We sent a code to",resetCode:c.resetCode||"Reset Code",newPassword:c.newPassword||"New Password",confirmPassword:c.confirmPassword||"Confirm Password",resetPassword:c.resetPassword||"Reset Password",setYourNewPassword:c.setYourNewPassword||"Set Your New Password",setPassword:c.setPassword||"Set Password",invalidCredentials:c.invalidCredentials||"Invalid credentials.",successRedirecting:c.successRedirecting||"Success! Redirecting...",pleaseFillAllFields:c.pleaseFillAllFields||"Please fill in all fields.",passwordsDoNotMatch:c.passwordsDoNotMatch||"Passwords do not match."},v=`\n <div class="auth-container">\n <div class="auth-card">\n <div class="auth-header">\n ${h?`<img src="${h}" alt="${b}" style="max-height:60px;margin-bottom:10px" />`:""}\n <h1 class="auth-title">${b}</h1>\n <p class="auth-subtitle">${f}</p>\n </div>\n\n <div id="status-message" class="alert" role="status" style="display:none;"></div>\n\n \x3c!-- Sign In View --\x3e\n <div id="view-signin" class="auth-view">\n <form id="form-signin" novalidate>\n <div class="mb-3">\n <label for="signin-username" class="form-label">${y.emailOrUsername}</label>\n <input type="text" class="form-control" id="signin-username" placeholder="${y.emailOrUsername}" autocomplete="username" required />\n </div>\n <div class="mb-3">\n <label for="signin-password" class="form-label">${y.password}</label>\n <input type="password" class="form-control" id="signin-password" placeholder="${y.password}" autocomplete="current-password" required />\n </div>\n <button type="submit" class="btn btn-primary w-100 mb-3" id="btn-signin">\n <span class="btn-text">${y.signIn}</span>\n <span class="btn-spinner spinner-border spinner-border-sm" style="display:none;"></span>\n </button>\n <div class="text-center">\n <a href="#" id="link-forgot" class="text-decoration-none">${y.forgotPassword}</a>\n </div>\n\n ${d&&(d.google||d.passkey)?`\n <div class="position-relative my-3">\n <hr class="text-muted" />\n <span class="position-absolute top-50 start-50 translate-middle bg-white px-3 text-muted small">OR</span>\n </div>\n <div class="d-grid gap-2">\n ${d.google?'<button type="button" class="btn btn-outline-primary" id="btn-google"><i class="bi bi-google me-2"></i>Continue with Google</button>':""}\n ${d.passkey?'<button type="button" class="btn btn-outline-secondary" id="btn-passkey"><i class="bi bi-fingerprint me-2"></i>Sign in with Passkey</button>':""}\n </div>\n `:""}\n </form>\n </div>\n\n \x3c!-- Forgot Password View --\x3e\n <div id="view-forgot" class="auth-view" style="display:none;">\n <button type="button" class="btn btn-link p-0 mb-3" id="btn-back-signin">\n <span aria-hidden="true">←</span> ${y.back}\n </button>\n <h2 class="h5 mb-3">${y.resetYourPassword}</h2>\n <form id="form-forgot" novalidate>\n <div class="mb-3">\n <label for="forgot-email" class="form-label">${y.emailAddress}</label>\n <input type="email" class="form-control" id="forgot-email" placeholder="${y.emailAddress}" autocomplete="email" required />\n </div>\n <div class="mb-3">\n <label class="form-label">${y.resetMethod}</label>\n <div class="form-check">\n <input class="form-check-input" type="radio" name="reset-method" id="method-code" value="code" checked />\n <label class="form-check-label" for="method-code">${y.emailCode}</label>\n </div>\n <div class="form-check">\n <input class="form-check-input" type="radio" name="reset-method" id="method-link" value="link" />\n <label class="form-check-label" for="method-link">${y.emailLink}</label>\n </div>\n </div>\n <button type="submit" class="btn btn-primary w-100" id="btn-forgot">\n <span class="btn-text">${y.sendReset}</span>\n <span class="btn-spinner spinner-border spinner-border-sm" style="display:none;"></span>\n </button>\n </form>\n </div>\n\n \x3c!-- Reset with Code View --\x3e\n <div id="view-reset-code" class="auth-view" style="display:none;">\n <button type="button" class="btn btn-link p-0 mb-3" id="btn-back-forgot">\n <span aria-hidden="true">←</span> ${y.back}\n </button>\n <h2 class="h5 mb-3">${y.enterResetCode}</h2>\n <p class="text-muted small mb-3">${y.weSentCodeTo} <strong id="reset-email-display"></strong></p>\n <form id="form-reset-code" novalidate>\n <div class="mb-3">\n <label for="reset-code" class="form-label">${y.resetCode}</label>\n <input type="text" class="form-control" id="reset-code" placeholder="${y.resetCode}" required />\n </div>\n <div class="mb-3">\n <label for="reset-password" class="form-label">${y.newPassword}</label>\n <input type="password" class="form-control" id="reset-password" placeholder="${y.newPassword}" autocomplete="new-password" required />\n </div>\n <div class="mb-3">\n <label for="reset-password-confirm" class="form-label">${y.confirmPassword}</label>\n <input type="password" class="form-control" id="reset-password-confirm" placeholder="${y.confirmPassword}" autocomplete="new-password" required />\n </div>\n <button type="submit" class="btn btn-primary w-100" id="btn-reset-code">\n <span class="btn-text">${y.resetPassword}</span>\n <span class="btn-spinner spinner-border spinner-border-sm" style="display:none;"></span>\n </button>\n </form>\n </div>\n\n \x3c!-- Set Password via Magic Link View --\x3e\n <div id="view-set-password" class="auth-view" style="display:none;">\n <h2 class="h5 mb-3">${y.setYourNewPassword}</h2>\n <form id="form-set-password" novalidate>\n <div class="mb-3">\n <label for="set-password" class="form-label">${y.newPassword}</label>\n <input type="password" class="form-control" id="set-password" placeholder="${y.newPassword}" autocomplete="new-password" required />\n </div>\n <div class="mb-3">\n <label for="set-password-confirm" class="form-label">${y.confirmPassword}</label>\n <input type="password" class="form-control" id="set-password-confirm" placeholder="${y.confirmPassword}" autocomplete="new-password" required />\n </div>\n <button type="submit" class="btn btn-primary w-100" id="btn-set-password">\n <span class="btn-text">${y.setPassword}</span>\n <span class="btn-spinner spinner-border spinner-border-sm" style="display:none;"></span>\n </button>\n </form>\n </div>\n </div>\n </div>\n `;e.innerHTML=v,i&&e.classList.add(String(i));const k={views:{signin:e.querySelector("#view-signin"),forgot:e.querySelector("#view-forgot"),resetCode:e.querySelector("#view-reset-code"),setPassword:e.querySelector("#view-set-password")},forms:{signin:e.querySelector("#form-signin"),forgot:e.querySelector("#form-forgot"),resetCode:e.querySelector("#form-reset-code"),setPassword:e.querySelector("#form-set-password")},buttons:{signin:e.querySelector("#btn-signin"),forgot:e.querySelector("#btn-forgot"),resetCode:e.querySelector("#btn-reset-code"),setPassword:e.querySelector("#btn-set-password"),backSignin:e.querySelector("#btn-back-signin"),backForgot:e.querySelector("#btn-back-forgot"),google:e.querySelector("#btn-google"),passkey:e.querySelector("#btn-passkey")},inputs:{signinUsername:e.querySelector("#signin-username"),signinPassword:e.querySelector("#signin-password"),forgotEmail:e.querySelector("#forgot-email"),resetCode:e.querySelector("#reset-code"),resetPassword:e.querySelector("#reset-password"),resetPasswordConfirm:e.querySelector("#reset-password-confirm"),setPassword:e.querySelector("#set-password"),setPasswordConfirm:e.querySelector("#set-password-confirm")},radios:{resetMethodCode:e.querySelector("#method-code"),resetMethodLink:e.querySelector("#method-link")},labels:{resetEmailDisplay:e.querySelector("#reset-email-display")},links:{forgot:e.querySelector("#link-forgot")},message:e.querySelector("#status-message")};function S(e){Object.entries(k.views).forEach(([s,t])=>{t&&(t.style.display=s===e?"block":"none")}),setTimeout(()=>{const s=k.views[e],t=s?.querySelector("h1, h2, .auth-title, .h5");if(t)t.setAttribute("tabindex","-1"),t.focus?.();else{const e=s?.querySelector("input, button");e?.focus?.()}},60)}function P(e,s="info"){const t=k.message;t&&(t.textContent=e,t.className=`alert alert-${s}`,t.style.display="block",t.setAttribute("role","danger"===s?"alert":"status"))}function C(){const e=k.message;e&&(e.style.display="none")}function E(e,s){if(!e)return;const t=e.querySelector(".btn-text"),n=e.querySelector(".btn-spinner");e.disabled=!!s,t&&(t.style.display=s?"none":"inline"),n&&(n.style.display=s?"inline-block":"none")}async function I(e){e?.preventDefault?.(),C();const s=k.inputs.signinUsername?.value?.trim(),t=k.inputs.signinPassword?.value;if(s&&t){E(k.buttons.signin,!0);try{await w.login(s,t),P(`${y.successRedirecting}`,"success"),setTimeout(g,350)}catch(n){P(w.getErrorMessage(n)||y.invalidCredentials,"danger"),E(k.buttons.signin,!1)}}else P("Please enter both username and password.","danger")}async function R(e){e?.preventDefault?.(),C();const s=k.inputs.forgotEmail?.value?.trim(),t=k.radios.resetMethodCode?.checked?"code":k.radios.resetMethodLink?.checked?"link":"code";if(s){E(k.buttons.forgot,!0);try{await w.forgot({email:s,method:t}),"code"===t?(sessionStorage.setItem("reset_email",s),sessionStorage.setItem("reset_method",t),k.labels.resetEmailDisplay&&(k.labels.resetEmailDisplay.textContent=s),S("resetCode"),P("Reset code sent! Check your email.","success")):P("Magic link sent! Check your email and click the link.","success")}catch(n){P(w.getErrorMessage(n)||"Something went wrong. Please try again.","danger")}finally{E(k.buttons.forgot,!1)}}else P("Please enter your email address.","danger")}async function q(e){e?.preventDefault?.(),C();const s=k.inputs.resetCode?.value?.trim(),t=k.inputs.resetPassword?.value,n=k.inputs.resetPasswordConfirm?.value,o=sessionStorage.getItem("reset_email");if(!o)return P("Session expired. Please restart the password reset process.","danger"),void S("forgot");if(s&&t)if(t===n){E(k.buttons.resetCode,!0);try{await w.resetWithCode({email:o,code:s,newPassword:t}),sessionStorage.removeItem("reset_email"),sessionStorage.removeItem("reset_method"),P(y.successRedirecting,"success"),setTimeout(g,350)}catch(r){P(w.getErrorMessage(r)||"Invalid code or code expired.","danger"),E(k.buttons.resetCode,!1)}}else P(y.passwordsDoNotMatch,"danger");else P(y.pleaseFillAllFields,"danger")}async function $(e){e?.preventDefault?.(),C();const s=k.inputs.setPassword?.value,t=k.inputs.setPasswordConfirm?.value,n=sessionStorage.getItem("login_token");if(!n)return P("Invalid or expired link. Please request a new one.","danger"),void S("forgot");if(s)if(s===t){E(k.buttons.setPassword,!0);try{await w.resetWithToken({token:n,newPassword:s}),sessionStorage.removeItem("login_token"),P(y.successRedirecting,"success"),setTimeout(g,350)}catch(o){P(w.getErrorMessage(o)||"Invalid or expired link.","danger"),E(k.buttons.setPassword,!1)}}else P(y.passwordsDoNotMatch,"danger");else P("Please enter a new password.","danger")}function x(e){e?.preventDefault?.(),C(),S("forgot")}function L(){C(),S("signin")}function _(){C(),S("forgot")}return k.forms.signin?.addEventListener("submit",I),k.forms.forgot?.addEventListener("submit",R),k.forms.resetCode?.addEventListener("submit",q),k.forms.setPassword?.addEventListener("submit",$),k.links.forgot?.addEventListener("click",x),k.buttons.backSignin?.addEventListener("click",L),k.buttons.backForgot?.addEventListener("click",_),d?.google&&k.buttons.google&&k.buttons.google.addEventListener("click",s=>{s?.preventDefault?.(),d.google.onClick?.({container:e,auth:w,redirect:g,showMessage:P})}),d?.passkey&&k.buttons.passkey&&k.buttons.passkey.addEventListener("click",s=>{s?.preventDefault?.(),d.passkey.onClick?.({container:e,auth:w,redirect:g,showMessage:P})}),function(){const e=new URLSearchParams(window.location.search),s=e.get("login_token");if(s){sessionStorage.setItem("login_token",s),e.delete("login_token");const t=e.toString()?`${window.location.pathname}?${e.toString()}`:window.location.pathname;return window.history.replaceState({},"",t),S("setPassword"),void P("Please set your new password.","info")}const t=sessionStorage.getItem("reset_email");if(t)return k.labels.resetEmailDisplay&&(k.labels.resetEmailDisplay.textContent=t),void S("resetCode");S("signin")}(),{destroy(){k.forms.signin?.removeEventListener("submit",I),k.forms.forgot?.removeEventListener("submit",R),k.forms.resetCode?.removeEventListener("submit",q),k.forms.setPassword?.removeEventListener("submit",$),k.links.forgot?.removeEventListener("click",x),k.buttons.backSignin?.removeEventListener("click",L),k.buttons.backForgot?.removeEventListener("click",_),d?.google&&k.buttons.google&&k.buttons.google.replaceWith(k.buttons.google.cloneNode(!0)),d?.passkey&&k.buttons.passkey&&k.buttons.passkey.replaceWith(k.buttons.passkey.cloneNode(!0)),e.innerHTML=""}}}const n={mountAuth:t,createAuthClient:s},o=/* @__PURE__ */Object.freeze(/* @__PURE__ */Object.defineProperty({__proto__:null,createAuthClient:s,default:n,mountAuth:t},Symbol.toStringTag,{value:"Module"}));exports.BUILD_TIME=e.BUILD_TIME,exports.VERSION=e.VERSION,exports.VERSION_INFO=e.VERSION_INFO,exports.VERSION_MAJOR=e.VERSION_MAJOR,exports.VERSION_MINOR=e.VERSION_MINOR,exports.VERSION_REVISION=e.VERSION_REVISION,exports.createAuthClient=s,exports.default=o,exports.mountAuth=t;
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./chunks/version-CKPqwcQJ.js");function s({baseURL:e,fetchImpl:s=("undefined"!=typeof fetch?fetch.bind(window):null),storage:t=("undefined"!=typeof localStorage?localStorage:null),endpoints:n={}}={}){if(!e)throw new Error("createAuthClient: baseURL is required");if(!s)throw new Error("createAuthClient: fetch implementation is not available in this environment");if(!t)throw new Error("createAuthClient: storage (localStorage) is not available in this environment");const o="access_token",r="refresh_token",a="user",i={login:"/login",forgot:"/auth/forgot",resetCode:"/auth/password/reset/code",resetToken:"/auth/password/reset/token",...n};async function l(t,n){const o=await s(`${e}${t}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n||{})});let r={};try{r=await o.json()}catch(a){}if(!o.ok)throw r||{message:`Request failed with status ${o.status}`};return r}function d(e){return e&&e.data&&e.data.data||e&&e.data||e}function c(e){const s=d(e);if(!s||!s.access_token)throw new Error("No access_token in response.");t.setItem(o,s.access_token),s.refresh_token&&t.setItem(r,s.refresh_token),s.user&&t.setItem(a,JSON.stringify(s.user))}return{async login(e,s){const t=await l(i.login,{username:e,password:s});return c(t),d(t)},forgot:async({email:e,method:s})=>l(i.forgot,{email:e,method:s}),async resetWithCode({email:e,code:s,newPassword:t}){const n=await l(i.resetCode,{email:e,code:s,new_password:t});return c(n),d(n)},async resetWithToken({token:e,newPassword:s}){const t=await l(i.resetToken,{token:e,new_password:s});return c(t),d(t)},logout(){t.removeItem(o),t.removeItem(r),t.removeItem(a)},isAuthenticated:()=>!!t.getItem(o),getToken:()=>t.getItem(o),getUser(){const e=t.getItem(a);try{return e?JSON.parse(e):null}catch{return null}},getAuthHeader(){const e=t.getItem(o);return e?`Bearer ${e}`:null},getErrorMessage:function(e){return e?.message||e?.error||Array.isArray(e?.errors)&&e.errors[0]?.message||"An error occurred. Please try again."},parseResponse:d}}function t(e,t={}){if(!(e&&e instanceof Element))throw new Error("mountAuth: container must be a DOM Element");const{baseURL:n,onSuccessRedirect:o,allowRedirectOrigins:r,branding:a={},theme:i,endpoints:l,providers:d,texts:c={}}=t;if(!n)throw new Error("mountAuth: baseURL is required");const u=new URLSearchParams(window.location.search),m=u.get("redirect")||u.get("next")||u.get("returnTo"),p=String(o||m||"/");function g(){!function(e){if(!r||0===r.length)return!0;try{const s=new URL(e,window.location.origin);return r.includes(s.origin)}catch{return!1}}(p)?window.location.href="/":window.location.href=p.startsWith("http")?p:new URL(p,window.location.origin).href}const w=s({baseURL:n,endpoints:l}),b=a.title||"Sign In",f=a.subtitle||"Sign in to your account",h=a.logoUrl||"",y={emailOrUsername:c.emailOrUsername||"Email or Username",password:c.password||"Password",signIn:c.signIn||"Sign In",forgotPassword:c.forgotPassword||"Forgot password?",resetYourPassword:c.resetYourPassword||"Reset Your Password",emailAddress:c.emailAddress||"Email Address",resetMethod:c.resetMethod||"Reset Method",emailCode:c.emailCode||"Email me a code",emailLink:c.emailLink||"Email me a magic link",sendReset:c.sendReset||"Send Reset",back:c.back||"Back",enterResetCode:c.enterResetCode||"Enter Reset Code",weSentCodeTo:c.weSentCodeTo||"We sent a code to",resetCode:c.resetCode||"Reset Code",newPassword:c.newPassword||"New Password",confirmPassword:c.confirmPassword||"Confirm Password",resetPassword:c.resetPassword||"Reset Password",setYourNewPassword:c.setYourNewPassword||"Set Your New Password",setPassword:c.setPassword||"Set Password",invalidCredentials:c.invalidCredentials||"Invalid credentials.",successRedirecting:c.successRedirecting||"Success! Redirecting...",pleaseFillAllFields:c.pleaseFillAllFields||"Please fill in all fields.",passwordsDoNotMatch:c.passwordsDoNotMatch||"Passwords do not match."},v=`\n <div class="auth-container">\n <div class="auth-card">\n <div class="auth-header">\n ${h?`<img src="${h}" alt="${b}" style="max-height:60px;margin-bottom:10px" />`:""}\n <h1 class="auth-title">${b}</h1>\n <p class="auth-subtitle">${f}</p>\n </div>\n\n <div id="status-message" class="alert" role="status" style="display:none;"></div>\n\n \x3c!-- Sign In View --\x3e\n <div id="view-signin" class="auth-view">\n <form id="form-signin" novalidate>\n <div class="mb-3">\n <label for="signin-username" class="form-label">${y.emailOrUsername}</label>\n <input type="text" class="form-control" id="signin-username" placeholder="${y.emailOrUsername}" autocomplete="username" required />\n </div>\n <div class="mb-3">\n <label for="signin-password" class="form-label">${y.password}</label>\n <input type="password" class="form-control" id="signin-password" placeholder="${y.password}" autocomplete="current-password" required />\n </div>\n <button type="submit" class="btn btn-primary w-100 mb-3" id="btn-signin">\n <span class="btn-text">${y.signIn}</span>\n <span class="btn-spinner spinner-border spinner-border-sm" style="display:none;"></span>\n </button>\n <div class="text-center">\n <a href="#" id="link-forgot" class="text-decoration-none">${y.forgotPassword}</a>\n </div>\n\n ${d&&(d.google||d.passkey)?`\n <div class="position-relative my-3">\n <hr class="text-muted" />\n <span class="position-absolute top-50 start-50 translate-middle bg-white px-3 text-muted small">OR</span>\n </div>\n <div class="d-grid gap-2">\n ${d.google?'<button type="button" class="btn btn-outline-primary" id="btn-google"><i class="bi bi-google me-2"></i>Continue with Google</button>':""}\n ${d.passkey?'<button type="button" class="btn btn-outline-secondary" id="btn-passkey"><i class="bi bi-fingerprint me-2"></i>Sign in with Passkey</button>':""}\n </div>\n `:""}\n </form>\n </div>\n\n \x3c!-- Forgot Password View --\x3e\n <div id="view-forgot" class="auth-view" style="display:none;">\n <button type="button" class="btn btn-link p-0 mb-3" id="btn-back-signin">\n <span aria-hidden="true">←</span> ${y.back}\n </button>\n <h2 class="h5 mb-3">${y.resetYourPassword}</h2>\n <form id="form-forgot" novalidate>\n <div class="mb-3">\n <label for="forgot-email" class="form-label">${y.emailAddress}</label>\n <input type="email" class="form-control" id="forgot-email" placeholder="${y.emailAddress}" autocomplete="email" required />\n </div>\n <div class="mb-3">\n <label class="form-label">${y.resetMethod}</label>\n <div class="form-check">\n <input class="form-check-input" type="radio" name="reset-method" id="method-code" value="code" checked />\n <label class="form-check-label" for="method-code">${y.emailCode}</label>\n </div>\n <div class="form-check">\n <input class="form-check-input" type="radio" name="reset-method" id="method-link" value="link" />\n <label class="form-check-label" for="method-link">${y.emailLink}</label>\n </div>\n </div>\n <button type="submit" class="btn btn-primary w-100" id="btn-forgot">\n <span class="btn-text">${y.sendReset}</span>\n <span class="btn-spinner spinner-border spinner-border-sm" style="display:none;"></span>\n </button>\n </form>\n </div>\n\n \x3c!-- Reset with Code View --\x3e\n <div id="view-reset-code" class="auth-view" style="display:none;">\n <button type="button" class="btn btn-link p-0 mb-3" id="btn-back-forgot">\n <span aria-hidden="true">←</span> ${y.back}\n </button>\n <h2 class="h5 mb-3">${y.enterResetCode}</h2>\n <p class="text-muted small mb-3">${y.weSentCodeTo} <strong id="reset-email-display"></strong></p>\n <form id="form-reset-code" novalidate>\n <div class="mb-3">\n <label for="reset-code" class="form-label">${y.resetCode}</label>\n <input type="text" class="form-control" id="reset-code" placeholder="${y.resetCode}" required />\n </div>\n <div class="mb-3">\n <label for="reset-password" class="form-label">${y.newPassword}</label>\n <input type="password" class="form-control" id="reset-password" placeholder="${y.newPassword}" autocomplete="new-password" required />\n </div>\n <div class="mb-3">\n <label for="reset-password-confirm" class="form-label">${y.confirmPassword}</label>\n <input type="password" class="form-control" id="reset-password-confirm" placeholder="${y.confirmPassword}" autocomplete="new-password" required />\n </div>\n <button type="submit" class="btn btn-primary w-100" id="btn-reset-code">\n <span class="btn-text">${y.resetPassword}</span>\n <span class="btn-spinner spinner-border spinner-border-sm" style="display:none;"></span>\n </button>\n </form>\n </div>\n\n \x3c!-- Set Password via Magic Link View --\x3e\n <div id="view-set-password" class="auth-view" style="display:none;">\n <h2 class="h5 mb-3">${y.setYourNewPassword}</h2>\n <form id="form-set-password" novalidate>\n <div class="mb-3">\n <label for="set-password" class="form-label">${y.newPassword}</label>\n <input type="password" class="form-control" id="set-password" placeholder="${y.newPassword}" autocomplete="new-password" required />\n </div>\n <div class="mb-3">\n <label for="set-password-confirm" class="form-label">${y.confirmPassword}</label>\n <input type="password" class="form-control" id="set-password-confirm" placeholder="${y.confirmPassword}" autocomplete="new-password" required />\n </div>\n <button type="submit" class="btn btn-primary w-100" id="btn-set-password">\n <span class="btn-text">${y.setPassword}</span>\n <span class="btn-spinner spinner-border spinner-border-sm" style="display:none;"></span>\n </button>\n </form>\n </div>\n </div>\n </div>\n `;e.innerHTML=v,i&&e.classList.add(String(i));const k={views:{signin:e.querySelector("#view-signin"),forgot:e.querySelector("#view-forgot"),resetCode:e.querySelector("#view-reset-code"),setPassword:e.querySelector("#view-set-password")},forms:{signin:e.querySelector("#form-signin"),forgot:e.querySelector("#form-forgot"),resetCode:e.querySelector("#form-reset-code"),setPassword:e.querySelector("#form-set-password")},buttons:{signin:e.querySelector("#btn-signin"),forgot:e.querySelector("#btn-forgot"),resetCode:e.querySelector("#btn-reset-code"),setPassword:e.querySelector("#btn-set-password"),backSignin:e.querySelector("#btn-back-signin"),backForgot:e.querySelector("#btn-back-forgot"),google:e.querySelector("#btn-google"),passkey:e.querySelector("#btn-passkey")},inputs:{signinUsername:e.querySelector("#signin-username"),signinPassword:e.querySelector("#signin-password"),forgotEmail:e.querySelector("#forgot-email"),resetCode:e.querySelector("#reset-code"),resetPassword:e.querySelector("#reset-password"),resetPasswordConfirm:e.querySelector("#reset-password-confirm"),setPassword:e.querySelector("#set-password"),setPasswordConfirm:e.querySelector("#set-password-confirm")},radios:{resetMethodCode:e.querySelector("#method-code"),resetMethodLink:e.querySelector("#method-link")},labels:{resetEmailDisplay:e.querySelector("#reset-email-display")},links:{forgot:e.querySelector("#link-forgot")},message:e.querySelector("#status-message")};function S(e){Object.entries(k.views).forEach(([s,t])=>{t&&(t.style.display=s===e?"block":"none")}),setTimeout(()=>{const s=k.views[e],t=s?.querySelector("h1, h2, .auth-title, .h5");if(t)t.setAttribute("tabindex","-1"),t.focus?.();else{const e=s?.querySelector("input, button");e?.focus?.()}},60)}function P(e,s="info"){const t=k.message;t&&(t.textContent=e,t.className=`alert alert-${s}`,t.style.display="block",t.setAttribute("role","danger"===s?"alert":"status"))}function C(){const e=k.message;e&&(e.style.display="none")}function E(e,s){if(!e)return;const t=e.querySelector(".btn-text"),n=e.querySelector(".btn-spinner");e.disabled=!!s,t&&(t.style.display=s?"none":"inline"),n&&(n.style.display=s?"inline-block":"none")}async function I(e){e?.preventDefault?.(),C();const s=k.inputs.signinUsername?.value?.trim(),t=k.inputs.signinPassword?.value;if(s&&t){E(k.buttons.signin,!0);try{await w.login(s,t),P(`${y.successRedirecting}`,"success"),setTimeout(g,350)}catch(n){P(w.getErrorMessage(n)||y.invalidCredentials,"danger"),E(k.buttons.signin,!1)}}else P("Please enter both username and password.","danger")}async function R(e){e?.preventDefault?.(),C();const s=k.inputs.forgotEmail?.value?.trim(),t=k.radios.resetMethodCode?.checked?"code":k.radios.resetMethodLink?.checked?"link":"code";if(s){E(k.buttons.forgot,!0);try{await w.forgot({email:s,method:t}),"code"===t?(sessionStorage.setItem("reset_email",s),sessionStorage.setItem("reset_method",t),k.labels.resetEmailDisplay&&(k.labels.resetEmailDisplay.textContent=s),S("resetCode"),P("Reset code sent! Check your email.","success")):P("Magic link sent! Check your email and click the link.","success")}catch(n){P(w.getErrorMessage(n)||"Something went wrong. Please try again.","danger")}finally{E(k.buttons.forgot,!1)}}else P("Please enter your email address.","danger")}async function q(e){e?.preventDefault?.(),C();const s=k.inputs.resetCode?.value?.trim(),t=k.inputs.resetPassword?.value,n=k.inputs.resetPasswordConfirm?.value,o=sessionStorage.getItem("reset_email");if(!o)return P("Session expired. Please restart the password reset process.","danger"),void S("forgot");if(s&&t)if(t===n){E(k.buttons.resetCode,!0);try{await w.resetWithCode({email:o,code:s,newPassword:t}),sessionStorage.removeItem("reset_email"),sessionStorage.removeItem("reset_method"),P(y.successRedirecting,"success"),setTimeout(g,350)}catch(r){P(w.getErrorMessage(r)||"Invalid code or code expired.","danger"),E(k.buttons.resetCode,!1)}}else P(y.passwordsDoNotMatch,"danger");else P(y.pleaseFillAllFields,"danger")}async function $(e){e?.preventDefault?.(),C();const s=k.inputs.setPassword?.value,t=k.inputs.setPasswordConfirm?.value,n=sessionStorage.getItem("login_token");if(!n)return P("Invalid or expired link. Please request a new one.","danger"),void S("forgot");if(s)if(s===t){E(k.buttons.setPassword,!0);try{await w.resetWithToken({token:n,newPassword:s}),sessionStorage.removeItem("login_token"),P(y.successRedirecting,"success"),setTimeout(g,350)}catch(o){P(w.getErrorMessage(o)||"Invalid or expired link.","danger"),E(k.buttons.setPassword,!1)}}else P(y.passwordsDoNotMatch,"danger");else P("Please enter a new password.","danger")}function x(e){e?.preventDefault?.(),C(),S("forgot")}function L(){C(),S("signin")}function _(){C(),S("forgot")}return k.forms.signin?.addEventListener("submit",I),k.forms.forgot?.addEventListener("submit",R),k.forms.resetCode?.addEventListener("submit",q),k.forms.setPassword?.addEventListener("submit",$),k.links.forgot?.addEventListener("click",x),k.buttons.backSignin?.addEventListener("click",L),k.buttons.backForgot?.addEventListener("click",_),d?.google&&k.buttons.google&&k.buttons.google.addEventListener("click",s=>{s?.preventDefault?.(),d.google.onClick?.({container:e,auth:w,redirect:g,showMessage:P})}),d?.passkey&&k.buttons.passkey&&k.buttons.passkey.addEventListener("click",s=>{s?.preventDefault?.(),d.passkey.onClick?.({container:e,auth:w,redirect:g,showMessage:P})}),function(){const e=new URLSearchParams(window.location.search),s=e.get("login_token");if(s){sessionStorage.setItem("login_token",s),e.delete("login_token");const t=e.toString()?`${window.location.pathname}?${e.toString()}`:window.location.pathname;return window.history.replaceState({},"",t),S("setPassword"),void P("Please set your new password.","info")}const t=sessionStorage.getItem("reset_email");if(t)return k.labels.resetEmailDisplay&&(k.labels.resetEmailDisplay.textContent=t),void S("resetCode");S("signin")}(),{destroy(){k.forms.signin?.removeEventListener("submit",I),k.forms.forgot?.removeEventListener("submit",R),k.forms.resetCode?.removeEventListener("submit",q),k.forms.setPassword?.removeEventListener("submit",$),k.links.forgot?.removeEventListener("click",x),k.buttons.backSignin?.removeEventListener("click",L),k.buttons.backForgot?.removeEventListener("click",_),d?.google&&k.buttons.google&&k.buttons.google.replaceWith(k.buttons.google.cloneNode(!0)),d?.passkey&&k.buttons.passkey&&k.buttons.passkey.replaceWith(k.buttons.passkey.cloneNode(!0)),e.innerHTML=""}}}const n={mountAuth:t,createAuthClient:s},o=/* @__PURE__ */Object.freeze(/* @__PURE__ */Object.defineProperty({__proto__:null,createAuthClient:s,default:n,mountAuth:t},Symbol.toStringTag,{value:"Module"}));exports.BUILD_TIME=e.BUILD_TIME,exports.VERSION=e.VERSION,exports.VERSION_INFO=e.VERSION_INFO,exports.VERSION_MAJOR=e.VERSION_MAJOR,exports.VERSION_MINOR=e.VERSION_MINOR,exports.VERSION_REVISION=e.VERSION_REVISION,exports.createAuthClient=s,exports.default=o,exports.mountAuth=t;
|
|
2
2
|
//# sourceMappingURL=auth.cjs.js.map
|
package/dist/auth.es.js
CHANGED
package/dist/charts.cjs.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("./chunks/MetricsMiniChartWidget-CN1HPnWf.js"),e=require("./chunks/Dialog-7T8ENHYD.js"),t=require("./chunks/version-WMgX72-y.js");exports.BaseChart=r.BaseChart,exports.MetricsChart=r.MetricsChart,exports.MetricsMiniChart=r.MetricsMiniChart,exports.MetricsMiniChartWidget=r.MetricsMiniChartWidget,exports.MiniChart=r.MiniChart,exports.PieChart=r.PieChart,exports.SeriesChart=r.SeriesChart,exports.WebApp=e.WebApp,exports.BUILD_TIME=t.BUILD_TIME,exports.VERSION=t.VERSION,exports.VERSION_INFO=t.VERSION_INFO,exports.VERSION_MAJOR=t.VERSION_MAJOR,exports.VERSION_MINOR=t.VERSION_MINOR,exports.VERSION_REVISION=t.VERSION_REVISION;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./chunks/MetricsMiniChartWidget-BNdGuSZV.js"),e=require("./chunks/Rest-BpDyhFfG.js"),s=require("./chunks/Dialog-BfXN-fFA.js"),i=require("./chunks/version-CKPqwcQJ.js");class CircularProgress extends e.View{constructor(t={}){super({className:`circular-progress ${t.className||""}`,...t}),this.SIZE_PRESETS={xs:40,sm:60,md:80,lg:120,xl:180},this.STROKE_PRESETS={xs:4,sm:6,md:8,lg:12,xl:16},this.value=void 0!==t.value?t.value:0,this.min=void 0!==t.min?t.min:0,this.max=void 0!==t.max?t.max:100,this.sizePreset="string"==typeof t.size&&this.SIZE_PRESETS[t.size]?t.size:null,this.size=this.resolveSize(void 0!==t.size?t.size:"md"),this.strokeWidth="auto"===t.strokeWidth||void 0===t.strokeWidth?this.getAutoStrokeWidth(t.size):t.strokeWidth,this.theme=t.theme||"basic",this.variant=t.variant||"default",this.color=t.color,this.trackColor=t.trackColor,this.textColor=t.textColor,this.gradientColors=t.gradientColors||null,this.applyTheme(),this.applyVariant(),this.rotation=void 0!==t.rotation?t.rotation:-90,this.gap=t.gap||0,this.showValue=!1!==t.showValue,this.valueFormat=t.valueFormat||"percentage",this.valueFormatter=t.valueFormatter||null,this.label=t.label||null,this.labelHtml=t.labelHtml||null,this.icon=t.icon||null,this.animate=!1!==t.animate,this.animationDuration=t.animationDuration||600,this.animationEasing=t.animationEasing||"ease-out",this.rounded=!1!==t.rounded,this.shadow=t.shadow||!1,this.clickable=t.clickable||!1,this.tooltip=t.tooltip||null,this.tooltipPlacement=t.tooltipPlacement||"top",this.segments=t.segments||null,this.segmentGap=t.segmentGap||2,this.dataFormatter=e.dataFormatter,this.svg=null,this.centerElement=null,this.popover=null,this.gradientId=`gradient-${Math.random().toString(36).substr(2,9)}`}resolveSize(t){return"string"==typeof t&&this.SIZE_PRESETS[t]?this.SIZE_PRESETS[t]:"number"==typeof t?t:this.SIZE_PRESETS.md}getAutoStrokeWidth(t){if("string"==typeof t&&this.STROKE_PRESETS[t])return this.STROKE_PRESETS[t];const e=this.resolveSize(t);return e<=40?4:e<=60?6:e<=80?8:e<=120?12:16}applyTheme(){const t={basic:{trackColor:"#e9ecef",textColor:null,backgroundColor:null},shadowed:{trackColor:"#d1d5db",textColor:null,backgroundColor:null,shadow:!0},dark:{trackColor:"#374151",textColor:"#e5e7eb",backgroundColor:"#1f2937"},light:{trackColor:"#f3f4f6",textColor:"#111827",backgroundColor:"#ffffff"}},e=t[this.theme]||t.basic;this.trackColor||(this.trackColor=e.trackColor),!this.textColor&&e.textColor&&(this.textColor=e.textColor),e.shadow&&!1===this.shadow&&(this.shadow=e.shadow)}applyVariant(){const t={success:{color:"#198754",trackColor:"rgba(25, 135, 84, 0.1)"},danger:{color:"#dc3545",trackColor:"rgba(220, 53, 69, 0.1)"},warning:{color:"#ffc107",trackColor:"rgba(255, 193, 7, 0.1)"},info:{color:"#0dcaf0",trackColor:"rgba(13, 202, 240, 0.1)"},default:{color:"#0d6efd"}};if(t[this.variant]){const e=t[this.variant];this.color||(this.color=e.color),e.trackColor&&this.trackColor===this.applyTheme.trackColor&&(this.trackColor=e.trackColor)}this.color||(this.color="#0d6efd")}getTemplate(){const t=this.sizePreset?`circular-progress-${this.sizePreset}`:"",e="default"!==this.variant?`circular-progress-${this.variant}`:"",s="basic"!==this.theme?`circular-progress-theme-${this.theme}`:"",i=this.clickable?"circular-progress-clickable":"",r=this.shadow?"circular-progress-shadow":"",o=this.textColor?`color: ${this.textColor};`:"";return`\n <div class="circular-progress-container ${t} ${e} ${s} ${i} ${r}"\n style="width: ${this.size}px; height: ${this.size}px;">\n <svg class="circular-progress-svg" \n width="${this.size}" \n height="${this.size}"\n viewBox="0 0 ${this.size} ${this.size}">\n </svg>\n <div class="circular-progress-center" style="${o}">\n <div class="circular-progress-content"></div>\n </div>\n </div>\n `}async onAfterRender(){this.svg=this.element.querySelector(".circular-progress-svg"),this.centerElement=this.element.querySelector(".circular-progress-content"),this.containerElement=this.element.querySelector(".circular-progress-container"),this.renderProgress(),this.renderCenterContent(),this.clickable&&this.setupClickHandler(),this.tooltip&&this.clickable&&this.setupTooltip()}renderProgress(){if(!this.svg)return;this.svg.innerHTML="";const t=this.size/2,e=(this.size-this.strokeWidth)/2,s=2*Math.PI*e;this.gradientColors&&this.gradientColors.length>1&&this.createGradient(),this.segments&&Array.isArray(this.segments)&&this.segments.length>0?this.renderSegments(t,e,s):this.renderSingleProgress(t,e,s)}renderSingleProgress(t,e,s){const i=(this.gap>0?360-this.gap:360)/360*s,r=this.createCircle(t,e,{stroke:this.trackColor,strokeWidth:this.strokeWidth,fill:"none",strokeLinecap:this.rounded?"round":"butt",strokeDasharray:this.gap>0?`${i} ${s}`:"none",transform:`rotate(${this.rotation} ${t} ${t})`});this.svg.appendChild(r);const o=i-this.getPercentage()/100*i,a=this.gradientColors?`url(#${this.gradientId})`:this.color,n=this.createCircle(t,e,{stroke:a,strokeWidth:this.strokeWidth,fill:"none",strokeLinecap:this.rounded?"round":"butt",strokeDasharray:`${i} ${s}`,strokeDashoffset:this.animate?i:o,transform:`rotate(${this.rotation} ${t} ${t})`,class:"circular-progress-bar"});this.svg.appendChild(n),this.animate&&this.animateProgress(n,o)}renderSegments(t,e,s){const i=(this.gap>0?360-this.gap:360)/360*s,r=this.createCircle(t,e,{stroke:this.trackColor,strokeWidth:this.strokeWidth,fill:"none",strokeLinecap:this.rounded?"round":"butt",strokeDasharray:this.gap>0?`${i} ${s}`:"none",transform:`rotate(${this.rotation} ${t} ${t})`});this.svg.appendChild(r),this.segments.reduce((t,e)=>t+(e.value||0),0)>this.max&&console.warn("CircularProgress: Segment total exceeds max value. Clamping to max.");let o=0;this.segments.forEach((r,a)=>{const n=(r.value||0)/(this.max-this.min)*100/100*i,h=this.segmentGap/360*s;if(n>0){const l=this.createCircle(t,e,{stroke:r.color||this.color,strokeWidth:this.strokeWidth,fill:"none",strokeLinecap:this.rounded?"round":"butt",strokeDasharray:`${n} ${s}`,strokeDashoffset:this.animate?i:-o,transform:`rotate(${this.rotation} ${t} ${t})`,class:`circular-progress-segment circular-progress-segment-${a}`,"data-segment-index":a});this.svg.appendChild(l),this.animate&&this.animateProgress(l,-o,100*a),o+=n+h}})}createCircle(t,e,s={}){const i=document.createElementNS("http://www.w3.org/2000/svg","circle");return i.setAttribute("cx",t),i.setAttribute("cy",t),i.setAttribute("r",e),Object.entries(s).forEach(([t,e])=>{"strokeWidth"===t?i.setAttribute("stroke-width",e):"strokeLinecap"===t?i.setAttribute("stroke-linecap",e):"strokeDasharray"===t?i.setAttribute("stroke-dasharray",e):"strokeDashoffset"===t?i.setAttribute("stroke-dashoffset",e):i.setAttribute(t,e)}),i}createGradient(){const t=document.createElementNS("http://www.w3.org/2000/svg","defs"),e=document.createElementNS("http://www.w3.org/2000/svg","linearGradient");e.setAttribute("id",this.gradientId),e.setAttribute("x1","0%"),e.setAttribute("y1","0%"),e.setAttribute("x2","100%"),e.setAttribute("y2","100%"),this.gradientColors.forEach((t,s)=>{const i=document.createElementNS("http://www.w3.org/2000/svg","stop"),r=s/(this.gradientColors.length-1)*100;i.setAttribute("offset",`${r}%`),i.setAttribute("stop-color",t),e.appendChild(i)}),t.appendChild(e),this.svg.appendChild(t)}animateProgress(t,e,s=0){setTimeout(()=>{t.style.transition=`stroke-dashoffset ${this.animationDuration}ms ${this.animationEasing}`,t.style.strokeDashoffset=e},s)}renderCenterContent(){if(this.centerElement)if(this.labelHtml)this.centerElement.innerHTML=this.labelHtml;else if(this.icon)this.centerElement.innerHTML=`<i class="${this.icon}"></i>`;else if(this.showValue){let t=`<div class="circular-progress-value">${this.getFormattedValue()}</div>`;this.label&&(t+=`<div class="circular-progress-label">${this.label}</div>`),this.centerElement.innerHTML=t}}getFormattedValue(){const t=this.value,e=this.min,s=this.max;if(this.valueFormatter&&"function"==typeof this.valueFormatter)return this.valueFormatter(t,e,s);switch(this.valueFormat){case"percentage":return`${Math.round(this.getPercentage())}%`;case"fraction":return`${t}/${s}`;case"value":return t.toString();default:if(this.dataFormatter)try{return this.dataFormatter.pipe(t,this.valueFormat)}catch(i){return console.warn("CircularProgress: DataFormatter error, falling back to percentage",i),`${Math.round(this.getPercentage())}%`}return`${Math.round(this.getPercentage())}%`}}getPercentage(){const t=this.max-this.min;return 0===t?0:(this.value-this.min)/t*100}setupClickHandler(){this.containerElement&&(this.containerElement.style.cursor="pointer",this.containerElement.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation();const e=this.getPercentage();this.emit("progress:clicked",{value:this.value,percentage:e,min:this.min,max:this.max}),this.tooltip&&this.togglePopover()}))}setupTooltip(){}togglePopover(){if(this.containerElement&&void 0!==window.bootstrap){if(!this.popover){const t=this.getTooltipContent(),e="object"==typeof this.tooltip&&this.tooltip.title?this.tooltip.title:void 0,s={content:t,html:!0,placement:this.tooltipPlacement,trigger:"manual",container:"body"};e&&(s.title=e),this.popover=new window.bootstrap.Popover(this.containerElement,s)}window.bootstrap.Popover.getInstance(this.containerElement)&&this.containerElement.getAttribute("aria-describedby")?this.popover.hide():(this.popover.setContent({".popover-body":this.getTooltipContent()}),this.popover.show())}else console.warn("CircularProgress: Bootstrap is required for tooltip support")}getTooltipContent(){return"function"==typeof this.tooltip?this.tooltip(this.value,{min:this.min,max:this.max,percentage:this.getPercentage()}):"object"==typeof this.tooltip?this.tooltip.html||this.tooltip.content||"":this.tooltip||""}setValue(t,e=!0){if(this.value,this.value=Math.max(this.min,Math.min(this.max,t)),this.renderCenterContent(),this.svg&&!this.segments){const t=this.svg.querySelector(".circular-progress-bar");if(t){const s=this.size/2-this.strokeWidth/2,i=2*Math.PI*s,r=(this.gap>0?360-this.gap:360)/360*i,o=r-this.getPercentage()/100*r;e?(t.style.transition=`stroke-dashoffset ${this.animationDuration}ms ${this.animationEasing}`,t.style.strokeDashoffset=o):(t.style.transition="none",t.style.strokeDashoffset=o)}}else{const t=this.animate;this.animate=e,this.renderProgress(),this.animate=t}}setRange(t,e){this.min=t,this.max=e,this.renderProgress(),this.renderCenterContent()}increment(t=1){this.setValue(this.value+t)}decrement(t=1){this.setValue(this.value-t)}setColor(t){if(this.color=t,this.gradientColors=null,this.svg&&!this.segments){const e=this.svg.querySelector(".circular-progress-bar");e&&e.setAttribute("stroke",t)}else this.renderProgress()}setGradient(t){Array.isArray(t)&&t.length>1&&(this.gradientColors=t,this.gradientId=`gradient-${Math.random().toString(36).substr(2,9)}`,this.renderProgress())}setSize(t){this.containerElement&&this.sizePreset&&this.containerElement.classList.remove(`circular-progress-${this.sizePreset}`),this.sizePreset="string"==typeof t&&this.SIZE_PRESETS[t]?t:null,this.size=this.resolveSize(t),this.strokeWidth=this.getAutoStrokeWidth(t),this.containerElement&&(this.containerElement.style.width=`${this.size}px`,this.containerElement.style.height=`${this.size}px`,this.sizePreset&&this.containerElement.classList.add(`circular-progress-${this.sizePreset}`)),this.svg&&(this.svg.setAttribute("width",this.size),this.svg.setAttribute("height",this.size),this.svg.setAttribute("viewBox",`0 0 ${this.size} ${this.size}`)),this.renderProgress()}animateTo(t,e=1e3){const s=this.value,i=t-s,r=performance.now(),o=a=>{const n=a-r,h=Math.min(n/e,1),l=1-Math.pow(1-h,3),c=s+i*l;this.setValue(c,!1),h<1?requestAnimationFrame(o):this.setValue(t,!1)};requestAnimationFrame(o)}pulse(){this.containerElement&&(this.containerElement.style.animation="none",setTimeout(()=>{this.containerElement.style.animation="circular-progress-pulse 0.5s ease-out"},10),setTimeout(()=>{this.containerElement.style.animation=""},500))}complete(){this.variant="success",this.applyVariant(),this.setValue(this.max),this.pulse()}reset(){this.setValue(this.min)}hide(){this.element&&(this.element.style.display="none")}show(){this.element&&(this.element.style.display="")}getValue(){return this.value}getPercentageValue(){return this.getPercentage()}async onBeforeDestroy(){this.popover&&(this.popover.dispose(),this.popover=null),await super.onBeforeDestroy()}}exports.BaseChart=t.BaseChart,exports.MetricsChart=t.MetricsChart,exports.MetricsMiniChart=t.MetricsMiniChart,exports.MetricsMiniChartWidget=t.MetricsMiniChartWidget,exports.MiniChart=t.MiniChart,exports.PieChart=t.PieChart,exports.SeriesChart=t.SeriesChart,exports.WebApp=s.WebApp,exports.BUILD_TIME=i.BUILD_TIME,exports.VERSION=i.VERSION,exports.VERSION_INFO=i.VERSION_INFO,exports.VERSION_MAJOR=i.VERSION_MAJOR,exports.VERSION_MINOR=i.VERSION_MINOR,exports.VERSION_REVISION=i.VERSION_REVISION,exports.CircularProgress=CircularProgress;
|
|
2
2
|
//# sourceMappingURL=charts.cjs.js.map
|
package/dist/charts.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"charts.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"charts.cjs.js","sources":["../src/extensions/charts/CircularProgress.js"],"sourcesContent":["/**\n * CircularProgress - Modern circular progress indicator component\n * Supports single/multi-segment progress, animations, gradients, and tooltips\n * Uses SVG for crisp rendering at any size\n */\n\nimport View from '@core/View.js';\nimport dataFormatter from '@core/utils/DataFormatter.js';\n\nexport default class CircularProgress extends View {\n constructor(options = {}) {\n super({\n className: `circular-progress ${options.className || ''}`,\n ...options\n });\n\n // Size presets\n this.SIZE_PRESETS = {\n 'xs': 40,\n 'sm': 60,\n 'md': 80,\n 'lg': 120,\n 'xl': 180\n };\n\n // Stroke width presets (auto-calculated based on size)\n this.STROKE_PRESETS = {\n 'xs': 4,\n 'sm': 6,\n 'md': 8,\n 'lg': 12,\n 'xl': 16\n };\n\n // Core configuration\n this.value = options.value !== undefined ? options.value : 0;\n this.min = options.min !== undefined ? options.min : 0;\n this.max = options.max !== undefined ? options.max : 100;\n\n // Dimensions\n this.sizePreset = (typeof options.size === 'string' && this.SIZE_PRESETS[options.size]) ? options.size : null;\n this.size = this.resolveSize(options.size !== undefined ? options.size : 'md');\n this.strokeWidth = options.strokeWidth === 'auto' || options.strokeWidth === undefined\n ? this.getAutoStrokeWidth(options.size)\n : options.strokeWidth;\n\n // Colors & Styling\n this.theme = options.theme || 'basic'; // 'basic', '3d', 'dark', 'light'\n this.variant = options.variant || 'default';\n this.color = options.color; // Will be set by applyVariant if not provided\n this.trackColor = options.trackColor; // Will be set by applyTheme if not provided\n this.textColor = options.textColor; // Custom text color\n this.gradientColors = options.gradientColors || null;\n\n // Apply theme (sets colors based on theme)\n this.applyTheme();\n \n // Apply variant colors (sets this.color if not provided)\n this.applyVariant();\n\n // Arc configuration\n this.rotation = options.rotation !== undefined ? options.rotation : -90; // Start at top\n this.gap = options.gap || 0; // Gap in degrees (0 = full circle)\n\n // Center content\n this.showValue = options.showValue !== false;\n this.valueFormat = options.valueFormat || 'percentage';\n this.valueFormatter = options.valueFormatter || null;\n this.label = options.label || null;\n this.labelHtml = options.labelHtml || null;\n this.icon = options.icon || null;\n\n // Animation\n this.animate = options.animate !== false;\n this.animationDuration = options.animationDuration || 600;\n this.animationEasing = options.animationEasing || 'ease-out';\n\n // Visual options\n this.rounded = options.rounded !== false;\n this.shadow = options.shadow || false;\n\n // Interaction\n this.clickable = options.clickable || false;\n this.tooltip = options.tooltip || null;\n this.tooltipPlacement = options.tooltipPlacement || 'top';\n\n // Multi-segment mode\n this.segments = options.segments || null;\n this.segmentGap = options.segmentGap || 2; // Gap between segments in degrees\n\n // DataFormatter instance\n this.dataFormatter = dataFormatter;\n\n // Internal state\n this.svg = null;\n this.centerElement = null;\n this.popover = null;\n this.gradientId = `gradient-${Math.random().toString(36).substr(2, 9)}`;\n }\n\n resolveSize(size) {\n if (typeof size === 'string' && this.SIZE_PRESETS[size]) {\n return this.SIZE_PRESETS[size];\n }\n return typeof size === 'number' ? size : this.SIZE_PRESETS.md;\n }\n\n getAutoStrokeWidth(size) {\n if (typeof size === 'string' && this.STROKE_PRESETS[size]) {\n return this.STROKE_PRESETS[size];\n }\n // Auto-calculate based on size\n const actualSize = this.resolveSize(size);\n if (actualSize <= 40) return 4;\n if (actualSize <= 60) return 6;\n if (actualSize <= 80) return 8;\n if (actualSize <= 120) return 12;\n return 16;\n }\n\n applyTheme() {\n const themes = {\n 'basic': {\n trackColor: '#e9ecef',\n textColor: null, // Use default\n backgroundColor: null\n },\n 'shadowed': {\n trackColor: '#d1d5db',\n textColor: null,\n backgroundColor: null,\n shadow: true\n },\n 'dark': {\n trackColor: '#374151',\n textColor: '#e5e7eb',\n backgroundColor: '#1f2937'\n },\n 'light': {\n trackColor: '#f3f4f6',\n textColor: '#111827',\n backgroundColor: '#ffffff'\n }\n };\n\n const themeConfig = themes[this.theme] || themes.basic;\n \n // Apply theme defaults if not explicitly set\n if (!this.trackColor) {\n this.trackColor = themeConfig.trackColor;\n }\n if (!this.textColor && themeConfig.textColor) {\n this.textColor = themeConfig.textColor;\n }\n if (themeConfig.shadow && this.shadow === false) {\n this.shadow = themeConfig.shadow;\n }\n }\n\n applyVariant() {\n const variants = {\n 'success': { color: '#198754', trackColor: 'rgba(25, 135, 84, 0.1)' },\n 'danger': { color: '#dc3545', trackColor: 'rgba(220, 53, 69, 0.1)' },\n 'warning': { color: '#ffc107', trackColor: 'rgba(255, 193, 7, 0.1)' },\n 'info': { color: '#0dcaf0', trackColor: 'rgba(13, 202, 240, 0.1)' },\n 'default': { color: '#0d6efd' } // Default blue color\n };\n\n if (variants[this.variant]) {\n const variantColors = variants[this.variant];\n if (!this.color) {\n this.color = variantColors.color;\n }\n if (variantColors.trackColor && this.trackColor === this.applyTheme.trackColor) {\n this.trackColor = variantColors.trackColor;\n }\n }\n \n // Fallback if no color is set\n if (!this.color) {\n this.color = '#0d6efd';\n }\n }\n\n getTemplate() {\n const sizeClass = this.sizePreset ? `circular-progress-${this.sizePreset}` : '';\n const variantClass = this.variant !== 'default' ? `circular-progress-${this.variant}` : '';\n const themeClass = this.theme !== 'basic' ? `circular-progress-theme-${this.theme}` : '';\n const clickableClass = this.clickable ? 'circular-progress-clickable' : '';\n const shadowClass = this.shadow ? 'circular-progress-shadow' : '';\n \n const textColorStyle = this.textColor ? `color: ${this.textColor};` : '';\n\n return `\n <div class=\"circular-progress-container ${sizeClass} ${variantClass} ${themeClass} ${clickableClass} ${shadowClass}\"\n style=\"width: ${this.size}px; height: ${this.size}px;\">\n <svg class=\"circular-progress-svg\" \n width=\"${this.size}\" \n height=\"${this.size}\"\n viewBox=\"0 0 ${this.size} ${this.size}\">\n </svg>\n <div class=\"circular-progress-center\" style=\"${textColorStyle}\">\n <div class=\"circular-progress-content\"></div>\n </div>\n </div>\n `;\n }\n\n async onAfterRender() {\n this.svg = this.element.querySelector('.circular-progress-svg');\n this.centerElement = this.element.querySelector('.circular-progress-content');\n this.containerElement = this.element.querySelector('.circular-progress-container');\n\n // Render the progress circle\n this.renderProgress();\n\n // Render center content\n this.renderCenterContent();\n\n // Setup interactions\n if (this.clickable) {\n this.setupClickHandler();\n }\n\n // Setup tooltip\n if (this.tooltip && this.clickable) {\n this.setupTooltip();\n }\n }\n\n renderProgress() {\n if (!this.svg) return;\n\n // Clear previous content\n this.svg.innerHTML = '';\n\n const center = this.size / 2;\n const radius = (this.size - this.strokeWidth) / 2;\n const circumference = 2 * Math.PI * radius;\n\n // Create gradient definition if needed\n if (this.gradientColors && this.gradientColors.length > 1) {\n this.createGradient();\n }\n\n // Determine if we're using segments or single progress\n if (this.segments && Array.isArray(this.segments) && this.segments.length > 0) {\n this.renderSegments(center, radius, circumference);\n } else {\n this.renderSingleProgress(center, radius, circumference);\n }\n }\n\n renderSingleProgress(center, radius, circumference) {\n // Calculate arc length\n const arcLength = this.gap > 0 ? (360 - this.gap) : 360;\n const arcCircumference = (arcLength / 360) * circumference;\n\n // Create track (background circle/arc)\n const track = this.createCircle(center, radius, {\n stroke: this.trackColor,\n strokeWidth: this.strokeWidth,\n fill: 'none',\n strokeLinecap: this.rounded ? 'round' : 'butt',\n strokeDasharray: this.gap > 0 ? `${arcCircumference} ${circumference}` : 'none',\n transform: `rotate(${this.rotation} ${center} ${center})`\n });\n this.svg.appendChild(track);\n\n // Create progress circle\n const percentage = this.getPercentage();\n const progressLength = (percentage / 100) * arcCircumference;\n const dashOffset = arcCircumference - progressLength;\n\n const strokeColor = this.gradientColors ? `url(#${this.gradientId})` : this.color;\n\n const progress = this.createCircle(center, radius, {\n stroke: strokeColor,\n strokeWidth: this.strokeWidth,\n fill: 'none',\n strokeLinecap: this.rounded ? 'round' : 'butt',\n strokeDasharray: `${arcCircumference} ${circumference}`,\n strokeDashoffset: this.animate ? arcCircumference : dashOffset,\n transform: `rotate(${this.rotation} ${center} ${center})`,\n class: 'circular-progress-bar'\n });\n\n this.svg.appendChild(progress);\n\n // Apply animation\n if (this.animate) {\n this.animateProgress(progress, dashOffset);\n }\n }\n\n renderSegments(center, radius, circumference) {\n // Calculate arc length\n const arcLength = this.gap > 0 ? (360 - this.gap) : 360;\n const arcCircumference = (arcLength / 360) * circumference;\n\n // Create track\n const track = this.createCircle(center, radius, {\n stroke: this.trackColor,\n strokeWidth: this.strokeWidth,\n fill: 'none',\n strokeLinecap: this.rounded ? 'round' : 'butt',\n strokeDasharray: this.gap > 0 ? `${arcCircumference} ${circumference}` : 'none',\n transform: `rotate(${this.rotation} ${center} ${center})`\n });\n this.svg.appendChild(track);\n\n // Validate segments total\n const total = this.segments.reduce((sum, seg) => sum + (seg.value || 0), 0);\n if (total > this.max) {\n console.warn('CircularProgress: Segment total exceeds max value. Clamping to max.');\n }\n\n // Render each segment\n let currentOffset = 0;\n\n this.segments.forEach((segment, index) => {\n const segmentPercentage = ((segment.value || 0) / (this.max - this.min)) * 100;\n const segmentLength = (segmentPercentage / 100) * arcCircumference;\n\n // Gap between segments (in circumference units)\n const gapLength = (this.segmentGap / 360) * circumference;\n\n if (segmentLength > 0) {\n const segmentCircle = this.createCircle(center, radius, {\n stroke: segment.color || this.color,\n strokeWidth: this.strokeWidth,\n fill: 'none',\n strokeLinecap: this.rounded ? 'round' : 'butt',\n strokeDasharray: `${segmentLength} ${circumference}`,\n strokeDashoffset: this.animate ? arcCircumference : -(currentOffset),\n transform: `rotate(${this.rotation} ${center} ${center})`,\n class: `circular-progress-segment circular-progress-segment-${index}`,\n 'data-segment-index': index\n });\n\n this.svg.appendChild(segmentCircle);\n\n // Apply animation\n if (this.animate) {\n this.animateProgress(segmentCircle, -(currentOffset), index * 100);\n }\n\n // Update offset for next segment\n currentOffset += segmentLength + gapLength;\n }\n });\n }\n\n createCircle(cx, cy, attributes = {}) {\n const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n circle.setAttribute('cx', cx);\n circle.setAttribute('cy', cx); // Use cx for cy since we pass center for both\n circle.setAttribute('r', cy); // cy parameter is actually the radius\n\n Object.entries(attributes).forEach(([key, value]) => {\n if (key === 'strokeWidth') {\n circle.setAttribute('stroke-width', value);\n } else if (key === 'strokeLinecap') {\n circle.setAttribute('stroke-linecap', value);\n } else if (key === 'strokeDasharray') {\n circle.setAttribute('stroke-dasharray', value);\n } else if (key === 'strokeDashoffset') {\n circle.setAttribute('stroke-dashoffset', value);\n } else {\n circle.setAttribute(key, value);\n }\n });\n\n return circle;\n }\n\n createGradient() {\n const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');\n const gradient = document.createElementNS('http://www.w3.org/2000/svg', 'linearGradient');\n gradient.setAttribute('id', this.gradientId);\n gradient.setAttribute('x1', '0%');\n gradient.setAttribute('y1', '0%');\n gradient.setAttribute('x2', '100%');\n gradient.setAttribute('y2', '100%');\n\n this.gradientColors.forEach((color, index) => {\n const stop = document.createElementNS('http://www.w3.org/2000/svg', 'stop');\n const offset = (index / (this.gradientColors.length - 1)) * 100;\n stop.setAttribute('offset', `${offset}%`);\n stop.setAttribute('stop-color', color);\n gradient.appendChild(stop);\n });\n\n defs.appendChild(gradient);\n this.svg.appendChild(defs);\n }\n\n animateProgress(circle, targetOffset, delay = 0) {\n setTimeout(() => {\n circle.style.transition = `stroke-dashoffset ${this.animationDuration}ms ${this.animationEasing}`;\n circle.style.strokeDashoffset = targetOffset;\n }, delay);\n }\n\n renderCenterContent() {\n if (!this.centerElement) return;\n\n // Priority: labelHtml > icon > value/label\n if (this.labelHtml) {\n this.centerElement.innerHTML = this.labelHtml;\n } else if (this.icon) {\n this.centerElement.innerHTML = `<i class=\"${this.icon}\"></i>`;\n } else if (this.showValue) {\n const formattedValue = this.getFormattedValue();\n let html = `<div class=\"circular-progress-value\">${formattedValue}</div>`;\n \n if (this.label) {\n html += `<div class=\"circular-progress-label\">${this.label}</div>`;\n }\n\n this.centerElement.innerHTML = html;\n }\n }\n\n getFormattedValue() {\n const value = this.value;\n const min = this.min;\n const max = this.max;\n\n // Custom formatter function takes precedence\n if (this.valueFormatter && typeof this.valueFormatter === 'function') {\n return this.valueFormatter(value, min, max);\n }\n\n // Built-in formats\n switch (this.valueFormat) {\n case 'percentage':\n return `${Math.round(this.getPercentage())}%`;\n \n case 'fraction':\n return `${value}/${max}`;\n \n case 'value':\n return value.toString();\n \n default:\n // Try DataFormatter\n if (this.dataFormatter) {\n try {\n return this.dataFormatter.pipe(value, this.valueFormat);\n } catch (error) {\n console.warn('CircularProgress: DataFormatter error, falling back to percentage', error);\n return `${Math.round(this.getPercentage())}%`;\n }\n }\n return `${Math.round(this.getPercentage())}%`;\n }\n }\n\n getPercentage() {\n const range = this.max - this.min;\n if (range === 0) return 0;\n return ((this.value - this.min) / range) * 100;\n }\n\n setupClickHandler() {\n if (!this.containerElement) return;\n\n this.containerElement.style.cursor = 'pointer';\n \n this.containerElement.addEventListener('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n\n const percentage = this.getPercentage();\n \n this.emit('progress:clicked', {\n value: this.value,\n percentage,\n min: this.min,\n max: this.max\n });\n\n // Toggle popover if tooltip is configured\n if (this.tooltip) {\n this.togglePopover();\n }\n });\n }\n\n setupTooltip() {\n // Bootstrap popover will be initialized on first click\n // We'll create the popover content dynamically\n }\n\n togglePopover() {\n if (!this.containerElement || typeof window.bootstrap === 'undefined') {\n console.warn('CircularProgress: Bootstrap is required for tooltip support');\n return;\n }\n\n // Get or create popover instance\n if (!this.popover) {\n const content = this.getTooltipContent();\n const title = typeof this.tooltip === 'object' && this.tooltip.title ? this.tooltip.title : undefined;\n\n // Build config object, omitting title if undefined\n const popoverConfig = {\n content: content,\n html: true,\n placement: this.tooltipPlacement,\n trigger: 'manual',\n container: 'body'\n };\n \n // Only add title if it exists\n if (title) {\n popoverConfig.title = title;\n }\n\n this.popover = new window.bootstrap.Popover(this.containerElement, popoverConfig);\n }\n\n // Toggle visibility\n const popoverElement = window.bootstrap.Popover.getInstance(this.containerElement);\n if (popoverElement && this.containerElement.getAttribute('aria-describedby')) {\n this.popover.hide();\n } else {\n // Update content before showing\n this.popover.setContent({\n '.popover-body': this.getTooltipContent()\n });\n this.popover.show();\n }\n }\n\n getTooltipContent() {\n if (typeof this.tooltip === 'function') {\n return this.tooltip(this.value, {\n min: this.min,\n max: this.max,\n percentage: this.getPercentage()\n });\n }\n\n if (typeof this.tooltip === 'object') {\n return this.tooltip.html || this.tooltip.content || '';\n }\n\n return this.tooltip || '';\n }\n\n // Public API\n\n setValue(value, animate = true) {\n const oldValue = this.value;\n this.value = Math.max(this.min, Math.min(this.max, value));\n \n // Update center content\n this.renderCenterContent();\n \n // Update progress without full re-render\n if (this.svg && !this.segments) {\n const progressBar = this.svg.querySelector('.circular-progress-bar');\n if (progressBar) {\n const radius = (this.size / 2) - (this.strokeWidth / 2);\n const circumference = 2 * Math.PI * radius;\n const arcLength = this.gap > 0 ? (360 - this.gap) : 360;\n const arcCircumference = (arcLength / 360) * circumference;\n const percentage = this.getPercentage();\n const progressLength = (percentage / 100) * arcCircumference;\n const dashOffset = arcCircumference - progressLength;\n \n if (animate) {\n // Animate from current offset to new offset\n progressBar.style.transition = `stroke-dashoffset ${this.animationDuration}ms ${this.animationEasing}`;\n progressBar.style.strokeDashoffset = dashOffset;\n } else {\n // Update immediately without animation\n progressBar.style.transition = 'none';\n progressBar.style.strokeDashoffset = dashOffset;\n }\n }\n } else {\n // For segments or if no existing progress bar, do full re-render\n const oldAnimate = this.animate;\n this.animate = animate;\n this.renderProgress();\n this.animate = oldAnimate;\n }\n }\n\n setRange(min, max) {\n this.min = min;\n this.max = max;\n this.renderProgress();\n this.renderCenterContent();\n }\n\n increment(amount = 1) {\n this.setValue(this.value + amount);\n }\n\n decrement(amount = 1) {\n this.setValue(this.value - amount);\n }\n\n setColor(color) {\n this.color = color;\n this.gradientColors = null; // Clear gradient\n \n // Update color without full re-render\n if (this.svg && !this.segments) {\n const progressBar = this.svg.querySelector('.circular-progress-bar');\n if (progressBar) {\n progressBar.setAttribute('stroke', color);\n }\n } else {\n // For segments, need to re-render\n this.renderProgress();\n }\n }\n\n setGradient(colors) {\n if (Array.isArray(colors) && colors.length > 1) {\n this.gradientColors = colors;\n this.gradientId = `gradient-${Math.random().toString(36).substr(2, 9)}`;\n this.renderProgress();\n }\n }\n\n setSize(size) {\n // Remove old size class if it exists\n if (this.containerElement && this.sizePreset) {\n this.containerElement.classList.remove(`circular-progress-${this.sizePreset}`);\n }\n \n // Update size preset if the new size is a preset string\n this.sizePreset = (typeof size === 'string' && this.SIZE_PRESETS[size]) ? size : null;\n this.size = this.resolveSize(size);\n this.strokeWidth = this.getAutoStrokeWidth(size);\n \n // Add new size class if it's a preset\n if (this.containerElement) {\n this.containerElement.style.width = `${this.size}px`;\n this.containerElement.style.height = `${this.size}px`;\n \n if (this.sizePreset) {\n this.containerElement.classList.add(`circular-progress-${this.sizePreset}`);\n }\n }\n \n if (this.svg) {\n this.svg.setAttribute('width', this.size);\n this.svg.setAttribute('height', this.size);\n this.svg.setAttribute('viewBox', `0 0 ${this.size} ${this.size}`);\n }\n \n this.renderProgress();\n }\n\n animateTo(targetValue, duration = 1000) {\n const startValue = this.value;\n const diff = targetValue - startValue;\n const startTime = performance.now();\n\n const animate = (currentTime) => {\n const elapsed = currentTime - startTime;\n const progress = Math.min(elapsed / duration, 1);\n\n // Ease-out function\n const easeProgress = 1 - Math.pow(1 - progress, 3);\n \n const newValue = startValue + (diff * easeProgress);\n this.setValue(newValue, false);\n\n if (progress < 1) {\n requestAnimationFrame(animate);\n } else {\n this.setValue(targetValue, false);\n }\n };\n\n requestAnimationFrame(animate);\n }\n\n pulse() {\n if (!this.containerElement) return;\n\n this.containerElement.style.animation = 'none';\n setTimeout(() => {\n this.containerElement.style.animation = 'circular-progress-pulse 0.5s ease-out';\n }, 10);\n\n setTimeout(() => {\n this.containerElement.style.animation = '';\n }, 500);\n }\n\n complete() {\n this.variant = 'success';\n this.applyVariant();\n this.setValue(this.max);\n this.pulse();\n }\n\n reset() {\n this.setValue(this.min);\n }\n\n hide() {\n if (this.element) {\n this.element.style.display = 'none';\n }\n }\n\n show() {\n if (this.element) {\n this.element.style.display = '';\n }\n }\n\n getValue() {\n return this.value;\n }\n\n getPercentageValue() {\n return this.getPercentage();\n }\n\n async onBeforeDestroy() {\n // Clean up popover\n if (this.popover) {\n this.popover.dispose();\n this.popover = null;\n }\n\n await super.onBeforeDestroy();\n }\n}\n"],"names":["CircularProgress","View","constructor","options","super","className","this","SIZE_PRESETS","xs","sm","md","lg","xl","STROKE_PRESETS","value","min","max","sizePreset","size","resolveSize","strokeWidth","getAutoStrokeWidth","theme","variant","color","trackColor","textColor","gradientColors","applyTheme","applyVariant","rotation","gap","showValue","valueFormat","valueFormatter","label","labelHtml","icon","animate","animationDuration","animationEasing","rounded","shadow","clickable","tooltip","tooltipPlacement","segments","segmentGap","dataFormatter","svg","centerElement","popover","gradientId","Math","random","toString","substr","actualSize","themes","basic","backgroundColor","shadowed","dark","light","themeConfig","variants","success","danger","warning","info","default","variantColors","getTemplate","sizeClass","variantClass","themeClass","clickableClass","shadowClass","textColorStyle","onAfterRender","element","querySelector","containerElement","renderProgress","renderCenterContent","setupClickHandler","setupTooltip","innerHTML","center","radius","circumference","PI","length","createGradient","Array","isArray","renderSegments","renderSingleProgress","arcCircumference","track","createCircle","stroke","fill","strokeLinecap","strokeDasharray","transform","appendChild","dashOffset","getPercentage","strokeColor","progress","strokeDashoffset","class","animateProgress","reduce","sum","seg","console","warn","currentOffset","forEach","segment","index","segmentLength","gapLength","segmentCircle","cx","cy","attributes","circle","document","createElementNS","setAttribute","Object","entries","key","defs","gradient","stop","offset","targetOffset","delay","setTimeout","style","transition","html","getFormattedValue","round","pipe","error","range","cursor","addEventListener","e","preventDefault","stopPropagation","percentage","emit","togglePopover","window","bootstrap","content","getTooltipContent","title","popoverConfig","placement","trigger","container","Popover","getInstance","getAttribute","hide","setContent","show","setValue","progressBar","oldAnimate","setRange","increment","amount","decrement","setColor","setGradient","colors","setSize","classList","remove","width","height","add","animateTo","targetValue","duration","startValue","diff","startTime","performance","now","currentTime","elapsed","easeProgress","pow","newValue","requestAnimationFrame","pulse","animation","complete","reset","display","getValue","getPercentageValue","onBeforeDestroy","dispose"],"mappings":"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"}
|
package/dist/charts.css
CHANGED
|
@@ -1270,3 +1270,322 @@
|
|
|
1270
1270
|
background: rgba(255, 255, 255, 0.9);
|
|
1271
1271
|
color: #212529;
|
|
1272
1272
|
}
|
|
1273
|
+
|
|
1274
|
+
/* ==========================================================================
|
|
1275
|
+
Circular Progress Component
|
|
1276
|
+
========================================================================== */
|
|
1277
|
+
|
|
1278
|
+
/* Container */
|
|
1279
|
+
.circular-progress {
|
|
1280
|
+
display: inline-block;
|
|
1281
|
+
font-family: var(--bs-font-sans-serif, system-ui, sans-serif);
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
.circular-progress-container {
|
|
1285
|
+
position: relative;
|
|
1286
|
+
display: inline-flex;
|
|
1287
|
+
align-items: center;
|
|
1288
|
+
justify-content: center;
|
|
1289
|
+
transition: transform 0.15s ease;
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
.circular-progress-container:hover {
|
|
1293
|
+
transform: scale(1.02);
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
/* SVG */
|
|
1297
|
+
.circular-progress-svg {
|
|
1298
|
+
display: block;
|
|
1299
|
+
overflow: visible;
|
|
1300
|
+
margin: 0 auto;
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
.circular-progress-bar,
|
|
1304
|
+
.circular-progress-segment {
|
|
1305
|
+
transition: stroke-dashoffset 0.6s ease-out;
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
/* Center content overlay */
|
|
1309
|
+
.circular-progress-center {
|
|
1310
|
+
position: absolute;
|
|
1311
|
+
top: 0;
|
|
1312
|
+
left: 0;
|
|
1313
|
+
right: 0;
|
|
1314
|
+
bottom: 0;
|
|
1315
|
+
display: flex;
|
|
1316
|
+
align-items: center;
|
|
1317
|
+
justify-content: center;
|
|
1318
|
+
text-align: center;
|
|
1319
|
+
pointer-events: none;
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
.circular-progress-content {
|
|
1323
|
+
display: flex;
|
|
1324
|
+
flex-direction: column;
|
|
1325
|
+
align-items: center;
|
|
1326
|
+
justify-content: center;
|
|
1327
|
+
gap: 0.125rem;
|
|
1328
|
+
max-width: 70%;
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
/* Value display */
|
|
1332
|
+
.circular-progress-value {
|
|
1333
|
+
font-size: 1.25rem;
|
|
1334
|
+
font-weight: 700;
|
|
1335
|
+
line-height: 1;
|
|
1336
|
+
color: var(--chart-text, #212529);
|
|
1337
|
+
white-space: nowrap;
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
.circular-progress-label {
|
|
1341
|
+
font-size: 0.625rem;
|
|
1342
|
+
font-weight: 500;
|
|
1343
|
+
line-height: 1.2;
|
|
1344
|
+
color: var(--chart-text-muted, #6c757d);
|
|
1345
|
+
text-transform: uppercase;
|
|
1346
|
+
letter-spacing: 0.025em;
|
|
1347
|
+
white-space: nowrap;
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1350
|
+
/* Icon display */
|
|
1351
|
+
.circular-progress-content i {
|
|
1352
|
+
font-size: 1.5rem;
|
|
1353
|
+
color: var(--chart-text, #212529);
|
|
1354
|
+
line-height: 1;
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
/* Size variants */
|
|
1358
|
+
.circular-progress-container.circular-progress-xs .circular-progress-value {
|
|
1359
|
+
font-size: 0.625rem;
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
.circular-progress-container.circular-progress-xs .circular-progress-label {
|
|
1363
|
+
font-size: 0.4rem;
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
.circular-progress-container.circular-progress-xs .circular-progress-content i {
|
|
1367
|
+
font-size: 0.75rem;
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1370
|
+
.circular-progress-container.circular-progress-sm .circular-progress-value {
|
|
1371
|
+
font-size: 0.875rem;
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1374
|
+
.circular-progress-container.circular-progress-sm .circular-progress-label {
|
|
1375
|
+
font-size: 0.5rem;
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
.circular-progress-container.circular-progress-sm .circular-progress-content i {
|
|
1379
|
+
font-size: 1rem;
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
.circular-progress-container.circular-progress-md .circular-progress-value {
|
|
1383
|
+
font-size: 1.125rem;
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
.circular-progress-container.circular-progress-md .circular-progress-label {
|
|
1387
|
+
font-size: 0.5625rem;
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
.circular-progress-container.circular-progress-md .circular-progress-content i {
|
|
1391
|
+
font-size: 1.25rem;
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
.circular-progress-container.circular-progress-lg .circular-progress-value {
|
|
1395
|
+
font-size: 1.5rem;
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
.circular-progress-container.circular-progress-lg .circular-progress-label {
|
|
1399
|
+
font-size: 0.6875rem;
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1402
|
+
.circular-progress-container.circular-progress-lg .circular-progress-content i {
|
|
1403
|
+
font-size: 1.75rem;
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
.circular-progress-container.circular-progress-xl .circular-progress-value {
|
|
1407
|
+
font-size: 2.25rem;
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
.circular-progress-container.circular-progress-xl .circular-progress-label {
|
|
1411
|
+
font-size: 0.8125rem;
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
.circular-progress-container.circular-progress-xl .circular-progress-content i {
|
|
1415
|
+
font-size: 2.5rem;
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
/* Variant colors */
|
|
1419
|
+
.circular-progress-container.circular-progress-success .circular-progress-value {
|
|
1420
|
+
color: #198754;
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1423
|
+
.circular-progress-container.circular-progress-success .circular-progress-content i {
|
|
1424
|
+
color: #198754;
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1427
|
+
.circular-progress-container.circular-progress-danger .circular-progress-value {
|
|
1428
|
+
color: #dc3545;
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
.circular-progress-container.circular-progress-danger .circular-progress-content i {
|
|
1432
|
+
color: #dc3545;
|
|
1433
|
+
}
|
|
1434
|
+
|
|
1435
|
+
.circular-progress-container.circular-progress-warning .circular-progress-value {
|
|
1436
|
+
color: #ffc107;
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1439
|
+
.circular-progress-container.circular-progress-warning .circular-progress-content i {
|
|
1440
|
+
color: #ffc107;
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
.circular-progress-container.circular-progress-info .circular-progress-value {
|
|
1444
|
+
color: #0dcaf0;
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
.circular-progress-container.circular-progress-info .circular-progress-content i {
|
|
1448
|
+
color: #0dcaf0;
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
/* Clickable state */
|
|
1452
|
+
.circular-progress-clickable .circular-progress-container {
|
|
1453
|
+
cursor: pointer;
|
|
1454
|
+
transition:
|
|
1455
|
+
transform 0.15s ease,
|
|
1456
|
+
filter 0.15s ease;
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
.circular-progress-clickable .circular-progress-container:hover {
|
|
1460
|
+
transform: scale(1.05);
|
|
1461
|
+
filter: brightness(1.1);
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
.circular-progress-clickable .circular-progress-container:active {
|
|
1465
|
+
transform: scale(0.98);
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
/* Shadow variant */
|
|
1469
|
+
.circular-progress-shadow .circular-progress-container {
|
|
1470
|
+
filter: drop-shadow(0 0.25rem 0.5rem rgba(0, 0, 0, 0.15));
|
|
1471
|
+
}
|
|
1472
|
+
|
|
1473
|
+
/* Theme: Shadowed */
|
|
1474
|
+
.circular-progress-theme-shadowed .circular-progress-svg {
|
|
1475
|
+
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.1));
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1478
|
+
.circular-progress-theme-shadowed circle[class*="progress"] {
|
|
1479
|
+
filter: drop-shadow(0 3px 6px rgba(0, 0, 0, 0.2)) drop-shadow(0 1px 3px rgba(0, 0, 0, 0.3));
|
|
1480
|
+
}
|
|
1481
|
+
|
|
1482
|
+
.circular-progress-theme-shadowed .circular-progress-svg circle:not([class]) {
|
|
1483
|
+
/* Track circle - shadow effect */
|
|
1484
|
+
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.1));
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1487
|
+
/* Theme: Dark */
|
|
1488
|
+
.circular-progress-theme-dark {
|
|
1489
|
+
background: #1f2937;
|
|
1490
|
+
border-radius: 0.5rem;
|
|
1491
|
+
padding: 1rem;
|
|
1492
|
+
}
|
|
1493
|
+
|
|
1494
|
+
.circular-progress-theme-dark .circular-progress-value,
|
|
1495
|
+
.circular-progress-theme-dark .circular-progress-label {
|
|
1496
|
+
color: #e5e7eb;
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
/* Theme: Light */
|
|
1500
|
+
.circular-progress-theme-light {
|
|
1501
|
+
background: #ffffff;
|
|
1502
|
+
border-radius: 0.5rem;
|
|
1503
|
+
padding: 1rem;
|
|
1504
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
.circular-progress-theme-light .circular-progress-value,
|
|
1508
|
+
.circular-progress-theme-light .circular-progress-label {
|
|
1509
|
+
color: #111827;
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
/* Pulse animation */
|
|
1513
|
+
@keyframes circular-progress-pulse {
|
|
1514
|
+
0% {
|
|
1515
|
+
transform: scale(1);
|
|
1516
|
+
}
|
|
1517
|
+
50% {
|
|
1518
|
+
transform: scale(1.1);
|
|
1519
|
+
}
|
|
1520
|
+
100% {
|
|
1521
|
+
transform: scale(1);
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1524
|
+
|
|
1525
|
+
/* Dark theme adjustments */
|
|
1526
|
+
[data-theme="dark"] .circular-progress-value {
|
|
1527
|
+
color: var(--chart-text, #ffffff);
|
|
1528
|
+
}
|
|
1529
|
+
|
|
1530
|
+
[data-theme="dark"] .circular-progress-label {
|
|
1531
|
+
color: var(--chart-text-muted, #adb5bd);
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
[data-theme="dark"] .circular-progress-content i {
|
|
1535
|
+
color: var(--chart-text, #ffffff);
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
[data-theme="dark"] .circular-progress-success .circular-progress-value,
|
|
1539
|
+
[data-theme="dark"] .circular-progress-success .circular-progress-content i {
|
|
1540
|
+
color: #75b798;
|
|
1541
|
+
}
|
|
1542
|
+
|
|
1543
|
+
[data-theme="dark"] .circular-progress-danger .circular-progress-value,
|
|
1544
|
+
[data-theme="dark"] .circular-progress-danger .circular-progress-content i {
|
|
1545
|
+
color: #ea868f;
|
|
1546
|
+
}
|
|
1547
|
+
|
|
1548
|
+
[data-theme="dark"] .circular-progress-warning .circular-progress-value,
|
|
1549
|
+
[data-theme="dark"] .circular-progress-warning .circular-progress-content i {
|
|
1550
|
+
color: #ffda6a;
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1553
|
+
[data-theme="dark"] .circular-progress-info .circular-progress-value,
|
|
1554
|
+
[data-theme="dark"] .circular-progress-info .circular-progress-content i {
|
|
1555
|
+
color: #6edff6;
|
|
1556
|
+
}
|
|
1557
|
+
|
|
1558
|
+
/* Accessibility */
|
|
1559
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1560
|
+
.circular-progress-bar,
|
|
1561
|
+
.circular-progress-segment,
|
|
1562
|
+
.circular-progress-container {
|
|
1563
|
+
transition: none !important;
|
|
1564
|
+
animation: none !important;
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1568
|
+
/* High contrast mode */
|
|
1569
|
+
@media (prefers-contrast: high) {
|
|
1570
|
+
.circular-progress-container {
|
|
1571
|
+
outline: 2px solid currentColor;
|
|
1572
|
+
outline-offset: 2px;
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
/* Focus styles for accessibility */
|
|
1577
|
+
.circular-progress-clickable .circular-progress-container:focus {
|
|
1578
|
+
outline: 2px solid var(--bs-primary, #0d6efd);
|
|
1579
|
+
outline-offset: 2px;
|
|
1580
|
+
}
|
|
1581
|
+
|
|
1582
|
+
/* Print styles */
|
|
1583
|
+
@media print {
|
|
1584
|
+
.circular-progress-container {
|
|
1585
|
+
break-inside: avoid;
|
|
1586
|
+
}
|
|
1587
|
+
|
|
1588
|
+
.circular-progress-clickable .circular-progress-container {
|
|
1589
|
+
cursor: default;
|
|
1590
|
+
}
|
|
1591
|
+
}
|