UNPKG

flex-theme

Version:

A flexible theming system for web applications

134 lines (132 loc) 4.16 kB
var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/theme.ts var theme_exports = {}; __export(theme_exports, { ThemeProvider: () => ThemeProvider, getResolvedTheme: () => getResolvedTheme, getTheme: () => getTheme, offThemeChange: () => offThemeChange, onThemeChange: () => onThemeChange, setTheme: () => setTheme, toggleTheme: () => toggleTheme }); module.exports = __toCommonJS(theme_exports); var currentTheme = "system"; var listeners = []; function safeMatchMedia(query) { if (typeof window === "undefined") return false; if (typeof window.matchMedia !== "function") return false; return window.matchMedia(query).matches; } function initTheme() { if (typeof window === "undefined") return; const savedTheme = localStorage.getItem("theme"); if (savedTheme && ["light", "dark", "system"].includes(savedTheme)) { currentTheme = savedTheme; } else { currentTheme = "system"; } applyTheme(); } function applyTheme() { if (typeof window === "undefined" || !document) return; let effectiveTheme = currentTheme; if (effectiveTheme === "system") { effectiveTheme = safeMatchMedia("(prefers-color-scheme: dark)") ? "dark" : "light"; } if (effectiveTheme === "dark") { document.documentElement.classList.add("dark"); document.documentElement.classList.remove("light"); } else { document.documentElement.classList.add("light"); document.documentElement.classList.remove("dark"); } if (typeof localStorage !== "undefined") { localStorage.setItem("theme", currentTheme); } } function getTheme() { return currentTheme; } function getResolvedTheme() { if (currentTheme === "system") { return safeMatchMedia("(prefers-color-scheme: dark)") ? "dark" : "light"; } return currentTheme; } function setTheme(theme) { if (!["light", "dark", "system"].includes(theme)) { console.error(`Invalid theme: ${theme}. Must be 'light', 'dark', or 'system'`); return; } currentTheme = theme; applyTheme(); listeners.forEach((listener) => listener(theme)); } function toggleTheme() { const newTheme = currentTheme === "light" ? "dark" : "light"; setTheme(newTheme); } function onThemeChange(listener) { listeners.push(listener); } function offThemeChange(listener) { const index = listeners.indexOf(listener); if (index !== -1) { listeners.splice(index, 1); } } if (typeof window !== "undefined") { initTheme(); if (typeof window.matchMedia === "function") { try { const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); if (mediaQuery.addEventListener) { mediaQuery.addEventListener("change", () => { if (currentTheme === "system") { applyTheme(); listeners.forEach((listener) => listener(currentTheme)); } }); } else if (mediaQuery.addListener) { mediaQuery.addListener(() => { if (currentTheme === "system") { applyTheme(); listeners.forEach((listener) => listener(currentTheme)); } }); } } catch (e) { console.error("Error setting up media query listener:", e); } } } var ThemeProvider = ({ children }) => { return children; }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { ThemeProvider, getResolvedTheme, getTheme, offThemeChange, onThemeChange, setTheme, toggleTheme });