cursedbelt 5.7.1 → 5.7.3
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cursedbelt",
|
|
3
|
-
"version": "5.7.
|
|
3
|
+
"version": "5.7.3",
|
|
4
4
|
"license": "ISC",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "The React design system of the cursedbelt split — components, styles, theme. cursedbelt-core below it; server tier in cursedbelt-server.",
|
|
@@ -693,7 +693,7 @@
|
|
|
693
693
|
"@vidstack/react": "1.15.6",
|
|
694
694
|
"@vitejs/plugin-react": "^5.2.0",
|
|
695
695
|
"cursedbelt-server": "^4.13.0",
|
|
696
|
-
"cursedops": "^0.
|
|
696
|
+
"cursedops": "^0.8.1",
|
|
697
697
|
"diff": "^9.0.0",
|
|
698
698
|
"emoji-mart": "^5.6.0",
|
|
699
699
|
"hls.js": "^1.5.0",
|
|
@@ -75,7 +75,7 @@ describe('checkAreaStyles', () => {
|
|
|
75
75
|
const js = [`const a="flex rounded-full";const b=\`recharts-tip \${x}\`;`];
|
|
76
76
|
const css = [`.flex{display:flex}.rounded-full{border-radius:9999px}`];
|
|
77
77
|
const result = checkAreaStyles({ js, css }, BELT);
|
|
78
|
-
expect(result.missing).toEqual([{ className: 'recharts-tip', area: 'charts' }]);
|
|
78
|
+
expect(result.missing).toEqual([{ className: 'recharts-tip', area: 'charts', areas: ['charts'] }]);
|
|
79
79
|
expect(result.referenced).toBe(3);
|
|
80
80
|
});
|
|
81
81
|
|
|
@@ -177,7 +177,23 @@ describe('an area is `@source inline` candidates since 5.1.0 (task 2124)', () =>
|
|
|
177
177
|
const belt = readBeltSheets();
|
|
178
178
|
expect(inlineCandidatesIn(belt.areas.core ?? '').size).toBeGreaterThan(400);
|
|
179
179
|
const { missing } = checkAreaStyles({ js: ['x("truncate")'], css: [''] }, belt);
|
|
180
|
-
expect(missing).toEqual([{ className: 'truncate', area: 'core' }]);
|
|
180
|
+
expect(missing).toEqual([{ className: 'truncate', area: 'core', areas: ['core'] }]);
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
describe('🔴 a class two areas carry names BOTH (5.7.2)', () => {
|
|
185
|
+
test("station's `min-w-40`: `media` AND `workbench`, not just the alphabetically first", () => {
|
|
186
|
+
// Measured 2026-09-24: station adopted `ListToolbar` (a `workbench` module), its gate went red
|
|
187
|
+
// on `min-w-40`, and the fix this printed was `media.css` — an area station renders nothing from.
|
|
188
|
+
const { missing } = checkAreaStyles({ js: ['x("min-w-40")'], css: [''] }, readBeltSheets());
|
|
189
|
+
expect(missing).toHaveLength(1);
|
|
190
|
+
expect(missing[0]?.areas).toContain('media');
|
|
191
|
+
expect(missing[0]?.areas).toContain('workbench');
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
test('the areas are sorted and never repeat — whatever order the sheets were read in', () => {
|
|
195
|
+
const belt = { union: '.w-1{width:1px}', areas: { zeta: '@source inline("w-1");\n.w-1{width:1px}', alpha: '@source inline("w-1");' } };
|
|
196
|
+
expect(checkAreaStyles({ js: ['x("w-1")'], css: [''] }, belt).missing).toEqual([{ className: 'w-1', area: 'alpha', areas: ['alpha', 'zeta'] }]);
|
|
181
197
|
});
|
|
182
198
|
});
|
|
183
199
|
|
|
@@ -476,8 +476,13 @@ function filesUnder(dir: string, ext: string, out: string[] = []): string[] {
|
|
|
476
476
|
}
|
|
477
477
|
|
|
478
478
|
export interface AreaCheckResult {
|
|
479
|
-
/**
|
|
480
|
-
|
|
479
|
+
/**
|
|
480
|
+
* Belt classes the JS uses and the CSS does not style → the areas that carry each. `areas` is
|
|
481
|
+
* EVERY area whose sheet carries the class, sorted; `area` is the first of them. 🔴 Name them all:
|
|
482
|
+
* `min-w-40` is in both `media` and `workbench`, and until 5.7.2 this said only `media` —
|
|
483
|
+
* the wrong advice for station, whose `min-w-40` came from `ListToolbar` (a `workbench` module).
|
|
484
|
+
*/
|
|
485
|
+
missing: { className: string; area: string; areas: string[] }[];
|
|
481
486
|
jsFiles: number;
|
|
482
487
|
cssFiles: number;
|
|
483
488
|
/** How many belt classes the JS references — a zero here means the check saw nothing. */
|
|
@@ -494,9 +499,9 @@ export function checkAreaStyles(
|
|
|
494
499
|
belt: { union: string; areas: Record<string, string> },
|
|
495
500
|
): Omit<AreaCheckResult, 'jsFiles' | 'cssFiles' | 'outOfOrder' | 'undefinedVariables'> {
|
|
496
501
|
const union = classesInCss(belt.union);
|
|
497
|
-
const areaOf = new Map<string, string>();
|
|
498
|
-
for (const [area, css] of Object.entries(belt.areas)) {
|
|
499
|
-
for (const name of [...classesInCss(css), ...inlineCandidatesIn(css)])
|
|
502
|
+
const areaOf = new Map<string, string[]>();
|
|
503
|
+
for (const [area, css] of Object.entries(belt.areas).sort(([a], [b]) => a.localeCompare(b))) {
|
|
504
|
+
for (const name of new Set([...classesInCss(css), ...inlineCandidatesIn(css)])) areaOf.set(name, [...(areaOf.get(name) ?? []), area]);
|
|
500
505
|
}
|
|
501
506
|
const emitted = new Set<string>();
|
|
502
507
|
for (const css of input.css) for (const name of classesInCss(css)) emitted.add(name);
|
|
@@ -507,7 +512,10 @@ export function checkAreaStyles(
|
|
|
507
512
|
.filter((name) => !emitted.has(name))
|
|
508
513
|
.filter((name) => !onlyInMergeTables(name, allJs) && !onlyAsPropertyName(name, allJs))
|
|
509
514
|
.sort()
|
|
510
|
-
.map((className) =>
|
|
515
|
+
.map((className) => {
|
|
516
|
+
const areas = areaOf.get(className) as string[];
|
|
517
|
+
return { className, area: areas[0] as string, areas };
|
|
518
|
+
});
|
|
511
519
|
return { missing, referenced: referenced.size };
|
|
512
520
|
}
|
|
513
521
|
|
|
@@ -595,9 +603,14 @@ if (import.meta.main) {
|
|
|
595
603
|
process.exit(0);
|
|
596
604
|
}
|
|
597
605
|
const byArea = new Map<string, string[]>();
|
|
598
|
-
for (const { className,
|
|
606
|
+
for (const { className, areas } of result.missing) {
|
|
607
|
+
const key = areas.map((a) => `${a}.css`).join(' | ');
|
|
608
|
+
byArea.set(key, [...(byArea.get(key) ?? []), className]);
|
|
609
|
+
}
|
|
599
610
|
console.error(`✗ ${result.missing.length} cursedbelt class(es) the built JS uses have NO rule in the built CSS.`);
|
|
600
|
-
console.error(' Import the area that carries them — `@import "cursedbelt/styles-areas/<area>.css"
|
|
601
|
-
|
|
611
|
+
console.error(' Import the area that carries them — `@import "cursedbelt/styles-areas/<area>.css";`.');
|
|
612
|
+
console.error(' Where a line names several (`a.css | b.css`), any one fixes it: import the area of the component you');
|
|
613
|
+
console.error(" mounted (scripts/styleAreas.ts says which that is) — not the first name, which is only alphabetical:");
|
|
614
|
+
for (const [areas, names] of [...byArea].sort()) console.error(` ${areas} ← ${names.slice(0, 8).join(' ')}${names.length > 8 ? ` … +${names.length - 8}` : ''}`);
|
|
602
615
|
process.exit(1);
|
|
603
616
|
}
|