Low-level stylesheet management with support for CSS rule injection, caching, serialization, and specialized Shadow DOM handling.
Main stylesheet management class for CSS rule injection and caching.
/**
* Core stylesheet management class
*/
class Stylesheet {
/**
* Creates a new Stylesheet instance
* @param config - Optional configuration for stylesheet behavior
* @param serializedStylesheet - Optional serialized stylesheet state for SSR
*/
constructor(config?: IStyleSheetConfig, serializedStylesheet?: ISerializedStylesheet);
/**
* Get singleton instance of Stylesheet
* @param shadowConfig - Optional shadow DOM configuration
* @returns Stylesheet instance
*/
static getInstance(shadowConfig?: ShadowConfig): Stylesheet;
/**
* Insert a CSS rule into the stylesheet
* @param rule - CSS rule string to insert
* @param preserve - Whether to preserve rule during reset
* @param stylesheetKey - Optional key for targeted insertion
*/
insertRule(rule: string, preserve?: boolean, stylesheetKey?: string): void;
/**
* Generate a unique CSS class name
* @param displayName - Optional display name for debugging
* @returns Generated unique class name
*/
getClassName(displayName?: string): string;
/**
* Get all generated CSS rules
* @param includePreservedRules - Whether to include preserved rules
* @returns CSS rules as string
*/
getRules(includePreservedRules?: boolean): string;
/**
* Cache a class name with its associated data
* @param className - Class name to cache
* @param key - Lookup key for the class
* @param args - Original style arguments
* @param rules - Generated CSS rules
*/
cacheClassName(className: string, key: string, args: IStyle[], rules: string[]): void;
/**
* Retrieve class name from cache key
* @param key - Lookup key
* @returns Cached class name or undefined
*/
classNameFromKey(key: string): string | undefined;
/**
* Retrieve original style arguments for a class name
* @param className - Class name to look up
* @returns Original style arguments or undefined
*/
argsFromClassName(className: string): IStyle[] | undefined;
/**
* Retrieve CSS rules for a class name
* @param className - Class name to look up
* @returns CSS rules array or undefined
*/
insertedRulesFromClassName(className: string): string[] | undefined;
/**
* Get current class name cache
* @returns Object mapping keys to class names
*/
getClassNameCache(): { [key: string]: string };
/**
* Set stylesheet configuration
* @param config - New configuration options
*/
setConfig(config?: IStyleSheetConfig): void;
/**
* Reset stylesheet state
*/
reset(): void;
/**
* Reset only the cached keys
*/
resetKeys(): void;
/**
* Serialize stylesheet state for SSR
* @returns Serialized stylesheet data
*/
serialize(): string;
/**
* Register callback for rule insertion events
* @param callback - Function to call when rules are inserted
* @returns Unsubscribe function
*/
onInsertRule(callback: Function | InsertRuleCallback): Function;
/**
* Register callback for stylesheet reset events
* @param callback - Function to call when stylesheet is reset
* @returns Unsubscribe function
*/
onReset(callback: Function): Function;
}Usage Examples:
import { Stylesheet, InjectionMode } from "@fluentui/merge-styles";
// Custom stylesheet with configuration
const customStylesheet = new Stylesheet({
injectionMode: InjectionMode.insertNode,
defaultPrefix: "my-app",
namespace: "my-namespace"
});
// Insert custom CSS rules
customStylesheet.insertRule(`.custom-class { color: red; }`, true);
// Generate class names
const className1 = customStylesheet.getClassName("button");
const className2 = customStylesheet.getClassName("header");
// Get all generated CSS
const cssRules = customStylesheet.getRules();
// Monitor rule insertion
const unsubscribe = customStylesheet.onInsertRule((rule) => {
console.log("Rule inserted:", rule);
});Specialized stylesheet class for Shadow DOM environments with constructable stylesheet support.
/**
* Specialized stylesheet for Shadow DOM environments
*/
class ShadowDomStylesheet extends Stylesheet {
/**
* Creates Shadow DOM stylesheet instance
* @param config - Configuration options including inShadow flag
* @param serializedStylesheet - Optional serialized state
*/
constructor(config?: IStyleSheetConfig, serializedStylesheet?: ISerializedStylesheet);
/**
* Get singleton Shadow DOM stylesheet instance
* @param shadowConfig - Shadow DOM configuration
* @returns ShadowDomStylesheet instance
*/
static getInstance(shadowConfig?: ShadowConfig): ShadowDomStylesheet;
/**
* Get map of adopted stylesheets
* @returns Map of stylesheet keys to ExtendedCSSStyleSheet
*/
getAdoptedSheets(): Map<string, ExtendedCSSStyleSheet>;
/**
* Register callback for sheet addition events
* @param callback - Function called when sheets are added
* @returns Unsubscribe function
*/
onAddSheet(callback: AddSheetCallback): Function;
/**
* Insert rule with Shadow DOM handling
* @param rule - CSS rule to insert
* @param preserve - Whether to preserve during reset
*/
insertRule(rule: string, preserve?: boolean): void;
}Usage Examples:
import { ShadowDomStylesheet, makeShadowConfig } from "@fluentui/merge-styles";
// Create shadow configuration
const shadowConfig = makeShadowConfig("my-component", true, window);
// Get Shadow DOM stylesheet
const shadowStylesheet = ShadowDomStylesheet.getInstance(shadowConfig);
// Monitor sheet additions
shadowStylesheet.onAddSheet(({ key, sheet }) => {
console.log(`Sheet added: ${key}`, sheet);
});
// Insert rules into Shadow DOM
shadowStylesheet.insertRule(`.shadow-style { background: blue; }`);
// Get adopted sheets
const adoptedSheets = shadowStylesheet.getAdoptedSheets();Additional utilities for stylesheet management.
/**
* Clone CSSStyleSheet from source to target
* @param srcSheet - Source stylesheet to clone from
* @param targetSheet - Target stylesheet to clone to
* @returns The target stylesheet
*/
function cloneCSSStyleSheet(srcSheet: CSSStyleSheet, targetSheet: CSSStyleSheet): CSSStyleSheet;interface IStyleSheetConfig {
/** CSS rule injection strategy */
injectionMode?: InjectionMode;
/** Default prefix for generated class names */
defaultPrefix?: string;
/** Namespace for CSS rules */
namespace?: string;
/** Whether stylesheet is in Shadow DOM */
inShadow?: boolean;
/** Window object reference */
window?: Window;
/** RTL mode flag */
rtl?: boolean;
/** Custom class name cache */
classNameCache?: { [key: string]: string };
/** Content Security Policy settings */
cspSettings?: ICSPSettings;
/** Key for stylesheet identification */
stylesheetKey?: string;
/** @deprecated Legacy rule insertion callback */
onInsertRule?: (rule: string) => void;
}
interface ICSPSettings {
/** Nonce value for CSP compliance */
nonce?: string;
}
interface ISerializedStylesheet {
/** Cached class name to arguments mapping */
classNameToArgs: Stylesheet['_classNameToArgs'];
/** Class name generation counter */
counter: Stylesheet['_counter'];
/** Key to class name mapping */
keyToClassName: Stylesheet['_keyToClassName'];
/** Preserved CSS rules */
preservedRules: Stylesheet['_preservedRules'];
/** All generated rules */
rules: Stylesheet['_rules'];
}
/** Extended CSSStyleSheet with metadata */
type ExtendedCSSStyleSheet = CSSStyleSheet & {
bucketName: string;
metadata: Record<string, unknown>;
};
/** Callback for sheet addition events */
type AddSheetCallback = ({ key, sheet }: {
key: string;
sheet: ExtendedCSSStyleSheet;
}) => void;
/** Callback for rule insertion events */
type InsertRuleCallback = ({ key, sheet, rule }: {
key: string;
sheet: CSSStyleSheet;
rule: string;
}) => void;Different strategies for CSS rule injection:
const InjectionMode = {
/** No injection - use getRules() to read styles */
none: 0,
/** Insert rules using insertRule API */
insertNode: 1,
/** Append rules using appendChild */
appendChild: 2,
} as const;
type InjectionMode = (typeof InjectionMode)[keyof typeof InjectionMode];Usage Examples:
import { Stylesheet, InjectionMode } from "@fluentui/merge-styles";
// Server-side rendering - no injection
const ssrStylesheet = new Stylesheet({
injectionMode: InjectionMode.none
});
// Client-side with insertRule API
const clientStylesheet = new Stylesheet({
injectionMode: InjectionMode.insertNode
});
// Legacy appendChild method
const legacyStylesheet = new Stylesheet({
injectionMode: InjectionMode.appendChild
});Constants for browser feature detection:
/** Browser supports constructable stylesheets */
const SUPPORTS_CONSTRUCTABLE_STYLESHEETS: boolean;
/** Browser supports modifying adopted stylesheets */
const SUPPORTS_MODIFYING_ADOPTED_STYLESHEETS: boolean;Stylesheet serialization and hydration for SSR:
// Server-side: serialize stylesheet state
const stylesheet = Stylesheet.getInstance();
// ... generate styles during SSR
const serializedState = stylesheet.serialize();
// Client-side: hydrate with serialized state
const hydratedStylesheet = new Stylesheet(
{ injectionMode: InjectionMode.insertNode },
JSON.parse(serializedState)
);