javivelasco / react-css-themr

Easy theming and composition for CSS Modules.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Context class order

doejon opened this issue · comments

Hi there!
First of all - thanks a lot for your library!
I was working now quite a bit on some issue I tried to solve.
Let's assume I do have a default button from react-toolbox/lib/button
that I'd love to style using ThemeProvider.
I do add my own styles through RTButton and expect default values to be overwritten.
They'll get rendered into something like class="test__button___hPsIx [...]".
Though when looking at the output, I get the default stylesheet set second in place (which will therefore overwrite my own styles set in test__button___hp...)
The whole class looks something like class="test__button___hPsIx theme__button___1iKuo " whereas second in place is the default lib/button style.

What's the easiest way to overwrite default styles without using !important all the time? Is there by chance a possibility to re-arrange class order - or some other way possible I'm not quite aware of?

Cheers
Korbi

There are no any difference of classes order. If the classes have the same specificity (https://www.smashingmagazine.com/2007/07/css-specificity-things-you-should-know/) the last class declaration wins.

<div class="a b c">TEST</div>
.c {color: red}
.a {color: blue}
.b {color: green}

You will see green TEST.

So you may try to set composeTheme prop to softly or false to override context styles with theme prop.

Thanks @k0r8i! First of all you need to make clear what kind of customization do you want to make. As @denisborovikov pointed, the class order does not affect the final styles applied. If you want to override a class (not a particular style but all the styles that class is setting) you probably should use composeTheme to specify so because themr assumes you want to concatenate with the original classes to override a style.

Of course, if you give a module via context you are not specializing the selector more than the original styles do. You either have to be more specific than the original or to be equal but bundling your styles after the original. I think you can do it sorting imports.

Finally I want to add that RT components come styled only if you import them from the index. If you want to import an unstyled component that can take styles from context you should import from the very component.

Thanks @denisborovikov for your answer!

One more thing. The most common use case for the context in react toolbox is when you import every component raw and feed the styles through there. So you may want to add styles for every component used in your application. This is exactly what the new playground is going to do: processing the theme live using postcss and then process it using postcss-modules to get a module that can be injected using the ThemeProvider. 😁

@denisborovikov darn, you're right - I got a bit confused there...
Just to get a feeling on how files will become included when using themr:

import { ThemeProvider } from 'react-css-themr';
import ReactDOM from 'react-dom';
import Button from "react-toolbox/lib/button";

const Theme = {
  RTButton: require('./test.scss')
}

ReactDOM.render((
  <ThemeProvider theme={Theme}>
      <Button primary raised>Yippee!</Button>
  </ThemeProvider>
), document.getElementById('__main'));

... with test.scss

.button{
  color: #000000;
}

How would I have to sort includes to successfully get test.scss included before the default lib/button/theme.scss? (not to mention using config variables in that case would be possible as well ;) )

In your example I guess the original styles would be bundled before but you shouldn't relay on it. You are importing Button from lib/button so it will come with styles bundled. If you want to pass a theme to a Button that has styles probably what you want to do is to create an specific type of button with some overrides. I would suggest to create a specific type of button instead of passing styles using the context:

const CustomButton = props => <Button {...props} className={buttonTheme.root} theme={buttonTheme} />

If what you want to do is override styles for all buttons in your application, instead of importing the Button with styles you should import it raw. Then your theme included in the context will be the only one used by the button. To override defaults in that case I'd better import the SCSS from the SCSS theme and then add overriding rules. Then what you are importing and injecting is the base, not some overrides.

The context is used to achieve that kind of things. Changes that affects every single component.

Awesome, that perfectly clarified my (mis)understandings!
Alright - importing 'react-toolbox/components/button/Button.js' and setting styles works just as expected.

🍻

Great! 💃