Socket
Socket
Sign inDemoInstall

@vanilla-extract/css

Package Overview
Dependencies
Maintainers
4
Versions
122
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@vanilla-extract/css - npm Package Compare versions

Comparing version 0.1.0 to 0.2.0

dist/declarations/src/transformCss.d.ts

18

CHANGELOG.md
# @vanilla-extract/css
## 0.2.0
### Minor Changes
- [#20](https://github.com/seek-oss/vanilla-extract/pull/20) [`3311914`](https://github.com/seek-oss/vanilla-extract/commit/3311914d92406cda5d5bb71ee72075501f868bd5) Thanks [@mattcompiles](https://github.com/mattcompiles)! - Ensure generated hashes are scoped by package
vanilla-extract uses file path to ensure unique identifier (e.g. class names, CSS Variables, keyframes, etc) hashes across your application. This information is added to your `*.css.ts` files at build time. The issue with this approach is it meant `*.css.ts` files couldn't be pre-compiled when being published to npm.
This change adds support for pre-compilation of packages by adding package name information to identifier hashes.
* [#25](https://github.com/seek-oss/vanilla-extract/pull/25) [`c4bedd5`](https://github.com/seek-oss/vanilla-extract/commit/c4bedd571f0c21291b58e050589b4db9465c0460) Thanks [@markdalgleish](https://github.com/markdalgleish)! - The `createInlineTheme` function has now moved to the `@vanilla-extract/dynamic` package.
```diff
-import { createInlineTheme } from '@vanilla-extract/css/createInlineTheme';
+import { createInlineTheme } from '@vanilla-extract/dynamic';
```
## 0.1.0
### Minor Changes
- e83ad50: Initial release

5

dist/declarations/src/fileScope.d.ts

@@ -1,4 +0,5 @@

export declare function setFileScope(newFileScope: string): void;
import type { FileScope } from './types';
export declare function setFileScope(filePath: string, packageName?: string): void;
export declare function endFileScope(): void;
export declare function getFileScope(): string;
export declare function getFileScope(): FileScope;
export declare function getAndIncrementRefCounter(): number;

2

dist/declarations/src/index.d.ts
import './runtimeAdapter';
export type { StyleRule, GlobalStyleRule, Adapter } from './types';
export type { StyleRule, GlobalStyleRule, Adapter, FileScope } from './types';
export * from './identifier';

@@ -4,0 +4,0 @@ export * from './theme';

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

import type { Contract, MapLeafNodes, ThemeVars, Tokens } from './types';
import type { Contract, MapLeafNodes } from '@vanilla-extract/private';
import type { ThemeVars, Tokens } from './types';
export declare function createGlobalTheme<ThemeTokens extends Tokens>(selector: string, tokens: ThemeTokens): ThemeVars<ThemeTokens>;

@@ -3,0 +4,0 @@ export declare function createGlobalTheme<ThemeContract extends Contract>(selector: string, themeContract: ThemeContract, tokens: ThemeVars<ThemeContract>): void;

@@ -0,3 +1,4 @@

import type { Contract, MapLeafNodes } from '@vanilla-extract/private';
import type { PropertiesFallback, AtRule } from 'csstype';
import type { SimplePseudos } from './transformCSS';
import type { SimplePseudos } from './transformCss';
declare type BasicCSSProperties = PropertiesFallback<string | number>;

@@ -56,17 +57,15 @@ export interface CSSKeyframes {

export declare type CSS = CSSStyleBlock | CSSFontFaceBlock | CSSKeyframesBlock | CSSSelectorBlock;
export declare type FileScope = {
packageName?: string;
filePath: string;
};
export interface Adapter {
appendCss: (css: CSS, fileScope: string) => void;
appendCss: (css: CSS, fileScope: FileScope) => void;
registerClassName: (className: string) => void;
onEndFileScope: (fileScope: string) => void;
onEndFileScope: (fileScope: FileScope) => void;
}
export declare type Contract = {
[key: string]: string | null | Contract;
};
export declare type Tokens = {
[key: string]: string | Tokens;
};
export declare type MapLeafNodes<Obj, LeafType> = {
[Prop in keyof Obj]: Obj[Prop] extends Record<string | number, any> ? MapLeafNodes<Obj[Prop], LeafType> : LeafType;
};
export declare type ThemeVars<ThemeContract extends Contract> = MapLeafNodes<ThemeContract, string>;
export {};

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

import { MapLeafNodes } from './types';
declare type BasicObj = {
[key: string]: any;
};
export declare function get(obj: any, path: Array<string>): any;
export declare function forEach<Input extends BasicObj>(obj: Input | undefined, fn: <Key extends keyof Input>(value: Input[Key], key: string) => void): void;
export declare function omit<Input extends BasicObj, OmitKey extends string>(obj: Input | undefined, omitKeys: Array<OmitKey>): Omit<Input, OmitKey>;
export declare function mapKeys<Input extends BasicObj>(obj: Input | undefined, fn: <Key extends keyof Input>(value: Input[Key], key: string) => string): Record<string, Input[keyof Input]>;
export declare function walkObject<T, MapTo>(obj: T, fn: (value: string | number, path: Array<string>) => MapTo, path?: Array<string>): MapLeafNodes<T, MapTo>;
export declare function isEqual(a: any, b: any): boolean;
export {};

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

import type { Contract, MapLeafNodes } from './types';
import { Contract, MapLeafNodes } from '@vanilla-extract/private';
declare type ThemeVars<ThemeContract extends Contract> = MapLeafNodes<ThemeContract, string>;

@@ -3,0 +3,0 @@ export declare function createVar(debugId?: string): string;

@@ -5,8 +5,8 @@ 'use strict';

var cssesc = require('cssesc');
var validateSelector = require('./validateSelector-a9e44540.browser.cjs.js');
var utils = require('./utils-03507b0d.browser.cjs.js');
var transformCss_dist_vanillaExtractCssTransformCss = require('../transformCss/dist/vanilla-extract-css-transformCss.browser.cjs.js');
var adapter_dist_vanillaExtractCssAdapter = require('../adapter/dist/vanilla-extract-css-adapter.browser.cjs.js');
var hash = require('@emotion/hash');
var fileScope_dist_vanillaExtractCssFileScope = require('../fileScope/dist/vanilla-extract-css-fileScope.browser.cjs.js');
var _private = require('@vanilla-extract/private');
var cssesc = require('cssesc');
var dedent = require('dedent');

@@ -17,291 +17,6 @@ require('css-selector-parser');

var hash__default = /*#__PURE__*/_interopDefault(hash);
var cssesc__default = /*#__PURE__*/_interopDefault(cssesc);
var hash__default = /*#__PURE__*/_interopDefault(hash);
var dedent__default = /*#__PURE__*/_interopDefault(dedent);
const UNITLESS = {
boxFlex: true,
boxFlexGroup: true,
columnCount: true,
flex: true,
flexGrow: true,
flexPositive: true,
flexShrink: true,
flexNegative: true,
fontWeight: true,
lineClamp: true,
lineHeight: true,
opacity: true,
order: true,
orphans: true,
tabSize: true,
widows: true,
zIndex: true,
zoom: true,
fillOpacity: true,
strokeDashoffset: true,
strokeOpacity: true,
strokeWidth: true
};
const simplePseudos = [':-moz-any-link', ':-moz-full-screen', ':-moz-placeholder', ':-moz-read-only', ':-moz-read-write', ':-ms-fullscreen', ':-ms-input-placeholder', ':-webkit-any-link', ':-webkit-full-screen', '::-moz-placeholder', '::-moz-progress-bar', '::-moz-range-progress', '::-moz-range-thumb', '::-moz-range-track', '::-moz-selection', '::-ms-backdrop', '::-ms-browse', '::-ms-check', '::-ms-clear', '::-ms-fill', '::-ms-fill-lower', '::-ms-fill-upper', '::-ms-reveal', '::-ms-thumb', '::-ms-ticks-after', '::-ms-ticks-before', '::-ms-tooltip', '::-ms-track', '::-ms-value', '::-webkit-backdrop', '::-webkit-input-placeholder', '::-webkit-progress-bar', '::-webkit-progress-inner-value', '::-webkit-progress-value', '::-webkit-slider-runnable-track', '::-webkit-slider-thumb', '::after', '::backdrop', '::before', '::cue', '::first-letter', '::first-line', '::grammar-error', '::placeholder', '::selection', '::spelling-error', ':active', ':after', ':any-link', ':before', ':blank', ':checked', ':default', ':defined', ':disabled', ':empty', ':enabled', ':first', ':first-child', ':first-letter', ':first-line', ':first-of-type', ':focus', ':focus-visible', ':focus-within', ':fullscreen', ':hover', ':in-range', ':indeterminate', ':invalid', ':last-child', ':last-of-type', ':left', ':link', ':only-child', ':only-of-type', ':optional', ':out-of-range', ':placeholder-shown', ':read-only', ':read-write', ':required', ':right', ':root', ':scope', ':target', ':valid', ':visited'];
function dashify(str) {
return str.replace(/([A-Z])/g, '-$1').replace(/^ms-/, '-ms-').toLowerCase();
}
const DOUBLE_SPACE = ' ';
const simplePseudoSet = new Set(simplePseudos);
const specialKeys = [...simplePseudos, '@media', '@supports', 'selectors'];
class Stylesheet {
constructor(localClassNames) {
this.rules = [];
this.conditionalRules = [];
this.fontFaceRules = [];
this.keyframesRules = [];
this.localClassNameRegex = localClassNames.length > 0 ? RegExp(`(${localClassNames.join('|')})`, 'g') : null;
}
processCssObj(root) {
if (root.type === 'fontFace') {
this.fontFaceRules.push(root.rule);
return;
}
if (root.type === 'keyframes') {
this.keyframesRules.push(root);
return;
} // Add main styles
const mainRule = utils.omit(root.rule, specialKeys);
this.addRule({
selector: root.selector,
rule: mainRule
});
this.transformSimplePsuedos(root, root.rule);
this.transformMedia(root, root.rule['@media']);
this.transformSupports(root, root.rule['@supports']);
this.transformSelectors(root, root.rule);
}
addRule(cssRule) {
// Run `pixelifyProperties` before `transformVars` as we don't want to pixelify CSS Vars
const rule = this.transformVars(this.pixelifyProperties(cssRule.rule));
const selector = this.transformSelector(cssRule.selector);
if (cssRule.conditions) {
this.conditionalRules.push({
selector,
rule,
conditions: cssRule.conditions.sort()
});
} else {
this.rules.push({
selector,
rule
});
}
}
pixelifyProperties(cssRule) {
utils.forEach(cssRule, (value, key) => {
if (typeof value === 'number' && value !== 0 && !UNITLESS[key]) {
// @ts-expect-error Any ideas?
cssRule[key] = `${value}px`;
}
});
return cssRule;
}
transformVars({
vars,
...rest
}) {
if (!vars) {
return rest;
}
return { ...utils.mapKeys(vars, (_value, key) => {
const matches = key.match(/^var\((.*)\)$/);
if (matches) {
return matches[1];
}
return key;
}),
...rest
};
}
transformSelector(selector) {
return this.localClassNameRegex ? selector.replace(this.localClassNameRegex, (_, className, index) => {
if (index > 0 && selector[index - 1] === '.') {
return className;
}
return `.${cssesc__default['default'](className, {
isIdentifier: true
})}`;
}) : selector;
}
transformSelectors(root, rule, conditions) {
utils.forEach(rule.selectors, (selectorRule, selector) => {
if (root.type !== 'local') {
throw new Error(`Selectors are not allowed within ${root.type === 'global' ? '"globalStyle"' : '"selectors"'}`);
}
const transformedSelector = this.transformSelector(selector.replace(RegExp('&', 'g'), root.selector));
validateSelector.validateSelector(transformedSelector, root.selector);
this.addRule({
conditions,
selector: transformedSelector,
rule: utils.omit(selectorRule, specialKeys)
});
const selectorRoot = {
type: 'selector',
selector: transformedSelector,
rule: selectorRule
};
this.transformSupports(selectorRoot, selectorRule['@supports'], conditions);
this.transformMedia(selectorRoot, selectorRule['@media'], conditions);
});
}
transformMedia(root, rules, parentConditions = []) {
utils.forEach(rules, (mediaRule, query) => {
const conditions = [`@media ${query}`, ...parentConditions];
this.addRule({
conditions,
selector: root.selector,
rule: utils.omit(mediaRule, specialKeys)
});
if (root.type === 'local') {
this.transformSimplePsuedos(root, mediaRule, conditions);
this.transformSelectors(root, mediaRule, conditions);
}
this.transformSupports(root, mediaRule['@supports'], conditions);
});
}
transformSupports(root, rules, parentConditions = []) {
utils.forEach(rules, (supportsRule, query) => {
const conditions = [`@supports ${query}`, ...parentConditions];
this.addRule({
conditions,
selector: root.selector,
rule: utils.omit(supportsRule, specialKeys)
});
if (root.type === 'local') {
this.transformSimplePsuedos(root, supportsRule, conditions);
this.transformSelectors(root, supportsRule, conditions);
}
this.transformMedia(root, supportsRule['@media'], conditions);
});
}
transformSimplePsuedos(root, rule, conditions) {
for (const key of Object.keys(rule)) {
// Process simple psuedos
if (simplePseudoSet.has(key)) {
if (root.type !== 'local') {
throw new Error(`Simple pseudos are not valid in ${root.type === 'global' ? '"globalStyle"' : '"selectors"'}`);
}
this.addRule({
conditions,
selector: `${root.selector}${key}`,
rule: rule[key]
});
}
}
}
toPostcssJs() {
const styles = {};
if (this.fontFaceRules.length > 0) {
styles['@font-face'] = this.fontFaceRules;
}
this.keyframesRules.forEach(rule => {
styles[`@keyframes ${rule.name}`] = rule.rule;
});
for (const rule of [...this.rules, ...this.conditionalRules]) {
if (rule.conditions && utils.isEqual(styles[rule.selector], rule.rule)) {
// Ignore conditional rules if they are identical to a non-conditional rule
continue;
}
if (Object.keys(rule.rule).length === 0) {
// Ignore empty rules
continue;
}
let styleNode = styles;
for (const condition of rule.conditions || []) {
if (!styleNode[condition]) {
styleNode[condition] = {};
}
styleNode = styleNode[condition];
}
styleNode[rule.selector] = { ...styleNode[rule.selector],
...rule.rule
};
}
return styles;
}
toCss() {
const styles = this.toPostcssJs();
function walkCss(v, indent = '') {
const rules = [];
for (const key of Object.keys(v)) {
const value = v[key];
if (value && Array.isArray(value)) {
rules.push(...value.map(v => walkCss({
[key]: v
}, indent).join('\n')));
} else if (value && typeof value === 'object') {
rules.push(`${indent}${key} {\n${walkCss(value, indent + DOUBLE_SPACE).join('\n')}\n${indent}}`);
} else {
rules.push(`${indent}${key.startsWith('--') ? key : dashify(key)}: ${value};`);
}
}
return rules;
}
return walkCss(styles);
}
}
function transformCss({
localClassNames,
cssObjs
}) {
const stylesheet = new Stylesheet(localClassNames);
for (const root of cssObjs) {
stylesheet.processCssObj(root);
}
return stylesheet.toCss();
}
const stylesheets = {};

@@ -311,5 +26,10 @@ const localClassNames = new Set();

function getStylesheet(fileScope) {
if (stylesheets[fileScope]) {
return stylesheets[fileScope];
function getStylesheet({
packageName,
filePath
}) {
const fileScopeId = packageName ? `${packageName}${filePath}` : filePath;
if (stylesheets[fileScopeId]) {
return stylesheets[fileScopeId];
}

@@ -324,3 +44,3 @@

stylesheets[fileScope] = styleEl.sheet;
stylesheets[fileScopeId] = styleEl.sheet;
return styleEl.sheet;

@@ -337,3 +57,3 @@ }

onEndFileScope: fileScope => {
const css = transformCss({
const css = transformCss_dist_vanillaExtractCssTransformCss.transformCss({
localClassNames: Array.from(localClassNames),

@@ -374,4 +94,6 @@ cssObjs: bufferedCSSObjs

function getShortFileName() {
const fileScope = fileScope_dist_vanillaExtractCssFileScope.getFileScope();
const matches = fileScope.match(/.*\/(.*)\..*\..*$/);
const {
filePath
} = fileScope_dist_vanillaExtractCssFileScope.getFileScope();
const matches = filePath.match(/.*\/(.*)\..*\..*$/);

@@ -387,3 +109,8 @@ if (matches && matches[1]) {

const refCount = fileScope_dist_vanillaExtractCssFileScope.getAndIncrementRefCounter();
const identifier = process.env.NODE_ENV !== 'production' && debugId ? `${getShortFileName()}_${debugId}__${hash__default['default'](fileScope_dist_vanillaExtractCssFileScope.getFileScope())}${refCount}` : `${hash__default['default'](fileScope_dist_vanillaExtractCssFileScope.getFileScope())}${refCount}`;
const {
filePath,
packageName
} = fileScope_dist_vanillaExtractCssFileScope.getFileScope();
const fileScopeHash = hash__default['default'](packageName ? `${packageName}${filePath}` : filePath);
const identifier = process.env.NODE_ENV !== 'production' && debugId ? `${getShortFileName()}_${debugId}__${fileScopeHash}${refCount}` : `${fileScopeHash}${refCount}`;
return identifier.match(/^[0-9]/) ? `_${identifier}` : identifier;

@@ -394,3 +121,8 @@ }

const refCount = fileScope_dist_vanillaExtractCssFileScope.getAndIncrementRefCounter();
const varName = process.env.NODE_ENV !== 'production' && debugId ? `${debugId}__${hash__default['default'](fileScope_dist_vanillaExtractCssFileScope.getFileScope())}${refCount}` : `${hash__default['default'](fileScope_dist_vanillaExtractCssFileScope.getFileScope())}${refCount}`; // Dashify CSS var names to replicate postcss-js behaviour
const {
filePath,
packageName
} = fileScope_dist_vanillaExtractCssFileScope.getFileScope();
const fileScopeHash = hash__default['default'](packageName ? `${packageName}${filePath}` : filePath);
const varName = process.env.NODE_ENV !== 'production' && debugId ? `${debugId}__${fileScopeHash}${refCount}` : `${fileScopeHash}${refCount}`; // Dashify CSS var names to replicate postcss-js behaviour
// See https://github.com/postcss/postcss-js/blob/d5127d4278c133f333f1c66f990f3552a907128e/parser.js#L30

@@ -425,4 +157,4 @@

utils.walkObject(tokens, (value, path) => {
varSetters[utils.get(varContract, path)] = String(value);
_private.walkObject(tokens, (value, path) => {
varSetters[_private.get(varContract, path)] = String(value);
});

@@ -432,3 +164,3 @@ return varSetters;

function createThemeVars(themeContract) {
return utils.walkObject(themeContract, (_value, path) => {
return _private.walkObject(themeContract, (_value, path) => {
return createVar(path.join('-'));

@@ -435,0 +167,0 @@ });

@@ -1,295 +0,10 @@

import cssesc from 'cssesc';
import { v as validateSelector } from './validateSelector-2dda5781.browser.esm.js';
import { o as omit, f as forEach, m as mapKeys, i as isEqual, w as walkObject, g as get } from './utils-24d5030c.browser.esm.js';
import { transformCss } from '../transformCss/dist/vanilla-extract-css-transformCss.browser.esm.js';
import { setAdapter, appendCss, registerClassName } from '../adapter/dist/vanilla-extract-css-adapter.browser.esm.js';
import hash from '@emotion/hash';
import { getAndIncrementRefCounter, getFileScope } from '../fileScope/dist/vanilla-extract-css-fileScope.browser.esm.js';
import { walkObject, get } from '@vanilla-extract/private';
import cssesc from 'cssesc';
import dedent from 'dedent';
import 'css-selector-parser';
const UNITLESS = {
boxFlex: true,
boxFlexGroup: true,
columnCount: true,
flex: true,
flexGrow: true,
flexPositive: true,
flexShrink: true,
flexNegative: true,
fontWeight: true,
lineClamp: true,
lineHeight: true,
opacity: true,
order: true,
orphans: true,
tabSize: true,
widows: true,
zIndex: true,
zoom: true,
fillOpacity: true,
strokeDashoffset: true,
strokeOpacity: true,
strokeWidth: true
};
const simplePseudos = [':-moz-any-link', ':-moz-full-screen', ':-moz-placeholder', ':-moz-read-only', ':-moz-read-write', ':-ms-fullscreen', ':-ms-input-placeholder', ':-webkit-any-link', ':-webkit-full-screen', '::-moz-placeholder', '::-moz-progress-bar', '::-moz-range-progress', '::-moz-range-thumb', '::-moz-range-track', '::-moz-selection', '::-ms-backdrop', '::-ms-browse', '::-ms-check', '::-ms-clear', '::-ms-fill', '::-ms-fill-lower', '::-ms-fill-upper', '::-ms-reveal', '::-ms-thumb', '::-ms-ticks-after', '::-ms-ticks-before', '::-ms-tooltip', '::-ms-track', '::-ms-value', '::-webkit-backdrop', '::-webkit-input-placeholder', '::-webkit-progress-bar', '::-webkit-progress-inner-value', '::-webkit-progress-value', '::-webkit-slider-runnable-track', '::-webkit-slider-thumb', '::after', '::backdrop', '::before', '::cue', '::first-letter', '::first-line', '::grammar-error', '::placeholder', '::selection', '::spelling-error', ':active', ':after', ':any-link', ':before', ':blank', ':checked', ':default', ':defined', ':disabled', ':empty', ':enabled', ':first', ':first-child', ':first-letter', ':first-line', ':first-of-type', ':focus', ':focus-visible', ':focus-within', ':fullscreen', ':hover', ':in-range', ':indeterminate', ':invalid', ':last-child', ':last-of-type', ':left', ':link', ':only-child', ':only-of-type', ':optional', ':out-of-range', ':placeholder-shown', ':read-only', ':read-write', ':required', ':right', ':root', ':scope', ':target', ':valid', ':visited'];
function dashify(str) {
return str.replace(/([A-Z])/g, '-$1').replace(/^ms-/, '-ms-').toLowerCase();
}
const DOUBLE_SPACE = ' ';
const simplePseudoSet = new Set(simplePseudos);
const specialKeys = [...simplePseudos, '@media', '@supports', 'selectors'];
class Stylesheet {
constructor(localClassNames) {
this.rules = [];
this.conditionalRules = [];
this.fontFaceRules = [];
this.keyframesRules = [];
this.localClassNameRegex = localClassNames.length > 0 ? RegExp(`(${localClassNames.join('|')})`, 'g') : null;
}
processCssObj(root) {
if (root.type === 'fontFace') {
this.fontFaceRules.push(root.rule);
return;
}
if (root.type === 'keyframes') {
this.keyframesRules.push(root);
return;
} // Add main styles
const mainRule = omit(root.rule, specialKeys);
this.addRule({
selector: root.selector,
rule: mainRule
});
this.transformSimplePsuedos(root, root.rule);
this.transformMedia(root, root.rule['@media']);
this.transformSupports(root, root.rule['@supports']);
this.transformSelectors(root, root.rule);
}
addRule(cssRule) {
// Run `pixelifyProperties` before `transformVars` as we don't want to pixelify CSS Vars
const rule = this.transformVars(this.pixelifyProperties(cssRule.rule));
const selector = this.transformSelector(cssRule.selector);
if (cssRule.conditions) {
this.conditionalRules.push({
selector,
rule,
conditions: cssRule.conditions.sort()
});
} else {
this.rules.push({
selector,
rule
});
}
}
pixelifyProperties(cssRule) {
forEach(cssRule, (value, key) => {
if (typeof value === 'number' && value !== 0 && !UNITLESS[key]) {
// @ts-expect-error Any ideas?
cssRule[key] = `${value}px`;
}
});
return cssRule;
}
transformVars({
vars,
...rest
}) {
if (!vars) {
return rest;
}
return { ...mapKeys(vars, (_value, key) => {
const matches = key.match(/^var\((.*)\)$/);
if (matches) {
return matches[1];
}
return key;
}),
...rest
};
}
transformSelector(selector) {
return this.localClassNameRegex ? selector.replace(this.localClassNameRegex, (_, className, index) => {
if (index > 0 && selector[index - 1] === '.') {
return className;
}
return `.${cssesc(className, {
isIdentifier: true
})}`;
}) : selector;
}
transformSelectors(root, rule, conditions) {
forEach(rule.selectors, (selectorRule, selector) => {
if (root.type !== 'local') {
throw new Error(`Selectors are not allowed within ${root.type === 'global' ? '"globalStyle"' : '"selectors"'}`);
}
const transformedSelector = this.transformSelector(selector.replace(RegExp('&', 'g'), root.selector));
validateSelector(transformedSelector, root.selector);
this.addRule({
conditions,
selector: transformedSelector,
rule: omit(selectorRule, specialKeys)
});
const selectorRoot = {
type: 'selector',
selector: transformedSelector,
rule: selectorRule
};
this.transformSupports(selectorRoot, selectorRule['@supports'], conditions);
this.transformMedia(selectorRoot, selectorRule['@media'], conditions);
});
}
transformMedia(root, rules, parentConditions = []) {
forEach(rules, (mediaRule, query) => {
const conditions = [`@media ${query}`, ...parentConditions];
this.addRule({
conditions,
selector: root.selector,
rule: omit(mediaRule, specialKeys)
});
if (root.type === 'local') {
this.transformSimplePsuedos(root, mediaRule, conditions);
this.transformSelectors(root, mediaRule, conditions);
}
this.transformSupports(root, mediaRule['@supports'], conditions);
});
}
transformSupports(root, rules, parentConditions = []) {
forEach(rules, (supportsRule, query) => {
const conditions = [`@supports ${query}`, ...parentConditions];
this.addRule({
conditions,
selector: root.selector,
rule: omit(supportsRule, specialKeys)
});
if (root.type === 'local') {
this.transformSimplePsuedos(root, supportsRule, conditions);
this.transformSelectors(root, supportsRule, conditions);
}
this.transformMedia(root, supportsRule['@media'], conditions);
});
}
transformSimplePsuedos(root, rule, conditions) {
for (const key of Object.keys(rule)) {
// Process simple psuedos
if (simplePseudoSet.has(key)) {
if (root.type !== 'local') {
throw new Error(`Simple pseudos are not valid in ${root.type === 'global' ? '"globalStyle"' : '"selectors"'}`);
}
this.addRule({
conditions,
selector: `${root.selector}${key}`,
rule: rule[key]
});
}
}
}
toPostcssJs() {
const styles = {};
if (this.fontFaceRules.length > 0) {
styles['@font-face'] = this.fontFaceRules;
}
this.keyframesRules.forEach(rule => {
styles[`@keyframes ${rule.name}`] = rule.rule;
});
for (const rule of [...this.rules, ...this.conditionalRules]) {
if (rule.conditions && isEqual(styles[rule.selector], rule.rule)) {
// Ignore conditional rules if they are identical to a non-conditional rule
continue;
}
if (Object.keys(rule.rule).length === 0) {
// Ignore empty rules
continue;
}
let styleNode = styles;
for (const condition of rule.conditions || []) {
if (!styleNode[condition]) {
styleNode[condition] = {};
}
styleNode = styleNode[condition];
}
styleNode[rule.selector] = { ...styleNode[rule.selector],
...rule.rule
};
}
return styles;
}
toCss() {
const styles = this.toPostcssJs();
function walkCss(v, indent = '') {
const rules = [];
for (const key of Object.keys(v)) {
const value = v[key];
if (value && Array.isArray(value)) {
rules.push(...value.map(v => walkCss({
[key]: v
}, indent).join('\n')));
} else if (value && typeof value === 'object') {
rules.push(`${indent}${key} {\n${walkCss(value, indent + DOUBLE_SPACE).join('\n')}\n${indent}}`);
} else {
rules.push(`${indent}${key.startsWith('--') ? key : dashify(key)}: ${value};`);
}
}
return rules;
}
return walkCss(styles);
}
}
function transformCss({
localClassNames,
cssObjs
}) {
const stylesheet = new Stylesheet(localClassNames);
for (const root of cssObjs) {
stylesheet.processCssObj(root);
}
return stylesheet.toCss();
}
const stylesheets = {};

@@ -299,5 +14,10 @@ const localClassNames = new Set();

function getStylesheet(fileScope) {
if (stylesheets[fileScope]) {
return stylesheets[fileScope];
function getStylesheet({
packageName,
filePath
}) {
const fileScopeId = packageName ? `${packageName}${filePath}` : filePath;
if (stylesheets[fileScopeId]) {
return stylesheets[fileScopeId];
}

@@ -312,3 +32,3 @@

stylesheets[fileScope] = styleEl.sheet;
stylesheets[fileScopeId] = styleEl.sheet;
return styleEl.sheet;

@@ -361,4 +81,6 @@ }

function getShortFileName() {
const fileScope = getFileScope();
const matches = fileScope.match(/.*\/(.*)\..*\..*$/);
const {
filePath
} = getFileScope();
const matches = filePath.match(/.*\/(.*)\..*\..*$/);

@@ -374,3 +96,8 @@ if (matches && matches[1]) {

const refCount = getAndIncrementRefCounter();
const identifier = process.env.NODE_ENV !== 'production' && debugId ? `${getShortFileName()}_${debugId}__${hash(getFileScope())}${refCount}` : `${hash(getFileScope())}${refCount}`;
const {
filePath,
packageName
} = getFileScope();
const fileScopeHash = hash(packageName ? `${packageName}${filePath}` : filePath);
const identifier = process.env.NODE_ENV !== 'production' && debugId ? `${getShortFileName()}_${debugId}__${fileScopeHash}${refCount}` : `${fileScopeHash}${refCount}`;
return identifier.match(/^[0-9]/) ? `_${identifier}` : identifier;

@@ -381,3 +108,8 @@ }

const refCount = getAndIncrementRefCounter();
const varName = process.env.NODE_ENV !== 'production' && debugId ? `${debugId}__${hash(getFileScope())}${refCount}` : `${hash(getFileScope())}${refCount}`; // Dashify CSS var names to replicate postcss-js behaviour
const {
filePath,
packageName
} = getFileScope();
const fileScopeHash = hash(packageName ? `${packageName}${filePath}` : filePath);
const varName = process.env.NODE_ENV !== 'production' && debugId ? `${debugId}__${fileScopeHash}${refCount}` : `${fileScopeHash}${refCount}`; // Dashify CSS var names to replicate postcss-js behaviour
// See https://github.com/postcss/postcss-js/blob/d5127d4278c133f333f1c66f990f3552a907128e/parser.js#L30

@@ -384,0 +116,0 @@

@@ -5,8 +5,8 @@ 'use strict';

var cssesc = require('cssesc');
var validateSelector = require('./validateSelector-acadedf9.cjs.dev.js');
var utils = require('./utils-c5ab417f.cjs.dev.js');
var transformCss_dist_vanillaExtractCssTransformCss = require('../transformCss/dist/vanilla-extract-css-transformCss.cjs.dev.js');
var adapter_dist_vanillaExtractCssAdapter = require('../adapter/dist/vanilla-extract-css-adapter.cjs.dev.js');
var hash = require('@emotion/hash');
var fileScope_dist_vanillaExtractCssFileScope = require('../fileScope/dist/vanilla-extract-css-fileScope.cjs.dev.js');
var _private = require('@vanilla-extract/private');
var cssesc = require('cssesc');
var dedent = require('dedent');

@@ -17,291 +17,6 @@ require('css-selector-parser');

var hash__default = /*#__PURE__*/_interopDefault(hash);
var cssesc__default = /*#__PURE__*/_interopDefault(cssesc);
var hash__default = /*#__PURE__*/_interopDefault(hash);
var dedent__default = /*#__PURE__*/_interopDefault(dedent);
const UNITLESS = {
boxFlex: true,
boxFlexGroup: true,
columnCount: true,
flex: true,
flexGrow: true,
flexPositive: true,
flexShrink: true,
flexNegative: true,
fontWeight: true,
lineClamp: true,
lineHeight: true,
opacity: true,
order: true,
orphans: true,
tabSize: true,
widows: true,
zIndex: true,
zoom: true,
fillOpacity: true,
strokeDashoffset: true,
strokeOpacity: true,
strokeWidth: true
};
const simplePseudos = [':-moz-any-link', ':-moz-full-screen', ':-moz-placeholder', ':-moz-read-only', ':-moz-read-write', ':-ms-fullscreen', ':-ms-input-placeholder', ':-webkit-any-link', ':-webkit-full-screen', '::-moz-placeholder', '::-moz-progress-bar', '::-moz-range-progress', '::-moz-range-thumb', '::-moz-range-track', '::-moz-selection', '::-ms-backdrop', '::-ms-browse', '::-ms-check', '::-ms-clear', '::-ms-fill', '::-ms-fill-lower', '::-ms-fill-upper', '::-ms-reveal', '::-ms-thumb', '::-ms-ticks-after', '::-ms-ticks-before', '::-ms-tooltip', '::-ms-track', '::-ms-value', '::-webkit-backdrop', '::-webkit-input-placeholder', '::-webkit-progress-bar', '::-webkit-progress-inner-value', '::-webkit-progress-value', '::-webkit-slider-runnable-track', '::-webkit-slider-thumb', '::after', '::backdrop', '::before', '::cue', '::first-letter', '::first-line', '::grammar-error', '::placeholder', '::selection', '::spelling-error', ':active', ':after', ':any-link', ':before', ':blank', ':checked', ':default', ':defined', ':disabled', ':empty', ':enabled', ':first', ':first-child', ':first-letter', ':first-line', ':first-of-type', ':focus', ':focus-visible', ':focus-within', ':fullscreen', ':hover', ':in-range', ':indeterminate', ':invalid', ':last-child', ':last-of-type', ':left', ':link', ':only-child', ':only-of-type', ':optional', ':out-of-range', ':placeholder-shown', ':read-only', ':read-write', ':required', ':right', ':root', ':scope', ':target', ':valid', ':visited'];
function dashify(str) {
return str.replace(/([A-Z])/g, '-$1').replace(/^ms-/, '-ms-').toLowerCase();
}
const DOUBLE_SPACE = ' ';
const simplePseudoSet = new Set(simplePseudos);
const specialKeys = [...simplePseudos, '@media', '@supports', 'selectors'];
class Stylesheet {
constructor(localClassNames) {
this.rules = [];
this.conditionalRules = [];
this.fontFaceRules = [];
this.keyframesRules = [];
this.localClassNameRegex = localClassNames.length > 0 ? RegExp(`(${localClassNames.join('|')})`, 'g') : null;
}
processCssObj(root) {
if (root.type === 'fontFace') {
this.fontFaceRules.push(root.rule);
return;
}
if (root.type === 'keyframes') {
this.keyframesRules.push(root);
return;
} // Add main styles
const mainRule = utils.omit(root.rule, specialKeys);
this.addRule({
selector: root.selector,
rule: mainRule
});
this.transformSimplePsuedos(root, root.rule);
this.transformMedia(root, root.rule['@media']);
this.transformSupports(root, root.rule['@supports']);
this.transformSelectors(root, root.rule);
}
addRule(cssRule) {
// Run `pixelifyProperties` before `transformVars` as we don't want to pixelify CSS Vars
const rule = this.transformVars(this.pixelifyProperties(cssRule.rule));
const selector = this.transformSelector(cssRule.selector);
if (cssRule.conditions) {
this.conditionalRules.push({
selector,
rule,
conditions: cssRule.conditions.sort()
});
} else {
this.rules.push({
selector,
rule
});
}
}
pixelifyProperties(cssRule) {
utils.forEach(cssRule, (value, key) => {
if (typeof value === 'number' && value !== 0 && !UNITLESS[key]) {
// @ts-expect-error Any ideas?
cssRule[key] = `${value}px`;
}
});
return cssRule;
}
transformVars({
vars,
...rest
}) {
if (!vars) {
return rest;
}
return { ...utils.mapKeys(vars, (_value, key) => {
const matches = key.match(/^var\((.*)\)$/);
if (matches) {
return matches[1];
}
return key;
}),
...rest
};
}
transformSelector(selector) {
return this.localClassNameRegex ? selector.replace(this.localClassNameRegex, (_, className, index) => {
if (index > 0 && selector[index - 1] === '.') {
return className;
}
return `.${cssesc__default['default'](className, {
isIdentifier: true
})}`;
}) : selector;
}
transformSelectors(root, rule, conditions) {
utils.forEach(rule.selectors, (selectorRule, selector) => {
if (root.type !== 'local') {
throw new Error(`Selectors are not allowed within ${root.type === 'global' ? '"globalStyle"' : '"selectors"'}`);
}
const transformedSelector = this.transformSelector(selector.replace(RegExp('&', 'g'), root.selector));
validateSelector.validateSelector(transformedSelector, root.selector);
this.addRule({
conditions,
selector: transformedSelector,
rule: utils.omit(selectorRule, specialKeys)
});
const selectorRoot = {
type: 'selector',
selector: transformedSelector,
rule: selectorRule
};
this.transformSupports(selectorRoot, selectorRule['@supports'], conditions);
this.transformMedia(selectorRoot, selectorRule['@media'], conditions);
});
}
transformMedia(root, rules, parentConditions = []) {
utils.forEach(rules, (mediaRule, query) => {
const conditions = [`@media ${query}`, ...parentConditions];
this.addRule({
conditions,
selector: root.selector,
rule: utils.omit(mediaRule, specialKeys)
});
if (root.type === 'local') {
this.transformSimplePsuedos(root, mediaRule, conditions);
this.transformSelectors(root, mediaRule, conditions);
}
this.transformSupports(root, mediaRule['@supports'], conditions);
});
}
transformSupports(root, rules, parentConditions = []) {
utils.forEach(rules, (supportsRule, query) => {
const conditions = [`@supports ${query}`, ...parentConditions];
this.addRule({
conditions,
selector: root.selector,
rule: utils.omit(supportsRule, specialKeys)
});
if (root.type === 'local') {
this.transformSimplePsuedos(root, supportsRule, conditions);
this.transformSelectors(root, supportsRule, conditions);
}
this.transformMedia(root, supportsRule['@media'], conditions);
});
}
transformSimplePsuedos(root, rule, conditions) {
for (const key of Object.keys(rule)) {
// Process simple psuedos
if (simplePseudoSet.has(key)) {
if (root.type !== 'local') {
throw new Error(`Simple pseudos are not valid in ${root.type === 'global' ? '"globalStyle"' : '"selectors"'}`);
}
this.addRule({
conditions,
selector: `${root.selector}${key}`,
rule: rule[key]
});
}
}
}
toPostcssJs() {
const styles = {};
if (this.fontFaceRules.length > 0) {
styles['@font-face'] = this.fontFaceRules;
}
this.keyframesRules.forEach(rule => {
styles[`@keyframes ${rule.name}`] = rule.rule;
});
for (const rule of [...this.rules, ...this.conditionalRules]) {
if (rule.conditions && utils.isEqual(styles[rule.selector], rule.rule)) {
// Ignore conditional rules if they are identical to a non-conditional rule
continue;
}
if (Object.keys(rule.rule).length === 0) {
// Ignore empty rules
continue;
}
let styleNode = styles;
for (const condition of rule.conditions || []) {
if (!styleNode[condition]) {
styleNode[condition] = {};
}
styleNode = styleNode[condition];
}
styleNode[rule.selector] = { ...styleNode[rule.selector],
...rule.rule
};
}
return styles;
}
toCss() {
const styles = this.toPostcssJs();
function walkCss(v, indent = '') {
const rules = [];
for (const key of Object.keys(v)) {
const value = v[key];
if (value && Array.isArray(value)) {
rules.push(...value.map(v => walkCss({
[key]: v
}, indent).join('\n')));
} else if (value && typeof value === 'object') {
rules.push(`${indent}${key} {\n${walkCss(value, indent + DOUBLE_SPACE).join('\n')}\n${indent}}`);
} else {
rules.push(`${indent}${key.startsWith('--') ? key : dashify(key)}: ${value};`);
}
}
return rules;
}
return walkCss(styles);
}
}
function transformCss({
localClassNames,
cssObjs
}) {
const stylesheet = new Stylesheet(localClassNames);
for (const root of cssObjs) {
stylesheet.processCssObj(root);
}
return stylesheet.toCss();
}
const stylesheets = {};

@@ -311,5 +26,10 @@ const localClassNames = new Set();

function getStylesheet(fileScope) {
if (stylesheets[fileScope]) {
return stylesheets[fileScope];
function getStylesheet({
packageName,
filePath
}) {
const fileScopeId = packageName ? `${packageName}${filePath}` : filePath;
if (stylesheets[fileScopeId]) {
return stylesheets[fileScopeId];
}

@@ -324,3 +44,3 @@

stylesheets[fileScope] = styleEl.sheet;
stylesheets[fileScopeId] = styleEl.sheet;
return styleEl.sheet;

@@ -337,3 +57,3 @@ }

onEndFileScope: fileScope => {
const css = transformCss({
const css = transformCss_dist_vanillaExtractCssTransformCss.transformCss({
localClassNames: Array.from(localClassNames),

@@ -374,4 +94,6 @@ cssObjs: bufferedCSSObjs

function getShortFileName() {
const fileScope = fileScope_dist_vanillaExtractCssFileScope.getFileScope();
const matches = fileScope.match(/.*\/(.*)\..*\..*$/);
const {
filePath
} = fileScope_dist_vanillaExtractCssFileScope.getFileScope();
const matches = filePath.match(/.*\/(.*)\..*\..*$/);

@@ -387,3 +109,8 @@ if (matches && matches[1]) {

const refCount = fileScope_dist_vanillaExtractCssFileScope.getAndIncrementRefCounter();
const identifier = process.env.NODE_ENV !== 'production' && debugId ? `${getShortFileName()}_${debugId}__${hash__default['default'](fileScope_dist_vanillaExtractCssFileScope.getFileScope())}${refCount}` : `${hash__default['default'](fileScope_dist_vanillaExtractCssFileScope.getFileScope())}${refCount}`;
const {
filePath,
packageName
} = fileScope_dist_vanillaExtractCssFileScope.getFileScope();
const fileScopeHash = hash__default['default'](packageName ? `${packageName}${filePath}` : filePath);
const identifier = process.env.NODE_ENV !== 'production' && debugId ? `${getShortFileName()}_${debugId}__${fileScopeHash}${refCount}` : `${fileScopeHash}${refCount}`;
return identifier.match(/^[0-9]/) ? `_${identifier}` : identifier;

@@ -394,3 +121,8 @@ }

const refCount = fileScope_dist_vanillaExtractCssFileScope.getAndIncrementRefCounter();
const varName = process.env.NODE_ENV !== 'production' && debugId ? `${debugId}__${hash__default['default'](fileScope_dist_vanillaExtractCssFileScope.getFileScope())}${refCount}` : `${hash__default['default'](fileScope_dist_vanillaExtractCssFileScope.getFileScope())}${refCount}`; // Dashify CSS var names to replicate postcss-js behaviour
const {
filePath,
packageName
} = fileScope_dist_vanillaExtractCssFileScope.getFileScope();
const fileScopeHash = hash__default['default'](packageName ? `${packageName}${filePath}` : filePath);
const varName = process.env.NODE_ENV !== 'production' && debugId ? `${debugId}__${fileScopeHash}${refCount}` : `${fileScopeHash}${refCount}`; // Dashify CSS var names to replicate postcss-js behaviour
// See https://github.com/postcss/postcss-js/blob/d5127d4278c133f333f1c66f990f3552a907128e/parser.js#L30

@@ -425,4 +157,4 @@

utils.walkObject(tokens, (value, path) => {
varSetters[utils.get(varContract, path)] = String(value);
_private.walkObject(tokens, (value, path) => {
varSetters[_private.get(varContract, path)] = String(value);
});

@@ -432,3 +164,3 @@ return varSetters;

function createThemeVars(themeContract) {
return utils.walkObject(themeContract, (_value, path) => {
return _private.walkObject(themeContract, (_value, path) => {
return createVar(path.join('-'));

@@ -435,0 +167,0 @@ });

@@ -5,8 +5,8 @@ 'use strict';

var cssesc = require('cssesc');
var validateSelector = require('./validateSelector-5a593081.cjs.prod.js');
var utils = require('./utils-2b734f0b.cjs.prod.js');
var transformCss_dist_vanillaExtractCssTransformCss = require('../transformCss/dist/vanilla-extract-css-transformCss.cjs.prod.js');
var adapter_dist_vanillaExtractCssAdapter = require('../adapter/dist/vanilla-extract-css-adapter.cjs.prod.js');
var hash = require('@emotion/hash');
var fileScope_dist_vanillaExtractCssFileScope = require('../fileScope/dist/vanilla-extract-css-fileScope.cjs.prod.js');
var _private = require('@vanilla-extract/private');
var cssesc = require('cssesc');
var dedent = require('dedent');

@@ -17,291 +17,6 @@ require('css-selector-parser');

var hash__default = /*#__PURE__*/_interopDefault(hash);
var cssesc__default = /*#__PURE__*/_interopDefault(cssesc);
var hash__default = /*#__PURE__*/_interopDefault(hash);
var dedent__default = /*#__PURE__*/_interopDefault(dedent);
const UNITLESS = {
boxFlex: true,
boxFlexGroup: true,
columnCount: true,
flex: true,
flexGrow: true,
flexPositive: true,
flexShrink: true,
flexNegative: true,
fontWeight: true,
lineClamp: true,
lineHeight: true,
opacity: true,
order: true,
orphans: true,
tabSize: true,
widows: true,
zIndex: true,
zoom: true,
fillOpacity: true,
strokeDashoffset: true,
strokeOpacity: true,
strokeWidth: true
};
const simplePseudos = [':-moz-any-link', ':-moz-full-screen', ':-moz-placeholder', ':-moz-read-only', ':-moz-read-write', ':-ms-fullscreen', ':-ms-input-placeholder', ':-webkit-any-link', ':-webkit-full-screen', '::-moz-placeholder', '::-moz-progress-bar', '::-moz-range-progress', '::-moz-range-thumb', '::-moz-range-track', '::-moz-selection', '::-ms-backdrop', '::-ms-browse', '::-ms-check', '::-ms-clear', '::-ms-fill', '::-ms-fill-lower', '::-ms-fill-upper', '::-ms-reveal', '::-ms-thumb', '::-ms-ticks-after', '::-ms-ticks-before', '::-ms-tooltip', '::-ms-track', '::-ms-value', '::-webkit-backdrop', '::-webkit-input-placeholder', '::-webkit-progress-bar', '::-webkit-progress-inner-value', '::-webkit-progress-value', '::-webkit-slider-runnable-track', '::-webkit-slider-thumb', '::after', '::backdrop', '::before', '::cue', '::first-letter', '::first-line', '::grammar-error', '::placeholder', '::selection', '::spelling-error', ':active', ':after', ':any-link', ':before', ':blank', ':checked', ':default', ':defined', ':disabled', ':empty', ':enabled', ':first', ':first-child', ':first-letter', ':first-line', ':first-of-type', ':focus', ':focus-visible', ':focus-within', ':fullscreen', ':hover', ':in-range', ':indeterminate', ':invalid', ':last-child', ':last-of-type', ':left', ':link', ':only-child', ':only-of-type', ':optional', ':out-of-range', ':placeholder-shown', ':read-only', ':read-write', ':required', ':right', ':root', ':scope', ':target', ':valid', ':visited'];
function dashify(str) {
return str.replace(/([A-Z])/g, '-$1').replace(/^ms-/, '-ms-').toLowerCase();
}
const DOUBLE_SPACE = ' ';
const simplePseudoSet = new Set(simplePseudos);
const specialKeys = [...simplePseudos, '@media', '@supports', 'selectors'];
class Stylesheet {
constructor(localClassNames) {
this.rules = [];
this.conditionalRules = [];
this.fontFaceRules = [];
this.keyframesRules = [];
this.localClassNameRegex = localClassNames.length > 0 ? RegExp(`(${localClassNames.join('|')})`, 'g') : null;
}
processCssObj(root) {
if (root.type === 'fontFace') {
this.fontFaceRules.push(root.rule);
return;
}
if (root.type === 'keyframes') {
this.keyframesRules.push(root);
return;
} // Add main styles
const mainRule = utils.omit(root.rule, specialKeys);
this.addRule({
selector: root.selector,
rule: mainRule
});
this.transformSimplePsuedos(root, root.rule);
this.transformMedia(root, root.rule['@media']);
this.transformSupports(root, root.rule['@supports']);
this.transformSelectors(root, root.rule);
}
addRule(cssRule) {
// Run `pixelifyProperties` before `transformVars` as we don't want to pixelify CSS Vars
const rule = this.transformVars(this.pixelifyProperties(cssRule.rule));
const selector = this.transformSelector(cssRule.selector);
if (cssRule.conditions) {
this.conditionalRules.push({
selector,
rule,
conditions: cssRule.conditions.sort()
});
} else {
this.rules.push({
selector,
rule
});
}
}
pixelifyProperties(cssRule) {
utils.forEach(cssRule, (value, key) => {
if (typeof value === 'number' && value !== 0 && !UNITLESS[key]) {
// @ts-expect-error Any ideas?
cssRule[key] = `${value}px`;
}
});
return cssRule;
}
transformVars({
vars,
...rest
}) {
if (!vars) {
return rest;
}
return { ...utils.mapKeys(vars, (_value, key) => {
const matches = key.match(/^var\((.*)\)$/);
if (matches) {
return matches[1];
}
return key;
}),
...rest
};
}
transformSelector(selector) {
return this.localClassNameRegex ? selector.replace(this.localClassNameRegex, (_, className, index) => {
if (index > 0 && selector[index - 1] === '.') {
return className;
}
return `.${cssesc__default['default'](className, {
isIdentifier: true
})}`;
}) : selector;
}
transformSelectors(root, rule, conditions) {
utils.forEach(rule.selectors, (selectorRule, selector) => {
if (root.type !== 'local') {
throw new Error(`Selectors are not allowed within ${root.type === 'global' ? '"globalStyle"' : '"selectors"'}`);
}
const transformedSelector = this.transformSelector(selector.replace(RegExp('&', 'g'), root.selector));
validateSelector.validateSelector(transformedSelector, root.selector);
this.addRule({
conditions,
selector: transformedSelector,
rule: utils.omit(selectorRule, specialKeys)
});
const selectorRoot = {
type: 'selector',
selector: transformedSelector,
rule: selectorRule
};
this.transformSupports(selectorRoot, selectorRule['@supports'], conditions);
this.transformMedia(selectorRoot, selectorRule['@media'], conditions);
});
}
transformMedia(root, rules, parentConditions = []) {
utils.forEach(rules, (mediaRule, query) => {
const conditions = [`@media ${query}`, ...parentConditions];
this.addRule({
conditions,
selector: root.selector,
rule: utils.omit(mediaRule, specialKeys)
});
if (root.type === 'local') {
this.transformSimplePsuedos(root, mediaRule, conditions);
this.transformSelectors(root, mediaRule, conditions);
}
this.transformSupports(root, mediaRule['@supports'], conditions);
});
}
transformSupports(root, rules, parentConditions = []) {
utils.forEach(rules, (supportsRule, query) => {
const conditions = [`@supports ${query}`, ...parentConditions];
this.addRule({
conditions,
selector: root.selector,
rule: utils.omit(supportsRule, specialKeys)
});
if (root.type === 'local') {
this.transformSimplePsuedos(root, supportsRule, conditions);
this.transformSelectors(root, supportsRule, conditions);
}
this.transformMedia(root, supportsRule['@media'], conditions);
});
}
transformSimplePsuedos(root, rule, conditions) {
for (const key of Object.keys(rule)) {
// Process simple psuedos
if (simplePseudoSet.has(key)) {
if (root.type !== 'local') {
throw new Error(`Simple pseudos are not valid in ${root.type === 'global' ? '"globalStyle"' : '"selectors"'}`);
}
this.addRule({
conditions,
selector: `${root.selector}${key}`,
rule: rule[key]
});
}
}
}
toPostcssJs() {
const styles = {};
if (this.fontFaceRules.length > 0) {
styles['@font-face'] = this.fontFaceRules;
}
this.keyframesRules.forEach(rule => {
styles[`@keyframes ${rule.name}`] = rule.rule;
});
for (const rule of [...this.rules, ...this.conditionalRules]) {
if (rule.conditions && utils.isEqual(styles[rule.selector], rule.rule)) {
// Ignore conditional rules if they are identical to a non-conditional rule
continue;
}
if (Object.keys(rule.rule).length === 0) {
// Ignore empty rules
continue;
}
let styleNode = styles;
for (const condition of rule.conditions || []) {
if (!styleNode[condition]) {
styleNode[condition] = {};
}
styleNode = styleNode[condition];
}
styleNode[rule.selector] = { ...styleNode[rule.selector],
...rule.rule
};
}
return styles;
}
toCss() {
const styles = this.toPostcssJs();
function walkCss(v, indent = '') {
const rules = [];
for (const key of Object.keys(v)) {
const value = v[key];
if (value && Array.isArray(value)) {
rules.push(...value.map(v => walkCss({
[key]: v
}, indent).join('\n')));
} else if (value && typeof value === 'object') {
rules.push(`${indent}${key} {\n${walkCss(value, indent + DOUBLE_SPACE).join('\n')}\n${indent}}`);
} else {
rules.push(`${indent}${key.startsWith('--') ? key : dashify(key)}: ${value};`);
}
}
return rules;
}
return walkCss(styles);
}
}
function transformCss({
localClassNames,
cssObjs
}) {
const stylesheet = new Stylesheet(localClassNames);
for (const root of cssObjs) {
stylesheet.processCssObj(root);
}
return stylesheet.toCss();
}
const stylesheets = {};

@@ -311,5 +26,10 @@ const localClassNames = new Set();

function getStylesheet(fileScope) {
if (stylesheets[fileScope]) {
return stylesheets[fileScope];
function getStylesheet({
packageName,
filePath
}) {
const fileScopeId = packageName ? `${packageName}${filePath}` : filePath;
if (stylesheets[fileScopeId]) {
return stylesheets[fileScopeId];
}

@@ -324,3 +44,3 @@

stylesheets[fileScope] = styleEl.sheet;
stylesheets[fileScopeId] = styleEl.sheet;
return styleEl.sheet;

@@ -337,3 +57,3 @@ }

onEndFileScope: fileScope => {
const css = transformCss({
const css = transformCss_dist_vanillaExtractCssTransformCss.transformCss({
localClassNames: Array.from(localClassNames),

@@ -375,3 +95,8 @@ cssObjs: bufferedCSSObjs

const refCount = fileScope_dist_vanillaExtractCssFileScope.getAndIncrementRefCounter();
const identifier = `${hash__default['default'](fileScope_dist_vanillaExtractCssFileScope.getFileScope())}${refCount}`;
const {
filePath,
packageName
} = fileScope_dist_vanillaExtractCssFileScope.getFileScope();
const fileScopeHash = hash__default['default'](packageName ? `${packageName}${filePath}` : filePath);
const identifier = `${fileScopeHash}${refCount}`;
return identifier.match(/^[0-9]/) ? `_${identifier}` : identifier;

@@ -382,3 +107,8 @@ }

const refCount = fileScope_dist_vanillaExtractCssFileScope.getAndIncrementRefCounter();
const varName = `${hash__default['default'](fileScope_dist_vanillaExtractCssFileScope.getFileScope())}${refCount}`; // Dashify CSS var names to replicate postcss-js behaviour
const {
filePath,
packageName
} = fileScope_dist_vanillaExtractCssFileScope.getFileScope();
const fileScopeHash = hash__default['default'](packageName ? `${packageName}${filePath}` : filePath);
const varName = `${fileScopeHash}${refCount}`; // Dashify CSS var names to replicate postcss-js behaviour
// See https://github.com/postcss/postcss-js/blob/d5127d4278c133f333f1c66f990f3552a907128e/parser.js#L30

@@ -413,4 +143,4 @@

utils.walkObject(tokens, (value, path) => {
varSetters[utils.get(varContract, path)] = String(value);
_private.walkObject(tokens, (value, path) => {
varSetters[_private.get(varContract, path)] = String(value);
});

@@ -420,3 +150,3 @@ return varSetters;

function createThemeVars(themeContract) {
return utils.walkObject(themeContract, (_value, path) => {
return _private.walkObject(themeContract, (_value, path) => {
return createVar(path.join('-'));

@@ -423,0 +153,0 @@ });

@@ -1,295 +0,10 @@

import cssesc from 'cssesc';
import { v as validateSelector } from './validateSelector-cfc75bf8.esm.js';
import { o as omit, f as forEach, m as mapKeys, i as isEqual, w as walkObject, g as get } from './utils-fbd6ce24.esm.js';
import { transformCss } from '../transformCss/dist/vanilla-extract-css-transformCss.esm.js';
import { setAdapter, appendCss, registerClassName } from '../adapter/dist/vanilla-extract-css-adapter.esm.js';
import hash from '@emotion/hash';
import { getAndIncrementRefCounter, getFileScope } from '../fileScope/dist/vanilla-extract-css-fileScope.esm.js';
import { walkObject, get } from '@vanilla-extract/private';
import cssesc from 'cssesc';
import dedent from 'dedent';
import 'css-selector-parser';
const UNITLESS = {
boxFlex: true,
boxFlexGroup: true,
columnCount: true,
flex: true,
flexGrow: true,
flexPositive: true,
flexShrink: true,
flexNegative: true,
fontWeight: true,
lineClamp: true,
lineHeight: true,
opacity: true,
order: true,
orphans: true,
tabSize: true,
widows: true,
zIndex: true,
zoom: true,
fillOpacity: true,
strokeDashoffset: true,
strokeOpacity: true,
strokeWidth: true
};
const simplePseudos = [':-moz-any-link', ':-moz-full-screen', ':-moz-placeholder', ':-moz-read-only', ':-moz-read-write', ':-ms-fullscreen', ':-ms-input-placeholder', ':-webkit-any-link', ':-webkit-full-screen', '::-moz-placeholder', '::-moz-progress-bar', '::-moz-range-progress', '::-moz-range-thumb', '::-moz-range-track', '::-moz-selection', '::-ms-backdrop', '::-ms-browse', '::-ms-check', '::-ms-clear', '::-ms-fill', '::-ms-fill-lower', '::-ms-fill-upper', '::-ms-reveal', '::-ms-thumb', '::-ms-ticks-after', '::-ms-ticks-before', '::-ms-tooltip', '::-ms-track', '::-ms-value', '::-webkit-backdrop', '::-webkit-input-placeholder', '::-webkit-progress-bar', '::-webkit-progress-inner-value', '::-webkit-progress-value', '::-webkit-slider-runnable-track', '::-webkit-slider-thumb', '::after', '::backdrop', '::before', '::cue', '::first-letter', '::first-line', '::grammar-error', '::placeholder', '::selection', '::spelling-error', ':active', ':after', ':any-link', ':before', ':blank', ':checked', ':default', ':defined', ':disabled', ':empty', ':enabled', ':first', ':first-child', ':first-letter', ':first-line', ':first-of-type', ':focus', ':focus-visible', ':focus-within', ':fullscreen', ':hover', ':in-range', ':indeterminate', ':invalid', ':last-child', ':last-of-type', ':left', ':link', ':only-child', ':only-of-type', ':optional', ':out-of-range', ':placeholder-shown', ':read-only', ':read-write', ':required', ':right', ':root', ':scope', ':target', ':valid', ':visited'];
function dashify(str) {
return str.replace(/([A-Z])/g, '-$1').replace(/^ms-/, '-ms-').toLowerCase();
}
const DOUBLE_SPACE = ' ';
const simplePseudoSet = new Set(simplePseudos);
const specialKeys = [...simplePseudos, '@media', '@supports', 'selectors'];
class Stylesheet {
constructor(localClassNames) {
this.rules = [];
this.conditionalRules = [];
this.fontFaceRules = [];
this.keyframesRules = [];
this.localClassNameRegex = localClassNames.length > 0 ? RegExp(`(${localClassNames.join('|')})`, 'g') : null;
}
processCssObj(root) {
if (root.type === 'fontFace') {
this.fontFaceRules.push(root.rule);
return;
}
if (root.type === 'keyframes') {
this.keyframesRules.push(root);
return;
} // Add main styles
const mainRule = omit(root.rule, specialKeys);
this.addRule({
selector: root.selector,
rule: mainRule
});
this.transformSimplePsuedos(root, root.rule);
this.transformMedia(root, root.rule['@media']);
this.transformSupports(root, root.rule['@supports']);
this.transformSelectors(root, root.rule);
}
addRule(cssRule) {
// Run `pixelifyProperties` before `transformVars` as we don't want to pixelify CSS Vars
const rule = this.transformVars(this.pixelifyProperties(cssRule.rule));
const selector = this.transformSelector(cssRule.selector);
if (cssRule.conditions) {
this.conditionalRules.push({
selector,
rule,
conditions: cssRule.conditions.sort()
});
} else {
this.rules.push({
selector,
rule
});
}
}
pixelifyProperties(cssRule) {
forEach(cssRule, (value, key) => {
if (typeof value === 'number' && value !== 0 && !UNITLESS[key]) {
// @ts-expect-error Any ideas?
cssRule[key] = `${value}px`;
}
});
return cssRule;
}
transformVars({
vars,
...rest
}) {
if (!vars) {
return rest;
}
return { ...mapKeys(vars, (_value, key) => {
const matches = key.match(/^var\((.*)\)$/);
if (matches) {
return matches[1];
}
return key;
}),
...rest
};
}
transformSelector(selector) {
return this.localClassNameRegex ? selector.replace(this.localClassNameRegex, (_, className, index) => {
if (index > 0 && selector[index - 1] === '.') {
return className;
}
return `.${cssesc(className, {
isIdentifier: true
})}`;
}) : selector;
}
transformSelectors(root, rule, conditions) {
forEach(rule.selectors, (selectorRule, selector) => {
if (root.type !== 'local') {
throw new Error(`Selectors are not allowed within ${root.type === 'global' ? '"globalStyle"' : '"selectors"'}`);
}
const transformedSelector = this.transformSelector(selector.replace(RegExp('&', 'g'), root.selector));
validateSelector(transformedSelector, root.selector);
this.addRule({
conditions,
selector: transformedSelector,
rule: omit(selectorRule, specialKeys)
});
const selectorRoot = {
type: 'selector',
selector: transformedSelector,
rule: selectorRule
};
this.transformSupports(selectorRoot, selectorRule['@supports'], conditions);
this.transformMedia(selectorRoot, selectorRule['@media'], conditions);
});
}
transformMedia(root, rules, parentConditions = []) {
forEach(rules, (mediaRule, query) => {
const conditions = [`@media ${query}`, ...parentConditions];
this.addRule({
conditions,
selector: root.selector,
rule: omit(mediaRule, specialKeys)
});
if (root.type === 'local') {
this.transformSimplePsuedos(root, mediaRule, conditions);
this.transformSelectors(root, mediaRule, conditions);
}
this.transformSupports(root, mediaRule['@supports'], conditions);
});
}
transformSupports(root, rules, parentConditions = []) {
forEach(rules, (supportsRule, query) => {
const conditions = [`@supports ${query}`, ...parentConditions];
this.addRule({
conditions,
selector: root.selector,
rule: omit(supportsRule, specialKeys)
});
if (root.type === 'local') {
this.transformSimplePsuedos(root, supportsRule, conditions);
this.transformSelectors(root, supportsRule, conditions);
}
this.transformMedia(root, supportsRule['@media'], conditions);
});
}
transformSimplePsuedos(root, rule, conditions) {
for (const key of Object.keys(rule)) {
// Process simple psuedos
if (simplePseudoSet.has(key)) {
if (root.type !== 'local') {
throw new Error(`Simple pseudos are not valid in ${root.type === 'global' ? '"globalStyle"' : '"selectors"'}`);
}
this.addRule({
conditions,
selector: `${root.selector}${key}`,
rule: rule[key]
});
}
}
}
toPostcssJs() {
const styles = {};
if (this.fontFaceRules.length > 0) {
styles['@font-face'] = this.fontFaceRules;
}
this.keyframesRules.forEach(rule => {
styles[`@keyframes ${rule.name}`] = rule.rule;
});
for (const rule of [...this.rules, ...this.conditionalRules]) {
if (rule.conditions && isEqual(styles[rule.selector], rule.rule)) {
// Ignore conditional rules if they are identical to a non-conditional rule
continue;
}
if (Object.keys(rule.rule).length === 0) {
// Ignore empty rules
continue;
}
let styleNode = styles;
for (const condition of rule.conditions || []) {
if (!styleNode[condition]) {
styleNode[condition] = {};
}
styleNode = styleNode[condition];
}
styleNode[rule.selector] = { ...styleNode[rule.selector],
...rule.rule
};
}
return styles;
}
toCss() {
const styles = this.toPostcssJs();
function walkCss(v, indent = '') {
const rules = [];
for (const key of Object.keys(v)) {
const value = v[key];
if (value && Array.isArray(value)) {
rules.push(...value.map(v => walkCss({
[key]: v
}, indent).join('\n')));
} else if (value && typeof value === 'object') {
rules.push(`${indent}${key} {\n${walkCss(value, indent + DOUBLE_SPACE).join('\n')}\n${indent}}`);
} else {
rules.push(`${indent}${key.startsWith('--') ? key : dashify(key)}: ${value};`);
}
}
return rules;
}
return walkCss(styles);
}
}
function transformCss({
localClassNames,
cssObjs
}) {
const stylesheet = new Stylesheet(localClassNames);
for (const root of cssObjs) {
stylesheet.processCssObj(root);
}
return stylesheet.toCss();
}
const stylesheets = {};

@@ -299,5 +14,10 @@ const localClassNames = new Set();

function getStylesheet(fileScope) {
if (stylesheets[fileScope]) {
return stylesheets[fileScope];
function getStylesheet({
packageName,
filePath
}) {
const fileScopeId = packageName ? `${packageName}${filePath}` : filePath;
if (stylesheets[fileScopeId]) {
return stylesheets[fileScopeId];
}

@@ -312,3 +32,3 @@

stylesheets[fileScope] = styleEl.sheet;
stylesheets[fileScopeId] = styleEl.sheet;
return styleEl.sheet;

@@ -361,4 +81,6 @@ }

function getShortFileName() {
const fileScope = getFileScope();
const matches = fileScope.match(/.*\/(.*)\..*\..*$/);
const {
filePath
} = getFileScope();
const matches = filePath.match(/.*\/(.*)\..*\..*$/);

@@ -374,3 +96,8 @@ if (matches && matches[1]) {

const refCount = getAndIncrementRefCounter();
const identifier = process.env.NODE_ENV !== 'production' && debugId ? `${getShortFileName()}_${debugId}__${hash(getFileScope())}${refCount}` : `${hash(getFileScope())}${refCount}`;
const {
filePath,
packageName
} = getFileScope();
const fileScopeHash = hash(packageName ? `${packageName}${filePath}` : filePath);
const identifier = process.env.NODE_ENV !== 'production' && debugId ? `${getShortFileName()}_${debugId}__${fileScopeHash}${refCount}` : `${fileScopeHash}${refCount}`;
return identifier.match(/^[0-9]/) ? `_${identifier}` : identifier;

@@ -381,3 +108,8 @@ }

const refCount = getAndIncrementRefCounter();
const varName = process.env.NODE_ENV !== 'production' && debugId ? `${debugId}__${hash(getFileScope())}${refCount}` : `${hash(getFileScope())}${refCount}`; // Dashify CSS var names to replicate postcss-js behaviour
const {
filePath,
packageName
} = getFileScope();
const fileScopeHash = hash(packageName ? `${packageName}${filePath}` : filePath);
const varName = process.env.NODE_ENV !== 'production' && debugId ? `${debugId}__${fileScopeHash}${refCount}` : `${fileScopeHash}${refCount}`; // Dashify CSS var names to replicate postcss-js behaviour
// See https://github.com/postcss/postcss-js/blob/d5127d4278c133f333f1c66f990f3552a907128e/parser.js#L30

@@ -384,0 +116,0 @@

@@ -9,5 +9,8 @@ 'use strict';

const fileScopes = [];
function setFileScope(newFileScope) {
function setFileScope(filePath, packageName) {
refCounter = 0;
fileScopes.unshift(newFileScope);
fileScopes.unshift({
filePath,
packageName
});
}

@@ -14,0 +17,0 @@ function endFileScope() {

@@ -5,5 +5,8 @@ import { onEndFileScope } from '../../adapter/dist/vanilla-extract-css-adapter.browser.esm.js';

const fileScopes = [];
function setFileScope(newFileScope) {
function setFileScope(filePath, packageName) {
refCounter = 0;
fileScopes.unshift(newFileScope);
fileScopes.unshift({
filePath,
packageName
});
}

@@ -10,0 +13,0 @@ function endFileScope() {

@@ -9,5 +9,8 @@ 'use strict';

const fileScopes = [];
function setFileScope(newFileScope) {
function setFileScope(filePath, packageName) {
refCounter = 0;
fileScopes.unshift(newFileScope);
fileScopes.unshift({
filePath,
packageName
});
}

@@ -14,0 +17,0 @@ function endFileScope() {

@@ -9,5 +9,8 @@ 'use strict';

const fileScopes = [];
function setFileScope(newFileScope) {
function setFileScope(filePath, packageName) {
refCounter = 0;
fileScopes.unshift(newFileScope);
fileScopes.unshift({
filePath,
packageName
});
}

@@ -14,0 +17,0 @@ function endFileScope() {

@@ -5,5 +5,8 @@ import { onEndFileScope } from '../../adapter/dist/vanilla-extract-css-adapter.esm.js';

const fileScopes = [];
function setFileScope(newFileScope) {
function setFileScope(filePath, packageName) {
refCounter = 0;
fileScopes.unshift(newFileScope);
fileScopes.unshift({
filePath,
packageName
});
}

@@ -10,0 +13,0 @@ function endFileScope() {

{
"name": "@vanilla-extract/css",
"version": "0.1.0",
"version": "0.2.0",
"description": "Zero-runtime Stylesheets-in-TypeScript",

@@ -17,4 +17,3 @@ "sideEffects": true,

"transformCss.ts",
"fileScope.ts",
"createInlineTheme.ts"
"fileScope.ts"
]

@@ -26,4 +25,3 @@ },

"/transformCss",
"/fileScope",
"/createInlineTheme"
"/fileScope"
],

@@ -39,2 +37,3 @@ "repository": {

"@emotion/hash": "^0.8.0",
"@vanilla-extract/private": "^0.1.0",
"css-selector-parser": "^1.4.1",

@@ -41,0 +40,0 @@ "cssesc": "^3.0.0",

@@ -33,2 +33,4 @@ # 🧁 vanilla-extract

🙈 &nbsp; Optional API for dynamic runtime theming.
---

@@ -79,2 +81,5 @@

- [Setup](#setup)
- [webpack](#webpack)
- [esbuild](#esbuild)
- [Gatsby](#gatsby)
- [API](#api)

@@ -86,3 +91,2 @@ - [style](#style)

- [createGlobalTheme](#createglobaltheme)
- [createInlineTheme](#createinlinetheme)
- [createThemeVars](#createthemevars)

@@ -96,2 +100,6 @@ - [assignVars](#assignvars)

- [globalKeyframes](#globalkeyframes)
- [Dynamic API](#dynamic-api)
- [createInlineTheme](#createinlinetheme)
- [setElementTheme](#setelementtheme)
- [setElementVar](#setelementvar)
- [Utility functions](#utility-functions)

@@ -106,2 +114,6 @@ - [calc](#calc)

There are currently a few integrations to choose from.
### webpack
1. Install the dependencies.

@@ -161,2 +173,29 @@

### esbuild
1. Install the dependencies.
```bash
$ yarn add --dev @vanilla-extract/css @vanilla-extract/esbuild-plugin
```
2. Add the [esbuild](https://esbuild.github.io/) plugin to your build script.
```js
const { vanillaExtractPlugin } = require('@vanilla-extract/esbuild-plugin');
require('esbuild').build({
entryPoints: ['app.ts'],
bundle: true,
plugins: [vanillaExtractPlugin()],
outfile: 'out.js',
}).catch(() => process.exit(1))
```
> Please note: There are currently no automatic readable class names during development. However, you can still manually provide a debug ID as the last argument to functions that generate scoped styles, e.g. `export const className = style({ ... }, 'className');`
### Gatsby
To add to your [Gatsby](https://www.gatsbyjs.com) site, use the [gatsby-plugin-vanilla-extract](https://github.com/KyleAMathews/gatsby-plugin-vanilla-extract) plugin.
---

@@ -166,2 +205,4 @@

> 🍬 If you're a [treat](https://seek-oss.github.io/treat) user, check out our [migration guide.](./docs/treat-migration-guide.md)
### style

@@ -226,2 +267,8 @@

> 💡 To improve maintainability, each `style` block can only target a single element. To enforce this, all selectors must target the `&` character which is a reference to the current element. For example, `'&:hover:not(:active)'` is considered valid, while `'& > a'` and ``[`& ${childClass}`]`` are not.
>
>If you want to target another scoped class then it should be defined within the `style` block of that class instead. For example, ``[`& ${childClass}`]`` is invalid since it targets `${childClass}`, so it should instead be defined in the `style` block for `childClass`.
>
>If you want to globally target child nodes within the current element (e.g. `'& > a'`), you should use [`globalStyle`](#globalstyle) instead.
### globalStyle

@@ -239,2 +286,14 @@

Global selectors can also contain references to other scoped class names.
```ts
import { globalStyle } from '@vanilla-extract/css';
export const parentClass = style({});
globalStyle(`${parentClass} > a`, {
color: 'pink'
});
```
### mapToStyles

@@ -334,23 +393,2 @@

### createInlineTheme
Generates a custom theme at runtime as an inline style object.
```ts
import { createInlineTheme } from '@vanilla-extract/css/createInlineTheme';
import { themeVars, exampleStyle } from './styles.css.ts';
const customTheme = createInlineTheme(themeVars, {
small: 4,
medium: 8,
large: 16
});
document.write(`
<section style="${customTheme}">
<h1 class="${exampleStyle}">Hello world!</h1>
</section>
`);
```
### createThemeVars

@@ -398,15 +436,22 @@

Allows you to set an entire collection of CSS Variables anywhere within a style block.
Assigns a collection of CSS Variables anywhere within a style block.
> 💡 This is useful for creating responsive themes since it can be used within an `@media` block.
> 💡 This is useful for creating responsive themes since it can be used within `@media` blocks.
```ts
import { style, assignVars } from '@vanilla-extract/css';
import { themeVars } from './vars.css.ts';
import { style, createThemeVars, assignVars } from '@vanilla-extract/css';
export const exampleStyle = style({
export const themeVars = createThemeVars({
space: {
small: null,
medium: null,
large: null
}
});
export const responsiveSpaceTheme = style({
vars: assignVars(themeVars.space, {
small: 4,
medium: 8,
large: 16
small: '4px',
medium: '8px',
large: '16px'
}),

@@ -416,5 +461,5 @@ '@media': {

vars: assignVars(themeVars.space, {
small: 8,
medium: 16,
large: 32
small: '8px',
medium: '16px',
large: '32px'
})

@@ -551,2 +596,61 @@ }

## Dynamic API
We also provide a lightweight standalone package to support dynamic runtime theming.
```bash
$ yarn add --dev @vanilla-extract/dynamic
```
### createInlineTheme
Generates a custom theme at runtime as an inline style object.
```ts
import { createInlineTheme } from '@vanilla-extract/dynamic';
import { themeVars, exampleStyle } from './styles.css.ts';
const customTheme = createInlineTheme(themeVars, {
small: '4px',
medium: '8px',
large: '16px'
});
document.write(`
<section style="${customTheme}">
<h1 class="${exampleStyle}">Hello world!</h1>
</section>
`);
```
### setElementTheme
Sets a collection of CSS Variables on an element.
```ts
import { setElementTheme } from '@vanilla-extract/dynamic';
import { themeVars } from './styles.css.ts';
const element = document.getElementById('myElement');
setElementTheme(element, themeVars, {
small: '4px',
medium: '8px',
large: '16px'
});
```
> 💡 All variables passed into this function must be assigned or it’s a type error.
### setElementVar
Sets a single var on an element.
```ts
import { setElementVar } from '@vanilla-extract/dynamic';
import { themeVars } from './styles.css.ts';
const element = document.getElementById('myElement');
setElementVar(element, themeVars.color.brand, 'darksalmon');
```
## Utility functions

@@ -553,0 +657,0 @@

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

var _private = require('@vanilla-extract/private');
var cssesc = require('cssesc');
var validateSelector = require('../../dist/validateSelector-a9e44540.browser.cjs.js');
var utils = require('../../dist/utils-03507b0d.browser.cjs.js');
require('css-selector-parser');
require('dedent');
var cssSelectorParser = require('css-selector-parser');
var dedent = require('dedent');

@@ -15,3 +14,116 @@ function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }

var cssesc__default = /*#__PURE__*/_interopDefault(cssesc);
var dedent__default = /*#__PURE__*/_interopDefault(dedent);
function escapeRegex(string) {
return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
const parser = new cssSelectorParser.CssSelectorParser();
parser.registerSelectorPseudos('has');
parser.registerNestingOperators('>', '+', '~');
parser.registerAttrEqualityMods('^', '$', '*', '~');
parser.enableSubstitutes();
const validateSelector = (selector, targetClassName) => {
const replaceTarget = () => {
const targetRegex = new RegExp(`.${escapeRegex(cssesc__default['default'](targetClassName, {
isIdentifier: true
}))}`, 'g');
return selector.replace(targetRegex, '&');
};
return selector.split(',').map(selectorPart => {
if (selectorPart.indexOf(targetClassName) === -1) {
throw new Error(dedent__default['default']`
Invalid selector: ${replaceTarget()}
Selectors must target the ampersand character ('&'), which refers to the generated class name, e.g. '&:nth-child(2n)'
`);
}
let currentRule;
try {
const result = parser.parse(selectorPart);
if (result.type === 'ruleSet') {
currentRule = result.rule;
} else {
throw new Error();
}
} catch (err) {
throw new Error(`Invalid selector: ${replaceTarget()}`);
}
while (currentRule.rule) {
currentRule = currentRule.rule;
}
const targetRule = currentRule;
if (!Array.isArray(targetRule.classNames) || !targetRule.classNames.find(className => className === targetClassName)) {
throw new Error(dedent__default['default']`
Invalid selector: ${replaceTarget()}
Style selectors must end with the '&' character (along with any modifiers), e.g. ${'`${parent} &`'} or ${'`${parent} &:hover`'}.
This is to ensure that each style block only affects the styling of a single class.
If your selector is targeting another class, you should move it to the style definition for that class, e.g. given we have styles for 'parent' and 'child' elements, instead of adding a selector of ${'`& ${child}`'}) to 'parent', you should add ${'`${parent} &`'} to 'child').
If your selector is targeting something global, use the 'globalStyle' function instead, e.g. if you wanted to write ${'`& h1`'}, you should instead write 'globalStyle(${'`${parent} h1`'}, { ... })'
`);
}
});
};
function forEach(obj, fn) {
for (const key in obj) {
fn(obj[key], key);
}
}
function omit(obj, omitKeys) {
let result = {};
for (const key in obj) {
if (omitKeys.indexOf(key) === -1) {
result[key] = obj[key];
}
}
return result;
}
function mapKeys(obj, fn) {
let result = {};
for (const key in obj) {
result[fn(obj[key], key)] = obj[key];
}
return result;
}
function isEqual(a, b) {
if (typeof a !== typeof b) {
return false;
}
if (typeof a === 'object') {
const keys1 = Object.keys(a);
const keys2 = Object.keys(b);
if (keys1.length !== keys2.length) {
return false;
}
for (const key in a) {
if (!isEqual(a[key], b[key])) {
return false;
}
}
return true;
} else {
return a === b;
}
}
const UNITLESS = {

@@ -72,3 +184,3 @@ boxFlex: true,

const mainRule = utils.omit(root.rule, specialKeys);
const mainRule = omit(root.rule, specialKeys);
this.addRule({

@@ -104,3 +216,3 @@ selector: root.selector,

pixelifyProperties(cssRule) {
utils.forEach(cssRule, (value, key) => {
forEach(cssRule, (value, key) => {
if (typeof value === 'number' && value !== 0 && !UNITLESS[key]) {

@@ -122,11 +234,3 @@ // @ts-expect-error Any ideas?

return { ...utils.mapKeys(vars, (_value, key) => {
const matches = key.match(/^var\((.*)\)$/);
if (matches) {
return matches[1];
}
return key;
}),
return { ...mapKeys(vars, (_value, key) => _private.getVarName(key)),
...rest

@@ -149,3 +253,3 @@ };

transformSelectors(root, rule, conditions) {
utils.forEach(rule.selectors, (selectorRule, selector) => {
forEach(rule.selectors, (selectorRule, selector) => {
if (root.type !== 'local') {

@@ -156,7 +260,7 @@ throw new Error(`Selectors are not allowed within ${root.type === 'global' ? '"globalStyle"' : '"selectors"'}`);

const transformedSelector = this.transformSelector(selector.replace(RegExp('&', 'g'), root.selector));
validateSelector.validateSelector(transformedSelector, root.selector);
validateSelector(transformedSelector, root.selector);
this.addRule({
conditions,
selector: transformedSelector,
rule: utils.omit(selectorRule, specialKeys)
rule: omit(selectorRule, specialKeys)
});

@@ -174,3 +278,3 @@ const selectorRoot = {

transformMedia(root, rules, parentConditions = []) {
utils.forEach(rules, (mediaRule, query) => {
forEach(rules, (mediaRule, query) => {
const conditions = [`@media ${query}`, ...parentConditions];

@@ -180,3 +284,3 @@ this.addRule({

selector: root.selector,
rule: utils.omit(mediaRule, specialKeys)
rule: omit(mediaRule, specialKeys)
});

@@ -194,3 +298,3 @@

transformSupports(root, rules, parentConditions = []) {
utils.forEach(rules, (supportsRule, query) => {
forEach(rules, (supportsRule, query) => {
const conditions = [`@supports ${query}`, ...parentConditions];

@@ -200,3 +304,3 @@ this.addRule({

selector: root.selector,
rule: utils.omit(supportsRule, specialKeys)
rule: omit(supportsRule, specialKeys)
});

@@ -242,3 +346,3 @@

for (const rule of [...this.rules, ...this.conditionalRules]) {
if (rule.conditions && utils.isEqual(styles[rule.selector], rule.rule)) {
if (rule.conditions && isEqual(styles[rule.selector], rule.rule)) {
// Ignore conditional rules if they are identical to a non-conditional rule

@@ -245,0 +349,0 @@ continue;

@@ -0,7 +1,118 @@

import { getVarName } from '@vanilla-extract/private';
import cssesc from 'cssesc';
import { v as validateSelector } from '../../dist/validateSelector-2dda5781.browser.esm.js';
import { o as omit, f as forEach, m as mapKeys, i as isEqual } from '../../dist/utils-24d5030c.browser.esm.js';
import 'css-selector-parser';
import 'dedent';
import { CssSelectorParser } from 'css-selector-parser';
import dedent from 'dedent';
function escapeRegex(string) {
return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
const parser = new CssSelectorParser();
parser.registerSelectorPseudos('has');
parser.registerNestingOperators('>', '+', '~');
parser.registerAttrEqualityMods('^', '$', '*', '~');
parser.enableSubstitutes();
const validateSelector = (selector, targetClassName) => {
const replaceTarget = () => {
const targetRegex = new RegExp(`.${escapeRegex(cssesc(targetClassName, {
isIdentifier: true
}))}`, 'g');
return selector.replace(targetRegex, '&');
};
return selector.split(',').map(selectorPart => {
if (selectorPart.indexOf(targetClassName) === -1) {
throw new Error(dedent`
Invalid selector: ${replaceTarget()}
Selectors must target the ampersand character ('&'), which refers to the generated class name, e.g. '&:nth-child(2n)'
`);
}
let currentRule;
try {
const result = parser.parse(selectorPart);
if (result.type === 'ruleSet') {
currentRule = result.rule;
} else {
throw new Error();
}
} catch (err) {
throw new Error(`Invalid selector: ${replaceTarget()}`);
}
while (currentRule.rule) {
currentRule = currentRule.rule;
}
const targetRule = currentRule;
if (!Array.isArray(targetRule.classNames) || !targetRule.classNames.find(className => className === targetClassName)) {
throw new Error(dedent`
Invalid selector: ${replaceTarget()}
Style selectors must end with the '&' character (along with any modifiers), e.g. ${'`${parent} &`'} or ${'`${parent} &:hover`'}.
This is to ensure that each style block only affects the styling of a single class.
If your selector is targeting another class, you should move it to the style definition for that class, e.g. given we have styles for 'parent' and 'child' elements, instead of adding a selector of ${'`& ${child}`'}) to 'parent', you should add ${'`${parent} &`'} to 'child').
If your selector is targeting something global, use the 'globalStyle' function instead, e.g. if you wanted to write ${'`& h1`'}, you should instead write 'globalStyle(${'`${parent} h1`'}, { ... })'
`);
}
});
};
function forEach(obj, fn) {
for (const key in obj) {
fn(obj[key], key);
}
}
function omit(obj, omitKeys) {
let result = {};
for (const key in obj) {
if (omitKeys.indexOf(key) === -1) {
result[key] = obj[key];
}
}
return result;
}
function mapKeys(obj, fn) {
let result = {};
for (const key in obj) {
result[fn(obj[key], key)] = obj[key];
}
return result;
}
function isEqual(a, b) {
if (typeof a !== typeof b) {
return false;
}
if (typeof a === 'object') {
const keys1 = Object.keys(a);
const keys2 = Object.keys(b);
if (keys1.length !== keys2.length) {
return false;
}
for (const key in a) {
if (!isEqual(a[key], b[key])) {
return false;
}
}
return true;
} else {
return a === b;
}
}
const UNITLESS = {

@@ -110,11 +221,3 @@ boxFlex: true,

return { ...mapKeys(vars, (_value, key) => {
const matches = key.match(/^var\((.*)\)$/);
if (matches) {
return matches[1];
}
return key;
}),
return { ...mapKeys(vars, (_value, key) => getVarName(key)),
...rest

@@ -121,0 +224,0 @@ };

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

export * from "../../dist/declarations/src/transformCSS";
export * from "../../dist/declarations/src/transformCss";

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

var _private = require('@vanilla-extract/private');
var cssesc = require('cssesc');
var validateSelector = require('../../dist/validateSelector-acadedf9.cjs.dev.js');
var utils = require('../../dist/utils-c5ab417f.cjs.dev.js');
require('css-selector-parser');
require('dedent');
var cssSelectorParser = require('css-selector-parser');
var dedent = require('dedent');

@@ -15,3 +14,116 @@ function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }

var cssesc__default = /*#__PURE__*/_interopDefault(cssesc);
var dedent__default = /*#__PURE__*/_interopDefault(dedent);
function escapeRegex(string) {
return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
const parser = new cssSelectorParser.CssSelectorParser();
parser.registerSelectorPseudos('has');
parser.registerNestingOperators('>', '+', '~');
parser.registerAttrEqualityMods('^', '$', '*', '~');
parser.enableSubstitutes();
const validateSelector = (selector, targetClassName) => {
const replaceTarget = () => {
const targetRegex = new RegExp(`.${escapeRegex(cssesc__default['default'](targetClassName, {
isIdentifier: true
}))}`, 'g');
return selector.replace(targetRegex, '&');
};
return selector.split(',').map(selectorPart => {
if (selectorPart.indexOf(targetClassName) === -1) {
throw new Error(dedent__default['default']`
Invalid selector: ${replaceTarget()}
Selectors must target the ampersand character ('&'), which refers to the generated class name, e.g. '&:nth-child(2n)'
`);
}
let currentRule;
try {
const result = parser.parse(selectorPart);
if (result.type === 'ruleSet') {
currentRule = result.rule;
} else {
throw new Error();
}
} catch (err) {
throw new Error(`Invalid selector: ${replaceTarget()}`);
}
while (currentRule.rule) {
currentRule = currentRule.rule;
}
const targetRule = currentRule;
if (!Array.isArray(targetRule.classNames) || !targetRule.classNames.find(className => className === targetClassName)) {
throw new Error(dedent__default['default']`
Invalid selector: ${replaceTarget()}
Style selectors must end with the '&' character (along with any modifiers), e.g. ${'`${parent} &`'} or ${'`${parent} &:hover`'}.
This is to ensure that each style block only affects the styling of a single class.
If your selector is targeting another class, you should move it to the style definition for that class, e.g. given we have styles for 'parent' and 'child' elements, instead of adding a selector of ${'`& ${child}`'}) to 'parent', you should add ${'`${parent} &`'} to 'child').
If your selector is targeting something global, use the 'globalStyle' function instead, e.g. if you wanted to write ${'`& h1`'}, you should instead write 'globalStyle(${'`${parent} h1`'}, { ... })'
`);
}
});
};
function forEach(obj, fn) {
for (const key in obj) {
fn(obj[key], key);
}
}
function omit(obj, omitKeys) {
let result = {};
for (const key in obj) {
if (omitKeys.indexOf(key) === -1) {
result[key] = obj[key];
}
}
return result;
}
function mapKeys(obj, fn) {
let result = {};
for (const key in obj) {
result[fn(obj[key], key)] = obj[key];
}
return result;
}
function isEqual(a, b) {
if (typeof a !== typeof b) {
return false;
}
if (typeof a === 'object') {
const keys1 = Object.keys(a);
const keys2 = Object.keys(b);
if (keys1.length !== keys2.length) {
return false;
}
for (const key in a) {
if (!isEqual(a[key], b[key])) {
return false;
}
}
return true;
} else {
return a === b;
}
}
const UNITLESS = {

@@ -72,3 +184,3 @@ boxFlex: true,

const mainRule = utils.omit(root.rule, specialKeys);
const mainRule = omit(root.rule, specialKeys);
this.addRule({

@@ -104,3 +216,3 @@ selector: root.selector,

pixelifyProperties(cssRule) {
utils.forEach(cssRule, (value, key) => {
forEach(cssRule, (value, key) => {
if (typeof value === 'number' && value !== 0 && !UNITLESS[key]) {

@@ -122,11 +234,3 @@ // @ts-expect-error Any ideas?

return { ...utils.mapKeys(vars, (_value, key) => {
const matches = key.match(/^var\((.*)\)$/);
if (matches) {
return matches[1];
}
return key;
}),
return { ...mapKeys(vars, (_value, key) => _private.getVarName(key)),
...rest

@@ -149,3 +253,3 @@ };

transformSelectors(root, rule, conditions) {
utils.forEach(rule.selectors, (selectorRule, selector) => {
forEach(rule.selectors, (selectorRule, selector) => {
if (root.type !== 'local') {

@@ -156,7 +260,7 @@ throw new Error(`Selectors are not allowed within ${root.type === 'global' ? '"globalStyle"' : '"selectors"'}`);

const transformedSelector = this.transformSelector(selector.replace(RegExp('&', 'g'), root.selector));
validateSelector.validateSelector(transformedSelector, root.selector);
validateSelector(transformedSelector, root.selector);
this.addRule({
conditions,
selector: transformedSelector,
rule: utils.omit(selectorRule, specialKeys)
rule: omit(selectorRule, specialKeys)
});

@@ -174,3 +278,3 @@ const selectorRoot = {

transformMedia(root, rules, parentConditions = []) {
utils.forEach(rules, (mediaRule, query) => {
forEach(rules, (mediaRule, query) => {
const conditions = [`@media ${query}`, ...parentConditions];

@@ -180,3 +284,3 @@ this.addRule({

selector: root.selector,
rule: utils.omit(mediaRule, specialKeys)
rule: omit(mediaRule, specialKeys)
});

@@ -194,3 +298,3 @@

transformSupports(root, rules, parentConditions = []) {
utils.forEach(rules, (supportsRule, query) => {
forEach(rules, (supportsRule, query) => {
const conditions = [`@supports ${query}`, ...parentConditions];

@@ -200,3 +304,3 @@ this.addRule({

selector: root.selector,
rule: utils.omit(supportsRule, specialKeys)
rule: omit(supportsRule, specialKeys)
});

@@ -242,3 +346,3 @@

for (const rule of [...this.rules, ...this.conditionalRules]) {
if (rule.conditions && utils.isEqual(styles[rule.selector], rule.rule)) {
if (rule.conditions && isEqual(styles[rule.selector], rule.rule)) {
// Ignore conditional rules if they are identical to a non-conditional rule

@@ -245,0 +349,0 @@ continue;

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

var _private = require('@vanilla-extract/private');
var cssesc = require('cssesc');
var validateSelector = require('../../dist/validateSelector-5a593081.cjs.prod.js');
var utils = require('../../dist/utils-2b734f0b.cjs.prod.js');
require('css-selector-parser');
require('dedent');
var cssSelectorParser = require('css-selector-parser');
var dedent = require('dedent');

@@ -15,3 +14,116 @@ function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }

var cssesc__default = /*#__PURE__*/_interopDefault(cssesc);
var dedent__default = /*#__PURE__*/_interopDefault(dedent);
function escapeRegex(string) {
return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
const parser = new cssSelectorParser.CssSelectorParser();
parser.registerSelectorPseudos('has');
parser.registerNestingOperators('>', '+', '~');
parser.registerAttrEqualityMods('^', '$', '*', '~');
parser.enableSubstitutes();
const validateSelector = (selector, targetClassName) => {
const replaceTarget = () => {
const targetRegex = new RegExp(`.${escapeRegex(cssesc__default['default'](targetClassName, {
isIdentifier: true
}))}`, 'g');
return selector.replace(targetRegex, '&');
};
return selector.split(',').map(selectorPart => {
if (selectorPart.indexOf(targetClassName) === -1) {
throw new Error(dedent__default['default']`
Invalid selector: ${replaceTarget()}
Selectors must target the ampersand character ('&'), which refers to the generated class name, e.g. '&:nth-child(2n)'
`);
}
let currentRule;
try {
const result = parser.parse(selectorPart);
if (result.type === 'ruleSet') {
currentRule = result.rule;
} else {
throw new Error();
}
} catch (err) {
throw new Error(`Invalid selector: ${replaceTarget()}`);
}
while (currentRule.rule) {
currentRule = currentRule.rule;
}
const targetRule = currentRule;
if (!Array.isArray(targetRule.classNames) || !targetRule.classNames.find(className => className === targetClassName)) {
throw new Error(dedent__default['default']`
Invalid selector: ${replaceTarget()}
Style selectors must end with the '&' character (along with any modifiers), e.g. ${'`${parent} &`'} or ${'`${parent} &:hover`'}.
This is to ensure that each style block only affects the styling of a single class.
If your selector is targeting another class, you should move it to the style definition for that class, e.g. given we have styles for 'parent' and 'child' elements, instead of adding a selector of ${'`& ${child}`'}) to 'parent', you should add ${'`${parent} &`'} to 'child').
If your selector is targeting something global, use the 'globalStyle' function instead, e.g. if you wanted to write ${'`& h1`'}, you should instead write 'globalStyle(${'`${parent} h1`'}, { ... })'
`);
}
});
};
function forEach(obj, fn) {
for (const key in obj) {
fn(obj[key], key);
}
}
function omit(obj, omitKeys) {
let result = {};
for (const key in obj) {
if (omitKeys.indexOf(key) === -1) {
result[key] = obj[key];
}
}
return result;
}
function mapKeys(obj, fn) {
let result = {};
for (const key in obj) {
result[fn(obj[key], key)] = obj[key];
}
return result;
}
function isEqual(a, b) {
if (typeof a !== typeof b) {
return false;
}
if (typeof a === 'object') {
const keys1 = Object.keys(a);
const keys2 = Object.keys(b);
if (keys1.length !== keys2.length) {
return false;
}
for (const key in a) {
if (!isEqual(a[key], b[key])) {
return false;
}
}
return true;
} else {
return a === b;
}
}
const UNITLESS = {

@@ -72,3 +184,3 @@ boxFlex: true,

const mainRule = utils.omit(root.rule, specialKeys);
const mainRule = omit(root.rule, specialKeys);
this.addRule({

@@ -104,3 +216,3 @@ selector: root.selector,

pixelifyProperties(cssRule) {
utils.forEach(cssRule, (value, key) => {
forEach(cssRule, (value, key) => {
if (typeof value === 'number' && value !== 0 && !UNITLESS[key]) {

@@ -122,11 +234,3 @@ // @ts-expect-error Any ideas?

return { ...utils.mapKeys(vars, (_value, key) => {
const matches = key.match(/^var\((.*)\)$/);
if (matches) {
return matches[1];
}
return key;
}),
return { ...mapKeys(vars, (_value, key) => _private.getVarName(key)),
...rest

@@ -149,3 +253,3 @@ };

transformSelectors(root, rule, conditions) {
utils.forEach(rule.selectors, (selectorRule, selector) => {
forEach(rule.selectors, (selectorRule, selector) => {
if (root.type !== 'local') {

@@ -156,7 +260,7 @@ throw new Error(`Selectors are not allowed within ${root.type === 'global' ? '"globalStyle"' : '"selectors"'}`);

const transformedSelector = this.transformSelector(selector.replace(RegExp('&', 'g'), root.selector));
validateSelector.validateSelector(transformedSelector, root.selector);
validateSelector(transformedSelector, root.selector);
this.addRule({
conditions,
selector: transformedSelector,
rule: utils.omit(selectorRule, specialKeys)
rule: omit(selectorRule, specialKeys)
});

@@ -174,3 +278,3 @@ const selectorRoot = {

transformMedia(root, rules, parentConditions = []) {
utils.forEach(rules, (mediaRule, query) => {
forEach(rules, (mediaRule, query) => {
const conditions = [`@media ${query}`, ...parentConditions];

@@ -180,3 +284,3 @@ this.addRule({

selector: root.selector,
rule: utils.omit(mediaRule, specialKeys)
rule: omit(mediaRule, specialKeys)
});

@@ -194,3 +298,3 @@

transformSupports(root, rules, parentConditions = []) {
utils.forEach(rules, (supportsRule, query) => {
forEach(rules, (supportsRule, query) => {
const conditions = [`@supports ${query}`, ...parentConditions];

@@ -200,3 +304,3 @@ this.addRule({

selector: root.selector,
rule: utils.omit(supportsRule, specialKeys)
rule: omit(supportsRule, specialKeys)
});

@@ -242,3 +346,3 @@

for (const rule of [...this.rules, ...this.conditionalRules]) {
if (rule.conditions && utils.isEqual(styles[rule.selector], rule.rule)) {
if (rule.conditions && isEqual(styles[rule.selector], rule.rule)) {
// Ignore conditional rules if they are identical to a non-conditional rule

@@ -245,0 +349,0 @@ continue;

@@ -0,7 +1,118 @@

import { getVarName } from '@vanilla-extract/private';
import cssesc from 'cssesc';
import { v as validateSelector } from '../../dist/validateSelector-cfc75bf8.esm.js';
import { o as omit, f as forEach, m as mapKeys, i as isEqual } from '../../dist/utils-fbd6ce24.esm.js';
import 'css-selector-parser';
import 'dedent';
import { CssSelectorParser } from 'css-selector-parser';
import dedent from 'dedent';
function escapeRegex(string) {
return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
const parser = new CssSelectorParser();
parser.registerSelectorPseudos('has');
parser.registerNestingOperators('>', '+', '~');
parser.registerAttrEqualityMods('^', '$', '*', '~');
parser.enableSubstitutes();
const validateSelector = (selector, targetClassName) => {
const replaceTarget = () => {
const targetRegex = new RegExp(`.${escapeRegex(cssesc(targetClassName, {
isIdentifier: true
}))}`, 'g');
return selector.replace(targetRegex, '&');
};
return selector.split(',').map(selectorPart => {
if (selectorPart.indexOf(targetClassName) === -1) {
throw new Error(dedent`
Invalid selector: ${replaceTarget()}
Selectors must target the ampersand character ('&'), which refers to the generated class name, e.g. '&:nth-child(2n)'
`);
}
let currentRule;
try {
const result = parser.parse(selectorPart);
if (result.type === 'ruleSet') {
currentRule = result.rule;
} else {
throw new Error();
}
} catch (err) {
throw new Error(`Invalid selector: ${replaceTarget()}`);
}
while (currentRule.rule) {
currentRule = currentRule.rule;
}
const targetRule = currentRule;
if (!Array.isArray(targetRule.classNames) || !targetRule.classNames.find(className => className === targetClassName)) {
throw new Error(dedent`
Invalid selector: ${replaceTarget()}
Style selectors must end with the '&' character (along with any modifiers), e.g. ${'`${parent} &`'} or ${'`${parent} &:hover`'}.
This is to ensure that each style block only affects the styling of a single class.
If your selector is targeting another class, you should move it to the style definition for that class, e.g. given we have styles for 'parent' and 'child' elements, instead of adding a selector of ${'`& ${child}`'}) to 'parent', you should add ${'`${parent} &`'} to 'child').
If your selector is targeting something global, use the 'globalStyle' function instead, e.g. if you wanted to write ${'`& h1`'}, you should instead write 'globalStyle(${'`${parent} h1`'}, { ... })'
`);
}
});
};
function forEach(obj, fn) {
for (const key in obj) {
fn(obj[key], key);
}
}
function omit(obj, omitKeys) {
let result = {};
for (const key in obj) {
if (omitKeys.indexOf(key) === -1) {
result[key] = obj[key];
}
}
return result;
}
function mapKeys(obj, fn) {
let result = {};
for (const key in obj) {
result[fn(obj[key], key)] = obj[key];
}
return result;
}
function isEqual(a, b) {
if (typeof a !== typeof b) {
return false;
}
if (typeof a === 'object') {
const keys1 = Object.keys(a);
const keys2 = Object.keys(b);
if (keys1.length !== keys2.length) {
return false;
}
for (const key in a) {
if (!isEqual(a[key], b[key])) {
return false;
}
}
return true;
} else {
return a === b;
}
}
const UNITLESS = {

@@ -110,11 +221,3 @@ boxFlex: true,

return { ...mapKeys(vars, (_value, key) => {
const matches = key.match(/^var\((.*)\)$/);
if (matches) {
return matches[1];
}
return key;
}),
return { ...mapKeys(vars, (_value, key) => getVarName(key)),
...rest

@@ -121,0 +224,0 @@ };

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc