@stylexjs/babel-plugin 0.18.0 → 0.18.2

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.
@@ -1,6 +1,6 @@
1
1
  import { packages } from '@babel/standalone';
2
2
  import parser from 'postcss-value-parser';
3
- import { legacyMerge, props } from '@stylexjs/stylex';
3
+ import { legacyMerge, attrs, props } from '@stylexjs/stylex';
4
4
 
5
5
  const {
6
6
  arrayExpression, arrowFunctionExpression, binaryExpression, booleanLiteral,
@@ -12,7 +12,7 @@ const {
12
12
  isNumericLiteral, isObjectExpression, isObjectProperty, isPrivateName,
13
13
  isSpreadElement, isStringLiteral, isTemplateLiteral, isUnaryExpression,
14
14
  isUpdateExpression, isValidIdentifier, isVariableDeclaration, jsxAttribute,
15
- jsxIdentifier, memberExpression, nullLiteral, numericLiteral, objectExpression,
15
+ jsxIdentifier, jsxSpreadAttribute, memberExpression, nullLiteral, numericLiteral, objectExpression,
16
16
  objectProperty, stringLiteral, unaryExpression, variableDeclaration, variableDeclarator
17
17
  } = packages.types;
18
18
 
@@ -55,6 +55,7 @@ var types = /*#__PURE__*/Object.freeze({
55
55
  isVariableDeclaration: isVariableDeclaration,
56
56
  jsxAttribute: jsxAttribute,
57
57
  jsxIdentifier: jsxIdentifier,
58
+ jsxSpreadAttribute: jsxSpreadAttribute,
58
59
  memberExpression: memberExpression,
59
60
  nullLiteral: nullLiteral,
60
61
  numericLiteral: numericLiteral,
@@ -1533,6 +1534,7 @@ class StateManager {
1533
1534
  const enableLegacyValueFlipping = logAndDefault(boolean(), options.enableLegacyValueFlipping ?? defaultOptions.enableLegacyValueFlipping, false, 'options.enableLegacyValueFlipping');
1534
1535
  const enableLogicalStylesPolyfill = logAndDefault(boolean(), options.enableLogicalStylesPolyfill ?? defaultOptions.enableLogicalStylesPolyfill, false, 'options.enableLogicalStylesPolyfill');
1535
1536
  const enableLTRRTLComments = logAndDefault(boolean(), options.enableLTRRTLComments ?? defaultOptions.enableLTRRTLComments, false, 'options.enableLTRRTLComments');
1537
+ const sxPropName = logAndDefault(unionOf(string(), literal(false)), options.sxPropName ?? 'sx', 'sx', 'options.sxPropName');
1536
1538
  const test = logAndDefault(boolean(), options.test ?? defaultOptions.test, false, 'options.test');
1537
1539
  const configRuntimeInjection = logAndDefault(checkRuntimeInjection, options.runtimeInjection ?? false, false, 'options.runtimeInjection');
1538
1540
  const runtimeInjection = configRuntimeInjection === true ? DEFAULT_INJECT_PATH : configRuntimeInjection === false ? undefined : configRuntimeInjection;
@@ -1573,6 +1575,7 @@ class StateManager {
1573
1575
  enableLegacyValueFlipping,
1574
1576
  enableLogicalStylesPolyfill,
1575
1577
  enableLTRRTLComments,
1578
+ sxPropName,
1576
1579
  importSources,
1577
1580
  rewriteAliases: typeof options.rewriteAliases === 'boolean' ? options.rewriteAliases : false,
1578
1581
  runtimeInjection,
@@ -1911,6 +1914,9 @@ function readImportDeclarations(path, state) {
1911
1914
  if (importedName === 'props') {
1912
1915
  state.stylexPropsImport.add(localName);
1913
1916
  }
1917
+ if (importedName === 'attrs') {
1918
+ state.stylexAttrsImport.add(localName);
1919
+ }
1914
1920
  if (importedName === 'keyframes') {
1915
1921
  state.stylexKeyframesImport.add(localName);
1916
1922
  }
@@ -1980,6 +1986,9 @@ function readRequires(path, state) {
1980
1986
  if (prop.key.name === 'props') {
1981
1987
  state.stylexPropsImport.add(value.name);
1982
1988
  }
1989
+ if (prop.key.name === 'attrs') {
1990
+ state.stylexAttrsImport.add(value.name);
1991
+ }
1983
1992
  if (prop.key.name === 'keyframes') {
1984
1993
  state.stylexKeyframesImport.add(value.name);
1985
1994
  }
@@ -8694,15 +8703,17 @@ class ConditionalStyle {
8694
8703
  }
8695
8704
  }
8696
8705
  function skipStylexPropsChildren(path, state) {
8697
- if (!isCalleeIdentifier(path, state) && !isCalleeMemberExpression(path, state)) {
8706
+ if (getPropsLikeCall(path, state) == null) {
8698
8707
  return;
8699
8708
  }
8700
8709
  path.skip();
8701
8710
  }
8702
8711
  function transformStylexProps(path, state) {
8703
- if (!isCalleeIdentifier(path, state) && !isCalleeMemberExpression(path, state)) {
8712
+ const propsLikeCall = getPropsLikeCall(path, state);
8713
+ if (propsLikeCall == null) {
8704
8714
  return;
8705
8715
  }
8716
+ const propsLikeFn = propsLikeCall === 'attrs' ? attrs : props;
8706
8717
  let bailOut = false;
8707
8718
  let conditional = 0;
8708
8719
  const argsPath = path.get('arguments').flatMap(argPath => argPath.isArrayExpression() ? argPath.get('elements') : [argPath]);
@@ -8842,7 +8853,7 @@ function transformStylexProps(path, state) {
8842
8853
  }
8843
8854
  } else {
8844
8855
  path.skip();
8845
- const stringExpression = makeStringExpression(resolvedArgs);
8856
+ const stringExpression = makeStringExpression(resolvedArgs, propsLikeFn);
8846
8857
  if (path.parentPath.node.type === 'JSXSpreadAttribute') {
8847
8858
  if (isObjectExpression(stringExpression) && stringExpression.properties.length > 0 && stringExpression.properties.every(prop => isObjectProperty(prop) && (isIdentifier(prop.key) || isStringLiteral(prop.key)) && !prop.computed)) {
8848
8859
  const jsxAttributes = stringExpression.properties.filter(prop => isObjectProperty(prop)).map(prop => {
@@ -8906,10 +8917,10 @@ function parseNullableStyle(path, state, evaluatePathFnConfig) {
8906
8917
  }
8907
8918
  return 'other';
8908
8919
  }
8909
- function makeStringExpression(values) {
8920
+ function makeStringExpression(values, propsLikeFn) {
8910
8921
  const conditions = values.filter(v => v instanceof ConditionalStyle).map(v => v.test);
8911
8922
  if (conditions.length === 0) {
8912
- const result = props(values);
8923
+ const result = propsLikeFn(values);
8913
8924
  return convertObjectToAST(result);
8914
8925
  }
8915
8926
  const conditionPermutations = genConditionPermutations(conditions.length);
@@ -8927,7 +8938,7 @@ function makeStringExpression(values) {
8927
8938
  }
8928
8939
  });
8929
8940
  const key = permutation.reduce((soFar, bool) => soFar << 1 | (bool ? 1 : 0), 0);
8930
- return objectProperty(numericLiteral(key), convertObjectToAST(props(args)));
8941
+ return objectProperty(numericLiteral(key), convertObjectToAST(propsLikeFn(args)));
8931
8942
  });
8932
8943
  const objExpressions = objectExpression(objEntries);
8933
8944
  const conditionsToKey = genBitwiseOrOfConditions(conditions);
@@ -8953,17 +8964,26 @@ function genBitwiseOrOfConditions(conditions) {
8953
8964
  return binaryExpression('|', acc, expr);
8954
8965
  });
8955
8966
  }
8956
- function isCalleeIdentifier(path, state) {
8967
+ function getPropsLikeCall(path, state) {
8957
8968
  const {
8958
8969
  node
8959
8970
  } = path;
8960
- return node != null && node.callee != null && node.callee.type === 'Identifier' && state.stylexPropsImport.has(node.callee.name);
8961
- }
8962
- function isCalleeMemberExpression(path, state) {
8963
- const {
8964
- node
8965
- } = path;
8966
- return node != null && node.callee != null && node.callee.type === 'MemberExpression' && node.callee.object.type === 'Identifier' && node.callee.property.type === 'Identifier' && node.callee.property.name === 'props' && state.stylexImport.has(node.callee.object.name);
8971
+ const callee = node?.callee;
8972
+ if (node != null && callee != null && callee.type === 'Identifier' && state.stylexPropsImport.has(callee.name)) {
8973
+ return 'props';
8974
+ }
8975
+ if (node != null && callee != null && callee.type === 'Identifier' && state.stylexAttrsImport.has(callee.name)) {
8976
+ return 'attrs';
8977
+ }
8978
+ if (node != null && callee != null && callee.type === 'MemberExpression' && callee.object.type === 'Identifier' && callee.property.type === 'Identifier' && state.stylexImport.has(callee.object.name)) {
8979
+ if (callee.property.name === 'props') {
8980
+ return 'props';
8981
+ }
8982
+ if (callee.property.name === 'attrs') {
8983
+ return 'attrs';
8984
+ }
8985
+ }
8986
+ return null;
8967
8987
  }
8968
8988
 
8969
8989
  function styleXViewTransitionClass(styles, options = defaultOptions) {
@@ -9308,6 +9328,31 @@ function styleXTransform() {
9308
9328
  });
9309
9329
  }
9310
9330
  },
9331
+ JSXOpeningElement(path) {
9332
+ const sxPropName = state.options.sxPropName;
9333
+ if (sxPropName === false) {
9334
+ return;
9335
+ }
9336
+ const node = path.node;
9337
+ if (node.name.type !== 'JSXIdentifier' || typeof node.name.name !== 'string' || node.name.name[0] !== node.name.name[0].toLowerCase()) {
9338
+ return;
9339
+ }
9340
+ for (const attr of path.get('attributes')) {
9341
+ if (!attr.isJSXAttribute() || !attr.get('name').isJSXIdentifier() || attr.get('name').node.name !== sxPropName) {
9342
+ continue;
9343
+ }
9344
+ const valuePath = attr.get('value');
9345
+ if (!valuePath.isJSXExpressionContainer()) {
9346
+ continue;
9347
+ }
9348
+ const value = valuePath.get('expression');
9349
+ if (value.isJSXEmptyExpression()) {
9350
+ continue;
9351
+ }
9352
+ attr.replaceWith(jsxSpreadAttribute(callExpression(memberExpression(identifier('stylex'), identifier('props')), [value.node])));
9353
+ break;
9354
+ }
9355
+ },
9311
9356
  CallExpression(path) {
9312
9357
  const parentPath = path.parentPath;
9313
9358
  if (parentPath.isVariableDeclarator()) {
@@ -9358,14 +9403,19 @@ function getLogicalFloatVars(rules) {
9358
9403
  ` : '';
9359
9404
  }
9360
9405
  function processStylexRules(rules, config) {
9406
+ const rawConfig = typeof config === 'boolean' ? {
9407
+ useLayers: config
9408
+ } : config ?? {};
9361
9409
  const {
9362
- useLayers = false,
9363
9410
  enableLTRRTLComments = false,
9364
9411
  legacyDisableLayers = false,
9365
9412
  useLegacyClassnamesSort = false
9366
- } = typeof config === 'boolean' ? {
9367
- useLayers: config
9368
- } : config ?? {};
9413
+ } = rawConfig;
9414
+ const rawUseLayers = rawConfig.useLayers ?? false;
9415
+ const useLayers = rawUseLayers !== false;
9416
+ const layersBefore = typeof rawUseLayers === 'object' ? rawUseLayers.before ?? [] : [];
9417
+ const layersAfter = typeof rawUseLayers === 'object' ? rawUseLayers.after ?? [] : [];
9418
+ const layerPrefix = typeof rawUseLayers === 'object' ? rawUseLayers.prefix ?? '' : '';
9369
9419
  if (rules.length === 0) {
9370
9420
  return '';
9371
9421
  }
@@ -9412,16 +9462,11 @@ function processStylexRules(rules, config) {
9412
9462
  if (useLegacyClassnamesSort) {
9413
9463
  return classname1.localeCompare(classname2);
9414
9464
  } else {
9415
- if (rule1.startsWith('@') && !rule2.startsWith('@')) {
9416
- const query1 = rule1.slice(0, rule1.indexOf('{'));
9417
- const query2 = rule2.slice(0, rule2.indexOf('{'));
9418
- if (query1 !== query2) {
9419
- return query1.localeCompare(query2);
9420
- }
9421
- }
9422
9465
  const property1 = rule1.slice(rule1.lastIndexOf('{'));
9423
9466
  const property2 = rule2.slice(rule2.lastIndexOf('{'));
9424
- return property1.localeCompare(property2);
9467
+ const propertyComparison = property1.localeCompare(property2);
9468
+ if (propertyComparison !== 0) return propertyComparison;
9469
+ return rule1.localeCompare(rule2);
9425
9470
  }
9426
9471
  });
9427
9472
  let lastKPri = -1;
@@ -9455,7 +9500,8 @@ function processStylexRules(rules, config) {
9455
9500
  return acc;
9456
9501
  }, []);
9457
9502
  const logicalFloatVars = getLogicalFloatVars(nonConstantRules);
9458
- const header = useLayers ? '\n@layer ' + grouped.map((_, index) => `priority${index + 1}`).join(', ') + ';\n' : '';
9503
+ const layerName = index => layerPrefix ? `${layerPrefix}.priority${index + 1}` : `priority${index + 1}`;
9504
+ const header = useLayers ? '\n@layer ' + [...layersBefore, ...grouped.map((_, index) => layerName(index)), ...layersAfter].join(', ') + ';\n' : '';
9459
9505
  const collectedCSS = grouped.map((group, index) => {
9460
9506
  const pri = group[0][2];
9461
9507
  const collectedCSS = Array.from(new Map(group.map(([a, b]) => [a, b])).values()).flatMap(rule => {
@@ -9475,7 +9521,7 @@ function processStylexRules(rules, config) {
9475
9521
  }
9476
9522
  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];
9477
9523
  }).join('\n');
9478
- return useLayers && pri > 0 ? `@layer priority${index + 1}{\n${collectedCSS}\n}` : collectedCSS;
9524
+ return useLayers && pri > 0 ? `@layer ${layerName(index)}{\n${collectedCSS}\n}` : collectedCSS;
9479
9525
  }).join('\n');
9480
9526
  return logicalFloatVars + header + collectedCSS;
9481
9527
  }
package/lib/index.d.ts CHANGED
@@ -44,7 +44,13 @@ declare function processStylexRules(
44
44
  config?:
45
45
  | boolean
46
46
  | {
47
- useLayers?: boolean;
47
+ useLayers?:
48
+ | boolean
49
+ | {
50
+ before?: ReadonlyArray<string>;
51
+ after?: ReadonlyArray<string>;
52
+ prefix?: string;
53
+ };
48
54
  enableLTRRTLComments?: boolean;
49
55
  legacyDisableLayers?: boolean;
50
56
  },
package/lib/index.js CHANGED
@@ -419,6 +419,7 @@ class StateManager {
419
419
  const enableLegacyValueFlipping = logAndDefault(boolean(), options.enableLegacyValueFlipping ?? defaultOptions.enableLegacyValueFlipping, false, 'options.enableLegacyValueFlipping');
420
420
  const enableLogicalStylesPolyfill = logAndDefault(boolean(), options.enableLogicalStylesPolyfill ?? defaultOptions.enableLogicalStylesPolyfill, false, 'options.enableLogicalStylesPolyfill');
421
421
  const enableLTRRTLComments = logAndDefault(boolean(), options.enableLTRRTLComments ?? defaultOptions.enableLTRRTLComments, false, 'options.enableLTRRTLComments');
422
+ const sxPropName = logAndDefault(unionOf(string(), literal(false)), options.sxPropName ?? 'sx', 'sx', 'options.sxPropName');
422
423
  const test = logAndDefault(boolean(), options.test ?? defaultOptions.test, false, 'options.test');
423
424
  const configRuntimeInjection = logAndDefault(checkRuntimeInjection, options.runtimeInjection ?? false, false, 'options.runtimeInjection');
424
425
  const runtimeInjection = configRuntimeInjection === true ? DEFAULT_INJECT_PATH : configRuntimeInjection === false ? undefined : configRuntimeInjection;
@@ -459,6 +460,7 @@ class StateManager {
459
460
  enableLegacyValueFlipping,
460
461
  enableLogicalStylesPolyfill,
461
462
  enableLTRRTLComments,
463
+ sxPropName,
462
464
  importSources,
463
465
  rewriteAliases: typeof options.rewriteAliases === 'boolean' ? options.rewriteAliases : false,
464
466
  runtimeInjection,
@@ -797,6 +799,9 @@ function readImportDeclarations(path, state) {
797
799
  if (importedName === 'props') {
798
800
  state.stylexPropsImport.add(localName);
799
801
  }
802
+ if (importedName === 'attrs') {
803
+ state.stylexAttrsImport.add(localName);
804
+ }
800
805
  if (importedName === 'keyframes') {
801
806
  state.stylexKeyframesImport.add(localName);
802
807
  }
@@ -866,6 +871,9 @@ function readRequires(path, state) {
866
871
  if (prop.key.name === 'props') {
867
872
  state.stylexPropsImport.add(value.name);
868
873
  }
874
+ if (prop.key.name === 'attrs') {
875
+ state.stylexAttrsImport.add(value.name);
876
+ }
869
877
  if (prop.key.name === 'keyframes') {
870
878
  state.stylexKeyframesImport.add(value.name);
871
879
  }
@@ -7576,15 +7584,17 @@ class ConditionalStyle {
7576
7584
  }
7577
7585
  }
7578
7586
  function skipStylexPropsChildren(path, state) {
7579
- if (!isCalleeIdentifier(path, state) && !isCalleeMemberExpression(path, state)) {
7587
+ if (getPropsLikeCall(path, state) == null) {
7580
7588
  return;
7581
7589
  }
7582
7590
  path.skip();
7583
7591
  }
7584
7592
  function transformStylexProps(path, state) {
7585
- if (!isCalleeIdentifier(path, state) && !isCalleeMemberExpression(path, state)) {
7593
+ const propsLikeCall = getPropsLikeCall(path, state);
7594
+ if (propsLikeCall == null) {
7586
7595
  return;
7587
7596
  }
7597
+ const propsLikeFn = propsLikeCall === 'attrs' ? stylex.attrs : stylex.props;
7588
7598
  let bailOut = false;
7589
7599
  let conditional = 0;
7590
7600
  const argsPath = path.get('arguments').flatMap(argPath => argPath.isArrayExpression() ? argPath.get('elements') : [argPath]);
@@ -7724,7 +7734,7 @@ function transformStylexProps(path, state) {
7724
7734
  }
7725
7735
  } else {
7726
7736
  path.skip();
7727
- const stringExpression = makeStringExpression(resolvedArgs);
7737
+ const stringExpression = makeStringExpression(resolvedArgs, propsLikeFn);
7728
7738
  if (path.parentPath.node.type === 'JSXSpreadAttribute') {
7729
7739
  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)) {
7730
7740
  const jsxAttributes = stringExpression.properties.filter(prop => t__namespace.isObjectProperty(prop)).map(prop => {
@@ -7788,10 +7798,10 @@ function parseNullableStyle(path, state, evaluatePathFnConfig) {
7788
7798
  }
7789
7799
  return 'other';
7790
7800
  }
7791
- function makeStringExpression(values) {
7801
+ function makeStringExpression(values, propsLikeFn) {
7792
7802
  const conditions = values.filter(v => v instanceof ConditionalStyle).map(v => v.test);
7793
7803
  if (conditions.length === 0) {
7794
- const result = stylex.props(values);
7804
+ const result = propsLikeFn(values);
7795
7805
  return convertObjectToAST(result);
7796
7806
  }
7797
7807
  const conditionPermutations = genConditionPermutations(conditions.length);
@@ -7809,7 +7819,7 @@ function makeStringExpression(values) {
7809
7819
  }
7810
7820
  });
7811
7821
  const key = permutation.reduce((soFar, bool) => soFar << 1 | (bool ? 1 : 0), 0);
7812
- return t__namespace.objectProperty(t__namespace.numericLiteral(key), convertObjectToAST(stylex.props(args)));
7822
+ return t__namespace.objectProperty(t__namespace.numericLiteral(key), convertObjectToAST(propsLikeFn(args)));
7813
7823
  });
7814
7824
  const objExpressions = t__namespace.objectExpression(objEntries);
7815
7825
  const conditionsToKey = genBitwiseOrOfConditions(conditions);
@@ -7835,17 +7845,26 @@ function genBitwiseOrOfConditions(conditions) {
7835
7845
  return t__namespace.binaryExpression('|', acc, expr);
7836
7846
  });
7837
7847
  }
7838
- function isCalleeIdentifier(path, state) {
7848
+ function getPropsLikeCall(path, state) {
7839
7849
  const {
7840
7850
  node
7841
7851
  } = path;
7842
- return node != null && node.callee != null && node.callee.type === 'Identifier' && state.stylexPropsImport.has(node.callee.name);
7843
- }
7844
- function isCalleeMemberExpression(path, state) {
7845
- const {
7846
- node
7847
- } = path;
7848
- return node != null && node.callee != null && node.callee.type === 'MemberExpression' && node.callee.object.type === 'Identifier' && node.callee.property.type === 'Identifier' && node.callee.property.name === 'props' && state.stylexImport.has(node.callee.object.name);
7852
+ const callee = node?.callee;
7853
+ if (node != null && callee != null && callee.type === 'Identifier' && state.stylexPropsImport.has(callee.name)) {
7854
+ return 'props';
7855
+ }
7856
+ if (node != null && callee != null && callee.type === 'Identifier' && state.stylexAttrsImport.has(callee.name)) {
7857
+ return 'attrs';
7858
+ }
7859
+ if (node != null && callee != null && callee.type === 'MemberExpression' && callee.object.type === 'Identifier' && callee.property.type === 'Identifier' && state.stylexImport.has(callee.object.name)) {
7860
+ if (callee.property.name === 'props') {
7861
+ return 'props';
7862
+ }
7863
+ if (callee.property.name === 'attrs') {
7864
+ return 'attrs';
7865
+ }
7866
+ }
7867
+ return null;
7849
7868
  }
7850
7869
 
7851
7870
  function styleXViewTransitionClass(styles, options = defaultOptions) {
@@ -8190,6 +8209,31 @@ function styleXTransform() {
8190
8209
  });
8191
8210
  }
8192
8211
  },
8212
+ JSXOpeningElement(path) {
8213
+ const sxPropName = state.options.sxPropName;
8214
+ if (sxPropName === false) {
8215
+ return;
8216
+ }
8217
+ const node = path.node;
8218
+ if (node.name.type !== 'JSXIdentifier' || typeof node.name.name !== 'string' || node.name.name[0] !== node.name.name[0].toLowerCase()) {
8219
+ return;
8220
+ }
8221
+ for (const attr of path.get('attributes')) {
8222
+ if (!attr.isJSXAttribute() || !attr.get('name').isJSXIdentifier() || attr.get('name').node.name !== sxPropName) {
8223
+ continue;
8224
+ }
8225
+ const valuePath = attr.get('value');
8226
+ if (!valuePath.isJSXExpressionContainer()) {
8227
+ continue;
8228
+ }
8229
+ const value = valuePath.get('expression');
8230
+ if (value.isJSXEmptyExpression()) {
8231
+ continue;
8232
+ }
8233
+ attr.replaceWith(t__namespace.jsxSpreadAttribute(t__namespace.callExpression(t__namespace.memberExpression(t__namespace.identifier('stylex'), t__namespace.identifier('props')), [value.node])));
8234
+ break;
8235
+ }
8236
+ },
8193
8237
  CallExpression(path) {
8194
8238
  const parentPath = path.parentPath;
8195
8239
  if (parentPath.isVariableDeclarator()) {
@@ -8240,14 +8284,19 @@ function getLogicalFloatVars(rules) {
8240
8284
  ` : '';
8241
8285
  }
8242
8286
  function processStylexRules(rules, config) {
8287
+ const rawConfig = typeof config === 'boolean' ? {
8288
+ useLayers: config
8289
+ } : config ?? {};
8243
8290
  const {
8244
- useLayers = false,
8245
8291
  enableLTRRTLComments = false,
8246
8292
  legacyDisableLayers = false,
8247
8293
  useLegacyClassnamesSort = false
8248
- } = typeof config === 'boolean' ? {
8249
- useLayers: config
8250
- } : config ?? {};
8294
+ } = rawConfig;
8295
+ const rawUseLayers = rawConfig.useLayers ?? false;
8296
+ const useLayers = rawUseLayers !== false;
8297
+ const layersBefore = typeof rawUseLayers === 'object' ? rawUseLayers.before ?? [] : [];
8298
+ const layersAfter = typeof rawUseLayers === 'object' ? rawUseLayers.after ?? [] : [];
8299
+ const layerPrefix = typeof rawUseLayers === 'object' ? rawUseLayers.prefix ?? '' : '';
8251
8300
  if (rules.length === 0) {
8252
8301
  return '';
8253
8302
  }
@@ -8294,16 +8343,11 @@ function processStylexRules(rules, config) {
8294
8343
  if (useLegacyClassnamesSort) {
8295
8344
  return classname1.localeCompare(classname2);
8296
8345
  } else {
8297
- if (rule1.startsWith('@') && !rule2.startsWith('@')) {
8298
- const query1 = rule1.slice(0, rule1.indexOf('{'));
8299
- const query2 = rule2.slice(0, rule2.indexOf('{'));
8300
- if (query1 !== query2) {
8301
- return query1.localeCompare(query2);
8302
- }
8303
- }
8304
8346
  const property1 = rule1.slice(rule1.lastIndexOf('{'));
8305
8347
  const property2 = rule2.slice(rule2.lastIndexOf('{'));
8306
- return property1.localeCompare(property2);
8348
+ const propertyComparison = property1.localeCompare(property2);
8349
+ if (propertyComparison !== 0) return propertyComparison;
8350
+ return rule1.localeCompare(rule2);
8307
8351
  }
8308
8352
  });
8309
8353
  let lastKPri = -1;
@@ -8337,7 +8381,8 @@ function processStylexRules(rules, config) {
8337
8381
  return acc;
8338
8382
  }, []);
8339
8383
  const logicalFloatVars = getLogicalFloatVars(nonConstantRules);
8340
- const header = useLayers ? '\n@layer ' + grouped.map((_, index) => `priority${index + 1}`).join(', ') + ';\n' : '';
8384
+ const layerName = index => layerPrefix ? `${layerPrefix}.priority${index + 1}` : `priority${index + 1}`;
8385
+ const header = useLayers ? '\n@layer ' + [...layersBefore, ...grouped.map((_, index) => layerName(index)), ...layersAfter].join(', ') + ';\n' : '';
8341
8386
  const collectedCSS = grouped.map((group, index) => {
8342
8387
  const pri = group[0][2];
8343
8388
  const collectedCSS = Array.from(new Map(group.map(([a, b]) => [a, b])).values()).flatMap(rule => {
@@ -8357,7 +8402,7 @@ function processStylexRules(rules, config) {
8357
8402
  }
8358
8403
  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];
8359
8404
  }).join('\n');
8360
- return useLayers && pri > 0 ? `@layer priority${index + 1}{\n${collectedCSS}\n}` : collectedCSS;
8405
+ return useLayers && pri > 0 ? `@layer ${layerName(index)}{\n${collectedCSS}\n}` : collectedCSS;
8361
8406
  }).join('\n');
8362
8407
  return logicalFloatVars + header + collectedCSS;
8363
8408
  }
package/lib/index.js.flow CHANGED
@@ -51,7 +51,13 @@ declare function processStylexRules(
51
51
  config?:
52
52
  | boolean
53
53
  | {
54
- useLayers?: boolean,
54
+ useLayers?:
55
+ | boolean
56
+ | $ReadOnly<{
57
+ before?: $ReadOnlyArray<string>,
58
+ after?: $ReadOnlyArray<string>,
59
+ prefix?: string,
60
+ }>,
55
61
  enableLTRRTLComments?: boolean,
56
62
  legacyDisableLayers?: boolean,
57
63
  useLegacyClassnamesSort?: boolean,
@@ -61,6 +61,7 @@ export type StyleXOptions = Readonly<
61
61
  enableLogicalStylesPolyfill?: boolean;
62
62
  enableLTRRTLComments?: boolean;
63
63
  enableMinifiedKeys?: boolean;
64
+ sxPropName?: string | false;
64
65
  importSources: ReadonlyArray<
65
66
  string | Readonly<{ from: string; as: string }>
66
67
  >;
@@ -88,6 +89,7 @@ export type StyleXOptions = Readonly<
88
89
  enableLogicalStylesPolyfill?: boolean;
89
90
  enableLTRRTLComments?: boolean;
90
91
  enableMinifiedKeys?: boolean;
92
+ sxPropName?: string | false;
91
93
  importSources: ReadonlyArray<
92
94
  string | Readonly<{ from: string; as: string }>
93
95
  >;
@@ -59,6 +59,7 @@ export type StyleXOptions = $ReadOnly<{
59
59
  enableLogicalStylesPolyfill?: boolean,
60
60
  enableLTRRTLComments?: boolean,
61
61
  enableMinifiedKeys?: boolean,
62
+ sxPropName?: string | false,
62
63
  importSources: $ReadOnlyArray<
63
64
  string | $ReadOnly<{ from: string, as: string }>,
64
65
  >,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stylexjs/babel-plugin",
3
- "version": "0.18.0",
3
+ "version": "0.18.2",
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.18.0",
27
- "@stylexjs/stylex": "0.18.0",
26
+ "@stylexjs/shared": "0.18.2",
27
+ "@stylexjs/stylex": "0.18.2",
28
28
  "postcss-value-parser": "^4.1.0"
29
29
  },
30
30
  "devDependencies": {
@@ -36,8 +36,8 @@
36
36
  "@rollup/plugin-replace": "^6.0.1",
37
37
  "babel-plugin-syntax-hermes-parser": "^0.32.1",
38
38
  "path-browserify": "^1.0.1",
39
- "rollup": "^4.24.0",
40
- "scripts": "0.18.0"
39
+ "rollup": "^4.59.0",
40
+ "scripts": "0.18.2"
41
41
  },
42
42
  "files": [
43
43
  "flow_modules/*",