From a1ccadca9ad5d07fb9ee9b1ef03ac37bd859677f Mon Sep 17 00:00:00 2001 From: Philipp Spiess Date: Fri, 6 Sep 2024 17:35:53 +0200 Subject: [PATCH 1/3] Support CSS `theme()` functions inside `@custom-media` rules --- CHANGELOG.md | 4 ++ .../tailwindcss/src/css-functions.test.ts | 59 +++++++++++++++++++ packages/tailwindcss/src/css-functions.ts | 2 +- 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1089c156e854..7a79218591a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Support CSS `theme()` functions inside `@custom-media` rules + ### Fixed - Ensure there is always CLI feedback on save even when no new classes were found ([#14351](https://github.com/tailwindlabs/tailwindcss/pull/14351)) diff --git a/packages/tailwindcss/src/css-functions.test.ts b/packages/tailwindcss/src/css-functions.test.ts index f33be7fc0934..662844fdcf80 100644 --- a/packages/tailwindcss/src/css-functions.test.ts +++ b/packages/tailwindcss/src/css-functions.test.ts @@ -619,6 +619,65 @@ describe('theme function', () => { `) }) }) + + describe('in @custom-media queries', () => { + test('@custom-media --my-media (min-width:theme(breakpoint.md)) and (max-width: theme(--breakpoint-lg))', async () => { + expect( + await compileCss(css` + @theme { + --breakpoint-md: 48rem; + --breakpoint-lg: 64rem; + } + /* prettier-ignore */ + @custom-media --my-media (min-width:theme(breakpoint.md)) and (max-width: theme(--breakpoint-lg)); + @media (--my-media) { + .red { + color: red; + } + } + `), + ).toMatchInlineSnapshot(` + ":root { + --breakpoint-md: 48rem; + --breakpoint-lg: 64rem; + } + + @media (width >= 48rem) and (width <= 64rem) { + .red { + color: red; + } + }" + `) + }) + + test('@custom-media --my-media (width >= theme(breakpoint.md)) and (width { + expect( + await compileCss(css` + @theme { + --breakpoint-md: 48rem; + --breakpoint-lg: 64rem; + } + @custom-media --my-media (width >= theme(breakpoint.md)) and (width= 48rem) and (width < 64rem) { + .red { + color: red; + } + }" + `) + }) + }) }) describe('in plugins', () => { diff --git a/packages/tailwindcss/src/css-functions.ts b/packages/tailwindcss/src/css-functions.ts index 6dd68bab2d8c..e9f62a3fa628 100644 --- a/packages/tailwindcss/src/css-functions.ts +++ b/packages/tailwindcss/src/css-functions.ts @@ -17,7 +17,7 @@ export function substituteFunctions(ast: AstNode[], pluginApi: PluginAPI) { if (node.kind === 'rule') { if ( node.selector[0] === '@' && - node.selector.startsWith('@media ') && + (node.selector.startsWith('@media ') || node.selector.startsWith('@custom-media ')) && node.selector.includes(THEME_FUNCTION_INVOCATION) ) { node.selector = substituteFunctionsInValue(node.selector, pluginApi) From fd1b94f45a7e92787503fc0ed69e9818556c91b7 Mon Sep 17 00:00:00 2001 From: Philipp Spiess Date: Fri, 6 Sep 2024 17:36:44 +0200 Subject: [PATCH 2/3] Update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a79218591a8..7bce1ff2a591 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Support CSS `theme()` functions inside `@custom-media` rules +- Support CSS `theme()` functions inside `@custom-media` rules ([#14358])(https://github.com/tailwindlabs/tailwindcss/pull/14358) ### Fixed From 625393228f994c92d9546a9f448de08b23555547 Mon Sep 17 00:00:00 2001 From: Philipp Spiess Date: Fri, 6 Sep 2024 17:53:26 +0200 Subject: [PATCH 3/3] Extend support to `@container` and `@supports` --- CHANGELOG.md | 2 +- .../tailwindcss/src/css-functions.test.ts | 107 ++++++++++-------- packages/tailwindcss/src/css-functions.ts | 7 +- 3 files changed, 68 insertions(+), 48 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7bce1ff2a591..c5036c56e944 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Support CSS `theme()` functions inside `@custom-media` rules ([#14358])(https://github.com/tailwindlabs/tailwindcss/pull/14358) +- Support CSS `theme()` functions inside other `@custom-media`, `@container`, and `@supports` rules ([#14358])(https://github.com/tailwindlabs/tailwindcss/pull/14358) ### Fixed diff --git a/packages/tailwindcss/src/css-functions.test.ts b/packages/tailwindcss/src/css-functions.test.ts index 662844fdcf80..dbec81d3f973 100644 --- a/packages/tailwindcss/src/css-functions.test.ts +++ b/packages/tailwindcss/src/css-functions.test.ts @@ -620,63 +620,80 @@ describe('theme function', () => { }) }) - describe('in @custom-media queries', () => { - test('@custom-media --my-media (min-width:theme(breakpoint.md)) and (max-width: theme(--breakpoint-lg))', async () => { - expect( - await compileCss(css` - @theme { - --breakpoint-md: 48rem; - --breakpoint-lg: 64rem; - } - /* prettier-ignore */ - @custom-media --my-media (min-width:theme(breakpoint.md)) and (max-width: theme(--breakpoint-lg)); - @media (--my-media) { - .red { - color: red; - } - } - `), - ).toMatchInlineSnapshot(` - ":root { + test('@custom-media --my-media (min-width: theme(breakpoint.md))', async () => { + expect( + await compileCss(css` + @theme { --breakpoint-md: 48rem; - --breakpoint-lg: 64rem; } - - @media (width >= 48rem) and (width <= 64rem) { + @custom-media --my-media (min-width: theme(breakpoint.md)); + @media (--my-media) { .red { color: red; } - }" - `) - }) + } + `), + ).toMatchInlineSnapshot(` + ":root { + --breakpoint-md: 48rem; + } - test('@custom-media --my-media (width >= theme(breakpoint.md)) and (width { - expect( - await compileCss(css` - @theme { - --breakpoint-md: 48rem; - --breakpoint-lg: 64rem; - } - @custom-media --my-media (width >= theme(breakpoint.md)) and (width= 48rem) { + .red { + color: red; + } + }" + `) + }) + + test('@container (width > theme(breakpoint.md))', async () => { + expect( + await compileCss(css` + @theme { --breakpoint-md: 48rem; - --breakpoint-lg: 64rem; } + @container (width > theme(breakpoint.md)) { + .red { + color: red; + } + } + `), + ).toMatchInlineSnapshot(` + ":root { + --breakpoint-md: 48rem; + } - @media (width >= 48rem) and (width < 64rem) { + @container (width > 48rem) { + .red { + color: red; + } + }" + `) + }) + + test('@supports (text-stroke: theme(--font-size-xs))', async () => { + expect( + await compileCss(css` + @theme { + --font-size-xs: 0.75rem; + } + @supports (text-stroke: theme(--font-size-xs)) { .red { color: red; } - }" - `) - }) + } + `), + ).toMatchInlineSnapshot(` + ":root { + --font-size-xs: .75rem; + } + + @supports (text-stroke: 0.75rem) { + .red { + color: red; + } + }" + `) }) }) diff --git a/packages/tailwindcss/src/css-functions.ts b/packages/tailwindcss/src/css-functions.ts index e9f62a3fa628..0c87d8bc07c6 100644 --- a/packages/tailwindcss/src/css-functions.ts +++ b/packages/tailwindcss/src/css-functions.ts @@ -13,11 +13,14 @@ export function substituteFunctions(ast: AstNode[], pluginApi: PluginAPI) { return } - // Find @media rules + // Find at-rules rules if (node.kind === 'rule') { if ( node.selector[0] === '@' && - (node.selector.startsWith('@media ') || node.selector.startsWith('@custom-media ')) && + (node.selector.startsWith('@media ') || + node.selector.startsWith('@custom-media ') || + node.selector.startsWith('@container ') || + node.selector.startsWith('@supports ')) && node.selector.includes(THEME_FUNCTION_INVOCATION) ) { node.selector = substituteFunctionsInValue(node.selector, pluginApi)