UNPKG

theme-o-rama

Version:

A TypeScript library for dynamic theme management in react + shadcn + tailwind applications

70 lines (69 loc) 2.62 kB
import { ThemeCache } from "./theme-cache.js"; import { validateTheme } from "./theme-schema-validation.js"; import { deepMerge } from "./utils.js"; export class ThemeLoader { constructor() { this.themesCache = new ThemeCache(); } clearCache() { this.themesCache.invalidate(); } getTheme(themeName) { return this.themesCache.getThemeSafe(themeName); } getThemes() { return this.themesCache.getThemes(); } async loadThemes(themes, imageResolver = null) { await Promise.all(themes.map((theme) => this.loadTheme(theme, imageResolver))); } async loadTheme(theme, imageResolver = null) { try { // Create a deep copy of the theme to avoid readonly issues const workingTheme = await this.initializeTheme(JSON.parse(JSON.stringify(theme)), imageResolver); this.themesCache.addTheme(workingTheme); } catch (error) { console.error(`Error loading theme`, error); } } async loadThemeFromJson(themeJson, imageResolver = null) { const theme = validateTheme(themeJson); const initializeTheme = await this.initializeTheme(theme, imageResolver); this.themesCache.addTheme(initializeTheme); return initializeTheme; } async initializeTheme(theme, imageResolver = null) { try { if (theme.inherits) { const inheritedTheme = this.themesCache.getThemeSafe(theme.inherits); const tags = theme.tags || []; theme = deepMerge(inheritedTheme, theme); theme.tags = tags; } if (theme.backgroundImage && imageResolver) { try { // we allow remote urls and local files for built in themes // local images get imported from the theme's folder if (urlRequiresResolution(theme.backgroundImage)) { theme.backgroundImage = await imageResolver(theme.name, theme.backgroundImage); } } catch (error) { console.warn(`Error loading background image for theme ${theme.name}:`, error); theme.backgroundImage = undefined; } } } catch (error) { console.error(`Error loading theme`, error); } return theme; } } function urlRequiresResolution(url) { return !!(url && !url.startsWith("http://") && !url.startsWith("https://") && !url.startsWith("data:")); }