Add legacy dark mode option
This commit is contained in:
parent
a94a21257a
commit
543dacf81a
4 changed files with 155 additions and 4 deletions
|
|
@ -242,6 +242,9 @@ export let variantPlugins = {
|
|||
|
||||
if (mode === 'class') {
|
||||
addVariant('dark', `:is(:where(${className}) &)`)
|
||||
} else if (mode === 'legacy') {
|
||||
// Exists for pre v3.4 compatibility
|
||||
addVariant('dark', `:is(${className} &)`)
|
||||
} else if (mode === 'media') {
|
||||
addVariant('dark', '@media (prefers-color-scheme: dark)')
|
||||
} else if (mode === 'variant') {
|
||||
|
|
|
|||
|
|
@ -765,6 +765,27 @@ function resolvePlugins(context, root) {
|
|||
variantPlugins['forcedColorsVariants'],
|
||||
]
|
||||
|
||||
// This is a compatibility fix for the pre 3.4 dark mode behavior
|
||||
// You can enable the old behavior by setting `darkMode: ['legacy', selector]`
|
||||
let isLegacyDarkMode = context.tailwindConfig.darkMode === 'legacy'
|
||||
|| (Array.isArray(context.tailwindConfig.darkMode) && context.tailwindConfig.darkMode[0] === 'legacy')
|
||||
|
||||
if (isLegacyDarkMode) {
|
||||
afterVariants = [
|
||||
variantPlugins['supportsVariants'],
|
||||
variantPlugins['directionVariants'],
|
||||
variantPlugins['reducedMotionVariants'],
|
||||
variantPlugins['prefersContrastVariants'],
|
||||
variantPlugins['printVariant'],
|
||||
variantPlugins['darkVariants'],
|
||||
variantPlugins['screenVariants'],
|
||||
variantPlugins['orientationVariants'],
|
||||
|
||||
// Forced colors didn't exist before 3.4 so it can keep its position at the end
|
||||
variantPlugins['forcedColorsVariants'],
|
||||
]
|
||||
}
|
||||
|
||||
return [...corePluginList, ...beforeVariants, ...userPlugins, ...afterVariants, ...layerPlugins]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -120,6 +120,108 @@ it('should default to the `media` mode when mode is set to `false`', () => {
|
|||
})
|
||||
})
|
||||
|
||||
it('should support legacy dark mode behavior', () => {
|
||||
let config = {
|
||||
darkMode: 'legacy',
|
||||
content: [{ raw: html`<div class="dark:font-bold"></div>` }],
|
||||
corePlugins: { preflight: false },
|
||||
}
|
||||
|
||||
let input = css`
|
||||
@tailwind utilities;
|
||||
`
|
||||
|
||||
return run(input, config).then((result) => {
|
||||
expect(result.css).toMatchFormattedCss(css`
|
||||
:is(.dark .dark\:font-bold) {
|
||||
font-weight: 700;
|
||||
}
|
||||
`)
|
||||
})
|
||||
})
|
||||
|
||||
it('should support custom classes with legacy dark mode', () => {
|
||||
let config = {
|
||||
darkMode: ['legacy', '.my-dark'],
|
||||
content: [{ raw: html`<div class="dark:font-bold"></div>` }],
|
||||
corePlugins: { preflight: false },
|
||||
}
|
||||
|
||||
let input = css`
|
||||
@tailwind utilities;
|
||||
`
|
||||
|
||||
return run(input, config).then((result) => {
|
||||
expect(result.css).toMatchFormattedCss(css`
|
||||
:is(.my-dark .dark\:font-bold) {
|
||||
font-weight: 700;
|
||||
}
|
||||
`)
|
||||
})
|
||||
})
|
||||
|
||||
it('should use legacy sorting when using darkMode: legacy', () => {
|
||||
let config = {
|
||||
darkMode: 'legacy',
|
||||
content: [{ raw: html`<div class="dark:text-green-100 hover:text-green-200 lg:text-green-300"></div>` }],
|
||||
corePlugins: { preflight: false },
|
||||
}
|
||||
|
||||
let input = css`
|
||||
@tailwind utilities;
|
||||
`
|
||||
|
||||
return run(input, config).then((result) => {
|
||||
expect(result.css).toMatchFormattedCss(css`
|
||||
.hover\:text-green-200:hover {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(187 247 208 / var(--tw-text-opacity));
|
||||
}
|
||||
:is(.dark .dark\:text-green-100) {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(220 252 231 / var(--tw-text-opacity));
|
||||
}
|
||||
@media (min-width: 1024px) {
|
||||
.lg\:text-green-300 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(134 239 172 / var(--tw-text-opacity));
|
||||
}
|
||||
}
|
||||
`)
|
||||
})
|
||||
})
|
||||
|
||||
it('should use modern sorting otherwise', () => {
|
||||
let config = {
|
||||
darkMode: 'class',
|
||||
content: [{ raw: html`<div class="dark:text-green-100 hover:text-green-200 lg:text-green-300"></div>` }],
|
||||
corePlugins: { preflight: false },
|
||||
}
|
||||
|
||||
let input = css`
|
||||
@tailwind utilities;
|
||||
`
|
||||
|
||||
return run(input, config).then((result) => {
|
||||
expect(result.css).toMatchFormattedCss(css`
|
||||
.hover\:text-green-200:hover {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(187 247 208 / var(--tw-text-opacity));
|
||||
}
|
||||
@media (min-width: 1024px) {
|
||||
.lg\:text-green-300 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(134 239 172 / var(--tw-text-opacity));
|
||||
}
|
||||
}
|
||||
:is(:where(.dark) .dark\:text-green-100) {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(220 252 231 / var(--tw-text-opacity));
|
||||
}
|
||||
`)
|
||||
})
|
||||
})
|
||||
|
||||
it('should allow customization of the dark mode variant', () => {
|
||||
let config = {
|
||||
darkMode: ['variant', '&:not(.light *)'],
|
||||
|
|
@ -128,17 +230,37 @@ it('should allow customization of the dark mode variant', () => {
|
|||
}
|
||||
|
||||
let input = css`
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
`
|
||||
|
||||
return run(input, config).then((result) => {
|
||||
expect(result.css).toMatchFormattedCss(css`
|
||||
${defaults}
|
||||
.dark\:font-bold:not(.light *) {
|
||||
font-weight: 700;
|
||||
}
|
||||
`)
|
||||
})
|
||||
})
|
||||
|
||||
it('should support parallel selectors for the dark mode variant', () => {
|
||||
let config = {
|
||||
darkMode: ['variant', ['&:not(.light *)', '&:not(.extralight *)']],
|
||||
content: [{ raw: html`<div class="dark:font-bold"></div>` }],
|
||||
corePlugins: { preflight: false },
|
||||
}
|
||||
|
||||
let input = css`
|
||||
@tailwind utilities;
|
||||
`
|
||||
|
||||
return run(input, config).then((result) => {
|
||||
expect(result.css).toMatchFormattedCss(css`
|
||||
.dark\:font-bold:not(.light *) {
|
||||
font-weight: 700;
|
||||
}
|
||||
.dark\:font-bold:not(.extralight *) {
|
||||
font-weight: 700;
|
||||
}
|
||||
`)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
7
types/config.d.ts
vendored
7
types/config.d.ts
vendored
|
|
@ -75,8 +75,13 @@ type DarkModeConfig =
|
|||
| 'class'
|
||||
// Use the `class` strategy with a custom class instead of `.dark`.
|
||||
| ['class', string]
|
||||
// Use the `legacy` strategy — same as `class` but restores pre-v3.4 behavior
|
||||
| 'legacy'
|
||||
// Use the `legacy` strategy with a custom class instead of `.dark`
|
||||
| ['legacy', string]
|
||||
// Use the `variant` strategy, which allows you to completely customize the selector
|
||||
| ['variant', string]
|
||||
// It takes a string or an array of strings, which are passed directly to `addVariant()`
|
||||
| ['variant', string | string[]]
|
||||
|
||||
type Screen = { raw: string } | { min: string } | { max: string } | { min: string; max: string }
|
||||
type ScreensConfig = string[] | KeyValuePair<string, string | Screen | Screen[]>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue