Sorry, the diff of this file is too big to display
| {"version":3,"file":"cssfun.min.js","sources":["../src/dev.js","../src/StyleSheet.js","../src/css.js","../src/createTheme.js"],"sourcesContent":["/**\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 * @private\n */\nconst __DEV__ = true;\n\nexport default __DEV__;\n","import __DEV__ from './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 (value.constructor === Object) {\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 {\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 (value.constructor === Object) {\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 {\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","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';\n\nconst makeCssVars = (theme = {}, prefix = '--') => {\n return Object.keys(theme).reduce((acc, key) => {\n if (theme[key].constructor === Object) {\n Object.assign(acc, makeCssVars(theme[key], `${prefix}-${key}`));\n } else {\n acc[`${prefix}-${key}`] = theme[key];\n }\n return acc;\n }, {});\n};\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} [options.cssVarsPrefix] - The prefix for the generated CSS variables. Default is `fun`. \n * For example, a key `color` in the theme will generate a CSS variable like `--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 = `--${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":["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","value","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","themes","colorScheme","cssVarsPrefix","cssVars","light","dark","diff","left","right","root","createStyleSheet"],"mappings":"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"} |
| {"version":3,"file":"createTheme.js","sources":["../src/createTheme.js"],"sourcesContent":["import css from './css.js';\nimport StyleSheet from './StyleSheet.js';\n\nconst makeCssVars = (theme = {}, prefix = '--') => {\n return Object.keys(theme).reduce((acc, key) => {\n if (theme[key].constructor === Object) {\n Object.assign(acc, makeCssVars(theme[key], `${prefix}-${key}`));\n } else {\n acc[`${prefix}-${key}`] = theme[key];\n }\n return acc;\n }, {});\n};\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} [options.cssVarsPrefix] - The prefix for the generated CSS variables. Default is `fun`. \n * For example, a key `color` in the theme will generate a CSS variable like `--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 = `--${options.cssVarsPrefix || StyleSheet.prefix}`;\n\n let styles;\n\n if (colorScheme === 'light dark') {\n const cssVars = {\n light : makeCssVars(themes.light, prefix),\n dark : makeCssVars(themes.dark, prefix)\n };\n\n const diff = getDiff(cssVars.light, cssVars.dark);\n\n styles = {\n root : {\n ':where(&)' : Object.assign({ colorScheme : 'light' }, cssVars.light),\n ':where([data-color-scheme=\"dark\"] &)' : Object.assign({ colorScheme : 'dark' }, diff.right),\n },\n '@media (prefers-color-scheme: dark)' : {\n ':where($root)' : Object.assign({ colorScheme : 'dark' }, diff.right),\n ':where([data-color-scheme=\"light\"] $root)' : Object.assign({ colorScheme : 'light' }, diff.left)\n }\n };\n } else {\n styles = {\n root : {\n ':where(&)' : Object.assign({ colorScheme }, makeCssVars(themes[colorScheme], prefix))\n }\n };\n }\n\n return (options.createStyleSheet || css)(styles, options.styleSheetOptions);\n};\n\nexport default createTheme;\n"],"names":[],"mappings":";;;;AAGA,MAAM,WAAW,GAAG,CAAC,KAAK,GAAG,EAAE,EAAE,MAAM,GAAG,IAAI,KAAK;AACnD,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK;AACnD,QAAQ,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,WAAW,KAAK,MAAM,EAAE;AAC/C,YAAY,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;AAC3E,QAAQ,CAAC,MAAM;AACf,YAAY,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC;AAChD,QAAQ;AACR,QAAQ,OAAO,GAAG;AAClB,IAAI,CAAC,EAAE,EAAE,CAAC;AACV,CAAC;;AAED,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,KAAK,KAAK;AACjC,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK;AAClD,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,EAAE;AACtC,YAAY,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC;AACrC,YAAY,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC;AACvC,QAAQ;AACR,QAAQ,OAAO,GAAG;AAClB,IAAI,CAAC,EAAE,EAAE,IAAI,GAAG,EAAE,EAAE,KAAK,GAAG,EAAE,EAAE,CAAC;AACjC,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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,WAAW,GAAG,CAAC,MAAM,GAAG,EAAE,EAAE,OAAO,GAAG,EAAE,KAAK;AACnD,IAAI,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,YAAY;AAC3D,IAAI,MAAM,MAAM,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,aAAa,KAAK,UAAU,CAAC,MAAM,CAAC,CAAC;;AAErE,IAAI,IAAI,MAAM;;AAEd,IAAI,IAAI,WAAW,KAAK,YAAY,EAAE;AACtC,QAAQ,MAAM,OAAO,GAAG;AACxB,YAAY,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC;AACrD,YAAY,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM;AAClD,SAAS;;AAET,QAAQ,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC;;AAEzD,QAAQ,MAAM,GAAG;AACjB,YAAY,IAAI,GAAG;AACnB,gBAAgB,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,EAAE,EAAE,OAAO,CAAC,KAAK,CAAC;AACrF,gBAAgB,sCAAsC,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC;AAC5G,aAAa;AACb,YAAY,qCAAqC,GAAG;AACpD,gBAAgB,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC;AACrF,gBAAgB,2CAA2C,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,EAAE,EAAE,IAAI,CAAC,IAAI;AAChH;AACA,SAAS;AACT,IAAI,CAAC,MAAM;AACX,QAAQ,MAAM,GAAG;AACjB,YAAY,IAAI,GAAG;AACnB,gBAAgB,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,EAAE,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;AACrG;AACA,SAAS;AACT,IAAI;;AAEJ,IAAI,OAAO,CAAC,OAAO,CAAC,gBAAgB,IAAI,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,iBAAiB,CAAC;AAC/E;;;;"} |
| {"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;;;;"} |
+13
| /** | ||
| * Development mode flag. | ||
| * This will be replaced during build: | ||
| * - ESM/CJS: replaced with process.env.NODE_ENV !== 'production' | ||
| * - UMD dev: replaced with true | ||
| * - UMD prod: replaced with false | ||
| * @type {boolean} | ||
| * @private | ||
| */ | ||
| const __DEV__ = process.env.NODE_ENV !== 'production'; | ||
| export { __DEV__ as default }; | ||
| //# sourceMappingURL=dev.js.map |
| {"version":3,"file":"dev.js","sources":["../src/dev.js"],"sourcesContent":["/**\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 * @private\n */\nconst __DEV__ = true;\n\nexport default __DEV__;\n"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAA,OAAA,GAAA,OAAA,CAAA,GAAA,CAAA,QAAA,KAAA;;;;"} |
| {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;"} |
| {"version":3,"file":"StyleSheet.js","sources":["../src/StyleSheet.js"],"sourcesContent":["import __DEV__ from './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 (value.constructor === Object) {\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 {\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 (value.constructor === Object) {\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 {\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":"createTheme.cjs","sources":["../src/createTheme.js"],"sourcesContent":["import css from './css.js';\nimport StyleSheet from './StyleSheet.js';\n\nconst makeCssVars = (theme = {}, prefix = '--') => {\n return Object.keys(theme).reduce((acc, key) => {\n if (theme[key].constructor === Object) {\n Object.assign(acc, makeCssVars(theme[key], `${prefix}-${key}`));\n } else {\n acc[`${prefix}-${key}`] = theme[key];\n }\n return acc;\n }, {});\n};\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} [options.cssVarsPrefix] - The prefix for the generated CSS variables. Default is `fun`. \n * For example, a key `color` in the theme will generate a CSS variable like `--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 = `--${options.cssVarsPrefix || StyleSheet.prefix}`;\n\n let styles;\n\n if (colorScheme === 'light dark') {\n const cssVars = {\n light : makeCssVars(themes.light, prefix),\n dark : makeCssVars(themes.dark, prefix)\n };\n\n const diff = getDiff(cssVars.light, cssVars.dark);\n\n styles = {\n root : {\n ':where(&)' : Object.assign({ colorScheme : 'light' }, cssVars.light),\n ':where([data-color-scheme=\"dark\"] &)' : Object.assign({ colorScheme : 'dark' }, diff.right),\n },\n '@media (prefers-color-scheme: dark)' : {\n ':where($root)' : Object.assign({ colorScheme : 'dark' }, diff.right),\n ':where([data-color-scheme=\"light\"] $root)' : Object.assign({ colorScheme : 'light' }, diff.left)\n }\n };\n } else {\n styles = {\n root : {\n ':where(&)' : Object.assign({ colorScheme }, makeCssVars(themes[colorScheme], prefix))\n }\n };\n }\n\n return (options.createStyleSheet || css)(styles, options.styleSheetOptions);\n};\n\nexport default createTheme;\n"],"names":[],"mappings":"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"} |
| {"version":3,"file":"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;;;;"} |
+15
| 'use strict'; | ||
| /** | ||
| * Development mode flag. | ||
| * This will be replaced during build: | ||
| * - ESM/CJS: replaced with process.env.NODE_ENV !== 'production' | ||
| * - UMD dev: replaced with true | ||
| * - UMD prod: replaced with false | ||
| * @type {boolean} | ||
| * @private | ||
| */ | ||
| const __DEV__ = process.env.NODE_ENV !== 'production'; | ||
| module.exports = __DEV__; | ||
| //# sourceMappingURL=dev.cjs.map |
| {"version":3,"file":"dev.cjs","sources":["../src/dev.js"],"sourcesContent":["/**\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 * @private\n */\nconst __DEV__ = true;\n\nexport default __DEV__;\n"],"names":[],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAA,OAAA,GAAA,OAAA,CAAA,GAAA,CAAA,QAAA,KAAA;;;;"} |
| {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"} |
| {"version":3,"file":"StyleSheet.cjs","sources":["../src/StyleSheet.js"],"sourcesContent":["import __DEV__ from './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 (value.constructor === Object) {\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 {\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 (value.constructor === Object) {\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 {\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__"],"mappings":"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"} |
+12
| /** | ||
| * Development mode flag. | ||
| * This will be replaced during build: | ||
| * - ESM/CJS: replaced with process.env.NODE_ENV !== 'production' | ||
| * - UMD dev: replaced with true | ||
| * - UMD prod: replaced with false | ||
| * @type {boolean} | ||
| * @private | ||
| */ | ||
| const __DEV__ = true; | ||
| export default __DEV__; |
+62
-44
@@ -7,4 +7,15 @@ (function (global, factory) { | ||
| /** | ||
| * Development mode flag. | ||
| * This will be replaced during build: | ||
| * - ESM/CJS: replaced with process.env.NODE_ENV !== 'production' | ||
| * - UMD dev: replaced with true | ||
| * - UMD prod: replaced with false | ||
| * @type {boolean} | ||
| * @private | ||
| */ | ||
| const __DEV__ = true; | ||
| const camelizedToDashed = str => str.replace(/([A-Z])/g, (g) => `-${g[0].toLowerCase()}`); | ||
| const compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args))); | ||
| const compose = fns => fns.reduce((f, g) => (...args) => f(g(...args))); | ||
@@ -24,17 +35,11 @@ const styleSheetOptions = ['prefix', 'generateUid', 'generateClassName', 'shouldAttachToDOM', 'attributes', 'renderers']; | ||
| * the renderers to generate the final CSS string. It is stored in the instance as `this.styles`. | ||
| * @param {Object} [options={}] - Optional configuration options for the StyleSheet instance. | ||
| * @param {String} [options.prefix='fun'] - A prefix used for generating unique identifiers | ||
| * and data attributes. | ||
| * @param {Function} [options.generateUid] - A custom function to generate the unique | ||
| * identifier for the StyleSheet instance. | ||
| * @param {Function} [options.generateClassName] - A custom function to generate unique | ||
| * class names for scoped styles. | ||
| * @param {Object} [options.attributes] - An object containing attributes to be added | ||
| * to the `<style>` element in the DOM. | ||
| * @param {Array} [options.renderers=['parseStyles', 'renderStyles']] - An array of | ||
| * renderer functions or method names. The renderers are composed in sequence, where | ||
| * the first receives the styles object, and the last outputs the final CSS string. | ||
| * Strings or functions will be automatically bound to `this`. | ||
| * @param {Function} [options.shouldAttachToDOM] - A custom function to determine whether | ||
| * the StyleSheet should be added to the DOM. | ||
| * @param {Object} [options={}] - Configuration options. The following options are assigned to the instance (`this`): | ||
| * `prefix`, `generateUid`, `generateClassName`, `shouldAttachToDOM`, `attributes`, `renderers`. | ||
| * @param {String} [options.prefix='fun'] - Prefix for generating unique identifiers and data attributes. | ||
| * @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 {Function} [options.shouldAttachToDOM] - Custom function to determine whether the StyleSheet should be added to the DOM. | ||
| * | ||
@@ -60,14 +65,9 @@ * @example | ||
| * | ||
| * @property {Object} classes - An object mapping the original class names to the | ||
| * generated unique class names. Use this to reference the generated class names | ||
| * in your components. | ||
| * @property {Object} classes - Object mapping original class names to generated unique class names. | ||
| * @property {Object} styles - The original styles object provided to the instance. | ||
| * @property {String} uid - A unique identifier for the StyleSheet instance, generated | ||
| * using `this.generateUid`. | ||
| * @property {Object} attributes - The attributes object, derived from `options.attributes`, | ||
| * to be added to the `<style>` element. | ||
| * @property {Array} renderers - The array of renderer functions or method names used | ||
| * to process the styles object. | ||
| * @property {HTMLElement} el - A reference to the `<style>` element in the DOM. This | ||
| * is created when the instance is attached to the DOM. | ||
| * @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 {HTMLElement} el - Reference to the `<style>` element in the DOM. Created when the instance is attached to the DOM. | ||
| */ | ||
@@ -91,5 +91,6 @@ class StyleSheet { | ||
| // Generate class names. Only generate class names for top-level selectors. | ||
| let counter = 0; | ||
| Object.keys(styles).forEach(selector => { | ||
| if (selector.match(StyleSheet.classRegex)) { | ||
| this.classes[selector] = this.generateClassName(selector); | ||
| this.classes[selector] = this.generateClassName(selector, ++counter); | ||
| } | ||
@@ -115,3 +116,3 @@ }); | ||
| // Convert the hash to a shorter base-36 string. | ||
| return `${this.prefix}-${hash.toString(36)}`; | ||
| return hash.toString(36); | ||
| } | ||
@@ -123,8 +124,11 @@ | ||
| * to be used as class names in the styles object. | ||
| * May be overridden by `options.generateClassName`. | ||
| * 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. | ||
| */ | ||
| generateClassName(className) { | ||
| return `${this.uid}-${className}`; | ||
| generateClassName(className, index) { | ||
| return StyleSheet.debug ? | ||
| `${this.prefix}-${this.uid}-${className}` : | ||
| `${this.prefix[0]}-${this.uid}-${index}`; | ||
| } | ||
@@ -138,7 +142,7 @@ | ||
| render() { | ||
| return compose( | ||
| ...this.renderers.map( | ||
| renderer => (typeof renderer === 'string' ? this[renderer] : renderer).bind(this) | ||
| ) | ||
| )(this.styles); | ||
| const renderers = this.renderers.map( | ||
| renderer => (typeof renderer === 'string' ? this[renderer] : renderer).bind(this) | ||
| ); | ||
| return compose(renderers)(this.styles); | ||
| } | ||
@@ -227,4 +231,6 @@ | ||
| acc[selector] = {}; | ||
| // Don't expand at-rules. | ||
| const args = selector.match(/@/) ? [] : [acc, selector]; | ||
| // Regular styles. | ||
| Object.assign(acc[selector], this.parseStyles(value, acc, selector)); | ||
| Object.assign(acc[selector], this.parseStyles(value, ...args)); | ||
| } | ||
@@ -236,3 +242,3 @@ } else { | ||
| // Allows css vars to contain camelCase parts between dashes. | ||
| acc[key.includes('-') ? key : camelizedToDashed(key)] = value; | ||
| acc[key.match(/-/) ? key : camelizedToDashed(key)] = value; | ||
| } | ||
@@ -268,3 +274,3 @@ | ||
| const attributesHtml = Object.keys(attributes).map(key => ` ${key}="${attributes[key]}"`).join(''); | ||
| const nl = StyleSheet.debug ? '\n' : ''; | ||
| const nl = (StyleSheet.debug) ? '\n' : ''; | ||
| return `<style${attributesHtml}>${nl}${this.render()}</style>${nl}`; | ||
@@ -333,3 +339,3 @@ } | ||
| this.el = null; | ||
| } | ||
| } | ||
@@ -340,3 +346,4 @@ return this; | ||
| /** | ||
| * Render all instances in the registry as a string. | ||
| * Render all instances in the registry as a string, including the style tags. | ||
| * Can be used to insert style tags in an HTML template for server-side rendering. | ||
| * @returns {string} All instances in the registry as a string. | ||
@@ -350,2 +357,12 @@ * @static | ||
| /** | ||
| * Render all instances in the registry as CSS string. | ||
| * Can be used to generate an external CSS file. | ||
| * @returns {string} All instances in the registry rendered as CSS string. | ||
| * @static | ||
| */ | ||
| static toCSS() { | ||
| return StyleSheet.registry.map(instance => instance.render()).join(''); | ||
| } | ||
| /** | ||
| * Destroy all instances in the registry and remove them from | ||
@@ -420,5 +437,5 @@ * it and from the DOM. | ||
| * indentation and new lines. | ||
| * @default false | ||
| * @default __DEV__ | ||
| */ | ||
| StyleSheet.debug = false; | ||
| StyleSheet.debug = __DEV__; | ||
@@ -581,1 +598,2 @@ /** | ||
| })); | ||
| //# sourceMappingURL=cssfun.js.map |
@@ -1,1 +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=["prefix","generateUid","generateClassName","shouldAttachToDOM","attributes","renderers"];class s{constructor(e,r={}){this.styles=e,this.classes={},t.forEach((e=>{e in r&&(this[e]=r[e])})),this.renderers||(this.renderers=[this.renderStyles,this.parseStyles]),this.prefix||(this.prefix=s.prefix),this.uid=this.generateUid(),Object.keys(e).forEach((e=>{e.match(s.classRegex)&&(this.classes[e]=this.generateClassName(e))}))}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`${this.prefix}-${t.toString(36)}`}generateClassName(e){return`${this.uid}-${e}`}render(){return((...e)=>e.reduce(((e,t)=>(...s)=>e(t(...s)))))(...this.renderers.map((e=>("string"==typeof e?this[e]:e).bind(this))))(this.styles)}renderStyles(e,t=1){return Object.keys(e).reduce(((r,i)=>{const c=e[i];let n="",h="",l="";if(s.debug&&(n=s.indent.repeat(t),h="\n",l=" "),c.constructor===Object){if(Object.keys(c).length>0){const e=this.renderStyles(c,t+1);r.push(`${n}${i}${l}{${h}${e}${n}}${h}`)}}else r.push(`${n}${i}:${l}${c};${h}`);return r}),[]).join("")}parseStyles(e,t,r,i){const c=e=>e in this.classes?`.${this.classes[e]}`:e,n=e=>i&&r?`${r} ${e}`:e.match(s.globalPrefixRegex)?`${r?`${r} `:""}${e.replace(s.globalPrefixRegex,"")}`:c(e).replace(s.referenceRegex,((e,t)=>c(t))).replace(s.nestedRegex,r);return Object.keys(e).reduce(((i,c)=>{const h=e[c];if(h.constructor===Object)if(c.match(s.globalRegex))Object.assign(t||i,this.parseStyles(h,i,r,!0));else if((c.match(s.nestedRegex)||c.match(s.globalPrefixRegex))&&t){const e=n(c);t[e]={},Object.assign(t[e],this.parseStyles(h,t,e))}else{const e=n(c);i[e]={},Object.assign(i[e],this.parseStyles(h,i,e))}else i[c.includes("-")?c:(l=c,l.replace(/([A-Z])/g,(e=>`-${e[0].toLowerCase()}`)))]=h;var l;return i}),{})}getAttributes(){const e=Object.assign({},this.attributes);return e[`data-${this.prefix}-uid`]=this.uid,e}toString(){const e=this.getAttributes(),t=Object.keys(e).map((t=>` ${t}="${e[t]}"`)).join(""),r=s.debug?"\n":"";return`<style${t}>${r}${this.render()}</style>${r}`}shouldAttachToDOM(){return"undefined"!=typeof document&&!document.querySelector(`style[data-${this.prefix}-uid="${this.uid}"]`)}attach(){if(s.registry.some((({uid:e})=>e===this.uid))||s.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=s.registry.indexOf(this);return e>-1&&s.registry.splice(e,1),this.el&&(this.el.parentNode&&this.el.parentNode.removeChild(this.el),this.el=null),this}static toString(){return s.registry.join("")}static destroy(){s.registry.slice().forEach((e=>e.destroy()))}}s.classRegex=/^\w+$/,s.globalRegex=/^@global$/,s.globalPrefixRegex=/^@global\s+/,s.referenceRegex=/\$(\w+)/g,s.nestedRegex=/&/g,s.prefix="fun",s.indent=" ",s.registry=[],s.debug=!1;const r=(e,t)=>new s(e,t).attach(),i=(e={},t="--")=>Object.keys(e).reduce(((s,r)=>(e[r].constructor===Object?Object.assign(s,i(e[r],`${t}-${r}`)):s[`${t}-${r}`]=e[r],s)),{});e.StyleSheet=s,e.createTheme=(e={},t={})=>{const c=t.colorScheme||"light dark",n=`--${t.cssVarsPrefix||s.prefix}`;let h;if("light dark"===c){const t={light:i(e.light,n),dark:i(e.dark,n)},s=(l=t.light,o=t.dark,Object.keys(l).reduce(((e,t)=>(l[t]!==o[t]&&(e.left[t]=l[t],e.right[t]=o[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:c},i(e[c],n))}};var l,o;return(t.createStyleSheet||r)(h,t.styleSheetOptions)},e.css=r})); | ||
| !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=["prefix","generateUid","generateClassName","shouldAttachToDOM","attributes","renderers"];class s{constructor(e,r={}){this.styles=e,this.classes={},t.forEach((e=>{e in r&&(this[e]=r[e])})),this.renderers||(this.renderers=[this.renderStyles,this.parseStyles]),this.prefix||(this.prefix=s.prefix),this.uid=this.generateUid();let i=0;Object.keys(e).forEach((e=>{e.match(s.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,t=1){return Object.keys(e).reduce(((s,r)=>{const i=e[r];if(i.constructor===Object){if(Object.keys(i).length>0){const e=this.renderStyles(i,t+1);s.push(`${r}{${e}}`)}}else s.push(`${r}:${i};`);return s}),[]).join("")}parseStyles(e,t,r,i){const c=e=>e in this.classes?`.${this.classes[e]}`:e,n=e=>i&&r?`${r} ${e}`:e.match(s.globalPrefixRegex)?`${r?`${r} `:""}${e.replace(s.globalPrefixRegex,"")}`:c(e).replace(s.referenceRegex,((e,t)=>c(t))).replace(s.nestedRegex,r);return Object.keys(e).reduce(((i,c)=>{const h=e[c];if(h.constructor===Object)if(c.match(s.globalRegex))Object.assign(t||i,this.parseStyles(h,i,r,!0));else if((c.match(s.nestedRegex)||c.match(s.globalPrefixRegex))&&t){const e=n(c);t[e]={},Object.assign(t[e],this.parseStyles(h,t,e))}else{const e=n(c);i[e]={};const t=e.match(/@/)?[]:[i,e];Object.assign(i[e],this.parseStyles(h,...t))}else i[c.match(/-/)?c:(o=c,o.replace(/([A-Z])/g,(e=>`-${e[0].toLowerCase()}`)))]=h;var o;return i}),{})}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(s.registry.some((({uid:e})=>e===this.uid))||s.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=s.registry.indexOf(this);return e>-1&&s.registry.splice(e,1),this.el&&(this.el.parentNode&&this.el.parentNode.removeChild(this.el),this.el=null),this}static toString(){return s.registry.join("")}static toCSS(){return s.registry.map((e=>e.render())).join("")}static destroy(){s.registry.slice().forEach((e=>e.destroy()))}}s.classRegex=/^\w+$/,s.globalRegex=/^@global$/,s.globalPrefixRegex=/^@global\s+/,s.referenceRegex=/\$(\w+)/g,s.nestedRegex=/&/g,s.prefix="fun",s.indent=" ",s.registry=[],s.debug=!1;const r=(e,t)=>new s(e,t).attach(),i=(e={},t="--")=>Object.keys(e).reduce(((s,r)=>(e[r].constructor===Object?Object.assign(s,i(e[r],`${t}-${r}`)):s[`${t}-${r}`]=e[r],s)),{});e.StyleSheet=s,e.createTheme=(e={},t={})=>{const c=t.colorScheme||"light dark",n=`--${t.cssVarsPrefix||s.prefix}`;let h;if("light dark"===c){const t={light:i(e.light,n),dark:i(e.dark,n)},s=(o=t.light,l=t.dark,Object.keys(o).reduce(((e,t)=>(o[t]!==l[t]&&(e.left[t]=o[t],e.right[t]=l[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:c},i(e[c],n))}};var o,l;return(t.createStyleSheet||r)(h,t.styleSheetOptions)},e.css=r})); | ||
| //# sourceMappingURL=cssfun.min.js.map |
| import StyleSheet from './StyleSheet.js'; | ||
| import css from './css.js'; | ||
| import './dev.js'; | ||
@@ -131,1 +132,2 @@ const makeCssVars = (theme = {}, prefix = '--') => { | ||
| export { createTheme as default }; | ||
| //# sourceMappingURL=createTheme.js.map |
+2
-0
| import StyleSheet from './StyleSheet.js'; | ||
| import './dev.js'; | ||
@@ -29,1 +30,2 @@ /** | ||
| export { css as default }; | ||
| //# sourceMappingURL=css.js.map |
+2
-0
| export { default as StyleSheet } from './StyleSheet.js'; | ||
| export { default as css } from './css.js'; | ||
| export { default as createTheme } from './createTheme.js'; | ||
| import './dev.js'; | ||
| //# sourceMappingURL=index.js.map |
+54
-45
@@ -0,3 +1,5 @@ | ||
| import __DEV__ from './dev.js'; | ||
| const camelizedToDashed = str => str.replace(/([A-Z])/g, (g) => `-${g[0].toLowerCase()}`); | ||
| const compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args))); | ||
| const compose = fns => fns.reduce((f, g) => (...args) => f(g(...args))); | ||
@@ -17,17 +19,11 @@ const styleSheetOptions = ['prefix', 'generateUid', 'generateClassName', 'shouldAttachToDOM', 'attributes', 'renderers']; | ||
| * the renderers to generate the final CSS string. It is stored in the instance as `this.styles`. | ||
| * @param {Object} [options={}] - Optional configuration options for the StyleSheet instance. | ||
| * @param {String} [options.prefix='fun'] - A prefix used for generating unique identifiers | ||
| * and data attributes. | ||
| * @param {Function} [options.generateUid] - A custom function to generate the unique | ||
| * identifier for the StyleSheet instance. | ||
| * @param {Function} [options.generateClassName] - A custom function to generate unique | ||
| * class names for scoped styles. | ||
| * @param {Object} [options.attributes] - An object containing attributes to be added | ||
| * to the `<style>` element in the DOM. | ||
| * @param {Array} [options.renderers=['parseStyles', 'renderStyles']] - An array of | ||
| * renderer functions or method names. The renderers are composed in sequence, where | ||
| * the first receives the styles object, and the last outputs the final CSS string. | ||
| * Strings or functions will be automatically bound to `this`. | ||
| * @param {Function} [options.shouldAttachToDOM] - A custom function to determine whether | ||
| * the StyleSheet should be added to the DOM. | ||
| * @param {Object} [options={}] - Configuration options. The following options are assigned to the instance (`this`): | ||
| * `prefix`, `generateUid`, `generateClassName`, `shouldAttachToDOM`, `attributes`, `renderers`. | ||
| * @param {String} [options.prefix='fun'] - Prefix for generating unique identifiers and data attributes. | ||
| * @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 {Function} [options.shouldAttachToDOM] - Custom function to determine whether the StyleSheet should be added to the DOM. | ||
| * | ||
@@ -53,14 +49,9 @@ * @example | ||
| * | ||
| * @property {Object} classes - An object mapping the original class names to the | ||
| * generated unique class names. Use this to reference the generated class names | ||
| * in your components. | ||
| * @property {Object} classes - Object mapping original class names to generated unique class names. | ||
| * @property {Object} styles - The original styles object provided to the instance. | ||
| * @property {String} uid - A unique identifier for the StyleSheet instance, generated | ||
| * using `this.generateUid`. | ||
| * @property {Object} attributes - The attributes object, derived from `options.attributes`, | ||
| * to be added to the `<style>` element. | ||
| * @property {Array} renderers - The array of renderer functions or method names used | ||
| * to process the styles object. | ||
| * @property {HTMLElement} el - A reference to the `<style>` element in the DOM. This | ||
| * is created when the instance is attached to the DOM. | ||
| * @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 {HTMLElement} el - Reference to the `<style>` element in the DOM. Created when the instance is attached to the DOM. | ||
| */ | ||
@@ -84,5 +75,6 @@ class StyleSheet { | ||
| // Generate class names. Only generate class names for top-level selectors. | ||
| let counter = 0; | ||
| Object.keys(styles).forEach(selector => { | ||
| if (selector.match(StyleSheet.classRegex)) { | ||
| this.classes[selector] = this.generateClassName(selector); | ||
| this.classes[selector] = this.generateClassName(selector, ++counter); | ||
| } | ||
@@ -108,3 +100,3 @@ }); | ||
| // Convert the hash to a shorter base-36 string. | ||
| return `${this.prefix}-${hash.toString(36)}`; | ||
| return hash.toString(36); | ||
| } | ||
@@ -116,8 +108,11 @@ | ||
| * to be used as class names in the styles object. | ||
| * May be overridden by `options.generateClassName`. | ||
| * 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. | ||
| */ | ||
| generateClassName(className) { | ||
| return `${this.uid}-${className}`; | ||
| generateClassName(className, index) { | ||
| return __DEV__ && StyleSheet.debug ? | ||
| `${this.prefix}-${this.uid}-${className}` : | ||
| `${this.prefix[0]}-${this.uid}-${index}`; | ||
| } | ||
@@ -131,7 +126,7 @@ | ||
| render() { | ||
| return compose( | ||
| ...this.renderers.map( | ||
| renderer => (typeof renderer === 'string' ? this[renderer] : renderer).bind(this) | ||
| ) | ||
| )(this.styles); | ||
| const renderers = this.renderers.map( | ||
| renderer => (typeof renderer === 'string' ? this[renderer] : renderer).bind(this) | ||
| ); | ||
| return compose(renderers)(this.styles); | ||
| } | ||
@@ -153,3 +148,3 @@ | ||
| // Format the CSS string. | ||
| if (StyleSheet.debug) { | ||
| if (__DEV__ && StyleSheet.debug) { | ||
| indent = StyleSheet.indent.repeat(level); | ||
@@ -221,4 +216,6 @@ nl = '\n'; | ||
| acc[selector] = {}; | ||
| // Don't expand at-rules. | ||
| const args = selector.match(/@/) ? [] : [acc, selector]; | ||
| // Regular styles. | ||
| Object.assign(acc[selector], this.parseStyles(value, acc, selector)); | ||
| Object.assign(acc[selector], this.parseStyles(value, ...args)); | ||
| } | ||
@@ -230,3 +227,3 @@ } else { | ||
| // Allows css vars to contain camelCase parts between dashes. | ||
| acc[key.includes('-') ? key : camelizedToDashed(key)] = value; | ||
| acc[key.match(/-/) ? key : camelizedToDashed(key)] = value; | ||
| } | ||
@@ -262,3 +259,3 @@ | ||
| const attributesHtml = Object.keys(attributes).map(key => ` ${key}="${attributes[key]}"`).join(''); | ||
| const nl = StyleSheet.debug ? '\n' : ''; | ||
| const nl = (__DEV__ && StyleSheet.debug) ? '\n' : ''; | ||
| return `<style${attributesHtml}>${nl}${this.render()}</style>${nl}`; | ||
@@ -327,3 +324,3 @@ } | ||
| this.el = null; | ||
| } | ||
| } | ||
@@ -334,3 +331,4 @@ return this; | ||
| /** | ||
| * Render all instances in the registry as a string. | ||
| * Render all instances in the registry as a string, including the style tags. | ||
| * Can be used to insert style tags in an HTML template for server-side rendering. | ||
| * @returns {string} All instances in the registry as a string. | ||
@@ -344,2 +342,12 @@ * @static | ||
| /** | ||
| * Render all instances in the registry as CSS string. | ||
| * Can be used to generate an external CSS file. | ||
| * @returns {string} All instances in the registry rendered as CSS string. | ||
| * @static | ||
| */ | ||
| static toCSS() { | ||
| return StyleSheet.registry.map(instance => instance.render()).join(''); | ||
| } | ||
| /** | ||
| * Destroy all instances in the registry and remove them from | ||
@@ -414,6 +422,7 @@ * it and from the DOM. | ||
| * indentation and new lines. | ||
| * @default false | ||
| * @default __DEV__ | ||
| */ | ||
| StyleSheet.debug = false; | ||
| StyleSheet.debug = __DEV__; | ||
| export { StyleSheet as default }; | ||
| //# sourceMappingURL=StyleSheet.js.map |
@@ -5,2 +5,3 @@ 'use strict'; | ||
| var css = require('./css.cjs'); | ||
| require('./dev.cjs'); | ||
@@ -134,1 +135,2 @@ const makeCssVars = (theme = {}, prefix = '--') => { | ||
| module.exports = createTheme; | ||
| //# sourceMappingURL=createTheme.cjs.map |
+2
-0
| 'use strict'; | ||
| var StyleSheet = require('./StyleSheet.cjs'); | ||
| require('./dev.cjs'); | ||
@@ -31,1 +32,2 @@ /** | ||
| module.exports = css; | ||
| //# sourceMappingURL=css.cjs.map |
+2
-0
@@ -6,2 +6,3 @@ 'use strict'; | ||
| var createTheme = require('./createTheme.cjs'); | ||
| require('./dev.cjs'); | ||
@@ -13,1 +14,2 @@ | ||
| exports.createTheme = createTheme; | ||
| //# sourceMappingURL=index.cjs.map |
+54
-45
| 'use strict'; | ||
| var dev = require('./dev.cjs'); | ||
| const camelizedToDashed = str => str.replace(/([A-Z])/g, (g) => `-${g[0].toLowerCase()}`); | ||
| const compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args))); | ||
| const compose = fns => fns.reduce((f, g) => (...args) => f(g(...args))); | ||
@@ -19,17 +21,11 @@ const styleSheetOptions = ['prefix', 'generateUid', 'generateClassName', 'shouldAttachToDOM', 'attributes', 'renderers']; | ||
| * the renderers to generate the final CSS string. It is stored in the instance as `this.styles`. | ||
| * @param {Object} [options={}] - Optional configuration options for the StyleSheet instance. | ||
| * @param {String} [options.prefix='fun'] - A prefix used for generating unique identifiers | ||
| * and data attributes. | ||
| * @param {Function} [options.generateUid] - A custom function to generate the unique | ||
| * identifier for the StyleSheet instance. | ||
| * @param {Function} [options.generateClassName] - A custom function to generate unique | ||
| * class names for scoped styles. | ||
| * @param {Object} [options.attributes] - An object containing attributes to be added | ||
| * to the `<style>` element in the DOM. | ||
| * @param {Array} [options.renderers=['parseStyles', 'renderStyles']] - An array of | ||
| * renderer functions or method names. The renderers are composed in sequence, where | ||
| * the first receives the styles object, and the last outputs the final CSS string. | ||
| * Strings or functions will be automatically bound to `this`. | ||
| * @param {Function} [options.shouldAttachToDOM] - A custom function to determine whether | ||
| * the StyleSheet should be added to the DOM. | ||
| * @param {Object} [options={}] - Configuration options. The following options are assigned to the instance (`this`): | ||
| * `prefix`, `generateUid`, `generateClassName`, `shouldAttachToDOM`, `attributes`, `renderers`. | ||
| * @param {String} [options.prefix='fun'] - Prefix for generating unique identifiers and data attributes. | ||
| * @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 {Function} [options.shouldAttachToDOM] - Custom function to determine whether the StyleSheet should be added to the DOM. | ||
| * | ||
@@ -55,14 +51,9 @@ * @example | ||
| * | ||
| * @property {Object} classes - An object mapping the original class names to the | ||
| * generated unique class names. Use this to reference the generated class names | ||
| * in your components. | ||
| * @property {Object} classes - Object mapping original class names to generated unique class names. | ||
| * @property {Object} styles - The original styles object provided to the instance. | ||
| * @property {String} uid - A unique identifier for the StyleSheet instance, generated | ||
| * using `this.generateUid`. | ||
| * @property {Object} attributes - The attributes object, derived from `options.attributes`, | ||
| * to be added to the `<style>` element. | ||
| * @property {Array} renderers - The array of renderer functions or method names used | ||
| * to process the styles object. | ||
| * @property {HTMLElement} el - A reference to the `<style>` element in the DOM. This | ||
| * is created when the instance is attached to the DOM. | ||
| * @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 {HTMLElement} el - Reference to the `<style>` element in the DOM. Created when the instance is attached to the DOM. | ||
| */ | ||
@@ -86,5 +77,6 @@ class StyleSheet { | ||
| // Generate class names. Only generate class names for top-level selectors. | ||
| let counter = 0; | ||
| Object.keys(styles).forEach(selector => { | ||
| if (selector.match(StyleSheet.classRegex)) { | ||
| this.classes[selector] = this.generateClassName(selector); | ||
| this.classes[selector] = this.generateClassName(selector, ++counter); | ||
| } | ||
@@ -110,3 +102,3 @@ }); | ||
| // Convert the hash to a shorter base-36 string. | ||
| return `${this.prefix}-${hash.toString(36)}`; | ||
| return hash.toString(36); | ||
| } | ||
@@ -118,8 +110,11 @@ | ||
| * to be used as class names in the styles object. | ||
| * May be overridden by `options.generateClassName`. | ||
| * 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. | ||
| */ | ||
| generateClassName(className) { | ||
| return `${this.uid}-${className}`; | ||
| generateClassName(className, index) { | ||
| return dev && StyleSheet.debug ? | ||
| `${this.prefix}-${this.uid}-${className}` : | ||
| `${this.prefix[0]}-${this.uid}-${index}`; | ||
| } | ||
@@ -133,7 +128,7 @@ | ||
| render() { | ||
| return compose( | ||
| ...this.renderers.map( | ||
| renderer => (typeof renderer === 'string' ? this[renderer] : renderer).bind(this) | ||
| ) | ||
| )(this.styles); | ||
| const renderers = this.renderers.map( | ||
| renderer => (typeof renderer === 'string' ? this[renderer] : renderer).bind(this) | ||
| ); | ||
| return compose(renderers)(this.styles); | ||
| } | ||
@@ -155,3 +150,3 @@ | ||
| // Format the CSS string. | ||
| if (StyleSheet.debug) { | ||
| if (dev && StyleSheet.debug) { | ||
| indent = StyleSheet.indent.repeat(level); | ||
@@ -223,4 +218,6 @@ nl = '\n'; | ||
| acc[selector] = {}; | ||
| // Don't expand at-rules. | ||
| const args = selector.match(/@/) ? [] : [acc, selector]; | ||
| // Regular styles. | ||
| Object.assign(acc[selector], this.parseStyles(value, acc, selector)); | ||
| Object.assign(acc[selector], this.parseStyles(value, ...args)); | ||
| } | ||
@@ -232,3 +229,3 @@ } else { | ||
| // Allows css vars to contain camelCase parts between dashes. | ||
| acc[key.includes('-') ? key : camelizedToDashed(key)] = value; | ||
| acc[key.match(/-/) ? key : camelizedToDashed(key)] = value; | ||
| } | ||
@@ -264,3 +261,3 @@ | ||
| const attributesHtml = Object.keys(attributes).map(key => ` ${key}="${attributes[key]}"`).join(''); | ||
| const nl = StyleSheet.debug ? '\n' : ''; | ||
| const nl = (dev && StyleSheet.debug) ? '\n' : ''; | ||
| return `<style${attributesHtml}>${nl}${this.render()}</style>${nl}`; | ||
@@ -329,3 +326,3 @@ } | ||
| this.el = null; | ||
| } | ||
| } | ||
@@ -336,3 +333,4 @@ return this; | ||
| /** | ||
| * Render all instances in the registry as a string. | ||
| * Render all instances in the registry as a string, including the style tags. | ||
| * Can be used to insert style tags in an HTML template for server-side rendering. | ||
| * @returns {string} All instances in the registry as a string. | ||
@@ -346,2 +344,12 @@ * @static | ||
| /** | ||
| * Render all instances in the registry as CSS string. | ||
| * Can be used to generate an external CSS file. | ||
| * @returns {string} All instances in the registry rendered as CSS string. | ||
| * @static | ||
| */ | ||
| static toCSS() { | ||
| return StyleSheet.registry.map(instance => instance.render()).join(''); | ||
| } | ||
| /** | ||
| * Destroy all instances in the registry and remove them from | ||
@@ -416,6 +424,7 @@ * it and from the DOM. | ||
| * indentation and new lines. | ||
| * @default false | ||
| * @default __DEV__ | ||
| */ | ||
| StyleSheet.debug = false; | ||
| StyleSheet.debug = dev; | ||
| module.exports = StyleSheet; | ||
| //# sourceMappingURL=StyleSheet.cjs.map |
+13
-8
| { | ||
| "name": "cssfun", | ||
| "version": "0.0.11", | ||
| "version": "0.0.12", | ||
| "description": "Near-zero runtime CSS-in-JS library", | ||
@@ -33,2 +33,3 @@ "type": "module", | ||
| "build": "rollup -c", | ||
| "version": "node -e \"const fs=require('fs');const {execSync}=require('child_process');const v=require('./package.json').version;const re=/cssfun@(v)?\\d+\\.\\d+\\.\\d+(?:-[\\w.-]+)?/g;const files=['README.md','example/rasti/index.html','example/react/index.html','example/vanilla/index.html'];files.forEach(f=>{const t=fs.readFileSync(f,'utf8');fs.writeFileSync(f,t.replace(re,(m,p)=>'cssfun@'+(p||'')+v));});execSync('git add '+files.join(' '),{stdio:'inherit'});\"", | ||
| "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" | ||
@@ -56,12 +57,16 @@ }, | ||
| "devDependencies": { | ||
| "@eslint/js": "^9.34.0", | ||
| "@rollup/plugin-replace": "^6.0.3", | ||
| "@rollup/plugin-terser": "^0.4.4", | ||
| "chai": "^5.1.1", | ||
| "eslint": "^8.57.0", | ||
| "jsdoc-to-markdown": "^9.0.1", | ||
| "jsdom": "^25.0.0", | ||
| "jsdom-global": "^3.0.2", | ||
| "mocha": "^10.7.3", | ||
| "chai": "^6.0.1", | ||
| "eslint": "^9.34.0", | ||
| "glob": "^13.0.0", | ||
| "globals": "^16.3.0", | ||
| "jsdoc-to-markdown": "^9.1.2", | ||
| "jsdom": "^26.1.0", | ||
| "jsdom-global": "3.0.2", | ||
| "mocha": "^11.7.1", | ||
| "rimraf": "^6.0.1", | ||
| "rollup": "^4.21.3" | ||
| "rollup": "^4.48.1" | ||
| } | ||
| } |
+48
-27
@@ -1,5 +0,7 @@ | ||
| <picture> | ||
| <source media="(prefers-color-scheme: dark)" srcset="docs/logo-dark.png"> | ||
| <img alt="CSSFUN" src="docs/logo.png"> | ||
| </picture> | ||
| <p align="center"> | ||
| <picture> | ||
| <source media="(prefers-color-scheme: dark)" srcset="https://cdn.jsdelivr.net/gh/8tentaculos/cssfun@v0.0.12/docs/logo-dark.svg"> | ||
| <img alt="CSSFUN" src="https://cdn.jsdelivr.net/gh/8tentaculos/cssfun@v0.0.12/docs/logo.svg"> | ||
| </picture> | ||
| </p> | ||
@@ -43,3 +45,3 @@ <p align="center"> | ||
| ### Using npm | ||
| ### Installing via npm | ||
@@ -94,2 +96,9 @@ ```bash | ||
| > **Note**: All examples below show class names generated in **development mode**. | ||
| > In **production**, class names are optimized for smaller bundle size: | ||
| > - **Development**: `.fun-9qkk9s-root { color: red; }` (full prefix + class name) | ||
| > - **Production**: `.f-9qkk9s-1{color:red;}` (first letter of prefix + index) | ||
| > | ||
| > Customize via [`options.generateClassName`](/docs/api.md#new-stylesheetstyles-options) or by [extending the class](/docs/api.md#stylesheet__generateclassname). | ||
| #### Camelized keys will be transformed to dashed keys | ||
@@ -108,3 +117,3 @@ | ||
| ```html | ||
| <style data-fun-uid="fun-uwitok"> | ||
| <style data-fun-uid="uwitok"> | ||
| .fun-uwitok-root { | ||
@@ -136,3 +145,3 @@ background-color: black; | ||
| ```html | ||
| <style data-fun-uid="fun-1pxyvx7"> | ||
| <style data-fun-uid="1pxyvx7"> | ||
| .fun-1pxyvx7-button { | ||
@@ -168,3 +177,3 @@ background-color: white; | ||
| ```html | ||
| <style data-fun-uid="fun-169vukw"> | ||
| <style data-fun-uid="169vukw"> | ||
| .fun-169vukw-button { | ||
@@ -202,3 +211,3 @@ background-color: white; | ||
| ```html | ||
| <style data-fun-uid="fun-2xfpy0"> | ||
| <style data-fun-uid="2xfpy0"> | ||
| .fun-2xfpy0-button { | ||
@@ -233,3 +242,3 @@ background-color: white; | ||
| ```html | ||
| <style data-fun-uid="fun-ml03n3"> | ||
| <style data-fun-uid="ml03n3"> | ||
| body { | ||
@@ -257,3 +266,3 @@ background-color: black; | ||
| ```html | ||
| <style data-fun-uid="fun-1eia2eq"> | ||
| <style data-fun-uid="1eia2eq"> | ||
| .fun-1eia2eq-root a { | ||
@@ -277,3 +286,3 @@ color: black; | ||
| ```html | ||
| <style data-fun-uid="fun-1p1av20"> | ||
| <style data-fun-uid="1p1av20"> | ||
| body { | ||
@@ -299,3 +308,3 @@ background-color: black; | ||
| ```html | ||
| <style data-fun-uid="fun-xvd6jj"> | ||
| <style data-fun-uid="xvd6jj"> | ||
| .fun-xvd6jj-root a { | ||
@@ -423,17 +432,32 @@ color: black; | ||
| ```javascript | ||
| // Creating a theme | ||
| const theme = createTheme(themes); | ||
| import express from 'express'; | ||
| import React from 'react'; | ||
| import { renderToString } from 'react-dom/server'; | ||
| import { StyleSheet, createTheme } from 'cssfun'; | ||
| import App from './App.js'; | ||
| // Express route that renders the app and returns HTML to the browser | ||
| // Create a theme with light and dark modes | ||
| const theme = createTheme({ | ||
| light : { | ||
| bg : '#fff', | ||
| color : '#000' | ||
| }, | ||
| dark : { | ||
| bg : '#000', | ||
| color : '#fff' | ||
| } | ||
| }); | ||
| const app = express(); | ||
| app.get('*', (req, res) => { | ||
| // Render the app as an HTML string | ||
| // Render the app | ||
| const html = renderToString(<App />); | ||
| // Get all StyleSheets styles as a string of <style> elements | ||
| // Get generated styles as string | ||
| const styles = StyleSheet.toString(); | ||
| // Get the root class name from the theme | ||
| // Get theme root class | ||
| const cls = theme.classes.root; | ||
| // Create the full HTML page template | ||
| const template = ` | ||
@@ -444,4 +468,3 @@ <!DOCTYPE html> | ||
| <meta charset="UTF-8"> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
| <title>Waving Cat</title> | ||
| <title>SSR App</title> | ||
| ${styles} | ||
@@ -455,4 +478,3 @@ </head> | ||
| `; | ||
| // Send the complete HTML response | ||
| res.send(template); | ||
@@ -479,3 +501,2 @@ }); | ||
| - **[Vanilla JS Example](https://github.com/8tentaculos/cssfun/tree/master/example/vanilla)**: A straightforward JavaScript example showing how to use **CSSFUN** for styling HTML components. [Try it](https://plnkr.co/plunk/4ypn83Ru5Z6uwZew). | ||
| - **[Rasti with Server-Side Rendering (SSR) Example](https://github.com/8tentaculos/cssfun/tree/master/example/ssr)**: A Rasti application with server-side rendering using Express, highlighting how to use **CSSFUN** for styling in an SSR environment. | ||
@@ -482,0 +503,0 @@ ## License |
+3
-5
@@ -1,5 +0,3 @@ | ||
| import StyleSheet from './StyleSheet.js'; | ||
| import css from './css.js'; | ||
| import createTheme from './createTheme.js'; | ||
| export { StyleSheet, css, createTheme }; | ||
| export { default as StyleSheet } from './StyleSheet.js'; | ||
| export { default as css } from './css.js'; | ||
| export { default as createTheme } from './createTheme.js'; |
+53
-45
@@ -0,3 +1,5 @@ | ||
| import __DEV__ from './dev.js'; | ||
| const camelizedToDashed = str => str.replace(/([A-Z])/g, (g) => `-${g[0].toLowerCase()}`); | ||
| const compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args))); | ||
| const compose = fns => fns.reduce((f, g) => (...args) => f(g(...args))); | ||
@@ -17,17 +19,11 @@ const styleSheetOptions = ['prefix', 'generateUid', 'generateClassName', 'shouldAttachToDOM', 'attributes', 'renderers']; | ||
| * the renderers to generate the final CSS string. It is stored in the instance as `this.styles`. | ||
| * @param {Object} [options={}] - Optional configuration options for the StyleSheet instance. | ||
| * @param {String} [options.prefix='fun'] - A prefix used for generating unique identifiers | ||
| * and data attributes. | ||
| * @param {Function} [options.generateUid] - A custom function to generate the unique | ||
| * identifier for the StyleSheet instance. | ||
| * @param {Function} [options.generateClassName] - A custom function to generate unique | ||
| * class names for scoped styles. | ||
| * @param {Object} [options.attributes] - An object containing attributes to be added | ||
| * to the `<style>` element in the DOM. | ||
| * @param {Array} [options.renderers=['parseStyles', 'renderStyles']] - An array of | ||
| * renderer functions or method names. The renderers are composed in sequence, where | ||
| * the first receives the styles object, and the last outputs the final CSS string. | ||
| * Strings or functions will be automatically bound to `this`. | ||
| * @param {Function} [options.shouldAttachToDOM] - A custom function to determine whether | ||
| * the StyleSheet should be added to the DOM. | ||
| * @param {Object} [options={}] - Configuration options. The following options are assigned to the instance (`this`): | ||
| * `prefix`, `generateUid`, `generateClassName`, `shouldAttachToDOM`, `attributes`, `renderers`. | ||
| * @param {String} [options.prefix='fun'] - Prefix for generating unique identifiers and data attributes. | ||
| * @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 {Function} [options.shouldAttachToDOM] - Custom function to determine whether the StyleSheet should be added to the DOM. | ||
| * | ||
@@ -53,14 +49,9 @@ * @example | ||
| * | ||
| * @property {Object} classes - An object mapping the original class names to the | ||
| * generated unique class names. Use this to reference the generated class names | ||
| * in your components. | ||
| * @property {Object} classes - Object mapping original class names to generated unique class names. | ||
| * @property {Object} styles - The original styles object provided to the instance. | ||
| * @property {String} uid - A unique identifier for the StyleSheet instance, generated | ||
| * using `this.generateUid`. | ||
| * @property {Object} attributes - The attributes object, derived from `options.attributes`, | ||
| * to be added to the `<style>` element. | ||
| * @property {Array} renderers - The array of renderer functions or method names used | ||
| * to process the styles object. | ||
| * @property {HTMLElement} el - A reference to the `<style>` element in the DOM. This | ||
| * is created when the instance is attached to the DOM. | ||
| * @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 {HTMLElement} el - Reference to the `<style>` element in the DOM. Created when the instance is attached to the DOM. | ||
| */ | ||
@@ -84,5 +75,6 @@ class StyleSheet { | ||
| // Generate class names. Only generate class names for top-level selectors. | ||
| let counter = 0; | ||
| Object.keys(styles).forEach(selector => { | ||
| if (selector.match(StyleSheet.classRegex)) { | ||
| this.classes[selector] = this.generateClassName(selector); | ||
| this.classes[selector] = this.generateClassName(selector, ++counter); | ||
| } | ||
@@ -108,3 +100,3 @@ }); | ||
| // Convert the hash to a shorter base-36 string. | ||
| return `${this.prefix}-${hash.toString(36)}`; | ||
| return hash.toString(36); | ||
| } | ||
@@ -116,8 +108,11 @@ | ||
| * to be used as class names in the styles object. | ||
| * May be overridden by `options.generateClassName`. | ||
| * 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. | ||
| */ | ||
| generateClassName(className) { | ||
| return `${this.uid}-${className}`; | ||
| generateClassName(className, index) { | ||
| return __DEV__ && StyleSheet.debug ? | ||
| `${this.prefix}-${this.uid}-${className}` : | ||
| `${this.prefix[0]}-${this.uid}-${index}`; | ||
| } | ||
@@ -131,7 +126,7 @@ | ||
| render() { | ||
| return compose( | ||
| ...this.renderers.map( | ||
| renderer => (typeof renderer === 'string' ? this[renderer] : renderer).bind(this) | ||
| ) | ||
| )(this.styles); | ||
| const renderers = this.renderers.map( | ||
| renderer => (typeof renderer === 'string' ? this[renderer] : renderer).bind(this) | ||
| ); | ||
| return compose(renderers)(this.styles); | ||
| } | ||
@@ -153,3 +148,3 @@ | ||
| // Format the CSS string. | ||
| if (StyleSheet.debug) { | ||
| if (__DEV__ && StyleSheet.debug) { | ||
| indent = StyleSheet.indent.repeat(level); | ||
@@ -221,4 +216,6 @@ nl = '\n'; | ||
| acc[selector] = {}; | ||
| // Don't expand at-rules. | ||
| const args = selector.match(/@/) ? [] : [acc, selector]; | ||
| // Regular styles. | ||
| Object.assign(acc[selector], this.parseStyles(value, acc, selector)); | ||
| Object.assign(acc[selector], this.parseStyles(value, ...args)); | ||
| } | ||
@@ -230,3 +227,3 @@ } else { | ||
| // Allows css vars to contain camelCase parts between dashes. | ||
| acc[key.includes('-') ? key : camelizedToDashed(key)] = value; | ||
| acc[key.match(/-/) ? key : camelizedToDashed(key)] = value; | ||
| } | ||
@@ -262,3 +259,3 @@ | ||
| const attributesHtml = Object.keys(attributes).map(key => ` ${key}="${attributes[key]}"`).join(''); | ||
| const nl = StyleSheet.debug ? '\n' : ''; | ||
| const nl = (__DEV__ && StyleSheet.debug) ? '\n' : ''; | ||
| return `<style${attributesHtml}>${nl}${this.render()}</style>${nl}`; | ||
@@ -327,3 +324,3 @@ } | ||
| this.el = null; | ||
| } | ||
| } | ||
@@ -334,3 +331,4 @@ return this; | ||
| /** | ||
| * Render all instances in the registry as a string. | ||
| * Render all instances in the registry as a string, including the style tags. | ||
| * Can be used to insert style tags in an HTML template for server-side rendering. | ||
| * @returns {string} All instances in the registry as a string. | ||
@@ -344,2 +342,12 @@ * @static | ||
| /** | ||
| * Render all instances in the registry as CSS string. | ||
| * Can be used to generate an external CSS file. | ||
| * @returns {string} All instances in the registry rendered as CSS string. | ||
| * @static | ||
| */ | ||
| static toCSS() { | ||
| return StyleSheet.registry.map(instance => instance.render()).join(''); | ||
| } | ||
| /** | ||
| * Destroy all instances in the registry and remove them from | ||
@@ -414,6 +422,6 @@ * it and from the DOM. | ||
| * indentation and new lines. | ||
| * @default false | ||
| * @default __DEV__ | ||
| */ | ||
| StyleSheet.debug = false; | ||
| StyleSheet.debug = __DEV__; | ||
| export default StyleSheet; |
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
356748
219.51%32
88.24%2197
3.78%496
4.42%13
44.44%3
200%