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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Pass options when using `addComponents` and `matchComponents` ([#14590](https://github.com/tailwindlabs/tailwindcss/pull/14590))
- Ensure `boxShadow` and `animation` theme keys in JS config files are accessible under `--shadow-*` and `--animate-*` using the `theme()` function ([#14642](https://github.com/tailwindlabs/tailwindcss/pull/14642))
- Ensure all theme keys with new names are also accessible under their old names when using the `theme()` function with the legacy dot notation syntax ([#14642](https://github.com/tailwindlabs/tailwindcss/pull/14642))
- Ensure `var(…)` can be used as the opacity value inside the `theme([path] / [modifier])` function ([#14653](https://github.com/tailwindlabs/tailwindcss/pull/14653))
- _Upgrade (experimental)_: Ensure CSS before a layer stays unlayered when running codemods ([#14596](https://github.com/tailwindlabs/tailwindcss/pull/14596))
- _Upgrade (experimental)_: Resolve issues where some prefixed candidates were not properly migrated ([#14600](https://github.com/tailwindlabs/tailwindcss/pull/14600))

Expand Down
64 changes: 64 additions & 0 deletions packages/tailwindcss/src/css-functions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,27 @@ describe('theme function', () => {
`)
})

test('theme(colors.red.500/75%)', async () => {
Copy link
Member Author

Choose a reason for hiding this comment

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

Same test as below, but without spaces. Already worked, but added for completeness sake.

expect(
await compileCss(css`
@theme {
--color-red-500: #f00;
}
.red {
color: theme(colors.red.500/75%);
}
`),
).toMatchInlineSnapshot(`
":root {
--color-red-500: red;
}

.red {
color: #ff0000bf;
}"
`)
})

test('theme(colors.red.500 / 75%)', async () => {
expect(
await compileCss(css`
Expand Down Expand Up @@ -178,6 +199,49 @@ describe('theme function', () => {
`)
})

test('theme(colors.red.500/var(--opacity))', async () => {
expect(
await compileCss(css`
@theme {
--color-red-500: #f00;
}
.red {
color: theme(colors.red.500/var(--opacity));
}
`),
).toMatchInlineSnapshot(`
":root {
--color-red-500: red;
}

.red {
color: color-mix(in srgb, red calc(var(--opacity) * 100%), transparent);
}"
`)
})

test('theme(colors.red.500/var(--opacity,50%))', async () => {
expect(
await compileCss(css`
@theme {
--color-red-500: #f00;
}
.red {
/* prettier-ignore */
color: theme(colors.red.500/var(--opacity,50%));
Copy link
Member Author

Choose a reason for hiding this comment

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

Prettier injected a space var(--opacity, 50%), but explicitly didn't want it so I added the prettier-ignore comment.

}
`),
).toMatchInlineSnapshot(`
":root {
--color-red-500: red;
}

.red {
color: color-mix(in srgb, red calc(var(--opacity, 50%) * 100%), transparent);
}"
`)
})

test('theme(spacing.12)', async () => {
expect(
await compileCss(css`
Expand Down
2 changes: 1 addition & 1 deletion packages/tailwindcss/src/css-functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export function substituteFunctionsInValue(
if (node.nodes[i].value.includes(',')) {
break
}
path += node.nodes[i].value
path += ValueParser.toCss([node.nodes[i]])
skipUntilIndex = i + 1
}

Expand Down
14 changes: 14 additions & 0 deletions packages/tailwindcss/src/value-parser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,20 @@ describe('parse', () => {
])
})

it('should parse a function with nested arguments separated by `/`', () => {
expect(parse('theme(colors.red.500/var(--opacity))')).toEqual([
{
kind: 'function',
value: 'theme',
nodes: [
{ kind: 'word', value: 'colors.red.500' },
{ kind: 'separator', value: '/' },
{ kind: 'function', value: 'var', nodes: [{ kind: 'word', value: '--opacity' }] },
],
},
])
})

it('should handle calculations', () => {
expect(parse('calc((1 + 2) * 3)')).toEqual([
{
Expand Down
2 changes: 2 additions & 0 deletions packages/tailwindcss/src/value-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ const SPACE = 0x20
const LESS_THAN = 0x3c
const GREATER_THAN = 0x3e
const EQUALS = 0x3d
const SLASH = 0x2f

export function parse(input: string) {
input = input.replaceAll('\r\n', '\n')
Expand Down Expand Up @@ -143,6 +144,7 @@ export function parse(input: string) {
case COLON:
case COMMA:
case SPACE:
case SLASH:
case LESS_THAN:
case GREATER_THAN:
case EQUALS: {
Expand Down