@csszyx/compiler 0.9.5 → 0.9.6

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/dist/index.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const core = require('@csszyx/core');
4
- const transformCore = require('./shared/compiler.BfDLUvcf.cjs');
4
+ const transformCore = require('./shared/compiler.BsKlgPl4.cjs');
5
5
  const oxcParser = require('oxc-parser');
6
6
  const t = require('@babel/types');
7
7
  const node_crypto = require('node:crypto');
@@ -605,6 +605,11 @@ function transformSourceCode(source, filename, options) {
605
605
  const szCall = t__namespace.callExpression(t__namespace.identifier("_sz"), [
606
606
  expression
607
607
  ]);
608
+ collectCandidatesFromBabelExpr(
609
+ expression,
610
+ path,
611
+ collectedClasses
612
+ );
608
613
  path.node.value = createMergedClassNameValue(szCall);
609
614
  usesRuntime = true;
610
615
  transformed = true;
@@ -1219,6 +1224,145 @@ function collectFromExpr(node, classes) {
1219
1224
  collectFromExpr(node.alternate, classes);
1220
1225
  }
1221
1226
  }
1227
+ function collectCandidatesFromBabelExpr(node, path, classes) {
1228
+ if (t__namespace.isTSAsExpression(node) || t__namespace.isTSSatisfiesExpression(node) || t__namespace.isTSNonNullExpression(node) || t__namespace.isTSInstantiationExpression(node)) {
1229
+ collectCandidatesFromBabelExpr(node.expression, path, classes);
1230
+ } else if (t__namespace.isArrayExpression(node)) {
1231
+ for (const element of node.elements) {
1232
+ if (element === null || t__namespace.isSpreadElement(element)) {
1233
+ continue;
1234
+ }
1235
+ const cand = t__namespace.isLogicalExpression(element) && element.operator === "&&" ? element.right : element;
1236
+ collectCandidatesFromBabelExpr(cand, path, classes);
1237
+ }
1238
+ } else if (t__namespace.isObjectExpression(node)) {
1239
+ collectCandidatesFromBabelObj(node, path, classes, "");
1240
+ } else if (t__namespace.isIdentifier(node)) {
1241
+ const binding = path.scope.getBinding(node.name);
1242
+ if (binding?.path.isVariableDeclarator()) {
1243
+ let init = binding.path.node.init;
1244
+ if (init) {
1245
+ while (t__namespace.isTSAsExpression(init) || t__namespace.isTSSatisfiesExpression(init)) {
1246
+ init = init.expression;
1247
+ }
1248
+ collectCandidatesFromBabelExpr(init, path, classes);
1249
+ }
1250
+ }
1251
+ } else if (t__namespace.isConditionalExpression(node)) {
1252
+ collectCandidatesFromBabelExpr(node.consequent, path, classes);
1253
+ collectCandidatesFromBabelExpr(node.alternate, path, classes);
1254
+ } else if (t__namespace.isLogicalExpression(node) && node.operator === "&&") {
1255
+ collectCandidatesFromBabelExpr(node.right, path, classes);
1256
+ }
1257
+ }
1258
+ function collectCandidatesFromBabelObj(node, path, classes, variantPrefix) {
1259
+ const getBinding = (name) => path.scope.getBinding(name);
1260
+ for (const prop of node.properties) {
1261
+ if (t__namespace.isSpreadElement(prop)) {
1262
+ const spreadArg = prop.argument;
1263
+ if (t__namespace.isIdentifier(spreadArg)) {
1264
+ const binding = getBinding(spreadArg.name);
1265
+ if (binding?.path.isVariableDeclarator()) {
1266
+ let init = binding.path.node.init;
1267
+ if (init) {
1268
+ while (t__namespace.isTSAsExpression(init) || t__namespace.isTSSatisfiesExpression(init)) {
1269
+ init = init.expression;
1270
+ }
1271
+ if (t__namespace.isObjectExpression(init)) {
1272
+ collectCandidatesFromBabelObj(init, path, classes, variantPrefix);
1273
+ continue;
1274
+ }
1275
+ }
1276
+ }
1277
+ }
1278
+ collectCandidatesFromBabelExpr(spreadArg, path, classes);
1279
+ } else if (t__namespace.isObjectProperty(prop)) {
1280
+ let key;
1281
+ if (t__namespace.isIdentifier(prop.key)) {
1282
+ key = prop.key.name;
1283
+ } else if (t__namespace.isStringLiteral(prop.key)) {
1284
+ key = prop.key.value;
1285
+ } else if (t__namespace.isNumericLiteral(prop.key)) {
1286
+ key = String(prop.key.value);
1287
+ } else {
1288
+ continue;
1289
+ }
1290
+ const val = prop.value;
1291
+ if (t__namespace.isObjectExpression(val)) {
1292
+ if (isKnownBabelVariant(key)) {
1293
+ const nestedVariant = variantPrefix ? `${variantPrefix}:${key}` : key;
1294
+ collectCandidatesFromBabelObj(val, path, classes, nestedVariant);
1295
+ } else {
1296
+ const flatVal = resolveObjectSpreads(val, getBinding) ?? val;
1297
+ const staticObj = evaluateStaticObject(flatVal);
1298
+ if (staticObj !== null) {
1299
+ const { className } = transformCore.transform({ [key]: staticObj });
1300
+ const prefixed = variantPrefix ? prefixClasses(className, variantPrefix) : className;
1301
+ for (const c of prefixed.split(/\s+/)) {
1302
+ if (c) classes.add(c);
1303
+ }
1304
+ } else {
1305
+ collectCandidatesFromBabelExpr(val, path, classes);
1306
+ }
1307
+ }
1308
+ } else if (t__namespace.isConditionalExpression(val)) {
1309
+ const consequent = val.consequent;
1310
+ const alternate = val.alternate;
1311
+ const staticCons = t__namespace.isStringLiteral(consequent) || t__namespace.isNumericLiteral(consequent) || t__namespace.isBooleanLiteral(consequent) || t__namespace.isObjectExpression(consequent) ? evaluateStaticObject(
1312
+ t__namespace.objectExpression([t__namespace.objectProperty(t__namespace.identifier(key), consequent)])
1313
+ ) : null;
1314
+ if (staticCons !== null) {
1315
+ const { className } = transformCore.transform(staticCons);
1316
+ const prefixed = variantPrefix ? prefixClasses(className, variantPrefix) : className;
1317
+ for (const c of prefixed.split(/\s+/)) {
1318
+ if (c) classes.add(c);
1319
+ }
1320
+ } else {
1321
+ collectCandidatesFromBabelExpr(consequent, path, classes);
1322
+ }
1323
+ const staticAlt = t__namespace.isStringLiteral(alternate) || t__namespace.isNumericLiteral(alternate) || t__namespace.isBooleanLiteral(alternate) || t__namespace.isObjectExpression(alternate) ? evaluateStaticObject(
1324
+ t__namespace.objectExpression([t__namespace.objectProperty(t__namespace.identifier(key), alternate)])
1325
+ ) : null;
1326
+ if (staticAlt !== null) {
1327
+ const { className } = transformCore.transform(staticAlt);
1328
+ const prefixed = variantPrefix ? prefixClasses(className, variantPrefix) : className;
1329
+ for (const c of prefixed.split(/\s+/)) {
1330
+ if (c) classes.add(c);
1331
+ }
1332
+ } else {
1333
+ collectCandidatesFromBabelExpr(alternate, path, classes);
1334
+ }
1335
+ } else {
1336
+ const staticVal = t__namespace.isStringLiteral(val) || t__namespace.isNumericLiteral(val) || t__namespace.isBooleanLiteral(val) ? evaluateStaticObject(
1337
+ t__namespace.objectExpression([t__namespace.objectProperty(t__namespace.identifier(key), val)])
1338
+ ) : null;
1339
+ if (staticVal !== null) {
1340
+ const { className } = transformCore.transform(staticVal);
1341
+ const prefixed = variantPrefix ? (
1342
+ /**
1343
+ *
1344
+ * @param classesStr
1345
+ * @param variantChain
1346
+ */
1347
+ prefixClasses(className, variantPrefix)
1348
+ ) : className;
1349
+ for (const c of prefixed.split(/\s+/)) {
1350
+ if (c) classes.add(c);
1351
+ }
1352
+ } else {
1353
+ collectCandidatesFromBabelExpr(val, path, classes);
1354
+ }
1355
+ }
1356
+ }
1357
+ }
1358
+ }
1359
+ function prefixClasses(classesStr, variantChain) {
1360
+ const variantPrefix = transformCore.getVariantPrefix(variantChain);
1361
+ return classesStr.split(/\s+/).map((c) => c ? `${variantPrefix}:${c}` : "").join(" ");
1362
+ }
1363
+ function isKnownBabelVariant(key) {
1364
+ return transformCore.KNOWN_VARIANTS.has(key) || transformCore.KNOWN_VARIANTS.has(transformCore.getVariantPrefix(key));
1365
+ }
1222
1366
  function buildCSSVarClassName$1(info) {
1223
1367
  const { twPrefix, varName, variantChain } = info;
1224
1368
  const variantPrefix = variantChain ? `${transformCore.getVariantPrefix(variantChain)}:` : "";
@@ -2142,6 +2286,12 @@ function transformOxc(source, filename, options) {
2142
2286
  objectBindings,
2143
2287
  classes
2144
2288
  );
2289
+ collectSzvCallClasses(
2290
+ node,
2291
+ effectiveFilename,
2292
+ objectBindings,
2293
+ classes
2294
+ );
2145
2295
  return;
2146
2296
  }
2147
2297
  if (node.type !== "JSXOpeningElement") {
@@ -2336,6 +2486,33 @@ function transformOxc(source, filename, options) {
2336
2486
  }
2337
2487
  }
2338
2488
  if (expression.type === "ArrayExpression") {
2489
+ const arrayMergeExpression = buildArrayMergeExpression(
2490
+ expression,
2491
+ effectiveFilename,
2492
+ objectBindings,
2493
+ globalVarAliases,
2494
+ cssVariableMap,
2495
+ source,
2496
+ classes
2497
+ );
2498
+ if (arrayMergeExpression) {
2499
+ const existingExpression = classNameAttr ? classNameMergeArgument(classNameAttr, source) : null;
2500
+ const mergeExpression = existingExpression ? `_szMerge(${existingExpression}, ${arrayMergeExpression})` : `_szMerge(${arrayMergeExpression})`;
2501
+ if (classNameAttr) {
2502
+ edits.overwrite(
2503
+ classNameAttr.start,
2504
+ classNameAttr.end,
2505
+ `className={${mergeExpression}}`
2506
+ );
2507
+ edits.remove(whitespaceStart(source, szAttr.start), szAttr.end);
2508
+ } else {
2509
+ edits.overwrite(szAttr.start, szAttr.end, `className={${mergeExpression}}`);
2510
+ }
2511
+ usesRuntime = true;
2512
+ usesMerge = true;
2513
+ transformed = true;
2514
+ return;
2515
+ }
2339
2516
  const arrayClasses = astArrayToStaticClasses(
2340
2517
  expression,
2341
2518
  effectiveFilename,
@@ -2348,7 +2525,8 @@ function transformOxc(source, filename, options) {
2348
2525
  expression,
2349
2526
  effectiveFilename,
2350
2527
  objectBindings,
2351
- classes
2528
+ classes,
2529
+ ""
2352
2530
  );
2353
2531
  runtimeFallbackExpr = expression;
2354
2532
  runtimeFallbackAttr = szAttr;
@@ -2408,7 +2586,7 @@ function transformOxc(source, filename, options) {
2408
2586
  reservedCSSVariableNames,
2409
2587
  globalVarAliases
2410
2588
  );
2411
- if (partial && szAttrs.length === 1) {
2589
+ if (partial && szAttrs.length === 1 && !(partial.hasConditional && classNameAttr)) {
2412
2590
  const mergedStyleProps = hoistedStyleProps.length > 0 ? [...hoistedStyleProps, ...partial.styleProps] : partial.styleProps;
2413
2591
  if (classNameAttr?.value?.type === "JSXExpressionContainer") {
2414
2592
  const classExpression = classNameAttr.value.expression;
@@ -2499,6 +2677,13 @@ function transformOxc(source, filename, options) {
2499
2677
  if (runtimeFallbackExpr.type !== "ArrayExpression") {
2500
2678
  diagnostics.push(buildRuntimeFallbackDiagnostic(runtimeFallbackExpr, source));
2501
2679
  }
2680
+ collectCandidateClassesFromExpression(
2681
+ runtimeFallbackExpr,
2682
+ effectiveFilename,
2683
+ objectBindings,
2684
+ classes,
2685
+ ""
2686
+ );
2502
2687
  edits.overwrite(
2503
2688
  runtimeFallbackAttr.start,
2504
2689
  runtimeFallbackAttr.end,
@@ -2696,32 +2881,278 @@ function astArrayToStaticClasses(node, filename, bindings, globalVarAliases, css
2696
2881
  }
2697
2882
  return out;
2698
2883
  }
2699
- function collectArrayCandidateClasses(node, filename, bindings, classes) {
2884
+ function buildArrayMergeExpression(node, filename, bindings, globalVarAliases, cssVariableMap, source, classes) {
2885
+ const parts = [];
2886
+ let hasConditional = false;
2887
+ for (const element of node.elements) {
2888
+ if (!element || isFalsyLiteral(element)) {
2889
+ continue;
2890
+ }
2891
+ const unwrapped = unwrapExpression(element);
2892
+ let condition = null;
2893
+ let candidate = unwrapped;
2894
+ if (unwrapped.type === "LogicalExpression" && unwrapped.operator === "&&") {
2895
+ const logical = unwrapped;
2896
+ condition = logical.left;
2897
+ candidate = unwrapExpression(logical.right);
2898
+ hasConditional = true;
2899
+ }
2900
+ const objectNode = resolveObjectExpression(candidate, bindings);
2901
+ if (!objectNode) {
2902
+ return null;
2903
+ }
2904
+ let result;
2905
+ try {
2906
+ result = transformCore.transform(
2907
+ applyGlobalVarAliasesToSzObject(
2908
+ astObjectToSzObject(objectNode, filename, bindings),
2909
+ globalVarAliases,
2910
+ cssVariableMap
2911
+ )
2912
+ );
2913
+ } catch (err) {
2914
+ if (err instanceof OxcNotImplementedError) {
2915
+ return null;
2916
+ }
2917
+ throw err;
2918
+ }
2919
+ for (const cls of result.className.split(/\s+/)) {
2920
+ if (cls) {
2921
+ classes.add(cls);
2922
+ }
2923
+ }
2924
+ const classLiteral = JSON.stringify(result.className);
2925
+ parts.push(
2926
+ condition ? `${source.slice(condition.start, condition.end)} && ${classLiteral}` : classLiteral
2927
+ );
2928
+ }
2929
+ return hasConditional ? parts.join(", ") : null;
2930
+ }
2931
+ function classNameMergeArgument(attribute, source) {
2932
+ const staticValue = stringLiteralValue(attribute.value);
2933
+ if (staticValue !== null) {
2934
+ return JSON.stringify(staticValue);
2935
+ }
2936
+ if (attribute.value?.type === "JSXExpressionContainer") {
2937
+ const expression = attribute.value.expression;
2938
+ return source.slice(expression.start, expression.end);
2939
+ }
2940
+ return '""';
2941
+ }
2942
+ function collectArrayCandidateClasses(node, filename, bindings, classes, variantPrefix) {
2700
2943
  for (const element of node.elements) {
2701
2944
  if (!element || isFalsyLiteral(element)) {
2702
2945
  continue;
2703
2946
  }
2704
2947
  const candidate = element.type === "LogicalExpression" && element.operator === "&&" ? element.right : element;
2705
- collectStaticObjectCandidateClasses(candidate, filename, bindings, classes);
2948
+ collectCandidateClassesFromExpression(
2949
+ candidate,
2950
+ filename,
2951
+ bindings,
2952
+ classes,
2953
+ variantPrefix
2954
+ );
2706
2955
  }
2707
2956
  }
2708
- function collectStaticObjectCandidateClasses(node, filename, bindings, classes) {
2709
- const objectNode = resolveObjectExpression(node, bindings);
2710
- if (!objectNode) {
2711
- return;
2957
+ function collectCandidateClassesFromExpression(node, filename, bindings, classes, variantPrefix) {
2958
+ const unwrapped = unwrapExpression(node);
2959
+ if (unwrapped.type === "ArrayExpression") {
2960
+ collectArrayCandidateClasses(
2961
+ unwrapped,
2962
+ filename,
2963
+ bindings,
2964
+ classes,
2965
+ variantPrefix
2966
+ );
2967
+ } else if (unwrapped.type === "ObjectExpression") {
2968
+ collectCandidateClassesFromObjectExpression(
2969
+ unwrapped,
2970
+ filename,
2971
+ bindings,
2972
+ classes,
2973
+ variantPrefix
2974
+ );
2975
+ } else if (unwrapped.type === "Identifier") {
2976
+ const bound = bindings.get(String(unwrapped.name));
2977
+ if (bound) {
2978
+ collectCandidateClassesFromExpression(
2979
+ bound,
2980
+ filename,
2981
+ bindings,
2982
+ classes,
2983
+ variantPrefix
2984
+ );
2985
+ }
2986
+ } else if (unwrapped.type === "ConditionalExpression") {
2987
+ const cond = unwrapped;
2988
+ collectCandidateClassesFromExpression(
2989
+ cond.consequent,
2990
+ filename,
2991
+ bindings,
2992
+ classes,
2993
+ variantPrefix
2994
+ );
2995
+ collectCandidateClassesFromExpression(
2996
+ cond.alternate,
2997
+ filename,
2998
+ bindings,
2999
+ classes,
3000
+ variantPrefix
3001
+ );
3002
+ } else if (unwrapped.type === "LogicalExpression" && unwrapped.operator === "&&") {
3003
+ const logical = unwrapped;
3004
+ collectCandidateClassesFromExpression(
3005
+ logical.right,
3006
+ filename,
3007
+ bindings,
3008
+ classes,
3009
+ variantPrefix
3010
+ );
2712
3011
  }
2713
- let result;
3012
+ }
3013
+ function collectCandidateClassesFromObjectExpression(node, filename, bindings, classes, variantPrefix) {
2714
3014
  try {
2715
- result = transformCore.transform(astObjectToSzObject(objectNode, filename, bindings));
3015
+ const compiled = transformCore.transform(astObjectToSzObject(node, filename, bindings));
3016
+ for (const cls of prefixVariantClasses(compiled.className, variantPrefix).split(/\s+/)) {
3017
+ if (cls) {
3018
+ classes.add(cls);
3019
+ }
3020
+ }
3021
+ return;
2716
3022
  } catch (err) {
2717
- if (err instanceof OxcNotImplementedError) {
2718
- return;
3023
+ if (!(err instanceof OxcNotImplementedError)) {
3024
+ throw err;
2719
3025
  }
2720
- throw err;
2721
3026
  }
2722
- for (const cls of result.className.split(/\s+/)) {
2723
- if (cls) {
2724
- classes.add(cls);
3027
+ for (const propRaw of node.properties) {
3028
+ if (propRaw.type === "SpreadElement") {
3029
+ const spread = propRaw;
3030
+ const spreadArg = unwrapExpression(spread.argument);
3031
+ if (spreadArg.type === "Identifier") {
3032
+ const bound = bindings.get(String(spreadArg.name));
3033
+ if (bound) {
3034
+ collectCandidateClassesFromObjectExpression(
3035
+ bound,
3036
+ filename,
3037
+ bindings,
3038
+ classes,
3039
+ variantPrefix
3040
+ );
3041
+ }
3042
+ } else {
3043
+ collectCandidateClassesFromExpression(
3044
+ spread.argument,
3045
+ filename,
3046
+ bindings,
3047
+ classes,
3048
+ variantPrefix
3049
+ );
3050
+ }
3051
+ } else if (propRaw.type === "Property") {
3052
+ const prop = propRaw;
3053
+ if (prop.computed) {
3054
+ continue;
3055
+ }
3056
+ const key = extractKeyName(prop.key);
3057
+ if (key === null) {
3058
+ continue;
3059
+ }
3060
+ const val = unwrapExpression(prop.value);
3061
+ if (val.type === "ObjectExpression") {
3062
+ if (isKnownVariant(key)) {
3063
+ const nestedVariant = variantPrefix ? `${variantPrefix}:${key}` : key;
3064
+ collectCandidateClassesFromObjectExpression(
3065
+ val,
3066
+ filename,
3067
+ bindings,
3068
+ classes,
3069
+ nestedVariant
3070
+ );
3071
+ } else {
3072
+ try {
3073
+ const propertyVal = astObjectToSzObject(
3074
+ val,
3075
+ filename,
3076
+ bindings
3077
+ );
3078
+ const singleObject = { [key]: propertyVal };
3079
+ const compiled = transformCore.transform(singleObject);
3080
+ for (const c of prefixVariantClasses(
3081
+ compiled.className,
3082
+ variantPrefix
3083
+ ).split(/\s+/)) {
3084
+ if (c) classes.add(c);
3085
+ }
3086
+ } catch {
3087
+ collectCandidateClassesFromExpression(
3088
+ val,
3089
+ filename,
3090
+ bindings,
3091
+ classes,
3092
+ variantPrefix
3093
+ );
3094
+ }
3095
+ }
3096
+ } else if (val.type === "ConditionalExpression") {
3097
+ const cond = val;
3098
+ try {
3099
+ const consequentVal = astValueToSzValue(cond.consequent, filename, bindings);
3100
+ const singleConsequent = { [key]: consequentVal };
3101
+ const compiledConsequent = transformCore.transform(singleConsequent);
3102
+ for (const c of prefixVariantClasses(
3103
+ compiledConsequent.className,
3104
+ variantPrefix
3105
+ ).split(/\s+/)) {
3106
+ if (c) classes.add(c);
3107
+ }
3108
+ } catch {
3109
+ collectCandidateClassesFromExpression(
3110
+ cond.consequent,
3111
+ filename,
3112
+ bindings,
3113
+ classes,
3114
+ variantPrefix
3115
+ );
3116
+ }
3117
+ try {
3118
+ const alternateVal = astValueToSzValue(cond.alternate, filename, bindings);
3119
+ const singleAlternate = { [key]: alternateVal };
3120
+ const compiledAlternate = transformCore.transform(singleAlternate);
3121
+ for (const c of prefixVariantClasses(
3122
+ compiledAlternate.className,
3123
+ variantPrefix
3124
+ ).split(/\s+/)) {
3125
+ if (c) classes.add(c);
3126
+ }
3127
+ } catch {
3128
+ collectCandidateClassesFromExpression(
3129
+ cond.alternate,
3130
+ filename,
3131
+ bindings,
3132
+ classes,
3133
+ variantPrefix
3134
+ );
3135
+ }
3136
+ } else {
3137
+ try {
3138
+ const propertyVal = astValueToSzValue(val, filename, bindings);
3139
+ const singleObject = { [key]: propertyVal };
3140
+ const compiled = transformCore.transform(singleObject);
3141
+ for (const c of prefixVariantClasses(compiled.className, variantPrefix).split(
3142
+ /\s+/
3143
+ )) {
3144
+ if (c) classes.add(c);
3145
+ }
3146
+ } catch {
3147
+ collectCandidateClassesFromExpression(
3148
+ val,
3149
+ filename,
3150
+ bindings,
3151
+ classes,
3152
+ variantPrefix
3153
+ );
3154
+ }
3155
+ }
2725
3156
  }
2726
3157
  }
2727
3158
  }
@@ -2768,6 +3199,53 @@ function collectDynamicCallClasses(node, filename, bindings, classes) {
2768
3199
  }
2769
3200
  }
2770
3201
  }
3202
+ function collectSzvCallClasses(node, filename, bindings, classes) {
3203
+ if (node.callee.type !== "Identifier" || node.callee.name !== "szv") {
3204
+ return;
3205
+ }
3206
+ const [firstArg] = node.arguments;
3207
+ if (!firstArg) {
3208
+ return;
3209
+ }
3210
+ const configNode = resolveObjectExpression(firstArg, bindings);
3211
+ if (!configNode) {
3212
+ return;
3213
+ }
3214
+ let config;
3215
+ try {
3216
+ config = astObjectToSzObject(configNode, filename, bindings);
3217
+ } catch (err) {
3218
+ if (err instanceof OxcNotImplementedError) {
3219
+ return;
3220
+ }
3221
+ throw err;
3222
+ }
3223
+ const base = isSzObject(config.base) ? config.base : {};
3224
+ addCompiledClasses(base, classes);
3225
+ const variants = isSzObject(config.variants) ? config.variants : {};
3226
+ for (const variantValues of Object.values(variants)) {
3227
+ if (!isSzObject(variantValues)) {
3228
+ continue;
3229
+ }
3230
+ for (const variantObject of Object.values(variantValues)) {
3231
+ if (!isSzObject(variantObject)) {
3232
+ continue;
3233
+ }
3234
+ addCompiledClasses({ ...base, ...variantObject }, classes);
3235
+ }
3236
+ }
3237
+ }
3238
+ function addCompiledClasses(object, classes) {
3239
+ const result = transformCore.transform(object);
3240
+ for (const cls of result.className.split(/\s+/)) {
3241
+ if (cls) {
3242
+ classes.add(cls);
3243
+ }
3244
+ }
3245
+ }
3246
+ function isSzObject(value) {
3247
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3248
+ }
2771
3249
  function resolveObjectExpression(node, bindings) {
2772
3250
  const unwrapped = unwrapExpression(node);
2773
3251
  if (unwrapped.type === "ObjectExpression") {
@@ -2863,7 +3341,7 @@ function buildPartialObjectTransform(node, filename, bindings, source, options,
2863
3341
  if (!partial || partial.dynamicProps.size === 0 && partial.conditionalClasses.length === 0) {
2864
3342
  return null;
2865
3343
  }
2866
- if (partial.conditionalClasses.length > 0 && (partial.conditionalClasses.length !== 1 || partial.dynamicProps.size > 0 || Object.keys(partial.staticProps).length > 0)) {
3344
+ if (partial.conditionalClasses.length > 0 && (partial.conditionalClasses.length !== 1 || partial.dynamicProps.size > 0)) {
2867
3345
  return null;
2868
3346
  }
2869
3347
  const classParts = [];
@@ -2890,7 +3368,13 @@ function buildPartialObjectTransform(node, filename, bindings, source, options,
2890
3368
  const styleProps = [...partial.dynamicProps.entries()].filter(([id]) => !hoistedNames?.has(id)).map(
2891
3369
  ([, info]) => `${JSON.stringify(info.varName)}: ${generateStyleValueSource(info, source)}`
2892
3370
  );
2893
- return { className, classNameAttr, styleProps, usesColorVar: partial.usesColorVar };
3371
+ return {
3372
+ className,
3373
+ classNameAttr,
3374
+ styleProps,
3375
+ usesColorVar: partial.usesColorVar,
3376
+ hasConditional: partial.conditionalClasses.length > 0
3377
+ };
2894
3378
  }
2895
3379
  function applyHoistedVariableNames(partial, hoistedNames, cssVariableMap) {
2896
3380
  if (!hoistedNames) {
@@ -3452,9 +3936,14 @@ function buildCSSVarClassName(info) {
3452
3936
  return `${variantPrefix}${info.twPrefix}-(${info.varName})`;
3453
3937
  }
3454
3938
  function buildConditionalClassSource(classParts, conditionals, source) {
3455
- if (conditionals.length === 1 && classParts.length === 2) {
3939
+ if (conditionals.length === 1) {
3456
3940
  const [entry] = conditionals;
3457
- return `${source.slice(entry.test.start, entry.test.end)} ? ${JSON.stringify(entry.consequent)} : ${JSON.stringify(entry.alternate)}`;
3941
+ const ternary = `${source.slice(entry.test.start, entry.test.end)} ? ${JSON.stringify(entry.consequent)} : ${JSON.stringify(entry.alternate)}`;
3942
+ const staticParts = classParts.slice(0, -2).filter(Boolean);
3943
+ if (staticParts.length === 0) {
3944
+ return ternary;
3945
+ }
3946
+ return `\`${staticParts.join(" ")} \${${ternary}}\``;
3458
3947
  }
3459
3948
  return JSON.stringify(classParts.filter(Boolean).join(" "));
3460
3949
  }
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { init, version, transform_sz, encode } from '@csszyx/core';
2
- import { t as transform, C as COLOR_PROPERTIES, P as PROPERTY_MAP, g as getCSSVariableName, a as PropertyCategory, K as KNOWN_VARIANTS, b as getVariantPrefix, c as getPropertyCategory, s as stripInvalidColorStrings } from './shared/compiler.wyFFQW-b.mjs';
3
- export { B as BOOLEAN_SHORTHANDS, d as PROPERTY_CATEGORY_MAP, S as SPECIAL_VARIANTS, e as SUGGESTION_MAP, i as isValidSzProp, n as normalizeClassName } from './shared/compiler.wyFFQW-b.mjs';
2
+ import { t as transform, C as COLOR_PROPERTIES, P as PROPERTY_MAP, g as getCSSVariableName, a as PropertyCategory, K as KNOWN_VARIANTS, b as getVariantPrefix, c as getPropertyCategory, s as stripInvalidColorStrings } from './shared/compiler.fR1gse9A.mjs';
3
+ export { B as BOOLEAN_SHORTHANDS, d as PROPERTY_CATEGORY_MAP, S as SPECIAL_VARIANTS, e as SUGGESTION_MAP, i as isValidSzProp, n as normalizeClassName } from './shared/compiler.fR1gse9A.mjs';
4
4
  import { parseSync } from 'oxc-parser';
5
5
  import * as t from '@babel/types';
6
6
  import { createHash } from 'node:crypto';
@@ -586,6 +586,11 @@ function transformSourceCode(source, filename, options) {
586
586
  const szCall = t.callExpression(t.identifier("_sz"), [
587
587
  expression
588
588
  ]);
589
+ collectCandidatesFromBabelExpr(
590
+ expression,
591
+ path,
592
+ collectedClasses
593
+ );
589
594
  path.node.value = createMergedClassNameValue(szCall);
590
595
  usesRuntime = true;
591
596
  transformed = true;
@@ -1200,6 +1205,145 @@ function collectFromExpr(node, classes) {
1200
1205
  collectFromExpr(node.alternate, classes);
1201
1206
  }
1202
1207
  }
1208
+ function collectCandidatesFromBabelExpr(node, path, classes) {
1209
+ if (t.isTSAsExpression(node) || t.isTSSatisfiesExpression(node) || t.isTSNonNullExpression(node) || t.isTSInstantiationExpression(node)) {
1210
+ collectCandidatesFromBabelExpr(node.expression, path, classes);
1211
+ } else if (t.isArrayExpression(node)) {
1212
+ for (const element of node.elements) {
1213
+ if (element === null || t.isSpreadElement(element)) {
1214
+ continue;
1215
+ }
1216
+ const cand = t.isLogicalExpression(element) && element.operator === "&&" ? element.right : element;
1217
+ collectCandidatesFromBabelExpr(cand, path, classes);
1218
+ }
1219
+ } else if (t.isObjectExpression(node)) {
1220
+ collectCandidatesFromBabelObj(node, path, classes, "");
1221
+ } else if (t.isIdentifier(node)) {
1222
+ const binding = path.scope.getBinding(node.name);
1223
+ if (binding?.path.isVariableDeclarator()) {
1224
+ let init = binding.path.node.init;
1225
+ if (init) {
1226
+ while (t.isTSAsExpression(init) || t.isTSSatisfiesExpression(init)) {
1227
+ init = init.expression;
1228
+ }
1229
+ collectCandidatesFromBabelExpr(init, path, classes);
1230
+ }
1231
+ }
1232
+ } else if (t.isConditionalExpression(node)) {
1233
+ collectCandidatesFromBabelExpr(node.consequent, path, classes);
1234
+ collectCandidatesFromBabelExpr(node.alternate, path, classes);
1235
+ } else if (t.isLogicalExpression(node) && node.operator === "&&") {
1236
+ collectCandidatesFromBabelExpr(node.right, path, classes);
1237
+ }
1238
+ }
1239
+ function collectCandidatesFromBabelObj(node, path, classes, variantPrefix) {
1240
+ const getBinding = (name) => path.scope.getBinding(name);
1241
+ for (const prop of node.properties) {
1242
+ if (t.isSpreadElement(prop)) {
1243
+ const spreadArg = prop.argument;
1244
+ if (t.isIdentifier(spreadArg)) {
1245
+ const binding = getBinding(spreadArg.name);
1246
+ if (binding?.path.isVariableDeclarator()) {
1247
+ let init = binding.path.node.init;
1248
+ if (init) {
1249
+ while (t.isTSAsExpression(init) || t.isTSSatisfiesExpression(init)) {
1250
+ init = init.expression;
1251
+ }
1252
+ if (t.isObjectExpression(init)) {
1253
+ collectCandidatesFromBabelObj(init, path, classes, variantPrefix);
1254
+ continue;
1255
+ }
1256
+ }
1257
+ }
1258
+ }
1259
+ collectCandidatesFromBabelExpr(spreadArg, path, classes);
1260
+ } else if (t.isObjectProperty(prop)) {
1261
+ let key;
1262
+ if (t.isIdentifier(prop.key)) {
1263
+ key = prop.key.name;
1264
+ } else if (t.isStringLiteral(prop.key)) {
1265
+ key = prop.key.value;
1266
+ } else if (t.isNumericLiteral(prop.key)) {
1267
+ key = String(prop.key.value);
1268
+ } else {
1269
+ continue;
1270
+ }
1271
+ const val = prop.value;
1272
+ if (t.isObjectExpression(val)) {
1273
+ if (isKnownBabelVariant(key)) {
1274
+ const nestedVariant = variantPrefix ? `${variantPrefix}:${key}` : key;
1275
+ collectCandidatesFromBabelObj(val, path, classes, nestedVariant);
1276
+ } else {
1277
+ const flatVal = resolveObjectSpreads(val, getBinding) ?? val;
1278
+ const staticObj = evaluateStaticObject(flatVal);
1279
+ if (staticObj !== null) {
1280
+ const { className } = transform({ [key]: staticObj });
1281
+ const prefixed = variantPrefix ? prefixClasses(className, variantPrefix) : className;
1282
+ for (const c of prefixed.split(/\s+/)) {
1283
+ if (c) classes.add(c);
1284
+ }
1285
+ } else {
1286
+ collectCandidatesFromBabelExpr(val, path, classes);
1287
+ }
1288
+ }
1289
+ } else if (t.isConditionalExpression(val)) {
1290
+ const consequent = val.consequent;
1291
+ const alternate = val.alternate;
1292
+ const staticCons = t.isStringLiteral(consequent) || t.isNumericLiteral(consequent) || t.isBooleanLiteral(consequent) || t.isObjectExpression(consequent) ? evaluateStaticObject(
1293
+ t.objectExpression([t.objectProperty(t.identifier(key), consequent)])
1294
+ ) : null;
1295
+ if (staticCons !== null) {
1296
+ const { className } = transform(staticCons);
1297
+ const prefixed = variantPrefix ? prefixClasses(className, variantPrefix) : className;
1298
+ for (const c of prefixed.split(/\s+/)) {
1299
+ if (c) classes.add(c);
1300
+ }
1301
+ } else {
1302
+ collectCandidatesFromBabelExpr(consequent, path, classes);
1303
+ }
1304
+ const staticAlt = t.isStringLiteral(alternate) || t.isNumericLiteral(alternate) || t.isBooleanLiteral(alternate) || t.isObjectExpression(alternate) ? evaluateStaticObject(
1305
+ t.objectExpression([t.objectProperty(t.identifier(key), alternate)])
1306
+ ) : null;
1307
+ if (staticAlt !== null) {
1308
+ const { className } = transform(staticAlt);
1309
+ const prefixed = variantPrefix ? prefixClasses(className, variantPrefix) : className;
1310
+ for (const c of prefixed.split(/\s+/)) {
1311
+ if (c) classes.add(c);
1312
+ }
1313
+ } else {
1314
+ collectCandidatesFromBabelExpr(alternate, path, classes);
1315
+ }
1316
+ } else {
1317
+ const staticVal = t.isStringLiteral(val) || t.isNumericLiteral(val) || t.isBooleanLiteral(val) ? evaluateStaticObject(
1318
+ t.objectExpression([t.objectProperty(t.identifier(key), val)])
1319
+ ) : null;
1320
+ if (staticVal !== null) {
1321
+ const { className } = transform(staticVal);
1322
+ const prefixed = variantPrefix ? (
1323
+ /**
1324
+ *
1325
+ * @param classesStr
1326
+ * @param variantChain
1327
+ */
1328
+ prefixClasses(className, variantPrefix)
1329
+ ) : className;
1330
+ for (const c of prefixed.split(/\s+/)) {
1331
+ if (c) classes.add(c);
1332
+ }
1333
+ } else {
1334
+ collectCandidatesFromBabelExpr(val, path, classes);
1335
+ }
1336
+ }
1337
+ }
1338
+ }
1339
+ }
1340
+ function prefixClasses(classesStr, variantChain) {
1341
+ const variantPrefix = getVariantPrefix(variantChain);
1342
+ return classesStr.split(/\s+/).map((c) => c ? `${variantPrefix}:${c}` : "").join(" ");
1343
+ }
1344
+ function isKnownBabelVariant(key) {
1345
+ return KNOWN_VARIANTS.has(key) || KNOWN_VARIANTS.has(getVariantPrefix(key));
1346
+ }
1203
1347
  function buildCSSVarClassName$1(info) {
1204
1348
  const { twPrefix, varName, variantChain } = info;
1205
1349
  const variantPrefix = variantChain ? `${getVariantPrefix(variantChain)}:` : "";
@@ -2123,6 +2267,12 @@ function transformOxc(source, filename, options) {
2123
2267
  objectBindings,
2124
2268
  classes
2125
2269
  );
2270
+ collectSzvCallClasses(
2271
+ node,
2272
+ effectiveFilename,
2273
+ objectBindings,
2274
+ classes
2275
+ );
2126
2276
  return;
2127
2277
  }
2128
2278
  if (node.type !== "JSXOpeningElement") {
@@ -2317,6 +2467,33 @@ function transformOxc(source, filename, options) {
2317
2467
  }
2318
2468
  }
2319
2469
  if (expression.type === "ArrayExpression") {
2470
+ const arrayMergeExpression = buildArrayMergeExpression(
2471
+ expression,
2472
+ effectiveFilename,
2473
+ objectBindings,
2474
+ globalVarAliases,
2475
+ cssVariableMap,
2476
+ source,
2477
+ classes
2478
+ );
2479
+ if (arrayMergeExpression) {
2480
+ const existingExpression = classNameAttr ? classNameMergeArgument(classNameAttr, source) : null;
2481
+ const mergeExpression = existingExpression ? `_szMerge(${existingExpression}, ${arrayMergeExpression})` : `_szMerge(${arrayMergeExpression})`;
2482
+ if (classNameAttr) {
2483
+ edits.overwrite(
2484
+ classNameAttr.start,
2485
+ classNameAttr.end,
2486
+ `className={${mergeExpression}}`
2487
+ );
2488
+ edits.remove(whitespaceStart(source, szAttr.start), szAttr.end);
2489
+ } else {
2490
+ edits.overwrite(szAttr.start, szAttr.end, `className={${mergeExpression}}`);
2491
+ }
2492
+ usesRuntime = true;
2493
+ usesMerge = true;
2494
+ transformed = true;
2495
+ return;
2496
+ }
2320
2497
  const arrayClasses = astArrayToStaticClasses(
2321
2498
  expression,
2322
2499
  effectiveFilename,
@@ -2329,7 +2506,8 @@ function transformOxc(source, filename, options) {
2329
2506
  expression,
2330
2507
  effectiveFilename,
2331
2508
  objectBindings,
2332
- classes
2509
+ classes,
2510
+ ""
2333
2511
  );
2334
2512
  runtimeFallbackExpr = expression;
2335
2513
  runtimeFallbackAttr = szAttr;
@@ -2389,7 +2567,7 @@ function transformOxc(source, filename, options) {
2389
2567
  reservedCSSVariableNames,
2390
2568
  globalVarAliases
2391
2569
  );
2392
- if (partial && szAttrs.length === 1) {
2570
+ if (partial && szAttrs.length === 1 && !(partial.hasConditional && classNameAttr)) {
2393
2571
  const mergedStyleProps = hoistedStyleProps.length > 0 ? [...hoistedStyleProps, ...partial.styleProps] : partial.styleProps;
2394
2572
  if (classNameAttr?.value?.type === "JSXExpressionContainer") {
2395
2573
  const classExpression = classNameAttr.value.expression;
@@ -2480,6 +2658,13 @@ function transformOxc(source, filename, options) {
2480
2658
  if (runtimeFallbackExpr.type !== "ArrayExpression") {
2481
2659
  diagnostics.push(buildRuntimeFallbackDiagnostic(runtimeFallbackExpr, source));
2482
2660
  }
2661
+ collectCandidateClassesFromExpression(
2662
+ runtimeFallbackExpr,
2663
+ effectiveFilename,
2664
+ objectBindings,
2665
+ classes,
2666
+ ""
2667
+ );
2483
2668
  edits.overwrite(
2484
2669
  runtimeFallbackAttr.start,
2485
2670
  runtimeFallbackAttr.end,
@@ -2677,32 +2862,278 @@ function astArrayToStaticClasses(node, filename, bindings, globalVarAliases, css
2677
2862
  }
2678
2863
  return out;
2679
2864
  }
2680
- function collectArrayCandidateClasses(node, filename, bindings, classes) {
2865
+ function buildArrayMergeExpression(node, filename, bindings, globalVarAliases, cssVariableMap, source, classes) {
2866
+ const parts = [];
2867
+ let hasConditional = false;
2868
+ for (const element of node.elements) {
2869
+ if (!element || isFalsyLiteral(element)) {
2870
+ continue;
2871
+ }
2872
+ const unwrapped = unwrapExpression(element);
2873
+ let condition = null;
2874
+ let candidate = unwrapped;
2875
+ if (unwrapped.type === "LogicalExpression" && unwrapped.operator === "&&") {
2876
+ const logical = unwrapped;
2877
+ condition = logical.left;
2878
+ candidate = unwrapExpression(logical.right);
2879
+ hasConditional = true;
2880
+ }
2881
+ const objectNode = resolveObjectExpression(candidate, bindings);
2882
+ if (!objectNode) {
2883
+ return null;
2884
+ }
2885
+ let result;
2886
+ try {
2887
+ result = transform(
2888
+ applyGlobalVarAliasesToSzObject(
2889
+ astObjectToSzObject(objectNode, filename, bindings),
2890
+ globalVarAliases,
2891
+ cssVariableMap
2892
+ )
2893
+ );
2894
+ } catch (err) {
2895
+ if (err instanceof OxcNotImplementedError) {
2896
+ return null;
2897
+ }
2898
+ throw err;
2899
+ }
2900
+ for (const cls of result.className.split(/\s+/)) {
2901
+ if (cls) {
2902
+ classes.add(cls);
2903
+ }
2904
+ }
2905
+ const classLiteral = JSON.stringify(result.className);
2906
+ parts.push(
2907
+ condition ? `${source.slice(condition.start, condition.end)} && ${classLiteral}` : classLiteral
2908
+ );
2909
+ }
2910
+ return hasConditional ? parts.join(", ") : null;
2911
+ }
2912
+ function classNameMergeArgument(attribute, source) {
2913
+ const staticValue = stringLiteralValue(attribute.value);
2914
+ if (staticValue !== null) {
2915
+ return JSON.stringify(staticValue);
2916
+ }
2917
+ if (attribute.value?.type === "JSXExpressionContainer") {
2918
+ const expression = attribute.value.expression;
2919
+ return source.slice(expression.start, expression.end);
2920
+ }
2921
+ return '""';
2922
+ }
2923
+ function collectArrayCandidateClasses(node, filename, bindings, classes, variantPrefix) {
2681
2924
  for (const element of node.elements) {
2682
2925
  if (!element || isFalsyLiteral(element)) {
2683
2926
  continue;
2684
2927
  }
2685
2928
  const candidate = element.type === "LogicalExpression" && element.operator === "&&" ? element.right : element;
2686
- collectStaticObjectCandidateClasses(candidate, filename, bindings, classes);
2929
+ collectCandidateClassesFromExpression(
2930
+ candidate,
2931
+ filename,
2932
+ bindings,
2933
+ classes,
2934
+ variantPrefix
2935
+ );
2687
2936
  }
2688
2937
  }
2689
- function collectStaticObjectCandidateClasses(node, filename, bindings, classes) {
2690
- const objectNode = resolveObjectExpression(node, bindings);
2691
- if (!objectNode) {
2692
- return;
2938
+ function collectCandidateClassesFromExpression(node, filename, bindings, classes, variantPrefix) {
2939
+ const unwrapped = unwrapExpression(node);
2940
+ if (unwrapped.type === "ArrayExpression") {
2941
+ collectArrayCandidateClasses(
2942
+ unwrapped,
2943
+ filename,
2944
+ bindings,
2945
+ classes,
2946
+ variantPrefix
2947
+ );
2948
+ } else if (unwrapped.type === "ObjectExpression") {
2949
+ collectCandidateClassesFromObjectExpression(
2950
+ unwrapped,
2951
+ filename,
2952
+ bindings,
2953
+ classes,
2954
+ variantPrefix
2955
+ );
2956
+ } else if (unwrapped.type === "Identifier") {
2957
+ const bound = bindings.get(String(unwrapped.name));
2958
+ if (bound) {
2959
+ collectCandidateClassesFromExpression(
2960
+ bound,
2961
+ filename,
2962
+ bindings,
2963
+ classes,
2964
+ variantPrefix
2965
+ );
2966
+ }
2967
+ } else if (unwrapped.type === "ConditionalExpression") {
2968
+ const cond = unwrapped;
2969
+ collectCandidateClassesFromExpression(
2970
+ cond.consequent,
2971
+ filename,
2972
+ bindings,
2973
+ classes,
2974
+ variantPrefix
2975
+ );
2976
+ collectCandidateClassesFromExpression(
2977
+ cond.alternate,
2978
+ filename,
2979
+ bindings,
2980
+ classes,
2981
+ variantPrefix
2982
+ );
2983
+ } else if (unwrapped.type === "LogicalExpression" && unwrapped.operator === "&&") {
2984
+ const logical = unwrapped;
2985
+ collectCandidateClassesFromExpression(
2986
+ logical.right,
2987
+ filename,
2988
+ bindings,
2989
+ classes,
2990
+ variantPrefix
2991
+ );
2693
2992
  }
2694
- let result;
2993
+ }
2994
+ function collectCandidateClassesFromObjectExpression(node, filename, bindings, classes, variantPrefix) {
2695
2995
  try {
2696
- result = transform(astObjectToSzObject(objectNode, filename, bindings));
2996
+ const compiled = transform(astObjectToSzObject(node, filename, bindings));
2997
+ for (const cls of prefixVariantClasses(compiled.className, variantPrefix).split(/\s+/)) {
2998
+ if (cls) {
2999
+ classes.add(cls);
3000
+ }
3001
+ }
3002
+ return;
2697
3003
  } catch (err) {
2698
- if (err instanceof OxcNotImplementedError) {
2699
- return;
3004
+ if (!(err instanceof OxcNotImplementedError)) {
3005
+ throw err;
2700
3006
  }
2701
- throw err;
2702
3007
  }
2703
- for (const cls of result.className.split(/\s+/)) {
2704
- if (cls) {
2705
- classes.add(cls);
3008
+ for (const propRaw of node.properties) {
3009
+ if (propRaw.type === "SpreadElement") {
3010
+ const spread = propRaw;
3011
+ const spreadArg = unwrapExpression(spread.argument);
3012
+ if (spreadArg.type === "Identifier") {
3013
+ const bound = bindings.get(String(spreadArg.name));
3014
+ if (bound) {
3015
+ collectCandidateClassesFromObjectExpression(
3016
+ bound,
3017
+ filename,
3018
+ bindings,
3019
+ classes,
3020
+ variantPrefix
3021
+ );
3022
+ }
3023
+ } else {
3024
+ collectCandidateClassesFromExpression(
3025
+ spread.argument,
3026
+ filename,
3027
+ bindings,
3028
+ classes,
3029
+ variantPrefix
3030
+ );
3031
+ }
3032
+ } else if (propRaw.type === "Property") {
3033
+ const prop = propRaw;
3034
+ if (prop.computed) {
3035
+ continue;
3036
+ }
3037
+ const key = extractKeyName(prop.key);
3038
+ if (key === null) {
3039
+ continue;
3040
+ }
3041
+ const val = unwrapExpression(prop.value);
3042
+ if (val.type === "ObjectExpression") {
3043
+ if (isKnownVariant(key)) {
3044
+ const nestedVariant = variantPrefix ? `${variantPrefix}:${key}` : key;
3045
+ collectCandidateClassesFromObjectExpression(
3046
+ val,
3047
+ filename,
3048
+ bindings,
3049
+ classes,
3050
+ nestedVariant
3051
+ );
3052
+ } else {
3053
+ try {
3054
+ const propertyVal = astObjectToSzObject(
3055
+ val,
3056
+ filename,
3057
+ bindings
3058
+ );
3059
+ const singleObject = { [key]: propertyVal };
3060
+ const compiled = transform(singleObject);
3061
+ for (const c of prefixVariantClasses(
3062
+ compiled.className,
3063
+ variantPrefix
3064
+ ).split(/\s+/)) {
3065
+ if (c) classes.add(c);
3066
+ }
3067
+ } catch {
3068
+ collectCandidateClassesFromExpression(
3069
+ val,
3070
+ filename,
3071
+ bindings,
3072
+ classes,
3073
+ variantPrefix
3074
+ );
3075
+ }
3076
+ }
3077
+ } else if (val.type === "ConditionalExpression") {
3078
+ const cond = val;
3079
+ try {
3080
+ const consequentVal = astValueToSzValue(cond.consequent, filename, bindings);
3081
+ const singleConsequent = { [key]: consequentVal };
3082
+ const compiledConsequent = transform(singleConsequent);
3083
+ for (const c of prefixVariantClasses(
3084
+ compiledConsequent.className,
3085
+ variantPrefix
3086
+ ).split(/\s+/)) {
3087
+ if (c) classes.add(c);
3088
+ }
3089
+ } catch {
3090
+ collectCandidateClassesFromExpression(
3091
+ cond.consequent,
3092
+ filename,
3093
+ bindings,
3094
+ classes,
3095
+ variantPrefix
3096
+ );
3097
+ }
3098
+ try {
3099
+ const alternateVal = astValueToSzValue(cond.alternate, filename, bindings);
3100
+ const singleAlternate = { [key]: alternateVal };
3101
+ const compiledAlternate = transform(singleAlternate);
3102
+ for (const c of prefixVariantClasses(
3103
+ compiledAlternate.className,
3104
+ variantPrefix
3105
+ ).split(/\s+/)) {
3106
+ if (c) classes.add(c);
3107
+ }
3108
+ } catch {
3109
+ collectCandidateClassesFromExpression(
3110
+ cond.alternate,
3111
+ filename,
3112
+ bindings,
3113
+ classes,
3114
+ variantPrefix
3115
+ );
3116
+ }
3117
+ } else {
3118
+ try {
3119
+ const propertyVal = astValueToSzValue(val, filename, bindings);
3120
+ const singleObject = { [key]: propertyVal };
3121
+ const compiled = transform(singleObject);
3122
+ for (const c of prefixVariantClasses(compiled.className, variantPrefix).split(
3123
+ /\s+/
3124
+ )) {
3125
+ if (c) classes.add(c);
3126
+ }
3127
+ } catch {
3128
+ collectCandidateClassesFromExpression(
3129
+ val,
3130
+ filename,
3131
+ bindings,
3132
+ classes,
3133
+ variantPrefix
3134
+ );
3135
+ }
3136
+ }
2706
3137
  }
2707
3138
  }
2708
3139
  }
@@ -2749,6 +3180,53 @@ function collectDynamicCallClasses(node, filename, bindings, classes) {
2749
3180
  }
2750
3181
  }
2751
3182
  }
3183
+ function collectSzvCallClasses(node, filename, bindings, classes) {
3184
+ if (node.callee.type !== "Identifier" || node.callee.name !== "szv") {
3185
+ return;
3186
+ }
3187
+ const [firstArg] = node.arguments;
3188
+ if (!firstArg) {
3189
+ return;
3190
+ }
3191
+ const configNode = resolveObjectExpression(firstArg, bindings);
3192
+ if (!configNode) {
3193
+ return;
3194
+ }
3195
+ let config;
3196
+ try {
3197
+ config = astObjectToSzObject(configNode, filename, bindings);
3198
+ } catch (err) {
3199
+ if (err instanceof OxcNotImplementedError) {
3200
+ return;
3201
+ }
3202
+ throw err;
3203
+ }
3204
+ const base = isSzObject(config.base) ? config.base : {};
3205
+ addCompiledClasses(base, classes);
3206
+ const variants = isSzObject(config.variants) ? config.variants : {};
3207
+ for (const variantValues of Object.values(variants)) {
3208
+ if (!isSzObject(variantValues)) {
3209
+ continue;
3210
+ }
3211
+ for (const variantObject of Object.values(variantValues)) {
3212
+ if (!isSzObject(variantObject)) {
3213
+ continue;
3214
+ }
3215
+ addCompiledClasses({ ...base, ...variantObject }, classes);
3216
+ }
3217
+ }
3218
+ }
3219
+ function addCompiledClasses(object, classes) {
3220
+ const result = transform(object);
3221
+ for (const cls of result.className.split(/\s+/)) {
3222
+ if (cls) {
3223
+ classes.add(cls);
3224
+ }
3225
+ }
3226
+ }
3227
+ function isSzObject(value) {
3228
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3229
+ }
2752
3230
  function resolveObjectExpression(node, bindings) {
2753
3231
  const unwrapped = unwrapExpression(node);
2754
3232
  if (unwrapped.type === "ObjectExpression") {
@@ -2844,7 +3322,7 @@ function buildPartialObjectTransform(node, filename, bindings, source, options,
2844
3322
  if (!partial || partial.dynamicProps.size === 0 && partial.conditionalClasses.length === 0) {
2845
3323
  return null;
2846
3324
  }
2847
- if (partial.conditionalClasses.length > 0 && (partial.conditionalClasses.length !== 1 || partial.dynamicProps.size > 0 || Object.keys(partial.staticProps).length > 0)) {
3325
+ if (partial.conditionalClasses.length > 0 && (partial.conditionalClasses.length !== 1 || partial.dynamicProps.size > 0)) {
2848
3326
  return null;
2849
3327
  }
2850
3328
  const classParts = [];
@@ -2871,7 +3349,13 @@ function buildPartialObjectTransform(node, filename, bindings, source, options,
2871
3349
  const styleProps = [...partial.dynamicProps.entries()].filter(([id]) => !hoistedNames?.has(id)).map(
2872
3350
  ([, info]) => `${JSON.stringify(info.varName)}: ${generateStyleValueSource(info, source)}`
2873
3351
  );
2874
- return { className, classNameAttr, styleProps, usesColorVar: partial.usesColorVar };
3352
+ return {
3353
+ className,
3354
+ classNameAttr,
3355
+ styleProps,
3356
+ usesColorVar: partial.usesColorVar,
3357
+ hasConditional: partial.conditionalClasses.length > 0
3358
+ };
2875
3359
  }
2876
3360
  function applyHoistedVariableNames(partial, hoistedNames, cssVariableMap) {
2877
3361
  if (!hoistedNames) {
@@ -3433,9 +3917,14 @@ function buildCSSVarClassName(info) {
3433
3917
  return `${variantPrefix}${info.twPrefix}-(${info.varName})`;
3434
3918
  }
3435
3919
  function buildConditionalClassSource(classParts, conditionals, source) {
3436
- if (conditionals.length === 1 && classParts.length === 2) {
3920
+ if (conditionals.length === 1) {
3437
3921
  const [entry] = conditionals;
3438
- return `${source.slice(entry.test.start, entry.test.end)} ? ${JSON.stringify(entry.consequent)} : ${JSON.stringify(entry.alternate)}`;
3922
+ const ternary = `${source.slice(entry.test.start, entry.test.end)} ? ${JSON.stringify(entry.consequent)} : ${JSON.stringify(entry.alternate)}`;
3923
+ const staticParts = classParts.slice(0, -2).filter(Boolean);
3924
+ if (staticParts.length === 0) {
3925
+ return ternary;
3926
+ }
3927
+ return `\`${staticParts.join(" ")} \${${ternary}}\``;
3439
3928
  }
3440
3929
  return JSON.stringify(classParts.filter(Boolean).join(" "));
3441
3930
  }
@@ -301,11 +301,17 @@ const PROPERTY_MAP = {
301
301
  borderColor: "border",
302
302
  borderStyle: "border",
303
303
  borderT: "border-t",
304
+ borderTColor: "border-t",
304
305
  borderR: "border-r",
306
+ borderRColor: "border-r",
305
307
  borderB: "border-b",
308
+ borderBColor: "border-b",
306
309
  borderL: "border-l",
310
+ borderLColor: "border-l",
307
311
  borderX: "border-x",
312
+ borderXColor: "border-x",
308
313
  borderY: "border-y",
314
+ borderYColor: "border-y",
309
315
  borderS: "border-s",
310
316
  borderE: "border-e",
311
317
  borderBs: "border-bs",
@@ -299,11 +299,17 @@ const PROPERTY_MAP = {
299
299
  borderColor: "border",
300
300
  borderStyle: "border",
301
301
  borderT: "border-t",
302
+ borderTColor: "border-t",
302
303
  borderR: "border-r",
304
+ borderRColor: "border-r",
303
305
  borderB: "border-b",
306
+ borderBColor: "border-b",
304
307
  borderL: "border-l",
308
+ borderLColor: "border-l",
305
309
  borderX: "border-x",
310
+ borderXColor: "border-x",
306
311
  borderY: "border-y",
312
+ borderYColor: "border-y",
307
313
  borderS: "border-s",
308
314
  borderE: "border-e",
309
315
  borderBs: "border-bs",
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const transformCore = require('./shared/compiler.BfDLUvcf.cjs');
3
+ const transformCore = require('./shared/compiler.BsKlgPl4.cjs');
4
4
 
5
5
 
6
6
 
@@ -1 +1 @@
1
- export { B as BOOLEAN_SHORTHANDS, K as KNOWN_VARIANTS, P as PROPERTY_MAP, S as SPECIAL_VARIANTS, e as SUGGESTION_MAP, V as VARIANT_MAP, b as getVariantPrefix, i as isValidSzProp, f as normalizeArbitraryValue, h as normalizeArbitraryVariant, n as normalizeClassName, t as transform } from './shared/compiler.wyFFQW-b.mjs';
1
+ export { B as BOOLEAN_SHORTHANDS, K as KNOWN_VARIANTS, P as PROPERTY_MAP, S as SPECIAL_VARIANTS, e as SUGGESTION_MAP, V as VARIANT_MAP, b as getVariantPrefix, i as isValidSzProp, f as normalizeArbitraryValue, h as normalizeArbitraryVariant, n as normalizeClassName, t as transform } from './shared/compiler.fR1gse9A.mjs';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@csszyx/compiler",
3
- "version": "0.9.5",
3
+ "version": "0.9.6",
4
4
  "description": "Core compiler and transformation logic for csszyx",
5
5
  "keywords": [
6
6
  "csszyx",
@@ -65,7 +65,7 @@
65
65
  "@babel/types": "^7.23.6",
66
66
  "magic-string": "0.30.21",
67
67
  "oxc-parser": "0.131.0",
68
- "@csszyx/core": "0.9.5"
68
+ "@csszyx/core": "0.9.6"
69
69
  },
70
70
  "devDependencies": {
71
71
  "@types/babel__core": "^7.20.5",