mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
Support opacity values in increments of 0.25 by default (#14980)
This PR updates all areas in the framework that accept opacity values (`opacity-*`, `backdrop-opacity-*`, `bg-red-500/*`, etc.) to accept fractional values in increments of 0.25 instead of just whole numbers. We noticed we use values like `2.5` and `7.5` pretty regularly in our templates and don't see why those should be treated as any more "weird" than something like `opacity-63` which we already support, so baking this in to core. IntelliSense will still only suggest values in increments of `5` like it did before. --------- Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
This commit is contained in:
parent
437579d3f0
commit
5ce575a83c
@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
- Nothing yet!
|
||||
### Added
|
||||
|
||||
- Support opacity values in increments of `0.25` by default ([#14980](https://github.com/tailwindlabs/tailwindcss/pull/14980))
|
||||
|
||||
## [4.0.0-alpha.33] - 2024-11-11
|
||||
|
||||
|
||||
@ -98,6 +98,18 @@ exports[`border-* 1`] = `
|
||||
border-color: var(--color-red-500);
|
||||
}
|
||||
|
||||
.border-red-500\\/2\\.5 {
|
||||
border-color: color-mix(in oklch, var(--color-red-500) 2.5%, transparent);
|
||||
}
|
||||
|
||||
.border-red-500\\/2\\.25 {
|
||||
border-color: color-mix(in oklch, var(--color-red-500) 2.25%, transparent);
|
||||
}
|
||||
|
||||
.border-red-500\\/2\\.75 {
|
||||
border-color: color-mix(in oklch, var(--color-red-500) 2.75%, transparent);
|
||||
}
|
||||
|
||||
.border-red-500\\/50 {
|
||||
border-color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
|
||||
}
|
||||
@ -219,6 +231,18 @@ exports[`border-b-* 1`] = `
|
||||
border-bottom-color: var(--color-red-500);
|
||||
}
|
||||
|
||||
.border-b-red-500\\/2\\.5 {
|
||||
border-bottom-color: color-mix(in oklch, var(--color-red-500) 2.5%, transparent);
|
||||
}
|
||||
|
||||
.border-b-red-500\\/2\\.25 {
|
||||
border-bottom-color: color-mix(in oklch, var(--color-red-500) 2.25%, transparent);
|
||||
}
|
||||
|
||||
.border-b-red-500\\/2\\.75 {
|
||||
border-bottom-color: color-mix(in oklch, var(--color-red-500) 2.75%, transparent);
|
||||
}
|
||||
|
||||
.border-b-red-500\\/50 {
|
||||
border-bottom-color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
|
||||
}
|
||||
@ -340,6 +364,18 @@ exports[`border-e-* 1`] = `
|
||||
border-inline-end-color: var(--color-red-500);
|
||||
}
|
||||
|
||||
.border-e-red-500\\/2\\.5 {
|
||||
border-inline-end-color: color-mix(in oklch, var(--color-red-500) 2.5%, transparent);
|
||||
}
|
||||
|
||||
.border-e-red-500\\/2\\.25 {
|
||||
border-inline-end-color: color-mix(in oklch, var(--color-red-500) 2.25%, transparent);
|
||||
}
|
||||
|
||||
.border-e-red-500\\/2\\.75 {
|
||||
border-inline-end-color: color-mix(in oklch, var(--color-red-500) 2.75%, transparent);
|
||||
}
|
||||
|
||||
.border-e-red-500\\/50 {
|
||||
border-inline-end-color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
|
||||
}
|
||||
@ -461,6 +497,18 @@ exports[`border-l-* 1`] = `
|
||||
border-left-color: var(--color-red-500);
|
||||
}
|
||||
|
||||
.border-l-red-500\\/2\\.5 {
|
||||
border-left-color: color-mix(in oklch, var(--color-red-500) 2.5%, transparent);
|
||||
}
|
||||
|
||||
.border-l-red-500\\/2\\.25 {
|
||||
border-left-color: color-mix(in oklch, var(--color-red-500) 2.25%, transparent);
|
||||
}
|
||||
|
||||
.border-l-red-500\\/2\\.75 {
|
||||
border-left-color: color-mix(in oklch, var(--color-red-500) 2.75%, transparent);
|
||||
}
|
||||
|
||||
.border-l-red-500\\/50 {
|
||||
border-left-color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
|
||||
}
|
||||
@ -582,6 +630,18 @@ exports[`border-r-* 1`] = `
|
||||
border-right-color: var(--color-red-500);
|
||||
}
|
||||
|
||||
.border-r-red-500\\/2\\.5 {
|
||||
border-right-color: color-mix(in oklch, var(--color-red-500) 2.5%, transparent);
|
||||
}
|
||||
|
||||
.border-r-red-500\\/2\\.25 {
|
||||
border-right-color: color-mix(in oklch, var(--color-red-500) 2.25%, transparent);
|
||||
}
|
||||
|
||||
.border-r-red-500\\/2\\.75 {
|
||||
border-right-color: color-mix(in oklch, var(--color-red-500) 2.75%, transparent);
|
||||
}
|
||||
|
||||
.border-r-red-500\\/50 {
|
||||
border-right-color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
|
||||
}
|
||||
@ -703,6 +763,18 @@ exports[`border-s-* 1`] = `
|
||||
border-inline-start-color: var(--color-red-500);
|
||||
}
|
||||
|
||||
.border-s-red-500\\/2\\.5 {
|
||||
border-inline-start-color: color-mix(in oklch, var(--color-red-500) 2.5%, transparent);
|
||||
}
|
||||
|
||||
.border-s-red-500\\/2\\.25 {
|
||||
border-inline-start-color: color-mix(in oklch, var(--color-red-500) 2.25%, transparent);
|
||||
}
|
||||
|
||||
.border-s-red-500\\/2\\.75 {
|
||||
border-inline-start-color: color-mix(in oklch, var(--color-red-500) 2.75%, transparent);
|
||||
}
|
||||
|
||||
.border-s-red-500\\/50 {
|
||||
border-inline-start-color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
|
||||
}
|
||||
@ -824,6 +896,18 @@ exports[`border-t-* 1`] = `
|
||||
border-top-color: var(--color-red-500);
|
||||
}
|
||||
|
||||
.border-t-red-500\\/2\\.5 {
|
||||
border-top-color: color-mix(in oklch, var(--color-red-500) 2.5%, transparent);
|
||||
}
|
||||
|
||||
.border-t-red-500\\/2\\.25 {
|
||||
border-top-color: color-mix(in oklch, var(--color-red-500) 2.25%, transparent);
|
||||
}
|
||||
|
||||
.border-t-red-500\\/2\\.75 {
|
||||
border-top-color: color-mix(in oklch, var(--color-red-500) 2.75%, transparent);
|
||||
}
|
||||
|
||||
.border-t-red-500\\/50 {
|
||||
border-top-color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
|
||||
}
|
||||
@ -945,6 +1029,18 @@ exports[`border-x-* 1`] = `
|
||||
border-inline-color: var(--color-red-500);
|
||||
}
|
||||
|
||||
.border-x-red-500\\/2\\.5 {
|
||||
border-inline-color: color-mix(in oklch, var(--color-red-500) 2.5%, transparent);
|
||||
}
|
||||
|
||||
.border-x-red-500\\/2\\.25 {
|
||||
border-inline-color: color-mix(in oklch, var(--color-red-500) 2.25%, transparent);
|
||||
}
|
||||
|
||||
.border-x-red-500\\/2\\.75 {
|
||||
border-inline-color: color-mix(in oklch, var(--color-red-500) 2.75%, transparent);
|
||||
}
|
||||
|
||||
.border-x-red-500\\/50 {
|
||||
border-inline-color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
|
||||
}
|
||||
@ -1066,6 +1162,18 @@ exports[`border-y-* 1`] = `
|
||||
border-block-color: var(--color-red-500);
|
||||
}
|
||||
|
||||
.border-y-red-500\\/2\\.5 {
|
||||
border-block-color: color-mix(in oklch, var(--color-red-500) 2.5%, transparent);
|
||||
}
|
||||
|
||||
.border-y-red-500\\/2\\.25 {
|
||||
border-block-color: color-mix(in oklch, var(--color-red-500) 2.25%, transparent);
|
||||
}
|
||||
|
||||
.border-y-red-500\\/2\\.75 {
|
||||
border-block-color: color-mix(in oklch, var(--color-red-500) 2.75%, transparent);
|
||||
}
|
||||
|
||||
.border-y-red-500\\/50 {
|
||||
border-block-color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
|
||||
}
|
||||
|
||||
@ -8022,6 +8022,9 @@ test('accent', async () => {
|
||||
[
|
||||
'accent-red-500',
|
||||
'accent-red-500/50',
|
||||
'accent-red-500/2.25',
|
||||
'accent-red-500/2.5',
|
||||
'accent-red-500/2.75',
|
||||
'accent-red-500/[0.5]',
|
||||
'accent-red-500/[50%]',
|
||||
'accent-current',
|
||||
@ -8065,6 +8068,18 @@ test('accent', async () => {
|
||||
accent-color: var(--color-red-500);
|
||||
}
|
||||
|
||||
.accent-red-500\\/2\\.5 {
|
||||
accent-color: color-mix(in oklch, var(--color-red-500) 2.5%, transparent);
|
||||
}
|
||||
|
||||
.accent-red-500\\/2\\.25 {
|
||||
accent-color: color-mix(in oklch, var(--color-red-500) 2.25%, transparent);
|
||||
}
|
||||
|
||||
.accent-red-500\\/2\\.75 {
|
||||
accent-color: color-mix(in oklch, var(--color-red-500) 2.75%, transparent);
|
||||
}
|
||||
|
||||
.accent-red-500\\/50, .accent-red-500\\/\\[0\\.5\\], .accent-red-500\\/\\[50\\%\\] {
|
||||
accent-color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
|
||||
}
|
||||
@ -8122,6 +8137,9 @@ test('caret', async () => {
|
||||
[
|
||||
'caret-red-500',
|
||||
'caret-red-500/50',
|
||||
'caret-red-500/2.25',
|
||||
'caret-red-500/2.5',
|
||||
'caret-red-500/2.75',
|
||||
'caret-red-500/[0.5]',
|
||||
'caret-red-500/[50%]',
|
||||
'caret-current',
|
||||
@ -8165,6 +8183,18 @@ test('caret', async () => {
|
||||
caret-color: var(--color-red-500);
|
||||
}
|
||||
|
||||
.caret-red-500\\/2\\.5 {
|
||||
caret-color: color-mix(in oklch, var(--color-red-500) 2.5%, transparent);
|
||||
}
|
||||
|
||||
.caret-red-500\\/2\\.25 {
|
||||
caret-color: color-mix(in oklch, var(--color-red-500) 2.25%, transparent);
|
||||
}
|
||||
|
||||
.caret-red-500\\/2\\.75 {
|
||||
caret-color: color-mix(in oklch, var(--color-red-500) 2.75%, transparent);
|
||||
}
|
||||
|
||||
.caret-red-500\\/50, .caret-red-500\\/\\[0\\.5\\], .caret-red-500\\/\\[50\\%\\] {
|
||||
caret-color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
|
||||
}
|
||||
@ -8220,6 +8250,9 @@ test('divide-color', async () => {
|
||||
[
|
||||
'divide-red-500',
|
||||
'divide-red-500/50',
|
||||
'divide-red-500/2.25',
|
||||
'divide-red-500/2.5',
|
||||
'divide-red-500/2.75',
|
||||
'divide-red-500/[0.5]',
|
||||
'divide-red-500/[50%]',
|
||||
'divide-current',
|
||||
@ -8263,6 +8296,18 @@ test('divide-color', async () => {
|
||||
border-color: var(--color-red-500);
|
||||
}
|
||||
|
||||
:where(.divide-red-500\\/2\\.5 > :not(:last-child)) {
|
||||
border-color: color-mix(in oklch, var(--color-red-500) 2.5%, transparent);
|
||||
}
|
||||
|
||||
:where(.divide-red-500\\/2\\.25 > :not(:last-child)) {
|
||||
border-color: color-mix(in oklch, var(--color-red-500) 2.25%, transparent);
|
||||
}
|
||||
|
||||
:where(.divide-red-500\\/2\\.75 > :not(:last-child)) {
|
||||
border-color: color-mix(in oklch, var(--color-red-500) 2.75%, transparent);
|
||||
}
|
||||
|
||||
:where(.divide-red-500\\/50 > :not(:last-child)), :where(.divide-red-500\\/\\[0\\.5\\] > :not(:last-child)), :where(.divide-red-500\\/\\[50\\%\\] > :not(:last-child)) {
|
||||
border-color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
|
||||
}
|
||||
@ -9889,6 +9934,9 @@ for (let prefix of prefixes) {
|
||||
// Color
|
||||
classes.push(`${prefix}-red-500`)
|
||||
classes.push(`${prefix}-red-500/50`)
|
||||
classes.push(`${prefix}-red-500/2.25`)
|
||||
classes.push(`${prefix}-red-500/2.5`)
|
||||
classes.push(`${prefix}-red-500/2.75`)
|
||||
classes.push(`${prefix}-[#0088cc]`)
|
||||
classes.push(`${prefix}-[#0088cc]/50`)
|
||||
classes.push(`${prefix}-current`)
|
||||
@ -9988,6 +10036,9 @@ test('bg', async () => {
|
||||
// background-color
|
||||
'bg-red-500',
|
||||
'bg-red-500/50',
|
||||
'bg-red-500/2.25',
|
||||
'bg-red-500/2.5',
|
||||
'bg-red-500/2.75',
|
||||
'bg-red-500/[0.5]',
|
||||
'bg-red-500/[50%]',
|
||||
'bg-current',
|
||||
@ -10132,6 +10183,18 @@ test('bg', async () => {
|
||||
background-color: var(--color-red-500);
|
||||
}
|
||||
|
||||
.bg-red-500\\/2\\.5 {
|
||||
background-color: color-mix(in oklch, var(--color-red-500) 2.5%, transparent);
|
||||
}
|
||||
|
||||
.bg-red-500\\/2\\.25 {
|
||||
background-color: color-mix(in oklch, var(--color-red-500) 2.25%, transparent);
|
||||
}
|
||||
|
||||
.bg-red-500\\/2\\.75 {
|
||||
background-color: color-mix(in oklch, var(--color-red-500) 2.75%, transparent);
|
||||
}
|
||||
|
||||
.bg-red-500\\/50, .bg-red-500\\/\\[0\\.5\\], .bg-red-500\\/\\[50\\%\\] {
|
||||
background-color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
|
||||
}
|
||||
@ -11578,6 +11641,9 @@ test('fill', async () => {
|
||||
[
|
||||
'fill-red-500',
|
||||
'fill-red-500/50',
|
||||
'fill-red-500/2.25',
|
||||
'fill-red-500/2.5',
|
||||
'fill-red-500/2.75',
|
||||
'fill-red-500/[0.5]',
|
||||
'fill-red-500/[50%]',
|
||||
'fill-current',
|
||||
@ -11621,6 +11687,18 @@ test('fill', async () => {
|
||||
fill: var(--color-red-500);
|
||||
}
|
||||
|
||||
.fill-red-500\\/2\\.5 {
|
||||
fill: color-mix(in oklch, var(--color-red-500) 2.5%, transparent);
|
||||
}
|
||||
|
||||
.fill-red-500\\/2\\.25 {
|
||||
fill: color-mix(in oklch, var(--color-red-500) 2.25%, transparent);
|
||||
}
|
||||
|
||||
.fill-red-500\\/2\\.75 {
|
||||
fill: color-mix(in oklch, var(--color-red-500) 2.75%, transparent);
|
||||
}
|
||||
|
||||
.fill-red-500\\/50, .fill-red-500\\/\\[0\\.5\\], .fill-red-500\\/\\[50\\%\\] {
|
||||
fill: color-mix(in oklch, var(--color-red-500) 50%, transparent);
|
||||
}
|
||||
@ -11664,6 +11742,9 @@ test('stroke', async () => {
|
||||
// Color
|
||||
'stroke-red-500',
|
||||
'stroke-red-500/50',
|
||||
'stroke-red-500/2.25',
|
||||
'stroke-red-500/2.5',
|
||||
'stroke-red-500/2.75',
|
||||
'stroke-red-500/[0.5]',
|
||||
'stroke-red-500/[50%]',
|
||||
'stroke-current',
|
||||
@ -11747,6 +11828,18 @@ test('stroke', async () => {
|
||||
stroke: var(--color-red-500);
|
||||
}
|
||||
|
||||
.stroke-red-500\\/2\\.5 {
|
||||
stroke: color-mix(in oklch, var(--color-red-500) 2.5%, transparent);
|
||||
}
|
||||
|
||||
.stroke-red-500\\/2\\.25 {
|
||||
stroke: color-mix(in oklch, var(--color-red-500) 2.25%, transparent);
|
||||
}
|
||||
|
||||
.stroke-red-500\\/2\\.75 {
|
||||
stroke: color-mix(in oklch, var(--color-red-500) 2.75%, transparent);
|
||||
}
|
||||
|
||||
.stroke-red-500\\/50, .stroke-red-500\\/\\[0\\.5\\], .stroke-red-500\\/\\[50\\%\\] {
|
||||
stroke: color-mix(in oklch, var(--color-red-500) 50%, transparent);
|
||||
}
|
||||
@ -12667,6 +12760,9 @@ test('placeholder', async () => {
|
||||
[
|
||||
'placeholder-red-500',
|
||||
'placeholder-red-500/50',
|
||||
'placeholder-red-500/2.25',
|
||||
'placeholder-red-500/2.5',
|
||||
'placeholder-red-500/2.75',
|
||||
'placeholder-red-500/[0.5]',
|
||||
'placeholder-red-500/[50%]',
|
||||
'placeholder-current',
|
||||
@ -12710,6 +12806,18 @@ test('placeholder', async () => {
|
||||
color: var(--color-red-500);
|
||||
}
|
||||
|
||||
.placeholder-red-500\\/2\\.5::placeholder {
|
||||
color: color-mix(in oklch, var(--color-red-500) 2.5%, transparent);
|
||||
}
|
||||
|
||||
.placeholder-red-500\\/2\\.25::placeholder {
|
||||
color: color-mix(in oklch, var(--color-red-500) 2.25%, transparent);
|
||||
}
|
||||
|
||||
.placeholder-red-500\\/2\\.75::placeholder {
|
||||
color: color-mix(in oklch, var(--color-red-500) 2.75%, transparent);
|
||||
}
|
||||
|
||||
.placeholder-red-500\\/50::placeholder, .placeholder-red-500\\/\\[0\\.5\\]::placeholder, .placeholder-red-500\\/\\[50\\%\\]::placeholder {
|
||||
color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
|
||||
}
|
||||
@ -13377,6 +13485,9 @@ test('backdrop-filter', async () => {
|
||||
'backdrop-invert-[var(--value)]',
|
||||
'backdrop-opacity-50',
|
||||
'backdrop-opacity-71',
|
||||
'backdrop-opacity-1.25',
|
||||
'backdrop-opacity-2.5',
|
||||
'backdrop-opacity-3.75',
|
||||
'backdrop-opacity-[0.5]',
|
||||
'backdrop-saturate-0',
|
||||
'backdrop-saturate-[1.75]',
|
||||
@ -13494,6 +13605,24 @@ test('backdrop-filter', async () => {
|
||||
backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, );
|
||||
}
|
||||
|
||||
.backdrop-opacity-1\\.25 {
|
||||
--tw-backdrop-opacity: opacity(1.25%);
|
||||
-webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, );
|
||||
backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, );
|
||||
}
|
||||
|
||||
.backdrop-opacity-2\\.5 {
|
||||
--tw-backdrop-opacity: opacity(2.5%);
|
||||
-webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, );
|
||||
backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, );
|
||||
}
|
||||
|
||||
.backdrop-opacity-3\\.75 {
|
||||
--tw-backdrop-opacity: opacity(3.75%);
|
||||
-webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, );
|
||||
backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, );
|
||||
}
|
||||
|
||||
.backdrop-opacity-50 {
|
||||
--tw-backdrop-opacity: opacity(50%);
|
||||
-webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, );
|
||||
@ -14720,8 +14849,28 @@ test('outline-offset', async () => {
|
||||
})
|
||||
|
||||
test('opacity', async () => {
|
||||
expect(await run(['opacity-15', 'opacity-[var(--value)]'])).toMatchInlineSnapshot(`
|
||||
".opacity-15 {
|
||||
expect(
|
||||
await run([
|
||||
'opacity-15',
|
||||
'opacity-2.5',
|
||||
'opacity-3.25',
|
||||
'opacity-4.75',
|
||||
'opacity-[var(--value)]',
|
||||
]),
|
||||
).toMatchInlineSnapshot(`
|
||||
".opacity-2\\.5 {
|
||||
opacity: .025;
|
||||
}
|
||||
|
||||
.opacity-3\\.25 {
|
||||
opacity: .0325;
|
||||
}
|
||||
|
||||
.opacity-4\\.75 {
|
||||
opacity: .0475;
|
||||
}
|
||||
|
||||
.opacity-15 {
|
||||
opacity: .15;
|
||||
}
|
||||
|
||||
@ -14733,6 +14882,7 @@ test('opacity', async () => {
|
||||
await run([
|
||||
'opacity',
|
||||
'opacity--15',
|
||||
'opacity-1.125',
|
||||
'-opacity-15',
|
||||
'-opacity-[var(--value)]',
|
||||
'opacity-unknown',
|
||||
@ -14822,6 +14972,9 @@ test('text', async () => {
|
||||
// color
|
||||
'text-red-500',
|
||||
'text-red-500/50',
|
||||
'text-red-500/2.25',
|
||||
'text-red-500/2.5',
|
||||
'text-red-500/2.75',
|
||||
'text-red-500/[0.5]',
|
||||
'text-red-500/[50%]',
|
||||
'text-current',
|
||||
@ -14985,6 +15138,18 @@ test('text', async () => {
|
||||
color: var(--color-red-500);
|
||||
}
|
||||
|
||||
.text-red-500\\/2\\.5 {
|
||||
color: color-mix(in oklch, var(--color-red-500) 2.5%, transparent);
|
||||
}
|
||||
|
||||
.text-red-500\\/2\\.25 {
|
||||
color: color-mix(in oklch, var(--color-red-500) 2.25%, transparent);
|
||||
}
|
||||
|
||||
.text-red-500\\/2\\.75 {
|
||||
color: color-mix(in oklch, var(--color-red-500) 2.75%, transparent);
|
||||
}
|
||||
|
||||
.text-red-500\\/50, .text-red-500\\/\\[0\\.5\\], .text-red-500\\/\\[50\\%\\] {
|
||||
color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
|
||||
}
|
||||
@ -15044,6 +15209,9 @@ test('shadow', async () => {
|
||||
// Colors
|
||||
'shadow-red-500',
|
||||
'shadow-red-500/50',
|
||||
'shadow-red-500/2.25',
|
||||
'shadow-red-500/2.5',
|
||||
'shadow-red-500/2.75',
|
||||
'shadow-red-500/[0.5]',
|
||||
'shadow-red-500/[50%]',
|
||||
'shadow-current',
|
||||
@ -15131,6 +15299,18 @@ test('shadow', async () => {
|
||||
--tw-shadow-color: var(--color-red-500);
|
||||
}
|
||||
|
||||
.shadow-red-500\\/2\\.5 {
|
||||
--tw-shadow-color: color-mix(in oklch, var(--color-red-500) 2.5%, transparent);
|
||||
}
|
||||
|
||||
.shadow-red-500\\/2\\.25 {
|
||||
--tw-shadow-color: color-mix(in oklch, var(--color-red-500) 2.25%, transparent);
|
||||
}
|
||||
|
||||
.shadow-red-500\\/2\\.75 {
|
||||
--tw-shadow-color: color-mix(in oklch, var(--color-red-500) 2.75%, transparent);
|
||||
}
|
||||
|
||||
.shadow-red-500\\/50, .shadow-red-500\\/\\[0\\.5\\], .shadow-red-500\\/\\[50\\%\\] {
|
||||
--tw-shadow-color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
|
||||
}
|
||||
@ -15272,6 +15452,9 @@ test('inset-shadow', async () => {
|
||||
// Colors
|
||||
'inset-shadow-red-500',
|
||||
'inset-shadow-red-500/50',
|
||||
'inset-shadow-red-500/2.25',
|
||||
'inset-shadow-red-500/2.5',
|
||||
'inset-shadow-red-500/2.75',
|
||||
'inset-shadow-red-500/[0.5]',
|
||||
'inset-shadow-red-500/[50%]',
|
||||
'inset-shadow-current',
|
||||
@ -15359,6 +15542,18 @@ test('inset-shadow', async () => {
|
||||
--tw-inset-shadow-color: var(--color-red-500);
|
||||
}
|
||||
|
||||
.inset-shadow-red-500\\/2\\.5 {
|
||||
--tw-inset-shadow-color: color-mix(in oklch, var(--color-red-500) 2.5%, transparent);
|
||||
}
|
||||
|
||||
.inset-shadow-red-500\\/2\\.25 {
|
||||
--tw-inset-shadow-color: color-mix(in oklch, var(--color-red-500) 2.25%, transparent);
|
||||
}
|
||||
|
||||
.inset-shadow-red-500\\/2\\.75 {
|
||||
--tw-inset-shadow-color: color-mix(in oklch, var(--color-red-500) 2.75%, transparent);
|
||||
}
|
||||
|
||||
.inset-shadow-red-500\\/50, .inset-shadow-red-500\\/\\[0\\.5\\], .inset-shadow-red-500\\/\\[50\\%\\] {
|
||||
--tw-inset-shadow-color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
|
||||
}
|
||||
@ -15490,6 +15685,9 @@ test('ring', async () => {
|
||||
'ring-inset',
|
||||
'ring-red-500',
|
||||
'ring-red-500/50',
|
||||
'ring-red-500/2.25',
|
||||
'ring-red-500/2.5',
|
||||
'ring-red-500/2.75',
|
||||
'ring-red-500/[0.5]',
|
||||
'ring-red-500/[50%]',
|
||||
'ring-current',
|
||||
@ -15601,6 +15799,18 @@ test('ring', async () => {
|
||||
--tw-ring-color: var(--color-red-500);
|
||||
}
|
||||
|
||||
.ring-red-500\\/2\\.5 {
|
||||
--tw-ring-color: color-mix(in oklch, var(--color-red-500) 2.5%, transparent);
|
||||
}
|
||||
|
||||
.ring-red-500\\/2\\.25 {
|
||||
--tw-ring-color: color-mix(in oklch, var(--color-red-500) 2.25%, transparent);
|
||||
}
|
||||
|
||||
.ring-red-500\\/2\\.75 {
|
||||
--tw-ring-color: color-mix(in oklch, var(--color-red-500) 2.75%, transparent);
|
||||
}
|
||||
|
||||
.ring-red-500\\/50, .ring-red-500\\/\\[0\\.5\\], .ring-red-500\\/\\[50\\%\\] {
|
||||
--tw-ring-color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
|
||||
}
|
||||
@ -15750,6 +15960,9 @@ test('inset-ring', async () => {
|
||||
// ring color
|
||||
'inset-ring-red-500',
|
||||
'inset-ring-red-500/50',
|
||||
'inset-ring-red-500/2.25',
|
||||
'inset-ring-red-500/2.5',
|
||||
'inset-ring-red-500/2.75',
|
||||
'inset-ring-red-500/[0.5]',
|
||||
'inset-ring-red-500/[50%]',
|
||||
'inset-ring-current',
|
||||
@ -15861,6 +16074,18 @@ test('inset-ring', async () => {
|
||||
--tw-inset-ring-color: var(--color-red-500);
|
||||
}
|
||||
|
||||
.inset-ring-red-500\\/2\\.5 {
|
||||
--tw-inset-ring-color: color-mix(in oklch, var(--color-red-500) 2.5%, transparent);
|
||||
}
|
||||
|
||||
.inset-ring-red-500\\/2\\.25 {
|
||||
--tw-inset-ring-color: color-mix(in oklch, var(--color-red-500) 2.25%, transparent);
|
||||
}
|
||||
|
||||
.inset-ring-red-500\\/2\\.75 {
|
||||
--tw-inset-ring-color: color-mix(in oklch, var(--color-red-500) 2.75%, transparent);
|
||||
}
|
||||
|
||||
.inset-ring-red-500\\/50, .inset-ring-red-500\\/\\[0\\.5\\], .inset-ring-red-500\\/\\[50\\%\\] {
|
||||
--tw-inset-ring-color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
|
||||
}
|
||||
|
||||
@ -2,7 +2,12 @@ import { atRoot, atRule, decl, styleRule, type AstNode } from './ast'
|
||||
import type { Candidate, CandidateModifier, NamedUtilityValue } from './candidate'
|
||||
import type { Theme, ThemeKey } from './theme'
|
||||
import { DefaultMap } from './utils/default-map'
|
||||
import { inferDataType, isPositiveInteger, isValidSpacingMultiplier } from './utils/infer-data-type'
|
||||
import {
|
||||
inferDataType,
|
||||
isPositiveInteger,
|
||||
isValidOpacityValue,
|
||||
isValidSpacingMultiplier,
|
||||
} from './utils/infer-data-type'
|
||||
import { replaceShadowColors } from './utils/replace-shadow-colors'
|
||||
import { segment } from './utils/segment'
|
||||
|
||||
@ -125,7 +130,7 @@ export function asColor(value: string, modifier: CandidateModifier | null): stri
|
||||
return withAlpha(value, modifier.value)
|
||||
}
|
||||
|
||||
if (!isPositiveInteger(modifier.value)) {
|
||||
if (!isValidOpacityValue(modifier.value)) {
|
||||
return null
|
||||
}
|
||||
|
||||
@ -3395,7 +3400,7 @@ export function createUtilities(theme: Theme) {
|
||||
functionalUtility('backdrop-opacity', {
|
||||
themeKeys: ['--backdrop-opacity', '--opacity'],
|
||||
handleBareValue: ({ value }) => {
|
||||
if (!isPositiveInteger(value)) return null
|
||||
if (!isValidOpacityValue(value)) return null
|
||||
return `${value}%`
|
||||
},
|
||||
handle: (value) => [
|
||||
@ -3849,7 +3854,7 @@ export function createUtilities(theme: Theme) {
|
||||
functionalUtility('opacity', {
|
||||
themeKeys: ['--opacity'],
|
||||
handleBareValue: ({ value }) => {
|
||||
if (!isPositiveInteger(value)) return null
|
||||
if (!isValidOpacityValue(value)) return null
|
||||
return `${value}%`
|
||||
},
|
||||
handle: (value) => [decl('opacity', value)],
|
||||
|
||||
@ -322,17 +322,26 @@ function isVector(value: string) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true of the value can be parsed as a positive whole number.
|
||||
* Returns true if the value can be parsed as a positive whole number.
|
||||
*/
|
||||
export function isPositiveInteger(value: any) {
|
||||
let num = Number(value)
|
||||
return Number.isInteger(num) && num >= 0 && String(num) === String(value)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the value is either a positive whole number or a multiple of 0.25.
|
||||
*/
|
||||
export function isValidSpacingMultiplier(value: any) {
|
||||
let num = Number(value)
|
||||
return num >= 0 && num % 0.25 === 0 && String(num) === String(value)
|
||||
return isMultipleOf(value, 0.25)
|
||||
}
|
||||
|
||||
export function isValidOpacityValue(value: any) {
|
||||
return isMultipleOf(value, 0.25)
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures a number (or numeric string) is a multiple of another number, and
|
||||
* that it has no unnecessary leading or trailing zeros.
|
||||
*/
|
||||
function isMultipleOf(value: string | number, divisor: number) {
|
||||
let num = Number(value)
|
||||
return num >= 0 && num % divisor === 0 && String(num) === String(value)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user