🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

cssfun

Package Overview
Dependencies
Maintainers
1
Versions
16
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.1
to
0.1.0-alpha.2
+77
-38
dist/cssfun.js

@@ -29,5 +29,23 @@ (function (global, factory) {

/**
* Convert a camelized string to a dashed string.
* @param {string} str String to be converted.
* @return {string} The converted string.
* @private
*/
const camelizedToDashed = str => str.replace(/([A-Z])/g, (g) => `-${g[0].toLowerCase()}`);
const compose = fns => fns.reduce((f, g) => (...args) => f(g(...args)));
/**
* Resolve a value that may be provided directly or as a function.
* If it's a function, call it with the provided context and return the result.
* Otherwise, return the value as is.
* @param {*} expression Value or function to be resolved.
* @param {*} context Context (`this`) to call the function with.
* @return {*} The resolved value.
* @private
*/
const getResult = (expression, context) =>
typeof expression !== 'function' ? expression :
expression.call(context);
const styleSheetOptions = ['prefix', 'generateUid', 'generateClassName', 'shouldAttachToDOM', 'attributes', 'renderers'];

@@ -48,8 +66,11 @@

* `prefix`, `generateUid`, `generateClassName`, `shouldAttachToDOM`, `attributes`, `renderers`.
* @param {String} [options.prefix='fun'] - Prefix for generating unique identifiers and data attributes.
* @param {string|Function} [options.prefix='fun'] - Prefix for generating unique identifiers and data attributes.
* May be a function returning the prefix, evaluated when the instance is created.
* @param {Function} [options.generateUid] - Custom function to generate the unique identifier.
* @param {Function} [options.generateClassName] - Custom function to generate unique class names.
* @param {Object} [options.attributes] - Attributes to be added to the `<style>` element.
* @param {Array} [options.renderers=['parseStyles', 'renderStyles']] - Array of renderer functions or method names.
* Renderers are composed in sequence. Strings or functions are automatically bound to `this`.
* @param {Object|Function} [options.attributes] - Attributes to be added to the `<style>` element.
* May be a function returning the attributes object, evaluated lazily by `getAttributes`.
* @param {Array|Function} [options.renderers=['parseStyles', 'renderStyles']] - Array of renderer functions or
* method names (or a function returning such an array). Resolved when the instance is created and applied in order
* by `render`, each renderer receiving the previous one's output. Renderers are called with the instance as `this`.
* @param {Function} [options.shouldAttachToDOM] - Custom function to determine whether the StyleSheet should be added to the DOM.

@@ -76,8 +97,12 @@ *

*
* @property {Object} classes - Object mapping original class names to generated unique class names.
* @property {Object} classes - Object mapping each top-level selector key (those matching `/^\w+$/`)
* to its generated unique class name string.
* @property {Object} styles - The original styles object provided to the instance.
* @property {String} uid - Unique identifier for the StyleSheet instance, generated using `this.generateUid`.
* @property {String} prefix - Prefix for generating unique identifiers. Set via options or subclass.
* @property {Object} attributes - Attributes to be added to the `<style>` element. Set via options or subclass.
* @property {Array} renderers - Array of renderer functions or method names used to process the styles object. Set via options or subclass.
* @property {string} uid - Unique identifier for the StyleSheet instance, generated using `this.generateUid`.
* @property {string} prefix - Prefix for generating unique identifiers. Resolved to a string when the instance
* is created (may be supplied as a function via options or a subclass).
* @property {Object|Function} [attributes] - Optional attributes to be added to the `<style>` element. May be
* `undefined`, an object, or a function returning the attributes object (evaluated lazily by `getAttributes`).
* @property {Array} renderers - Array of renderer functions used to process the styles object. Method-name
* strings passed via options are resolved to methods when the instance is created.
* @property {HTMLElement} el - Reference to the `<style>` element in the DOM. Created when the instance is attached to the DOM.

@@ -87,2 +112,3 @@ */

constructor(styles, options = {}) {
this.preinitialize.apply(this, arguments);
// Styles object.

@@ -97,5 +123,7 @@ this.styles = styles;

// Set default renderers.
if (!this.renderers) this.renderers = [this.renderStyles, this.parseStyles];
this.renderers = this.renderers ?
getResult(this.renderers, this).map(r => typeof r === 'string' ? this[r] : r) :
[this.parseStyles, this.renderStyles];
// Set default prefix.
if (!this.prefix) this.prefix = StyleSheet.prefix;
this.prefix = this.prefix ? getResult(this.prefix, this) : StyleSheet.prefix;
// Generate the `StyleSheet` unique identifier.

@@ -113,5 +141,17 @@ this.uid = this.generateUid();

/**
* Hook run at the very start of the constructor, before `styles` and `options`
* are applied and before `renderers`, `prefix`, `uid` and `classes` are computed.
* Does nothing by default. Override it in a subclass to run setup logic or define
* instance properties such as `prefix`, `attributes` or `renderers`. Values set
* here are still overridden by the matching `options`.
* @param {Object} styles - The styles object passed to the constructor.
* @param {Object} [options] - The options object passed to the constructor (may be `undefined`).
* @returns {void}
*/
preinitialize() {}
/**
* Generate a stable unique identifier.
* May be overridden by `options.generateUid`.
* @returns {String} The unique identifier.
* @returns {string} The unique identifier.
*/

@@ -137,5 +177,5 @@ generateUid() {

* May be overridden by `options.generateClassName` or by extending the class.
* @param {String} className - The class name.
* @param {Number} index - The index of the class name.
* @returns {String} The unique class name.
* @param {string} className - The class name.
* @param {number} index - The index of the class name.
* @returns {string} The unique class name.
*/

@@ -150,11 +190,9 @@ generateClassName(className, index) {

* Apply the renderers to the styles object.
* Renderers are applied in order, starting from `this.styles`, with each renderer
* receiving the previous one's output and called with the instance as `this`.
* It will return a string ready to be added to the style element.
* @returns {String} The styles object as a string.
* @returns {string} The styles object as a string.
*/
render() {
const renderers = this.renderers.map(
renderer => (typeof renderer === 'string' ? this[renderer] : renderer).bind(this)
);
return compose(renderers)(this.styles);
return this.renderers.reduce((acc, r) => r.call(this, acc), this.styles);
}

@@ -167,4 +205,4 @@

* @param {Object} styles - The styles object.
* @param {Number} level - The level of indentation. Used for debugging.
* @returns {String} The styles object as a string.
* @param {number} level - The level of indentation. Used for debugging.
* @returns {string} The styles object as a string.
* @private

@@ -206,4 +244,4 @@ */

* @param {Object} parent - The parent object. Used for nested styles.
* @param {String} parentSelector - The parent selector. Used for nested styles.
* @param {Boolean} isGlobal - If true, the styles are global styles.
* @param {string} parentSelector - The parent selector. Used for nested styles.
* @param {boolean} isGlobal - If true, the styles are global styles.
* @returns {Object} The styles object.

@@ -226,3 +264,3 @@ * @private

return fromClasses(key)
.replace(StyleSheet.referenceRegex, (match, ref) => fromClasses(ref))
.replace(StyleSheet.referenceRegex, (_match, ref) => fromClasses(ref))
.replace(StyleSheet.nestedRegex, parentSelector);

@@ -266,6 +304,6 @@ };

/**
* Get the attributes object.
* The attributes object will be used to set the attributes on the style element.
* The attributes object will be merged with the `this.attributes` object.
* The `data-fun-uid` attribute will be added to the attributes object.
* Get the attributes object used to set the attributes on the style element.
* Starts from `this.attributes`, which is optional and may be `undefined`, an
* object, or a function returning the attributes object (resolved via `getResult`).
* The `data-<prefix>-uid` attribute is always added.
* @returns {Object} The attributes object.

@@ -275,3 +313,3 @@ * @private

getAttributes() {
const attributes = Object.assign({}, this.attributes);
const attributes = Object.assign({}, getResult(this.attributes, this));
attributes[`data-${this.prefix}-uid`] = this.uid;

@@ -284,3 +322,3 @@ return attributes;

* Used for server-side rendering.
* @returns {String} The instance as a string.
* @returns {string} The instance as a string.
*/

@@ -300,3 +338,3 @@ toString() {

* May be overridden by `options.shouldAttachToDOM`.
* @returns {Boolean} True if the StyleSheet should be added to the DOM, false otherwise.
* @returns {boolean} True if the StyleSheet should be added to the DOM, false otherwise.
*/

@@ -427,3 +465,3 @@ shouldAttachToDOM() {

* @static
* @property {String} prefix - The class prefix. Used to generate unique class names.
* @property {string} prefix - The class prefix. Used to generate unique class names.
* @default fun

@@ -435,3 +473,3 @@ */

* @static
* @property {String} indent - The indent string. Used to format text when debug is enabled.
* @property {string} indent - The indent string. Used to format text when debug is enabled.
* @default ' '

@@ -450,3 +488,3 @@ */

* @static
* @property {Boolean} debug - The debug flag. If true, the styles will be formatted with
* @property {boolean} debug - The debug flag. If true, the styles will be formatted with
* indentation and new lines.

@@ -464,3 +502,4 @@ * @default __DEV__

* @param {Object} [options] - Optional configuration for the StyleSheet instance. Includes options like `prefix`, `renderers`, and more.
* @returns {StyleSheet} The created StyleSheet instance. Use the `classes` property to access the generated class names.
* @returns {StyleSheet} The created and attached StyleSheet instance. Its `classes` property maps
* each top-level selector to its generated class name.
*

@@ -467,0 +506,0 @@ * @example

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

!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).CSSFUN={})}(this,function(e){"use strict";const t=e=>null!==e&&"object"==typeof e&&!Array.isArray(e),s=["prefix","generateUid","generateClassName","shouldAttachToDOM","attributes","renderers"];class r{constructor(e,t={}){this.styles=e,this.classes={},s.forEach(e=>{e in t&&(this[e]=t[e])}),this.renderers||(this.renderers=[this.renderStyles,this.parseStyles]),this.prefix||(this.prefix=r.prefix),this.uid=this.generateUid();let i=0;Object.keys(e).forEach(e=>{e.match(r.classRegex)&&(this.classes[e]=this.generateClassName(e,++i))})}generateUid(){const e=JSON.stringify(this.styles);let t=2166136261;for(let s=0;s<e.length;s++)t^=e.charCodeAt(s),t=16777619*t>>>0;return t.toString(36)}generateClassName(e,t){return`${this.prefix[0]}-${this.uid}-${t}`}render(){const e=this.renderers.map(e=>("string"==typeof e?this[e]:e).bind(this));return e.reduce((e,t)=>(...s)=>e(t(...s)))(this.styles)}renderStyles(e,s=1){return Object.keys(e).reduce((r,i)=>{const n=e[i];if(t(n)){if(Object.keys(n).length>0){const e=this.renderStyles(n,s+1);r.push(`${i}{${e}}`)}}else null!=n&&r.push(`${i}:${n};`);return r},[]).join("")}parseStyles(e,s,i,n){const c=e=>e in this.classes?`.${this.classes[e]}`:e,l=e=>n&&i?`${i} ${e}`:e.match(r.globalPrefixRegex)?`${i?`${i} `:""}${e.replace(r.globalPrefixRegex,"")}`:c(e).replace(r.referenceRegex,(e,t)=>c(t)).replace(r.nestedRegex,i);return Object.keys(e).reduce((n,c)=>{const h=e[c];if(t(h))if(c.match(r.globalRegex))Object.assign(s||n,this.parseStyles(h,n,i,!0));else if((c.match(r.nestedRegex)||c.match(r.globalPrefixRegex))&&s){const e=l(c);s[e]={},Object.assign(s[e],this.parseStyles(h,s,e))}else{const e=l(c);n[e]={};const t=e.match(/@/)?[]:[n,e];Object.assign(n[e],this.parseStyles(h,...t))}else null!=h&&(n[c.match(/-/)?c:(o=c,o.replace(/([A-Z])/g,e=>`-${e[0].toLowerCase()}`))]=h);var o;return n},{})}getAttributes(){const e=Object.assign({},this.attributes);return e[`data-${this.prefix}-uid`]=this.uid,e}toString(){const e=this.getAttributes();return`<style${Object.keys(e).map(t=>` ${t}="${e[t]}"`).join("")}>${this.render()}</style>`}shouldAttachToDOM(){return"undefined"!=typeof document&&!document.querySelector(`style[data-${this.prefix}-uid="${this.uid}"]`)}attach(){if(r.registry.some(({uid:e})=>e===this.uid)||r.registry.push(this),this.shouldAttachToDOM()){this.el=document.createElement("style");const e=this.getAttributes();Object.keys(e).forEach(t=>{this.el.setAttribute(t,e[t])}),this.el.textContent=this.render(),document.head.appendChild(this.el)}return this}destroy(){const e=r.registry.indexOf(this);return e>-1&&r.registry.splice(e,1),this.el&&(this.el.parentNode&&this.el.parentNode.removeChild(this.el),this.el=null),this}static toString(){return r.registry.join("")}static toCSS(){return r.registry.map(e=>e.render()).join("")}static destroy(){r.registry.slice().forEach(e=>e.destroy())}}r.classRegex=/^\w+$/,r.globalRegex=/^@global$/,r.globalPrefixRegex=/^@global\s+/,r.referenceRegex=/\$(\w+)/g,r.nestedRegex=/&/g,r.prefix="fun",r.indent=" ",r.registry=[],r.debug=!1;const i=(e,t)=>new r(e,t).attach(),n=(e={},s)=>function e(r,i){return Object.keys(r).reduce((n,c)=>{const l=r[c],h=i?`${i}-${c}`:s?`--${s}-${c}`:`--${c}`;return t(l)?Object.assign(n,e(l,h)):null!=l&&(n[h]=l),n},{})}(e);e.StyleSheet=r,e.createTheme=(e={},t={})=>{const s=t.colorScheme||"light dark",c="cssVarsPrefix"in t?t.cssVarsPrefix:r.prefix;let l;if("light dark"===s){const t={light:n(e.light,c),dark:n(e.dark,c)},s=(h=t.light,o=t.dark,Object.keys(h).reduce((e,t)=>(h[t]!==o[t]&&(e.left[t]=h[t],e.right[t]=o[t]),e),{left:{},right:{}}));l={root:{":where(&)":Object.assign({colorScheme:"light"},t.light),':where([data-color-scheme="dark"] &)':Object.assign({colorScheme:"dark"},s.right)},"@media (prefers-color-scheme: dark)":{":where($root)":Object.assign({colorScheme:"dark"},s.right),':where([data-color-scheme="light"] $root)':Object.assign({colorScheme:"light"},s.left)}}}else l={root:{":where(&)":Object.assign({colorScheme:s},n(e[s],c))}};var h,o;return(t.createStyleSheet||i)(l,t.styleSheetOptions)},e.css=i});
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).CSSFUN={})}(this,function(e){"use strict";const t=e=>null!==e&&"object"==typeof e&&!Array.isArray(e),s=(e,t)=>"function"!=typeof e?e:e.call(t),r=["prefix","generateUid","generateClassName","shouldAttachToDOM","attributes","renderers"];class i{constructor(e,t={}){this.preinitialize.apply(this,arguments),this.styles=e,this.classes={},r.forEach(e=>{e in t&&(this[e]=t[e])}),this.renderers=this.renderers?s(this.renderers,this).map(e=>"string"==typeof e?this[e]:e):[this.parseStyles,this.renderStyles],this.prefix=this.prefix?s(this.prefix,this):i.prefix,this.uid=this.generateUid();let n=0;Object.keys(e).forEach(e=>{e.match(i.classRegex)&&(this.classes[e]=this.generateClassName(e,++n))})}preinitialize(){}generateUid(){const e=JSON.stringify(this.styles);let t=2166136261;for(let s=0;s<e.length;s++)t^=e.charCodeAt(s),t=16777619*t>>>0;return t.toString(36)}generateClassName(e,t){return`${this.prefix[0]}-${this.uid}-${t}`}render(){return this.renderers.reduce((e,t)=>t.call(this,e),this.styles)}renderStyles(e,s=1){return Object.keys(e).reduce((r,i)=>{const n=e[i];if(t(n)){if(Object.keys(n).length>0){const e=this.renderStyles(n,s+1);r.push(`${i}{${e}}`)}}else null!=n&&r.push(`${i}:${n};`);return r},[]).join("")}parseStyles(e,s,r,n){const l=e=>e in this.classes?`.${this.classes[e]}`:e,h=e=>n&&r?`${r} ${e}`:e.match(i.globalPrefixRegex)?`${r?`${r} `:""}${e.replace(i.globalPrefixRegex,"")}`:l(e).replace(i.referenceRegex,(e,t)=>l(t)).replace(i.nestedRegex,r);return Object.keys(e).reduce((n,l)=>{const c=e[l];if(t(c))if(l.match(i.globalRegex))Object.assign(s||n,this.parseStyles(c,n,r,!0));else if((l.match(i.nestedRegex)||l.match(i.globalPrefixRegex))&&s){const e=h(l);s[e]={},Object.assign(s[e],this.parseStyles(c,s,e))}else{const e=h(l);n[e]={};const t=e.match(/@/)?[]:[n,e];Object.assign(n[e],this.parseStyles(c,...t))}else null!=c&&(n[l.match(/-/)?l:(a=l,a.replace(/([A-Z])/g,e=>`-${e[0].toLowerCase()}`))]=c);var a;return n},{})}getAttributes(){const e=Object.assign({},s(this.attributes,this));return e[`data-${this.prefix}-uid`]=this.uid,e}toString(){const e=this.getAttributes();return`<style${Object.keys(e).map(t=>` ${t}="${e[t]}"`).join("")}>${this.render()}</style>`}shouldAttachToDOM(){return"undefined"!=typeof document&&!document.querySelector(`style[data-${this.prefix}-uid="${this.uid}"]`)}attach(){if(i.registry.some(({uid:e})=>e===this.uid)||i.registry.push(this),this.shouldAttachToDOM()){this.el=document.createElement("style");const e=this.getAttributes();Object.keys(e).forEach(t=>{this.el.setAttribute(t,e[t])}),this.el.textContent=this.render(),document.head.appendChild(this.el)}return this}destroy(){const e=i.registry.indexOf(this);return e>-1&&i.registry.splice(e,1),this.el&&(this.el.parentNode&&this.el.parentNode.removeChild(this.el),this.el=null),this}static toString(){return i.registry.join("")}static toCSS(){return i.registry.map(e=>e.render()).join("")}static destroy(){i.registry.slice().forEach(e=>e.destroy())}}i.classRegex=/^\w+$/,i.globalRegex=/^@global$/,i.globalPrefixRegex=/^@global\s+/,i.referenceRegex=/\$(\w+)/g,i.nestedRegex=/&/g,i.prefix="fun",i.indent=" ",i.registry=[],i.debug=!1;const n=(e,t)=>new i(e,t).attach(),l=(e={},s)=>function e(r,i){return Object.keys(r).reduce((n,l)=>{const h=r[l],c=i?`${i}-${l}`:s?`--${s}-${l}`:`--${l}`;return t(h)?Object.assign(n,e(h,c)):null!=h&&(n[c]=h),n},{})}(e);e.StyleSheet=i,e.createTheme=(e={},t={})=>{const s=t.colorScheme||"light dark",r="cssVarsPrefix"in t?t.cssVarsPrefix:i.prefix;let h;if("light dark"===s){const t={light:l(e.light,r),dark:l(e.dark,r)},s=(c=t.light,a=t.dark,Object.keys(c).reduce((e,t)=>(c[t]!==a[t]&&(e.left[t]=c[t],e.right[t]=a[t]),e),{left:{},right:{}}));h={root:{":where(&)":Object.assign({colorScheme:"light"},t.light),':where([data-color-scheme="dark"] &)':Object.assign({colorScheme:"dark"},s.right)},"@media (prefers-color-scheme: dark)":{":where($root)":Object.assign({colorScheme:"dark"},s.right),':where([data-color-scheme="light"] $root)':Object.assign({colorScheme:"light"},s.left)}}}else h={root:{":where(&)":Object.assign({colorScheme:s},l(e[s],r))}};var c,a;return(t.createStyleSheet||n)(h,t.styleSheetOptions)},e.css=n});
//# sourceMappingURL=cssfun.min.js.map

@@ -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\nconst camelizedToDashed = str => str.replace(/([A-Z])/g, (g) => `-${g[0].toLowerCase()}`);\nconst compose = fns => fns.reduce((f, g) => (...args) => f(g(...args)));\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} [options.prefix='fun'] - Prefix for generating unique identifiers and data attributes.\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} [options.attributes] - Attributes to be added to the `<style>` element.\n * @param {Array} [options.renderers=['parseStyles', 'renderStyles']] - Array of renderer functions or method names.\n * Renderers are composed in sequence. Strings or functions are automatically bound to `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 original class names to generated unique class names.\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. Set via options or subclass.\n * @property {Object} attributes - Attributes to be added to the `<style>` element. Set via options or subclass.\n * @property {Array} renderers - Array of renderer functions or method names used to process the styles object. Set via options or subclass.\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 // 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 if (!this.renderers) this.renderers = [this.renderStyles, this.parseStyles];\n // Set default prefix.\n if (!this.prefix) this.prefix = 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 * 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 * 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 const renderers = this.renderers.map(\n renderer => (typeof renderer === 'string' ? this[renderer] : renderer).bind(this)\n );\n\n return compose(renderers)(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.\n * The attributes object will be used to set the attributes on the style element.\n * The attributes object will be merged with the `this.attributes` object.\n * The `data-fun-uid` attribute will be added to the attributes object.\n * @returns {Object} The attributes object.\n * @private\n */\n getAttributes() {\n const attributes = Object.assign({}, this.attributes);\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 StyleSheet instance. Use the `classes` property to access the generated class names.\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","styleSheetOptions","StyleSheet","constructor","styles","options","this","classes","forEach","key","renderers","renderStyles","parseStyles","prefix","uid","generateUid","counter","Object","keys","selector","match","classRegex","generateClassName","JSON","stringify","hash","i","length","charCodeAt","toString","className","index","render","map","renderer","bind","reduce","f","g","args","compose","level","acc","renderedStyles","push","join","parent","parentSelector","isGlobal","fromClasses","generateKey","globalPrefixRegex","replace","referenceRegex","ref","nestedRegex","globalRegex","assign","str","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 * 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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"}

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

* @param {Object} [options] - Optional configuration for the StyleSheet instance. Includes options like `prefix`, `renderers`, and more.
* @returns {StyleSheet} The created StyleSheet instance. Use the `classes` property to access the generated class names.
* @returns {StyleSheet} The created and attached StyleSheet instance. Its `classes` property maps
* each top-level selector to its generated class name.
*

@@ -15,0 +16,0 @@ * @example

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

{"version":3,"file":"css.js","sources":["../src/css.js"],"sourcesContent":["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 StyleSheet instance. Use the `classes` property to access the generated class names.\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"],"names":[],"mappings":";;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACK,MAAC,GAAG,GAAG,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,MAAM;;;;"}
{"version":3,"file":"css.js","sources":["../src/css.js"],"sourcesContent":["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"],"names":[],"mappings":";;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACK,MAAC,GAAG,GAAG,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,MAAM;;;;"}
import isObject from './utils/isObject.js';
import __DEV__ from './utils/dev.js';
/**
* Convert a camelized string to a dashed string.
* @param {string} str String to be converted.
* @return {string} The converted string.
* @private
*/
const camelizedToDashed = str => str.replace(/([A-Z])/g, (g) => `-${g[0].toLowerCase()}`);
const compose = fns => fns.reduce((f, g) => (...args) => f(g(...args)));
/**
* Resolve a value that may be provided directly or as a function.
* If it's a function, call it with the provided context and return the result.
* Otherwise, return the value as is.
* @param {*} expression Value or function to be resolved.
* @param {*} context Context (`this`) to call the function with.
* @return {*} The resolved value.
* @private
*/
const getResult = (expression, context) =>
typeof expression !== 'function' ? expression :
expression.call(context);
const styleSheetOptions = ['prefix', 'generateUid', 'generateClassName', 'shouldAttachToDOM', 'attributes', 'renderers'];

@@ -22,8 +40,11 @@

* `prefix`, `generateUid`, `generateClassName`, `shouldAttachToDOM`, `attributes`, `renderers`.
* @param {String} [options.prefix='fun'] - Prefix for generating unique identifiers and data attributes.
* @param {string|Function} [options.prefix='fun'] - Prefix for generating unique identifiers and data attributes.
* May be a function returning the prefix, evaluated when the instance is created.
* @param {Function} [options.generateUid] - Custom function to generate the unique identifier.
* @param {Function} [options.generateClassName] - Custom function to generate unique class names.
* @param {Object} [options.attributes] - Attributes to be added to the `<style>` element.
* @param {Array} [options.renderers=['parseStyles', 'renderStyles']] - Array of renderer functions or method names.
* Renderers are composed in sequence. Strings or functions are automatically bound to `this`.
* @param {Object|Function} [options.attributes] - Attributes to be added to the `<style>` element.
* May be a function returning the attributes object, evaluated lazily by `getAttributes`.
* @param {Array|Function} [options.renderers=['parseStyles', 'renderStyles']] - Array of renderer functions or
* method names (or a function returning such an array). Resolved when the instance is created and applied in order
* by `render`, each renderer receiving the previous one's output. Renderers are called with the instance as `this`.
* @param {Function} [options.shouldAttachToDOM] - Custom function to determine whether the StyleSheet should be added to the DOM.

@@ -50,8 +71,12 @@ *

*
* @property {Object} classes - Object mapping original class names to generated unique class names.
* @property {Object} classes - Object mapping each top-level selector key (those matching `/^\w+$/`)
* to its generated unique class name string.
* @property {Object} styles - The original styles object provided to the instance.
* @property {String} uid - Unique identifier for the StyleSheet instance, generated using `this.generateUid`.
* @property {String} prefix - Prefix for generating unique identifiers. Set via options or subclass.
* @property {Object} attributes - Attributes to be added to the `<style>` element. Set via options or subclass.
* @property {Array} renderers - Array of renderer functions or method names used to process the styles object. Set via options or subclass.
* @property {string} uid - Unique identifier for the StyleSheet instance, generated using `this.generateUid`.
* @property {string} prefix - Prefix for generating unique identifiers. Resolved to a string when the instance
* is created (may be supplied as a function via options or a subclass).
* @property {Object|Function} [attributes] - Optional attributes to be added to the `<style>` element. May be
* `undefined`, an object, or a function returning the attributes object (evaluated lazily by `getAttributes`).
* @property {Array} renderers - Array of renderer functions used to process the styles object. Method-name
* strings passed via options are resolved to methods when the instance is created.
* @property {HTMLElement} el - Reference to the `<style>` element in the DOM. Created when the instance is attached to the DOM.

@@ -61,2 +86,3 @@ */

constructor(styles, options = {}) {
this.preinitialize.apply(this, arguments);
// Styles object.

@@ -71,5 +97,7 @@ this.styles = styles;

// Set default renderers.
if (!this.renderers) this.renderers = [this.renderStyles, this.parseStyles];
this.renderers = this.renderers ?
getResult(this.renderers, this).map(r => typeof r === 'string' ? this[r] : r) :
[this.parseStyles, this.renderStyles];
// Set default prefix.
if (!this.prefix) this.prefix = StyleSheet.prefix;
this.prefix = this.prefix ? getResult(this.prefix, this) : StyleSheet.prefix;
// Generate the `StyleSheet` unique identifier.

@@ -87,5 +115,17 @@ this.uid = this.generateUid();

/**
* Hook run at the very start of the constructor, before `styles` and `options`
* are applied and before `renderers`, `prefix`, `uid` and `classes` are computed.
* Does nothing by default. Override it in a subclass to run setup logic or define
* instance properties such as `prefix`, `attributes` or `renderers`. Values set
* here are still overridden by the matching `options`.
* @param {Object} styles - The styles object passed to the constructor.
* @param {Object} [options] - The options object passed to the constructor (may be `undefined`).
* @returns {void}
*/
preinitialize() {}
/**
* Generate a stable unique identifier.
* May be overridden by `options.generateUid`.
* @returns {String} The unique identifier.
* @returns {string} The unique identifier.
*/

@@ -111,5 +151,5 @@ generateUid() {

* May be overridden by `options.generateClassName` or by extending the class.
* @param {String} className - The class name.
* @param {Number} index - The index of the class name.
* @returns {String} The unique class name.
* @param {string} className - The class name.
* @param {number} index - The index of the class name.
* @returns {string} The unique class name.
*/

@@ -124,11 +164,9 @@ generateClassName(className, index) {

* Apply the renderers to the styles object.
* Renderers are applied in order, starting from `this.styles`, with each renderer
* receiving the previous one's output and called with the instance as `this`.
* It will return a string ready to be added to the style element.
* @returns {String} The styles object as a string.
* @returns {string} The styles object as a string.
*/
render() {
const renderers = this.renderers.map(
renderer => (typeof renderer === 'string' ? this[renderer] : renderer).bind(this)
);
return compose(renderers)(this.styles);
return this.renderers.reduce((acc, r) => r.call(this, acc), this.styles);
}

@@ -141,4 +179,4 @@

* @param {Object} styles - The styles object.
* @param {Number} level - The level of indentation. Used for debugging.
* @returns {String} The styles object as a string.
* @param {number} level - The level of indentation. Used for debugging.
* @returns {string} The styles object as a string.
* @private

@@ -180,4 +218,4 @@ */

* @param {Object} parent - The parent object. Used for nested styles.
* @param {String} parentSelector - The parent selector. Used for nested styles.
* @param {Boolean} isGlobal - If true, the styles are global styles.
* @param {string} parentSelector - The parent selector. Used for nested styles.
* @param {boolean} isGlobal - If true, the styles are global styles.
* @returns {Object} The styles object.

@@ -200,3 +238,3 @@ * @private

return fromClasses(key)
.replace(StyleSheet.referenceRegex, (match, ref) => fromClasses(ref))
.replace(StyleSheet.referenceRegex, (_match, ref) => fromClasses(ref))
.replace(StyleSheet.nestedRegex, parentSelector);

@@ -240,6 +278,6 @@ };

/**
* Get the attributes object.
* The attributes object will be used to set the attributes on the style element.
* The attributes object will be merged with the `this.attributes` object.
* The `data-fun-uid` attribute will be added to the attributes object.
* Get the attributes object used to set the attributes on the style element.
* Starts from `this.attributes`, which is optional and may be `undefined`, an
* object, or a function returning the attributes object (resolved via `getResult`).
* The `data-<prefix>-uid` attribute is always added.
* @returns {Object} The attributes object.

@@ -249,3 +287,3 @@ * @private

getAttributes() {
const attributes = Object.assign({}, this.attributes);
const attributes = Object.assign({}, getResult(this.attributes, this));
attributes[`data-${this.prefix}-uid`] = this.uid;

@@ -258,3 +296,3 @@ return attributes;

* Used for server-side rendering.
* @returns {String} The instance as a string.
* @returns {string} The instance as a string.
*/

@@ -274,3 +312,3 @@ toString() {

* May be overridden by `options.shouldAttachToDOM`.
* @returns {Boolean} True if the StyleSheet should be added to the DOM, false otherwise.
* @returns {boolean} True if the StyleSheet should be added to the DOM, false otherwise.
*/

@@ -401,3 +439,3 @@ shouldAttachToDOM() {

* @static
* @property {String} prefix - The class prefix. Used to generate unique class names.
* @property {string} prefix - The class prefix. Used to generate unique class names.
* @default fun

@@ -409,3 +447,3 @@ */

* @static
* @property {String} indent - The indent string. Used to format text when debug is enabled.
* @property {string} indent - The indent string. Used to format text when debug is enabled.
* @default ' '

@@ -424,3 +462,3 @@ */

* @static
* @property {Boolean} debug - The debug flag. If true, the styles will be formatted with
* @property {boolean} debug - The debug flag. If true, the styles will be formatted with
* indentation and new lines.

@@ -427,0 +465,0 @@ * @default __DEV__

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

{"version":3,"file":"StyleSheet.js","sources":["../src/StyleSheet.js"],"sourcesContent":["import isObject from './utils/isObject.js';\nimport __DEV__ from './utils/dev.js';\n\nconst camelizedToDashed = str => str.replace(/([A-Z])/g, (g) => `-${g[0].toLowerCase()}`);\nconst compose = fns => fns.reduce((f, g) => (...args) => f(g(...args)));\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} [options.prefix='fun'] - Prefix for generating unique identifiers and data attributes.\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} [options.attributes] - Attributes to be added to the `<style>` element.\n * @param {Array} [options.renderers=['parseStyles', 'renderStyles']] - Array of renderer functions or method names.\n * Renderers are composed in sequence. Strings or functions are automatically bound to `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 original class names to generated unique class names.\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. Set via options or subclass.\n * @property {Object} attributes - Attributes to be added to the `<style>` element. Set via options or subclass.\n * @property {Array} renderers - Array of renderer functions or method names used to process the styles object. Set via options or subclass.\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 // 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 if (!this.renderers) this.renderers = [this.renderStyles, this.parseStyles];\n // Set default prefix.\n if (!this.prefix) this.prefix = 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 * 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 * 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 const renderers = this.renderers.map(\n renderer => (typeof renderer === 'string' ? this[renderer] : renderer).bind(this)\n );\n\n return compose(renderers)(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.\n * The attributes object will be used to set the attributes on the style element.\n * The attributes object will be merged with the `this.attributes` object.\n * The `data-fun-uid` attribute will be added to the attributes object.\n * @returns {Object} The attributes object.\n * @private\n */\n getAttributes() {\n const attributes = Object.assign({}, this.attributes);\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"],"names":[],"mappings":"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"}
{"version":3,"file":"StyleSheet.js","sources":["../src/StyleSheet.js"],"sourcesContent":["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"],"names":[],"mappings":"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"}

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

* @param {Object} [options] - Optional configuration for the StyleSheet instance. Includes options like `prefix`, `renderers`, and more.
* @returns {StyleSheet} The created StyleSheet instance. Use the `classes` property to access the generated class names.
* @returns {StyleSheet} The created and attached StyleSheet instance. Its `classes` property maps
* each top-level selector to its generated class name.
*

@@ -17,0 +18,0 @@ * @example

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

{"version":3,"file":"css.cjs","sources":["../src/css.js"],"sourcesContent":["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 StyleSheet instance. Use the `classes` property to access the generated class names.\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"],"names":[],"mappings":";;;;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACK,MAAC,GAAG,GAAG,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,MAAM;;;;"}
{"version":3,"file":"css.cjs","sources":["../src/css.js"],"sourcesContent":["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"],"names":[],"mappings":";;;;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACK,MAAC,GAAG,GAAG,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,MAAM;;;;"}

@@ -6,5 +6,23 @@ 'use strict';

/**
* Convert a camelized string to a dashed string.
* @param {string} str String to be converted.
* @return {string} The converted string.
* @private
*/
const camelizedToDashed = str => str.replace(/([A-Z])/g, (g) => `-${g[0].toLowerCase()}`);
const compose = fns => fns.reduce((f, g) => (...args) => f(g(...args)));
/**
* Resolve a value that may be provided directly or as a function.
* If it's a function, call it with the provided context and return the result.
* Otherwise, return the value as is.
* @param {*} expression Value or function to be resolved.
* @param {*} context Context (`this`) to call the function with.
* @return {*} The resolved value.
* @private
*/
const getResult = (expression, context) =>
typeof expression !== 'function' ? expression :
expression.call(context);
const styleSheetOptions = ['prefix', 'generateUid', 'generateClassName', 'shouldAttachToDOM', 'attributes', 'renderers'];

@@ -25,8 +43,11 @@

* `prefix`, `generateUid`, `generateClassName`, `shouldAttachToDOM`, `attributes`, `renderers`.
* @param {String} [options.prefix='fun'] - Prefix for generating unique identifiers and data attributes.
* @param {string|Function} [options.prefix='fun'] - Prefix for generating unique identifiers and data attributes.
* May be a function returning the prefix, evaluated when the instance is created.
* @param {Function} [options.generateUid] - Custom function to generate the unique identifier.
* @param {Function} [options.generateClassName] - Custom function to generate unique class names.
* @param {Object} [options.attributes] - Attributes to be added to the `<style>` element.
* @param {Array} [options.renderers=['parseStyles', 'renderStyles']] - Array of renderer functions or method names.
* Renderers are composed in sequence. Strings or functions are automatically bound to `this`.
* @param {Object|Function} [options.attributes] - Attributes to be added to the `<style>` element.
* May be a function returning the attributes object, evaluated lazily by `getAttributes`.
* @param {Array|Function} [options.renderers=['parseStyles', 'renderStyles']] - Array of renderer functions or
* method names (or a function returning such an array). Resolved when the instance is created and applied in order
* by `render`, each renderer receiving the previous one's output. Renderers are called with the instance as `this`.
* @param {Function} [options.shouldAttachToDOM] - Custom function to determine whether the StyleSheet should be added to the DOM.

@@ -53,8 +74,12 @@ *

*
* @property {Object} classes - Object mapping original class names to generated unique class names.
* @property {Object} classes - Object mapping each top-level selector key (those matching `/^\w+$/`)
* to its generated unique class name string.
* @property {Object} styles - The original styles object provided to the instance.
* @property {String} uid - Unique identifier for the StyleSheet instance, generated using `this.generateUid`.
* @property {String} prefix - Prefix for generating unique identifiers. Set via options or subclass.
* @property {Object} attributes - Attributes to be added to the `<style>` element. Set via options or subclass.
* @property {Array} renderers - Array of renderer functions or method names used to process the styles object. Set via options or subclass.
* @property {string} uid - Unique identifier for the StyleSheet instance, generated using `this.generateUid`.
* @property {string} prefix - Prefix for generating unique identifiers. Resolved to a string when the instance
* is created (may be supplied as a function via options or a subclass).
* @property {Object|Function} [attributes] - Optional attributes to be added to the `<style>` element. May be
* `undefined`, an object, or a function returning the attributes object (evaluated lazily by `getAttributes`).
* @property {Array} renderers - Array of renderer functions used to process the styles object. Method-name
* strings passed via options are resolved to methods when the instance is created.
* @property {HTMLElement} el - Reference to the `<style>` element in the DOM. Created when the instance is attached to the DOM.

@@ -64,2 +89,3 @@ */

constructor(styles, options = {}) {
this.preinitialize.apply(this, arguments);
// Styles object.

@@ -74,5 +100,7 @@ this.styles = styles;

// Set default renderers.
if (!this.renderers) this.renderers = [this.renderStyles, this.parseStyles];
this.renderers = this.renderers ?
getResult(this.renderers, this).map(r => typeof r === 'string' ? this[r] : r) :
[this.parseStyles, this.renderStyles];
// Set default prefix.
if (!this.prefix) this.prefix = StyleSheet.prefix;
this.prefix = this.prefix ? getResult(this.prefix, this) : StyleSheet.prefix;
// Generate the `StyleSheet` unique identifier.

@@ -90,5 +118,17 @@ this.uid = this.generateUid();

/**
* Hook run at the very start of the constructor, before `styles` and `options`
* are applied and before `renderers`, `prefix`, `uid` and `classes` are computed.
* Does nothing by default. Override it in a subclass to run setup logic or define
* instance properties such as `prefix`, `attributes` or `renderers`. Values set
* here are still overridden by the matching `options`.
* @param {Object} styles - The styles object passed to the constructor.
* @param {Object} [options] - The options object passed to the constructor (may be `undefined`).
* @returns {void}
*/
preinitialize() {}
/**
* Generate a stable unique identifier.
* May be overridden by `options.generateUid`.
* @returns {String} The unique identifier.
* @returns {string} The unique identifier.
*/

@@ -114,5 +154,5 @@ generateUid() {

* May be overridden by `options.generateClassName` or by extending the class.
* @param {String} className - The class name.
* @param {Number} index - The index of the class name.
* @returns {String} The unique class name.
* @param {string} className - The class name.
* @param {number} index - The index of the class name.
* @returns {string} The unique class name.
*/

@@ -127,11 +167,9 @@ generateClassName(className, index) {

* Apply the renderers to the styles object.
* Renderers are applied in order, starting from `this.styles`, with each renderer
* receiving the previous one's output and called with the instance as `this`.
* It will return a string ready to be added to the style element.
* @returns {String} The styles object as a string.
* @returns {string} The styles object as a string.
*/
render() {
const renderers = this.renderers.map(
renderer => (typeof renderer === 'string' ? this[renderer] : renderer).bind(this)
);
return compose(renderers)(this.styles);
return this.renderers.reduce((acc, r) => r.call(this, acc), this.styles);
}

@@ -144,4 +182,4 @@

* @param {Object} styles - The styles object.
* @param {Number} level - The level of indentation. Used for debugging.
* @returns {String} The styles object as a string.
* @param {number} level - The level of indentation. Used for debugging.
* @returns {string} The styles object as a string.
* @private

@@ -183,4 +221,4 @@ */

* @param {Object} parent - The parent object. Used for nested styles.
* @param {String} parentSelector - The parent selector. Used for nested styles.
* @param {Boolean} isGlobal - If true, the styles are global styles.
* @param {string} parentSelector - The parent selector. Used for nested styles.
* @param {boolean} isGlobal - If true, the styles are global styles.
* @returns {Object} The styles object.

@@ -203,3 +241,3 @@ * @private

return fromClasses(key)
.replace(StyleSheet.referenceRegex, (match, ref) => fromClasses(ref))
.replace(StyleSheet.referenceRegex, (_match, ref) => fromClasses(ref))
.replace(StyleSheet.nestedRegex, parentSelector);

@@ -243,6 +281,6 @@ };

/**
* Get the attributes object.
* The attributes object will be used to set the attributes on the style element.
* The attributes object will be merged with the `this.attributes` object.
* The `data-fun-uid` attribute will be added to the attributes object.
* Get the attributes object used to set the attributes on the style element.
* Starts from `this.attributes`, which is optional and may be `undefined`, an
* object, or a function returning the attributes object (resolved via `getResult`).
* The `data-<prefix>-uid` attribute is always added.
* @returns {Object} The attributes object.

@@ -252,3 +290,3 @@ * @private

getAttributes() {
const attributes = Object.assign({}, this.attributes);
const attributes = Object.assign({}, getResult(this.attributes, this));
attributes[`data-${this.prefix}-uid`] = this.uid;

@@ -261,3 +299,3 @@ return attributes;

* Used for server-side rendering.
* @returns {String} The instance as a string.
* @returns {string} The instance as a string.
*/

@@ -277,3 +315,3 @@ toString() {

* May be overridden by `options.shouldAttachToDOM`.
* @returns {Boolean} True if the StyleSheet should be added to the DOM, false otherwise.
* @returns {boolean} True if the StyleSheet should be added to the DOM, false otherwise.
*/

@@ -404,3 +442,3 @@ shouldAttachToDOM() {

* @static
* @property {String} prefix - The class prefix. Used to generate unique class names.
* @property {string} prefix - The class prefix. Used to generate unique class names.
* @default fun

@@ -412,3 +450,3 @@ */

* @static
* @property {String} indent - The indent string. Used to format text when debug is enabled.
* @property {string} indent - The indent string. Used to format text when debug is enabled.
* @default ' '

@@ -427,3 +465,3 @@ */

* @static
* @property {Boolean} debug - The debug flag. If true, the styles will be formatted with
* @property {boolean} debug - The debug flag. If true, the styles will be formatted with
* indentation and new lines.

@@ -430,0 +468,0 @@ * @default __DEV__

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

{"version":3,"file":"StyleSheet.cjs","sources":["../src/StyleSheet.js"],"sourcesContent":["import isObject from './utils/isObject.js';\nimport __DEV__ from './utils/dev.js';\n\nconst camelizedToDashed = str => str.replace(/([A-Z])/g, (g) => `-${g[0].toLowerCase()}`);\nconst compose = fns => fns.reduce((f, g) => (...args) => f(g(...args)));\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} [options.prefix='fun'] - Prefix for generating unique identifiers and data attributes.\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} [options.attributes] - Attributes to be added to the `<style>` element.\n * @param {Array} [options.renderers=['parseStyles', 'renderStyles']] - Array of renderer functions or method names.\n * Renderers are composed in sequence. Strings or functions are automatically bound to `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 original class names to generated unique class names.\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. Set via options or subclass.\n * @property {Object} attributes - Attributes to be added to the `<style>` element. Set via options or subclass.\n * @property {Array} renderers - Array of renderer functions or method names used to process the styles object. Set via options or subclass.\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 // 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 if (!this.renderers) this.renderers = [this.renderStyles, this.parseStyles];\n // Set default prefix.\n if (!this.prefix) this.prefix = 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 * 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 * 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 const renderers = this.renderers.map(\n renderer => (typeof renderer === 'string' ? this[renderer] : renderer).bind(this)\n );\n\n return compose(renderers)(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.\n * The attributes object will be used to set the attributes on the style element.\n * The attributes object will be merged with the `this.attributes` object.\n * The `data-fun-uid` attribute will be added to the attributes object.\n * @returns {Object} The attributes object.\n * @private\n */\n getAttributes() {\n const attributes = Object.assign({}, this.attributes);\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"],"names":["__DEV__","isObject"],"mappings":"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"}
{"version":3,"file":"StyleSheet.cjs","sources":["../src/StyleSheet.js"],"sourcesContent":["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"],"names":["__DEV__","isObject"],"mappings":"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"}
{
"name": "cssfun",
"version": "0.1.0-alpha.1",
"version": "0.1.0-alpha.2",
"description": "Near-zero runtime CSS-in-JS library",

@@ -34,10 +34,15 @@ "type": "module",

],
"directories": {
"example": "example",
"test": "test",
"doc": "docs"
},
"scripts": {
"prepare": "npm run clean && npm run test && npm run build",
"test": "mocha --require jsdom-global/register --reporter nyan test/*.js",
"test:types": "tsd",
"clean": "node -e \"const fs=require('fs');['lib','dist','es'].forEach(d=>fs.rmSync(d,{recursive:true,force:true}))\"",
"test": "mocha --require jsdom-global/register --reporter nyan test/*.js",
"posttest": "npm run lint && npm run test:types",
"lint": "eslint src test",
"build": "rollup -c",
"clean": "node -e \"const fs=require('fs');['lib','dist','es'].forEach(d=>fs.rmSync(d,{recursive:true,force:true}))\"",
"version": "node scripts/bump-cdn-links.js && node scripts/release-changelog.js",

@@ -49,7 +54,2 @@ "docs:api": "jsdoc2md --module-index-format none --helper jsdoc2md/helper.cjs --partial jsdoc2md/header.hbs --partial jsdoc2md/sig-link.hbs --partial jsdoc2md/sig-link-html.hbs --partial jsdoc2md/sig-link-parent.hbs --files src/*.js > docs/api.md"

"bugs": "https://github.com/8tentaculos/cssfun/issues",
"directories": {
"example": "example",
"test": "test",
"doc": "docs"
},
"author": "Alberto Masuelli <alberto.masuelli@gmail.com> (https://github.com/8tentaculos)",

@@ -56,0 +56,0 @@ "license": "MIT",

+96
-37
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://cdn.jsdelivr.net/gh/8tentaculos/cssfun@v0.1.0-alpha.1/docs/logo-dark.svg">
<img alt="CSSFUN" src="https://cdn.jsdelivr.net/gh/8tentaculos/cssfun@v0.1.0-alpha.1/docs/logo.svg">
<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">
</picture>

@@ -14,2 +14,3 @@ </p>

[![CI](https://github.com/8tentaculos/cssfun/actions/workflows/ci.yml/badge.svg)](https://github.com/8tentaculos/cssfun/actions/workflows/ci.yml)
[![npm version](https://img.shields.io/npm/v/cssfun.svg)](https://www.npmjs.com/package/cssfun)

@@ -19,2 +20,3 @@ [![npm package minimized gzipped size](https://img.shields.io/bundlejs/size/cssfun)](https://unpkg.com/cssfun/dist/cssfun.min.js)

[![jsDelivr hits (npm)](https://img.shields.io/jsdelivr/npm/hm/cssfun)](https://www.jsdelivr.com/package/npm/cssfun)
[![license](https://img.shields.io/npm/l/cssfun.svg)](https://github.com/8tentaculos/cssfun/blob/master/LICENSE)

@@ -32,3 +34,3 @@ ## Key Features

- **Framework-Agnostic and Lightweight** 🌐
**CSSFUN** is compatible with any environment. At just **1.7KB**, it adds minimal overhead to your projects.
**CSSFUN** is compatible with any environment. At just **1.8KB**, it adds minimal overhead to your projects.

@@ -80,2 +82,4 @@ - **No Build Tools Required** 🛠️

`css()` injects the styles and returns a `StyleSheet` instance. Its `classes` property holds the generated class names, one per top-level selector:
```javascript

@@ -98,39 +102,50 @@ const { classes } = css({

See [Class Name Generation](#class-name-generation) for how the names are built.
## Class Name Generation
When you call `css()`, **CSSFUN** automatically generates unique, scoped class names for each top-level selector in your styles object. These class names are created **at module initialization**, ensuring near-zero runtime overhead.
`css(styles)` returns a [`StyleSheet`](/docs/api.md#stylesheet) instance. Its `classes` property is an object that maps each top-level selector in your styles to a unique, scoped class name:
### How Classes Are Generated
```javascript
const sheet = css({
button: { color: 'red' },
link: { color: 'blue' }
});
1. **When**: Classes are generated immediately when `css()` is called, during StyleSheet instance creation.
2. **Stable**: The unique ID embedded in each class name is derived from a hash of the styles' content. The same styles always produce the same class names across environments (server and client), hot reloads, and multiple calls with identical styles.
3. **Which selectors**: Only top-level selectors that match valid class name patterns (alphanumeric characters, no special characters) get generated classes.
4. **Format**: The format differs between development and production modes:
sheet.classes; // { button: "fun-9qkk9s-button", link: "fun-9qkk9s-link" }
sheet.classes.button; // "fun-9qkk9s-button"
```
**Development Mode** (readable, for debugging):
```
{prefix}-{uid}-{className}
```
Example: `.fun-9qkk9s-button` (prefix `fun` + unique ID `9qkk9s` + original class name `button`)
Destructure `classes` to use the generated names as `className`:
**Production Mode** (optimized, smaller bundle):
```
{prefix[0]}-{uid}-{index}
```
Example: `.f-9qkk9s-1` (first letter of prefix `f` + unique ID `9qkk9s` + sequential index `1`)
```javascript
const { classes } = css({ button: { color: 'red' } });
5. **Access**: Generated class names are available via the `classes` object returned by `css()`:
```javascript
const { classes } = css({
button: { color: 'red' },
link: { color: 'blue' }
});
// classes.button → "fun-9qkk9s-button" (dev) or "f-9qkk9s-1" (prod)
// classes.link → "fun-9qkk9s-link" (dev) or "f-9qkk9s-2" (prod)
```
const Button = () => <button className={classes.button}>Click me</button>;
```
> **Note**: All examples in this documentation show class names in **development mode** for clarity.
> In **production**, class names are automatically optimized for smaller bundle size.
> You can customize class name generation via [`options.generateClassName`](/docs/api.md#new-stylesheetstyles-options) or by [extending the class](/docs/api.md#stylesheet__generateclassname).
Generation happens once, when the instance is created — never during rendering — so there is no per-render overhead.
### Which selectors get a class
Only top-level keys that are plain identifiers (matching `/^\w+$/` — letters, digits and underscores) get a generated class. At-rules (`@global`, `@media …`, `@keyframes …`), `$` references and keys with dashes, spaces or commas are left untouched and don't appear in `classes`.
### Stable across environments
Each class name embeds a `uid` hashed from the styles' content, so identical styles always produce identical class names — across server and client, hot reloads, and repeated calls. This is what makes [SSR hydration](#server-side-rendering-ssr) seamless.
### Name format
The format depends on the build:
| Build | Format | Example |
| --- | --- | --- |
| Development | `{prefix}-{uid}-{name}` | `fun-9qkk9s-button` |
| Production | `{prefix[0]}-{uid}-{index}` | `f-9qkk9s-1` |
In production, the original name is replaced by a 1-based index to keep the output small. The default `prefix` is `fun`.
> **Note**: Examples in this documentation use the development format for readability.
> You can override generation via [`options.generateClassName`](/docs/api.md#new-stylesheetstyles-options) or by [extending `StyleSheet`](/docs/api.md#stylesheet__generateclassname).
## Renderers

@@ -369,12 +384,18 @@

You can customize the renderers by setting the `renderers` array on the [`StyleSheet`](/docs/api.md#stylesheet) instance.
If passed via [`options.renderers`](/docs/api.md#new-stylesheetstyles-options), they will be automatically added to the instance.
You can customize the renderers via [`options.renderers`](/docs/api.md#new-stylesheetstyles-options) (or by setting `renderers` on a [`StyleSheet`](/docs/api.md#stylesheet) subclass).
Elements in the `renderers` array can be either functions or strings that reference methods of the [`StyleSheet`](/docs/api.md#stylesheet) instance. These
methods will be bound to the instance before they are invoked.
Elements in the `renderers` array can be either functions or strings that reference methods of the [`StyleSheet`](/docs/api.md#stylesheet) instance. Method-name strings are resolved to methods when the instance is created, and every renderer is called with the instance as `this`.
By default, [`StyleSheet`](/docs/api.md#stylesheet) instances are rendered using the built-in renderers: `[this.renderStyles, this.parseStyles]`.
Renderers are applied in array order, each receiving the previous one's output. By default, [`StyleSheet`](/docs/api.md#stylesheet) instances use `[this.parseStyles, this.renderStyles]`: `parseStyles` runs first (transforms the object), then `renderStyles` (converts it to the CSS string).
**Note:** The order matters! Renderers are composed, so they execute in reverse order. With `[renderStyles, parseStyles]`, `parseStyles` executes first (transforms the object), then `renderStyles` (converts to CSS string).
`renderers` may also be given as a function that returns the array, resolved when the instance is created.
## Subclassing & dynamic values
The `prefix`, `attributes` and `renderers` options also accept a **function** that returns the value, so you can compute it at runtime instead of passing a static value. The timing differs: `prefix` and `renderers` are resolved once, when the instance is created, while `attributes` is resolved lazily every time the styles are rendered — handy for per-request values such as a [CSP nonce](#content-security-policy-csp).
For subclasses, the `preinitialize` method runs at the very start of the constructor — before the options are applied and before the class names are generated. Override it to run setup logic or define `prefix`, `attributes` or `renderers` (matching options still take precedence).
See [Content Security Policy (CSP)](#content-security-policy-csp) for a real-world example that combines `preinitialize` with a function-valued `attributes`.
## Themes

@@ -534,2 +555,40 @@

## Content Security Policy (CSP)
If your site uses a strict [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) with a per-request nonce (`style-src 'nonce-…'`), add that nonce to the generated `<style>` tags through the [`attributes`](/docs/api.md#new-stylesheetstyles-options) option/property. `StyleSheet.toString()` then emits `<style nonce="…" data-fun-uid="…">`.
### Set it on the prototype per request
Instances fall back to `StyleSheet.prototype.attributes`, which is read fresh on every render, so set the nonce there before rendering:
```javascript
app.get('*', (req, res) => {
StyleSheet.prototype.attributes = { nonce : res.locals.cspNonce };
const html = renderToString(<App />);
const styles = StyleSheet.toString(); // <style nonce="…" data-fun-uid="…">…</style>
// …embed `styles` in the <head> as in the SSR example above.
});
```
Simple and effective for synchronous SSR: the styles are rendered on the server and reused on the client during hydration without being recreated, so the client needs no nonce handling. (For streaming/async SSR, resolve the nonce per request from context — e.g. [`AsyncLocalStorage`](https://nodejs.org/api/async_context.html) — via the function form, since the prototype is shared across concurrent requests.)
### Scoped alternative: a subclass with `preinitialize`
To avoid mutating the global prototype, scope it to your own subclass and `css` helper. `preinitialize` runs once per instance, so use the function form to read the nonce lazily at render time:
```javascript
import { StyleSheet } from 'cssfun';
class CSPStyleSheet extends StyleSheet {
preinitialize() {
this.attributes = () => ({ nonce : getRequestNonce() });
}
}
const css = (styles, options) => new CSPStyleSheet(styles, options).attach();
```
Pass `CSPStyleSheet` to [`createTheme`](#themes) via [`options.createStyleSheet`](/docs/api.md#createtheme) so theme styles carry the nonce too.
## TypeScript

@@ -536,0 +595,0 @@

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

* @param {Object} [options] - Optional configuration for the StyleSheet instance. Includes options like `prefix`, `renderers`, and more.
* @returns {StyleSheet} The created StyleSheet instance. Use the `classes` property to access the generated class names.
* @returns {StyleSheet} The created and attached StyleSheet instance. Its `classes` property maps
* each top-level selector to its generated class name.
*

@@ -13,0 +14,0 @@ * @example

import isObject from './utils/isObject.js';
import __DEV__ from './utils/dev.js';
/**
* Convert a camelized string to a dashed string.
* @param {string} str String to be converted.
* @return {string} The converted string.
* @private
*/
const camelizedToDashed = str => str.replace(/([A-Z])/g, (g) => `-${g[0].toLowerCase()}`);
const compose = fns => fns.reduce((f, g) => (...args) => f(g(...args)));
/**
* Resolve a value that may be provided directly or as a function.
* If it's a function, call it with the provided context and return the result.
* Otherwise, return the value as is.
* @param {*} expression Value or function to be resolved.
* @param {*} context Context (`this`) to call the function with.
* @return {*} The resolved value.
* @private
*/
const getResult = (expression, context) =>
typeof expression !== 'function' ? expression :
expression.call(context);
const styleSheetOptions = ['prefix', 'generateUid', 'generateClassName', 'shouldAttachToDOM', 'attributes', 'renderers'];

@@ -22,8 +40,11 @@

* `prefix`, `generateUid`, `generateClassName`, `shouldAttachToDOM`, `attributes`, `renderers`.
* @param {String} [options.prefix='fun'] - Prefix for generating unique identifiers and data attributes.
* @param {string|Function} [options.prefix='fun'] - Prefix for generating unique identifiers and data attributes.
* May be a function returning the prefix, evaluated when the instance is created.
* @param {Function} [options.generateUid] - Custom function to generate the unique identifier.
* @param {Function} [options.generateClassName] - Custom function to generate unique class names.
* @param {Object} [options.attributes] - Attributes to be added to the `<style>` element.
* @param {Array} [options.renderers=['parseStyles', 'renderStyles']] - Array of renderer functions or method names.
* Renderers are composed in sequence. Strings or functions are automatically bound to `this`.
* @param {Object|Function} [options.attributes] - Attributes to be added to the `<style>` element.
* May be a function returning the attributes object, evaluated lazily by `getAttributes`.
* @param {Array|Function} [options.renderers=['parseStyles', 'renderStyles']] - Array of renderer functions or
* method names (or a function returning such an array). Resolved when the instance is created and applied in order
* by `render`, each renderer receiving the previous one's output. Renderers are called with the instance as `this`.
* @param {Function} [options.shouldAttachToDOM] - Custom function to determine whether the StyleSheet should be added to the DOM.

@@ -50,8 +71,12 @@ *

*
* @property {Object} classes - Object mapping original class names to generated unique class names.
* @property {Object} classes - Object mapping each top-level selector key (those matching `/^\w+$/`)
* to its generated unique class name string.
* @property {Object} styles - The original styles object provided to the instance.
* @property {String} uid - Unique identifier for the StyleSheet instance, generated using `this.generateUid`.
* @property {String} prefix - Prefix for generating unique identifiers. Set via options or subclass.
* @property {Object} attributes - Attributes to be added to the `<style>` element. Set via options or subclass.
* @property {Array} renderers - Array of renderer functions or method names used to process the styles object. Set via options or subclass.
* @property {string} uid - Unique identifier for the StyleSheet instance, generated using `this.generateUid`.
* @property {string} prefix - Prefix for generating unique identifiers. Resolved to a string when the instance
* is created (may be supplied as a function via options or a subclass).
* @property {Object|Function} [attributes] - Optional attributes to be added to the `<style>` element. May be
* `undefined`, an object, or a function returning the attributes object (evaluated lazily by `getAttributes`).
* @property {Array} renderers - Array of renderer functions used to process the styles object. Method-name
* strings passed via options are resolved to methods when the instance is created.
* @property {HTMLElement} el - Reference to the `<style>` element in the DOM. Created when the instance is attached to the DOM.

@@ -61,2 +86,3 @@ */

constructor(styles, options = {}) {
this.preinitialize.apply(this, arguments);
// Styles object.

@@ -71,5 +97,7 @@ this.styles = styles;

// Set default renderers.
if (!this.renderers) this.renderers = [this.renderStyles, this.parseStyles];
this.renderers = this.renderers ?
getResult(this.renderers, this).map(r => typeof r === 'string' ? this[r] : r) :
[this.parseStyles, this.renderStyles];
// Set default prefix.
if (!this.prefix) this.prefix = StyleSheet.prefix;
this.prefix = this.prefix ? getResult(this.prefix, this) : StyleSheet.prefix;
// Generate the `StyleSheet` unique identifier.

@@ -87,5 +115,17 @@ this.uid = this.generateUid();

/**
* Hook run at the very start of the constructor, before `styles` and `options`
* are applied and before `renderers`, `prefix`, `uid` and `classes` are computed.
* Does nothing by default. Override it in a subclass to run setup logic or define
* instance properties such as `prefix`, `attributes` or `renderers`. Values set
* here are still overridden by the matching `options`.
* @param {Object} styles - The styles object passed to the constructor.
* @param {Object} [options] - The options object passed to the constructor (may be `undefined`).
* @returns {void}
*/
preinitialize() {}
/**
* Generate a stable unique identifier.
* May be overridden by `options.generateUid`.
* @returns {String} The unique identifier.
* @returns {string} The unique identifier.
*/

@@ -111,5 +151,5 @@ generateUid() {

* May be overridden by `options.generateClassName` or by extending the class.
* @param {String} className - The class name.
* @param {Number} index - The index of the class name.
* @returns {String} The unique class name.
* @param {string} className - The class name.
* @param {number} index - The index of the class name.
* @returns {string} The unique class name.
*/

@@ -124,11 +164,9 @@ generateClassName(className, index) {

* Apply the renderers to the styles object.
* Renderers are applied in order, starting from `this.styles`, with each renderer
* receiving the previous one's output and called with the instance as `this`.
* It will return a string ready to be added to the style element.
* @returns {String} The styles object as a string.
* @returns {string} The styles object as a string.
*/
render() {
const renderers = this.renderers.map(
renderer => (typeof renderer === 'string' ? this[renderer] : renderer).bind(this)
);
return compose(renderers)(this.styles);
return this.renderers.reduce((acc, r) => r.call(this, acc), this.styles);
}

@@ -141,4 +179,4 @@

* @param {Object} styles - The styles object.
* @param {Number} level - The level of indentation. Used for debugging.
* @returns {String} The styles object as a string.
* @param {number} level - The level of indentation. Used for debugging.
* @returns {string} The styles object as a string.
* @private

@@ -180,4 +218,4 @@ */

* @param {Object} parent - The parent object. Used for nested styles.
* @param {String} parentSelector - The parent selector. Used for nested styles.
* @param {Boolean} isGlobal - If true, the styles are global styles.
* @param {string} parentSelector - The parent selector. Used for nested styles.
* @param {boolean} isGlobal - If true, the styles are global styles.
* @returns {Object} The styles object.

@@ -200,3 +238,3 @@ * @private

return fromClasses(key)
.replace(StyleSheet.referenceRegex, (match, ref) => fromClasses(ref))
.replace(StyleSheet.referenceRegex, (_match, ref) => fromClasses(ref))
.replace(StyleSheet.nestedRegex, parentSelector);

@@ -240,6 +278,6 @@ };

/**
* Get the attributes object.
* The attributes object will be used to set the attributes on the style element.
* The attributes object will be merged with the `this.attributes` object.
* The `data-fun-uid` attribute will be added to the attributes object.
* Get the attributes object used to set the attributes on the style element.
* Starts from `this.attributes`, which is optional and may be `undefined`, an
* object, or a function returning the attributes object (resolved via `getResult`).
* The `data-<prefix>-uid` attribute is always added.
* @returns {Object} The attributes object.

@@ -249,3 +287,3 @@ * @private

getAttributes() {
const attributes = Object.assign({}, this.attributes);
const attributes = Object.assign({}, getResult(this.attributes, this));
attributes[`data-${this.prefix}-uid`] = this.uid;

@@ -258,3 +296,3 @@ return attributes;

* Used for server-side rendering.
* @returns {String} The instance as a string.
* @returns {string} The instance as a string.
*/

@@ -274,3 +312,3 @@ toString() {

* May be overridden by `options.shouldAttachToDOM`.
* @returns {Boolean} True if the StyleSheet should be added to the DOM, false otherwise.
* @returns {boolean} True if the StyleSheet should be added to the DOM, false otherwise.
*/

@@ -401,3 +439,3 @@ shouldAttachToDOM() {

* @static
* @property {String} prefix - The class prefix. Used to generate unique class names.
* @property {string} prefix - The class prefix. Used to generate unique class names.
* @default fun

@@ -409,3 +447,3 @@ */

* @static
* @property {String} indent - The indent string. Used to format text when debug is enabled.
* @property {string} indent - The indent string. Used to format text when debug is enabled.
* @default ' '

@@ -424,3 +462,3 @@ */

* @static
* @property {Boolean} debug - The debug flag. If true, the styles will be formatted with
* @property {boolean} debug - The debug flag. If true, the styles will be formatted with
* indentation and new lines.

@@ -427,0 +465,0 @@ * @default __DEV__

@@ -31,4 +31,7 @@ import StyleSheet from './StyleSheet';

cssVarsPrefix?: string | null;
/** A function used to create a new StyleSheet instance. By default, uses the `css` function. */
createStyleSheet?: <S extends Styles>(styles: S, options?: StyleSheetOptions) => StyleSheet<S>;
/**
* A function used to create a new StyleSheet instance. By default, uses the `css` function.
* Accepts `StyleSheet` subclasses so you can plug in a custom implementation.
*/
createStyleSheet?: (styles: Styles, options?: StyleSheetOptions) => StyleSheet;
/** Options to pass when creating the StyleSheet instance. */

@@ -35,0 +38,0 @@ styleSheetOptions?: StyleSheetOptions;

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

* @param options - Optional configuration for the StyleSheet instance.
* @returns The created StyleSheet instance. Use the `classes` property to access the generated class names.
* @returns The created and attached StyleSheet instance. Its `classes` property maps
* each top-level selector to its generated class name.
*/

@@ -13,0 +14,0 @@ declare function css<S extends Styles>(styles: S, options?: StyleSheetOptions): StyleSheet<S>;

@@ -28,6 +28,15 @@ 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;
/** A value provided directly or as a function returning it (called with the StyleSheet as `this`). */
type Resolvable<T> = T | ((this: StyleSheet<any>) => T);
/** 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'`. */
prefix?: string;
/**
* 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<string>;
/** Custom function to generate the unique identifier. */

@@ -39,6 +48,13 @@ generateUid?: (this: StyleSheet<any>) => string;

shouldAttachToDOM?: (this: StyleSheet<any>) => boolean;
/** Attributes to be added to the `<style>` element. */
attributes?: Record<string, string>;
/** Array of renderer functions or method names. Default: `['parseStyles', 'renderStyles']`. */
renderers?: Array<string | ((this: StyleSheet<any>, styles: any) => any)>;
/**
* Attributes to be added to the `<style>` element.
* May be a function returning the attributes object, evaluated lazily by `getAttributes`.
*/
attributes?: Resolvable<Record<string, string>>;
/**
* Renderer functions or method names (or a function returning such an array).
* Default: `['parseStyles', 'renderStyles']`. Resolved when the instance is created
* and applied in order, each renderer receiving the previous one's output.
*/
renderers?: Resolvable<Array<string | RendererFn>>;
/** Any additional custom options, e.g. for subclasses or custom renderers. */

@@ -60,3 +76,13 @@ [key: string]: unknown;

/**
* Object mapping original class names to generated unique class names.
* Hook run at the very start of the constructor, before `styles`/`options` are
* applied and before `renderers`, `prefix`, `uid` and `classes` are computed.
* Does nothing by default. Override it in a subclass to run setup logic or define
* instance properties such as `prefix`, `attributes` or `renderers`. Values set
* here are still overridden by the matching `options`.
*/
preinitialize(styles: S, options?: StyleSheetOptions): void;
/**
* Object mapping each top-level selector key (those matching `/^\w+$/`) to its
* generated unique class name string.
* At-rule keys (`@global`, `@keyframes …`, `@media …`, `@supports …`)

@@ -73,8 +99,15 @@ * and class reference keys (`$name`) are excluded — they don't produce

uid: string;
/** Prefix for generating unique identifiers. */
/** Prefix for generating unique identifiers. Resolved to a string when the instance is created. */
prefix: string;
/** Attributes to be added to the `<style>` element. */
attributes: Record<string, string>;
/** Array of renderer functions or method names used to process the styles object. */
renderers: Array<string | ((this: StyleSheet<any>, styles: any) => any)>;
/**
* Attributes to be added to the `<style>` element. Optional — may be `undefined`
* (only set when passed as an option or assigned manually), an object, or a function
* returning the attributes object (resolved lazily by `getAttributes`).
*/
attributes?: Resolvable<Record<string, string>>;
/**
* Renderer functions used to process the styles object. Method-name strings passed
* via options are resolved to methods when the instance is created.
*/
renderers: RendererFn[];
/** Reference to the `<style>` element in the DOM. Set after `attach()`, `null` after `destroy()`. */

@@ -81,0 +114,0 @@ el: HTMLStyleElement | null | undefined;

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