Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
9 changes: 9 additions & 0 deletions integrations/upgrade/js-config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ test(
import customPlugin from './custom-plugin'

export default {
darkMode: ['variant', '@media not print { .dark & }'],
plugins: [
typography,
customPlugin({
Expand Down Expand Up @@ -379,6 +380,14 @@ test(
is-arr-mixed: null, true, false, 1234567, 1.35, 'foo', 'bar', 'true';
}

@custom-variant dark {
@media not print {
.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
Expand Down
25 changes: 23 additions & 2 deletions packages/@tailwindcss-upgrade/src/migrate-js-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,15 +196,36 @@ 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 })

if (variant === '') {
return ''
}
return `\n@tw-bucket custom-variant {\n@custom-variant dark (${variant});\n}\n`

if (!Array.isArray(variant)) {
variant = [variant]
}

let output = ''

for (let variantName of variant) {
if (variantName === 'class') {
continue
}

// Convert to the block syntax if a block is used
if (variantName.includes('{')) {
variantName = variantName.replace('}', '{ @slot }}')
output += `\n@tw-bucket custom-variant {\n@custom-variant dark {${variantName}}}\n`
} else {
output += `\n@tw-bucket custom-variant {\n@custom-variant dark (${variantName});\n}\n`
}
}

return output
Copy link
Contributor

Choose a reason for hiding this comment

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

Will this actually work with an array of format strings? @custom-variant overrides

Copy link
Member Author

Choose a reason for hiding this comment

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

ok i will be less lazy

}

// Returns a string identifier used to section theme declarations
Expand Down