@buildy-ui/theme
Version:
React theme state management library for utility and semantic CSS approaches
189 lines (184 loc) • 4.56 kB
JavaScript
// src/constants.ts
var THEME_TYPES = {
SEMANTIC: "semantic",
UI8KIT: "ui8kit"
};
var DEFAULT_THEME = THEME_TYPES.UI8KIT;
var STORAGE_KEYS = {
THEME: "app-theme"
};
var LOCAL_STORAGE_KEY = STORAGE_KEYS.THEME;
// src/current.ts
var currentTheme = DEFAULT_THEME;
function getTheme() {
return currentTheme;
}
function setTheme(theme) {
if (Object.values(THEME_TYPES).includes(theme)) {
currentTheme = theme;
} else {
console.warn(`Invalid theme: ${theme}. Using default: ${DEFAULT_THEME}`);
currentTheme = DEFAULT_THEME;
}
}
// src/utils.ts
var getStoredTheme = () => {
if (typeof window === "undefined") {
return null;
}
try {
const storedTheme = localStorage.getItem(LOCAL_STORAGE_KEY);
if (storedTheme && Object.values(THEME_TYPES).includes(storedTheme)) {
return storedTheme;
}
return null;
} catch (error) {
console.error("Failed to get theme from localStorage:", error);
return null;
}
};
var storeTheme = (theme) => {
if (typeof window === "undefined") {
return;
}
try {
localStorage.setItem(LOCAL_STORAGE_KEY, theme);
} catch (error) {
console.error("Failed to store theme in localStorage:", error);
}
};
var getThemeFromUrl = () => {
if (typeof window === "undefined") {
return null;
}
try {
const url = new URL(window.location.href);
const themeParam = url.searchParams.get("theme");
if (themeParam && Object.values(THEME_TYPES).includes(themeParam)) {
return themeParam;
}
return null;
} catch (error) {
console.error("Failed to get theme from URL:", error);
return null;
}
};
var removeThemeParamFromUrl = () => {
if (typeof window === "undefined") {
return;
}
try {
const url = new URL(window.location.href);
if (url.searchParams.has("theme")) {
url.searchParams.delete("theme");
window.history.replaceState({}, "", url.toString());
}
} catch (error) {
console.error("Failed to remove theme param from URL:", error);
}
};
var getInitialTheme = () => {
const urlTheme = getThemeFromUrl();
if (urlTheme) {
storeTheme(urlTheme);
removeThemeParamFromUrl();
return urlTheme;
}
const storedTheme = getStoredTheme();
if (storedTheme) {
return storedTheme;
}
return DEFAULT_THEME;
};
var toggleTheme = (currentTheme2) => {
return currentTheme2 === THEME_TYPES.SEMANTIC ? THEME_TYPES.UI8KIT : THEME_TYPES.SEMANTIC;
};
// src/context.tsx
import { createContext, useContext, useEffect, useReducer } from "react";
// src/reducer.ts
var initialThemeState = {
current: DEFAULT_THEME,
isLoading: false
};
function themeReducer(state, action) {
switch (action.type) {
case "SET_THEME":
return {
...state,
current: action.payload
};
case "TOGGLE_THEME":
return {
...state,
current: toggleTheme(state.current)
};
case "SET_LOADING":
return {
...state,
isLoading: action.payload
};
default:
return state;
}
}
// src/context.tsx
import { jsx } from "react/jsx-runtime";
var ThemeContext = createContext(void 0);
var ThemeProvider = ({
children,
initialTheme
}) => {
const [state, dispatch] = useReducer(themeReducer, {
...initialThemeState,
current: initialTheme || (typeof window !== "undefined" ? getInitialTheme() : initialThemeState.current)
});
const setTheme2 = (theme) => {
dispatch({ type: "SET_THEME", payload: theme });
};
const handleToggleTheme = () => {
dispatch({ type: "TOGGLE_THEME" });
};
useEffect(() => {
storeTheme(state.current);
}, [state.current]);
useEffect(() => {
if (typeof window !== "undefined" && !initialTheme) {
const clientInitialTheme = getInitialTheme();
if (clientInitialTheme !== state.current) {
setTheme2(clientInitialTheme);
}
}
}, []);
const value = {
...state,
setTheme: setTheme2,
toggleTheme: handleToggleTheme
};
return /* @__PURE__ */ jsx(ThemeContext.Provider, { value, children });
};
var useTheme = () => {
const context = useContext(ThemeContext);
if (context === void 0) {
throw new Error("useTheme must be used within a ThemeProvider");
}
return context;
};
export {
DEFAULT_THEME,
LOCAL_STORAGE_KEY,
STORAGE_KEYS,
THEME_TYPES,
ThemeProvider,
getInitialTheme,
getStoredTheme,
getTheme,
getThemeFromUrl,
initialThemeState,
removeThemeParamFromUrl,
setTheme,
storeTheme,
themeReducer,
toggleTheme,
useTheme
};
//# sourceMappingURL=index.js.map