Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Support using CSS variables as arbitrary values without `var(…)` by using parentheses instead of square brackets (e.g. `bg-(--my-color)`) ([#15020](https://github.com/tailwindlabs/tailwindcss/pull/15020))
- Add new `in-*` variant ([#15025](https://github.com/tailwindlabs/tailwindcss/pull/15025))
- Allow `addUtilities()` and `addComponents()` to work with child combinators and other complex selectors ([#15029](https://github.com/tailwindlabs/tailwindcss/pull/15029))
- Support colors that use `<alpha-value>` in JS configs and plugins ([#15033](https://github.com/tailwindlabs/tailwindcss/pull/15033))
- _Upgrade (experimental)_: Migrate `[&>*]` to the `*` variant ([#15022](https://github.com/tailwindlabs/tailwindcss/pull/15022))
- _Upgrade (experimental)_: Migrate `[&_*]` to the `**` variant ([#15022](https://github.com/tailwindlabs/tailwindcss/pull/15022))
- _Upgrade (experimental)_: Warn when trying to migrating a project that is not on Tailwind CSS v3 ([#15015](https://github.com/tailwindlabs/tailwindcss/pull/15015))
- _Upgrade (experimental)_: Migrate colors that use `<alpha-value>` in JS configs ([#15033](https://github.com/tailwindlabs/tailwindcss/pull/15033))

### Fixed

Expand Down
5 changes: 5 additions & 0 deletions integrations/upgrade/js-config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ test(
400: '#f87171',
500: 'red',
},
steel: 'rgb(70 130 180 / <alpha-value>)',
smoke: 'rgba(245, 245, 245, var(--smoke-alpha, <alpha-value>))',
},
fontSize: {
xs: ['0.75rem', { lineHeight: '1rem' }],
Expand Down Expand Up @@ -175,6 +177,9 @@ test(
--color-red-500: #ef4444;
--color-red-600: #dc2626;

--color-steel: rgb(70 130 180);
--color-smoke: rgba(245, 245, 245, var(--smoke-alpha, 1));

--text-*: initial;
--text-xs: 0.75rem;
--text-xs--line-height: 1rem;
Expand Down
10 changes: 10 additions & 0 deletions packages/@tailwindcss-upgrade/src/migrate-js-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,16 @@ async function migrateTheme(
continue
}

if (typeof value === 'string') {
// This is more advanced than the version in core as ideally something
// like `rgba(0 0 0 / <alpha-value>)` becomes `rgba(0 0 0)`. Since we know
// from the `/` that it's used in an alpha channel and we can remove it.
//
// In other cases we may not know exactly how its used, so we'll just
// replace it with `1` like core does.
value = value.replace(/\s*\/\s*<alpha-value>/, '').replace(/<alpha-value>/, '1')
}

if (key[0] === 'keyframes') {
continue
}
Expand Down
4 changes: 4 additions & 0 deletions packages/tailwindcss/src/compat/apply-config-to-theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ export function applyConfigToTheme(
continue
}

if (typeof value === 'string') {
value = value.replace(/<alpha-value>/g, '1')
}

let name = keyPathToCssProperty(path)
if (!name) continue

Expand Down
87 changes: 87 additions & 0 deletions packages/tailwindcss/src/compat/plugin-api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,93 @@ describe('theme', async () => {
"
`)
})

test('plugin theme colors can use <alpha-value>', async () => {
let input = css`
@tailwind utilities;
@theme {
/* This should not work */
--color-custom-css: rgba(255 0 0 / <alpha-value>);
}
@plugin "my-plugin";
`

let compiler = await compile(input, {
loadModule: async (id, base) => {
return {
base,
module: plugin(
function ({ addUtilities, theme }) {
addUtilities({
'.css-percentage': {
color: theme('colors.custom-css / 50%'),
},
'.css-fraction': {
color: theme('colors.custom-css / 0.5'),
},
'.css-variable': {
color: theme('colors.custom-css / var(--opacity)'),
},
'.js-percentage': {
color: theme('colors.custom-js / 50%'),
},
'.js-fraction': {
color: theme('colors.custom-js / 0.5'),
},
'.js-variable': {
color: theme('colors.custom-js / var(--opacity)'),
},
})
},
{
theme: {
colors: {
/* This should work */
'custom-js': 'rgb(255 0 0 / <alpha-value>)',
},
},
},
),
}
},
})

expect(
compiler.build([
'bg-custom',
'css-percentage',
'css-fraction',
'css-variable',
'js-percentage',
'js-fraction',
'js-variable',
]),
).toMatchInlineSnapshot(`
".css-fraction {
color: color-mix(in oklch, rgba(255 0 0 / <alpha-value>) 50%, transparent);
}
.css-percentage {
color: color-mix(in oklch, rgba(255 0 0 / <alpha-value>) 50%, transparent);
}
.css-variable {
color: color-mix(in oklch, rgba(255 0 0 / <alpha-value>) var(--opacity), transparent);
}
.js-fraction {
color: color-mix(in oklch, rgb(255 0 0 / 1) 50%, transparent);
}
.js-percentage {
color: color-mix(in oklch, rgb(255 0 0 / 1) 50%, transparent);
}
.js-variable {
color: color-mix(in oklch, rgb(255 0 0 / 1) var(--opacity), transparent);
}
:root {
--color-custom-css: rgba(255 0 0 / <alpha-value>);
}
"
`)
})

test('theme value functions are resolved correctly regardless of order', async () => {
let input = css`
@tailwind utilities;
Expand Down
4 changes: 4 additions & 0 deletions packages/tailwindcss/src/compat/plugin-functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ export function createThemeFn(

let configValue = resolveValue(get(configTheme() ?? {}, keypath) ?? null)

if (typeof configValue === 'string') {
configValue = configValue.replace('<alpha-value>', '1')
}

// Resolved to a primitive value.
if (typeof cssValue !== 'object') {
if (typeof options !== 'object' && options & ThemeOptions.DEFAULT) {
Expand Down