From 96fef8c148f58d6432481609ee420e7c94dfbd6c Mon Sep 17 00:00:00 2001 From: wotnak Date: Sun, 14 Sep 2025 12:26:59 +0200 Subject: [PATCH 1/3] feat(compileCss): use standard css layers for base tailwind styles --- src/assets.ts | 16 +++++++++ src/compile-css.test.ts | 15 ++++++++ src/compile-css.ts | 64 ++++++++++++++++++++++++++++++++--- src/types/tailwindcss-v4.d.ts | 12 ++++++- 4 files changed, 101 insertions(+), 6 deletions(-) create mode 100644 src/assets.ts create mode 100644 src/compile-css.test.ts diff --git a/src/assets.ts b/src/assets.ts new file mode 100644 index 0000000..76074e6 --- /dev/null +++ b/src/assets.ts @@ -0,0 +1,16 @@ +/** + * @see https://github.com/tailwindlabs/tailwindcss/blob/d0a1bd655bfcc51818d2ae064eddef14f4983f67/packages/%40tailwindcss-browser/src/assets.ts + */ +import index from "tailwindcss-v4/index.css"; +import preflight from "tailwindcss-v4/preflight.css"; +import theme from "tailwindcss-v4/theme.css"; +import utilities from "tailwindcss-v4/utilities.css"; + +const css = { + index, + preflight, + theme, + utilities, +}; + +export default { css }; diff --git a/src/compile-css.test.ts b/src/compile-css.test.ts new file mode 100644 index 0000000..c059ee5 --- /dev/null +++ b/src/compile-css.test.ts @@ -0,0 +1,15 @@ +import { expect, it } from "vitest"; +import compileCss from "./compile-css.js"; + +it("compiled css should contain standard tailwindcss layers", async () => { + const compiledCss = await compileCss([], "", { addPreflight: true }); + const standardLayers = ["theme", "base", "utilities"]; + standardLayers.forEach((layer) => { + expect(compiledCss).toContain(`@layer ${layer}`); + }); +}); + +it("compiled css should contain standard tailwindcss layers order declaration", async () => { + const compiledCss = await compileCss([], "", { addPreflight: true }); + expect(compiledCss).toContain("@layer theme, base, components, utilities;"); +}); diff --git a/src/compile-css.ts b/src/compile-css.ts index e906371..4ac88ec 100644 --- a/src/compile-css.ts +++ b/src/compile-css.ts @@ -1,8 +1,58 @@ import { compile as tailwindV4Compile } from "tailwindcss-v4"; -import tailwindV4PreflightCss from "tailwindcss-v4/preflight.css"; -import tailwindV4DefaultThemeCss from "tailwindcss-v4/theme.css"; +import assets from "./assets.js"; import extractImports from "./extract-imports.js"; +/** + * Same as loadStylesheet function from `@tailwindcss/browser`, + * but with instrumentation removed. + * + * @see https://github.com/tailwindlabs/tailwindcss/blob/d0a1bd655bfcc51818d2ae064eddef14f4983f67/packages/%40tailwindcss-browser/src/index.ts#L109 + */ +async function loadStylesheet(id: string, base: string) { + if (id === "tailwindcss") { + return { + path: "virtual:tailwindcss-v4/index.css", + base, + content: assets.css.index, + }; + } + if ( + id === "tailwindcss/preflight" || + id === "tailwindcss/preflight.css" || + id === "./preflight.css" + ) { + return { + path: "virtual:tailwindcss-v4/preflight.css", + base, + content: assets.css.preflight, + }; + } + if ( + id === "tailwindcss/theme" || + id === "tailwindcss/theme.css" || + id === "./theme.css" + ) { + return { + path: "virtual:tailwindcss-v4/theme.css", + base, + content: assets.css.theme, + }; + } + if ( + id === "tailwindcss/utilities" || + id === "tailwindcss/utilities.css" || + id === "./utilities.css" + ) { + return { + path: "virtual:tailwindcss-v4/utilities.css", + base, + content: assets.css.utilities, + }; + } + + throw new Error(`The browser build does not support @import for "${id}"`); +} + /** * Options for compiling CSS. * @see {compileCss} @@ -52,13 +102,17 @@ export default async function compileCss( const { cssWithoutImports: configurationCssWithoutImports, importRules } = extractImports(configurationCss); const { build } = await tailwindV4Compile( + // Since preflight can be disabled, we need to import each layer explicitly, + // instead of just `@import "tailwindcss"`. ` ${importRules} - ${addPreflight ? tailwindV4PreflightCss : ""} - ${tailwindV4DefaultThemeCss} + @layer theme, base, components, utilities; + @import "tailwindcss/theme.css" layer(theme); + ${addPreflight ? '@import "tailwindcss/preflight.css" layer(base);' : ""} + @import "tailwindcss/utilities.css" layer(utilities); ${configurationCssWithoutImports} - @tailwind utilities; `, + { loadStylesheet }, ); return build(classNameCandidates); } diff --git a/src/types/tailwindcss-v4.d.ts b/src/types/tailwindcss-v4.d.ts index dc3b843..e754f2e 100644 --- a/src/types/tailwindcss-v4.d.ts +++ b/src/types/tailwindcss-v4.d.ts @@ -1,4 +1,4 @@ -declare module "tailwindcss-v4/theme.css" { +declare module "tailwindcss-v4/index.css" { const content: string; export default content; } @@ -7,3 +7,13 @@ declare module "tailwindcss-v4/preflight.css" { const content: string; export default content; } + +declare module "tailwindcss-v4/theme.css" { + const content: string; + export default content; +} + +declare module "tailwindcss-v4/utilities.css" { + const content: string; + export default content; +} From 006b35001d466dd0d893beecb079d80c60d6ca6c Mon Sep 17 00:00:00 2001 From: Balint Kleri Date: Tue, 23 Sep 2025 13:47:26 +0200 Subject: [PATCH 2/3] fix: linting --- src/compile-css.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compile-css.ts b/src/compile-css.ts index 5ab13fd..54a4e7f 100644 --- a/src/compile-css.ts +++ b/src/compile-css.ts @@ -8,6 +8,7 @@ import extractImports from "./extract-imports.js"; * * @see https://github.com/tailwindlabs/tailwindcss/blob/d0a1bd655bfcc51818d2ae064eddef14f4983f67/packages/%40tailwindcss-browser/src/index.ts#L109 */ +// eslint-disable-next-line @typescript-eslint/require-await async function loadStylesheet(id: string, base: string) { if (id === "tailwindcss") { return { From 8bf87c92d0761f64b69733a8dff92d6e261d61cc Mon Sep 17 00:00:00 2001 From: Balint Kleri Date: Tue, 23 Sep 2025 13:50:02 +0200 Subject: [PATCH 3/3] chore: update links --- src/assets.ts | 2 +- src/compile-css.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/assets.ts b/src/assets.ts index 76074e6..1fe717d 100644 --- a/src/assets.ts +++ b/src/assets.ts @@ -1,5 +1,5 @@ /** - * @see https://github.com/tailwindlabs/tailwindcss/blob/d0a1bd655bfcc51818d2ae064eddef14f4983f67/packages/%40tailwindcss-browser/src/assets.ts + * @see https://github.com/tailwindlabs/tailwindcss/blob/v4.1.13/packages/%40tailwindcss-browser/src/assets.ts */ import index from "tailwindcss-v4/index.css"; import preflight from "tailwindcss-v4/preflight.css"; diff --git a/src/compile-css.ts b/src/compile-css.ts index 54a4e7f..c0ef0c2 100644 --- a/src/compile-css.ts +++ b/src/compile-css.ts @@ -6,7 +6,7 @@ import extractImports from "./extract-imports.js"; * Same as loadStylesheet function from `@tailwindcss/browser`, * but with instrumentation removed. * - * @see https://github.com/tailwindlabs/tailwindcss/blob/d0a1bd655bfcc51818d2ae064eddef14f4983f67/packages/%40tailwindcss-browser/src/index.ts#L109 + * @see https://github.com/tailwindlabs/tailwindcss/blob/v4.1.13/packages/%40tailwindcss-browser/src/index.ts#L109 */ // eslint-disable-next-line @typescript-eslint/require-await async function loadStylesheet(id: string, base: string) {