Using SASS variables in JavaScript: A guide

My JavaScript file contains a list of color variables as an Object.

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

The Object above is derived from a scss file which holds 50 colors. I named the objects in line with the scss variables so I can easily use them in my React component.

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

I have imported these colors to my jsx file from a color.js file.

import { colors } from './theme';

Now, I am trying to set the background of a div using one of those color variables. However, the usual approach is not working for me.

component.jsx

Code:

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

I have tried different methods but none seem to be effective. Any assistance on this matter would be highly appreciated. (It would be preferable if I could also apply the variable in a css file within the theme-color class. If not possible, that's okay too).

I am currently utilizing react 16. Your help and guidance would be greatly valued.

Answer №1

Initially, it's important to note that SASS variables are not available during runtime but only at compilation time. The resulting CSS file does not contain any SASS variables as it replaces them with their raw values.

To work around this limitation, you can create CSS variables based on your SCSS counterparts and then use these CSS variables in your code.

:root { 
  --ui-background: #{map-get($carbon--theme, "ui-background")};
  --ui-01: #{map-get($carbon--theme, "ui-01")};
  --ui-02: #{map-get($carbon--theme, "ui-02")};
}

Simply create an additional SASS/SCSS file with the provided snippet above and adjust the values in the colors variable accordingly.

This method works seamlessly during runtime.

As a bonus tip, if you need to iterate over every color in the theme map, you can utilize SASS's @each flow-control rule like shown below:

:root {
  @each $name, $color in $carbon--theme {
    --#{$name}: #{$color};
  }
}

In addition, the colors variable is structured as an array, eliminating the need to extract keys for iteration.

One potential issue to watch out for is: className={'theme-color')} - there appears to be an extra closing parenthesis here. For string values, simply pass the value directly in quotes without using JSX placeholders.

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

If the colors array consists solely of color values, you can simplify it by replacing it with an array of strings like: ['--ui01', '--ui02', ...]

With this approach, the mapping becomes even more straightforward:

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

Lastly, if you prefer not to use CSS variables, another option is to utilize a library such as scss-to-json which extracts SCSS variables and outputs them as JSON. This will require an additional build step and importing/merging the JSON into your codebase.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

When clicking on links that are not within the ng-view element, you will be redirected to the

I'm having trouble coming up with a name for this question, but here's my current situation This is the structure of my template: ├── index.html ├── ... ├── account │ ├── index.html │ ├── authorizat ...

Using NPM in conjunction with a PHP/STATIC web site directory structure: A comprehensive guide

My PHP website has a file structure like this: / css/ js/ index.php When I run the following commands: npm init npm install <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="eb8984849f989f998a9babdfc5dd">[email p ...

Unable to maintain active status on Vuejs (PrimeVue) Sidebar component leads to malfunction

I currently have a PrimeVue Sidebar component set up with a dynamic component being passed to it. At the moment, I am only using a single component to test this functionality. <Sidebar v-model:visible="sidebarState" :baseZIndex="1000" ...

Troubleshooting Problem with React Hooks When Invoking useState

I'm currently working on a React Todo component and encountering an issue. Here is the code snippet: import React, { useState } from 'react'; const todo = props => { const inputState = useState('') // facing an issue with t ...

Troubleshooting: React promise not functioning in functional component due to issues with UseEffect and UseState

I'm facing a challenge in fetching data and updating the state in a functional component using useEffect and useState. The issue arises when I try to separate the data fetching logic, which is done with axios async/await, into a different file for be ...

Issue with passing parameter in Jquery AJAX request to controller function

Currently, I am integrating a Jquery AJAX Call into my MVC Application. Here is an overview of how my view is structured: <p> Name @Html.TextBox("Name") Date @Html.TextBox("Date") <input type="submit" id="SubmitName" value="Submit" /& ...

Updating UI in React after submitting a modal form

One of the challenges I'm facing is ensuring that my modal form on a page updates consistently each time an item is added to a list and saved in a SQL database. Sometimes, the page updates immediately after adding an item, while other times it saves t ...

Protractor performs the afterEach function prior to the expectations being met

I am completely baffled by the behavior of this code. Everything seems to be executing correctly up until the 'expect' statement, at which point it abruptly navigates to a new page and runs the afterEach function. I've tried various solution ...

Looking to streamline a JavaScript function, while also incorporating jQuery techniques

I've got this lengthy function for uploading photos using hidden iFrames, and while it does the job well, it's quite messy. I'm looking to simplify it into a cleaner function with fewer lines of code for easier maintenance. function simplif ...

Unexpected resizing occurs when SVGs are nested within each other

I am experimenting with using nested inline SVGs to creatively position smaller svg images within an svg container. However, I am finding it challenging to grasp the guidelines for sizing nested SVG elements. svg { display: block; } Here is my query - ...

Receive real-time price updates from Next.js using GetServerSideProps data

I'm currently working on fetching live bitcoin prices from CoinGecko. In my index.js file, I have an async GetServerSideProps function that is functioning correctly. The returned props are then passed down to the <Home /> component, and subseque ...

Numbering each numeral

Looking to add a sequence number next to each digit using jQuery or JavaScript: If I enter the following numbers: 1, 1, 1, 2, 3, 4, 5, 5, 5, 6, 7, 8, 8, 9, 10 and so on then the desired output should be: 1.1, 1.2, 1.3, 2.1, 3.1, 4.1, 5.1, 5.2, 5.3, 6.1 ...

Using Bootstrap's dual listbox, you can easily select single options with the ability to add or delete them. Upon selection, the

Could someone please assist me in resolving this issue? I am looking for a dual listbox with single select option, unlike Bootstrap which only offers dual listboxes with single/multiple select. To Clarify: Here is an example: In my dual listbox, the le ...

Struggling to locate a declaration file for the 'cloudinary-react' module? Consider running `npm i --save-dev @types/cloudinary-react` or exploring other options to resolve this issue

Currently, I am working with Typescript in React. Strangely, when I try to import the following: import { Image } from 'cloudinary-react'; I encounter this error: Could not find a declaration file for module 'cloudinary-react'. ' ...

What is the method for displaying an asterisk in a select box option?

Is there a way to append an asterisk after the first option in a select element? Here is my html <select class="form-control textyformcontrol"> <option selected>Service area</option> <option>First Option</option> &l ...

Arrange blocks within bootstrap columns using grid css

I have a layout with two columns, each containing two blocks Currently, the mobile order is: 1 2 3 4 But I want it to be: 3 1 2 4 I attempted to use CSS grid but I am unsure how to move block 3 out of column 2. Here's the code snippet: body { ...

vertical alignment, almost there

Is there a way to align a block of text so that the top of the first line is positioned 50% down from the top of the td element? Imagine this scenario, where the top of the first row is exactly at the 50% mark. -------------- | | | ...

An error was encountered while linting /app/layout.tsx at line 16: Rule "@typescript-eslint/no-empty-function" was violated due to inability to read properties of undefined (reading 'getTokens')

I am puzzled as to why the function that generates JSX is being checked by the "next lint" script with the rule "@typescript-eslint/no-empty-function". The code snippet at line 16 of the layout.tsx file looks like this: export default function RootLayout( ...

jQuery - Event cannot be triggered on the 'deselect' or 'focusout' of <option> tag

Check out the demo here Hello there, I have a situation where I need an input box to appear below a select option, only if the user selects "Other". The code currently uses the .click() function on the option, but now I am trying to make the input box di ...

AngularJS: Monitoring $locationChangeStart for token verification

I am attempting to check if the next has a token or not, but it is not working and I am getting an error: TypeError: Cannot read property 'next' of undefined Any suggestions? app.js .run(function ($rootScope, $location,$log,User) { ...