From 1544ef576d48b9b20bbee14deb6e6bf8206ed242 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Thu, 21 Dec 2023 10:34:09 -0500 Subject: [PATCH] Add dark mode variant option --- src/corePlugins.js | 14 ++++++++++++++ tests/dark-mode.test.js | 23 +++++++++++++++++++++++ types/config.d.ts | 2 ++ 3 files changed, 39 insertions(+) diff --git a/src/corePlugins.js b/src/corePlugins.js index 6b2f88ffc..4f396b591 100644 --- a/src/corePlugins.js +++ b/src/corePlugins.js @@ -225,12 +225,26 @@ export let variantPlugins = { 'Change `darkMode` to `media` or remove it entirely.', 'https://tailwindcss.com/docs/upgrade-guide#remove-dark-mode-configuration', ]) + } else if (mode === 'variant' && className === '.dark') { + mode = false + log.warn('darkmode-variant-without-selector', [ + 'darkMode: "variant" was used without a provided selector.', + 'Change to `darkMode: ["variant", ".your-selector &"]` ', + ]) + } else if (mode === 'variant' && !className.includes('&')) { + mode = false + log.warn('darkmode-variant-without-ampersand', [ + 'A custom dark mode selector was used without an `&` — a `&` is required to correctly scope the custom selector.', + 'Change to `darkMode: ["variant", ".your-selector &"]` ', + ]) } if (mode === 'class') { addVariant('dark', `:is(:where(${className}) &)`) } else if (mode === 'media') { addVariant('dark', '@media (prefers-color-scheme: dark)') + } else if (mode === 'variant') { + addVariant('dark', className) } }, diff --git a/tests/dark-mode.test.js b/tests/dark-mode.test.js index 276c6c9e3..924a9f335 100644 --- a/tests/dark-mode.test.js +++ b/tests/dark-mode.test.js @@ -119,3 +119,26 @@ it('should default to the `media` mode when mode is set to `false`', () => { `) }) }) + +it('should allow customization of the dark mode variant', () => { + let config = { + darkMode: ['variant', '&:not(.light *)'], + content: [{ raw: html`
` }], + corePlugins: { preflight: false }, + } + + 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; + } + `) + }) +}) diff --git a/types/config.d.ts b/types/config.d.ts index 051ccad5b..69ea448df 100644 --- a/types/config.d.ts +++ b/types/config.d.ts @@ -75,6 +75,8 @@ type DarkModeConfig = | 'class' // Use the `class` strategy with a custom class instead of `.dark`. | ['class', string] + // Use the `variant` strategy, which allows you to completely customize the selector + | ['variant', string] type Screen = { raw: string } | { min: string } | { max: string } | { min: string; max: string } type ScreensConfig = string[] | KeyValuePair