diff --git a/CHANGELOG.md b/CHANGELOG.md index 356005dec84a..1dafd6313891 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -- Nothing yet! +### Changed + +- Bring back support for color opacity modifiers to read from `--opacity-*` theme values ([#14278](https://github.com/tailwindlabs/tailwindcss/pull/14278)) ## [4.0.0-alpha.34] - 2024-11-14 diff --git a/packages/tailwindcss/src/compile.ts b/packages/tailwindcss/src/compile.ts index 4d3ee5dd278e..81419ce77926 100644 --- a/packages/tailwindcss/src/compile.ts +++ b/packages/tailwindcss/src/compile.ts @@ -263,7 +263,7 @@ function compileBaseUtility(candidate: Candidate, designSystem: DesignSystem) { // Assumption: If an arbitrary property has a modifier, then we assume it // is an opacity modifier. if (candidate.modifier) { - value = asColor(value, candidate.modifier) + value = asColor(value, candidate.modifier, designSystem.theme) } if (value === null) return [] diff --git a/packages/tailwindcss/src/utilities.test.ts b/packages/tailwindcss/src/utilities.test.ts index 167f7feb9659..6c6808e97e85 100644 --- a/packages/tailwindcss/src/utilities.test.ts +++ b/packages/tailwindcss/src/utilities.test.ts @@ -10998,7 +10998,19 @@ test('bg', async () => { `, ['bg-current/half', 'bg-current/custom', '[color:red]/half'], ), - ).toEqual('') + ).toMatchInlineSnapshot(` + ".bg-current\\/custom { + background-color: color-mix(in oklch, currentColor var(--opacity-custom), transparent); + } + + .bg-current\\/half { + background-color: color-mix(in oklch, currentColor var(--opacity-half), transparent); + } + + .\\[color\\:red\\]\\/half { + color: color-mix(in oklch, red var(--opacity-half), transparent); + }" + `) }) test('from', async () => { diff --git a/packages/tailwindcss/src/utilities.ts b/packages/tailwindcss/src/utilities.ts index 0b93a10f7ca3..2e2397cae0af 100644 --- a/packages/tailwindcss/src/utilities.ts +++ b/packages/tailwindcss/src/utilities.ts @@ -124,13 +124,24 @@ export function withAlpha(value: string, alpha: string): string { /** * Resolve a color value + optional opacity modifier to a final color. */ -export function asColor(value: string, modifier: CandidateModifier | null): string | null { +export function asColor( + value: string, + modifier: CandidateModifier | null, + theme: Theme, +): string | null { if (!modifier) return value if (modifier.kind === 'arbitrary') { return withAlpha(value, modifier.value) } + // Check if the modifier exists in the `opacity` theme configuration and use + // that value if so. + let alpha = theme.resolve(modifier.value, ['--opacity']) + if (alpha) { + return withAlpha(value, alpha) + } + if (!isValidOpacityValue(modifier.value)) { return null } @@ -182,7 +193,7 @@ function resolveThemeColor( } } - return value ? asColor(value, candidate.modifier) : null + return value ? asColor(value, candidate.modifier, theme) : null } export function createUtilities(theme: Theme) { @@ -340,7 +351,7 @@ export function createUtilities(theme: Theme) { value = candidate.value.value // Apply an opacity modifier to the value if appropriate. - value = asColor(value, candidate.modifier) + value = asColor(value, candidate.modifier, theme) } else { value = resolveThemeColor(candidate, theme, desc.themeKeys) } @@ -2048,7 +2059,7 @@ export function createUtilities(theme: Theme) { return [borderProperties(), ...decls] } default: { - value = asColor(value, candidate.modifier) + value = asColor(value, candidate.modifier, theme) if (value === null) return return desc.color(value) @@ -2510,7 +2521,7 @@ export function createUtilities(theme: Theme) { return [decl('background-image', value)] } default: { - value = asColor(value, candidate.modifier) + value = asColor(value, candidate.modifier, theme) if (value === null) return return [decl('background-color', value)] @@ -2584,7 +2595,7 @@ export function createUtilities(theme: Theme) { return desc.position(value) } default: { - value = asColor(value, candidate.modifier) + value = asColor(value, candidate.modifier, theme) if (value === null) return return desc.color(value) @@ -2721,7 +2732,7 @@ export function createUtilities(theme: Theme) { if (!candidate.value) return if (candidate.value.kind === 'arbitrary') { - let value = asColor(candidate.value.value, candidate.modifier) + let value = asColor(candidate.value.value, candidate.modifier, theme) if (value === null) return return [decl('fill', value)] } @@ -2758,7 +2769,7 @@ export function createUtilities(theme: Theme) { return [decl('stroke-width', value)] } default: { - value = asColor(candidate.value.value, candidate.modifier) + value = asColor(candidate.value.value, candidate.modifier, theme) if (value === null) return return [decl('stroke', value)] @@ -3002,7 +3013,7 @@ export function createUtilities(theme: Theme) { return [decl('text-decoration-thickness', value)] } default: { - value = asColor(value, candidate.modifier) + value = asColor(value, candidate.modifier, theme) if (value === null) return return [decl('text-decoration-color', value)] @@ -3880,7 +3891,7 @@ export function createUtilities(theme: Theme) { ] } default: { - value = asColor(value, candidate.modifier) + value = asColor(value, candidate.modifier, theme) if (value === null) return return [decl('outline-color', value)] @@ -4017,7 +4028,7 @@ export function createUtilities(theme: Theme) { return [decl('font-size', value)] } default: { - value = asColor(value, candidate.modifier) + value = asColor(value, candidate.modifier, theme) if (value === null) return return [decl('color', value)] @@ -4151,7 +4162,7 @@ export function createUtilities(theme: Theme) { switch (type) { case 'color': { - value = asColor(value, candidate.modifier) + value = asColor(value, candidate.modifier, theme) if (value === null) return return [boxShadowProperties(), decl('--tw-shadow-color', value)] @@ -4243,7 +4254,7 @@ export function createUtilities(theme: Theme) { switch (type) { case 'color': { - value = asColor(value, candidate.modifier) + value = asColor(value, candidate.modifier, theme) if (value === null) return return [boxShadowProperties(), decl('--tw-inset-shadow-color', value)] @@ -4341,7 +4352,7 @@ export function createUtilities(theme: Theme) { ] } default: { - value = asColor(value, candidate.modifier) + value = asColor(value, candidate.modifier, theme) if (value === null) return return [decl('--tw-ring-color', value)] @@ -4414,7 +4425,7 @@ export function createUtilities(theme: Theme) { ] } default: { - value = asColor(value, candidate.modifier) + value = asColor(value, candidate.modifier, theme) if (value === null) return return [decl('--tw-inset-ring-color', value)] @@ -4478,7 +4489,7 @@ export function createUtilities(theme: Theme) { ] } default: { - value = asColor(value, candidate.modifier) + value = asColor(value, candidate.modifier, theme) if (value === null) return return [decl('--tw-ring-offset-color', value)]