🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

cssfun

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cssfun - npm Package Compare versions

Comparing version
0.1.0-alpha.2
to
0.1.0-alpha.3
+1
-2
dist/cssfun.js

@@ -577,4 +577,3 @@ (function (global, factory) {

*
* @param {Object} [options.styleSheetOptions] - Options to pass when creating the StyleSheet instance.
* Default is `system`.
* @param {Object} [options.styleSheetOptions] - Options to pass when creating the StyleSheet instance.
*

@@ -581,0 +580,0 @@ * @returns {StyleSheet} The theme StyleSheet instance. Use `classes.root` to get the theme class name.

@@ -1,1 +0,1 @@

{"version":3,"file":"cssfun.min.js","sources":["../src/utils/isObject.js","../src/StyleSheet.js","../src/utils/dev.js","../src/css.js","../src/createTheme.js"],"sourcesContent":["/**\n * Check if a value is an object.\n * @param {any} value - The value to check.\n * @returns {boolean} True if the value is an object, false otherwise.\n * @module\n * @private\n */\nconst isObject = value =>\n value !== null && typeof value === 'object' && !Array.isArray(value);\n\nexport default isObject;\n","import isObject from './utils/isObject.js';\nimport __DEV__ from './utils/dev.js';\n\n/**\n * Convert a camelized string to a dashed string.\n * @param {string} str String to be converted.\n * @return {string} The converted string.\n * @private\n */\nconst camelizedToDashed = str => str.replace(/([A-Z])/g, (g) => `-${g[0].toLowerCase()}`);\n\n/**\n * Resolve a value that may be provided directly or as a function.\n * If it's a function, call it with the provided context and return the result.\n * Otherwise, return the value as is.\n * @param {*} expression Value or function to be resolved.\n * @param {*} context Context (`this`) to call the function with.\n * @return {*} The resolved value.\n * @private\n */\nconst getResult = (expression, context) =>\n typeof expression !== 'function' ? expression :\n expression.call(context);\n\nconst styleSheetOptions = ['prefix', 'generateUid', 'generateClassName', 'shouldAttachToDOM', 'attributes', 'renderers'];\n\n/**\n * The StyleSheet class is responsible for creating and managing a CSS stylesheet.\n * It takes a styles object and an optional options object as input, processes the styles, \n * and generates a CSS stylesheet that can be attached to the DOM, destroyed, or \n * rendered as a string for server-side rendering.\n * \n * @module\n * @class\n * @param {Object} styles - The styles object. This is an object where keys represent \n * CSS selectors and values are style objects. The styles object is processed through \n * the renderers to generate the final CSS string. It is stored in the instance as `this.styles`.\n * @param {Object} [options={}] - Configuration options. The following options are assigned to the instance (`this`):\n * `prefix`, `generateUid`, `generateClassName`, `shouldAttachToDOM`, `attributes`, `renderers`.\n * @param {string|Function} [options.prefix='fun'] - Prefix for generating unique identifiers and data attributes.\n * May be a function returning the prefix, evaluated when the instance is created.\n * @param {Function} [options.generateUid] - Custom function to generate the unique identifier.\n * @param {Function} [options.generateClassName] - Custom function to generate unique class names.\n * @param {Object|Function} [options.attributes] - Attributes to be added to the `<style>` element.\n * May be a function returning the attributes object, evaluated lazily by `getAttributes`.\n * @param {Array|Function} [options.renderers=['parseStyles', 'renderStyles']] - Array of renderer functions or\n * method names (or a function returning such an array). Resolved when the instance is created and applied in order\n * by `render`, each renderer receiving the previous one's output. Renderers are called with the instance as `this`.\n * @param {Function} [options.shouldAttachToDOM] - Custom function to determine whether the StyleSheet should be added to the DOM.\n * \n * @example\n * // Create a new StyleSheet instance with a styles object.\n * const instance = new StyleSheet({\n * root: {\n * color: 'black'\n * }\n * });\n * \n * // Attach the StyleSheet instance to the DOM.\n * instance.attach();\n * \n * // Retrieve the generated classes object from the instance.\n * const { classes } = instance;\n * \n * // Use the generated class name in your component.\n * function Header() {\n * return <h1 className={classes.root}>Hello World</h1>;\n * }\n * \n * @property {Object} classes - Object mapping each top-level selector key (those matching `/^\\w+$/`)\n * to its generated unique class name string.\n * @property {Object} styles - The original styles object provided to the instance.\n * @property {string} uid - Unique identifier for the StyleSheet instance, generated using `this.generateUid`.\n * @property {string} prefix - Prefix for generating unique identifiers. Resolved to a string when the instance\n * is created (may be supplied as a function via options or a subclass).\n * @property {Object|Function} [attributes] - Optional attributes to be added to the `<style>` element. May be\n * `undefined`, an object, or a function returning the attributes object (evaluated lazily by `getAttributes`).\n * @property {Array} renderers - Array of renderer functions used to process the styles object. Method-name\n * strings passed via options are resolved to methods when the instance is created.\n * @property {HTMLElement} el - Reference to the `<style>` element in the DOM. Created when the instance is attached to the DOM.\n */\nclass StyleSheet {\n constructor(styles, options = {}) {\n this.preinitialize.apply(this, arguments);\n // Styles object.\n this.styles = styles;\n // Original class names object.\n this.classes = {};\n // Set options on the instance.\n styleSheetOptions.forEach(key => {\n if (key in options) this[key] = options[key];\n });\n // Set default renderers.\n this.renderers = this.renderers ?\n getResult(this.renderers, this).map(r => typeof r === 'string' ? this[r] : r) :\n [this.parseStyles, this.renderStyles];\n // Set default prefix.\n this.prefix = this.prefix ? getResult(this.prefix, this) : StyleSheet.prefix;\n // Generate the `StyleSheet` unique identifier.\n this.uid = this.generateUid();\n // Generate class names. Only generate class names for top-level selectors.\n let counter = 0;\n Object.keys(styles).forEach(selector => {\n if (selector.match(StyleSheet.classRegex)) {\n this.classes[selector] = this.generateClassName(selector, ++counter);\n }\n });\n }\n\n /**\n * Hook run at the very start of the constructor, before `styles` and `options`\n * are applied and before `renderers`, `prefix`, `uid` and `classes` are computed.\n * Does nothing by default. Override it in a subclass to run setup logic or define\n * instance properties such as `prefix`, `attributes` or `renderers`. Values set\n * here are still overridden by the matching `options`.\n * @param {Object} styles - The styles object passed to the constructor.\n * @param {Object} [options] - The options object passed to the constructor (may be `undefined`).\n * @returns {void}\n */\n preinitialize() {}\n\n /**\n * Generate a stable unique identifier.\n * May be overridden by `options.generateUid`.\n * @returns {string} The unique identifier.\n */\n generateUid() {\n const styles = JSON.stringify(this.styles);\n // FNV-1a 32-bit offset basis.\n let hash = 2166136261;\n for (let i = 0; i < styles.length; i++) {\n // XOR with the byte value.\n hash ^= styles.charCodeAt(i);\n // Multiply by FNV prime and ensure 32-bit unsigned integer.\n hash = (hash * 16777619) >>> 0;\n }\n // Convert the hash to a shorter base-36 string.\n return hash.toString(36);\n }\n\n /**\n * Generate a unique class name.\n * Transform local selectors that are classes to unique class names\n * to be used as class names in the styles object.\n * May be overridden by `options.generateClassName` or by extending the class.\n * @param {string} className - The class name.\n * @param {number} index - The index of the class name.\n * @returns {string} The unique class name.\n */\n generateClassName(className, index) {\n return __DEV__ && StyleSheet.debug ?\n `${this.prefix}-${this.uid}-${className}` :\n `${this.prefix[0]}-${this.uid}-${index}`;\n }\n\n /**\n * Apply the renderers to the styles object.\n * Renderers are applied in order, starting from `this.styles`, with each renderer\n * receiving the previous one's output and called with the instance as `this`.\n * It will return a string ready to be added to the style element.\n * @returns {string} The styles object as a string.\n */\n render() {\n return this.renderers.reduce((acc, r) => r.call(this, acc), this.styles);\n }\n\n /**\n * Render the styles object as a string.\n * Its one of the default renderers.\n * It will return a string ready to be added to the `style` element.\n * @param {Object} styles - The styles object.\n * @param {number} level - The level of indentation. Used for debugging.\n * @returns {string} The styles object as a string.\n * @private\n */\n renderStyles(styles, level = 1) {\n return Object.keys(styles).reduce((acc, key) => {\n const value = styles[key];\n let indent = '', nl = '', whitespace = '';\n // Format the CSS string.\n if (__DEV__ && StyleSheet.debug) {\n indent = StyleSheet.indent.repeat(level);\n nl = '\\n';\n whitespace = ' ';\n }\n // Add the styles to the accumulator recursively.\n if (isObject(value)) {\n if (Object.keys(value).length > 0) {\n const renderedStyles = this.renderStyles(value, level + 1);\n // Add rules to the accumulator.\n acc.push(`${indent}${key}${whitespace}{${nl}${renderedStyles}${indent}}${nl}`);\n }\n } else if (typeof value !== 'undefined' && value !== null) {\n // Add the style to the accumulator.\n acc.push(`${indent}${key}:${whitespace}${value};${nl}`);\n }\n\n return acc;\n }, []).join('');\n }\n\n /**\n * Parse the styles object and transform it. \n * Expand nested styles, parse global styles, generate selectors, replace selector references \n * and convert camelized keys to dashed-case.\n * Its one of the default renderers.\n * It will return an object ready to be rendered as string by `renderStyles`.\n * @param {Object} styles - The styles object.\n * @param {Object} parent - The parent object. Used for nested styles.\n * @param {string} parentSelector - The parent selector. Used for nested styles.\n * @param {boolean} isGlobal - If true, the styles are global styles.\n * @returns {Object} The styles object.\n * @private\n */\n parseStyles(styles, parent, parentSelector, isGlobal) {\n const fromClasses = selector => selector in this.classes ? `.${this.classes[selector]}` : selector;\n // Parse the key and generate a selector.\n const generateKey = key => {\n if (isGlobal && parentSelector) {\n // Nested global selectors.\n return `${parentSelector} ${key}`;\n }\n if (key.match(StyleSheet.globalPrefixRegex)) {\n // Global prefix and nested global prefix.\n return `${parentSelector ? `${parentSelector} ` : ''}${key.replace(StyleSheet.globalPrefixRegex, '')}`;\n }\n // Nested, references and replace class names with created ones.\n return fromClasses(key)\n .replace(StyleSheet.referenceRegex, (_match, ref) => fromClasses(ref))\n .replace(StyleSheet.nestedRegex, parentSelector);\n };\n\n const result = Object.keys(styles).reduce((acc, key) => {\n const value = styles[key];\n // Parse styles recursively.\n if (isObject(value)) {\n if (key.match(StyleSheet.globalRegex)) {\n // Global and nested global styles.\n Object.assign(parent || acc, this.parseStyles(value, acc, parentSelector, true));\n } else if ((key.match(StyleSheet.nestedRegex) || key.match(StyleSheet.globalPrefixRegex)) && parent) {\n const selector = generateKey(key);\n parent[selector] = {};\n // Nested global prefix and nested styles with reference.\n Object.assign(parent[selector], this.parseStyles(value, parent, selector));\n } else {\n const selector = generateKey(key);\n acc[selector] = {};\n // Don't expand at-rules.\n const args = selector.match(/@/) ? [] : [acc, selector];\n // Regular styles.\n Object.assign(acc[selector], this.parseStyles(value, ...args));\n }\n } else if (typeof value !== 'undefined' && value !== null) {\n // Add style rules.\n // Convert camelCase to dashed-case.\n // Only convert if the key doesn't already contain a dash.\n // Allows css vars to contain camelCase parts between dashes.\n acc[key.match(/-/) ? key : camelizedToDashed(key)] = value;\n }\n\n return acc;\n }, {});\n\n return result;\n }\n\n /**\n * Get the attributes object used to set the attributes on the style element.\n * Starts from `this.attributes`, which is optional and may be `undefined`, an\n * object, or a function returning the attributes object (resolved via `getResult`).\n * The `data-<prefix>-uid` attribute is always added.\n * @returns {Object} The attributes object.\n * @private\n */\n getAttributes() {\n const attributes = Object.assign({}, getResult(this.attributes, this));\n attributes[`data-${this.prefix}-uid`] = this.uid;\n return attributes;\n }\n\n /**\n * Render the StyleSheet as a style element string.\n * Used for server-side rendering.\n * @returns {string} The instance as a string.\n */\n toString() {\n const attributes = this.getAttributes();\n const attributesHtml = Object.keys(attributes).map(key => ` ${key}=\"${attributes[key]}\"`).join('');\n const nl = (__DEV__ && StyleSheet.debug) ? '\\n' : '';\n return `<style${attributesHtml}>${nl}${this.render()}</style>${nl}`;\n }\n\n /**\n * Check if the StyleSheet should be added to the DOM.\n * By default, it returns true if running in a browser environment and no style element\n * with the same `data-fun-uid` attribute exists in the DOM.\n * This prevents duplicate style elements and ensures proper behavior for server-side rendering.\n * May be overridden by `options.shouldAttachToDOM`.\n * @returns {boolean} True if the StyleSheet should be added to the DOM, false otherwise.\n */\n shouldAttachToDOM() {\n return typeof document !== 'undefined' && !document.querySelector(`style[data-${this.prefix}-uid=\"${this.uid}\"]`);\n }\n\n /**\n * Add the instance to the registry and if we are in the browser, \n * attach it to the DOM.\n * @returns {StyleSheet} The instance.\n */\n attach() {\n // Add the instance to the registry if it's not already there.\n if (!StyleSheet.registry.some(({ uid }) => uid === this.uid)) {\n StyleSheet.registry.push(this);\n }\n // If we're in the browser and the style element doesn't exist, create it.\n if (this.shouldAttachToDOM()) {\n // Create the style element.\n this.el = document.createElement('style');\n\n const attributes = this.getAttributes();\n // Set the attributes on the style element.\n Object.keys(attributes).forEach(key => {\n this.el.setAttribute(key, attributes[key]);\n });\n // Render the styles and set the text content of the style element.\n this.el.textContent = this.render();\n // Append the style element to the head.\n document.head.appendChild(this.el);\n }\n\n return this;\n }\n\n /**\n * Destroy the instance and remove it from the registry and \n * from the DOM, if it's present.\n * @returns {StyleSheet} The instance.\n */\n destroy() {\n const index = StyleSheet.registry.indexOf(this);\n // Remove the instance from the registry.\n if (index > -1) {\n StyleSheet.registry.splice(index, 1);\n }\n\n if (this.el) {\n // Remove the style element from the DOM.\n if (this.el.parentNode) {\n this.el.parentNode.removeChild(this.el);\n }\n // Remove the reference to the style element.\n this.el = null;\n }\n\n return this;\n }\n\n /**\n * Render all instances in the registry as a string, including the style tags.\n * Can be used to insert style tags in an HTML template for server-side rendering.\n * @returns {string} All instances in the registry as a string.\n * @static\n */\n static toString() {\n return StyleSheet.registry.join('');\n }\n\n /**\n * Render all instances in the registry as CSS string.\n * Can be used to generate an external CSS file.\n * @returns {string} All instances in the registry rendered as CSS string.\n * @static\n */\n static toCSS() {\n return StyleSheet.registry.map(instance => instance.render()).join('');\n }\n\n /**\n * Destroy all instances in the registry and remove them from \n * it and from the DOM.\n * @static\n */\n static destroy() {\n StyleSheet.registry.slice().forEach(instance => instance.destroy());\n }\n}\n\n/**\n * Regular expressions to match class names.\n * @static\n * @private\n */\nStyleSheet.classRegex = /^\\w+$/;\n\n/**\n * Regular expression to match global styles.\n * @static\n * @private\n */\nStyleSheet.globalRegex = /^@global$/;\n\n/**\n * Regular expression to match global styles with a prefix.\n * @static\n * @private\n */\nStyleSheet.globalPrefixRegex = /^@global\\s+/;\n\n/**\n * Regular expression to match references to other class names.\n * @static\n * @private\n */\nStyleSheet.referenceRegex = /\\$(\\w+)/g;\n\n/**\n * Regular expression to match nested styles.\n * @static\n * @private\n */\nStyleSheet.nestedRegex = /&/g;\n\n/**\n * @static\n * @property {string} prefix - The class prefix. Used to generate unique class names.\n * @default fun\n */\nStyleSheet.prefix = 'fun';\n\n/**\n * @static\n * @property {string} indent - The indent string. Used to format text when debug is enabled.\n * @default ' '\n */\nStyleSheet.indent = ' ';\n\n/**\n * @static\n * @property {Array} registry - The registry array. StyleSheet instances \n * will be added to this array.\n */\nStyleSheet.registry = [];\n\n/**\n * @static\n * @property {boolean} debug - The debug flag. If true, the styles will be formatted with\n * indentation and new lines.\n * @default __DEV__\n */\nStyleSheet.debug = __DEV__;\n\nexport default StyleSheet;\n","/**\n * Development mode flag.\n * This will be replaced during build:\n * - ESM/CJS: replaced with process.env.NODE_ENV !== 'production'\n * - UMD dev: replaced with true\n * - UMD prod: replaced with false\n * @type {boolean}\n * @module\n * @private\n */\nconst __DEV__ = true;\n\nexport default __DEV__;\n","import StyleSheet from './StyleSheet.js';\n\n/**\n * Creates and attaches a new StyleSheet instance to the DOM.\n * \n * @module\n * @function\n * @param {Object} styles - An object containing CSS rules. Keys represent selectors, and values represent style objects.\n * @param {Object} [options] - Optional configuration for the StyleSheet instance. Includes options like `prefix`, `renderers`, and more.\n * @returns {StyleSheet} The created and attached StyleSheet instance. Its `classes` property maps\n * each top-level selector to its generated class name.\n * \n * @example\n * // Create styles for a link component.\n * const { classes } = css({\n * link : {\n * color : 'blue',\n * '&:hover' : {\n * textDecoration : 'underline'\n * }\n * }\n * });\n * \n * // Use the generated `link` class in a component.\n * const Link = ({ label, href }) => <a className={classes.link} href={href}>{label}</a>;\n */\nconst css = (styles, options) => new StyleSheet(styles, options).attach();\n\nexport default css;\n","import css from './css.js';\nimport StyleSheet from './StyleSheet.js';\nimport isObject from './utils/isObject.js';\n\n/**\n * Flattens a nested theme object into a map of CSS variable names to values.\n * Nested keys are joined with `-` (e.g. `{ colors: { primary: 'blue' } }` → `--prefix-colors-primary`).\n * @private\n * @param {Object} [theme={}] - Nested theme object.\n * @param {string|null} [prefix] - Prefix for variable names (e.g. `fun` → `--fun-key`). Omit or pass `null`/`''` for no prefix.\n * @returns {Object} Map of CSS variable names (e.g. `--fun-color`) to values.\n */\nconst makeCssVars = (theme = {}, prefix) => {\n function build(theme, nameAcc) {\n return Object.keys(theme).reduce((acc, key) => {\n const value = theme[key];\n const name = nameAcc ? `${nameAcc}-${key}` : prefix ? `--${prefix}-${key}` : `--${key}`;\n\n if (isObject(value)) {\n Object.assign(acc, build(value, name));\n } else if (typeof value !== 'undefined' && value !== null) {\n acc[name] = value;\n }\n\n return acc;\n }, {});\n }\n return build(theme);\n};\n\n/**\n * Returns keys that differ between two objects, with each side’s value.\n * @private\n * @param {Object} left - First object.\n * @param {Object} right - Second object.\n * @returns {{ left: Object, right: Object }} Objects containing only the differing keys and their values per side.\n */\nconst getDiff = (left, right) => {\n return Object.keys(left).reduce((acc, key) => {\n if (left[key] !== right[key]) {\n acc.left[key] = left[key];\n acc.right[key] = right[key];\n }\n return acc;\n }, { left : {}, right : {} });\n};\n\n/**\n * The `createTheme` function generates a theme StyleSheet instance with CSS variables \n * based on the provided themes and options. It supports multiple color schemes, \n * including `light`, `dark`, `light dark`, and `normal`. \n * \n * The `themes` object defines the styles for these color schemes. Each key in the object \n * corresponds to a color scheme (`light`, `dark`, `normal`), and its value is an object \n * containing key-value pairs that will be converted into CSS variables. Nested keys are \n * concatenated with `-` to form the variable name. For example, `{ light : { colors : { primary : 'blue' } } }` \n * generates `--fun-colors-primary : blue`.\n * \n * @module\n * @function\n * @param {Object} themes - An object defining styles for color schemes (`light`, `dark`, `normal`). \n * Each key corresponds to a color scheme, and its value is an object of key-value pairs converted \n * to CSS variables. Nested keys are concatenated with `-` to form variable names.\n * \n * @param {Object} [options] - An optional object to customize the theme generation. It includes options \n * for selecting color schemes, customizing CSS variable prefixes, and controlling StyleSheet creation.\n * \n * @param {String} [options.colorScheme] - Specifies the color scheme(s) to use. Possible values are: \n * `light` (uses the `light` theme only), `dark` (uses the `dark` theme only), `light dark` (default, \n * supports both `light` and `dark` themes, adapting to system preferences; can override system \n * preference with `data-color-scheme` set to `light` or `dark`), and `normal` (uses the `normal` theme only).\n * \n * @param {String|null} [options.cssVarsPrefix] - Prefix for the generated CSS variables. Defaults to `StyleSheet.prefix`.\n * Pass `null` or `''` to generate variables without a prefix (e.g. `--color` instead of `--fun-color`).\n * \n * @param {Function} [options.createStyleSheet] - A function used to create a new StyleSheet instance. \n * By default, it uses the `css` function.\n * \n * @param {Object} [options.styleSheetOptions] - Options to pass when creating the StyleSheet instance. \n * Default is `system`.\n * \n * @returns {StyleSheet} The theme StyleSheet instance. Use `classes.root` to get the theme class name. \n * Apply this class to the element you want to theme. The CSS variables will be available for all \n * its descendants.\n * \n * @example\n * // Create a theme with light and dark color schemes and apply it to the entire page.\n * const theme = createTheme({\n * light : {\n * colorPrimary : 'black',\n * backgroundLevel1 : 'white'\n * },\n * dark : {\n * colorPrimary : 'white',\n * backgroundLevel1 : 'black'\n * }\n * });\n * \n * // Add the `root` class (the theme class) to the body element.\n * // This will apply the theme to the entire page.\n * document.body.classList.add(theme.classes.root);\n * \n * // Add some styles using the theme CSS variables.\n * const { classes } = css({\n * button : {\n * color : 'var(--fun-colorPrimary)', // Use the CSS variable generated from the theme.\n * backgroundColor : 'var(--fun-backgroundLevel1)'\n * }\n * });\n * \n * // Add the `button` class to a button component.\n * // The button will use the CSS variables defined in the theme for its styles.\n * // Once the theme is applied, the button will automatically update its styles.\n * // If the system color scheme changes (e.g., from light to dark), the button will \n * // dynamically update to reflect the new theme without requiring additional code.\n * const Button = ({ label }) => <button className={classes.button}>{label}</button>;\n */\nconst createTheme = (themes = {}, options = {}) => {\n const colorScheme = options.colorScheme || 'light dark';\n const prefix = 'cssVarsPrefix' in options ? options.cssVarsPrefix : StyleSheet.prefix;\n\n let styles;\n\n if (colorScheme === 'light dark') {\n const cssVars = {\n light : makeCssVars(themes.light, prefix),\n dark : makeCssVars(themes.dark, prefix)\n };\n\n const diff = getDiff(cssVars.light, cssVars.dark);\n\n styles = {\n root : {\n ':where(&)' : Object.assign({ colorScheme : 'light' }, cssVars.light),\n ':where([data-color-scheme=\"dark\"] &)' : Object.assign({ colorScheme : 'dark' }, diff.right),\n },\n '@media (prefers-color-scheme: dark)' : {\n ':where($root)' : Object.assign({ colorScheme : 'dark' }, diff.right),\n ':where([data-color-scheme=\"light\"] $root)' : Object.assign({ colorScheme : 'light' }, diff.left)\n }\n };\n } else {\n styles = {\n root : {\n ':where(&)' : Object.assign({ colorScheme }, makeCssVars(themes[colorScheme], prefix))\n }\n };\n }\n\n return (options.createStyleSheet || css)(styles, options.styleSheetOptions);\n};\n\nexport default createTheme;\n"],"names":["isObject","value","Array","isArray","getResult","expression","context","call","styleSheetOptions","StyleSheet","constructor","styles","options","this","preinitialize","apply","arguments","classes","forEach","key","renderers","map","r","parseStyles","renderStyles","prefix","uid","generateUid","counter","Object","keys","selector","match","classRegex","generateClassName","JSON","stringify","hash","i","length","charCodeAt","toString","className","index","render","reduce","acc","level","renderedStyles","push","join","parent","parentSelector","isGlobal","fromClasses","generateKey","globalPrefixRegex","replace","referenceRegex","_match","ref","nestedRegex","globalRegex","assign","args","str","g","toLowerCase","getAttributes","attributes","shouldAttachToDOM","document","querySelector","attach","registry","some","el","createElement","setAttribute","textContent","head","appendChild","destroy","indexOf","splice","parentNode","removeChild","toCSS","instance","slice","indent","debug","css","makeCssVars","theme","build","nameAcc","name","themes","colorScheme","cssVarsPrefix","cssVars","light","dark","diff","left","right","root","createStyleSheet"],"mappings":"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"}
{"version":3,"file":"cssfun.min.js","sources":["../src/utils/isObject.js","../src/StyleSheet.js","../src/utils/dev.js","../src/css.js","../src/createTheme.js"],"sourcesContent":["/**\n * Check if a value is an object.\n * @param {any} value - The value to check.\n * @returns {boolean} True if the value is an object, false otherwise.\n * @module\n * @private\n */\nconst isObject = value =>\n value !== null && typeof value === 'object' && !Array.isArray(value);\n\nexport default isObject;\n","import isObject from './utils/isObject.js';\nimport __DEV__ from './utils/dev.js';\n\n/**\n * Convert a camelized string to a dashed string.\n * @param {string} str String to be converted.\n * @return {string} The converted string.\n * @private\n */\nconst camelizedToDashed = str => str.replace(/([A-Z])/g, (g) => `-${g[0].toLowerCase()}`);\n\n/**\n * Resolve a value that may be provided directly or as a function.\n * If it's a function, call it with the provided context and return the result.\n * Otherwise, return the value as is.\n * @param {*} expression Value or function to be resolved.\n * @param {*} context Context (`this`) to call the function with.\n * @return {*} The resolved value.\n * @private\n */\nconst getResult = (expression, context) =>\n typeof expression !== 'function' ? expression :\n expression.call(context);\n\nconst styleSheetOptions = ['prefix', 'generateUid', 'generateClassName', 'shouldAttachToDOM', 'attributes', 'renderers'];\n\n/**\n * The StyleSheet class is responsible for creating and managing a CSS stylesheet.\n * It takes a styles object and an optional options object as input, processes the styles, \n * and generates a CSS stylesheet that can be attached to the DOM, destroyed, or \n * rendered as a string for server-side rendering.\n * \n * @module\n * @class\n * @param {Object} styles - The styles object. This is an object where keys represent \n * CSS selectors and values are style objects. The styles object is processed through \n * the renderers to generate the final CSS string. It is stored in the instance as `this.styles`.\n * @param {Object} [options={}] - Configuration options. The following options are assigned to the instance (`this`):\n * `prefix`, `generateUid`, `generateClassName`, `shouldAttachToDOM`, `attributes`, `renderers`.\n * @param {string|Function} [options.prefix='fun'] - Prefix for generating unique identifiers and data attributes.\n * May be a function returning the prefix, evaluated when the instance is created.\n * @param {Function} [options.generateUid] - Custom function to generate the unique identifier.\n * @param {Function} [options.generateClassName] - Custom function to generate unique class names.\n * @param {Object|Function} [options.attributes] - Attributes to be added to the `<style>` element.\n * May be a function returning the attributes object, evaluated lazily by `getAttributes`.\n * @param {Array|Function} [options.renderers=['parseStyles', 'renderStyles']] - Array of renderer functions or\n * method names (or a function returning such an array). Resolved when the instance is created and applied in order\n * by `render`, each renderer receiving the previous one's output. Renderers are called with the instance as `this`.\n * @param {Function} [options.shouldAttachToDOM] - Custom function to determine whether the StyleSheet should be added to the DOM.\n * \n * @example\n * // Create a new StyleSheet instance with a styles object.\n * const instance = new StyleSheet({\n * root: {\n * color: 'black'\n * }\n * });\n * \n * // Attach the StyleSheet instance to the DOM.\n * instance.attach();\n * \n * // Retrieve the generated classes object from the instance.\n * const { classes } = instance;\n * \n * // Use the generated class name in your component.\n * function Header() {\n * return <h1 className={classes.root}>Hello World</h1>;\n * }\n * \n * @property {Object} classes - Object mapping each top-level selector key (those matching `/^\\w+$/`)\n * to its generated unique class name string.\n * @property {Object} styles - The original styles object provided to the instance.\n * @property {string} uid - Unique identifier for the StyleSheet instance, generated using `this.generateUid`.\n * @property {string} prefix - Prefix for generating unique identifiers. Resolved to a string when the instance\n * is created (may be supplied as a function via options or a subclass).\n * @property {Object|Function} [attributes] - Optional attributes to be added to the `<style>` element. May be\n * `undefined`, an object, or a function returning the attributes object (evaluated lazily by `getAttributes`).\n * @property {Array} renderers - Array of renderer functions used to process the styles object. Method-name\n * strings passed via options are resolved to methods when the instance is created.\n * @property {HTMLElement} el - Reference to the `<style>` element in the DOM. Created when the instance is attached to the DOM.\n */\nclass StyleSheet {\n constructor(styles, options = {}) {\n this.preinitialize.apply(this, arguments);\n // Styles object.\n this.styles = styles;\n // Original class names object.\n this.classes = {};\n // Set options on the instance.\n styleSheetOptions.forEach(key => {\n if (key in options) this[key] = options[key];\n });\n // Set default renderers.\n this.renderers = this.renderers ?\n getResult(this.renderers, this).map(r => typeof r === 'string' ? this[r] : r) :\n [this.parseStyles, this.renderStyles];\n // Set default prefix.\n this.prefix = this.prefix ? getResult(this.prefix, this) : StyleSheet.prefix;\n // Generate the `StyleSheet` unique identifier.\n this.uid = this.generateUid();\n // Generate class names. Only generate class names for top-level selectors.\n let counter = 0;\n Object.keys(styles).forEach(selector => {\n if (selector.match(StyleSheet.classRegex)) {\n this.classes[selector] = this.generateClassName(selector, ++counter);\n }\n });\n }\n\n /**\n * Hook run at the very start of the constructor, before `styles` and `options`\n * are applied and before `renderers`, `prefix`, `uid` and `classes` are computed.\n * Does nothing by default. Override it in a subclass to run setup logic or define\n * instance properties such as `prefix`, `attributes` or `renderers`. Values set\n * here are still overridden by the matching `options`.\n * @param {Object} styles - The styles object passed to the constructor.\n * @param {Object} [options] - The options object passed to the constructor (may be `undefined`).\n * @returns {void}\n */\n preinitialize() {}\n\n /**\n * Generate a stable unique identifier.\n * May be overridden by `options.generateUid`.\n * @returns {string} The unique identifier.\n */\n generateUid() {\n const styles = JSON.stringify(this.styles);\n // FNV-1a 32-bit offset basis.\n let hash = 2166136261;\n for (let i = 0; i < styles.length; i++) {\n // XOR with the byte value.\n hash ^= styles.charCodeAt(i);\n // Multiply by FNV prime and ensure 32-bit unsigned integer.\n hash = (hash * 16777619) >>> 0;\n }\n // Convert the hash to a shorter base-36 string.\n return hash.toString(36);\n }\n\n /**\n * Generate a unique class name.\n * Transform local selectors that are classes to unique class names\n * to be used as class names in the styles object.\n * May be overridden by `options.generateClassName` or by extending the class.\n * @param {string} className - The class name.\n * @param {number} index - The index of the class name.\n * @returns {string} The unique class name.\n */\n generateClassName(className, index) {\n return __DEV__ && StyleSheet.debug ?\n `${this.prefix}-${this.uid}-${className}` :\n `${this.prefix[0]}-${this.uid}-${index}`;\n }\n\n /**\n * Apply the renderers to the styles object.\n * Renderers are applied in order, starting from `this.styles`, with each renderer\n * receiving the previous one's output and called with the instance as `this`.\n * It will return a string ready to be added to the style element.\n * @returns {string} The styles object as a string.\n */\n render() {\n return this.renderers.reduce((acc, r) => r.call(this, acc), this.styles);\n }\n\n /**\n * Render the styles object as a string.\n * Its one of the default renderers.\n * It will return a string ready to be added to the `style` element.\n * @param {Object} styles - The styles object.\n * @param {number} level - The level of indentation. Used for debugging.\n * @returns {string} The styles object as a string.\n * @private\n */\n renderStyles(styles, level = 1) {\n return Object.keys(styles).reduce((acc, key) => {\n const value = styles[key];\n let indent = '', nl = '', whitespace = '';\n // Format the CSS string.\n if (__DEV__ && StyleSheet.debug) {\n indent = StyleSheet.indent.repeat(level);\n nl = '\\n';\n whitespace = ' ';\n }\n // Add the styles to the accumulator recursively.\n if (isObject(value)) {\n if (Object.keys(value).length > 0) {\n const renderedStyles = this.renderStyles(value, level + 1);\n // Add rules to the accumulator.\n acc.push(`${indent}${key}${whitespace}{${nl}${renderedStyles}${indent}}${nl}`);\n }\n } else if (typeof value !== 'undefined' && value !== null) {\n // Add the style to the accumulator.\n acc.push(`${indent}${key}:${whitespace}${value};${nl}`);\n }\n\n return acc;\n }, []).join('');\n }\n\n /**\n * Parse the styles object and transform it. \n * Expand nested styles, parse global styles, generate selectors, replace selector references \n * and convert camelized keys to dashed-case.\n * Its one of the default renderers.\n * It will return an object ready to be rendered as string by `renderStyles`.\n * @param {Object} styles - The styles object.\n * @param {Object} parent - The parent object. Used for nested styles.\n * @param {string} parentSelector - The parent selector. Used for nested styles.\n * @param {boolean} isGlobal - If true, the styles are global styles.\n * @returns {Object} The styles object.\n * @private\n */\n parseStyles(styles, parent, parentSelector, isGlobal) {\n const fromClasses = selector => selector in this.classes ? `.${this.classes[selector]}` : selector;\n // Parse the key and generate a selector.\n const generateKey = key => {\n if (isGlobal && parentSelector) {\n // Nested global selectors.\n return `${parentSelector} ${key}`;\n }\n if (key.match(StyleSheet.globalPrefixRegex)) {\n // Global prefix and nested global prefix.\n return `${parentSelector ? `${parentSelector} ` : ''}${key.replace(StyleSheet.globalPrefixRegex, '')}`;\n }\n // Nested, references and replace class names with created ones.\n return fromClasses(key)\n .replace(StyleSheet.referenceRegex, (_match, ref) => fromClasses(ref))\n .replace(StyleSheet.nestedRegex, parentSelector);\n };\n\n const result = Object.keys(styles).reduce((acc, key) => {\n const value = styles[key];\n // Parse styles recursively.\n if (isObject(value)) {\n if (key.match(StyleSheet.globalRegex)) {\n // Global and nested global styles.\n Object.assign(parent || acc, this.parseStyles(value, acc, parentSelector, true));\n } else if ((key.match(StyleSheet.nestedRegex) || key.match(StyleSheet.globalPrefixRegex)) && parent) {\n const selector = generateKey(key);\n parent[selector] = {};\n // Nested global prefix and nested styles with reference.\n Object.assign(parent[selector], this.parseStyles(value, parent, selector));\n } else {\n const selector = generateKey(key);\n acc[selector] = {};\n // Don't expand at-rules.\n const args = selector.match(/@/) ? [] : [acc, selector];\n // Regular styles.\n Object.assign(acc[selector], this.parseStyles(value, ...args));\n }\n } else if (typeof value !== 'undefined' && value !== null) {\n // Add style rules.\n // Convert camelCase to dashed-case.\n // Only convert if the key doesn't already contain a dash.\n // Allows css vars to contain camelCase parts between dashes.\n acc[key.match(/-/) ? key : camelizedToDashed(key)] = value;\n }\n\n return acc;\n }, {});\n\n return result;\n }\n\n /**\n * Get the attributes object used to set the attributes on the style element.\n * Starts from `this.attributes`, which is optional and may be `undefined`, an\n * object, or a function returning the attributes object (resolved via `getResult`).\n * The `data-<prefix>-uid` attribute is always added.\n * @returns {Object} The attributes object.\n * @private\n */\n getAttributes() {\n const attributes = Object.assign({}, getResult(this.attributes, this));\n attributes[`data-${this.prefix}-uid`] = this.uid;\n return attributes;\n }\n\n /**\n * Render the StyleSheet as a style element string.\n * Used for server-side rendering.\n * @returns {string} The instance as a string.\n */\n toString() {\n const attributes = this.getAttributes();\n const attributesHtml = Object.keys(attributes).map(key => ` ${key}=\"${attributes[key]}\"`).join('');\n const nl = (__DEV__ && StyleSheet.debug) ? '\\n' : '';\n return `<style${attributesHtml}>${nl}${this.render()}</style>${nl}`;\n }\n\n /**\n * Check if the StyleSheet should be added to the DOM.\n * By default, it returns true if running in a browser environment and no style element\n * with the same `data-fun-uid` attribute exists in the DOM.\n * This prevents duplicate style elements and ensures proper behavior for server-side rendering.\n * May be overridden by `options.shouldAttachToDOM`.\n * @returns {boolean} True if the StyleSheet should be added to the DOM, false otherwise.\n */\n shouldAttachToDOM() {\n return typeof document !== 'undefined' && !document.querySelector(`style[data-${this.prefix}-uid=\"${this.uid}\"]`);\n }\n\n /**\n * Add the instance to the registry and if we are in the browser, \n * attach it to the DOM.\n * @returns {StyleSheet} The instance.\n */\n attach() {\n // Add the instance to the registry if it's not already there.\n if (!StyleSheet.registry.some(({ uid }) => uid === this.uid)) {\n StyleSheet.registry.push(this);\n }\n // If we're in the browser and the style element doesn't exist, create it.\n if (this.shouldAttachToDOM()) {\n // Create the style element.\n this.el = document.createElement('style');\n\n const attributes = this.getAttributes();\n // Set the attributes on the style element.\n Object.keys(attributes).forEach(key => {\n this.el.setAttribute(key, attributes[key]);\n });\n // Render the styles and set the text content of the style element.\n this.el.textContent = this.render();\n // Append the style element to the head.\n document.head.appendChild(this.el);\n }\n\n return this;\n }\n\n /**\n * Destroy the instance and remove it from the registry and \n * from the DOM, if it's present.\n * @returns {StyleSheet} The instance.\n */\n destroy() {\n const index = StyleSheet.registry.indexOf(this);\n // Remove the instance from the registry.\n if (index > -1) {\n StyleSheet.registry.splice(index, 1);\n }\n\n if (this.el) {\n // Remove the style element from the DOM.\n if (this.el.parentNode) {\n this.el.parentNode.removeChild(this.el);\n }\n // Remove the reference to the style element.\n this.el = null;\n }\n\n return this;\n }\n\n /**\n * Render all instances in the registry as a string, including the style tags.\n * Can be used to insert style tags in an HTML template for server-side rendering.\n * @returns {string} All instances in the registry as a string.\n * @static\n */\n static toString() {\n return StyleSheet.registry.join('');\n }\n\n /**\n * Render all instances in the registry as CSS string.\n * Can be used to generate an external CSS file.\n * @returns {string} All instances in the registry rendered as CSS string.\n * @static\n */\n static toCSS() {\n return StyleSheet.registry.map(instance => instance.render()).join('');\n }\n\n /**\n * Destroy all instances in the registry and remove them from \n * it and from the DOM.\n * @static\n */\n static destroy() {\n StyleSheet.registry.slice().forEach(instance => instance.destroy());\n }\n}\n\n/**\n * Regular expressions to match class names.\n * @static\n * @private\n */\nStyleSheet.classRegex = /^\\w+$/;\n\n/**\n * Regular expression to match global styles.\n * @static\n * @private\n */\nStyleSheet.globalRegex = /^@global$/;\n\n/**\n * Regular expression to match global styles with a prefix.\n * @static\n * @private\n */\nStyleSheet.globalPrefixRegex = /^@global\\s+/;\n\n/**\n * Regular expression to match references to other class names.\n * @static\n * @private\n */\nStyleSheet.referenceRegex = /\\$(\\w+)/g;\n\n/**\n * Regular expression to match nested styles.\n * @static\n * @private\n */\nStyleSheet.nestedRegex = /&/g;\n\n/**\n * @static\n * @property {string} prefix - The class prefix. Used to generate unique class names.\n * @default fun\n */\nStyleSheet.prefix = 'fun';\n\n/**\n * @static\n * @property {string} indent - The indent string. Used to format text when debug is enabled.\n * @default ' '\n */\nStyleSheet.indent = ' ';\n\n/**\n * @static\n * @property {Array} registry - The registry array. StyleSheet instances \n * will be added to this array.\n */\nStyleSheet.registry = [];\n\n/**\n * @static\n * @property {boolean} debug - The debug flag. If true, the styles will be formatted with\n * indentation and new lines.\n * @default __DEV__\n */\nStyleSheet.debug = __DEV__;\n\nexport default StyleSheet;\n","/**\n * Development mode flag.\n * This will be replaced during build:\n * - ESM/CJS: replaced with process.env.NODE_ENV !== 'production'\n * - UMD dev: replaced with true\n * - UMD prod: replaced with false\n * @type {boolean}\n * @module\n * @private\n */\nconst __DEV__ = true;\n\nexport default __DEV__;\n","import StyleSheet from './StyleSheet.js';\n\n/**\n * Creates and attaches a new StyleSheet instance to the DOM.\n * \n * @module\n * @function\n * @param {Object} styles - An object containing CSS rules. Keys represent selectors, and values represent style objects.\n * @param {Object} [options] - Optional configuration for the StyleSheet instance. Includes options like `prefix`, `renderers`, and more.\n * @returns {StyleSheet} The created and attached StyleSheet instance. Its `classes` property maps\n * each top-level selector to its generated class name.\n * \n * @example\n * // Create styles for a link component.\n * const { classes } = css({\n * link : {\n * color : 'blue',\n * '&:hover' : {\n * textDecoration : 'underline'\n * }\n * }\n * });\n * \n * // Use the generated `link` class in a component.\n * const Link = ({ label, href }) => <a className={classes.link} href={href}>{label}</a>;\n */\nconst css = (styles, options) => new StyleSheet(styles, options).attach();\n\nexport default css;\n","import css from './css.js';\nimport StyleSheet from './StyleSheet.js';\nimport isObject from './utils/isObject.js';\n\n/**\n * Flattens a nested theme object into a map of CSS variable names to values.\n * Nested keys are joined with `-` (e.g. `{ colors: { primary: 'blue' } }` → `--prefix-colors-primary`).\n * @private\n * @param {Object} [theme={}] - Nested theme object.\n * @param {string|null} [prefix] - Prefix for variable names (e.g. `fun` → `--fun-key`). Omit or pass `null`/`''` for no prefix.\n * @returns {Object} Map of CSS variable names (e.g. `--fun-color`) to values.\n */\nconst makeCssVars = (theme = {}, prefix) => {\n function build(theme, nameAcc) {\n return Object.keys(theme).reduce((acc, key) => {\n const value = theme[key];\n const name = nameAcc ? `${nameAcc}-${key}` : prefix ? `--${prefix}-${key}` : `--${key}`;\n\n if (isObject(value)) {\n Object.assign(acc, build(value, name));\n } else if (typeof value !== 'undefined' && value !== null) {\n acc[name] = value;\n }\n\n return acc;\n }, {});\n }\n return build(theme);\n};\n\n/**\n * Returns keys that differ between two objects, with each side’s value.\n * @private\n * @param {Object} left - First object.\n * @param {Object} right - Second object.\n * @returns {{ left: Object, right: Object }} Objects containing only the differing keys and their values per side.\n */\nconst getDiff = (left, right) => {\n return Object.keys(left).reduce((acc, key) => {\n if (left[key] !== right[key]) {\n acc.left[key] = left[key];\n acc.right[key] = right[key];\n }\n return acc;\n }, { left : {}, right : {} });\n};\n\n/**\n * The `createTheme` function generates a theme StyleSheet instance with CSS variables \n * based on the provided themes and options. It supports multiple color schemes, \n * including `light`, `dark`, `light dark`, and `normal`. \n * \n * The `themes` object defines the styles for these color schemes. Each key in the object \n * corresponds to a color scheme (`light`, `dark`, `normal`), and its value is an object \n * containing key-value pairs that will be converted into CSS variables. Nested keys are \n * concatenated with `-` to form the variable name. For example, `{ light : { colors : { primary : 'blue' } } }` \n * generates `--fun-colors-primary : blue`.\n * \n * @module\n * @function\n * @param {Object} themes - An object defining styles for color schemes (`light`, `dark`, `normal`). \n * Each key corresponds to a color scheme, and its value is an object of key-value pairs converted \n * to CSS variables. Nested keys are concatenated with `-` to form variable names.\n * \n * @param {Object} [options] - An optional object to customize the theme generation. It includes options \n * for selecting color schemes, customizing CSS variable prefixes, and controlling StyleSheet creation.\n * \n * @param {String} [options.colorScheme] - Specifies the color scheme(s) to use. Possible values are: \n * `light` (uses the `light` theme only), `dark` (uses the `dark` theme only), `light dark` (default, \n * supports both `light` and `dark` themes, adapting to system preferences; can override system \n * preference with `data-color-scheme` set to `light` or `dark`), and `normal` (uses the `normal` theme only).\n * \n * @param {String|null} [options.cssVarsPrefix] - Prefix for the generated CSS variables. Defaults to `StyleSheet.prefix`.\n * Pass `null` or `''` to generate variables without a prefix (e.g. `--color` instead of `--fun-color`).\n * \n * @param {Function} [options.createStyleSheet] - A function used to create a new StyleSheet instance. \n * By default, it uses the `css` function.\n * \n * @param {Object} [options.styleSheetOptions] - Options to pass when creating the StyleSheet instance.\n * \n * @returns {StyleSheet} The theme StyleSheet instance. Use `classes.root` to get the theme class name. \n * Apply this class to the element you want to theme. The CSS variables will be available for all \n * its descendants.\n * \n * @example\n * // Create a theme with light and dark color schemes and apply it to the entire page.\n * const theme = createTheme({\n * light : {\n * colorPrimary : 'black',\n * backgroundLevel1 : 'white'\n * },\n * dark : {\n * colorPrimary : 'white',\n * backgroundLevel1 : 'black'\n * }\n * });\n * \n * // Add the `root` class (the theme class) to the body element.\n * // This will apply the theme to the entire page.\n * document.body.classList.add(theme.classes.root);\n * \n * // Add some styles using the theme CSS variables.\n * const { classes } = css({\n * button : {\n * color : 'var(--fun-colorPrimary)', // Use the CSS variable generated from the theme.\n * backgroundColor : 'var(--fun-backgroundLevel1)'\n * }\n * });\n * \n * // Add the `button` class to a button component.\n * // The button will use the CSS variables defined in the theme for its styles.\n * // Once the theme is applied, the button will automatically update its styles.\n * // If the system color scheme changes (e.g., from light to dark), the button will \n * // dynamically update to reflect the new theme without requiring additional code.\n * const Button = ({ label }) => <button className={classes.button}>{label}</button>;\n */\nconst createTheme = (themes = {}, options = {}) => {\n const colorScheme = options.colorScheme || 'light dark';\n const prefix = 'cssVarsPrefix' in options ? options.cssVarsPrefix : StyleSheet.prefix;\n\n let styles;\n\n if (colorScheme === 'light dark') {\n const cssVars = {\n light : makeCssVars(themes.light, prefix),\n dark : makeCssVars(themes.dark, prefix)\n };\n\n const diff = getDiff(cssVars.light, cssVars.dark);\n\n styles = {\n root : {\n ':where(&)' : Object.assign({ colorScheme : 'light' }, cssVars.light),\n ':where([data-color-scheme=\"dark\"] &)' : Object.assign({ colorScheme : 'dark' }, diff.right),\n },\n '@media (prefers-color-scheme: dark)' : {\n ':where($root)' : Object.assign({ colorScheme : 'dark' }, diff.right),\n ':where([data-color-scheme=\"light\"] $root)' : Object.assign({ colorScheme : 'light' }, diff.left)\n }\n };\n } else {\n styles = {\n root : {\n ':where(&)' : Object.assign({ colorScheme }, makeCssVars(themes[colorScheme], prefix))\n }\n };\n }\n\n return (options.createStyleSheet || css)(styles, options.styleSheetOptions);\n};\n\nexport default createTheme;\n"],"names":["isObject","value","Array","isArray","getResult","expression","context","call","styleSheetOptions","StyleSheet","constructor","styles","options","this","preinitialize","apply","arguments","classes","forEach","key","renderers","map","r","parseStyles","renderStyles","prefix","uid","generateUid","counter","Object","keys","selector","match","classRegex","generateClassName","JSON","stringify","hash","i","length","charCodeAt","toString","className","index","render","reduce","acc","level","renderedStyles","push","join","parent","parentSelector","isGlobal","fromClasses","generateKey","globalPrefixRegex","replace","referenceRegex","_match","ref","nestedRegex","globalRegex","assign","args","str","g","toLowerCase","getAttributes","attributes","shouldAttachToDOM","document","querySelector","attach","registry","some","el","createElement","setAttribute","textContent","head","appendChild","destroy","indexOf","splice","parentNode","removeChild","toCSS","instance","slice","indent","debug","css","makeCssVars","theme","build","nameAcc","name","themes","colorScheme","cssVarsPrefix","cssVars","light","dark","diff","left","right","root","createStyleSheet"],"mappings":"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"}

@@ -80,4 +80,3 @@ import StyleSheet from './StyleSheet.js';

*
* @param {Object} [options.styleSheetOptions] - Options to pass when creating the StyleSheet instance.
* Default is `system`.
* @param {Object} [options.styleSheetOptions] - Options to pass when creating the StyleSheet instance.
*

@@ -84,0 +83,0 @@ * @returns {StyleSheet} The theme StyleSheet instance. Use `classes.root` to get the theme class name.

@@ -1,1 +0,1 @@

{"version":3,"file":"createTheme.js","sources":["../src/createTheme.js"],"sourcesContent":["import css from './css.js';\nimport StyleSheet from './StyleSheet.js';\nimport isObject from './utils/isObject.js';\n\n/**\n * Flattens a nested theme object into a map of CSS variable names to values.\n * Nested keys are joined with `-` (e.g. `{ colors: { primary: 'blue' } }` → `--prefix-colors-primary`).\n * @private\n * @param {Object} [theme={}] - Nested theme object.\n * @param {string|null} [prefix] - Prefix for variable names (e.g. `fun` → `--fun-key`). Omit or pass `null`/`''` for no prefix.\n * @returns {Object} Map of CSS variable names (e.g. `--fun-color`) to values.\n */\nconst makeCssVars = (theme = {}, prefix) => {\n function build(theme, nameAcc) {\n return Object.keys(theme).reduce((acc, key) => {\n const value = theme[key];\n const name = nameAcc ? `${nameAcc}-${key}` : prefix ? `--${prefix}-${key}` : `--${key}`;\n\n if (isObject(value)) {\n Object.assign(acc, build(value, name));\n } else if (typeof value !== 'undefined' && value !== null) {\n acc[name] = value;\n }\n\n return acc;\n }, {});\n }\n return build(theme);\n};\n\n/**\n * Returns keys that differ between two objects, with each side’s value.\n * @private\n * @param {Object} left - First object.\n * @param {Object} right - Second object.\n * @returns {{ left: Object, right: Object }} Objects containing only the differing keys and their values per side.\n */\nconst getDiff = (left, right) => {\n return Object.keys(left).reduce((acc, key) => {\n if (left[key] !== right[key]) {\n acc.left[key] = left[key];\n acc.right[key] = right[key];\n }\n return acc;\n }, { left : {}, right : {} });\n};\n\n/**\n * The `createTheme` function generates a theme StyleSheet instance with CSS variables \n * based on the provided themes and options. It supports multiple color schemes, \n * including `light`, `dark`, `light dark`, and `normal`. \n * \n * The `themes` object defines the styles for these color schemes. Each key in the object \n * corresponds to a color scheme (`light`, `dark`, `normal`), and its value is an object \n * containing key-value pairs that will be converted into CSS variables. Nested keys are \n * concatenated with `-` to form the variable name. For example, `{ light : { colors : { primary : 'blue' } } }` \n * generates `--fun-colors-primary : blue`.\n * \n * @module\n * @function\n * @param {Object} themes - An object defining styles for color schemes (`light`, `dark`, `normal`). \n * Each key corresponds to a color scheme, and its value is an object of key-value pairs converted \n * to CSS variables. Nested keys are concatenated with `-` to form variable names.\n * \n * @param {Object} [options] - An optional object to customize the theme generation. It includes options \n * for selecting color schemes, customizing CSS variable prefixes, and controlling StyleSheet creation.\n * \n * @param {String} [options.colorScheme] - Specifies the color scheme(s) to use. Possible values are: \n * `light` (uses the `light` theme only), `dark` (uses the `dark` theme only), `light dark` (default, \n * supports both `light` and `dark` themes, adapting to system preferences; can override system \n * preference with `data-color-scheme` set to `light` or `dark`), and `normal` (uses the `normal` theme only).\n * \n * @param {String|null} [options.cssVarsPrefix] - Prefix for the generated CSS variables. Defaults to `StyleSheet.prefix`.\n * Pass `null` or `''` to generate variables without a prefix (e.g. `--color` instead of `--fun-color`).\n * \n * @param {Function} [options.createStyleSheet] - A function used to create a new StyleSheet instance. \n * By default, it uses the `css` function.\n * \n * @param {Object} [options.styleSheetOptions] - Options to pass when creating the StyleSheet instance. \n * Default is `system`.\n * \n * @returns {StyleSheet} The theme StyleSheet instance. Use `classes.root` to get the theme class name. \n * Apply this class to the element you want to theme. The CSS variables will be available for all \n * its descendants.\n * \n * @example\n * // Create a theme with light and dark color schemes and apply it to the entire page.\n * const theme = createTheme({\n * light : {\n * colorPrimary : 'black',\n * backgroundLevel1 : 'white'\n * },\n * dark : {\n * colorPrimary : 'white',\n * backgroundLevel1 : 'black'\n * }\n * });\n * \n * // Add the `root` class (the theme class) to the body element.\n * // This will apply the theme to the entire page.\n * document.body.classList.add(theme.classes.root);\n * \n * // Add some styles using the theme CSS variables.\n * const { classes } = css({\n * button : {\n * color : 'var(--fun-colorPrimary)', // Use the CSS variable generated from the theme.\n * backgroundColor : 'var(--fun-backgroundLevel1)'\n * }\n * });\n * \n * // Add the `button` class to a button component.\n * // The button will use the CSS variables defined in the theme for its styles.\n * // Once the theme is applied, the button will automatically update its styles.\n * // If the system color scheme changes (e.g., from light to dark), the button will \n * // dynamically update to reflect the new theme without requiring additional code.\n * const Button = ({ label }) => <button className={classes.button}>{label}</button>;\n */\nconst createTheme = (themes = {}, options = {}) => {\n const colorScheme = options.colorScheme || 'light dark';\n const prefix = 'cssVarsPrefix' in options ? options.cssVarsPrefix : StyleSheet.prefix;\n\n let styles;\n\n if (colorScheme === 'light dark') {\n const cssVars = {\n light : makeCssVars(themes.light, prefix),\n dark : makeCssVars(themes.dark, prefix)\n };\n\n const diff = getDiff(cssVars.light, cssVars.dark);\n\n styles = {\n root : {\n ':where(&)' : Object.assign({ colorScheme : 'light' }, cssVars.light),\n ':where([data-color-scheme=\"dark\"] &)' : Object.assign({ colorScheme : 'dark' }, diff.right),\n },\n '@media (prefers-color-scheme: dark)' : {\n ':where($root)' : Object.assign({ colorScheme : 'dark' }, diff.right),\n ':where([data-color-scheme=\"light\"] $root)' : Object.assign({ colorScheme : 'light' }, diff.left)\n }\n };\n } else {\n styles = {\n root : {\n ':where(&)' : Object.assign({ colorScheme }, makeCssVars(themes[colorScheme], prefix))\n }\n };\n }\n\n return (options.createStyleSheet || css)(styles, options.styleSheetOptions);\n};\n\nexport default createTheme;\n"],"names":[],"mappings":"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"}
{"version":3,"file":"createTheme.js","sources":["../src/createTheme.js"],"sourcesContent":["import css from './css.js';\nimport StyleSheet from './StyleSheet.js';\nimport isObject from './utils/isObject.js';\n\n/**\n * Flattens a nested theme object into a map of CSS variable names to values.\n * Nested keys are joined with `-` (e.g. `{ colors: { primary: 'blue' } }` → `--prefix-colors-primary`).\n * @private\n * @param {Object} [theme={}] - Nested theme object.\n * @param {string|null} [prefix] - Prefix for variable names (e.g. `fun` → `--fun-key`). Omit or pass `null`/`''` for no prefix.\n * @returns {Object} Map of CSS variable names (e.g. `--fun-color`) to values.\n */\nconst makeCssVars = (theme = {}, prefix) => {\n function build(theme, nameAcc) {\n return Object.keys(theme).reduce((acc, key) => {\n const value = theme[key];\n const name = nameAcc ? `${nameAcc}-${key}` : prefix ? `--${prefix}-${key}` : `--${key}`;\n\n if (isObject(value)) {\n Object.assign(acc, build(value, name));\n } else if (typeof value !== 'undefined' && value !== null) {\n acc[name] = value;\n }\n\n return acc;\n }, {});\n }\n return build(theme);\n};\n\n/**\n * Returns keys that differ between two objects, with each side’s value.\n * @private\n * @param {Object} left - First object.\n * @param {Object} right - Second object.\n * @returns {{ left: Object, right: Object }} Objects containing only the differing keys and their values per side.\n */\nconst getDiff = (left, right) => {\n return Object.keys(left).reduce((acc, key) => {\n if (left[key] !== right[key]) {\n acc.left[key] = left[key];\n acc.right[key] = right[key];\n }\n return acc;\n }, { left : {}, right : {} });\n};\n\n/**\n * The `createTheme` function generates a theme StyleSheet instance with CSS variables \n * based on the provided themes and options. It supports multiple color schemes, \n * including `light`, `dark`, `light dark`, and `normal`. \n * \n * The `themes` object defines the styles for these color schemes. Each key in the object \n * corresponds to a color scheme (`light`, `dark`, `normal`), and its value is an object \n * containing key-value pairs that will be converted into CSS variables. Nested keys are \n * concatenated with `-` to form the variable name. For example, `{ light : { colors : { primary : 'blue' } } }` \n * generates `--fun-colors-primary : blue`.\n * \n * @module\n * @function\n * @param {Object} themes - An object defining styles for color schemes (`light`, `dark`, `normal`). \n * Each key corresponds to a color scheme, and its value is an object of key-value pairs converted \n * to CSS variables. Nested keys are concatenated with `-` to form variable names.\n * \n * @param {Object} [options] - An optional object to customize the theme generation. It includes options \n * for selecting color schemes, customizing CSS variable prefixes, and controlling StyleSheet creation.\n * \n * @param {String} [options.colorScheme] - Specifies the color scheme(s) to use. Possible values are: \n * `light` (uses the `light` theme only), `dark` (uses the `dark` theme only), `light dark` (default, \n * supports both `light` and `dark` themes, adapting to system preferences; can override system \n * preference with `data-color-scheme` set to `light` or `dark`), and `normal` (uses the `normal` theme only).\n * \n * @param {String|null} [options.cssVarsPrefix] - Prefix for the generated CSS variables. Defaults to `StyleSheet.prefix`.\n * Pass `null` or `''` to generate variables without a prefix (e.g. `--color` instead of `--fun-color`).\n * \n * @param {Function} [options.createStyleSheet] - A function used to create a new StyleSheet instance. \n * By default, it uses the `css` function.\n * \n * @param {Object} [options.styleSheetOptions] - Options to pass when creating the StyleSheet instance.\n * \n * @returns {StyleSheet} The theme StyleSheet instance. Use `classes.root` to get the theme class name. \n * Apply this class to the element you want to theme. The CSS variables will be available for all \n * its descendants.\n * \n * @example\n * // Create a theme with light and dark color schemes and apply it to the entire page.\n * const theme = createTheme({\n * light : {\n * colorPrimary : 'black',\n * backgroundLevel1 : 'white'\n * },\n * dark : {\n * colorPrimary : 'white',\n * backgroundLevel1 : 'black'\n * }\n * });\n * \n * // Add the `root` class (the theme class) to the body element.\n * // This will apply the theme to the entire page.\n * document.body.classList.add(theme.classes.root);\n * \n * // Add some styles using the theme CSS variables.\n * const { classes } = css({\n * button : {\n * color : 'var(--fun-colorPrimary)', // Use the CSS variable generated from the theme.\n * backgroundColor : 'var(--fun-backgroundLevel1)'\n * }\n * });\n * \n * // Add the `button` class to a button component.\n * // The button will use the CSS variables defined in the theme for its styles.\n * // Once the theme is applied, the button will automatically update its styles.\n * // If the system color scheme changes (e.g., from light to dark), the button will \n * // dynamically update to reflect the new theme without requiring additional code.\n * const Button = ({ label }) => <button className={classes.button}>{label}</button>;\n */\nconst createTheme = (themes = {}, options = {}) => {\n const colorScheme = options.colorScheme || 'light dark';\n const prefix = 'cssVarsPrefix' in options ? options.cssVarsPrefix : StyleSheet.prefix;\n\n let styles;\n\n if (colorScheme === 'light dark') {\n const cssVars = {\n light : makeCssVars(themes.light, prefix),\n dark : makeCssVars(themes.dark, prefix)\n };\n\n const diff = getDiff(cssVars.light, cssVars.dark);\n\n styles = {\n root : {\n ':where(&)' : Object.assign({ colorScheme : 'light' }, cssVars.light),\n ':where([data-color-scheme=\"dark\"] &)' : Object.assign({ colorScheme : 'dark' }, diff.right),\n },\n '@media (prefers-color-scheme: dark)' : {\n ':where($root)' : Object.assign({ colorScheme : 'dark' }, diff.right),\n ':where([data-color-scheme=\"light\"] $root)' : Object.assign({ colorScheme : 'light' }, diff.left)\n }\n };\n } else {\n styles = {\n root : {\n ':where(&)' : Object.assign({ colorScheme }, makeCssVars(themes[colorScheme], prefix))\n }\n };\n }\n\n return (options.createStyleSheet || css)(styles, options.styleSheetOptions);\n};\n\nexport default createTheme;\n"],"names":[],"mappings":"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"}

@@ -82,4 +82,3 @@ 'use strict';

*
* @param {Object} [options.styleSheetOptions] - Options to pass when creating the StyleSheet instance.
* Default is `system`.
* @param {Object} [options.styleSheetOptions] - Options to pass when creating the StyleSheet instance.
*

@@ -86,0 +85,0 @@ * @returns {StyleSheet} The theme StyleSheet instance. Use `classes.root` to get the theme class name.

@@ -1,1 +0,1 @@

{"version":3,"file":"createTheme.cjs","sources":["../src/createTheme.js"],"sourcesContent":["import css from './css.js';\nimport StyleSheet from './StyleSheet.js';\nimport isObject from './utils/isObject.js';\n\n/**\n * Flattens a nested theme object into a map of CSS variable names to values.\n * Nested keys are joined with `-` (e.g. `{ colors: { primary: 'blue' } }` → `--prefix-colors-primary`).\n * @private\n * @param {Object} [theme={}] - Nested theme object.\n * @param {string|null} [prefix] - Prefix for variable names (e.g. `fun` → `--fun-key`). Omit or pass `null`/`''` for no prefix.\n * @returns {Object} Map of CSS variable names (e.g. `--fun-color`) to values.\n */\nconst makeCssVars = (theme = {}, prefix) => {\n function build(theme, nameAcc) {\n return Object.keys(theme).reduce((acc, key) => {\n const value = theme[key];\n const name = nameAcc ? `${nameAcc}-${key}` : prefix ? `--${prefix}-${key}` : `--${key}`;\n\n if (isObject(value)) {\n Object.assign(acc, build(value, name));\n } else if (typeof value !== 'undefined' && value !== null) {\n acc[name] = value;\n }\n\n return acc;\n }, {});\n }\n return build(theme);\n};\n\n/**\n * Returns keys that differ between two objects, with each side’s value.\n * @private\n * @param {Object} left - First object.\n * @param {Object} right - Second object.\n * @returns {{ left: Object, right: Object }} Objects containing only the differing keys and their values per side.\n */\nconst getDiff = (left, right) => {\n return Object.keys(left).reduce((acc, key) => {\n if (left[key] !== right[key]) {\n acc.left[key] = left[key];\n acc.right[key] = right[key];\n }\n return acc;\n }, { left : {}, right : {} });\n};\n\n/**\n * The `createTheme` function generates a theme StyleSheet instance with CSS variables \n * based on the provided themes and options. It supports multiple color schemes, \n * including `light`, `dark`, `light dark`, and `normal`. \n * \n * The `themes` object defines the styles for these color schemes. Each key in the object \n * corresponds to a color scheme (`light`, `dark`, `normal`), and its value is an object \n * containing key-value pairs that will be converted into CSS variables. Nested keys are \n * concatenated with `-` to form the variable name. For example, `{ light : { colors : { primary : 'blue' } } }` \n * generates `--fun-colors-primary : blue`.\n * \n * @module\n * @function\n * @param {Object} themes - An object defining styles for color schemes (`light`, `dark`, `normal`). \n * Each key corresponds to a color scheme, and its value is an object of key-value pairs converted \n * to CSS variables. Nested keys are concatenated with `-` to form variable names.\n * \n * @param {Object} [options] - An optional object to customize the theme generation. It includes options \n * for selecting color schemes, customizing CSS variable prefixes, and controlling StyleSheet creation.\n * \n * @param {String} [options.colorScheme] - Specifies the color scheme(s) to use. Possible values are: \n * `light` (uses the `light` theme only), `dark` (uses the `dark` theme only), `light dark` (default, \n * supports both `light` and `dark` themes, adapting to system preferences; can override system \n * preference with `data-color-scheme` set to `light` or `dark`), and `normal` (uses the `normal` theme only).\n * \n * @param {String|null} [options.cssVarsPrefix] - Prefix for the generated CSS variables. Defaults to `StyleSheet.prefix`.\n * Pass `null` or `''` to generate variables without a prefix (e.g. `--color` instead of `--fun-color`).\n * \n * @param {Function} [options.createStyleSheet] - A function used to create a new StyleSheet instance. \n * By default, it uses the `css` function.\n * \n * @param {Object} [options.styleSheetOptions] - Options to pass when creating the StyleSheet instance. \n * Default is `system`.\n * \n * @returns {StyleSheet} The theme StyleSheet instance. Use `classes.root` to get the theme class name. \n * Apply this class to the element you want to theme. The CSS variables will be available for all \n * its descendants.\n * \n * @example\n * // Create a theme with light and dark color schemes and apply it to the entire page.\n * const theme = createTheme({\n * light : {\n * colorPrimary : 'black',\n * backgroundLevel1 : 'white'\n * },\n * dark : {\n * colorPrimary : 'white',\n * backgroundLevel1 : 'black'\n * }\n * });\n * \n * // Add the `root` class (the theme class) to the body element.\n * // This will apply the theme to the entire page.\n * document.body.classList.add(theme.classes.root);\n * \n * // Add some styles using the theme CSS variables.\n * const { classes } = css({\n * button : {\n * color : 'var(--fun-colorPrimary)', // Use the CSS variable generated from the theme.\n * backgroundColor : 'var(--fun-backgroundLevel1)'\n * }\n * });\n * \n * // Add the `button` class to a button component.\n * // The button will use the CSS variables defined in the theme for its styles.\n * // Once the theme is applied, the button will automatically update its styles.\n * // If the system color scheme changes (e.g., from light to dark), the button will \n * // dynamically update to reflect the new theme without requiring additional code.\n * const Button = ({ label }) => <button className={classes.button}>{label}</button>;\n */\nconst createTheme = (themes = {}, options = {}) => {\n const colorScheme = options.colorScheme || 'light dark';\n const prefix = 'cssVarsPrefix' in options ? options.cssVarsPrefix : StyleSheet.prefix;\n\n let styles;\n\n if (colorScheme === 'light dark') {\n const cssVars = {\n light : makeCssVars(themes.light, prefix),\n dark : makeCssVars(themes.dark, prefix)\n };\n\n const diff = getDiff(cssVars.light, cssVars.dark);\n\n styles = {\n root : {\n ':where(&)' : Object.assign({ colorScheme : 'light' }, cssVars.light),\n ':where([data-color-scheme=\"dark\"] &)' : Object.assign({ colorScheme : 'dark' }, diff.right),\n },\n '@media (prefers-color-scheme: dark)' : {\n ':where($root)' : Object.assign({ colorScheme : 'dark' }, diff.right),\n ':where([data-color-scheme=\"light\"] $root)' : Object.assign({ colorScheme : 'light' }, diff.left)\n }\n };\n } else {\n styles = {\n root : {\n ':where(&)' : Object.assign({ colorScheme }, makeCssVars(themes[colorScheme], prefix))\n }\n };\n }\n\n return (options.createStyleSheet || css)(styles, options.styleSheetOptions);\n};\n\nexport default createTheme;\n"],"names":["isObject"],"mappings":"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"}
{"version":3,"file":"createTheme.cjs","sources":["../src/createTheme.js"],"sourcesContent":["import css from './css.js';\nimport StyleSheet from './StyleSheet.js';\nimport isObject from './utils/isObject.js';\n\n/**\n * Flattens a nested theme object into a map of CSS variable names to values.\n * Nested keys are joined with `-` (e.g. `{ colors: { primary: 'blue' } }` → `--prefix-colors-primary`).\n * @private\n * @param {Object} [theme={}] - Nested theme object.\n * @param {string|null} [prefix] - Prefix for variable names (e.g. `fun` → `--fun-key`). Omit or pass `null`/`''` for no prefix.\n * @returns {Object} Map of CSS variable names (e.g. `--fun-color`) to values.\n */\nconst makeCssVars = (theme = {}, prefix) => {\n function build(theme, nameAcc) {\n return Object.keys(theme).reduce((acc, key) => {\n const value = theme[key];\n const name = nameAcc ? `${nameAcc}-${key}` : prefix ? `--${prefix}-${key}` : `--${key}`;\n\n if (isObject(value)) {\n Object.assign(acc, build(value, name));\n } else if (typeof value !== 'undefined' && value !== null) {\n acc[name] = value;\n }\n\n return acc;\n }, {});\n }\n return build(theme);\n};\n\n/**\n * Returns keys that differ between two objects, with each side’s value.\n * @private\n * @param {Object} left - First object.\n * @param {Object} right - Second object.\n * @returns {{ left: Object, right: Object }} Objects containing only the differing keys and their values per side.\n */\nconst getDiff = (left, right) => {\n return Object.keys(left).reduce((acc, key) => {\n if (left[key] !== right[key]) {\n acc.left[key] = left[key];\n acc.right[key] = right[key];\n }\n return acc;\n }, { left : {}, right : {} });\n};\n\n/**\n * The `createTheme` function generates a theme StyleSheet instance with CSS variables \n * based on the provided themes and options. It supports multiple color schemes, \n * including `light`, `dark`, `light dark`, and `normal`. \n * \n * The `themes` object defines the styles for these color schemes. Each key in the object \n * corresponds to a color scheme (`light`, `dark`, `normal`), and its value is an object \n * containing key-value pairs that will be converted into CSS variables. Nested keys are \n * concatenated with `-` to form the variable name. For example, `{ light : { colors : { primary : 'blue' } } }` \n * generates `--fun-colors-primary : blue`.\n * \n * @module\n * @function\n * @param {Object} themes - An object defining styles for color schemes (`light`, `dark`, `normal`). \n * Each key corresponds to a color scheme, and its value is an object of key-value pairs converted \n * to CSS variables. Nested keys are concatenated with `-` to form variable names.\n * \n * @param {Object} [options] - An optional object to customize the theme generation. It includes options \n * for selecting color schemes, customizing CSS variable prefixes, and controlling StyleSheet creation.\n * \n * @param {String} [options.colorScheme] - Specifies the color scheme(s) to use. Possible values are: \n * `light` (uses the `light` theme only), `dark` (uses the `dark` theme only), `light dark` (default, \n * supports both `light` and `dark` themes, adapting to system preferences; can override system \n * preference with `data-color-scheme` set to `light` or `dark`), and `normal` (uses the `normal` theme only).\n * \n * @param {String|null} [options.cssVarsPrefix] - Prefix for the generated CSS variables. Defaults to `StyleSheet.prefix`.\n * Pass `null` or `''` to generate variables without a prefix (e.g. `--color` instead of `--fun-color`).\n * \n * @param {Function} [options.createStyleSheet] - A function used to create a new StyleSheet instance. \n * By default, it uses the `css` function.\n * \n * @param {Object} [options.styleSheetOptions] - Options to pass when creating the StyleSheet instance.\n * \n * @returns {StyleSheet} The theme StyleSheet instance. Use `classes.root` to get the theme class name. \n * Apply this class to the element you want to theme. The CSS variables will be available for all \n * its descendants.\n * \n * @example\n * // Create a theme with light and dark color schemes and apply it to the entire page.\n * const theme = createTheme({\n * light : {\n * colorPrimary : 'black',\n * backgroundLevel1 : 'white'\n * },\n * dark : {\n * colorPrimary : 'white',\n * backgroundLevel1 : 'black'\n * }\n * });\n * \n * // Add the `root` class (the theme class) to the body element.\n * // This will apply the theme to the entire page.\n * document.body.classList.add(theme.classes.root);\n * \n * // Add some styles using the theme CSS variables.\n * const { classes } = css({\n * button : {\n * color : 'var(--fun-colorPrimary)', // Use the CSS variable generated from the theme.\n * backgroundColor : 'var(--fun-backgroundLevel1)'\n * }\n * });\n * \n * // Add the `button` class to a button component.\n * // The button will use the CSS variables defined in the theme for its styles.\n * // Once the theme is applied, the button will automatically update its styles.\n * // If the system color scheme changes (e.g., from light to dark), the button will \n * // dynamically update to reflect the new theme without requiring additional code.\n * const Button = ({ label }) => <button className={classes.button}>{label}</button>;\n */\nconst createTheme = (themes = {}, options = {}) => {\n const colorScheme = options.colorScheme || 'light dark';\n const prefix = 'cssVarsPrefix' in options ? options.cssVarsPrefix : StyleSheet.prefix;\n\n let styles;\n\n if (colorScheme === 'light dark') {\n const cssVars = {\n light : makeCssVars(themes.light, prefix),\n dark : makeCssVars(themes.dark, prefix)\n };\n\n const diff = getDiff(cssVars.light, cssVars.dark);\n\n styles = {\n root : {\n ':where(&)' : Object.assign({ colorScheme : 'light' }, cssVars.light),\n ':where([data-color-scheme=\"dark\"] &)' : Object.assign({ colorScheme : 'dark' }, diff.right),\n },\n '@media (prefers-color-scheme: dark)' : {\n ':where($root)' : Object.assign({ colorScheme : 'dark' }, diff.right),\n ':where([data-color-scheme=\"light\"] $root)' : Object.assign({ colorScheme : 'light' }, diff.left)\n }\n };\n } else {\n styles = {\n root : {\n ':where(&)' : Object.assign({ colorScheme }, makeCssVars(themes[colorScheme], prefix))\n }\n };\n }\n\n return (options.createStyleSheet || css)(styles, options.styleSheetOptions);\n};\n\nexport default createTheme;\n"],"names":["isObject"],"mappings":"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"}
{
"name": "cssfun",
"version": "0.1.0-alpha.2",
"version": "0.1.0-alpha.3",
"description": "Near-zero runtime CSS-in-JS library",

@@ -5,0 +5,0 @@ "type": "module",

+10
-12
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://cdn.jsdelivr.net/gh/8tentaculos/cssfun@v0.1.0-alpha.2/docs/logo-dark.svg">
<img alt="CSSFUN" src="https://cdn.jsdelivr.net/gh/8tentaculos/cssfun@v0.1.0-alpha.2/docs/logo.svg">
<source media="(prefers-color-scheme: dark)" srcset="https://cdn.jsdelivr.net/gh/8tentaculos/cssfun@v0.1.0-alpha.3/docs/logo-dark.svg">
<img alt="CSSFUN" src="https://cdn.jsdelivr.net/gh/8tentaculos/cssfun@v0.1.0-alpha.3/docs/logo.svg">
</picture>

@@ -521,6 +521,4 @@ </p>

const html = renderToString(<App />);
// Get generated styles as string
const styles = StyleSheet.toString();
// Get theme root class

@@ -590,3 +588,3 @@ const cls = theme.classes.root;

**CSSFUN** ships with TypeScript declarations out of the box — no `@types/cssfun` needed. The types are bundled in the package and resolved automatically via the `types` field in `package.json`.
**CSSFUN** ships with TypeScript declarations out of the box. The types are bundled in the package and resolved automatically.

@@ -612,6 +610,4 @@ > Requires **TypeScript 4.1+** (the `classes` inference relies on key remapping and template literal types).

At-rule keys (`@global`, `@keyframes …`, `@media …`, `@supports …`) and class reference keys (`$name`) are filtered out of `classes` automatically — they don't produce class names at runtime, so they don't appear in the type either.
Only top-level keys that are valid class-name identifiers (letters, digits and underscores — i.e. matching `/^\w+$/`) get a generated class at runtime, and the type mirrors that: at-rule keys (`@global`, `@keyframes …`, `@media …`, `@supports …`), class reference keys (`$name`) and keys containing selector syntax (dashes, spaces, `&`, `:`, etc.) are filtered out of `classes` automatically — they don't produce class names at runtime, so they don't appear in the type either.
Only top-level keys that are valid class-name identifiers (letters, digits and underscores — i.e. matching `/^\w+$/`) get a generated class at runtime. The type can't fully express that pattern, so keys with dashes, spaces or commas (e.g. `'my-card'`) appear in `classes` as `string` but resolve to `undefined` at runtime. Stick to simple identifiers for top-level class keys.
### CSS property autocomplete

@@ -625,5 +621,5 @@

color : 'red',
backgroundColor : null, // ok — filtered at runtime
margin : undefined, // ok
padding : 10, // numbers accepted for length props
backgroundColor : null, // ok — filtered at runtime
margin : undefined, // ok
padding : 10, // numbers accepted for length props
},

@@ -654,2 +650,4 @@ root : {

StyleSheetOptions,
RendererFn,
Resolvable,
ThemeDefinition,

@@ -671,3 +669,3 @@ ThemeVars,

The `examples` folder contains various sample projects demonstrating how to use **CSSFUN** in
The `example` folder contains various sample projects demonstrating how to use **CSSFUN** in
different environments and frameworks. Each example is a standalone project that you can run locally

@@ -674,0 +672,0 @@ to see **CSSFUN** in action.

@@ -79,4 +79,3 @@ import css from './css.js';

*
* @param {Object} [options.styleSheetOptions] - Options to pass when creating the StyleSheet instance.
* Default is `system`.
* @param {Object} [options.styleSheetOptions] - Options to pass when creating the StyleSheet instance.
*

@@ -83,0 +82,0 @@ * @returns {StyleSheet} The theme StyleSheet instance. Use `classes.root` to get the theme class name.

import StyleSheet from './StyleSheet';
import type { StyleRule, Styles, StyleSheetOptions } from './StyleSheet';
/** A recursive theme variables object. Nested keys are joined with `-` to form CSS variable names. */
/**
* A recursive theme variables object. Nested keys are joined with `-` to form CSS
* variable names. `null`/`undefined` values are accepted and filtered at runtime.
*/
export interface ThemeVars {
[key: string]: string | number | ThemeVars;
[key: string]: string | number | ThemeVars | null | undefined;
}

@@ -8,0 +11,0 @@

export { default as StyleSheet } from './StyleSheet';
export type { CSSValue, CSSProperties, StyleRule, Styles, StyleSheetOptions } from './StyleSheet';
export type { CSSValue, CSSProperties, StyleRule, Styles, StyleSheetOptions, RendererFn, Resolvable } from './StyleSheet';
export { default as css } from './css';
export { default as createTheme } from './createTheme';
export type { ThemeVars, ThemeDefinition, CreateThemeOptions } from './createTheme';

@@ -29,7 +29,16 @@ import type { Properties } from 'csstype';

/** A renderer function: receives the current value and returns the next, called with the StyleSheet as `this`. */
type RendererFn = (this: StyleSheet<any>, styles: any) => any;
export type RendererFn = (this: StyleSheet<any>, styles: any) => any;
/** A value provided directly or as a function returning it (called with the StyleSheet as `this`). */
type Resolvable<T> = T | ((this: StyleSheet<any>) => T);
export type Resolvable<T> = T | ((this: StyleSheet<any>) => T);
/**
* Characters that can't appear in a top-level class key. At runtime only keys
* matching `/^\w+$/` produce a class name; keys containing any selector
* syntax (dashes, spaces, combinators, at-rules, references, etc.) don't.
*/
type InvalidClassChar =
| '-' | ' ' | '.' | ',' | ':' | '&' | '>' | '+' | '~'
| '*' | '[' | ']' | '(' | ')' | '#' | '@' | '$' | '%' | '"' | "'" | '=' | '|' | '^';
/** Options for the StyleSheet constructor. Accepts custom keys for subclasses and custom renderers. */

@@ -86,8 +95,9 @@ export interface StyleSheetOptions {

* generated unique class name string.
* At-rule keys (`@global`, `@keyframes …`, `@media …`, `@supports …`)
* and class reference keys (`$name`) are excluded — they don't produce
* class names at runtime.
* Keys containing selector syntax — at-rules (`@global`, `@keyframes …`,
* `@media …`, `@supports …`), class references (`$name`) and keys with
* dashes, spaces or other special characters — are excluded, matching
* the runtime behavior: they don't produce class names.
*/
readonly classes: {
readonly [K in keyof S as K extends `@${string}` | `$${string}` ? never : K]: string;
readonly [K in keyof S as K extends `${string}${InvalidClassChar}${string}` ? never : K & string]: string;
};

@@ -94,0 +104,0 @@ /** The original styles object provided to the instance. */

Sorry, the diff of this file is too big to display