Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
migrate supports theme key to @custom-variant
  • Loading branch information
RobinMalfait committed Aug 28, 2025
commit 331c7760492a2e567a8734c9ae18c5a0cb5ddd74
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
isValidOpacityValue,
isValidSpacingMultiplier,
} from '../../../../tailwindcss/src/utils/infer-data-type'
import * as ValueParser from '../../../../tailwindcss/src/value-parser'
import { findStaticPlugins, type StaticPluginOptions } from '../../utils/extract-static-plugins'
import { highlight, info, relative } from '../../utils/renderer'

Expand Down Expand Up @@ -164,6 +165,35 @@ async function migrateTheme(
}
delete resolvedConfig.theme.data
}

if ('supports' in resolvedConfig.theme) {
for (let [key, value] of Object.entries(resolvedConfig.theme.supports ?? {})) {
// Will be handled by bare values if the value of the declaration is a
// CSS variable.
let parsed = ValueParser.parse(`${value}`)

// Unwrap the parens, e.g.: `(foo: var(--bar))` → `foo: var(--bar)`
if (parsed.length === 1 && parsed[0].kind === 'function' && parsed[0].value === '') {
parsed = parsed[0].nodes
}

// Verify structure: `foo: var(--bar)`
// ^^^ ← must match the `key`
if (
parsed.length === 3 &&
parsed[0].kind === 'word' &&
parsed[0].value === key &&
parsed[2].kind === 'function' &&
parsed[2].value === 'var'
) {
continue
}

// Create custom variant
variants.set(`supports-${key}`, `{@supports(${value}){@slot;}}`)
}
delete resolvedConfig.theme.supports
}
}

// Convert theme values to CSS custom properties
Expand Down Expand Up @@ -242,7 +272,11 @@ async function migrateTheme(
if (previousRoot !== root) css += '\n'
previousRoot = root

css += `@custom-variant ${name} (${selector});\n`
if (selector.startsWith('{')) {
css += `@custom-variant ${name} ${selector}\n`
} else {
css += `@custom-variant ${name} (${selector});\n`
}
}
css += '}\n'
}
Expand Down Expand Up @@ -407,15 +441,11 @@ const ALLOWED_THEME_KEYS = [
// Used by @tailwindcss/container-queries
'containers',
]
const BLOCKED_THEME_KEYS = ['supports']
function onlyAllowedThemeValues(theme: ThemeConfig): boolean {
for (let key of Object.keys(theme)) {
if (!ALLOWED_THEME_KEYS.includes(key)) {
return false
}
if (BLOCKED_THEME_KEYS.includes(key)) {
return false
}
Comment on lines -416 to -418
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👋 bye bye blocked theme keys

We still have aria, data and supports handling in: https://github.com/tailwindlabs/tailwindcss/blob/feat%2Fupgrade-supports-theme/packages/tailwindcss/src/compat/theme-variants.ts

This is still necessary in case the config file could not be migrated due to other issues. So didn't get rid of that part.

}

if ('screens' in theme && typeof theme.screens === 'object' && theme.screens !== null) {
Expand Down