ketan
ketan

Reputation: 19341

How to reuse SASS variable in JavaScript

I have list of color variables in JavaScript file as an Object.

export const colors = [
{
    colorVariable: "$ui-background"
},
{
    colorVariable: "$ui-01"
},
{
    colorVariable: "$ui-02"
},
...
]

I created above object file based on scss file which have list of 50 colors. I used same name as scss variable So, i can use scss variable in my React component.

$carbon--theme: (
    ui-background: #ffffff,
    ui-01: #f3f3f3,
    ui-02: #ffffff,
    ...
)

I imported those colors to jsx file from color.js file.

import { colors } from './theme';

And i want use that color variable to give background of following div. I tried following way So, i can apply scss variable. But, not working.

component.jsx

Code:

Object.keys(colors).map(key => {
        return (
        <div style={{ background: colors[key].colorVariable }} className={'theme-color')} />
        )
})

I tried many things but nothing worked. Any help would be greatly appreciated. (It would be nice if i can use that variable in css (component.scss) file inside theme-color class. If not then ok ).

I am using react 16. Any help would be greatly appreciated and let me know if any questions.

Upvotes: 1

Views: 3492

Answers (1)

abuduba
abuduba

Reputation: 5042

First of all - the SASS variables does not exist on runtime. Are available only during compilation time. The output CSS file does not include the SASS variables at all because and replaces any variable occurence with the raw value.

You might create CSS variables basing on the SCSS counterparts, then reuse the CSS variables in your code.

:root { /* or your element selector instead of `:root` so the variables will be scoped */
  --ui-background: #{map-get($carbon--theme, "ui-background")};
  --ui-01: #{map-get($carbon--theme, "ui-01")};
  --ui-02: #{map-get($carbon--theme, "ui-02")};
}

Just create additional SASS/SCSS file with the snippet above.

Then simply adjust the values in the colors variable.

export const colors = [
  {
    colorVariable: "var(--ui-background)"
  },
  {
    colorVariable: "var(--ui-01)"
  },
  {
    colorVariable: "var(--ui-02)"
  }
]

It perfectly works in runtime.

Bonus - if for some reason you need to reuse every color you might just iterate over the theme map using SASS's @each flow-control rule like:

:root { /* or your element selector */
  @each $name, $color in $carbon--theme {
    --#{$name}: #{$color};
  }
}

BTW The colors variable is an array so you don't need to get the keys in order to iterate over it.

There is an additional problem that probably throws an error: className={'theme-color')} - you have a closing paren ) there. Anyway, for the string values you can simply omit the JSX placeholders and pass the value directly in quotes. Look at the fixed example:

colors.map(
  (item) => <div key={item.colorVariable} style={{ background: item.colorVariable }} className="theme-color"/>
);

If the colors array consists only with the color values you might simply replace it with array of strings like: ['--ui01', '--ui02', ...]

Then it is even simpler:

colors.map(
  (color) => <div key={color} style={{ background: color }} className="theme-color"/>
);

BTW #2. If for some reason you don't want to use the CSS variables the other option is to use some library like scss-to-json that extracts the SCSS variables and outputs as JSON. This require an additional build step as well as importing/merging the JSON in your code base.

Upvotes: 1

Related Questions