treat icon indicating copy to clipboard operation
treat copied to clipboard

Why can't I use `:hover` with `globalStyle`?

Open willhoney7 opened this issue 5 years ago • 4 comments

Thank you for this excellent library! I'm a big fan of zero runtime css-in-js and typescript.

I've been using globalStyle a lot because we've been doing our css with our own "toolkit" similar to tailwindcss or basscss. We still have legacy code in angularjs and it's nice to be able to share these common classes between frameworks. globalStyle lets us still define those classes in typescript (with our theme variables) but use them anywhere in the app.

I've noticed the TS definitions for globalStyle don't allow for a :hover selector.

import { globalStyle } from 'treat';

globalStyle('a', {
    color: 'red',
    ':hover': { // Argument of type '{ color: string; ':hover': any; }' is not assignable to parameter of type 'ThemedStyle<GlobalStyle, any>'.
        color: 'orange'
    }
})

Is there a technical reason for this? I can do this as an alternative, but it's not as clean.

import { globalStyle } from 'treat';

globalStyle('a', {
    color: 'red',
})
globalStyle('a:hover', {
    color: 'orange'
})

Thanks again for this excellent library.

willhoney7 avatar Jan 22 '20 23:01 willhoney7

Hey 👋,

The reason you can't use pseudos in globalStyle is because we don't control what it is attached to.

For example, what should the following compile to?

globalStyle('div, .someClass:active', {
  color: 'orange',
  ':hover': {
    color: 'blur'
  }
})

Also, if your legacy code is using webpack there's no reason you can't use treat imports there too. However, I understand it may be a "don't touch the legacy" type scenario 😅

mattcompiles avatar Jan 22 '20 23:01 mattcompiles

Thanks for your response! That makes sense. I was imagining treat was processing the css selector somehow. Now I'm thinking it basically generates a css string from the style object and calls CSSStyleSheet.insertRule()? Supporting :hover or other selectors would be more complicated. I still think it would be useful, but can understand not wanting to support it.

re: your example

globalStyle('div, .someClass:active', {
  color: 'orange',
  ':hover': {
    color: 'blue'
  }
})

// would be equivalent to 

globalStyle('div, .someClass:active', {
  color: 'orange',
})

globalStyle('div:hover, .someClass:active:hover', {
  color: 'blue,
})

willhoney7 avatar Jan 23 '20 16:01 willhoney7

To @Tibfib point, this is what scss does too. Eg:

div, .someClass:active {
   &:hover {
       color: red
   }
}

// is
div:hover, .someClass:active:hover {
     color: red
}

so yeah, think this feature should be something worth adding. Perhaps @Tibfib you could investigate this further, and add a PR?

maraisr avatar Feb 11 '20 02:02 maraisr

I would love to create a PR for this... However, I don't foresee having time to work on this in the near future. 😞

I wasn't sure if I was doing something wrong or if the ts definitions were wrong. I think this would be a valuable feature to add but I can't put my money where my mouth is to implement.

willhoney7 avatar Feb 20 '20 22:02 willhoney7