diff --git a/src/shiki-style-to-class.test.ts b/src/shiki-style-to-class.test.ts index bfda4300..8126aa0f 100644 --- a/src/shiki-style-to-class.test.ts +++ b/src/shiki-style-to-class.test.ts @@ -70,6 +70,48 @@ describe("shikiStyleToClass", () => { expect(uniqueClasses.size).toBe(2); }); + it("emits CSS for reused colors on later code blocks", () => { + const transformer = shikiStyleToClass(); + + const style = + "color:light-dark(#D73A49, #F47067);--shiki-light:#D73A49;--shiki-dark:#F47067"; + + const firstRoot = makeRoot([{ style }]); + transformer.root.call({} as any, firstRoot as any); + + const firstSpan = firstRoot.children[0].children[0].children[0]; + const cls = firstSpan.properties.class; + + const secondRoot = makeRoot([{ style }]); + transformer.root.call({} as any, secondRoot as any); + + const secondPre = secondRoot.children[0]; + expect(secondPre.properties["data-shiki-css"]).toContain( + `.${cls}{${style}}`, + ); + }); + + it("canonicalizes CSS rule order for equivalent blocks", () => { + const transformer = shikiStyleToClass(); + + const style1 = + "color:light-dark(#D73A49, #F47067);--shiki-light:#D73A49;--shiki-dark:#F47067"; + const style2 = + "color:light-dark(#24292E, #ADBAC7);--shiki-light:#24292E;--shiki-dark:#ADBAC7"; + + const firstRoot = makeRoot([{ style: style1 }, { style: style2 }]); + transformer.root.call({} as any, firstRoot as any); + + const secondRoot = makeRoot([{ style: style2 }, { style: style1 }]); + transformer.root.call({} as any, secondRoot as any); + + const firstPre = firstRoot.children[0]; + const secondPre = secondRoot.children[0]; + expect(secondPre.properties["data-shiki-css"]).toBe( + firstPre.properties["data-shiki-css"], + ); + }); + it("preserves non-color style properties", () => { const transformer = shikiStyleToClass(); diff --git a/src/shiki-style-to-class.ts b/src/shiki-style-to-class.ts index 4943acba..b3c8f928 100644 --- a/src/shiki-style-to-class.ts +++ b/src/shiki-style-to-class.ts @@ -12,10 +12,11 @@ * * 1. BUILD TIME (Shiki transformer — `shikiStyleToClass`): * Runs during MDX compilation. Walks every token , extracts color - * styles into a global Map, replaces `style` with `class`, and stores - * the CSS rules as a `data-shiki-css` attribute on the
 element.
- *    Data attributes survive RSC serialization (raw