diff --git a/CHANGELOG.md b/CHANGELOG.md index 04b99390a9d6..0c5773360d6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,7 +24,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Use the right import base path when using the CLI to reading files from stdin ([#14522](https://github.com/tailwindlabs/tailwindcss/pull/14522)) - Ensure that `@utility` is top-level and cannot be nested ([#14525](https://github.com/tailwindlabs/tailwindcss/pull/14525)) -- Editing imported CSS files should trigger a rebuild ([#14561](https://github.com/tailwindlabs/tailwindcss/pull/14561)) +- Ensure editing imported CSS files triggers a rebuild ([#14561](https://github.com/tailwindlabs/tailwindcss/pull/14561)) +- Ensure `@apply` and CSS functions work inside imported stylesheets ([#14576](https://github.com/tailwindlabs/tailwindcss/pull/14576)) - _Experimental_: Improve codemod output, keep CSS after last Tailwind directive unlayered ([#14512](https://github.com/tailwindlabs/tailwindcss/pull/14512)) - _Experimental_: Fix incorrect empty `layer()` at the end of `@import` at-rules when running codemods ([#14513](https://github.com/tailwindlabs/tailwindcss/pull/14513)) - _Experimental_: Do not wrap comment nodes in `@layer` when running codemods ([#14517](https://github.com/tailwindlabs/tailwindcss/pull/14517)) diff --git a/packages/tailwindcss/src/css-functions.test.ts b/packages/tailwindcss/src/css-functions.test.ts index 521f50009852..2e3e5f0aa378 100644 --- a/packages/tailwindcss/src/css-functions.test.ts +++ b/packages/tailwindcss/src/css-functions.test.ts @@ -901,3 +901,37 @@ describe('in JS config files', () => { `) }) }) + +test('replaces CSS theme() function with values inside imported stylesheets', async () => { + expect( + await compileCss( + css` + @theme { + --color-red-500: #f00; + } + @import './bar.css'; + `, + [], + { + async loadStylesheet() { + return { + base: '/bar.css', + content: css` + .red { + color: theme(colors.red.500); + } + `, + } + }, + }, + ), + ).toMatchInlineSnapshot(` + ":root { + --color-red-500: red; + } + + .red { + color: red; + }" + `) +}) diff --git a/packages/tailwindcss/src/index.test.ts b/packages/tailwindcss/src/index.test.ts index 06a81b2774d2..3eee033dd1aa 100644 --- a/packages/tailwindcss/src/index.test.ts +++ b/packages/tailwindcss/src/index.test.ts @@ -254,6 +254,34 @@ describe('@apply', () => { `) }) + it('should replace @apply with the correct result inside imported stylesheets', async () => { + expect( + await compileCss( + css` + @import './bar.css'; + @tailwind utilities; + `, + [], + { + async loadStylesheet() { + return { + base: '/bar.css', + content: css` + .foo { + @apply underline; + } + `, + } + }, + }, + ), + ).toMatchInlineSnapshot(` + ".foo { + text-decoration-line: underline; + }" + `) + }) + it('should @apply in order the utilities would be sorted in if they were used in HTML', async () => { expect( await compileCss(css` diff --git a/packages/tailwindcss/src/index.ts b/packages/tailwindcss/src/index.ts index 82c8203a5522..9f8968f269e2 100644 --- a/packages/tailwindcss/src/index.ts +++ b/packages/tailwindcss/src/index.ts @@ -16,7 +16,7 @@ import { applyCompatibilityHooks } from './compat/apply-compat-hooks' import type { UserConfig } from './compat/config/types' import { type Plugin } from './compat/plugin-api' import { compileCandidates } from './compile' -import { substituteFunctions, THEME_FUNCTION_INVOCATION } from './css-functions' +import { substituteFunctions } from './css-functions' import * as CSS from './css-parser' import { buildDesignSystem, type DesignSystem } from './design-system' import { Theme, ThemeOptions } from './theme' @@ -341,13 +341,9 @@ async function parseCss( } // Replace `@apply` rules with the actual utility classes. - if (css.includes('@apply')) { - substituteAtApply(ast, designSystem) - } + substituteAtApply(ast, designSystem) - if (css.includes(THEME_FUNCTION_INVOCATION)) { - substituteFunctions(ast, designSystem.resolveThemeValue) - } + substituteFunctions(ast, designSystem.resolveThemeValue) // Remove `@utility`, we couldn't replace it before yet because we had to // handle the nested `@apply` at-rules first. diff --git a/packages/tailwindcss/src/test-utils/run.ts b/packages/tailwindcss/src/test-utils/run.ts index d5fd54c03fbd..e8da80e3ade1 100644 --- a/packages/tailwindcss/src/test-utils/run.ts +++ b/packages/tailwindcss/src/test-utils/run.ts @@ -1,8 +1,8 @@ import { Features, transform } from 'lightningcss' import { compile } from '..' -export async function compileCss(css: string, candidates: string[] = []) { - let { build } = await compile(css) +export async function compileCss(css: string, candidates: string[] = [], options = {}) { + let { build } = await compile(css, options) return optimizeCss(build(candidates)).trim() }