Files

154 lines
4.6 KiB
JavaScript

(function () {
const KEY = "theme";
const STYLE_ID = "wespKioskThemeStyles";
const TOGGLE_ID = "wespThemeToggleWrap";
function savedTheme() {
const t = (localStorage.getItem(KEY) || "").trim().toLowerCase();
return t === "light" ? "light" : "dark";
}
function applyTheme(theme) {
const next = theme === "dark" ? "dark" : "light";
document.documentElement.setAttribute("data-theme", next);
localStorage.setItem(KEY, next);
}
function injectModalChromeStyles() {
const id = "wespKioskModalsCss";
if (document.getElementById(id)) return;
const link = document.createElement("link");
link.id = id;
link.rel = "stylesheet";
link.href = "/static/css/kiosk-modals.css";
document.head.appendChild(link);
}
function ensureModalStyles() {
injectModalChromeStyles();
}
function injectStyles() {
if (document.getElementById(STYLE_ID)) return;
const style = document.createElement("style");
style.id = STYLE_ID;
style.textContent = `
[data-theme="dark"] body {
background: #1a1a1a !important;
color: #e6e6e6 !important;
}
[data-theme="dark"] .card,
[data-theme="dark"] .data-container,
[data-theme="dark"] .admin-panel,
[data-theme="dark"] .modal-content,
[data-theme="dark"] .modal,
[data-theme="dark"] .stat-card,
[data-theme="dark"] .table-section,
[data-theme="dark"] .loading-content,
[data-theme="dark"] .error-modal {
background: #242424 !important;
color: #f0f0f0 !important;
border-color: #3a3a3a !important;
}
[data-theme="dark"] .subtitle,
[data-theme="dark"] .meta,
[data-theme="dark"] .stat-label,
[data-theme="dark"] .text-muted {
color: #bdbdbd !important;
}
[data-theme="dark"] .btn,
[data-theme="dark"] .control-button,
[data-theme="dark"] .numpad-btn {
color: #fff !important;
}
[data-theme="dark"] pre {
background: #181818 !important;
color: #dcdcdc !important;
border: 1px solid #353535 !important;
}
#${TOGGLE_ID} {
position: fixed;
bottom: 12px;
right: 16px;
z-index: 4249;
display: inline-flex;
align-items: center;
user-select: none;
background: transparent;
border: none;
padding: 0;
}
#${TOGGLE_ID} input {
--s: 40px;
height: var(--s);
aspect-ratio: 2.5;
width: auto;
border-radius: var(--s);
padding: calc(var(--s) / 10);
margin: 0;
cursor: pointer;
background:
radial-gradient(farthest-side, #15202a 96%, #0000)
var(--_p, 0%) / var(--s) content-box no-repeat,
var(--_c, #ff7a7a);
box-sizing: content-box;
transform-origin: calc(3 * var(--s) / 5) 50%;
transition:
transform cubic-bezier(0, 300, 1, 300) .5s,
background .3s .1s ease-in;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
border: 1px solid rgba(255, 255, 255, 0.18);
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
}
#${TOGGLE_ID} input:checked {
--_c: #85ff7a;
--_p: 100%;
transform-origin: calc(100% - 3 * var(--s) / 5) 50%;
transform: rotate(0.1deg);
}
@media (max-width: 768px) {
#${TOGGLE_ID} {
bottom: 12px;
right: 12px;
transform: scale(0.9);
transform-origin: bottom right;
}
}
`;
document.head.appendChild(style);
}
function ensureToggle() {
let wrap = document.getElementById(TOGGLE_ID);
if (wrap) return wrap;
wrap = document.createElement("button");
wrap.id = TOGGLE_ID;
wrap.type = "button";
wrap.innerHTML = `<input id="wespThemeSwitch" type="checkbox" aria-label="Тёмная тема" title="Выключено — светлая тема. Включено — тёмная.">`;
const input = wrap.querySelector("#wespThemeSwitch");
input.addEventListener("change", function () {
const next = input.checked ? "dark" : "light";
applyTheme(next);
});
document.body.appendChild(wrap);
return wrap;
}
function setup(opts) {
const options = opts || {};
const theme = savedTheme();
injectModalChromeStyles();
injectStyles();
applyTheme(theme);
if (options.withToggle !== false) {
const t = ensureToggle();
const input = t.querySelector("#wespThemeSwitch");
if (input) input.checked = theme === "dark";
}
}
window.WespKioskTheme = { setup, applyTheme, ensureModalStyles };
})();