diff --git a/CHANGELOG.md b/CHANGELOG.md index cce3e765b638..22868c5c4863 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Ensure drop shadow utilities don't inherit unexpectedly ([#16471](https://github.com/tailwindlabs/tailwindcss/pull/16471)) - Export backwards compatible config and plugin types from `tailwindcss/plugin` ([#16505](https://github.com/tailwindlabs/tailwindcss/pull/16505)) - Upgrade: Report errors when updating dependencies ([#16504](https://github.com/tailwindlabs/tailwindcss/pull/16504)) +- Upgrade: Ensure a `darkMode` JS config setting with block syntax converts to use `@slot` ([#16507](https://github.com/tailwindlabs/tailwindcss/pull/16507)) ## [4.0.6] - 2025-02-10 diff --git a/integrations/upgrade/js-config.test.ts b/integrations/upgrade/js-config.test.ts index 8d61bc2853c6..b667a3f0940b 100644 --- a/integrations/upgrade/js-config.test.ts +++ b/integrations/upgrade/js-config.test.ts @@ -318,6 +318,14 @@ test( import customPlugin from './custom-plugin' export default { + darkMode: [ + 'variant', + [ + '@media not print { .dark & }', + '@media not eink { .dark & }', + '&:where(.dark, .dark *)', + ], + ], plugins: [ typography, customPlugin({ @@ -379,6 +387,22 @@ test( is-arr-mixed: null, true, false, 1234567, 1.35, 'foo', 'bar', 'true'; } + @custom-variant dark { + @media not print { + .dark & { + @slot; + } + } + @media not eink { + .dark & { + @slot; + } + } + &:where(.dark, .dark *) { + @slot; + } + } + /* The default border color has changed to \`currentColor\` in Tailwind CSS v4, so we've added these compatibility styles to make sure everything still diff --git a/packages/@tailwindcss-upgrade/src/migrate-js-config.ts b/packages/@tailwindcss-upgrade/src/migrate-js-config.ts index c05ee6babebe..ac0a71a15e4b 100644 --- a/packages/@tailwindcss-upgrade/src/migrate-js-config.ts +++ b/packages/@tailwindcss-upgrade/src/migrate-js-config.ts @@ -196,7 +196,7 @@ async function migrateTheme( } function migrateDarkMode(unresolvedConfig: Config & { darkMode: any }): string { - let variant: string = '' + let variant: string | string[] = '' let addVariant = (_name: string, _variant: string) => (variant = _variant) let config = () => unresolvedConfig.darkMode darkModePlugin({ config, addVariant }) @@ -204,7 +204,30 @@ function migrateDarkMode(unresolvedConfig: Config & { darkMode: any }): string { if (variant === '') { return '' } - return `\n@tw-bucket custom-variant {\n@custom-variant dark (${variant});\n}\n` + + if (!Array.isArray(variant)) { + variant = [variant] + } + + if (variant.length === 1 && !variant[0].includes('{')) { + return `\n@tw-bucket custom-variant {\n@custom-variant dark (${variant[0]});\n}\n` + } + + let customVariant = '' + for (let variantName of variant) { + // Convert to the block syntax if a block is used + if (variantName.includes('{')) { + customVariant += variantName.replace('}', '{ @slot }}') + '\n' + } else { + customVariant += variantName + '{ @slot }\n' + } + } + + if (customVariant !== '') { + return `\n@tw-bucket custom-variant {\n@custom-variant dark {${customVariant}};\n}\n` + } + + return '' } // Returns a string identifier used to section theme declarations