@homebound/truss 2.29.3 → 2.29.5

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.
@@ -1102,7 +1102,7 @@ function segmentClassPrefix(condition, mapping) {
1102
1102
  }
1103
1103
  if (condition.mediaQuery) {
1104
1104
  const breakpoint = breakpointNameForMediaQuery(mapping, condition.mediaQuery);
1105
- parts.push(breakpoint ? `${breakpoint.toLowerCase()}_` : "mq_");
1105
+ parts.push(`${breakpoint ? breakpoint.toLowerCase() : sanitizeClassNameToken(condition.mediaQuery)}_`);
1106
1106
  }
1107
1107
  if (condition.pseudoClass) {
1108
1108
  parts.push(`${pseudoSelectorPrefix(condition.pseudoClass)}_`);
@@ -1327,7 +1327,9 @@ function typographyLookupKeySuffix(context, mapping) {
1327
1327
  if (context.pseudoElement) parts.push(context.pseudoElement.replace(/^::/, ""));
1328
1328
  if (context.mediaQuery) {
1329
1329
  const breakpoint = breakpointNameForMediaQuery(mapping, context.mediaQuery);
1330
- parts.push(breakpoint ? breakpoint.replace(/^./, (c) => c.toLowerCase()) : "mq");
1330
+ parts.push(
1331
+ breakpoint ? breakpoint.replace(/^./, (c) => c.toLowerCase()) : sanitizeClassNameToken(context.mediaQuery)
1332
+ );
1331
1333
  }
1332
1334
  if (context.pseudoClass) parts.push(context.pseudoClass.replace(/^:+/, "").replace(/-/g, "_"));
1333
1335
  if (context.whenPseudo) parts.push(whenLookupKeyPart(context.whenPseudo));
@@ -2426,18 +2428,56 @@ function computeRulePriority(rule) {
2426
2428
  function isVariableRule(rule) {
2427
2429
  return rule.declarations.some((d) => d.cssVarName !== void 0);
2428
2430
  }
2431
+ function ruleSortKey(priority, className, atRulePrelude2) {
2432
+ const widthInterval = atRulePrelude2 === void 0 ? null : parseWidthInterval(atRulePrelude2);
2433
+ return { priority, className, widthInterval };
2434
+ }
2435
+ function compareRuleSortKeys(a, b) {
2436
+ return a.priority - b.priority || compareWidthIntervals(a.widthInterval, b.widthInterval) || compareClassNames(a.className, b.className);
2437
+ }
2429
2438
  function sortRulesByPriority(rules) {
2430
2439
  const decorated = Array.from(rules, (rule) => {
2431
- return { rule, priority: computeRulePriority(rule) };
2432
- });
2433
- decorated.sort((a, b) => {
2434
- return a.priority - b.priority || compareClassNames(a.rule.className, b.rule.className);
2440
+ const priority = computeRulePriority(rule);
2441
+ return { rule, priority, key: ruleSortKey(priority, rule.className, rule.mediaQuery) };
2435
2442
  });
2436
- return decorated;
2443
+ decorated.sort((a, b) => compareRuleSortKeys(a.key, b.key));
2444
+ return decorated.map((d) => ({ rule: d.rule, priority: d.priority }));
2437
2445
  }
2438
2446
  function compareClassNames(a, b) {
2439
2447
  return a < b ? -1 : a > b ? 1 : 0;
2440
2448
  }
2449
+ function parseWidthInterval(prelude) {
2450
+ if (/,|\bnot\b|\bor\b|[<>]/.test(prelude)) return null;
2451
+ const terms = Array.from(prelude.matchAll(/\((min|max)-width:\s*([^)]*)\)/g));
2452
+ if (terms.length === 0) return null;
2453
+ let lo = 0;
2454
+ let hi = Infinity;
2455
+ for (const term of terms) {
2456
+ const px = parsePxLength(term[2]);
2457
+ if (px === null) return null;
2458
+ if (term[1] === "min") {
2459
+ lo = Math.max(lo, px);
2460
+ } else {
2461
+ hi = Math.min(hi, px);
2462
+ }
2463
+ }
2464
+ return { lo, hi };
2465
+ }
2466
+ function parsePxLength(value) {
2467
+ const match = value.trim().match(/^(\d+(?:\.\d+)?)(px)?$/);
2468
+ if (!match) return null;
2469
+ if (match[2] === void 0 && Number(match[1]) !== 0) return null;
2470
+ return Number(match[1]);
2471
+ }
2472
+ function compareWidthIntervals(a, b) {
2473
+ if (a === null || b === null) {
2474
+ return (a === null ? 1 : 0) - (b === null ? 1 : 0);
2475
+ }
2476
+ const widthA = a.hi - a.lo;
2477
+ const widthB = b.hi - b.lo;
2478
+ if (widthA !== widthB) return widthA > widthB ? -1 : 1;
2479
+ return a.lo - b.lo;
2480
+ }
2441
2481
 
2442
2482
  // src/plugin/emit-css.ts
2443
2483
  function collectAtomicRules(chains, mapping) {
@@ -3477,11 +3517,14 @@ function mergeTrussCss(sources) {
3477
3517
  }
3478
3518
  allArbitraryCssBlocks.push(...source.arbitraryCssBlocks);
3479
3519
  }
3480
- allRules.sort((a, b) => a.priority - b.priority || compareClassNames(a.className, b.className));
3520
+ const decorated = allRules.map((rule) => {
3521
+ return { rule, key: ruleSortKey(rule.priority, rule.className, atRulePrelude(rule.cssText)) };
3522
+ });
3523
+ decorated.sort((a, b) => compareRuleSortKeys(a.key, b.key));
3481
3524
  const lines = [];
3482
- for (const rule of allRules) {
3483
- lines.push(`/* @truss p:${rule.priority} c:${rule.className} */`);
3484
- lines.push(rule.cssText);
3525
+ for (const entry of decorated) {
3526
+ lines.push(`/* @truss p:${entry.rule.priority} c:${entry.rule.className} */`);
3527
+ lines.push(entry.rule.cssText);
3485
3528
  }
3486
3529
  for (const prop of allProperties) {
3487
3530
  lines.push(`/* @truss @property */`);
@@ -3492,6 +3535,11 @@ function mergeTrussCss(sources) {
3492
3535
  }
3493
3536
  return lines.join("\n");
3494
3537
  }
3538
+ function atRulePrelude(cssText) {
3539
+ if (!cssText.startsWith("@")) return void 0;
3540
+ const brace = cssText.indexOf("{");
3541
+ return brace === -1 ? void 0 : cssText.slice(0, brace).trim();
3542
+ }
3495
3543
 
3496
3544
  // src/plugin/transform-session.ts
3497
3545
  function createTrussTransformSession(options) {