UNPKG

@tenoxui/browser

Version:

A JavaScript library for creating highly customized, flexible, and extensible utility-first CSS framework

203 lines (202 loc) 6.36 kB
import { TenoxUI as T } from "tenoxui"; import { TenoxUI as g } from "@tenoxui/moxie"; function x(l) { return l.replace(/\\3(\d) /g, "$1").replace(/\\([#{}.:;?%&,@+*~'"!^$[\]()=>|/])/g, "$1"); } class w extends T { constructor({ // tenoxui configuration moxie: s = g, tabSize: e = 2, values: t = {}, classes: i = {}, aliases: r = {}, property: n = {}, variants: a = {}, safelist: o = [], typeOrder: h = [], breakpoints: c = {}, moxieOptions: d = {}, selectorPrefix: u = "", prefixLoaderOptions: p = {}, reservedVariantChars: f = [], // dom options apply: m = {}, watch: y = !0, debounceDelay: E = 10, processExisting: C = !0, selector: b = "[class]", styleId: v = "tenoxui-browser-id" } = {}) { super({ moxie: s, values: t, aliases: r, classes: i, tabSize: e, property: n, variants: a, safelist: o, typeOrder: h, breakpoints: c, moxieOptions: d, selectorPrefix: u, prefixLoaderOptions: p, reservedVariantChars: f }), this.apply = m, this.watch = y, this.styleId = v, this.selector = b, this.updateTimeout = null, this.debounceDelay = E, this.processExisting = C, this.observer = null, this.styleElement = null, this.isInitialized = !1, this.processedClasses = /* @__PURE__ */ new Set(); } /** * Initialize the TenoxUI instance */ init() { return this.isInitialized ? (console.warn("TenoxUI is already initialized"), this) : (this.createStyleElement(), this.processExisting && this.scanAndProcessClasses(), this.watch && this.startObserving(), this.isInitialized = !0, this); } /** * Create or get the style element for injecting CSS */ createStyleElement() { return this.styleElement = document.getElementById(this.styleId), this.styleElement || (this.styleElement = document.createElement("style"), this.styleElement.id = this.styleId, this.styleElement.setAttribute("data-tenoxui", "true"), document.head.appendChild(this.styleElement)), this.styleElement; } /** * Scan existing elements and process their classes */ scanAndProcessClasses() { const s = document.querySelectorAll(this.selector), e = /* @__PURE__ */ new Set(); s.forEach((t) => { const i = t.classList; i.length > 0 && i.forEach((r) => { r.trim() && e.add(r); }); }), e.size > 0 && this.processClasses(Array.from(e)); } /** * Create styles from CSS and apply configuration */ createStyles(s) { const e = this.render(this.apply); return this.injectCSS(e + ` ` + s); } /** * Process an array of class names and generate CSS */ processClasses(s) { const e = s.filter((t) => !this.processedClasses.has(t)); e.length !== 0 && (e.forEach((t) => this.processedClasses.add(t)), this.createStyles(this.render(e))); } /** * Inject CSS into the style element */ injectCSS(s) { return this.styleElement && s.trim() && (this.styleElement.textContent += ` ` + s), this; } /** * Start observing DOM changes for new classes */ startObserving() { if (!window.MutationObserver) { console.warn("MutationObserver not supported, dynamic class detection disabled"); return; } this.observer = new MutationObserver((s) => { this.debouncedUpdate(() => { this.handleMutations(s); }); }), this.observer.observe(document.body, { childList: !0, subtree: !0, attributes: !0, attributeFilter: ["class"] }); } /** * Handle DOM mutations and extract new classes */ handleMutations(s) { const e = /* @__PURE__ */ new Set(); s.forEach((t) => { if (t.type === "attributes" && t.attributeName === "class") { const i = t.target; i.classList && i.classList.forEach((r) => { r.trim() && !this.processedClasses.has(r) && e.add(r); }); } t.type === "childList" && t.addedNodes.length > 0 && t.addedNodes.forEach((i) => { i.nodeType === Node.ELEMENT_NODE && this.extractClassesFromElement(i, e); }); }), e.size > 0 && this.processClasses(Array.from(e)); } /** * Extract classes from an element and its descendants */ extractClassesFromElement(s, e) { s.classList && s.classList.forEach((i) => { i.trim() && !this.processedClasses.has(i) && e.add(i); }), s.querySelectorAll("[class]").forEach((i) => { i.classList.forEach((r) => { r.trim() && !this.processedClasses.has(r) && e.add(r); }); }); } /** * Debounce updates to avoid excessive processing */ debouncedUpdate(s) { this.updateTimeout && clearTimeout(this.updateTimeout), this.updateTimeout = setTimeout(s, this.debounceDelay); } /** * Manually add classes for processing */ addClass(...s) { const e = []; for (const t of s) Array.isArray(t) ? e.push(...t) : t && e.push(t); return this.processClasses(e), this; } /** * Rescan existing elements for classes */ rescan() { return this.scanAndProcessClasses(), this; } /** * Clear all processed classes and rescan */ refresh() { return this.processedClasses.clear(), this.styleElement && (this.styleElement.textContent = ""), this.scanAndProcessClasses(), this; } /** * Stop observing DOM changes */ stopObserving() { return this.observer && (this.observer.disconnect(), this.observer = null), this; } /** * Destroy the TenoxUI instance and clean up resources */ destroy() { return this.stopObserving(), this.styleElement && (this.styleElement.remove(), this.styleElement = null), this.updateTimeout && (clearTimeout(this.updateTimeout), this.updateTimeout = null), this.processedClasses.clear(), this.isInitialized = !1, this; } /** * Get status information about the current instance */ status() { const s = Array.from(this.processedClasses), e = this.getRulesData(s), t = this.process(s); return { processedClasses: [s.length, s], validClasses: [ e.length, t ? t.map((i) => x(i.className)) : [] ], isObserving: !!this.observer, isInitialized: this.isInitialized, styleElementExists: !!this.styleElement }; } } export { w as TenoxUI, w as default }; //# sourceMappingURL=index.es.js.map