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

Support for experimental dark mode #10

Closed
timfee opened this issue Sep 22, 2020 · 12 comments
Closed

Support for experimental dark mode #10

timfee opened this issue Sep 22, 2020 · 12 comments

Comments

@timfee
Copy link

timfee commented Sep 22, 2020

Hi there,

When I try to use experimental dark mode, I get an error:

Error: Utility with variant class 'dark' not found"
    at @tailwindcssinjs/tailwindcss-data/lib/transformers/getGenerateTwClassSubstituteRoot.js:52:27

Here's the snippet:

tw`dark[from-blue-400 via-pink-500 to-red-400 bg-gradient-to-tr]`

Here's the config file:

module.exports = {
  experimental: {
    darkModeVariant: true
  },
  future: {
    removeDeprecatedGapUtilities: true,
    purgeLayersByDefault: true
  },
  purge: {
    content: ['./src/**/*.{js,ts,jsx,tsx}', './pages/**/*.{js,ts,jsx,tsx}']
  },
  important: true,
  dark: 'class',
  plugins: [
    require('@tailwindcss/typography')({
      modifiers: []
    }),
    require('@tailwindcss/ui')
  ]
}

Interestingly, the vscode plugin renders a tooltip correctly:
Screen Shot 2020-09-21 at 5 30 25 PM

Any thoughts? :)

@timfee
Copy link
Author

timfee commented Sep 22, 2020

also, FWIW, I'm using with emotion.sh:

// .babelrc
{
    "presets": [
        "next/babel"
    ],
    "plugins": [
        "macros",
        "@emotion/babel-plugin"
    ]
}

Full stack trace

Error: Utility with variant class 'dark' not found"
    at @tailwindcssinjs/tailwindcss-data/lib/transformers/getGenerateTwClassSubstituteRoot.js:52:27
    at transformTwClassesToStyleObjects (@tailwindcssinjs/tailwindcss-data/lib/transformers/transformTwClassesToStyleObject.js:104:27)
    at Object.transformTwClassesToStyleObject (@tailwindcssinjs/tailwindcss-data/lib/transformers/transformTwClassesToStyleObject.js:114:26)
    at tailwind (@tailwindcssinjs/macro/lib/tailwindcssinjs.js:28:46)

@Arthie
Copy link
Owner

Arthie commented Sep 22, 2020

Hello, what version of tailwindcss are you using? It should work on "tailwindcss": "1.8.7",. Later versions broke it again. The current implementation of dark mode in tailwindcss is really unstable.

@timfee
Copy link
Author

timfee commented Sep 22, 2020

Ah, I was using 1.8.10. Moving to 1.8.7 breaks it differently (below).

Even with the plugins out there, it's deceptively challenging to get dark mode done "right" and to have it support classname strategies!

Thanks :)

error - TypeError: corePlugins is not a function or its return value is not iterable
    at Object.tailwindData (/Users/timfee/Developer/timfeeley.com/site/node_modules/@tailwindcssinjs/tailwindcss-data/lib/tailwindcssData.js:39:59)
    at tailwindcssinjs (/Users/timfee/Developer/timfeeley.com/site/node_modules/@tailwindcssinjs/macro/lib/tailwindcssinjs.js:18:163)
    at eval (webpack-internal:///./pages/_app.tsx:24:94)
    at Module../pages/_app.tsx (/Users/timfee/Developer/timfeeley.com/site/.next/server/pages/_app.js:104:1)
    at __webpack_require__ (/Users/timfee/Developer/timfeeley.com/site/.next/server/pages/_app.js:23:31)
    at Object.0 (/Users/timfee/Developer/timfeeley.com/site/.next/server/pages/_app.js:137:18)
    at __webpack_require__ (/Users/timfee/Developer/timfeeley.com/site/.next/server/pages/_app.js:23:31)
    at /Users/timfee/Developer/timfeeley.com/site/.next/server/pages/_app.js:91:18
    at Object.<anonymous> (/Users/timfee/Developer/timfeeley.com/site/.next/server/pages/_app.js:94:10)

@Arthie
Copy link
Owner

Arthie commented Sep 22, 2020

Ah, that's an easy fix. @tailwindcssinjs/macro has to generate a custom coreplugins file to support hot reloading on tailwind.config.js changes.

Please try one of these steps and it should work fine again:

  • Delete the .next folder this contains chached files that will be regenerated when you run next dev
  • Delete node_modules and lock file and reinstall your modules.

Next's heavy caching sometimes causes problems when changing/updating modules.

if it still doesn't work you can disable this feature developmentMode: false, in the babel macro config

@timfee
Copy link
Author

timfee commented Sep 22, 2020

Thanks! That worked.

I ended up writing my own dark mode plugin that replicates the dark class strategy that plays nicely:

// tailwind.conf.js
// ...
  plugins: [
    require('@tailwindcss/typography')({
      modifiers: []
    }),
    require('@tailwindcss/ui'),
    require('./src/plugin-darkmode')
  ],
// ...
// plugin-darkmode.js
const plugin = require('tailwindcss/plugin')

module.exports = plugin(function ({ addVariant, e }) {
  addVariant('dark', ({ container, separator }) => {
    container.walkRules(rule => {
      const clone = rule
      clone.selector = `html.dark .${e(
        `dark${separator}${rule.selector.slice(1)}`
      )}`
    })
  })
})
// browser-script.js
function checkDarkMode() {
  return (
    window.matchMedia &&
    window.matchMedia('(prefers-color-scheme: dark)').matches
  )
}
function watchDarkMode() {
  if (!window.matchMedia) return
  window
    .matchMedia('(prefers-color-scheme: dark)')
    .addListener(addDarkModeSelector)
}
function addDarkModeSelector() {
  if (checkDarkMode()) {
    document.documentElement.classList.add('dark')
  } else {
    document.documentElement.classList.remove('dark')
  }
}
addDarkModeSelector()
watchDarkMode()

@Arthie
Copy link
Owner

Arthie commented Sep 22, 2020

Awesome! Yea that will be the more stable solution until tailwindcss figures it out.

Btw @tailwindcss/ui includes @tailwindcss/typography you can remove this dependency if you'd like.

These are my custom plugins, might be of interest:

Add keyframes to tailwindcss base css

  //Add keyframes to tailwindcss base file
  plugin(function ({ addBase, addUtilities, e, theme, variants }) {
    const keyframesConfig = theme('keyframes')
    const keyframesStyles = Object.fromEntries(
      Object.entries(keyframesConfig).map(([name, keyframes]) => {
        return [`@keyframes ${name}`, keyframes]
      })
    )
    addBase(keyframesStyles)
  })

Add !important variant: important:bg-red-300

  //Add !important variant: important
  plugin(function ({ addVariant }) {
    addVariant('important', ({ container }) => {
      container.walkRules(rule => {
        rule.selector = `.\\!${rule.selector.slice(1)}`
        rule.walkDecls(decl => {
          decl.important = true
        })
      })
    })
  })

@timfee
Copy link
Author

timfee commented Sep 22, 2020

Thanks! The important one will be super handy :)

@timfee timfee closed this as completed Sep 22, 2020
@timfee
Copy link
Author

timfee commented Sep 22, 2020

and thanks for the tailwindui / typography tip. I was wondering why my classes were duplicated!

@timfee timfee reopened this Sep 22, 2020
@timfee
Copy link
Author

timfee commented Sep 22, 2020

hey, reopening so it delivers a notification (not sure how exactly Github determines when to ping you).

It turns out that for dark mode to fully traverse typography correctly, it needs a little more elbow grease.

I found this approach, but the macro doesn’t seem to like the nested colon syntax for addVariant("dark:typography", ({ modifySelectors, separator })

If I rename the variant to darktypography, it works fine.

Maybe WAI and too edge casey to care about, but figured I’d ping :)

@Arthie
Copy link
Owner

Arthie commented Sep 22, 2020

Interesting, the tailwind classes parser only knows about the separator. It thinks its 2 different variants (dark variant and typography variant). Since this can be confusing I would argue that you made the better/clearer choice with darktypography or dark-typography.

I could add the variants list to the classes parser to fix this but since this is indeed an edge case I'll leave it for now.
Thanks!

@Arthie Arthie closed this as completed Sep 24, 2020
@sondh0127
Copy link

sondh0127 commented Oct 19, 2020

I wonder how you do the dark mode now. With tailwind 1.9.x @Arthie Thanks

@Arthie
Copy link
Owner

Arthie commented Oct 19, 2020

I wonder how you do the dark mode now. With tailwind 1.9.x @Arthie Thanks

@sondh0127 you'll have to add the dark mode plugin from tailwindcss in your tailwind.config.js. This will be necessary until dark mode becomes a non-experimental feature.

Example:

//tailwind.config.js
module.exports = {
  // ... config options
  dark: 'media', // or 'class'
  experimental: "all",
  future: "all",
  plugins: [
    require("tailwindcss/lib/flagged/darkModeVariantPlugin").default
  ]
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants