diff --git a/src/__tests__/compiler/compiler.test.tsx b/src/__tests__/compiler/compiler.test.tsx index b08e24c3..3dfabb32 100644 --- a/src/__tests__/compiler/compiler.test.tsx +++ b/src/__tests__/compiler/compiler.test.tsx @@ -77,6 +77,29 @@ test(":root CSS variables with media queries", () => { }); }); +test("every read of a stylesheet lists each variable's most specific value first", () => { + const compiled = compile( + `:root { --tone: red; } + @media (prefers-color-scheme: dark) { :root { --tone: blue; } } + * { --gap: 1px; } + @media (min-width: 100px) { * { --gap: 2px; } }`, + { inlineVariables: false }, + ); + const expected = { + vr: [ + ["tone", [["blue", [["=", "prefers-color-scheme", "dark"]]], ["red"]]], + ], + vu: [["gap", [[2, [[">=", "width", 100]]], [1]]]], + }; + + const first = compiled.stylesheet(); + expect({ vr: first.vr, vu: first.vu }).toStrictEqual(expected); + + const second = compiled.stylesheet(); + expect({ vr: second.vr, vu: second.vu }).toStrictEqual(expected); + expect({ vr: first.vr, vu: first.vu }).toStrictEqual(expected); +}); + test("removes unused CSS variables while preserving the resolved value", () => { const result = compile( `.test { --blue: blue; --green: green; --red: red; color: var(--red, var(--blue)); }`, diff --git a/src/compiler/stylesheet.ts b/src/compiler/stylesheet.ts index a77fdf89..23108523 100644 --- a/src/compiler/stylesheet.ts +++ b/src/compiler/stylesheet.ts @@ -161,15 +161,15 @@ export class StylesheetBuilder { if (this.shared.rootVariables) { stylesheetOptions.vr = Object.entries(this.shared.rootVariables).map( - // Reverse these so the most specific variables are first - ([key, value]) => [key, value.reverse()] as const, + // Most specific first, on a copy: the builder can be read again + ([key, value]) => [key, value.toReversed()] as const, ); } if (this.shared.universalVariables) { stylesheetOptions.vu = Object.entries(this.shared.universalVariables).map( - // Reverse these so the most specific variables are first - ([key, value]) => [key, value.reverse()] as const, + // Most specific first, on a copy: the builder can be read again + ([key, value]) => [key, value.toReversed()] as const, ); }