UNPKG

@winglet/style-utils

Version:

Comprehensive CSS and style management utilities including className manipulation, CSS compression, and universal style manager for TypeScript projects

178 lines (177 loc) 5.9 kB
import { type StyleManagerConfig } from './type'; /** * A scoped CSS management system that provides efficient style injection and cleanup. * It supports both regular DOM and Shadow DOM environments. * * StyleManager allows you to: * - Create isolated CSS scopes using class-based selectors * - Add/remove styles dynamically with automatic DOM updates * - Batch style updates using requestAnimationFrame for optimal performance * - Support both modern CSSStyleSheet API and fallback style element injection * - Automatically scope CSS selectors to prevent style conflicts * - Compress CSS for production optimization * - Work within Shadow DOM boundaries * * Each StyleManager instance manages styles for a specific scope, identified by a unique scopeId. * Styles are automatically prefixed with `className=".${scopeId}"` to ensure isolation. * * @example * ```typescript * // Get a manager for a specific scope * const manager = StyleManager.get('my-component'); * * // Add scoped styles * manager.add('button-style', ` * .btn { * background: blue; * color: white; * padding: 8px 16px; * } * .btn:hover { * background: darkblue; * } * `); * * // The CSS will be applied as: * // .my-component .btn { ... } * // .my-component .btn:hover { ... } * * // Remove specific styles * manager.remove('button-style'); * * // Clean up the entire scope * manager.destroy(); * ``` * * @example * ```typescript * // Using with Shadow DOM * const shadowRoot = element.attachShadow({ mode: 'open' }); * const manager = StyleManager.get('shadow-component', { shadowRoot }); * * manager.add('shadow-styles', ` * :host { display: block; } * .content { padding: 1rem; } * `); * ``` */ export declare class StyleManager { private scopeId; private static __SHEETS__; private static __SHADOW_ID_KEY__; private __processedStyles__; private __element__; private __sheet__; private __dirty__; private __frameId__; private __scope__; private __root__; private __isShadowDOM__; private __instanceKey__; private constructor(); /** * Gets or creates a StyleManager instance for the specified scope. * * This is a singleton factory method that ensures only one StyleManager * instance exists per scope ID and target (document or shadow root). * If a manager for the scope doesn't exist, it creates a new one and stores * it in the internal registry. * * @param scopeId - The unique identifier for the style scope * @param config - Optional configuration for the StyleManager * @returns The StyleManager instance for the specified scope * * @example * ```typescript * const manager1 = StyleManager.get('my-scope'); * const manager2 = StyleManager.get('my-scope'); * console.log(manager1 === manager2); // true - same instance * * // With Shadow DOM * const shadowManager = StyleManager.get('shadow-scope', { shadowRoot }); * ``` */ static get(scopeId: string, config?: StyleManagerConfig): StyleManager; /** * Adds or updates a CSS style in this scope. * * The CSS will be automatically scoped with the scope ID and applied to the DOM. * Updates are batched using requestAnimationFrame for optimal performance. * If a style with the same ID already exists, it will be replaced. * * @param id - Unique identifier for this specific style within the scope * @param css - The CSS string to add (will be automatically scoped) * @param compressed - If true, skips compression for this CSS (default: false) * * @example * ```typescript * const manager = StyleManager.get('my-component'); * * manager.add('button-style', ` * .btn { * background: blue; * color: white; * } * `); * * // CSS will be applied as: * // .my-component .btn { background: blue; color: white; } * ``` * * @example * ```typescript * // Using pre-compressed CSS * manager.add('compressed-style', '.btn{background:blue;color:white}', true); * ``` */ add(id: string, css: string, compressed?: boolean): void; /** * Removes a specific CSS style from this scope. * * If the style exists and is successfully removed, the DOM will be updated * in the next animation frame to reflect the change. * * @param id - The unique identifier of the style to remove * * @example * ```typescript * const manager = StyleManager.get('my-component'); * * // Add a style * manager.add('temp-style', '.temp { color: red; }'); * * // Later, remove it * manager.remove('temp-style'); * ``` */ remove(id: string): void; /** * Completely destroys this StyleManager instance and removes all associated styles from the DOM. * * This method performs a complete cleanup by: * - Canceling any pending animation frames * - Removing the CSSStyleSheet from adoptedStyleSheets (modern browsers) * - Removing the style element from the DOM (fallback browsers) * - Clearing all cached styles * - Removing this instance from the global registry * * After calling destroy(), this StyleManager instance should not be used. * * @example * ```typescript * const manager = StyleManager.get('my-component'); * manager.add('style1', '.class1 { color: red; }'); * manager.add('style2', '.class2 { color: blue; }'); * * // Clean up everything * manager.destroy(); * * // The scope is now completely removed from DOM and registry * ``` */ destroy(): void; private __scheduleDOMUpdate__; private __scopeCSS__; private __flush__; private __applyCSS__; }