import type { Properties } from 'csstype'; /** A CSS property value. */ export type CSSValue = string | number | null | undefined; /** csstype's value union for property `K`, with `string & {}` for arbitrary strings. */ type PropValue> = Properties<(string & {}) | number, string & {}>[K]; /** * CSS properties with full value autocomplete. Uses csstype's original value * unions (which include `string & {}` for arbitrary strings) plus `null` * (filtered at runtime). Numbers accepted for length properties. An array value * emits one declaration per element, providing CSS fallback values. */ export type CSSProperties = { [K in keyof Properties<(string & {}) | number, string & {}>]?: PropValue | null | PropValue[]; }; /** * A style rule object. Keys can be CSS properties (camelCase) or selectors * for nesting (`&:hover`), at-rules (`@media ...`), global styles (`@global`), * and class references (`$className`). */ export interface StyleRule extends CSSProperties { [selector: string]: StyleRule | CSSValue | CSSValue[]; } /** * Top-level styles object mapping class names and selectors to style rules. * An at-rule key may also hold a statement prelude, rendered as * `@rule prelude;` (e.g. `'@layer' : 'base, utilities'`). An array of preludes * emits one statement per element, so a name can repeat (e.g. several * `'@import'` rules). */ export type Styles = Record; /** A renderer function: receives the current value and returns the next, called with the StyleSheet as `this`. */ export type RendererFn = (this: StyleSheet, styles: any) => any; /** A value provided directly or as a function returning it (called with the StyleSheet as `this`). */ export type Resolvable = T | ((this: StyleSheet) => T); /** * Characters that can't appear in a class key. At runtime only keys matching * `/^\w+$/` produce a class name. */ type InvalidClassChar = | '-' | ' ' | '.' | ',' | ':' | '&' | '>' | '+' | '~' | '*' | '[' | ']' | '(' | ')' | '#' | '@' | '$' | '%' | '"' | "'" | '=' | '|' | '^'; /** At-rules whose block nests style rules, and may therefore declare class names. */ type AtBlockPrefix = '@media' | '@supports' | '@layer' | '@container' | '@scope' | '@starting-style'; /** * Values that hold no nested rules: a declaration value, or an array of them * (fallback declarations and repeated at-rule statements). A key holding one of * these declares no class name and is not descended into. */ type FlatValue = CSSValue | readonly CSSValue[]; /** Own keys that produce a class name: plain identifiers whose value is a rule object. */ type OwnClassKeys = keyof { [K in keyof S as K extends `${string}${InvalidClassChar}${string}` ? never : S[K] extends FlatValue ? never : K & string]: unknown; }; /** * Every key that produces a class name: an object's own class keys, plus the class * keys declared inside at-rule blocks that nest style rules (`@media`, `@layer`, …), * gathered recursively through those blocks. * * The descent is unrolled into fixed levels (`ClassKeys` → `ClassKeys1` → `ClassKeys2` * → `ClassKeys3`) rather than written as a single self-referential type. A * self-referential version destabilizes the TypeScript language server; the bounded * depth (four levels of at-rule nesting, which covers `@layer > @media > @supports > * @container`) keeps type-checking cheap and stops the compiler's recursion budget * from blowing up on large stylesheets. */ type ClassKeys = OwnClassKeys | { [K in keyof S]: K extends `${AtBlockPrefix}${string}` ? (S[K] extends FlatValue ? never : ClassKeys1) : never; }[keyof S]; type ClassKeys1 = OwnClassKeys | { [K in keyof S]: K extends `${AtBlockPrefix}${string}` ? (S[K] extends FlatValue ? never : ClassKeys2) : never; }[keyof S]; type ClassKeys2 = OwnClassKeys | { [K in keyof S]: K extends `${AtBlockPrefix}${string}` ? (S[K] extends FlatValue ? never : ClassKeys3) : never; }[keyof S]; type ClassKeys3 = OwnClassKeys | { [K in keyof S]: K extends `${AtBlockPrefix}${string}` ? (S[K] extends FlatValue ? never : OwnClassKeys) : never; }[keyof S]; /** Options for the StyleSheet constructor. Accepts custom keys for subclasses and custom renderers. */ export interface StyleSheetOptions { /** * Prefix for generating unique identifiers and data attributes. Default: `'fun'`. * May be a function returning the prefix, evaluated when the instance is created. */ prefix?: Resolvable; /** Custom function to generate the unique identifier. */ generateUid?: (this: StyleSheet) => string; /** Custom function to generate unique class names. */ generateClassName?: (this: StyleSheet, className: string, index: number) => string; /** Custom function to determine whether the StyleSheet should be added to the DOM. */ shouldAttachToDOM?: (this: StyleSheet) => boolean; /** * Attributes to be added to the `