Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add future flag to preserve custom, default ring color opacity #8448

Merged
merged 3 commits into from May 27, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -51,6 +51,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Experimental support for variant grouping ([#8405](https://github.com/tailwindlabs/tailwindcss/pull/8405))
- Add opacity support when referencing colors with `theme` function ([#8416](https://github.com/tailwindlabs/tailwindcss/pull/8416))
- Add `postcss-import` support to the CLI ([#8437](https://github.com/tailwindlabs/tailwindcss/pull/8437))
- Add future flag to preserve custom, default ring color opacity ([#8448](https://github.com/tailwindlabs/tailwindcss/pull/8448))

## [3.0.24] - 2022-04-12

Expand Down
21 changes: 14 additions & 7 deletions src/corePlugins.js
Expand Up @@ -1977,13 +1977,20 @@ export let corePlugins = {
)
},

ringWidth: ({ matchUtilities, addDefaults, addUtilities, theme }) => {
let ringOpacityDefault = theme('ringOpacity.DEFAULT', '0.5')
let ringColorDefault = withAlphaValue(
theme('ringColor')?.DEFAULT,
ringOpacityDefault,
`rgb(147 197 253 / ${ringOpacityDefault})`
)
ringWidth: ({ matchUtilities, addDefaults, addUtilities, theme, config }) => {
let ringColorDefault = (() => {
if (flagEnabled(config(), 'respectDefaultRingColorOpacity')) {
return theme('ringColor.DEFAULT')
}

let ringOpacityDefault = theme('ringOpacity.DEFAULT', '0.5')

return withAlphaValue(
theme('ringColor')?.DEFAULT,
ringOpacityDefault,
`rgb(147 197 253 / ${ringOpacityDefault})`
)
})()

addDefaults('ring-width', {
'--tw-ring-inset': ' ',
Expand Down
2 changes: 1 addition & 1 deletion src/featureFlags.js
Expand Up @@ -6,7 +6,7 @@ let defaults = {
}

let featureFlags = {
future: ['hoverOnlyWhenSupported'],
future: ['hoverOnlyWhenSupported', 'respectDefaultRingColorOpacity'],
experimental: ['optimizeUniversalDefaults', 'variantGrouping'],
}

Expand Down
7 changes: 7 additions & 0 deletions src/util/getAllConfigs.js
Expand Up @@ -9,6 +9,13 @@ export default function getAllConfigs(config) {

const features = {
// Add experimental configs here...
respectDefaultRingColorOpacity: {
theme: {
ringColor: {
DEFAULT: '#3b82f67f',
},
},
},
}

const experimentals = Object.keys(features)
Expand Down
2 changes: 1 addition & 1 deletion stubs/defaultConfig.stub.js
Expand Up @@ -720,7 +720,7 @@ module.exports = {
8: '8px',
},
ringColor: ({ theme }) => ({
DEFAULT: theme('colors.blue.500', '#3b82f6'),
DEFAULT: theme(`colors.blue.500`, '#3b82f6'),
...theme('colors'),
}),
ringOffsetColor: ({ theme }) => theme('colors'),
Expand Down
234 changes: 234 additions & 0 deletions tests/basic-usage.test.js
Expand Up @@ -430,3 +430,237 @@ it('supports multiple backgrounds as arbitrary values even if only some are quot
`)
})
})

it('The "default" ring opacity is used by the default ring color when not using respectDefaultRingColorOpacity (1)', () => {
let config = {
content: [{ raw: html`<div class="ring"></div>` }],
corePlugins: { preflight: false },
}

let input = css`
@tailwind base;
@tailwind utilities;
`

return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
${defaults({ defaultRingColor: 'rgb(59 130 246 / 0.5)' })}
.ring {
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width)
var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width))
var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
`)
})
})

it('The "default" ring opacity is used by the default ring color when not using respectDefaultRingColorOpacity (2)', () => {
let config = {
content: [{ raw: html`<div class="ring"></div>` }],
corePlugins: { preflight: false },
theme: {
ringOpacity: {
DEFAULT: 0.75,
},
},
}

let input = css`
@tailwind base;
@tailwind utilities;
`

return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
${defaults({ defaultRingColor: 'rgb(59 130 246 / 0.75)' })}
.ring {
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width)
var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width))
var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
`)
})
})

it('Customizing the default ring color uses the "default" opacity when not using respectDefaultRingColorOpacity (1)', () => {
let config = {
content: [{ raw: html`<div class="ring"></div>` }],
corePlugins: { preflight: false },
theme: {
ringColor: {
DEFAULT: '#ff7f7f',
},
},
}

let input = css`
@tailwind base;
@tailwind utilities;
`

return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
${defaults({ defaultRingColor: 'rgb(255 127 127 / 0.5)' })}
.ring {
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width)
var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width))
var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
`)
})
})

it('Customizing the default ring color uses the "default" opacity when not using respectDefaultRingColorOpacity (2)', () => {
let config = {
content: [{ raw: html`<div class="ring"></div>` }],
corePlugins: { preflight: false },
theme: {
ringColor: {
DEFAULT: '#ff7f7f00',
},
},
}

let input = css`
@tailwind base;
@tailwind utilities;
`

return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
${defaults({ defaultRingColor: 'rgb(255 127 127 / 0.5)' })}
.ring {
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width)
var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width))
var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
`)
})
})

it('The "default" ring color ignores the default opacity when using respectDefaultRingColorOpacity (1)', () => {
let config = {
future: { respectDefaultRingColorOpacity: true },
content: [{ raw: html`<div class="ring"></div>` }],
corePlugins: { preflight: false },
}

let input = css`
@tailwind base;
@tailwind utilities;
`

return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
${defaults({ defaultRingColor: '#3b82f67f' })}
.ring {
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width)
var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width))
var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
`)
})
})

it('The "default" ring color ignores the default opacity when using respectDefaultRingColorOpacity (2)', () => {
let config = {
future: { respectDefaultRingColorOpacity: true },
content: [{ raw: html`<div class="ring"></div>` }],
corePlugins: { preflight: false },
theme: {
ringOpacity: {
DEFAULT: 0.75,
},
},
}

let input = css`
@tailwind base;
@tailwind utilities;
`

return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
${defaults({ defaultRingColor: '#3b82f67f' })}
.ring {
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width)
var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width))
var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
`)
})
})

it('Customizing the default ring color preserves its opacity when using respectDefaultRingColorOpacity (1)', () => {
let config = {
future: { respectDefaultRingColorOpacity: true },
content: [{ raw: html`<div class="ring"></div>` }],
corePlugins: { preflight: false },
theme: {
ringColor: {
DEFAULT: '#ff7f7f',
},
},
}

let input = css`
@tailwind base;
@tailwind utilities;
`

return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
${defaults({ defaultRingColor: '#ff7f7f' })}
.ring {
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width)
var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width))
var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
`)
})
})

it('Customizing the default ring color preserves its opacity when using respectDefaultRingColorOpacity (2)', () => {
let config = {
future: { respectDefaultRingColorOpacity: true },
content: [{ raw: html`<div class="ring"></div>` }],
corePlugins: { preflight: false },
theme: {
ringColor: {
DEFAULT: '#ff7f7f00',
},
},
}

let input = css`
@tailwind base;
@tailwind utilities;
`

return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
${defaults({ defaultRingColor: '#ff7f7f00' })}
.ring {
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width)
var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width))
var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
`)
})
})