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

Access SASS variables from css-module in a React component #86

Closed
hdmchl opened this issue Nov 20, 2015 · 8 comments
Closed

Access SASS variables from css-module in a React component #86

hdmchl opened this issue Nov 20, 2015 · 8 comments

Comments

@hdmchl
Copy link

hdmchl commented Nov 20, 2015

I have a React component that is using css-modules. Is there a way for me to get access to the SASS variables used in the css-module?

My styles.scss file is using a shared _colors.scss file. My files look something like this (note the comment for use-case):

index.jsx

import styles from './styles';
import React from 'react';
import SomeFooBarComponent from 'irrelevant';

export default class MyComponent extends React.Component {
  render() {
    return (
      <div className={styles.root}>
        <h1>My amazing page</h1>
{/* I want to use a variable here, rather than hard-code the color. 
I want that variable to come from my imported styles file (i.e. through the `styles` object) */}
        <SomeFooBarComponent takesAColorProperty="#00FF00" />
      </div>
    );
  }
}

shared/variables/_colors.scss

$brand-primary: #FF0000;
$brand-secondary: #00FF00;

styles.scss

@import "~shared/variables/colors";

.root {
  color: $brand-primary;
}
@hdmchl
Copy link
Author

hdmchl commented Nov 20, 2015

Speaking to @geelen we first tried using @value by adding the following line to styles.scss:

@value brandSecondary "#{$brand-secondary}";

This worked, but it returned a string of a string { brandSecondary: ""#00FF00"" }

FINAL SOLUTION that worked (again on suggestion from Glen) was to use: :export { ... } which comes from ICSS.

I am now doing the following, and it works nicely:

styles.scss

@import "~shared/variables/colors";

:export { brandSecondary: $brand-secondary; }

.root {
  color: $brand-primary;
}

index.jsx

...
        <SomeFooBarComponent takesAColorProperty={styles.brandSecondary} />
...

@hdmchl hdmchl changed the title Access SASS variables (e.g. colors) in a React component Access SASS variables (e.g. colors) from css-module in a React component Nov 20, 2015
@hdmchl hdmchl changed the title Access SASS variables (e.g. colors) from css-module in a React component Access SASS variables from css-module in a React component Nov 20, 2015
@teameh
Copy link

teameh commented Jan 6, 2016

This is awesome

@axelson
Copy link

axelson commented Apr 18, 2016

@hadimichael Can you explain how this is working? I would've expected something more like this for index.jsx:

...
        import styles from './styles.scss'
...
        <SomeFooBarComponent takesAColorProperty={styles.brandSecondary} />
...

Otherwise when just given a string how does <SomeFooBarComponent> find the style value?

@hdmchl
Copy link
Author

hdmchl commented Apr 20, 2016

@axelson you're totally right! Typo on my behalf, thanks for pointing it out. Edited above.

@hdmchl hdmchl closed this as completed Apr 20, 2016
@GuillaumeCisco
Copy link

GuillaumeCisco commented Aug 11, 2016

Thank you @axelson and @hadimichael
Just tried it! And it works well!
Only drawback, it breaks webpack HMR when I modify one of my css file.
This is due to :export.
Any idea how to make it works with HMR?
I'm thinking of something like that I use fro my reducers :

    //Hot reload reducers (requires Webpack or Browserify HMR to be enabled)
    if (module.hot) {
        module.hot.accept('./reducers', () =>
            store.replaceReducer(require('./reducers').default/* if you use Babel 6+ */)
        );
    }

But not sure how to adapt it to my scss files...
If someone has an idea :)

EDIT: Just made it work with this project https://github.com/nordnet/sass-variable-loader.
Awesome work guys! Thanks!

@v-trof
Copy link

v-trof commented Jul 31, 2017

If you don't need all your variables \ install one more loader
Now

@value brandSecondary #{$brand-secondary} works just as fine

@milewski
Copy link

This totally breaks my HMR too... any way to fix this?

@ShahriarKh
Copy link

styles.scss

@import "~shared/variables/colors";

:export { brandSecondary: $brand-secondary; }

.root {
  color: $brand-primary;
}

index.jsx

...
        <SomeFooBarComponent takesAColorProperty={styles.brandSecondary} />
...

Thanks for this great solution!
If anyone is still confused how to use variable color name to select from the list, use this:

let selectedColor = "brandSecondary";
<SomeFooBarComponent takesAColorProperty={styles[selectedColor] />

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

7 participants