@voilajsx/uikit
Version:
Cross-platform React components with beautiful themes and OKLCH color sciences - Now with mobile (Capacitor) support
155 lines (154 loc) • 4.84 kB
JavaScript
import { jsx as L } from "react/jsx-runtime";
import { createContext as $, useState as S, useEffect as h, useContext as E } from "react";
const x = {
AdminLayout: "subtle",
// Professional admin interfaces
PageLayout: "clean",
// Clean public websites
AuthLayout: "clean",
// Focused authentication
PopupLayout: "clean",
// Clean extensions
BlankLayout: "clean",
// Simple pages
Header: "clean",
// Clean headers
Footer: "contrast",
// Bold footers
AdminSidebar: "subtle",
// Subtle sidebars
AdminHeader: "clean",
// Clean admin headers
PopupHeader: "brand"
// Branded popup headers
}, A = {
clean: "bg-background text-foreground border-border",
subtle: "bg-muted/30 text-foreground border-border/50",
brand: "bg-primary text-primary-foreground border-primary/20",
contrast: "bg-foreground text-background border-foreground/20"
// Automatically flips with mode
}, P = [
"base",
// Sky blue theme - clean & professional (DEFAULT)
"elegant",
// Minimal blue - clean & professional
"metro",
// Dark teal - admin dashboards
"studio",
// Designer grays - creative tools
"vivid"
// Premium cursive - luxury/creative portfolios
], g = $(void 0);
function T(t, n, a, m = !1, s = "uikit-theme") {
if (typeof window > "u")
return { theme: t, mode: n };
if (m)
return console.log(`🎨 Config priority: ${t} (${n} mode)`), { theme: t, mode: n };
if (s === null) {
if (a) {
const o = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
return console.log(`🎨 System preference (no storage): ${t} (${o} mode)`), { theme: t, mode: o };
}
return console.log(`🎨 Props only (no storage): ${t} (${n} mode)`), { theme: t, mode: n };
}
try {
const r = localStorage.getItem(s);
if (r) {
const o = JSON.parse(r);
if (o.theme && typeof o.theme == "string" && ["light", "dark"].includes(o.mode))
return console.log(`🎨 Restored from storage: ${o.theme} (${o.mode} mode)`), o;
}
if (a) {
const i = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
return console.log(`🎨 System preference: ${t} (${i} mode)`), { theme: t, mode: i };
}
return console.log(`🎨 Props fallback: ${t} (${n} mode)`), { theme: t, mode: n };
} catch (r) {
return console.warn("Failed to load theme preferences, using defaults:", r), { theme: t, mode: n };
}
}
function u(t, n) {
if (typeof window > "u") return;
const a = document.documentElement;
a.classList.remove("light", "dark"), Array.from(a.classList).filter(
(s) => s.startsWith("theme-")
).forEach((s) => {
a.classList.remove(s);
}), a.classList.add(n), a.classList.add(`theme-${t}`);
}
function F({
children: t,
theme: n = "base",
mode: a = "light",
detectSystem: m = !0,
forceConfig: s = !1,
// 🔧 NEW: Force config over storage
storageKey: r = "uikit-theme"
// 🔧 NEW: Configurable storage key
}) {
const [o, i] = S(() => {
const e = T(n, a, m, s, r);
return u(e.theme, e.mode), e;
});
h(() => {
if (typeof window > "u") return;
const { theme: e, mode: c } = o;
if (u(e, c), r && !s)
try {
localStorage.setItem(r, JSON.stringify({ theme: e, mode: c }));
} catch (d) {
console.warn("Failed to save theme preferences:", d);
}
console.log(`🎨 Applied theme: ${e} (${c} mode)`);
}, [o, r, s]), h(() => {
if (!m || typeof window > "u") return;
const e = window.matchMedia("(prefers-color-scheme: dark)"), c = (d) => {
if (!s)
try {
(r ? localStorage.getItem(r) : null) || i((y) => ({
...y,
mode: d.matches ? "dark" : "light"
}));
} catch (l) {
console.warn("Failed to handle system preference change:", l);
}
};
return e.addEventListener("change", c), () => e.removeEventListener("change", c);
}, [m, s, r]);
const p = (e) => {
i((c) => ({ ...c, theme: e }));
}, f = (e) => {
if (e !== "light" && e !== "dark") {
console.warn(`Invalid mode: ${e}. Expected 'light' or 'dark'.`);
return;
}
i((c) => ({ ...c, mode: e }));
}, b = () => {
i((e) => ({
...e,
mode: e.mode === "light" ? "dark" : "light"
}));
}, k = (e) => A[e], v = (e) => x[e] || "clean", w = {
theme: o.theme,
mode: o.mode,
availableThemes: P,
setTheme: p,
setMode: f,
toggleMode: b,
getToneClasses: k,
getDefaultTone: v
};
return /* @__PURE__ */ L(g.Provider, { value: w, children: t });
}
function H() {
const t = E(g);
if (!t)
throw new Error("useTheme must be used within a ThemeProvider");
return t;
}
export {
P as AVAILABLE_THEMES,
F as ThemeProvider,
H as useTheme
};
//# sourceMappingURL=theme-provider.js.map