mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
Migrate data theme keys (#18816)
This PR is similar to and a follow up of #18815, but this time to migrate the `data` theme keys. Let's imagine you have the following Tailwind CSS v3 configuration: ```ts export default { content: ['./src/**/*.html'], theme: { extend: { data: { // Automatically handled by bare values foo: 'foo', // ^^^ ^^^ ← same names // Not automatically handled by bare values bar: 'baz', // ^^^ ^^^ ← different names // Completely custom checked: 'ui~="checked"', }, }, }, } ``` Then we would generate the following Tailwind CSS v4 CSS: ```css @custom-variant data-bar (&[data-baz]); @custom-variant data-checked (&[data-ui~="checked"]); ``` Notice how we didn't generate a custom variant for `data-foo` because those are automatically handled by bare values.
This commit is contained in:
parent
9e498a3e78
commit
82034ec327
@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Discard matched variants with non-string values ([#18799](https://github.com/tailwindlabs/tailwindcss/pull/18799))
|
||||
- Show suggestions for known `matchVariant` values ([#18798](https://github.com/tailwindlabs/tailwindcss/pull/18798))
|
||||
- Migrate `aria` theme keys to `@custom-variant` ([#18815](https://github.com/tailwindlabs/tailwindcss/pull/18815))
|
||||
- Migrate `data` theme keys to `@custom-variant` ([#18816](https://github.com/tailwindlabs/tailwindcss/pull/18816))
|
||||
|
||||
## [4.1.12] - 2025-08-13
|
||||
|
||||
|
||||
@ -1048,6 +1048,80 @@ test(
|
||||
},
|
||||
)
|
||||
|
||||
test(
|
||||
'migrate data theme keys to custom variants',
|
||||
{
|
||||
fs: {
|
||||
'package.json': json`
|
||||
{
|
||||
"dependencies": {
|
||||
"tailwindcss": "^3",
|
||||
"@tailwindcss/upgrade": "workspace:^"
|
||||
}
|
||||
}
|
||||
`,
|
||||
'tailwind.config.ts': ts`
|
||||
export default {
|
||||
content: {
|
||||
relative: true,
|
||||
files: ['./src/**/*.html'],
|
||||
},
|
||||
theme: {
|
||||
extend: {
|
||||
data: {
|
||||
// Automatically handled by bare values
|
||||
foo: 'foo',
|
||||
|
||||
// Not automatically handled by bare values because names differ
|
||||
bar: 'baz',
|
||||
|
||||
// Custom
|
||||
checked: 'ui~="checked"',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`,
|
||||
'src/input.css': css`
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
`,
|
||||
},
|
||||
},
|
||||
async ({ exec, fs, expect }) => {
|
||||
await exec('npx @tailwindcss/upgrade')
|
||||
|
||||
expect(await fs.dumpFiles('src/*.css')).toMatchInlineSnapshot(`
|
||||
"
|
||||
--- src/input.css ---
|
||||
@import 'tailwindcss';
|
||||
|
||||
@custom-variant data-bar (&[data-baz]);
|
||||
@custom-variant data-checked (&[data-ui~="checked"]);
|
||||
|
||||
/*
|
||||
The default border color has changed to \`currentcolor\` in Tailwind CSS v4,
|
||||
so we've added these compatibility styles to make sure everything still
|
||||
looks the same as it did with Tailwind CSS v3.
|
||||
|
||||
If we ever want to remove these styles, we need to add an explicit border
|
||||
color utility to any element that depends on these defaults.
|
||||
*/
|
||||
@layer base {
|
||||
*,
|
||||
::after,
|
||||
::before,
|
||||
::backdrop,
|
||||
::file-selector-button {
|
||||
border-color: var(--color-gray-200, currentcolor);
|
||||
}
|
||||
}
|
||||
"
|
||||
`)
|
||||
},
|
||||
)
|
||||
|
||||
describe('border compatibility', () => {
|
||||
test(
|
||||
'migrate border compatibility',
|
||||
|
||||
@ -152,6 +152,18 @@ async function migrateTheme(
|
||||
}
|
||||
delete resolvedConfig.theme.aria
|
||||
}
|
||||
|
||||
if ('data' in resolvedConfig.theme) {
|
||||
for (let [key, value] of Object.entries(resolvedConfig.theme.data ?? {})) {
|
||||
// Will be handled by bare values if the names match.
|
||||
// E.g.: `data-foo:flex` should produce `[data-foo]`
|
||||
if (key === value) continue
|
||||
|
||||
// Create custom variant
|
||||
variants.set(`data-${key}`, `&[data-${value}]`)
|
||||
}
|
||||
delete resolvedConfig.theme.data
|
||||
}
|
||||
}
|
||||
|
||||
// Convert theme values to CSS custom properties
|
||||
@ -223,7 +235,13 @@ async function migrateTheme(
|
||||
|
||||
if (variants.size > 0) {
|
||||
css += '\n@tw-bucket custom-variant {\n'
|
||||
|
||||
let previousRoot = ''
|
||||
for (let [name, selector] of variants) {
|
||||
let root = name.split('-')[0]
|
||||
if (previousRoot !== root) css += '\n'
|
||||
previousRoot = root
|
||||
|
||||
css += `@custom-variant ${name} (${selector});\n`
|
||||
}
|
||||
css += '}\n'
|
||||
@ -389,7 +407,7 @@ const ALLOWED_THEME_KEYS = [
|
||||
// Used by @tailwindcss/container-queries
|
||||
'containers',
|
||||
]
|
||||
const BLOCKED_THEME_KEYS = ['supports', 'data']
|
||||
const BLOCKED_THEME_KEYS = ['supports']
|
||||
function onlyAllowedThemeValues(theme: ThemeConfig): boolean {
|
||||
for (let key of Object.keys(theme)) {
|
||||
if (!ALLOWED_THEME_KEYS.includes(key)) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user