From 20f31a9282e5f3aa6a98356f44c0a95feb1dc1a8 Mon Sep 17 00:00:00 2001 From: Adam Wathan <4323180+adamwathan@users.noreply.github.com> Date: Wed, 18 Sep 2024 14:14:40 -0400 Subject: [PATCH 1/2] Preserve shadow color when overriding shadow size --- .../src/__snapshots__/index.test.ts.snap | 17 ++- packages/tailwindcss/src/utilities.test.ts | 106 ++++++------------ packages/tailwindcss/src/utilities.ts | 63 ++++------- .../src/utils/replace-shadow-colors.test.ts | 16 +-- .../src/utils/replace-shadow-colors.ts | 22 ++-- packages/tailwindcss/tests/ui.spec.ts | 97 +++++++++++++++- 6 files changed, 174 insertions(+), 147 deletions(-) diff --git a/packages/tailwindcss/src/__snapshots__/index.test.ts.snap b/packages/tailwindcss/src/__snapshots__/index.test.ts.snap index d16657b1b7aa..a29cb7740f22 100644 --- a/packages/tailwindcss/src/__snapshots__/index.test.ts.snap +++ b/packages/tailwindcss/src/__snapshots__/index.test.ts.snap @@ -414,8 +414,7 @@ exports[`compiling CSS > \`@tailwind utilities\` is replaced by utilities using } .shadow { - --tw-shadow: 0 1px 3px 0 #0000001a, 0 1px 2px -1px #0000001a; - --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); + --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, #0000001a), 0 1px 2px -1px var(--tw-shadow-color, #0000001a); box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } @@ -429,9 +428,9 @@ exports[`compiling CSS > \`@tailwind utilities\` is replaced by utilities using @layer base { *, :before, :after, ::backdrop { --tw-shadow: 0 0 #0000; - --tw-shadow-colored: 0 0 #0000; + --tw-shadow-color: initial; --tw-inset-shadow: 0 0 #0000; - --tw-inset-shadow-colored: 0 0 #0000; + --tw-inset-shadow-color: initial; --tw-ring-color: initial; --tw-ring-shadow: 0 0 #0000; --tw-inset-ring-color: initial; @@ -481,10 +480,9 @@ exports[`compiling CSS > \`@tailwind utilities\` is replaced by utilities using initial-value: 0 0 #0000; } -@property --tw-shadow-colored { +@property --tw-shadow-color { syntax: "*"; - inherits: false; - initial-value: 0 0 #0000; + inherits: false } @property --tw-inset-shadow { @@ -493,10 +491,9 @@ exports[`compiling CSS > \`@tailwind utilities\` is replaced by utilities using initial-value: 0 0 #0000; } -@property --tw-inset-shadow-colored { +@property --tw-inset-shadow-color { syntax: "*"; - inherits: false; - initial-value: 0 0 #0000; + inherits: false } @property --tw-ring-color { diff --git a/packages/tailwindcss/src/utilities.test.ts b/packages/tailwindcss/src/utilities.test.ts index 6e22534a7e24..b826d959c871 100644 --- a/packages/tailwindcss/src/utilities.test.ts +++ b/packages/tailwindcss/src/utilities.test.ts @@ -14103,104 +14103,87 @@ test('shadow', async () => { } .shadow { - --tw-shadow: 0 1px 3px 0 #0000001a, 0 1px 2px -1px #0000001a; - --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); + --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, #0000001a), 0 1px 2px -1px var(--tw-shadow-color, #0000001a); box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } .shadow-\\[--value\\] { --tw-shadow: var(--value); - --tw-shadow-colored: var(--value); box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } .shadow-\\[10px_10px\\] { - --tw-shadow: 10px 10px; - --tw-shadow-colored: 10px 10px var(--tw-shadow-color); + --tw-shadow: 10px 10px var(--tw-shadow-color, currentcolor); box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } .shadow-\\[12px_12px_\\#0088cc\\] { - --tw-shadow: 12px 12px #08c; - --tw-shadow-colored: 12px 12px var(--tw-shadow-color); + --tw-shadow: 12px 12px var(--tw-shadow-color, #08c); box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } .shadow-\\[shadow\\:--value\\] { --tw-shadow: var(--value); - --tw-shadow-colored: var(--value); box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } .shadow-none { --tw-shadow: 0 0 #0000; - --tw-shadow-colored: 0 0 #0000; box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } .shadow-xl { - --tw-shadow: 0 20px 25px -5px #0000001a, 0 8px 10px -6px #0000001a; - --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color); + --tw-shadow: 0 20px 25px -5px var(--tw-shadow-color, #0000001a), 0 8px 10px -6px var(--tw-shadow-color, #0000001a); box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } .shadow-\\[\\#0088cc\\] { --tw-shadow-color: #08c; - --tw-shadow: var(--tw-shadow-colored); } .shadow-\\[\\#0088cc\\]\\/50, .shadow-\\[\\#0088cc\\]\\/\\[0\\.5\\], .shadow-\\[\\#0088cc\\]\\/\\[50\\%\\] { --tw-shadow-color: #0088cc80; - --tw-shadow: var(--tw-shadow-colored); } .shadow-\\[color\\:--value\\] { --tw-shadow-color: var(--value); - --tw-shadow: var(--tw-shadow-colored); } .shadow-\\[color\\:--value\\]\\/50, .shadow-\\[color\\:--value\\]\\/\\[0\\.5\\], .shadow-\\[color\\:--value\\]\\/\\[50\\%\\] { --tw-shadow-color: color-mix(in srgb, var(--value) 50%, transparent); - --tw-shadow: var(--tw-shadow-colored); } .shadow-current { --tw-shadow-color: currentColor; - --tw-shadow: var(--tw-shadow-colored); } .shadow-current\\/50, .shadow-current\\/\\[0\\.5\\], .shadow-current\\/\\[50\\%\\] { --tw-shadow-color: color-mix(in srgb, currentColor 50%, transparent); - --tw-shadow: var(--tw-shadow-colored); } .shadow-inherit { --tw-shadow-color: inherit; - --tw-shadow: var(--tw-shadow-colored); } .shadow-red-500 { --tw-shadow-color: var(--color-red-500, #ef4444); - --tw-shadow: var(--tw-shadow-colored); } .shadow-red-500\\/50, .shadow-red-500\\/\\[0\\.5\\], .shadow-red-500\\/\\[50\\%\\] { --tw-shadow-color: color-mix(in srgb, var(--color-red-500, #ef4444) 50%, transparent); - --tw-shadow: var(--tw-shadow-colored); } .shadow-transparent { --tw-shadow-color: transparent; - --tw-shadow: var(--tw-shadow-colored); } @supports (-moz-orient: inline) { @layer base { *, :before, :after, ::backdrop { --tw-shadow: 0 0 #0000; - --tw-shadow-colored: 0 0 #0000; + --tw-shadow-color: initial; --tw-inset-shadow: 0 0 #0000; - --tw-inset-shadow-colored: 0 0 #0000; + --tw-inset-shadow-color: initial; --tw-ring-color: initial; --tw-ring-shadow: 0 0 #0000; --tw-inset-ring-color: initial; @@ -14219,10 +14202,9 @@ test('shadow', async () => { initial-value: 0 0 #0000; } - @property --tw-shadow-colored { + @property --tw-shadow-color { syntax: "*"; - inherits: false; - initial-value: 0 0 #0000; + inherits: false } @property --tw-inset-shadow { @@ -14231,10 +14213,9 @@ test('shadow', async () => { initial-value: 0 0 #0000; } - @property --tw-inset-shadow-colored { + @property --tw-inset-shadow-color { syntax: "*"; - inherits: false; - initial-value: 0 0 #0000; + inherits: false } @property --tw-ring-color { @@ -14355,104 +14336,87 @@ test('inset-shadow', async () => { } .inset-shadow { - --tw-inset-shadow: inset 0 2px 4px #0000000d; - --tw-inset-shadow-colored: inset 0 2px 4px var(--tw-inset-shadow-color); + --tw-inset-shadow: inset 0 2px 4px var(--tw-inset-shadow-color, #0000000d); box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } .inset-shadow-\\[--value\\] { --tw-inset-shadow: inset var(--value); - --tw-inset-shadow-colored: inset var(--value); box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } .inset-shadow-\\[10px_10px\\] { - --tw-inset-shadow: inset 10px 10px; - --tw-inset-shadow-colored: inset 10px 10px var(--tw-inset-shadow-color); + --tw-inset-shadow: inset 10px 10px var(--tw-inset-shadow-color, currentcolor); box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } .inset-shadow-\\[12px_12px_\\#0088cc\\] { - --tw-inset-shadow: inset 12px 12px #08c; - --tw-inset-shadow-colored: inset 12px 12px var(--tw-inset-shadow-color); + --tw-inset-shadow: inset 12px 12px var(--tw-inset-shadow-color, #08c); box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } .inset-shadow-\\[shadow\\:--value\\] { --tw-inset-shadow: inset var(--value); - --tw-inset-shadow-colored: inset var(--value); box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } .inset-shadow-none { --tw-inset-shadow: 0 0 #0000; - --tw-inset-shadow-colored: 0 0 #0000; box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } .inset-shadow-sm { - --tw-inset-shadow: inset 0 1px 1px #0000000d; - --tw-inset-shadow-colored: inset 0 1px 1px var(--tw-inset-shadow-color); + --tw-inset-shadow: inset 0 1px 1px var(--tw-inset-shadow-color, #0000000d); box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } .inset-shadow-\\[\\#0088cc\\] { --tw-inset-shadow-color: #08c; - --tw-inset-shadow: var(--tw-inset-shadow-colored); } .inset-shadow-\\[\\#0088cc\\]\\/50, .inset-shadow-\\[\\#0088cc\\]\\/\\[0\\.5\\], .inset-shadow-\\[\\#0088cc\\]\\/\\[50\\%\\] { --tw-inset-shadow-color: #0088cc80; - --tw-inset-shadow: var(--tw-inset-shadow-colored); } .inset-shadow-\\[color\\:--value\\] { --tw-inset-shadow-color: var(--value); - --tw-inset-shadow: var(--tw-inset-shadow-colored); } .inset-shadow-\\[color\\:--value\\]\\/50, .inset-shadow-\\[color\\:--value\\]\\/\\[0\\.5\\], .inset-shadow-\\[color\\:--value\\]\\/\\[50\\%\\] { --tw-inset-shadow-color: color-mix(in srgb, var(--value) 50%, transparent); - --tw-inset-shadow: var(--tw-inset-shadow-colored); } .inset-shadow-current { --tw-inset-shadow-color: currentColor; - --tw-inset-shadow: var(--tw-inset-shadow-colored); } .inset-shadow-current\\/50, .inset-shadow-current\\/\\[0\\.5\\], .inset-shadow-current\\/\\[50\\%\\] { --tw-inset-shadow-color: color-mix(in srgb, currentColor 50%, transparent); - --tw-inset-shadow: var(--tw-inset-shadow-colored); } .inset-shadow-inherit { --tw-inset-shadow-color: inherit; - --tw-inset-shadow: var(--tw-inset-shadow-colored); } .inset-shadow-red-500 { --tw-inset-shadow-color: var(--color-red-500, #ef4444); - --tw-inset-shadow: var(--tw-inset-shadow-colored); } .inset-shadow-red-500\\/50, .inset-shadow-red-500\\/\\[0\\.5\\], .inset-shadow-red-500\\/\\[50\\%\\] { --tw-inset-shadow-color: color-mix(in srgb, var(--color-red-500, #ef4444) 50%, transparent); - --tw-inset-shadow: var(--tw-inset-shadow-colored); } .inset-shadow-transparent { --tw-inset-shadow-color: transparent; - --tw-inset-shadow: var(--tw-inset-shadow-colored); } @supports (-moz-orient: inline) { @layer base { *, :before, :after, ::backdrop { --tw-shadow: 0 0 #0000; - --tw-shadow-colored: 0 0 #0000; + --tw-shadow-color: initial; --tw-inset-shadow: 0 0 #0000; - --tw-inset-shadow-colored: 0 0 #0000; + --tw-inset-shadow-color: initial; --tw-ring-color: initial; --tw-ring-shadow: 0 0 #0000; --tw-inset-ring-color: initial; @@ -14471,10 +14435,9 @@ test('inset-shadow', async () => { initial-value: 0 0 #0000; } - @property --tw-shadow-colored { + @property --tw-shadow-color { syntax: "*"; - inherits: false; - initial-value: 0 0 #0000; + inherits: false } @property --tw-inset-shadow { @@ -14483,10 +14446,9 @@ test('inset-shadow', async () => { initial-value: 0 0 #0000; } - @property --tw-inset-shadow-colored { + @property --tw-inset-shadow-color { syntax: "*"; - inherits: false; - initial-value: 0 0 #0000; + inherits: false } @property --tw-ring-color { @@ -14698,9 +14660,9 @@ test('ring', async () => { @layer base { *, :before, :after, ::backdrop { --tw-shadow: 0 0 #0000; - --tw-shadow-colored: 0 0 #0000; + --tw-shadow-color: initial; --tw-inset-shadow: 0 0 #0000; - --tw-inset-shadow-colored: 0 0 #0000; + --tw-inset-shadow-color: initial; --tw-ring-color: initial; --tw-ring-shadow: 0 0 #0000; --tw-inset-ring-color: initial; @@ -14719,10 +14681,9 @@ test('ring', async () => { initial-value: 0 0 #0000; } - @property --tw-shadow-colored { + @property --tw-shadow-color { syntax: "*"; - inherits: false; - initial-value: 0 0 #0000; + inherits: false } @property --tw-inset-shadow { @@ -14731,10 +14692,9 @@ test('ring', async () => { initial-value: 0 0 #0000; } - @property --tw-inset-shadow-colored { + @property --tw-inset-shadow-color { syntax: "*"; - inherits: false; - initial-value: 0 0 #0000; + inherits: false } @property --tw-ring-color { @@ -14959,9 +14919,9 @@ test('inset-ring', async () => { @layer base { *, :before, :after, ::backdrop { --tw-shadow: 0 0 #0000; - --tw-shadow-colored: 0 0 #0000; + --tw-shadow-color: initial; --tw-inset-shadow: 0 0 #0000; - --tw-inset-shadow-colored: 0 0 #0000; + --tw-inset-shadow-color: initial; --tw-ring-color: initial; --tw-ring-shadow: 0 0 #0000; --tw-inset-ring-color: initial; @@ -14980,10 +14940,9 @@ test('inset-ring', async () => { initial-value: 0 0 #0000; } - @property --tw-shadow-colored { + @property --tw-shadow-color { syntax: "*"; - inherits: false; - initial-value: 0 0 #0000; + inherits: false } @property --tw-inset-shadow { @@ -14992,10 +14951,9 @@ test('inset-ring', async () => { initial-value: 0 0 #0000; } - @property --tw-inset-shadow-colored { + @property --tw-inset-shadow-color { syntax: "*"; - inherits: false; - initial-value: 0 0 #0000; + inherits: false } @property --tw-ring-color { diff --git a/packages/tailwindcss/src/utilities.ts b/packages/tailwindcss/src/utilities.ts index 95f8a1dd6f8d..b3a2abc9786b 100644 --- a/packages/tailwindcss/src/utilities.ts +++ b/packages/tailwindcss/src/utilities.ts @@ -4197,9 +4197,9 @@ export function createUtilities(theme: Theme) { let boxShadowProperties = () => { return atRoot([ property('--tw-shadow', nullShadow), - property('--tw-shadow-colored', nullShadow), + property('--tw-shadow-color'), property('--tw-inset-shadow', nullShadow), - property('--tw-inset-shadow-colored', nullShadow), + property('--tw-inset-shadow-color'), property('--tw-ring-color'), property('--tw-ring-shadow', nullShadow), property('--tw-inset-ring-color'), @@ -4222,8 +4222,10 @@ export function createUtilities(theme: Theme) { return [ boxShadowProperties(), - decl('--tw-shadow', value), - decl('--tw-shadow-colored', replaceShadowColors(value, 'var(--tw-shadow-color)')), + decl( + '--tw-shadow', + replaceShadowColors(value, (color) => `var(--tw-shadow-color, ${color})`), + ), decl('box-shadow', cssBoxShadowValue), ] } @@ -4237,17 +4239,15 @@ export function createUtilities(theme: Theme) { value = asColor(value, candidate.modifier) if (value === null) return - return [ - boxShadowProperties(), - decl('--tw-shadow-color', value), - decl('--tw-shadow', 'var(--tw-shadow-colored)'), - ] + return [boxShadowProperties(), decl('--tw-shadow-color', value)] } default: { return [ boxShadowProperties(), - decl('--tw-shadow', value), - decl('--tw-shadow-colored', replaceShadowColors(value, 'var(--tw-shadow-color)')), + decl( + '--tw-shadow', + replaceShadowColors(value, (color) => `var(--tw-shadow-color, ${color})`), + ), decl('box-shadow', cssBoxShadowValue), ] } @@ -4260,7 +4260,6 @@ export function createUtilities(theme: Theme) { return [ boxShadowProperties(), decl('--tw-shadow', nullShadow), - decl('--tw-shadow-colored', nullShadow), decl('box-shadow', cssBoxShadowValue), ] } @@ -4272,8 +4271,10 @@ export function createUtilities(theme: Theme) { if (candidate.modifier) return return [ boxShadowProperties(), - decl('--tw-shadow', value), - decl('--tw-shadow-colored', replaceShadowColors(value, 'var(--tw-shadow-color)')), + decl( + '--tw-shadow', + replaceShadowColors(value, (color) => `var(--tw-shadow-color, ${color})`), + ), decl('box-shadow', cssBoxShadowValue), ] } @@ -4283,11 +4284,7 @@ export function createUtilities(theme: Theme) { { let value = resolveThemeColor(candidate, theme, ['--box-shadow-color', '--color']) if (value) { - return [ - boxShadowProperties(), - decl('--tw-shadow-color', value), - decl('--tw-shadow', 'var(--tw-shadow-colored)'), - ] + return [boxShadowProperties(), decl('--tw-shadow-color', value)] } } }) @@ -4314,10 +4311,9 @@ export function createUtilities(theme: Theme) { return [ boxShadowProperties(), - decl('--tw-inset-shadow', value), decl( - '--tw-inset-shadow-colored', - replaceShadowColors(value, 'var(--tw-inset-shadow-color)'), + '--tw-inset-shadow', + replaceShadowColors(value, (color) => `var(--tw-inset-shadow-color, ${color})`), ), decl('box-shadow', cssBoxShadowValue), ] @@ -4332,19 +4328,14 @@ export function createUtilities(theme: Theme) { value = asColor(value, candidate.modifier) if (value === null) return - return [ - boxShadowProperties(), - decl('--tw-inset-shadow-color', value), - decl('--tw-inset-shadow', 'var(--tw-inset-shadow-colored)'), - ] + return [boxShadowProperties(), decl('--tw-inset-shadow-color', value)] } default: { return [ boxShadowProperties(), - decl('--tw-inset-shadow', `inset ${value}`), decl( - '--tw-inset-shadow-colored', - replaceShadowColors(`inset ${value}`, 'var(--tw-inset-shadow-color)'), + '--tw-inset-shadow', + `inset ${replaceShadowColors(value, (color) => `var(--tw-inset-shadow-color, ${color})`)}`, ), decl('box-shadow', cssBoxShadowValue), ] @@ -4358,7 +4349,6 @@ export function createUtilities(theme: Theme) { return [ boxShadowProperties(), decl('--tw-inset-shadow', nullShadow), - decl('--tw-inset-shadow-colored', nullShadow), decl('box-shadow', cssBoxShadowValue), ] } @@ -4371,10 +4361,9 @@ export function createUtilities(theme: Theme) { if (candidate.modifier) return return [ boxShadowProperties(), - decl('--tw-inset-shadow', value), decl( - '--tw-inset-shadow-colored', - replaceShadowColors(value, 'var(--tw-inset-shadow-color)'), + '--tw-inset-shadow', + replaceShadowColors(value, (color) => `var(--tw-inset-shadow-color, ${color})`), ), decl('box-shadow', cssBoxShadowValue), ] @@ -4385,11 +4374,7 @@ export function createUtilities(theme: Theme) { { let value = resolveThemeColor(candidate, theme, ['--box-shadow-color', '--color']) if (value) { - return [ - boxShadowProperties(), - decl('--tw-inset-shadow-color', value), - decl('--tw-inset-shadow', 'var(--tw-inset-shadow-colored)'), - ] + return [boxShadowProperties(), decl('--tw-inset-shadow-color', value)] } } }) diff --git a/packages/tailwindcss/src/utils/replace-shadow-colors.test.ts b/packages/tailwindcss/src/utils/replace-shadow-colors.test.ts index 175273d80cd3..3b1e90ba6d4a 100644 --- a/packages/tailwindcss/src/utils/replace-shadow-colors.test.ts +++ b/packages/tailwindcss/src/utils/replace-shadow-colors.test.ts @@ -12,30 +12,30 @@ const table = [ }, { input: '1px 1px var(--my-color)', - output: '1px 1px var(--tw-shadow-color)', + output: '1px 1px var(--tw-shadow-color, var(--my-color))', }, { input: '0 0 0 var(--my-color)', - output: '0 0 0 var(--tw-shadow-color)', + output: '0 0 0 var(--tw-shadow-color, var(--my-color))', }, { input: '1px 2px', - output: '1px 2px var(--tw-shadow-color)', + output: '1px 2px var(--tw-shadow-color, currentcolor)', }, { input: '1px 2px 3px', - output: '1px 2px 3px var(--tw-shadow-color)', + output: '1px 2px 3px var(--tw-shadow-color, currentcolor)', }, { input: '1px 2px 3px 4px', - output: '1px 2px 3px 4px var(--tw-shadow-color)', + output: '1px 2px 3px 4px var(--tw-shadow-color, currentcolor)', }, { input: ['var(--my-shadow)', '1px 1px var(--my-color)', '0 0 1px var(--my-color)'].join(', '), output: [ 'var(--my-shadow)', - '1px 1px var(--tw-shadow-color)', - '0 0 1px var(--tw-shadow-color)', + '1px 1px var(--tw-shadow-color, var(--my-color))', + '0 0 1px var(--tw-shadow-color, var(--my-color))', ].join(', '), }, ] @@ -43,7 +43,7 @@ const table = [ it.each(table)( 'should replace the color of box-shadow $input with $output', ({ input, output }) => { - let parsed = replaceShadowColors(input, 'var(--tw-shadow-color)') + let parsed = replaceShadowColors(input, (color) => `var(--tw-shadow-color, ${color})`) expect(parsed).toEqual(output) }, ) diff --git a/packages/tailwindcss/src/utils/replace-shadow-colors.ts b/packages/tailwindcss/src/utils/replace-shadow-colors.ts index cf6976d11596..e51f9c2a0536 100644 --- a/packages/tailwindcss/src/utils/replace-shadow-colors.ts +++ b/packages/tailwindcss/src/utils/replace-shadow-colors.ts @@ -3,8 +3,9 @@ import { segment } from './segment' const KEYWORDS = new Set(['inset', 'inherit', 'initial', 'revert', 'unset']) const LENGTH = /^-?(\d+|\.\d+)(.*?)$/g -export function replaceShadowColors(input: string, replacement: string): string { - for (let shadow of segment(input, ',')) { +export function replaceShadowColors(input: string, replacement: (color: string) => string) { + let shadows = segment(input, ',').map((shadow) => { + shadow = shadow.trim() let parts = segment(shadow, ' ').filter((part) => part.trim() !== '') let color = null let offsetX = null @@ -30,17 +31,18 @@ export function replaceShadowColors(input: string, replacement: string): string // If the x and y offsets were not detected, the shadow is either invalid or // using a variable to represent more than one field in the shadow value, so // we can't know what to replace. - if (offsetX === null || offsetY === null) continue + if (offsetX === null || offsetY === null) return shadow + + let replacementColor = replacement(color ?? 'currentcolor') if (color !== null) { // If a color was found, replace the color. - input = input.replace(color, replacement) - } else { - // If no color was found, assume the shadow is relying on the browser - // default shadow color and append the replacement color. - input = `${input} ${replacement}` + return shadow.replace(color, replacementColor) } - } + // If no color was found, assume the shadow is relying on the browser + // default shadow color and append the replacement color. + return `${shadow} ${replacementColor}` + }) - return input + return shadows.join(', ') } diff --git a/packages/tailwindcss/tests/ui.spec.ts b/packages/tailwindcss/tests/ui.spec.ts index 59546cf6daf4..c16b0f920a77 100644 --- a/packages/tailwindcss/tests/ui.spec.ts +++ b/packages/tailwindcss/tests/ui.spec.ts @@ -164,13 +164,14 @@ test('shadow colors', async ({ page }) => { let { getPropertyValue } = await render( page, html` -
-
-
+
+
+
+
Hello world
`, ) - expect(await getPropertyValue('#x', 'box-shadow')).toEqual( + expect(await getPropertyValue('#a', 'box-shadow')).toEqual( [ 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', @@ -179,7 +180,7 @@ test('shadow colors', async ({ page }) => { 'rgb(239, 68, 68) 0px 1px 3px 0px, rgb(239, 68, 68) 0px 1px 2px -1px', ].join(', '), ) - expect(await getPropertyValue('#y', 'box-shadow')).toEqual( + expect(await getPropertyValue('#b', 'box-shadow')).toEqual( [ 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', @@ -188,7 +189,7 @@ test('shadow colors', async ({ page }) => { 'rgb(239, 68, 68) 0px 20px 25px -5px, rgb(239, 68, 68) 0px 8px 10px -6px', ].join(', '), ) - expect(await getPropertyValue('#z', 'box-shadow')).toEqual( + expect(await getPropertyValue('#c', 'box-shadow')).toEqual( [ 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', @@ -197,6 +198,90 @@ test('shadow colors', async ({ page }) => { 'rgb(239, 68, 68) 0px 2px 4px 0px', ].join(', '), ) + + expect(await getPropertyValue('#d', 'box-shadow')).toEqual( + [ + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + 'rgb(239, 68, 68) 0px 1px 3px 0px, rgb(239, 68, 68) 0px 1px 2px -1px', + ].join(', '), + ) + + await page.locator('#d').hover() + + expect(await getPropertyValue('#d', 'box-shadow')).toEqual( + [ + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + 'rgb(239, 68, 68) 0px 20px 25px -5px, rgb(239, 68, 68) 0px 8px 10px -6px', + ].join(', '), + ) +}) + +test('inset shadow colors', async ({ page }) => { + let { getPropertyValue } = await render( + page, + html` +
+
+
+
Hello world
+ `, + ) + + expect(await getPropertyValue('#a', 'box-shadow')).toEqual( + [ + 'rgb(239, 68, 68) 0px 1px 1px 0px inset', + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + ].join(', '), + ) + expect(await getPropertyValue('#b', 'box-shadow')).toEqual( + [ + 'rgb(239, 68, 68) 0px 2px 4px 0px inset', + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + ].join(', '), + ) + expect(await getPropertyValue('#c', 'box-shadow')).toEqual( + [ + 'rgb(239, 68, 68) 0px 3px 6px 0px inset', + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + ].join(', '), + ) + + expect(await getPropertyValue('#d', 'box-shadow')).toEqual( + [ + 'rgb(239, 68, 68) 0px 1px 1px 0px inset', + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + ].join(', '), + ) + + await page.locator('#d').hover() + + expect(await getPropertyValue('#d', 'box-shadow')).toEqual( + [ + 'rgb(239, 68, 68) 0px 2px 4px 0px inset', + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + 'rgba(0, 0, 0, 0) 0px 0px 0px 0px', + ].join(', '), + ) }) test('outline style is optional', async ({ page }) => { From 2cfcbfa08441bb85a97f46cf0a994f9f85236a1b Mon Sep 17 00:00:00 2001 From: Adam Wathan <4323180+adamwathan@users.noreply.github.com> Date: Thu, 19 Sep 2024 09:22:37 -0400 Subject: [PATCH 2/2] Update changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 952d5ea12fe9..77b270384646 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,8 +27,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Don't override explicit `leading-*`, `tracking-*`, or `font-{weight}` utilities with font-size utility defaults ([#14403](https://github.com/tailwindlabs/tailwindcss/pull/14403)) +- Preserve explicit `leading-*`, `tracking-*`, and `font-{weight}` value when overriding font-size ([#14403](https://github.com/tailwindlabs/tailwindcss/pull/14403)) - Disallow negative bare values in core utilities and variants ([#14453](https://github.com/tailwindlabs/tailwindcss/pull/14453)) +- Preserve explicit shadow color when overriding shadow size ([#14458](https://github.com/tailwindlabs/tailwindcss/pull/14458)) ## [4.0.0-alpha.24] - 2024-09-11