@awal-solution/tailwind-theming
Version:
<div align="left"> <h1>Tailwind theming</h1> <p>The <b>TailwindCSS Multi-Theming Plugin</b> is a utility for creating and managing multiple themes in your TailwindCSS-based projects. With this library, you can define, add, update, and remove themes dyn
174 lines (173 loc) • 5.2 kB
JavaScript
var u = Object.defineProperty;
var T = (d, e, s) => e in d ? u(d, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : d[e] = s;
var o = (d, e, s) => T(d, typeof e != "symbol" ? e + "" : e, s);
class x {
constructor() {
o(this, "default");
o(this, "themes");
this.default = "light-theme", this.themes = {
defaultTheme: {
name: "light-theme",
extend: { colors: { background: "#FFFFFF" } }
}
};
}
deepMerge(e, s) {
if (typeof e != "object" || e === null)
return s;
if (typeof s != "object" || s === null)
return e;
const t = Array.isArray(e) ? [...e] : { ...e };
for (const i of Object.keys(s)) {
const h = s[i], n = e[i];
h && typeof h == "object" && !Array.isArray(h) ? t[i] = this.deepMerge(n, h) : t[i] = h;
}
return t;
}
/**
* Validate theme name.
* @param themeName - The theme name to validate
*/
validateThemeName(e) {
if (!e.match(/theme$/i))
throw new Error(`Object keys must contain theme suffix example: "${e}-theme" or "${e}Theme"`);
}
/**
* Find a theme by name.
* @param themeName - The theme name to find
*/
find(e) {
var i, h;
const s = this.default === e && ((i = this.themes.defaultTheme) == null ? void 0 : i.name) === e ? this.themes.defaultTheme : null, t = (h = this.themes.themes) == null ? void 0 : h.find((n) => n.name === e);
return s || t || null;
}
/**
* Set default theme.
* @param themeName - The theme name to set new default theme
*/
init({ themes: e = {}, defaultTheme: s, utilities: t }) {
const i = [];
Object.entries(e).reduce(
(m, [r, l]) => {
this.validateThemeName(r);
const c = {
name: r,
extend: l
};
return i.push(c), m[r] = l, m;
},
{}
);
const n = [...this.themes.themes ?? [], ...i];
this.default = s || this.default;
const a = n.find((m) => m.name === this.default) ?? n[0], f = n.filter((m) => m.name !== this.default).map((m) => ({
...m,
selectors: [`[data-theme="${m.name}"]`]
}));
this.themes = {
defaultTheme: a,
themes: f,
utilities: this.deepMerge(this.themes.utilities, t || {})
};
}
/**
* Set default theme.
* @param themeName - The theme name to set new default theme
*/
defaultTheme(e) {
var n;
this.validateThemeName(e);
const s = this.find(e);
if (!s) throw new Error(`Theme "${e}" does not exists.`);
if (this.default === s.name) return;
this.default = e;
const t = this.themes.defaultTheme, i = ((n = this.themes.themes) == null ? void 0 : n.filter((a) => a.name !== e)) ?? [];
i.push({
name: (t == null ? void 0 : t.name) ?? "",
selectors: [`[data-theme="${t == null ? void 0 : t.name}"]`],
extend: (t == null ? void 0 : t.extend) ?? {}
});
const h = {
defaultTheme: { extend: s.extend, name: s.name },
themes: i
};
this.themes = {
...h,
utilities: this.themes.utilities
};
}
/**
* Set default theme.
* @param utilities - utilities classes for tailwind css it will merge previous and new classes
*/
addUtilities(e) {
this.themes.utilities = { ...this.themes.utilities, ...e };
}
/**
* Get available themes with their names and selectors.
* @returns An object of available themes
*/
getThemeSelectors() {
var s;
const e = {};
return e.default = { name: this.default ?? "" }, (s = this.themes.themes) == null || s.forEach((t) => {
e[t.name] = { name: t.name, selectors: t.selectors };
}), e;
}
/**
* Add a new theme.
* @param theme - The theme to add
*/
add(e) {
var i;
if (this.validateThemeName(e.name), this.find(e.name)) throw new Error(`Theme "${e.name}" already exists.`);
const t = {
name: e.name,
selectors: [`[data-theme="${e.name}"]`],
extend: { ...e.theme }
};
(i = this.themes.themes) == null || i.push(t);
}
/**
* Update an existing theme.
* @param themeName - The name of the theme to update
* @param properties - The properties to update
*/
update(e, s) {
var h;
this.validateThemeName(e);
const t = this.find(e);
if (!t) throw new Error(`Theme "${e}" does not exists.`);
const i = {
...t,
extend: this.deepMerge(t.extend ?? {}, s)
};
if (e === this.default)
this.themes.defaultTheme = i;
else {
const n = ((h = this.themes.themes) == null ? void 0 : h.filter((a) => a.name !== e)) ?? [];
this.themes.themes = [...n, i];
}
}
/**
* Remove a theme by name.
* @param themeName - The name of the theme to remove
*/
remove(e) {
var t, i;
const s = (t = this.themes.themes) == null ? void 0 : t.findIndex((h) => h.name === e);
if (s === void 0 || s === -1) throw new Error(`Theme "${e}" does not exist.`);
(i = this.themes.themes) == null || i.splice(s, 1);
}
/**
* Get all available themes.
* @returns MultiThemePluginOptions containing the default theme and additional themes.
*/
get() {
return this.themes;
}
}
const w = new x();
export {
w as themeManager
};