@stylexjs/babel-plugin 0.17.5 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.browser.js +124 -19
- package/lib/index.js +124 -19
- package/lib/shared/common-types.js.flow +1 -0
- package/lib/shared/messages.d.ts +0 -2
- package/lib/shared/messages.js.flow +0 -1
- package/lib/shared/when/when.d.ts +6 -5
- package/lib/shared/when/when.js.flow +7 -5
- package/lib/utils/state-manager.d.ts +5 -0
- package/lib/utils/state-manager.js.flow +5 -0
- package/lib/visitors/inline-css.d.ts +28 -0
- package/lib/visitors/inline-css.js.flow +30 -0
- package/lib/visitors/stylex-define-consts.js.flow +0 -1
- package/lib/visitors/stylex-merge.js.flow +0 -1
- package/package.json +4 -4
package/lib/index.browser.js
CHANGED
|
@@ -1484,6 +1484,12 @@ const checkRuntimeInjection = unionOf3(boolean(), string(), object({
|
|
|
1484
1484
|
from: string(),
|
|
1485
1485
|
as: string()
|
|
1486
1486
|
}));
|
|
1487
|
+
const checkEnvOption = (value, name = 'options.env') => {
|
|
1488
|
+
if (typeof value !== 'object' || value == null || Array.isArray(value)) {
|
|
1489
|
+
return new Error(`Expected (${name}) to be an object, but got \`${String(JSON.stringify(value))}\`.`);
|
|
1490
|
+
}
|
|
1491
|
+
return value;
|
|
1492
|
+
};
|
|
1487
1493
|
const DEFAULT_INJECT_PATH = '@stylexjs/stylex/lib/stylex-inject';
|
|
1488
1494
|
class StateManager {
|
|
1489
1495
|
importPaths = new Set();
|
|
@@ -1503,6 +1509,7 @@ class StateManager {
|
|
|
1503
1509
|
stylexViewTransitionClassImport = new Set();
|
|
1504
1510
|
stylexDefaultMarkerImport = new Set();
|
|
1505
1511
|
stylexWhenImport = new Set();
|
|
1512
|
+
stylexEnvImport = new Set();
|
|
1506
1513
|
injectImportInserted = null;
|
|
1507
1514
|
styleMap = new Map();
|
|
1508
1515
|
styleVars = new Map();
|
|
@@ -1536,6 +1543,10 @@ class StateManager {
|
|
|
1536
1543
|
const propertyValidationMode = logAndDefault(unionOf3(literal('throw'), literal('warn'), literal('silent')), options.propertyValidationMode ?? defaultOptions.propertyValidationMode, 'silent', 'options.propertyValidationMode');
|
|
1537
1544
|
const unstable_moduleResolution = logAndDefault(unionOf(nullish(), CheckModuleResolution), options.unstable_moduleResolution, null, 'options.unstable_moduleResolution');
|
|
1538
1545
|
const treeshakeCompensation = logAndDefault(boolean(), options.treeshakeCompensation ?? defaultOptions.treeshakeCompensation, false, 'options.treeshakeCompensation');
|
|
1546
|
+
const envInput = logAndDefault(checkEnvOption, options.env ?? {}, {}, 'options.env');
|
|
1547
|
+
const env = Object.freeze({
|
|
1548
|
+
...envInput
|
|
1549
|
+
});
|
|
1539
1550
|
const aliasesOption = logAndDefault(unionOf(nullish(), objectOf(unionOf(string(), array(string())))), options.aliases, null, 'options.aliases');
|
|
1540
1551
|
const aliases = aliasesOption == null ? aliasesOption : Object.fromEntries(Object.entries(aliasesOption).map(([key, value]) => {
|
|
1541
1552
|
if (typeof value === 'string') {
|
|
@@ -1551,6 +1562,7 @@ class StateManager {
|
|
|
1551
1562
|
definedStylexCSSVariables: {},
|
|
1552
1563
|
dev,
|
|
1553
1564
|
propertyValidationMode,
|
|
1565
|
+
env,
|
|
1554
1566
|
enableDebugClassNames,
|
|
1555
1567
|
enableDebugDataProp,
|
|
1556
1568
|
enableDevClassNames,
|
|
@@ -1592,6 +1604,31 @@ class StateManager {
|
|
|
1592
1604
|
}
|
|
1593
1605
|
return null;
|
|
1594
1606
|
}
|
|
1607
|
+
applyStylexEnv(identifiers) {
|
|
1608
|
+
const env = this.options.env;
|
|
1609
|
+
this.stylexImport.forEach(importName => {
|
|
1610
|
+
const current = identifiers[importName];
|
|
1611
|
+
if (current != null && typeof current === 'object' && !Array.isArray(current)) {
|
|
1612
|
+
if ('fn' in current) {
|
|
1613
|
+
identifiers[importName] = {
|
|
1614
|
+
env
|
|
1615
|
+
};
|
|
1616
|
+
} else {
|
|
1617
|
+
identifiers[importName] = {
|
|
1618
|
+
...current,
|
|
1619
|
+
env
|
|
1620
|
+
};
|
|
1621
|
+
}
|
|
1622
|
+
return;
|
|
1623
|
+
}
|
|
1624
|
+
identifiers[importName] = {
|
|
1625
|
+
env
|
|
1626
|
+
};
|
|
1627
|
+
});
|
|
1628
|
+
this.stylexEnvImport.forEach(importName => {
|
|
1629
|
+
identifiers[importName] = env;
|
|
1630
|
+
});
|
|
1631
|
+
}
|
|
1595
1632
|
get canReferenceTheme() {
|
|
1596
1633
|
return !!this.inStyleXCreate;
|
|
1597
1634
|
}
|
|
@@ -1910,6 +1947,9 @@ function readImportDeclarations(path, state) {
|
|
|
1910
1947
|
if (importedName === 'defaultMarker') {
|
|
1911
1948
|
state.stylexDefaultMarkerImport.add(localName);
|
|
1912
1949
|
}
|
|
1950
|
+
if (importedName === 'env') {
|
|
1951
|
+
state.stylexEnvImport.add(localName);
|
|
1952
|
+
}
|
|
1913
1953
|
}
|
|
1914
1954
|
}
|
|
1915
1955
|
}
|
|
@@ -1976,6 +2016,9 @@ function readRequires(path, state) {
|
|
|
1976
2016
|
if (prop.key.name === 'defaultMarker') {
|
|
1977
2017
|
state.stylexDefaultMarkerImport.add(value.name);
|
|
1978
2018
|
}
|
|
2019
|
+
if (prop.key.name === 'env') {
|
|
2020
|
+
state.stylexEnvImport.add(value.name);
|
|
2021
|
+
}
|
|
1979
2022
|
}
|
|
1980
2023
|
}
|
|
1981
2024
|
}
|
|
@@ -4574,7 +4617,6 @@ const ILLEGAL_NESTED_PSEUDO = "Pseudo objects can't be nested more than one leve
|
|
|
4574
4617
|
const ILLEGAL_PROP_VALUE = 'A style value can only contain an array, string or number.';
|
|
4575
4618
|
const ILLEGAL_PROP_ARRAY_VALUE = 'A style array value can only contain strings or numbers.';
|
|
4576
4619
|
const ILLEGAL_NAMESPACE_VALUE = 'A StyleX namespace must be an object.';
|
|
4577
|
-
const INVALID_CONST_KEY = 'Keys in defineConsts() cannot start with "--".';
|
|
4578
4620
|
const INVALID_PSEUDO = 'Invalid pseudo selector, not on the whitelist.';
|
|
4579
4621
|
const INVALID_PSEUDO_OR_AT_RULE = 'Invalid pseudo or at-rule.';
|
|
4580
4622
|
const INVALID_MEDIA_QUERY_SYNTAX = 'Invalid media query syntax.';
|
|
@@ -4597,7 +4639,6 @@ var m = /*#__PURE__*/Object.freeze({
|
|
|
4597
4639
|
ILLEGAL_NESTED_PSEUDO: ILLEGAL_NESTED_PSEUDO,
|
|
4598
4640
|
ILLEGAL_PROP_ARRAY_VALUE: ILLEGAL_PROP_ARRAY_VALUE,
|
|
4599
4641
|
ILLEGAL_PROP_VALUE: ILLEGAL_PROP_VALUE,
|
|
4600
|
-
INVALID_CONST_KEY: INVALID_CONST_KEY,
|
|
4601
4642
|
INVALID_MEDIA_QUERY_SYNTAX: INVALID_MEDIA_QUERY_SYNTAX,
|
|
4602
4643
|
INVALID_PSEUDO: INVALID_PSEUDO,
|
|
4603
4644
|
INVALID_PSEUDO_OR_AT_RULE: INVALID_PSEUDO_OR_AT_RULE,
|
|
@@ -5598,6 +5639,16 @@ function requirePropertyPriorities () {
|
|
|
5598
5639
|
SIBLING_AFTER: /^:where\(:has\(~\s\.[0-9a-zA-Z_-]+(:[a-zA-Z-]+)\)\)$/,
|
|
5599
5640
|
ANY_SIBLING: /^:where\(\.[0-9a-zA-Z_-]+(:[a-zA-Z-]+)\s+~\s+\*,\s+:has\(~\s\.[0-9a-zA-Z_-]+(:[a-zA-Z-]+)\)\)$/
|
|
5600
5641
|
};
|
|
5642
|
+
const PSEUDO_PART_REGEX = /::[a-zA-Z-]+|:[a-zA-Z-]+(?:\([^)]*\))?/g;
|
|
5643
|
+
function getCompoundPseudoPriority(key) {
|
|
5644
|
+
const parts = key.match(PSEUDO_PART_REGEX);
|
|
5645
|
+
if (!parts || parts.length <= 1 || parts.some(p => p.includes('('))) return;
|
|
5646
|
+
let total = 0;
|
|
5647
|
+
for (const part of parts) {
|
|
5648
|
+
total += part.startsWith('::') ? PSEUDO_ELEMENT_PRIORITY : PSEUDO_CLASS_PRIORITIES[part] ?? 40;
|
|
5649
|
+
}
|
|
5650
|
+
return total;
|
|
5651
|
+
}
|
|
5601
5652
|
function getAtRulePriority(key) {
|
|
5602
5653
|
if (key.startsWith('--')) {
|
|
5603
5654
|
return 1;
|
|
@@ -5638,7 +5689,7 @@ function requirePropertyPriorities () {
|
|
|
5638
5689
|
return 40 + pseudoBase(siblingAfterMatch[1]);
|
|
5639
5690
|
}
|
|
5640
5691
|
if (key.startsWith(':')) {
|
|
5641
|
-
const prop = key.
|
|
5692
|
+
const prop = key.split('(')[0];
|
|
5642
5693
|
return PSEUDO_CLASS_PRIORITIES[prop] ?? 40;
|
|
5643
5694
|
}
|
|
5644
5695
|
}
|
|
@@ -5659,6 +5710,8 @@ function requirePropertyPriorities () {
|
|
|
5659
5710
|
function getPriority(key) {
|
|
5660
5711
|
const atRulePriority = getAtRulePriority(key);
|
|
5661
5712
|
if (atRulePriority) return atRulePriority;
|
|
5713
|
+
const compoundPriority = getCompoundPseudoPriority(key);
|
|
5714
|
+
if (compoundPriority != null) return compoundPriority;
|
|
5662
5715
|
const pseudoElementPriority = getPseudoElementPriority(key);
|
|
5663
5716
|
if (pseudoElementPriority) return pseudoElementPriority;
|
|
5664
5717
|
const pseudoClassPriority = getPseudoClassPriority(key);
|
|
@@ -5869,7 +5922,7 @@ class PreRule {
|
|
|
5869
5922
|
this.value = value;
|
|
5870
5923
|
}
|
|
5871
5924
|
get pseudos() {
|
|
5872
|
-
const unsortedPseudos = this.keyPath.filter(key => key.startsWith(':'));
|
|
5925
|
+
const unsortedPseudos = this.keyPath.filter(key => key.startsWith(':') || key.startsWith('['));
|
|
5873
5926
|
return sortPseudos(unsortedPseudos);
|
|
5874
5927
|
}
|
|
5875
5928
|
get atRules() {
|
|
@@ -5974,7 +6027,7 @@ function _flattenRawStyleObject(style, keyPath, options) {
|
|
|
5974
6027
|
});
|
|
5975
6028
|
continue;
|
|
5976
6029
|
}
|
|
5977
|
-
if (typeof value === 'object' && !key.startsWith(':') && !key.startsWith('@')) {
|
|
6030
|
+
if (typeof value === 'object' && !key.startsWith(':') && !key.startsWith('@') && !key.startsWith('[')) {
|
|
5978
6031
|
const equivalentPairs = {};
|
|
5979
6032
|
for (const condition in value) {
|
|
5980
6033
|
const innerValue = value[condition];
|
|
@@ -6000,7 +6053,7 @@ function _flattenRawStyleObject(style, keyPath, options) {
|
|
|
6000
6053
|
flattened.push([property, PreRuleSet.create(rules)]);
|
|
6001
6054
|
}
|
|
6002
6055
|
}
|
|
6003
|
-
if (typeof value === 'object' && (key.startsWith(':') || key.startsWith('@'))) {
|
|
6056
|
+
if (typeof value === 'object' && (key.startsWith(':') || key.startsWith('@') || key.startsWith('['))) {
|
|
6004
6057
|
const pairs = _flattenRawStyleObject(value, [...keyPath, _key], options);
|
|
6005
6058
|
for (const [property, preRule] of pairs) {
|
|
6006
6059
|
flattened.push([key + '_' + property, preRule]);
|
|
@@ -6030,7 +6083,7 @@ function validateNamespace(namespace, conditions = []) {
|
|
|
6030
6083
|
continue;
|
|
6031
6084
|
}
|
|
6032
6085
|
if (isPlainObject(val)) {
|
|
6033
|
-
if (key.startsWith('@') || key.startsWith(':')) {
|
|
6086
|
+
if (key.startsWith('@') || key.startsWith(':') || key.startsWith('[')) {
|
|
6034
6087
|
if (conditions.includes(key)) {
|
|
6035
6088
|
throw new Error(DUPLICATE_CONDITIONAL);
|
|
6036
6089
|
}
|
|
@@ -6046,7 +6099,7 @@ function validateNamespace(namespace, conditions = []) {
|
|
|
6046
6099
|
function validateConditionalStyles(val, conditions = []) {
|
|
6047
6100
|
for (const key in val) {
|
|
6048
6101
|
const v = val[key];
|
|
6049
|
-
if (!(key.startsWith('@') || key.startsWith(':') || key.startsWith('var(--') || key === 'default')) {
|
|
6102
|
+
if (!(key.startsWith('@') || key.startsWith(':') || key.startsWith('[') || key.startsWith('var(--') || key === 'default')) {
|
|
6050
6103
|
throw new Error(INVALID_PSEUDO_OR_AT_RULE);
|
|
6051
6104
|
}
|
|
6052
6105
|
if (conditions.includes(key)) {
|
|
@@ -6432,11 +6485,8 @@ function styleXDefineConsts(constants, options) {
|
|
|
6432
6485
|
const jsOutput = {};
|
|
6433
6486
|
const injectableStyles = {};
|
|
6434
6487
|
for (const [key, value] of Object.entries(constants)) {
|
|
6435
|
-
if (key.startsWith('--')) {
|
|
6436
|
-
throw new Error(INVALID_CONST_KEY);
|
|
6437
|
-
}
|
|
6438
6488
|
const varSafeKey = (key[0] >= '0' && key[0] <= '9' ? `_${key}` : key).replace(/[^a-zA-Z0-9]/g, '_');
|
|
6439
|
-
const constKey = debug && enableDebugClassNames ? `${varSafeKey}-${classNamePrefix}${hash(`${exportId}.${key}`)}` : `${classNamePrefix}${hash(`${exportId}.${key}`)}`;
|
|
6489
|
+
const constKey = key.startsWith('--') ? key.slice(2) : debug && enableDebugClassNames ? `${varSafeKey}-${classNamePrefix}${hash(`${exportId}.${key}`)}` : `${classNamePrefix}${hash(`${exportId}.${key}`)}`;
|
|
6440
6490
|
jsOutput[key] = value;
|
|
6441
6491
|
injectableStyles[constKey] = {
|
|
6442
6492
|
constKey,
|
|
@@ -6608,12 +6658,15 @@ function getDefaultMarkerClassName(options = defaultOptions) {
|
|
|
6608
6658
|
return `${prefix}default-marker`;
|
|
6609
6659
|
}
|
|
6610
6660
|
function validatePseudoSelector(pseudo) {
|
|
6611
|
-
if (!pseudo.startsWith(':')) {
|
|
6612
|
-
throw new Error('Pseudo selector must start with ":"');
|
|
6661
|
+
if (!(pseudo.startsWith(':') || pseudo.startsWith('['))) {
|
|
6662
|
+
throw new Error('Pseudo selector must start with ":" or "["');
|
|
6613
6663
|
}
|
|
6614
6664
|
if (pseudo.startsWith('::')) {
|
|
6615
6665
|
throw new Error('Pseudo selector cannot start with "::" (pseudo-elements are not supported)');
|
|
6616
6666
|
}
|
|
6667
|
+
if (pseudo.startsWith('[') && !pseudo.endsWith(']')) {
|
|
6668
|
+
throw new Error('Attribute selector must end with "]"');
|
|
6669
|
+
}
|
|
6617
6670
|
}
|
|
6618
6671
|
function ancestor(pseudo, options = defaultOptions) {
|
|
6619
6672
|
validatePseudoSelector(pseudo);
|
|
@@ -7651,6 +7704,18 @@ function isSafeToSkipNullCheck(expr) {
|
|
|
7651
7704
|
}
|
|
7652
7705
|
return false;
|
|
7653
7706
|
}
|
|
7707
|
+
function hasExplicitNullishFallback(expr) {
|
|
7708
|
+
if (isNullLiteral(expr)) return true;
|
|
7709
|
+
if (isIdentifier(expr) && expr.name === 'undefined') return true;
|
|
7710
|
+
if (isUnaryExpression(expr) && expr.operator === 'void') return true;
|
|
7711
|
+
if (isConditionalExpression(expr)) {
|
|
7712
|
+
return hasExplicitNullishFallback(expr.consequent) || hasExplicitNullishFallback(expr.alternate);
|
|
7713
|
+
}
|
|
7714
|
+
if (isLogicalExpression(expr)) {
|
|
7715
|
+
return hasExplicitNullishFallback(expr.left) || hasExplicitNullishFallback(expr.right);
|
|
7716
|
+
}
|
|
7717
|
+
return false;
|
|
7718
|
+
}
|
|
7654
7719
|
function transformStyleXCreate(path, state) {
|
|
7655
7720
|
const {
|
|
7656
7721
|
node
|
|
@@ -7719,6 +7784,7 @@ function transformStyleXCreate(path, state) {
|
|
|
7719
7784
|
when: stylexWhen
|
|
7720
7785
|
};
|
|
7721
7786
|
});
|
|
7787
|
+
state.applyStylexEnv(identifiers);
|
|
7722
7788
|
const {
|
|
7723
7789
|
confident,
|
|
7724
7790
|
value,
|
|
@@ -7746,7 +7812,7 @@ function transformStyleXCreate(path, state) {
|
|
|
7746
7812
|
const isPseudoElement = path.some(p => p.startsWith('::'));
|
|
7747
7813
|
injectedInheritStyles[variableName] = {
|
|
7748
7814
|
priority: 0,
|
|
7749
|
-
ltr: `@property ${variableName} { syntax: "*"
|
|
7815
|
+
ltr: `@property ${variableName} { syntax: "*"; inherits: ${isPseudoElement ? 'true' : 'false'};}`,
|
|
7750
7816
|
rtl: null
|
|
7751
7817
|
};
|
|
7752
7818
|
});
|
|
@@ -7795,14 +7861,21 @@ function transformStyleXCreate(path, state) {
|
|
|
7795
7861
|
for (const [className, classPaths] of Object.entries(classPathsPerNamespace[key])) {
|
|
7796
7862
|
origClassPaths[className] = classPaths.join('_');
|
|
7797
7863
|
}
|
|
7798
|
-
let dynamicStyles = Object.entries(inlineStyles).map(([
|
|
7864
|
+
let dynamicStyles = Object.entries(inlineStyles).map(([varName, v]) => ({
|
|
7799
7865
|
expression: v.originalExpression,
|
|
7800
7866
|
key: v.path.slice(0, v.path.findIndex(p => !p.startsWith(':') && !p.startsWith('@')) + 1).join('_'),
|
|
7867
|
+
varName,
|
|
7801
7868
|
path: v.path.join('_')
|
|
7802
7869
|
}));
|
|
7803
7870
|
if (state.options.styleResolution === 'legacy-expand-shorthands') {
|
|
7804
7871
|
dynamicStyles = legacyExpandShorthands(dynamicStyles);
|
|
7805
7872
|
}
|
|
7873
|
+
const nullishVarExpressions = new Map();
|
|
7874
|
+
dynamicStyles.forEach(style => {
|
|
7875
|
+
if (hasExplicitNullishFallback(style.expression)) {
|
|
7876
|
+
nullishVarExpressions.set(style.varName, style.expression);
|
|
7877
|
+
}
|
|
7878
|
+
});
|
|
7806
7879
|
if (isObjectExpression(prop.value)) {
|
|
7807
7880
|
const value = prop.value;
|
|
7808
7881
|
let cssTagValue = booleanLiteral(true);
|
|
@@ -7826,9 +7899,23 @@ function transformStyleXCreate(path, state) {
|
|
|
7826
7899
|
let isStatic = true;
|
|
7827
7900
|
const exprList = [];
|
|
7828
7901
|
classList.forEach((cls, index) => {
|
|
7829
|
-
|
|
7902
|
+
let expr = dynamicStyles.find(({
|
|
7830
7903
|
path
|
|
7831
7904
|
}) => origClassPaths[cls] === path)?.expression;
|
|
7905
|
+
if (expr == null && nullishVarExpressions.size > 0) {
|
|
7906
|
+
const injectedStyle = injectedStyles[cls];
|
|
7907
|
+
const rule = injectedStyle != null ? typeof injectedStyle.ltr === 'string' ? injectedStyle.ltr : typeof injectedStyle.rtl === 'string' ? injectedStyle.rtl : null : null;
|
|
7908
|
+
if (rule != null) {
|
|
7909
|
+
const matches = rule.matchAll(/var\((--x-[^,)]+)[^)]*\)/g);
|
|
7910
|
+
for (const match of matches) {
|
|
7911
|
+
const varExpr = nullishVarExpressions.get(match[1]);
|
|
7912
|
+
if (varExpr != null) {
|
|
7913
|
+
expr = varExpr;
|
|
7914
|
+
break;
|
|
7915
|
+
}
|
|
7916
|
+
}
|
|
7917
|
+
}
|
|
7918
|
+
}
|
|
7832
7919
|
const isLast = index === classList.length - 1;
|
|
7833
7920
|
const clsWithSpace = isLast ? cls : cls + ' ';
|
|
7834
7921
|
if (expr && !isSafeToSkipNullCheck(expr)) {
|
|
@@ -7989,6 +8076,7 @@ function transformStyleXCreateTheme(callExpressionPath, state) {
|
|
|
7989
8076
|
types: stylexTypes
|
|
7990
8077
|
};
|
|
7991
8078
|
});
|
|
8079
|
+
state.applyStylexEnv(identifiers);
|
|
7992
8080
|
const {
|
|
7993
8081
|
confident: confident2,
|
|
7994
8082
|
value: overrides
|
|
@@ -8103,6 +8191,7 @@ function transformStyleXDefineVars(callExpressionPath, state) {
|
|
|
8103
8191
|
types: stylexTypes
|
|
8104
8192
|
};
|
|
8105
8193
|
});
|
|
8194
|
+
state.applyStylexEnv(identifiers);
|
|
8106
8195
|
const {
|
|
8107
8196
|
confident,
|
|
8108
8197
|
value
|
|
@@ -8165,10 +8254,16 @@ function transformStyleXDefineConsts(callExpressionPath, state) {
|
|
|
8165
8254
|
const varId = variableDeclaratorNode.id;
|
|
8166
8255
|
const args = callExpressionPath.get('arguments');
|
|
8167
8256
|
const firstArg = args[0];
|
|
8257
|
+
const evaluatePathFnConfig = {
|
|
8258
|
+
identifiers: {},
|
|
8259
|
+
memberExpressions: {},
|
|
8260
|
+
disableImports: true
|
|
8261
|
+
};
|
|
8262
|
+
state.applyStylexEnv(evaluatePathFnConfig.identifiers);
|
|
8168
8263
|
const {
|
|
8169
8264
|
confident,
|
|
8170
8265
|
value
|
|
8171
|
-
} = evaluate(firstArg, state);
|
|
8266
|
+
} = evaluate(firstArg, state, evaluatePathFnConfig);
|
|
8172
8267
|
if (!confident) {
|
|
8173
8268
|
throw callExpressionPath.buildCodeFrameError(messages.nonStaticValue('defineConsts'), SyntaxError);
|
|
8174
8269
|
}
|
|
@@ -8250,6 +8345,7 @@ function transformStyleXKeyframes(path, state) {
|
|
|
8250
8345
|
fn: firstThatWorks
|
|
8251
8346
|
};
|
|
8252
8347
|
});
|
|
8348
|
+
state.applyStylexEnv(identifiers);
|
|
8253
8349
|
const {
|
|
8254
8350
|
confident,
|
|
8255
8351
|
value
|
|
@@ -8321,6 +8417,7 @@ function transformStyleXPositionTry(path, state) {
|
|
|
8321
8417
|
fn: firstThatWorks
|
|
8322
8418
|
};
|
|
8323
8419
|
});
|
|
8420
|
+
state.applyStylexEnv(identifiers);
|
|
8324
8421
|
const {
|
|
8325
8422
|
confident,
|
|
8326
8423
|
value
|
|
@@ -8375,6 +8472,12 @@ function transformStyleXMerge(path, state) {
|
|
|
8375
8472
|
if (node == null || node.callee.type !== 'Identifier' || !state.stylexImport.has(node.callee.name)) {
|
|
8376
8473
|
return;
|
|
8377
8474
|
}
|
|
8475
|
+
const evaluatePathFnConfig = {
|
|
8476
|
+
identifiers: {},
|
|
8477
|
+
memberExpressions: {},
|
|
8478
|
+
disableImports: true
|
|
8479
|
+
};
|
|
8480
|
+
state.applyStylexEnv(evaluatePathFnConfig.identifiers);
|
|
8378
8481
|
let bailOut = false;
|
|
8379
8482
|
let conditional = 0;
|
|
8380
8483
|
let currentIndex = -1;
|
|
@@ -8481,7 +8584,7 @@ function transformStyleXMerge(path, state) {
|
|
|
8481
8584
|
const {
|
|
8482
8585
|
confident,
|
|
8483
8586
|
value: styleValue
|
|
8484
|
-
} = evaluate(path, state);
|
|
8587
|
+
} = evaluate(path, state, evaluatePathFnConfig);
|
|
8485
8588
|
if (!confident || styleValue == null) {
|
|
8486
8589
|
nonNullProps = true;
|
|
8487
8590
|
styleNonNullProps = true;
|
|
@@ -8617,6 +8720,7 @@ function transformStylexProps(path, state) {
|
|
|
8617
8720
|
}
|
|
8618
8721
|
};
|
|
8619
8722
|
});
|
|
8723
|
+
state.applyStylexEnv(identifiers);
|
|
8620
8724
|
const evaluatePathFnConfig = {
|
|
8621
8725
|
identifiers,
|
|
8622
8726
|
memberExpressions,
|
|
@@ -8942,6 +9046,7 @@ function transformStyleXViewTransitionClass(path, state) {
|
|
|
8942
9046
|
fn: keyframes$1
|
|
8943
9047
|
};
|
|
8944
9048
|
});
|
|
9049
|
+
state.applyStylexEnv(identifiers);
|
|
8945
9050
|
const {
|
|
8946
9051
|
confident,
|
|
8947
9052
|
value
|
package/lib/index.js
CHANGED
|
@@ -370,6 +370,12 @@ const checkRuntimeInjection = unionOf3(boolean(), string(), object({
|
|
|
370
370
|
from: string(),
|
|
371
371
|
as: string()
|
|
372
372
|
}));
|
|
373
|
+
const checkEnvOption = (value, name = 'options.env') => {
|
|
374
|
+
if (typeof value !== 'object' || value == null || Array.isArray(value)) {
|
|
375
|
+
return new Error(`Expected (${name}) to be an object, but got \`${String(JSON.stringify(value))}\`.`);
|
|
376
|
+
}
|
|
377
|
+
return value;
|
|
378
|
+
};
|
|
373
379
|
const DEFAULT_INJECT_PATH = '@stylexjs/stylex/lib/stylex-inject';
|
|
374
380
|
class StateManager {
|
|
375
381
|
importPaths = new Set();
|
|
@@ -389,6 +395,7 @@ class StateManager {
|
|
|
389
395
|
stylexViewTransitionClassImport = new Set();
|
|
390
396
|
stylexDefaultMarkerImport = new Set();
|
|
391
397
|
stylexWhenImport = new Set();
|
|
398
|
+
stylexEnvImport = new Set();
|
|
392
399
|
injectImportInserted = null;
|
|
393
400
|
styleMap = new Map();
|
|
394
401
|
styleVars = new Map();
|
|
@@ -422,6 +429,10 @@ class StateManager {
|
|
|
422
429
|
const propertyValidationMode = logAndDefault(unionOf3(literal('throw'), literal('warn'), literal('silent')), options.propertyValidationMode ?? defaultOptions.propertyValidationMode, 'silent', 'options.propertyValidationMode');
|
|
423
430
|
const unstable_moduleResolution = logAndDefault(unionOf(nullish(), CheckModuleResolution), options.unstable_moduleResolution, null, 'options.unstable_moduleResolution');
|
|
424
431
|
const treeshakeCompensation = logAndDefault(boolean(), options.treeshakeCompensation ?? defaultOptions.treeshakeCompensation, false, 'options.treeshakeCompensation');
|
|
432
|
+
const envInput = logAndDefault(checkEnvOption, options.env ?? {}, {}, 'options.env');
|
|
433
|
+
const env = Object.freeze({
|
|
434
|
+
...envInput
|
|
435
|
+
});
|
|
425
436
|
const aliasesOption = logAndDefault(unionOf(nullish(), objectOf(unionOf(string(), array(string())))), options.aliases, null, 'options.aliases');
|
|
426
437
|
const aliases = aliasesOption == null ? aliasesOption : Object.fromEntries(Object.entries(aliasesOption).map(([key, value]) => {
|
|
427
438
|
if (typeof value === 'string') {
|
|
@@ -437,6 +448,7 @@ class StateManager {
|
|
|
437
448
|
definedStylexCSSVariables: {},
|
|
438
449
|
dev,
|
|
439
450
|
propertyValidationMode,
|
|
451
|
+
env,
|
|
440
452
|
enableDebugClassNames,
|
|
441
453
|
enableDebugDataProp,
|
|
442
454
|
enableDevClassNames,
|
|
@@ -478,6 +490,31 @@ class StateManager {
|
|
|
478
490
|
}
|
|
479
491
|
return null;
|
|
480
492
|
}
|
|
493
|
+
applyStylexEnv(identifiers) {
|
|
494
|
+
const env = this.options.env;
|
|
495
|
+
this.stylexImport.forEach(importName => {
|
|
496
|
+
const current = identifiers[importName];
|
|
497
|
+
if (current != null && typeof current === 'object' && !Array.isArray(current)) {
|
|
498
|
+
if ('fn' in current) {
|
|
499
|
+
identifiers[importName] = {
|
|
500
|
+
env
|
|
501
|
+
};
|
|
502
|
+
} else {
|
|
503
|
+
identifiers[importName] = {
|
|
504
|
+
...current,
|
|
505
|
+
env
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
identifiers[importName] = {
|
|
511
|
+
env
|
|
512
|
+
};
|
|
513
|
+
});
|
|
514
|
+
this.stylexEnvImport.forEach(importName => {
|
|
515
|
+
identifiers[importName] = env;
|
|
516
|
+
});
|
|
517
|
+
}
|
|
481
518
|
get canReferenceTheme() {
|
|
482
519
|
return !!this.inStyleXCreate;
|
|
483
520
|
}
|
|
@@ -796,6 +833,9 @@ function readImportDeclarations(path, state) {
|
|
|
796
833
|
if (importedName === 'defaultMarker') {
|
|
797
834
|
state.stylexDefaultMarkerImport.add(localName);
|
|
798
835
|
}
|
|
836
|
+
if (importedName === 'env') {
|
|
837
|
+
state.stylexEnvImport.add(localName);
|
|
838
|
+
}
|
|
799
839
|
}
|
|
800
840
|
}
|
|
801
841
|
}
|
|
@@ -862,6 +902,9 @@ function readRequires(path, state) {
|
|
|
862
902
|
if (prop.key.name === 'defaultMarker') {
|
|
863
903
|
state.stylexDefaultMarkerImport.add(value.name);
|
|
864
904
|
}
|
|
905
|
+
if (prop.key.name === 'env') {
|
|
906
|
+
state.stylexEnvImport.add(value.name);
|
|
907
|
+
}
|
|
865
908
|
}
|
|
866
909
|
}
|
|
867
910
|
}
|
|
@@ -3460,7 +3503,6 @@ const ILLEGAL_NESTED_PSEUDO = "Pseudo objects can't be nested more than one leve
|
|
|
3460
3503
|
const ILLEGAL_PROP_VALUE = 'A style value can only contain an array, string or number.';
|
|
3461
3504
|
const ILLEGAL_PROP_ARRAY_VALUE = 'A style array value can only contain strings or numbers.';
|
|
3462
3505
|
const ILLEGAL_NAMESPACE_VALUE = 'A StyleX namespace must be an object.';
|
|
3463
|
-
const INVALID_CONST_KEY = 'Keys in defineConsts() cannot start with "--".';
|
|
3464
3506
|
const INVALID_PSEUDO = 'Invalid pseudo selector, not on the whitelist.';
|
|
3465
3507
|
const INVALID_PSEUDO_OR_AT_RULE = 'Invalid pseudo or at-rule.';
|
|
3466
3508
|
const INVALID_MEDIA_QUERY_SYNTAX = 'Invalid media query syntax.';
|
|
@@ -3483,7 +3525,6 @@ var m = /*#__PURE__*/Object.freeze({
|
|
|
3483
3525
|
ILLEGAL_NESTED_PSEUDO: ILLEGAL_NESTED_PSEUDO,
|
|
3484
3526
|
ILLEGAL_PROP_ARRAY_VALUE: ILLEGAL_PROP_ARRAY_VALUE,
|
|
3485
3527
|
ILLEGAL_PROP_VALUE: ILLEGAL_PROP_VALUE,
|
|
3486
|
-
INVALID_CONST_KEY: INVALID_CONST_KEY,
|
|
3487
3528
|
INVALID_MEDIA_QUERY_SYNTAX: INVALID_MEDIA_QUERY_SYNTAX,
|
|
3488
3529
|
INVALID_PSEUDO: INVALID_PSEUDO,
|
|
3489
3530
|
INVALID_PSEUDO_OR_AT_RULE: INVALID_PSEUDO_OR_AT_RULE,
|
|
@@ -4484,6 +4525,16 @@ function requirePropertyPriorities () {
|
|
|
4484
4525
|
SIBLING_AFTER: /^:where\(:has\(~\s\.[0-9a-zA-Z_-]+(:[a-zA-Z-]+)\)\)$/,
|
|
4485
4526
|
ANY_SIBLING: /^:where\(\.[0-9a-zA-Z_-]+(:[a-zA-Z-]+)\s+~\s+\*,\s+:has\(~\s\.[0-9a-zA-Z_-]+(:[a-zA-Z-]+)\)\)$/
|
|
4486
4527
|
};
|
|
4528
|
+
const PSEUDO_PART_REGEX = /::[a-zA-Z-]+|:[a-zA-Z-]+(?:\([^)]*\))?/g;
|
|
4529
|
+
function getCompoundPseudoPriority(key) {
|
|
4530
|
+
const parts = key.match(PSEUDO_PART_REGEX);
|
|
4531
|
+
if (!parts || parts.length <= 1 || parts.some(p => p.includes('('))) return;
|
|
4532
|
+
let total = 0;
|
|
4533
|
+
for (const part of parts) {
|
|
4534
|
+
total += part.startsWith('::') ? PSEUDO_ELEMENT_PRIORITY : PSEUDO_CLASS_PRIORITIES[part] ?? 40;
|
|
4535
|
+
}
|
|
4536
|
+
return total;
|
|
4537
|
+
}
|
|
4487
4538
|
function getAtRulePriority(key) {
|
|
4488
4539
|
if (key.startsWith('--')) {
|
|
4489
4540
|
return 1;
|
|
@@ -4524,7 +4575,7 @@ function requirePropertyPriorities () {
|
|
|
4524
4575
|
return 40 + pseudoBase(siblingAfterMatch[1]);
|
|
4525
4576
|
}
|
|
4526
4577
|
if (key.startsWith(':')) {
|
|
4527
|
-
const prop = key.
|
|
4578
|
+
const prop = key.split('(')[0];
|
|
4528
4579
|
return PSEUDO_CLASS_PRIORITIES[prop] ?? 40;
|
|
4529
4580
|
}
|
|
4530
4581
|
}
|
|
@@ -4545,6 +4596,8 @@ function requirePropertyPriorities () {
|
|
|
4545
4596
|
function getPriority(key) {
|
|
4546
4597
|
const atRulePriority = getAtRulePriority(key);
|
|
4547
4598
|
if (atRulePriority) return atRulePriority;
|
|
4599
|
+
const compoundPriority = getCompoundPseudoPriority(key);
|
|
4600
|
+
if (compoundPriority != null) return compoundPriority;
|
|
4548
4601
|
const pseudoElementPriority = getPseudoElementPriority(key);
|
|
4549
4602
|
if (pseudoElementPriority) return pseudoElementPriority;
|
|
4550
4603
|
const pseudoClassPriority = getPseudoClassPriority(key);
|
|
@@ -4755,7 +4808,7 @@ class PreRule {
|
|
|
4755
4808
|
this.value = value;
|
|
4756
4809
|
}
|
|
4757
4810
|
get pseudos() {
|
|
4758
|
-
const unsortedPseudos = this.keyPath.filter(key => key.startsWith(':'));
|
|
4811
|
+
const unsortedPseudos = this.keyPath.filter(key => key.startsWith(':') || key.startsWith('['));
|
|
4759
4812
|
return sortPseudos(unsortedPseudos);
|
|
4760
4813
|
}
|
|
4761
4814
|
get atRules() {
|
|
@@ -4860,7 +4913,7 @@ function _flattenRawStyleObject(style, keyPath, options) {
|
|
|
4860
4913
|
});
|
|
4861
4914
|
continue;
|
|
4862
4915
|
}
|
|
4863
|
-
if (typeof value === 'object' && !key.startsWith(':') && !key.startsWith('@')) {
|
|
4916
|
+
if (typeof value === 'object' && !key.startsWith(':') && !key.startsWith('@') && !key.startsWith('[')) {
|
|
4864
4917
|
const equivalentPairs = {};
|
|
4865
4918
|
for (const condition in value) {
|
|
4866
4919
|
const innerValue = value[condition];
|
|
@@ -4886,7 +4939,7 @@ function _flattenRawStyleObject(style, keyPath, options) {
|
|
|
4886
4939
|
flattened.push([property, PreRuleSet.create(rules)]);
|
|
4887
4940
|
}
|
|
4888
4941
|
}
|
|
4889
|
-
if (typeof value === 'object' && (key.startsWith(':') || key.startsWith('@'))) {
|
|
4942
|
+
if (typeof value === 'object' && (key.startsWith(':') || key.startsWith('@') || key.startsWith('['))) {
|
|
4890
4943
|
const pairs = _flattenRawStyleObject(value, [...keyPath, _key], options);
|
|
4891
4944
|
for (const [property, preRule] of pairs) {
|
|
4892
4945
|
flattened.push([key + '_' + property, preRule]);
|
|
@@ -4916,7 +4969,7 @@ function validateNamespace(namespace, conditions = []) {
|
|
|
4916
4969
|
continue;
|
|
4917
4970
|
}
|
|
4918
4971
|
if (isPlainObject(val)) {
|
|
4919
|
-
if (key.startsWith('@') || key.startsWith(':')) {
|
|
4972
|
+
if (key.startsWith('@') || key.startsWith(':') || key.startsWith('[')) {
|
|
4920
4973
|
if (conditions.includes(key)) {
|
|
4921
4974
|
throw new Error(DUPLICATE_CONDITIONAL);
|
|
4922
4975
|
}
|
|
@@ -4932,7 +4985,7 @@ function validateNamespace(namespace, conditions = []) {
|
|
|
4932
4985
|
function validateConditionalStyles(val, conditions = []) {
|
|
4933
4986
|
for (const key in val) {
|
|
4934
4987
|
const v = val[key];
|
|
4935
|
-
if (!(key.startsWith('@') || key.startsWith(':') || key.startsWith('var(--') || key === 'default')) {
|
|
4988
|
+
if (!(key.startsWith('@') || key.startsWith(':') || key.startsWith('[') || key.startsWith('var(--') || key === 'default')) {
|
|
4936
4989
|
throw new Error(INVALID_PSEUDO_OR_AT_RULE);
|
|
4937
4990
|
}
|
|
4938
4991
|
if (conditions.includes(key)) {
|
|
@@ -5318,11 +5371,8 @@ function styleXDefineConsts(constants, options) {
|
|
|
5318
5371
|
const jsOutput = {};
|
|
5319
5372
|
const injectableStyles = {};
|
|
5320
5373
|
for (const [key, value] of Object.entries(constants)) {
|
|
5321
|
-
if (key.startsWith('--')) {
|
|
5322
|
-
throw new Error(INVALID_CONST_KEY);
|
|
5323
|
-
}
|
|
5324
5374
|
const varSafeKey = (key[0] >= '0' && key[0] <= '9' ? `_${key}` : key).replace(/[^a-zA-Z0-9]/g, '_');
|
|
5325
|
-
const constKey = debug && enableDebugClassNames ? `${varSafeKey}-${classNamePrefix}${hash(`${exportId}.${key}`)}` : `${classNamePrefix}${hash(`${exportId}.${key}`)}`;
|
|
5375
|
+
const constKey = key.startsWith('--') ? key.slice(2) : debug && enableDebugClassNames ? `${varSafeKey}-${classNamePrefix}${hash(`${exportId}.${key}`)}` : `${classNamePrefix}${hash(`${exportId}.${key}`)}`;
|
|
5326
5376
|
jsOutput[key] = value;
|
|
5327
5377
|
injectableStyles[constKey] = {
|
|
5328
5378
|
constKey,
|
|
@@ -5494,12 +5544,15 @@ function getDefaultMarkerClassName(options = defaultOptions) {
|
|
|
5494
5544
|
return `${prefix}default-marker`;
|
|
5495
5545
|
}
|
|
5496
5546
|
function validatePseudoSelector(pseudo) {
|
|
5497
|
-
if (!pseudo.startsWith(':')) {
|
|
5498
|
-
throw new Error('Pseudo selector must start with ":"');
|
|
5547
|
+
if (!(pseudo.startsWith(':') || pseudo.startsWith('['))) {
|
|
5548
|
+
throw new Error('Pseudo selector must start with ":" or "["');
|
|
5499
5549
|
}
|
|
5500
5550
|
if (pseudo.startsWith('::')) {
|
|
5501
5551
|
throw new Error('Pseudo selector cannot start with "::" (pseudo-elements are not supported)');
|
|
5502
5552
|
}
|
|
5553
|
+
if (pseudo.startsWith('[') && !pseudo.endsWith(']')) {
|
|
5554
|
+
throw new Error('Attribute selector must end with "]"');
|
|
5555
|
+
}
|
|
5503
5556
|
}
|
|
5504
5557
|
function ancestor(pseudo, options = defaultOptions) {
|
|
5505
5558
|
validatePseudoSelector(pseudo);
|
|
@@ -6533,6 +6586,18 @@ function isSafeToSkipNullCheck(expr) {
|
|
|
6533
6586
|
}
|
|
6534
6587
|
return false;
|
|
6535
6588
|
}
|
|
6589
|
+
function hasExplicitNullishFallback(expr) {
|
|
6590
|
+
if (t__namespace.isNullLiteral(expr)) return true;
|
|
6591
|
+
if (t__namespace.isIdentifier(expr) && expr.name === 'undefined') return true;
|
|
6592
|
+
if (t__namespace.isUnaryExpression(expr) && expr.operator === 'void') return true;
|
|
6593
|
+
if (t__namespace.isConditionalExpression(expr)) {
|
|
6594
|
+
return hasExplicitNullishFallback(expr.consequent) || hasExplicitNullishFallback(expr.alternate);
|
|
6595
|
+
}
|
|
6596
|
+
if (t__namespace.isLogicalExpression(expr)) {
|
|
6597
|
+
return hasExplicitNullishFallback(expr.left) || hasExplicitNullishFallback(expr.right);
|
|
6598
|
+
}
|
|
6599
|
+
return false;
|
|
6600
|
+
}
|
|
6536
6601
|
function transformStyleXCreate(path, state) {
|
|
6537
6602
|
const {
|
|
6538
6603
|
node
|
|
@@ -6601,6 +6666,7 @@ function transformStyleXCreate(path, state) {
|
|
|
6601
6666
|
when: stylexWhen
|
|
6602
6667
|
};
|
|
6603
6668
|
});
|
|
6669
|
+
state.applyStylexEnv(identifiers);
|
|
6604
6670
|
const {
|
|
6605
6671
|
confident,
|
|
6606
6672
|
value,
|
|
@@ -6628,7 +6694,7 @@ function transformStyleXCreate(path, state) {
|
|
|
6628
6694
|
const isPseudoElement = path.some(p => p.startsWith('::'));
|
|
6629
6695
|
injectedInheritStyles[variableName] = {
|
|
6630
6696
|
priority: 0,
|
|
6631
|
-
ltr: `@property ${variableName} { syntax: "*"
|
|
6697
|
+
ltr: `@property ${variableName} { syntax: "*"; inherits: ${isPseudoElement ? 'true' : 'false'};}`,
|
|
6632
6698
|
rtl: null
|
|
6633
6699
|
};
|
|
6634
6700
|
});
|
|
@@ -6677,14 +6743,21 @@ function transformStyleXCreate(path, state) {
|
|
|
6677
6743
|
for (const [className, classPaths] of Object.entries(classPathsPerNamespace[key])) {
|
|
6678
6744
|
origClassPaths[className] = classPaths.join('_');
|
|
6679
6745
|
}
|
|
6680
|
-
let dynamicStyles = Object.entries(inlineStyles).map(([
|
|
6746
|
+
let dynamicStyles = Object.entries(inlineStyles).map(([varName, v]) => ({
|
|
6681
6747
|
expression: v.originalExpression,
|
|
6682
6748
|
key: v.path.slice(0, v.path.findIndex(p => !p.startsWith(':') && !p.startsWith('@')) + 1).join('_'),
|
|
6749
|
+
varName,
|
|
6683
6750
|
path: v.path.join('_')
|
|
6684
6751
|
}));
|
|
6685
6752
|
if (state.options.styleResolution === 'legacy-expand-shorthands') {
|
|
6686
6753
|
dynamicStyles = legacyExpandShorthands(dynamicStyles);
|
|
6687
6754
|
}
|
|
6755
|
+
const nullishVarExpressions = new Map();
|
|
6756
|
+
dynamicStyles.forEach(style => {
|
|
6757
|
+
if (hasExplicitNullishFallback(style.expression)) {
|
|
6758
|
+
nullishVarExpressions.set(style.varName, style.expression);
|
|
6759
|
+
}
|
|
6760
|
+
});
|
|
6688
6761
|
if (t__namespace.isObjectExpression(prop.value)) {
|
|
6689
6762
|
const value = prop.value;
|
|
6690
6763
|
let cssTagValue = t__namespace.booleanLiteral(true);
|
|
@@ -6708,9 +6781,23 @@ function transformStyleXCreate(path, state) {
|
|
|
6708
6781
|
let isStatic = true;
|
|
6709
6782
|
const exprList = [];
|
|
6710
6783
|
classList.forEach((cls, index) => {
|
|
6711
|
-
|
|
6784
|
+
let expr = dynamicStyles.find(({
|
|
6712
6785
|
path
|
|
6713
6786
|
}) => origClassPaths[cls] === path)?.expression;
|
|
6787
|
+
if (expr == null && nullishVarExpressions.size > 0) {
|
|
6788
|
+
const injectedStyle = injectedStyles[cls];
|
|
6789
|
+
const rule = injectedStyle != null ? typeof injectedStyle.ltr === 'string' ? injectedStyle.ltr : typeof injectedStyle.rtl === 'string' ? injectedStyle.rtl : null : null;
|
|
6790
|
+
if (rule != null) {
|
|
6791
|
+
const matches = rule.matchAll(/var\((--x-[^,)]+)[^)]*\)/g);
|
|
6792
|
+
for (const match of matches) {
|
|
6793
|
+
const varExpr = nullishVarExpressions.get(match[1]);
|
|
6794
|
+
if (varExpr != null) {
|
|
6795
|
+
expr = varExpr;
|
|
6796
|
+
break;
|
|
6797
|
+
}
|
|
6798
|
+
}
|
|
6799
|
+
}
|
|
6800
|
+
}
|
|
6714
6801
|
const isLast = index === classList.length - 1;
|
|
6715
6802
|
const clsWithSpace = isLast ? cls : cls + ' ';
|
|
6716
6803
|
if (expr && !isSafeToSkipNullCheck(expr)) {
|
|
@@ -6871,6 +6958,7 @@ function transformStyleXCreateTheme(callExpressionPath, state) {
|
|
|
6871
6958
|
types: stylexTypes
|
|
6872
6959
|
};
|
|
6873
6960
|
});
|
|
6961
|
+
state.applyStylexEnv(identifiers);
|
|
6874
6962
|
const {
|
|
6875
6963
|
confident: confident2,
|
|
6876
6964
|
value: overrides
|
|
@@ -6985,6 +7073,7 @@ function transformStyleXDefineVars(callExpressionPath, state) {
|
|
|
6985
7073
|
types: stylexTypes
|
|
6986
7074
|
};
|
|
6987
7075
|
});
|
|
7076
|
+
state.applyStylexEnv(identifiers);
|
|
6988
7077
|
const {
|
|
6989
7078
|
confident,
|
|
6990
7079
|
value
|
|
@@ -7047,10 +7136,16 @@ function transformStyleXDefineConsts(callExpressionPath, state) {
|
|
|
7047
7136
|
const varId = variableDeclaratorNode.id;
|
|
7048
7137
|
const args = callExpressionPath.get('arguments');
|
|
7049
7138
|
const firstArg = args[0];
|
|
7139
|
+
const evaluatePathFnConfig = {
|
|
7140
|
+
identifiers: {},
|
|
7141
|
+
memberExpressions: {},
|
|
7142
|
+
disableImports: true
|
|
7143
|
+
};
|
|
7144
|
+
state.applyStylexEnv(evaluatePathFnConfig.identifiers);
|
|
7050
7145
|
const {
|
|
7051
7146
|
confident,
|
|
7052
7147
|
value
|
|
7053
|
-
} = evaluate(firstArg, state);
|
|
7148
|
+
} = evaluate(firstArg, state, evaluatePathFnConfig);
|
|
7054
7149
|
if (!confident) {
|
|
7055
7150
|
throw callExpressionPath.buildCodeFrameError(messages.nonStaticValue('defineConsts'), SyntaxError);
|
|
7056
7151
|
}
|
|
@@ -7132,6 +7227,7 @@ function transformStyleXKeyframes(path, state) {
|
|
|
7132
7227
|
fn: firstThatWorks
|
|
7133
7228
|
};
|
|
7134
7229
|
});
|
|
7230
|
+
state.applyStylexEnv(identifiers);
|
|
7135
7231
|
const {
|
|
7136
7232
|
confident,
|
|
7137
7233
|
value
|
|
@@ -7203,6 +7299,7 @@ function transformStyleXPositionTry(path, state) {
|
|
|
7203
7299
|
fn: firstThatWorks
|
|
7204
7300
|
};
|
|
7205
7301
|
});
|
|
7302
|
+
state.applyStylexEnv(identifiers);
|
|
7206
7303
|
const {
|
|
7207
7304
|
confident,
|
|
7208
7305
|
value
|
|
@@ -7257,6 +7354,12 @@ function transformStyleXMerge(path, state) {
|
|
|
7257
7354
|
if (node == null || node.callee.type !== 'Identifier' || !state.stylexImport.has(node.callee.name)) {
|
|
7258
7355
|
return;
|
|
7259
7356
|
}
|
|
7357
|
+
const evaluatePathFnConfig = {
|
|
7358
|
+
identifiers: {},
|
|
7359
|
+
memberExpressions: {},
|
|
7360
|
+
disableImports: true
|
|
7361
|
+
};
|
|
7362
|
+
state.applyStylexEnv(evaluatePathFnConfig.identifiers);
|
|
7260
7363
|
let bailOut = false;
|
|
7261
7364
|
let conditional = 0;
|
|
7262
7365
|
let currentIndex = -1;
|
|
@@ -7363,7 +7466,7 @@ function transformStyleXMerge(path, state) {
|
|
|
7363
7466
|
const {
|
|
7364
7467
|
confident,
|
|
7365
7468
|
value: styleValue
|
|
7366
|
-
} = evaluate(path, state);
|
|
7469
|
+
} = evaluate(path, state, evaluatePathFnConfig);
|
|
7367
7470
|
if (!confident || styleValue == null) {
|
|
7368
7471
|
nonNullProps = true;
|
|
7369
7472
|
styleNonNullProps = true;
|
|
@@ -7499,6 +7602,7 @@ function transformStylexProps(path, state) {
|
|
|
7499
7602
|
}
|
|
7500
7603
|
};
|
|
7501
7604
|
});
|
|
7605
|
+
state.applyStylexEnv(identifiers);
|
|
7502
7606
|
const evaluatePathFnConfig = {
|
|
7503
7607
|
identifiers,
|
|
7504
7608
|
memberExpressions,
|
|
@@ -7824,6 +7928,7 @@ function transformStyleXViewTransitionClass(path, state) {
|
|
|
7824
7928
|
fn: keyframes$1
|
|
7825
7929
|
};
|
|
7826
7930
|
});
|
|
7931
|
+
state.applyStylexEnv(identifiers);
|
|
7827
7932
|
const {
|
|
7828
7933
|
confident,
|
|
7829
7934
|
value
|
|
@@ -47,6 +47,7 @@ export type StyleXOptions = $ReadOnly<{
|
|
|
47
47
|
classNamePrefix: string,
|
|
48
48
|
debug: ?boolean,
|
|
49
49
|
definedStylexCSSVariables?: { [key: string]: mixed },
|
|
50
|
+
env?: $ReadOnly<{ [string]: any }>,
|
|
50
51
|
dev: boolean,
|
|
51
52
|
propertyValidationMode?: 'throw' | 'warn' | 'silent',
|
|
52
53
|
enableDebugClassNames?: ?boolean,
|
package/lib/shared/messages.d.ts
CHANGED
|
@@ -35,8 +35,6 @@ export declare const ILLEGAL_PROP_ARRAY_VALUE: 'A style array value can only con
|
|
|
35
35
|
export declare type ILLEGAL_PROP_ARRAY_VALUE = typeof ILLEGAL_PROP_ARRAY_VALUE;
|
|
36
36
|
export declare const ILLEGAL_NAMESPACE_VALUE: 'A StyleX namespace must be an object.';
|
|
37
37
|
export declare type ILLEGAL_NAMESPACE_VALUE = typeof ILLEGAL_NAMESPACE_VALUE;
|
|
38
|
-
export declare const INVALID_CONST_KEY: 'Keys in defineConsts() cannot start with "--".';
|
|
39
|
-
export declare type INVALID_CONST_KEY = typeof INVALID_CONST_KEY;
|
|
40
38
|
export declare const INVALID_PSEUDO: 'Invalid pseudo selector, not on the whitelist.';
|
|
41
39
|
export declare type INVALID_PSEUDO = typeof INVALID_PSEUDO;
|
|
42
40
|
export declare const INVALID_PSEUDO_OR_AT_RULE: 'Invalid pseudo or at-rule.';
|
|
@@ -26,7 +26,6 @@ declare export const ILLEGAL_NESTED_PSEUDO: "Pseudo objects can't be nested more
|
|
|
26
26
|
declare export const ILLEGAL_PROP_VALUE: 'A style value can only contain an array, string or number.';
|
|
27
27
|
declare export const ILLEGAL_PROP_ARRAY_VALUE: 'A style array value can only contain strings or numbers.';
|
|
28
28
|
declare export const ILLEGAL_NAMESPACE_VALUE: 'A StyleX namespace must be an object.';
|
|
29
|
-
declare export const INVALID_CONST_KEY: 'Keys in defineConsts() cannot start with "--".';
|
|
30
29
|
declare export const INVALID_PSEUDO: 'Invalid pseudo selector, not on the whitelist.';
|
|
31
30
|
declare export const INVALID_PSEUDO_OR_AT_RULE: 'Invalid pseudo or at-rule.';
|
|
32
31
|
declare export const INVALID_MEDIA_QUERY_SYNTAX: 'Invalid media query syntax.';
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import type { StyleXOptions } from '../common-types';
|
|
11
|
+
type WhenSelector = `:${string}` | `[${string}`;
|
|
11
12
|
/**
|
|
12
13
|
* Creates selector that observes if the given pseudo-class is
|
|
13
14
|
* active on an ancestor with the "defaultMarker"
|
|
@@ -17,7 +18,7 @@ import type { StyleXOptions } from '../common-types';
|
|
|
17
18
|
* @returns A :where() clause for the ancestor observer
|
|
18
19
|
*/
|
|
19
20
|
export declare function ancestor(
|
|
20
|
-
pseudo:
|
|
21
|
+
pseudo: WhenSelector,
|
|
21
22
|
options?: string | StyleXOptions,
|
|
22
23
|
): string;
|
|
23
24
|
/**
|
|
@@ -28,7 +29,7 @@ export declare function ancestor(
|
|
|
28
29
|
* @returns A :has() clause for the descendant observer
|
|
29
30
|
*/
|
|
30
31
|
export declare function descendant(
|
|
31
|
-
pseudo:
|
|
32
|
+
pseudo: WhenSelector,
|
|
32
33
|
options?: string | StyleXOptions,
|
|
33
34
|
): string;
|
|
34
35
|
/**
|
|
@@ -39,7 +40,7 @@ export declare function descendant(
|
|
|
39
40
|
* @returns A :where() clause for the previous sibling observer
|
|
40
41
|
*/
|
|
41
42
|
export declare function siblingBefore(
|
|
42
|
-
pseudo:
|
|
43
|
+
pseudo: WhenSelector,
|
|
43
44
|
options?: string | StyleXOptions,
|
|
44
45
|
): string;
|
|
45
46
|
/**
|
|
@@ -50,7 +51,7 @@ export declare function siblingBefore(
|
|
|
50
51
|
* @returns A :has() clause for the next sibling observer
|
|
51
52
|
*/
|
|
52
53
|
export declare function siblingAfter(
|
|
53
|
-
pseudo:
|
|
54
|
+
pseudo: WhenSelector,
|
|
54
55
|
options?: string | StyleXOptions,
|
|
55
56
|
): string;
|
|
56
57
|
/**
|
|
@@ -61,6 +62,6 @@ export declare function siblingAfter(
|
|
|
61
62
|
* @returns A :where() clause for the any sibling observer
|
|
62
63
|
*/
|
|
63
64
|
export declare function anySibling(
|
|
64
|
-
pseudo:
|
|
65
|
+
pseudo: WhenSelector,
|
|
65
66
|
options?: string | StyleXOptions,
|
|
66
67
|
): string;
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
|
|
10
10
|
import type { StyleXOptions } from '../common-types';
|
|
11
11
|
|
|
12
|
+
type WhenSelector = StringPrefix<':'> | StringPrefix<'['>;
|
|
13
|
+
|
|
12
14
|
/**
|
|
13
15
|
* Creates selector that observes if the given pseudo-class is
|
|
14
16
|
* active on an ancestor with the "defaultMarker"
|
|
@@ -18,7 +20,7 @@ import type { StyleXOptions } from '../common-types';
|
|
|
18
20
|
* @returns A :where() clause for the ancestor observer
|
|
19
21
|
*/
|
|
20
22
|
declare export function ancestor(
|
|
21
|
-
pseudo:
|
|
23
|
+
pseudo: WhenSelector,
|
|
22
24
|
options?: string | StyleXOptions,
|
|
23
25
|
): string;
|
|
24
26
|
|
|
@@ -30,7 +32,7 @@ declare export function ancestor(
|
|
|
30
32
|
* @returns A :has() clause for the descendant observer
|
|
31
33
|
*/
|
|
32
34
|
declare export function descendant(
|
|
33
|
-
pseudo:
|
|
35
|
+
pseudo: WhenSelector,
|
|
34
36
|
options?: string | StyleXOptions,
|
|
35
37
|
): string;
|
|
36
38
|
|
|
@@ -42,7 +44,7 @@ declare export function descendant(
|
|
|
42
44
|
* @returns A :where() clause for the previous sibling observer
|
|
43
45
|
*/
|
|
44
46
|
declare export function siblingBefore(
|
|
45
|
-
pseudo:
|
|
47
|
+
pseudo: WhenSelector,
|
|
46
48
|
options?: string | StyleXOptions,
|
|
47
49
|
): string;
|
|
48
50
|
|
|
@@ -54,7 +56,7 @@ declare export function siblingBefore(
|
|
|
54
56
|
* @returns A :has() clause for the next sibling observer
|
|
55
57
|
*/
|
|
56
58
|
declare export function siblingAfter(
|
|
57
|
-
pseudo:
|
|
59
|
+
pseudo: WhenSelector,
|
|
58
60
|
options?: string | StyleXOptions,
|
|
59
61
|
): string;
|
|
60
62
|
|
|
@@ -66,6 +68,6 @@ declare export function siblingAfter(
|
|
|
66
68
|
* @returns A :where() clause for the any sibling observer
|
|
67
69
|
*/
|
|
68
70
|
declare export function anySibling(
|
|
69
|
-
pseudo:
|
|
71
|
+
pseudo: WhenSelector,
|
|
70
72
|
options?: string | StyleXOptions,
|
|
71
73
|
): string;
|
|
@@ -13,6 +13,7 @@ import type {
|
|
|
13
13
|
CompiledNamespaces,
|
|
14
14
|
StyleXOptions as RuntimeOptions,
|
|
15
15
|
} from '../shared';
|
|
16
|
+
import type { FunctionConfig } from './evaluate-path';
|
|
16
17
|
import * as t from '@babel/types';
|
|
17
18
|
export type ImportPathResolution =
|
|
18
19
|
| false
|
|
@@ -104,6 +105,7 @@ type StyleXStateOptions = Readonly<
|
|
|
104
105
|
Omit<
|
|
105
106
|
StyleXOptions,
|
|
106
107
|
| keyof {
|
|
108
|
+
env: Readonly<{ [$$Key$$: string]: any }>;
|
|
107
109
|
runtimeInjection:
|
|
108
110
|
| (null | undefined | string)
|
|
109
111
|
| Readonly<{ from: string; as: null | undefined | string }>;
|
|
@@ -114,6 +116,7 @@ type StyleXStateOptions = Readonly<
|
|
|
114
116
|
rewriteAliases: boolean;
|
|
115
117
|
}
|
|
116
118
|
> & {
|
|
119
|
+
env: Readonly<{ [$$Key$$: string]: any }>;
|
|
117
120
|
runtimeInjection:
|
|
118
121
|
| (null | undefined | string)
|
|
119
122
|
| Readonly<{ from: string; as: null | undefined | string }>;
|
|
@@ -143,6 +146,7 @@ declare class StateManager {
|
|
|
143
146
|
readonly stylexViewTransitionClassImport: Set<string>;
|
|
144
147
|
readonly stylexDefaultMarkerImport: Set<string>;
|
|
145
148
|
readonly stylexWhenImport: Set<string>;
|
|
149
|
+
readonly stylexEnvImport: Set<string>;
|
|
146
150
|
injectImportInserted: null | undefined | t.Identifier;
|
|
147
151
|
readonly styleMap: Map<string, CompiledNamespaces>;
|
|
148
152
|
readonly styleVars: Map<string, NodePath>;
|
|
@@ -156,6 +160,7 @@ declare class StateManager {
|
|
|
156
160
|
get importPathString(): string;
|
|
157
161
|
get importSources(): ReadonlyArray<string>;
|
|
158
162
|
importAs(source: string): null | string;
|
|
163
|
+
applyStylexEnv(identifiers: FunctionConfig['identifiers']): void;
|
|
159
164
|
get canReferenceTheme(): boolean;
|
|
160
165
|
get metadata(): { [key: string]: any };
|
|
161
166
|
get runtimeInjection():
|
|
@@ -13,6 +13,8 @@ import type {
|
|
|
13
13
|
CompiledNamespaces,
|
|
14
14
|
StyleXOptions as RuntimeOptions,
|
|
15
15
|
} from '../shared';
|
|
16
|
+
import type { FunctionConfig } from './evaluate-path';
|
|
17
|
+
|
|
16
18
|
import * as t from '@babel/types';
|
|
17
19
|
export type ImportPathResolution =
|
|
18
20
|
| false
|
|
@@ -70,6 +72,7 @@ export type StyleXOptions = $ReadOnly<{
|
|
|
70
72
|
|
|
71
73
|
type StyleXStateOptions = $ReadOnly<{
|
|
72
74
|
...StyleXOptions,
|
|
75
|
+
env: $ReadOnly<{ [string]: any }>,
|
|
73
76
|
runtimeInjection: ?string | $ReadOnly<{ from: string, as: ?string }>,
|
|
74
77
|
aliases?: ?$ReadOnly<{ [string]: $ReadOnlyArray<string> }>,
|
|
75
78
|
rewriteAliases: boolean,
|
|
@@ -96,6 +99,7 @@ declare export default class StateManager {
|
|
|
96
99
|
+stylexViewTransitionClassImport: Set<string>;
|
|
97
100
|
+stylexDefaultMarkerImport: Set<string>;
|
|
98
101
|
+stylexWhenImport: Set<string>;
|
|
102
|
+
+stylexEnvImport: Set<string>;
|
|
99
103
|
injectImportInserted: ?t.Identifier;
|
|
100
104
|
// `stylex.create` calls
|
|
101
105
|
+styleMap: Map<string, CompiledNamespaces>;
|
|
@@ -109,6 +113,7 @@ declare export default class StateManager {
|
|
|
109
113
|
get importPathString(): string;
|
|
110
114
|
get importSources(): $ReadOnlyArray<string>;
|
|
111
115
|
importAs(source: string): null | string;
|
|
116
|
+
applyStylexEnv(identifiers: FunctionConfig['identifiers']): void;
|
|
112
117
|
get canReferenceTheme(): boolean;
|
|
113
118
|
get metadata(): { [key: string]: any };
|
|
114
119
|
get runtimeInjection(): ?$ReadOnly<{ from: string, as?: ?string }>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { NodePath } from '@babel/traverse';
|
|
11
|
+
import * as t from '@babel/types';
|
|
12
|
+
import StateManager from '../utils/state-manager';
|
|
13
|
+
/**
|
|
14
|
+
* Transform inline-css call expressions like `css.color(value)`.
|
|
15
|
+
* These become arrow functions that return [compiledObj, inlineObj].
|
|
16
|
+
*/
|
|
17
|
+
export declare function transformInlineCSSCall(
|
|
18
|
+
path: NodePath<t.CallExpression>,
|
|
19
|
+
state: StateManager,
|
|
20
|
+
): void;
|
|
21
|
+
/**
|
|
22
|
+
* Transform inline-css member expressions like `css.display.flex`.
|
|
23
|
+
* These become compiled namespace objects: { [key]: className, $$css: true }
|
|
24
|
+
*/
|
|
25
|
+
export declare function transformInlineCSSMemberExpression(
|
|
26
|
+
path: NodePath<t.MemberExpression>,
|
|
27
|
+
state: StateManager,
|
|
28
|
+
): void;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @flow strict
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { NodePath } from '@babel/traverse';
|
|
11
|
+
|
|
12
|
+
import * as t from '@babel/types';
|
|
13
|
+
import StateManager from '../utils/state-manager';
|
|
14
|
+
/**
|
|
15
|
+
* Transform inline-css call expressions like `css.color(value)`.
|
|
16
|
+
* These become arrow functions that return [compiledObj, inlineObj].
|
|
17
|
+
*/
|
|
18
|
+
declare export function transformInlineCSSCall(
|
|
19
|
+
path: NodePath<t.CallExpression>,
|
|
20
|
+
state: StateManager,
|
|
21
|
+
): void;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Transform inline-css member expressions like `css.display.flex`.
|
|
25
|
+
* These become compiled namespace objects: { [key]: className, $$css: true }
|
|
26
|
+
*/
|
|
27
|
+
declare export function transformInlineCSSMemberExpression(
|
|
28
|
+
path: NodePath<t.MemberExpression>,
|
|
29
|
+
state: StateManager,
|
|
30
|
+
): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stylexjs/babel-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "StyleX babel plugin.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"browser": "lib/index.browser.js",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
"@babel/traverse": "^7.26.8",
|
|
24
24
|
"@babel/types": "^7.26.8",
|
|
25
25
|
"@dual-bundle/import-meta-resolve": "^4.1.0",
|
|
26
|
-
"@stylexjs/shared": "0.
|
|
27
|
-
"@stylexjs/stylex": "0.
|
|
26
|
+
"@stylexjs/shared": "0.18.0",
|
|
27
|
+
"@stylexjs/stylex": "0.18.0",
|
|
28
28
|
"postcss-value-parser": "^4.1.0"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"babel-plugin-syntax-hermes-parser": "^0.32.1",
|
|
38
38
|
"path-browserify": "^1.0.1",
|
|
39
39
|
"rollup": "^4.24.0",
|
|
40
|
-
"scripts": "0.
|
|
40
|
+
"scripts": "0.18.0"
|
|
41
41
|
},
|
|
42
42
|
"files": [
|
|
43
43
|
"flow_modules/*",
|