@stylexjs/babel-plugin 0.15.2 → 0.15.4

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.js CHANGED
@@ -829,6 +829,7 @@ class StateManager {
829
829
  const enableMediaQueryOrder = logAndDefault(boolean(), options.enableMediaQueryOrder ?? false, false, 'options.enableMediaQueryOrder');
830
830
  const enableLegacyValueFlipping = logAndDefault(boolean(), options.enableLegacyValueFlipping ?? false, false, 'options.enableLegacyValueFlipping');
831
831
  const enableLogicalStylesPolyfill = logAndDefault(boolean(), options.enableLogicalStylesPolyfill ?? false, false, 'options.enableLogicalStylesPolyfill');
832
+ const enableLTRRTLComments = logAndDefault(boolean(), options.enableLTRRTLComments ?? false, false, 'options.enableLTRRTLComments');
832
833
  const test = logAndDefault(boolean(), options.test ?? false, false, 'options.test');
833
834
  const configRuntimeInjection = logAndDefault(checkRuntimeInjection, options.runtimeInjection ?? false, false, 'options.runtimeInjection');
834
835
  const runtimeInjection = configRuntimeInjection === true ? DEFAULT_INJECT_PATH : configRuntimeInjection === false ? undefined : configRuntimeInjection;
@@ -860,6 +861,7 @@ class StateManager {
860
861
  enableMediaQueryOrder,
861
862
  enableLegacyValueFlipping,
862
863
  enableLogicalStylesPolyfill,
864
+ enableLTRRTLComments,
863
865
  importSources,
864
866
  rewriteAliases: typeof options.rewriteAliases === 'boolean' ? options.rewriteAliases : false,
865
867
  runtimeInjection,
@@ -978,32 +980,27 @@ class StateManager {
978
980
  if (sourceFilePath == null) {
979
981
  return false;
980
982
  }
983
+ const themeFileExtension = this.options.unstable_moduleResolution?.themeFileExtension ?? '.stylex';
984
+ const transformedVarsFileExtension = '.transformed';
985
+ const isValidStylexFile = matchesFileSuffix(themeFileExtension)(importPath);
986
+ const isValidTransformedVarsFile = matchesFileSuffix(transformedVarsFileExtension)(importPath);
987
+ if (!isValidStylexFile && !isValidTransformedVarsFile) {
988
+ return false;
989
+ }
981
990
  switch (this.options.unstable_moduleResolution?.type) {
982
991
  case 'commonJS':
983
992
  {
984
993
  const aliases = this.options.aliases;
985
- const themeFileExtension = this.options.unstable_moduleResolution?.themeFileExtension ?? '.stylex';
986
- if (!matchesFileSuffix(themeFileExtension)(importPath)) {
987
- return false;
988
- }
989
994
  const resolvedFilePath = filePathResolver(importPath, sourceFilePath, aliases);
990
995
  return resolvedFilePath ? ['themeNameRef', this.getCanonicalFilePath(resolvedFilePath)] : false;
991
996
  }
992
997
  case 'haste':
993
998
  {
994
- const themeFileExtension = this.options.unstable_moduleResolution.themeFileExtension ?? '.stylex';
995
- if (!matchesFileSuffix(themeFileExtension)(importPath)) {
996
- return false;
997
- }
998
999
  return ['themeNameRef', addFileExtension(importPath, sourceFilePath)];
999
1000
  }
1000
1001
  case 'experimental_crossFileParsing':
1001
1002
  {
1002
1003
  const aliases = this.options.aliases;
1003
- const themeFileExtension = this.options.unstable_moduleResolution.themeFileExtension ?? '.stylex';
1004
- if (!matchesFileSuffix(themeFileExtension)(importPath)) {
1005
- return false;
1006
- }
1007
1004
  const resolvedFilePath = filePathResolver(importPath, sourceFilePath, aliases);
1008
1005
  return resolvedFilePath ? ['filePath', resolvedFilePath] : false;
1009
1006
  }
@@ -1295,6 +1292,7 @@ const defaultOptions = {
1295
1292
  enableMediaQueryOrder: false,
1296
1293
  enableLegacyValueFlipping: false,
1297
1294
  enableLogicalStylesPolyfill: false,
1295
+ enableLTRRTLComments: false,
1298
1296
  enableMinifiedKeys: true,
1299
1297
  styleResolution: 'property-specificity',
1300
1298
  test: false
@@ -2070,8 +2068,9 @@ var parser = /*@__PURE__*/getDefaultExportFromCjs(libExports$1);
2070
2068
  function printNode(node) {
2071
2069
  switch (node.type) {
2072
2070
  case 'word':
2073
- case 'string':
2074
2071
  return `${node.value}`;
2072
+ case 'string':
2073
+ return `${node.quote}${node.value}${node.quote}`;
2075
2074
  case 'function':
2076
2075
  return `${node.value}(${node.nodes.map(printNode).join('')})`;
2077
2076
  default:
@@ -2093,6 +2092,9 @@ function splitValue(str) {
2093
2092
  return nodes;
2094
2093
  }
2095
2094
 
2095
+ const listStyleGlobalValues = new Set(['inherit', 'initial', 'revert', 'unset']);
2096
+ const listStylePositionValues = new Set(['inside', 'outside']);
2097
+ const listStyleTypeRegex = /^([a-z-]+|".*?"|'.*?')$/;
2096
2098
  const shorthands$1 = {
2097
2099
  border: rawValue => {
2098
2100
  return [['borderTop', rawValue], ['borderInlineEnd', rawValue], ['borderBottom', rawValue], ['borderInlineStart', rawValue]];
@@ -2156,6 +2158,49 @@ const shorthands$1 = {
2156
2158
  const [row, column = row] = splitValue(rawValue);
2157
2159
  return [['rowGap', row], ['columnGap', column]];
2158
2160
  },
2161
+ listStyle: rawValue => {
2162
+ if (rawValue == null) {
2163
+ return [['listStyleType', null], ['listStylePosition', null], ['listStyleImage', null]];
2164
+ }
2165
+ const parts = splitValue(rawValue);
2166
+ let image = null;
2167
+ let position = null;
2168
+ let type = null;
2169
+ if (parts.length === 1 && parts[0] != null && typeof parts[0] === 'string' && listStyleGlobalValues.has(parts[0])) {
2170
+ const globalValue = parts[0];
2171
+ return [['listStyleType', globalValue], ['listStylePosition', globalValue], ['listStyleImage', globalValue]];
2172
+ }
2173
+ const remainingParts = [];
2174
+ for (const part of parts) {
2175
+ if (part == null || typeof part !== 'string') continue;
2176
+ if (listStyleGlobalValues.has(part) || part.includes('var(--')) {
2177
+ throw new Error(`invalid "listStyle" value of "${JSON.stringify(rawValue)}"`);
2178
+ } else if (listStylePositionValues.has(part)) {
2179
+ if (position != null) {
2180
+ throw new Error(`invalid "listStyle" value of ${JSON.stringify(rawValue)}`);
2181
+ }
2182
+ position = part;
2183
+ } else if (part !== 'none' && listStyleTypeRegex.test(part)) {
2184
+ if (type != null) {
2185
+ throw new Error(`invalid "listStyle" value of ${JSON.stringify(rawValue)}`);
2186
+ }
2187
+ type = part;
2188
+ } else {
2189
+ remainingParts.push(part);
2190
+ }
2191
+ }
2192
+ for (const part of remainingParts) {
2193
+ if (part === 'none' && type == null) {
2194
+ type = part;
2195
+ } else {
2196
+ if (image != null) {
2197
+ throw new Error(`invalid "listStyle" value of ${JSON.stringify(rawValue)}`);
2198
+ }
2199
+ image = part;
2200
+ }
2201
+ }
2202
+ return [['listStyleType', type], ['listStylePosition', position], ['listStyleImage', image]];
2203
+ },
2159
2204
  margin: rawValue => {
2160
2205
  const [top, right = top, bottom = top, left = right] = splitValue(rawValue);
2161
2206
  return [['marginTop', top], ['marginInlineEnd', right], ['marginBottom', bottom], ['marginInlineStart', left]];
@@ -3971,6 +4016,8 @@ function requireMediaQuery () {
3971
4016
  width: [],
3972
4017
  height: []
3973
4018
  };
4019
+ const units = {};
4020
+ let hasAnyUnitConflicts = false;
3974
4021
  for (const rule of rules) {
3975
4022
  if (rule.type === 'not' && rule.rule.type === 'and') {
3976
4023
  const inner = rule.rule.rules;
@@ -3998,10 +4045,20 @@ function requireMediaQuery () {
3998
4045
  for (const dim of dimensions) {
3999
4046
  if (rule.type === 'pair' && (rule.key === `min-${dim}` || rule.key === `max-${dim}`) && isNumericLength(rule.value)) {
4000
4047
  const val = rule.value;
4048
+ if (intervals[dim].length === 0) {
4049
+ units[dim] = val.unit;
4050
+ } else if (units[dim] !== val.unit) {
4051
+ hasAnyUnitConflicts = true;
4052
+ }
4001
4053
  intervals[dim].push(rule.key === `min-${dim}` ? [val.value, Infinity] : [-Infinity, val.value]);
4002
4054
  break;
4003
4055
  } else if (rule.type === 'not' && rule.rule && rule.rule.type === 'pair' && (rule.rule.key === `min-${dim}` || rule.rule.key === `max-${dim}`) && isNumericLength(rule.rule.value)) {
4004
4056
  const val = rule.rule.value;
4057
+ if (intervals[dim].length === 0) {
4058
+ units[dim] = val.unit;
4059
+ } else if (units[dim] !== val.unit) {
4060
+ hasAnyUnitConflicts = true;
4061
+ }
4005
4062
  if (rule.rule.key === `min-${dim}`) {
4006
4063
  intervals[dim].push([-Infinity, val.value - epsilon]);
4007
4064
  } else {
@@ -4015,6 +4072,9 @@ function requireMediaQuery () {
4015
4072
  }
4016
4073
  }
4017
4074
  const result = [];
4075
+ if (hasAnyUnitConflicts) {
4076
+ return rules;
4077
+ }
4018
4078
  for (const dim of dimensions) {
4019
4079
  const dimIntervals = intervals[dim];
4020
4080
  if (dimIntervals.length === 0) continue;
@@ -4033,7 +4093,7 @@ function requireMediaQuery () {
4033
4093
  key: `min-${dim}`,
4034
4094
  value: {
4035
4095
  value: lower,
4036
- unit: 'px',
4096
+ unit: units[dim],
4037
4097
  type: 'integer'
4038
4098
  }
4039
4099
  });
@@ -4044,7 +4104,7 @@ function requireMediaQuery () {
4044
4104
  key: `max-${dim}`,
4045
4105
  value: {
4046
4106
  value: upper,
4047
- unit: 'px',
4107
+ unit: units[dim],
4048
4108
  type: 'integer'
4049
4109
  }
4050
4110
  });
@@ -7084,10 +7144,13 @@ function evaluatePartialObjectRecursively(path, traversalState, functions = {
7084
7144
  };
7085
7145
  }
7086
7146
  let key = keyResult.value;
7147
+ const valuePath = prop.get('value');
7087
7148
  if (key.startsWith('var(') && key.endsWith(')')) {
7088
- key = key.slice(4, -1);
7149
+ const inner = key.slice(4, -1);
7150
+ if (keyPath.length === 0) {
7151
+ key = inner;
7152
+ }
7089
7153
  }
7090
- const valuePath = prop.get('value');
7091
7154
  if (valuePath.isObjectExpression()) {
7092
7155
  const result = evaluatePartialObjectRecursively(valuePath, traversalState, functions, [...keyPath, key]);
7093
7156
  if (!result.confident) {
@@ -7340,15 +7403,17 @@ function transformStyleXCreate(path, state) {
7340
7403
  const classList = t__namespace.isStringLiteral(objProp.value) ? objProp.value.value.split(' ') : [];
7341
7404
  let isStatic = true;
7342
7405
  const exprList = [];
7343
- classList.forEach(cls => {
7406
+ classList.forEach((cls, index) => {
7344
7407
  const expr = dynamicStyles.find(({
7345
7408
  path
7346
7409
  }) => origClassPaths[cls] === path)?.expression;
7410
+ const isLast = index === classList.length - 1;
7411
+ const clsWithSpace = isLast ? cls : cls + ' ';
7347
7412
  if (expr && !isSafeToSkipNullCheck(expr)) {
7348
7413
  isStatic = false;
7349
- exprList.push(t__namespace.conditionalExpression(t__namespace.binaryExpression('!=', expr, t__namespace.nullLiteral()), t__namespace.stringLiteral(cls), expr));
7414
+ exprList.push(t__namespace.conditionalExpression(t__namespace.binaryExpression('!=', expr, t__namespace.nullLiteral()), t__namespace.stringLiteral(clsWithSpace), expr));
7350
7415
  } else {
7351
- exprList.push(t__namespace.stringLiteral(cls));
7416
+ exprList.push(t__namespace.stringLiteral(clsWithSpace));
7352
7417
  }
7353
7418
  });
7354
7419
  const joined = exprList.length === 0 ? t__namespace.stringLiteral('') : exprList.reduce((acc, curr) => t__namespace.binaryExpression('+', acc, curr));
@@ -8238,6 +8303,29 @@ function transformStylexProps(path, state) {
8238
8303
  } else {
8239
8304
  path.skip();
8240
8305
  const stringExpression = makeStringExpression(resolvedArgs);
8306
+ if (path.parentPath.node.type === 'JSXSpreadAttribute') {
8307
+ if (t__namespace.isObjectExpression(stringExpression) && stringExpression.properties.length > 0 && stringExpression.properties.every(prop => t__namespace.isObjectProperty(prop) && (t__namespace.isIdentifier(prop.key) || t__namespace.isStringLiteral(prop.key)) && !prop.computed)) {
8308
+ const jsxAttributes = stringExpression.properties.filter(prop => t__namespace.isObjectProperty(prop)).map(prop => {
8309
+ const objectProp = prop;
8310
+ const key = objectProp.key;
8311
+ let attrName = '';
8312
+ if (t__namespace.isIdentifier(key)) {
8313
+ attrName = key.name;
8314
+ } else if (t__namespace.isStringLiteral(key)) {
8315
+ attrName = key.value;
8316
+ }
8317
+ let attributeValue;
8318
+ if (t__namespace.isStringLiteral(objectProp.value)) {
8319
+ attributeValue = objectProp.value;
8320
+ } else {
8321
+ attributeValue = t__namespace.stringLiteral(String(objectProp.value));
8322
+ }
8323
+ return t__namespace.jsxAttribute(t__namespace.jsxIdentifier(attrName), attributeValue);
8324
+ });
8325
+ path.parentPath.replaceWithMultiple(jsxAttributes);
8326
+ return;
8327
+ }
8328
+ }
8241
8329
  path.replaceWith(stringExpression);
8242
8330
  }
8243
8331
  }
@@ -8633,7 +8721,13 @@ function isExported(path) {
8633
8721
  }
8634
8722
  return isExported(path.parentPath);
8635
8723
  }
8636
- function processStylexRules(rules, useLayers = false) {
8724
+ function processStylexRules(rules, config) {
8725
+ const {
8726
+ useLayers = false,
8727
+ enableLTRRTLComments = false
8728
+ } = typeof config === 'boolean' ? {
8729
+ useLayers: config
8730
+ } : config ?? {};
8637
8731
  if (rules.length === 0) {
8638
8732
  return '';
8639
8733
  }
@@ -8724,7 +8818,11 @@ function processStylexRules(rules, useLayers = false) {
8724
8818
  ltrRule = addSpecificityLevel(ltrRule, index);
8725
8819
  rtlRule = rtlRule && addSpecificityLevel(rtlRule, index);
8726
8820
  }
8727
- return rtlRule ? [addAncestorSelector(ltrRule, "html:not([dir='rtl'])"), addAncestorSelector(rtlRule, "html[dir='rtl']")] : [ltrRule];
8821
+ ltrRule = ltrRule.replace(/\.([a-zA-Z0-9]+), \.([a-zA-Z0-9]+):root/g, '.$1.$1, .$1.$1:root');
8822
+ if (rtlRule) {
8823
+ rtlRule = rtlRule.replace(/\.([a-zA-Z0-9]+), \.([a-zA-Z0-9]+):root/g, '.$1.$1, .$1.$1:root');
8824
+ }
8825
+ return rtlRule ? enableLTRRTLComments ? [`/* @ltr begin */${ltrRule}/* @ltr end */`, `/* @rtl begin */${rtlRule}/* @rtl end */`] : [addAncestorSelector(ltrRule, "html:not([dir='rtl'])"), addAncestorSelector(rtlRule, "html[dir='rtl']")] : [ltrRule];
8728
8826
  }).join('\n');
8729
8827
  return useLayers && pri > 0 ? `@layer priority${index + 1}{\n${collectedCSS}\n}` : collectedCSS;
8730
8828
  }).join('\n');
package/lib/index.js.flow CHANGED
@@ -47,7 +47,13 @@ export type Rule = [
47
47
  ];
48
48
  declare function processStylexRules(
49
49
  rules: Array<Rule>,
50
- useLayers: boolean,
50
+ config?:
51
+ | boolean
52
+ | {
53
+ useLayers?: boolean,
54
+ enableLTRRTLComments?: boolean,
55
+ ...
56
+ },
51
57
  ): string;
52
58
 
53
59
  export type StyleXTransformObj = $ReadOnly<{
@@ -49,6 +49,7 @@ export type StyleXOptions = Readonly<{
49
49
  enableMediaQueryOrder?: null | undefined | boolean;
50
50
  enableLegacyValueFlipping?: null | undefined | boolean;
51
51
  enableLogicalStylesPolyfill?: null | undefined | boolean;
52
+ enableLTRRTLComments?: null | undefined | boolean;
52
53
  enableMinifiedKeys?: null | undefined | boolean;
53
54
  styleResolution:
54
55
  | 'application-order'
@@ -55,6 +55,7 @@ export type StyleXOptions = $ReadOnly<{
55
55
  enableMediaQueryOrder?: ?boolean,
56
56
  enableLegacyValueFlipping?: ?boolean,
57
57
  enableLogicalStylesPolyfill?: ?boolean,
58
+ enableLTRRTLComments?: ?boolean,
58
59
  enableMinifiedKeys?: ?boolean,
59
60
  styleResolution:
60
61
  | 'application-order' // The last style applied wins.
@@ -44,6 +44,7 @@ export type StyleXOptions = Readonly<
44
44
  enableMediaQueryOrder?: boolean;
45
45
  enableLegacyValueFlipping?: boolean;
46
46
  enableLogicalStylesPolyfill?: boolean;
47
+ enableLTRRTLComments?: boolean;
47
48
  enableMinifiedKeys?: boolean;
48
49
  importSources: ReadonlyArray<
49
50
  string | Readonly<{ from: string; as: string }>
@@ -68,6 +69,7 @@ export type StyleXOptions = Readonly<
68
69
  enableMediaQueryOrder?: boolean;
69
70
  enableLegacyValueFlipping?: boolean;
70
71
  enableLogicalStylesPolyfill?: boolean;
72
+ enableLTRRTLComments?: boolean;
71
73
  enableMinifiedKeys?: boolean;
72
74
  importSources: ReadonlyArray<
73
75
  string | Readonly<{ from: string; as: string }>
@@ -44,6 +44,7 @@ export type StyleXOptions = $ReadOnly<{
44
44
  enableMediaQueryOrder?: boolean,
45
45
  enableLegacyValueFlipping?: boolean,
46
46
  enableLogicalStylesPolyfill?: boolean,
47
+ enableLTRRTLComments?: boolean,
47
48
  enableMinifiedKeys?: boolean,
48
49
  importSources: $ReadOnlyArray<
49
50
  string | $ReadOnly<{ from: string, as: string }>,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stylexjs/babel-plugin",
3
- "version": "0.15.2",
3
+ "version": "0.15.4",
4
4
  "description": "StyleX babel plugin.",
5
5
  "main": "lib/index.js",
6
6
  "repository": {
@@ -21,7 +21,7 @@
21
21
  "@babel/traverse": "^7.26.8",
22
22
  "@babel/types": "^7.26.8",
23
23
  "@dual-bundle/import-meta-resolve": "^4.1.0",
24
- "@stylexjs/stylex": "0.15.2",
24
+ "@stylexjs/stylex": "0.15.4",
25
25
  "postcss-value-parser": "^4.1.0"
26
26
  },
27
27
  "devDependencies": {
@@ -33,7 +33,7 @@
33
33
  "@rollup/plugin-replace": "^6.0.1",
34
34
  "babel-plugin-syntax-hermes-parser": "^0.26.0",
35
35
  "rollup": "^4.24.0",
36
- "scripts": "0.15.2"
36
+ "scripts": "0.15.4"
37
37
  },
38
38
  "files": [
39
39
  "flow_modules/*",