@plumeria/unplugin 18.1.0 → 18.1.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.
Files changed (3) hide show
  1. package/dist/core.js +116 -39
  2. package/dist/core.mjs +116 -39
  3. package/package.json +2 -2
package/dist/core.js CHANGED
@@ -813,6 +813,8 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
813
813
  });
814
814
  const conditionals = [];
815
815
  let groupIdCounter = 0;
816
+ let sourceOrder = 0;
817
+ const baseChunks = [];
816
818
  let baseStyle = {};
817
819
  let isOptimizable = true;
818
820
  const resolveCreateObject = (varName) => {
@@ -839,15 +841,15 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
839
841
  ? { varName, keyExpr: node.property.expression, obj }
840
842
  : null;
841
843
  };
842
- const buildDecision = (node, prefix, off, counter) => {
844
+ const buildDecision = (node, prefix, off, counter, scoped) => {
843
845
  if (node.type === 'ParenthesisExpression') {
844
- return buildDecision(node.expression, prefix, off, counter);
846
+ return buildDecision(node.expression, prefix, off, counter, scoped);
845
847
  }
846
848
  if (node.type === 'ConditionalExpression') {
847
- const a = buildDecision(node.consequent, prefix, off, counter);
849
+ const a = buildDecision(node.consequent, prefix, off, counter, scoped);
848
850
  if (!a)
849
851
  return null;
850
- const b = buildDecision(node.alternate, prefix, off, counter);
852
+ const b = buildDecision(node.alternate, prefix, off, counter, scoped);
851
853
  if (!b)
852
854
  return null;
853
855
  return {
@@ -858,7 +860,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
858
860
  };
859
861
  }
860
862
  if (node.type === 'BinaryExpression' && node.operator === '&&') {
861
- const right = buildDecision(node.right, prefix, off, counter);
863
+ const right = buildDecision(node.right, prefix, off, counter, scoped);
862
864
  if (!right)
863
865
  return null;
864
866
  return {
@@ -870,10 +872,14 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
870
872
  }
871
873
  const group = resolveBracketGroup(node);
872
874
  if (group) {
875
+ const tag = scoped ? `${counter.n++}:` : '';
876
+ const keySource = getSource(group.keyExpr);
873
877
  return {
874
- keyExpr: getSource(group.keyExpr),
878
+ keyExpr: tag
879
+ ? `(${JSON.stringify(tag)} + ${keySource})`
880
+ : keySource,
875
881
  options: Object.entries(group.obj).map(([value, style]) => ({
876
- value,
882
+ value: `${tag}${value}`,
877
883
  style: style,
878
884
  })),
879
885
  leaves: 1,
@@ -906,23 +912,30 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
906
912
  else {
907
913
  const group = resolveBracketGroup(node);
908
914
  if (group)
909
- Object.keys(group.obj).forEach((k) => acc.add(k));
915
+ Object.entries(group.obj).forEach(([key, style]) => {
916
+ let styles = acc.get(key);
917
+ if (!styles)
918
+ acc.set(key, (styles = new Set()));
919
+ styles.add(style);
920
+ });
910
921
  }
911
922
  };
912
923
  const resolveDecision = (node) => {
913
- const groupKeys = new Set();
924
+ const groupKeys = new Map();
914
925
  collectGroupKeys(node, groupKeys);
915
926
  let prefix = '#';
916
- while ([...groupKeys].some((k) => k.startsWith(prefix)))
927
+ while ([...groupKeys.keys()].some((k) => k.startsWith(prefix)))
917
928
  prefix += '#';
918
- const off = groupKeys.has('') ? `${prefix}off` : '';
919
- return buildDecision(node, prefix, off, { n: 0 });
929
+ const scoped = [...groupKeys.values()].some((styles) => styles.size > 1);
930
+ const off = !scoped && groupKeys.has('') ? `${prefix}off` : '';
931
+ return buildDecision(node, prefix, off, { n: 0 }, scoped);
920
932
  };
921
933
  const collectConditions = (node, currentTestStrings = []) => {
922
934
  const staticStyle = resolveStyleObject(node);
923
935
  if (staticStyle) {
924
936
  if (currentTestStrings.length === 0) {
925
937
  baseStyle = (0, utils_1.deepMerge)(baseStyle, staticStyle);
938
+ baseChunks.push({ order: sourceOrder++, style: staticStyle });
926
939
  }
927
940
  else {
928
941
  conditionals.push({
@@ -931,6 +944,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
931
944
  truthy: staticStyle,
932
945
  falsy: {},
933
946
  varName: undefined,
947
+ order: sourceOrder++,
934
948
  });
935
949
  }
936
950
  return true;
@@ -947,6 +961,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
947
961
  truthy: trueStyle,
948
962
  falsy: falseStyle,
949
963
  varName: undefined,
964
+ order: sourceOrder++,
950
965
  });
951
966
  return true;
952
967
  }
@@ -998,6 +1013,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
998
1013
  }
999
1014
  if (propPossibilities && propPossibilities.length > 0) {
1000
1015
  const currentGroupId = ++groupIdCounter;
1016
+ const currentOrder = sourceOrder++;
1001
1017
  const uniqueEntries = [];
1002
1018
  propPossibilities.forEach((entry) => {
1003
1019
  if (!uniqueEntries.some((x) => x.key === entry.key)) {
@@ -1012,6 +1028,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1012
1028
  truthy: entry.styleObj,
1013
1029
  falsy: {},
1014
1030
  groupId: currentGroupId,
1031
+ order: currentOrder,
1015
1032
  groupName: undefined,
1016
1033
  valueName: entry.key,
1017
1034
  varName,
@@ -1068,11 +1085,18 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1068
1085
  if (!groupVariants)
1069
1086
  continue;
1070
1087
  const currentGroupId = ++groupIdCounter;
1088
+ const currentOrder = sourceOrder++;
1071
1089
  const valSource = getSource(valExpr);
1072
1090
  if (valExpr.type === 'StringLiteral') {
1073
1091
  const groupVariantsAsObj = groupVariants;
1074
- if (groupVariantsAsObj[valExpr.value])
1075
- baseStyle = (0, utils_1.deepMerge)(baseStyle, groupVariantsAsObj[valExpr.value]);
1092
+ const picked = groupVariantsAsObj[valExpr.value];
1093
+ if (picked) {
1094
+ baseStyle = (0, utils_1.deepMerge)(baseStyle, picked);
1095
+ baseChunks.push({
1096
+ order: sourceOrder++,
1097
+ style: picked,
1098
+ });
1099
+ }
1076
1100
  continue;
1077
1101
  }
1078
1102
  Object.entries(groupVariants).forEach(([optionName, style]) => {
@@ -1083,6 +1107,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1083
1107
  truthy: style,
1084
1108
  falsy: {},
1085
1109
  groupId: currentGroupId,
1110
+ order: currentOrder,
1086
1111
  groupName,
1087
1112
  valueName: optionName,
1088
1113
  varName,
@@ -1094,11 +1119,15 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1094
1119
  }
1095
1120
  const argSource = getSource(arg);
1096
1121
  if (utils_1.t.isStringLiteral(arg)) {
1097
- if (variantObj[arg.value])
1098
- baseStyle = (0, utils_1.deepMerge)(baseStyle, variantObj[arg.value]);
1122
+ const picked = variantObj[arg.value];
1123
+ if (picked) {
1124
+ baseStyle = (0, utils_1.deepMerge)(baseStyle, picked);
1125
+ baseChunks.push({ order: sourceOrder++, style: picked });
1126
+ }
1099
1127
  continue;
1100
1128
  }
1101
1129
  const currentGroupId = ++groupIdCounter;
1130
+ const currentOrder = sourceOrder++;
1102
1131
  Object.entries(variantObj).forEach(([key, style]) => {
1103
1132
  conditionals.push({
1104
1133
  test: arg,
@@ -1107,6 +1136,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1107
1136
  truthy: style,
1108
1137
  falsy: {},
1109
1138
  groupId: currentGroupId,
1139
+ order: currentOrder,
1110
1140
  groupName: undefined,
1111
1141
  valueName: key,
1112
1142
  varName,
@@ -1134,6 +1164,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1134
1164
  if (!groupVariants)
1135
1165
  return;
1136
1166
  const currentGroupId = ++groupIdCounter;
1167
+ const currentOrder = sourceOrder++;
1137
1168
  Object.entries(groupVariants).forEach(([optionName, style]) => {
1138
1169
  conditionals.push({
1139
1170
  test: expr,
@@ -1142,6 +1173,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1142
1173
  truthy: style,
1143
1174
  falsy: {},
1144
1175
  groupId: currentGroupId,
1176
+ order: currentOrder,
1145
1177
  groupName,
1146
1178
  valueName: optionName,
1147
1179
  varName,
@@ -1160,6 +1192,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1160
1192
  const dynExpr = expr.property.expression;
1161
1193
  const dynSource = getSource(dynExpr);
1162
1194
  const currentGroupId = ++groupIdCounter;
1195
+ const currentOrder = sourceOrder++;
1163
1196
  Object.entries(styleObj).forEach(([optionName, style]) => {
1164
1197
  conditionals.push({
1165
1198
  test: dynExpr,
@@ -1168,9 +1201,11 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1168
1201
  truthy: style,
1169
1202
  falsy: {},
1170
1203
  groupId: currentGroupId,
1204
+ order: currentOrder,
1171
1205
  groupName: undefined,
1172
1206
  valueName: optionName,
1173
1207
  varName,
1208
+ ownKeys: true,
1174
1209
  });
1175
1210
  });
1176
1211
  continue;
@@ -1179,6 +1214,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1179
1214
  const decision = resolveDecision(expr);
1180
1215
  if (decision && (decision.hasGroup || decision.leaves > 2)) {
1181
1216
  const groupId = ++groupIdCounter;
1217
+ const currentOrder = sourceOrder++;
1182
1218
  decision.options.forEach(({ value, style }) => conditionals.push({
1183
1219
  test: expr,
1184
1220
  testLHS: decision.keyExpr,
@@ -1186,9 +1222,11 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1186
1222
  truthy: style,
1187
1223
  falsy: {},
1188
1224
  groupId,
1225
+ order: currentOrder,
1189
1226
  groupName: undefined,
1190
1227
  valueName: value,
1191
1228
  varName: undefined,
1229
+ ownKeys: true,
1192
1230
  }));
1193
1231
  continue;
1194
1232
  }
@@ -1342,17 +1380,38 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1342
1380
  });
1343
1381
  if (Object.keys(baseConflict).length > 0 ||
1344
1382
  conflictConditionals.length > 0) {
1345
- const dimensions = [];
1383
+ const ordered = [];
1384
+ baseChunks.forEach(({ order, style }) => {
1385
+ const conflicting = {};
1386
+ Object.entries(style).forEach(([key, value]) => {
1387
+ if (conflictingKeys.has(key))
1388
+ conflicting[key] = value;
1389
+ });
1390
+ if (Object.keys(conflicting).length === 0)
1391
+ return;
1392
+ ordered.push({
1393
+ order,
1394
+ dimension: {
1395
+ type: 'const',
1396
+ options: [
1397
+ { value: undefined, style: conflicting, label: 'base' },
1398
+ ],
1399
+ },
1400
+ });
1401
+ });
1346
1402
  conflictConditionals
1347
1403
  .filter((c) => c.groupId === undefined)
1348
1404
  .forEach((c) => {
1349
- dimensions.push({
1350
- type: 'std',
1351
- testExpr: c.testString ?? getSource(c.test),
1352
- options: [
1353
- { value: 0, style: c.falsy, label: 'false' },
1354
- { value: 1, style: c.truthy, label: 'true' },
1355
- ],
1405
+ ordered.push({
1406
+ order: c.order ?? 0,
1407
+ dimension: {
1408
+ type: 'std',
1409
+ testExpr: c.testString ?? getSource(c.test),
1410
+ options: [
1411
+ { value: 0, style: c.falsy, label: 'false' },
1412
+ { value: 1, style: c.truthy, label: 'true' },
1413
+ ],
1414
+ },
1356
1415
  });
1357
1416
  });
1358
1417
  const conflictVarGroups = {};
@@ -1373,17 +1432,34 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1373
1432
  opts.push({ ...off, truthy: {}, falsy: {} });
1374
1433
  });
1375
1434
  Object.entries(conflictVarGroups).forEach(([, opts]) => {
1376
- dimensions.push({
1377
- type: 'var',
1378
- testExpr: opts[0].testLHS ??
1379
- opts[0].testString ??
1380
- getSource(opts[0].test),
1381
- options: opts.map((opt) => ({
1382
- value: opt.valueName,
1383
- style: opt.truthy,
1384
- label: opt.valueName || 'default',
1385
- })),
1435
+ ordered.push({
1436
+ order: opts[0].order ?? 0,
1437
+ dimension: {
1438
+ type: 'var',
1439
+ testExpr: opts[0].testLHS ??
1440
+ opts[0].testString ??
1441
+ getSource(opts[0].test),
1442
+ options: opts.map((opt) => ({
1443
+ value: opt.valueName,
1444
+ style: opt.truthy,
1445
+ label: opt.valueName || 'default',
1446
+ })),
1447
+ ownKeys: opts[0].ownKeys,
1448
+ },
1449
+ });
1450
+ });
1451
+ ordered.sort((a, b) => a.order - b.order);
1452
+ const dimensions = ordered.map((o) => o.dimension);
1453
+ const joined = dimensions.filter((dim) => dim.type !== 'const').length > 1;
1454
+ dimensions.forEach((dim) => {
1455
+ if (!joined || dim.type !== 'var' || !dim.ownKeys)
1456
+ return;
1457
+ const numbers = {};
1458
+ dim.options.forEach((opt, index) => {
1459
+ numbers[String(opt.value)] = String(index);
1460
+ opt.value = String(index);
1386
1461
  });
1462
+ dim.testExpr = `(${JSON.stringify(numbers)}[${dim.testExpr}] || "")`;
1387
1463
  });
1388
1464
  const results = {};
1389
1465
  const recurse = (dimIndex, currentStyle, keyParts) => {
@@ -1395,18 +1471,19 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1395
1471
  results[keyParts.join('__')] = className;
1396
1472
  return;
1397
1473
  }
1398
- dimensions[dimIndex].options.forEach((opt) => recurse(dimIndex + 1, (0, utils_1.deepMerge)(currentStyle, opt.style), [
1399
- ...keyParts,
1400
- String(opt.value),
1401
- ]));
1474
+ const dimension = dimensions[dimIndex];
1475
+ dimension.options.forEach((opt) => recurse(dimIndex + 1, (0, utils_1.deepMerge)(currentStyle, opt.style), dimension.type === 'const'
1476
+ ? keyParts
1477
+ : [...keyParts, String(opt.value)]));
1402
1478
  };
1403
- recurse(0, baseConflict, []);
1479
+ recurse(0, {}, []);
1404
1480
  const baseConflictClass = Object.keys(baseConflict).length > 0
1405
1481
  ? processStyleRecords(baseConflict)
1406
1482
  .map((r) => r.hash)
1407
1483
  .join(' ')
1408
1484
  : '';
1409
1485
  const masterKeyExpr = dimensions
1486
+ .filter((dim) => dim.type !== 'const')
1410
1487
  .map((dim) => dim.type === 'std'
1411
1488
  ? `(${dim.testExpr} ? "1" : "0")`
1412
1489
  : dim.testExpr || '""')
package/dist/core.mjs CHANGED
@@ -777,6 +777,8 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
777
777
  });
778
778
  const conditionals = [];
779
779
  let groupIdCounter = 0;
780
+ let sourceOrder = 0;
781
+ const baseChunks = [];
780
782
  let baseStyle = {};
781
783
  let isOptimizable = true;
782
784
  const resolveCreateObject = (varName) => {
@@ -803,15 +805,15 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
803
805
  ? { varName, keyExpr: node.property.expression, obj }
804
806
  : null;
805
807
  };
806
- const buildDecision = (node, prefix, off, counter) => {
808
+ const buildDecision = (node, prefix, off, counter, scoped) => {
807
809
  if (node.type === 'ParenthesisExpression') {
808
- return buildDecision(node.expression, prefix, off, counter);
810
+ return buildDecision(node.expression, prefix, off, counter, scoped);
809
811
  }
810
812
  if (node.type === 'ConditionalExpression') {
811
- const a = buildDecision(node.consequent, prefix, off, counter);
813
+ const a = buildDecision(node.consequent, prefix, off, counter, scoped);
812
814
  if (!a)
813
815
  return null;
814
- const b = buildDecision(node.alternate, prefix, off, counter);
816
+ const b = buildDecision(node.alternate, prefix, off, counter, scoped);
815
817
  if (!b)
816
818
  return null;
817
819
  return {
@@ -822,7 +824,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
822
824
  };
823
825
  }
824
826
  if (node.type === 'BinaryExpression' && node.operator === '&&') {
825
- const right = buildDecision(node.right, prefix, off, counter);
827
+ const right = buildDecision(node.right, prefix, off, counter, scoped);
826
828
  if (!right)
827
829
  return null;
828
830
  return {
@@ -834,10 +836,14 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
834
836
  }
835
837
  const group = resolveBracketGroup(node);
836
838
  if (group) {
839
+ const tag = scoped ? `${counter.n++}:` : '';
840
+ const keySource = getSource(group.keyExpr);
837
841
  return {
838
- keyExpr: getSource(group.keyExpr),
842
+ keyExpr: tag
843
+ ? `(${JSON.stringify(tag)} + ${keySource})`
844
+ : keySource,
839
845
  options: Object.entries(group.obj).map(([value, style]) => ({
840
- value,
846
+ value: `${tag}${value}`,
841
847
  style: style,
842
848
  })),
843
849
  leaves: 1,
@@ -870,23 +876,30 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
870
876
  else {
871
877
  const group = resolveBracketGroup(node);
872
878
  if (group)
873
- Object.keys(group.obj).forEach((k) => acc.add(k));
879
+ Object.entries(group.obj).forEach(([key, style]) => {
880
+ let styles = acc.get(key);
881
+ if (!styles)
882
+ acc.set(key, (styles = new Set()));
883
+ styles.add(style);
884
+ });
874
885
  }
875
886
  };
876
887
  const resolveDecision = (node) => {
877
- const groupKeys = new Set();
888
+ const groupKeys = new Map();
878
889
  collectGroupKeys(node, groupKeys);
879
890
  let prefix = '#';
880
- while ([...groupKeys].some((k) => k.startsWith(prefix)))
891
+ while ([...groupKeys.keys()].some((k) => k.startsWith(prefix)))
881
892
  prefix += '#';
882
- const off = groupKeys.has('') ? `${prefix}off` : '';
883
- return buildDecision(node, prefix, off, { n: 0 });
893
+ const scoped = [...groupKeys.values()].some((styles) => styles.size > 1);
894
+ const off = !scoped && groupKeys.has('') ? `${prefix}off` : '';
895
+ return buildDecision(node, prefix, off, { n: 0 }, scoped);
884
896
  };
885
897
  const collectConditions = (node, currentTestStrings = []) => {
886
898
  const staticStyle = resolveStyleObject(node);
887
899
  if (staticStyle) {
888
900
  if (currentTestStrings.length === 0) {
889
901
  baseStyle = deepMerge(baseStyle, staticStyle);
902
+ baseChunks.push({ order: sourceOrder++, style: staticStyle });
890
903
  }
891
904
  else {
892
905
  conditionals.push({
@@ -895,6 +908,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
895
908
  truthy: staticStyle,
896
909
  falsy: {},
897
910
  varName: undefined,
911
+ order: sourceOrder++,
898
912
  });
899
913
  }
900
914
  return true;
@@ -911,6 +925,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
911
925
  truthy: trueStyle,
912
926
  falsy: falseStyle,
913
927
  varName: undefined,
928
+ order: sourceOrder++,
914
929
  });
915
930
  return true;
916
931
  }
@@ -962,6 +977,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
962
977
  }
963
978
  if (propPossibilities && propPossibilities.length > 0) {
964
979
  const currentGroupId = ++groupIdCounter;
980
+ const currentOrder = sourceOrder++;
965
981
  const uniqueEntries = [];
966
982
  propPossibilities.forEach((entry) => {
967
983
  if (!uniqueEntries.some((x) => x.key === entry.key)) {
@@ -976,6 +992,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
976
992
  truthy: entry.styleObj,
977
993
  falsy: {},
978
994
  groupId: currentGroupId,
995
+ order: currentOrder,
979
996
  groupName: undefined,
980
997
  valueName: entry.key,
981
998
  varName,
@@ -1032,11 +1049,18 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1032
1049
  if (!groupVariants)
1033
1050
  continue;
1034
1051
  const currentGroupId = ++groupIdCounter;
1052
+ const currentOrder = sourceOrder++;
1035
1053
  const valSource = getSource(valExpr);
1036
1054
  if (valExpr.type === 'StringLiteral') {
1037
1055
  const groupVariantsAsObj = groupVariants;
1038
- if (groupVariantsAsObj[valExpr.value])
1039
- baseStyle = deepMerge(baseStyle, groupVariantsAsObj[valExpr.value]);
1056
+ const picked = groupVariantsAsObj[valExpr.value];
1057
+ if (picked) {
1058
+ baseStyle = deepMerge(baseStyle, picked);
1059
+ baseChunks.push({
1060
+ order: sourceOrder++,
1061
+ style: picked,
1062
+ });
1063
+ }
1040
1064
  continue;
1041
1065
  }
1042
1066
  Object.entries(groupVariants).forEach(([optionName, style]) => {
@@ -1047,6 +1071,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1047
1071
  truthy: style,
1048
1072
  falsy: {},
1049
1073
  groupId: currentGroupId,
1074
+ order: currentOrder,
1050
1075
  groupName,
1051
1076
  valueName: optionName,
1052
1077
  varName,
@@ -1058,11 +1083,15 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1058
1083
  }
1059
1084
  const argSource = getSource(arg);
1060
1085
  if (t.isStringLiteral(arg)) {
1061
- if (variantObj[arg.value])
1062
- baseStyle = deepMerge(baseStyle, variantObj[arg.value]);
1086
+ const picked = variantObj[arg.value];
1087
+ if (picked) {
1088
+ baseStyle = deepMerge(baseStyle, picked);
1089
+ baseChunks.push({ order: sourceOrder++, style: picked });
1090
+ }
1063
1091
  continue;
1064
1092
  }
1065
1093
  const currentGroupId = ++groupIdCounter;
1094
+ const currentOrder = sourceOrder++;
1066
1095
  Object.entries(variantObj).forEach(([key, style]) => {
1067
1096
  conditionals.push({
1068
1097
  test: arg,
@@ -1071,6 +1100,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1071
1100
  truthy: style,
1072
1101
  falsy: {},
1073
1102
  groupId: currentGroupId,
1103
+ order: currentOrder,
1074
1104
  groupName: undefined,
1075
1105
  valueName: key,
1076
1106
  varName,
@@ -1098,6 +1128,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1098
1128
  if (!groupVariants)
1099
1129
  return;
1100
1130
  const currentGroupId = ++groupIdCounter;
1131
+ const currentOrder = sourceOrder++;
1101
1132
  Object.entries(groupVariants).forEach(([optionName, style]) => {
1102
1133
  conditionals.push({
1103
1134
  test: expr,
@@ -1106,6 +1137,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1106
1137
  truthy: style,
1107
1138
  falsy: {},
1108
1139
  groupId: currentGroupId,
1140
+ order: currentOrder,
1109
1141
  groupName,
1110
1142
  valueName: optionName,
1111
1143
  varName,
@@ -1124,6 +1156,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1124
1156
  const dynExpr = expr.property.expression;
1125
1157
  const dynSource = getSource(dynExpr);
1126
1158
  const currentGroupId = ++groupIdCounter;
1159
+ const currentOrder = sourceOrder++;
1127
1160
  Object.entries(styleObj).forEach(([optionName, style]) => {
1128
1161
  conditionals.push({
1129
1162
  test: dynExpr,
@@ -1132,9 +1165,11 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1132
1165
  truthy: style,
1133
1166
  falsy: {},
1134
1167
  groupId: currentGroupId,
1168
+ order: currentOrder,
1135
1169
  groupName: undefined,
1136
1170
  valueName: optionName,
1137
1171
  varName,
1172
+ ownKeys: true,
1138
1173
  });
1139
1174
  });
1140
1175
  continue;
@@ -1143,6 +1178,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1143
1178
  const decision = resolveDecision(expr);
1144
1179
  if (decision && (decision.hasGroup || decision.leaves > 2)) {
1145
1180
  const groupId = ++groupIdCounter;
1181
+ const currentOrder = sourceOrder++;
1146
1182
  decision.options.forEach(({ value, style }) => conditionals.push({
1147
1183
  test: expr,
1148
1184
  testLHS: decision.keyExpr,
@@ -1150,9 +1186,11 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1150
1186
  truthy: style,
1151
1187
  falsy: {},
1152
1188
  groupId,
1189
+ order: currentOrder,
1153
1190
  groupName: undefined,
1154
1191
  valueName: value,
1155
1192
  varName: undefined,
1193
+ ownKeys: true,
1156
1194
  }));
1157
1195
  continue;
1158
1196
  }
@@ -1306,17 +1344,38 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1306
1344
  });
1307
1345
  if (Object.keys(baseConflict).length > 0 ||
1308
1346
  conflictConditionals.length > 0) {
1309
- const dimensions = [];
1347
+ const ordered = [];
1348
+ baseChunks.forEach(({ order, style }) => {
1349
+ const conflicting = {};
1350
+ Object.entries(style).forEach(([key, value]) => {
1351
+ if (conflictingKeys.has(key))
1352
+ conflicting[key] = value;
1353
+ });
1354
+ if (Object.keys(conflicting).length === 0)
1355
+ return;
1356
+ ordered.push({
1357
+ order,
1358
+ dimension: {
1359
+ type: 'const',
1360
+ options: [
1361
+ { value: undefined, style: conflicting, label: 'base' },
1362
+ ],
1363
+ },
1364
+ });
1365
+ });
1310
1366
  conflictConditionals
1311
1367
  .filter((c) => c.groupId === undefined)
1312
1368
  .forEach((c) => {
1313
- dimensions.push({
1314
- type: 'std',
1315
- testExpr: c.testString ?? getSource(c.test),
1316
- options: [
1317
- { value: 0, style: c.falsy, label: 'false' },
1318
- { value: 1, style: c.truthy, label: 'true' },
1319
- ],
1369
+ ordered.push({
1370
+ order: c.order ?? 0,
1371
+ dimension: {
1372
+ type: 'std',
1373
+ testExpr: c.testString ?? getSource(c.test),
1374
+ options: [
1375
+ { value: 0, style: c.falsy, label: 'false' },
1376
+ { value: 1, style: c.truthy, label: 'true' },
1377
+ ],
1378
+ },
1320
1379
  });
1321
1380
  });
1322
1381
  const conflictVarGroups = {};
@@ -1337,17 +1396,34 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1337
1396
  opts.push({ ...off, truthy: {}, falsy: {} });
1338
1397
  });
1339
1398
  Object.entries(conflictVarGroups).forEach(([, opts]) => {
1340
- dimensions.push({
1341
- type: 'var',
1342
- testExpr: opts[0].testLHS ??
1343
- opts[0].testString ??
1344
- getSource(opts[0].test),
1345
- options: opts.map((opt) => ({
1346
- value: opt.valueName,
1347
- style: opt.truthy,
1348
- label: opt.valueName || 'default',
1349
- })),
1399
+ ordered.push({
1400
+ order: opts[0].order ?? 0,
1401
+ dimension: {
1402
+ type: 'var',
1403
+ testExpr: opts[0].testLHS ??
1404
+ opts[0].testString ??
1405
+ getSource(opts[0].test),
1406
+ options: opts.map((opt) => ({
1407
+ value: opt.valueName,
1408
+ style: opt.truthy,
1409
+ label: opt.valueName || 'default',
1410
+ })),
1411
+ ownKeys: opts[0].ownKeys,
1412
+ },
1413
+ });
1414
+ });
1415
+ ordered.sort((a, b) => a.order - b.order);
1416
+ const dimensions = ordered.map((o) => o.dimension);
1417
+ const joined = dimensions.filter((dim) => dim.type !== 'const').length > 1;
1418
+ dimensions.forEach((dim) => {
1419
+ if (!joined || dim.type !== 'var' || !dim.ownKeys)
1420
+ return;
1421
+ const numbers = {};
1422
+ dim.options.forEach((opt, index) => {
1423
+ numbers[String(opt.value)] = String(index);
1424
+ opt.value = String(index);
1350
1425
  });
1426
+ dim.testExpr = `(${JSON.stringify(numbers)}[${dim.testExpr}] || "")`;
1351
1427
  });
1352
1428
  const results = {};
1353
1429
  const recurse = (dimIndex, currentStyle, keyParts) => {
@@ -1359,18 +1435,19 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1359
1435
  results[keyParts.join('__')] = className;
1360
1436
  return;
1361
1437
  }
1362
- dimensions[dimIndex].options.forEach((opt) => recurse(dimIndex + 1, deepMerge(currentStyle, opt.style), [
1363
- ...keyParts,
1364
- String(opt.value),
1365
- ]));
1438
+ const dimension = dimensions[dimIndex];
1439
+ dimension.options.forEach((opt) => recurse(dimIndex + 1, deepMerge(currentStyle, opt.style), dimension.type === 'const'
1440
+ ? keyParts
1441
+ : [...keyParts, String(opt.value)]));
1366
1442
  };
1367
- recurse(0, baseConflict, []);
1443
+ recurse(0, {}, []);
1368
1444
  const baseConflictClass = Object.keys(baseConflict).length > 0
1369
1445
  ? processStyleRecords(baseConflict)
1370
1446
  .map((r) => r.hash)
1371
1447
  .join(' ')
1372
1448
  : '';
1373
1449
  const masterKeyExpr = dimensions
1450
+ .filter((dim) => dim.type !== 'const')
1374
1451
  .map((dim) => dim.type === 'std'
1375
1452
  ? `(${dim.testExpr} ? "1" : "0")`
1376
1453
  : dim.testExpr || '""')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plumeria/unplugin",
3
- "version": "18.1.0",
3
+ "version": "18.1.2",
4
4
  "description": "Universal Plumeria plugin for various build tools",
5
5
  "author": "Refirst 11",
6
6
  "license": "MIT",
@@ -89,7 +89,7 @@
89
89
  "dependencies": {
90
90
  "@rollup/pluginutils": "^5.4.0",
91
91
  "unplugin": "^3.0.0",
92
- "@plumeria/utils": "^18.1.0"
92
+ "@plumeria/utils": "^18.1.2"
93
93
  },
94
94
  "devDependencies": {
95
95
  "@swc/core": "1.15.43",