Migrating to Styled-Components with global SASS variables in React - reactjs

I'm trying to slowly introduce Styled-Components into my existing codebase which relies heavily on global SASS variables (partials imported into a main.scss).
How do I reference the SCSS variables? The following doesn't work:
import React from 'react';
import styled from 'styled-components';
const Button = styled.button`
background-color: $color-blue;
`;
export default Button;
Am I approaching this from the wrong way?

I wrote up an article about solving this very issue. https://medium.com/styled-components/getting-sassy-with-sass-styled-theme-9a375cfb78e8
Essentially, you can use the excellent sass-extract library along with sass-extract-loader and the sass-extract-js plugin to bring your global Sass variables into your app as a theme object.

Pardon me if this is an old question but I thought I chip in on how I use CSS variables for both my .scss and styled-components when the need arises.
Basic Usage:
Declaring a global variable (preferably at _variables.scss)
:root {
--primary-color: #fec85b;
}
Using the global property:
.button {
background-color: var(--primary-color);
}
or
const Button = styled.button`
background-color: var(--primary-color);
`;
Please pay attention to the double line --.

Variables play a very important role in .scss or .sass, but the functionality cannot be extended outside the file.
Instead, you have to create a separate .js file (For example: variable.js) and define all your variables as an object.

I recommend using the ThemeProvider component. I'm also moving away from sass and towards styled components. The Theming with styled-components uses React's context api and is quite nice. Check out the this documentation Styled Components Theming.

Related

What is proper way to add global css style in react component if I am using styled Component?

Right now, I figure out that I have two way to do this:
One , I am putting global style such as in the App.css and then import them in the App.js
:root {
box-sizing: border-box;
font-size: 62.5%;
}
*,
::before,
::after {
box-sizing: inherit;
margin: 0;
padding: 0;
}
Another way is to use GlobalStyles that provide by styled Component. Which way should I do ?
Thanks for the help!
If you using a library you should stick to its API.
Meaning using createGlobalStyle.
A helper function to generate a special StyledComponent that handles global styles.
In more advanced use cases (like having a theme) your only option to alter the global styles will be using the pre defined API.
As a side note, you can do it in more than two ways (BUT DONT DO IT), like querying the DOM and editing the style.

Import TypeScript variable in React

I am trying to style (styled-components) a fabric js component (Dropdown) as a react component.
The css class names are declared in a file office-ui-fabric-react/lib/components/Dropdown/Dropdown.scss.d.ts. Example:
export declare const root = "root_15a7b352";
I want to import this class name so I can use it in styled.
AFAIK this is TypeScript global variable and I tried looking for information on how to get to it but with no success.
The statement declare const root is not the same as const root. It means:
There is a variable called root somewhere else, and I'm just here to describe it.
In other words, it tells us something on the type level, but it doesn't contain any executable code. It's not possible to consume it in runtime. You can verify it by inspecting the generated code in TypeScript playground.
Most likely it's meant to be imported from someplace else, or is, in fact, a global variable Since the declaration file describes Dropdown.scss, it's likely that root is a CSS class living in that file. Try:
import { root } from 'office-ui-fabric-react/lib/components/Dropdown/Dropdown.scss'
Karol Majeswski's Answer gets it right on importing the variable from typescript.
However, it seems your intention is to style parts of the dropdown using styled-components, instead of importing this variable from scss file, the Dropdown component provides readable classnames like ms-Dropdown-title that can be used for styling.
For eg. to style the Dropdown, you would use:
const StyledDropdown = styled(Dropdown)`
color: red;
& .ms-Dropdown-title {
background-color: red;
}
`;
See Codepen example

How can I access postcss variables in styled components for media-query?

I'm using a CDN, which has a bunch of defined pcss variables that I would like to use in my styled components. I was able to use the color vars easily via var(--color-green). However, the media-queries variables don't seem to work. Anyone know why this might the case?
This is what I've tried, where --media-query-max-small is defined in the cdn as max-width: 647px
const comp = styled.div`
#media (var(--media-query-max-small)) { }
`
As a creator of PostCSS, I recommend to use astroturf. It is CSS-in-JS solution with styled-components API, but in contrast to styled-component, astroturf doesn’t have runtime (SC has 15 KB runtime), parse CSS only during build (SC parse it every time on the client) and support PostCSS and many other CSS tools.
In your case, just put postcss-loader for CSS and astroturf/loader for JS files. Everything will work.

How to use SCSS variables into my React components

I am working on a React project that follows this structure
src |
components |
Footer |
index.jsx
styles.scss
Header |
index.jsx
styles.scss
scss |
helpers.scss
variables.scss
...
main.scss
Into my variables file I was using the css custom variables so, all them where on :root and I can access them in my components styles.
When I wanted to create the dark colours I wanted to use the SCSS function darken, but it does not evaluate them and throws an error saying that var(--blue) is not a valid colour.
As a solution I decided to move all the variables into a SCSS variables but when project is building it throws another error that says that a $blue is not defined.
The unique solution possible I can use, it is to include the variables file in all the styles files but, I do not know if there are a better solution for the structure that I am using.
From React 17
To access your scss variables into the react component, you need to do something like that
Install node-sass as a dependency or dev dependency
No need to do any config change in webpack
import as a module <-- main point
variables.module.scss
$color: skyblue;
$primaryColor: red;
:export {
color: $color;
primary-color: $primaryColor;
}
App.js
import variables from '<YOUR_PATH>/variables.module.scss';
const App = () => {
console.log(variables);
}
If you don't want to use styled-component
then you can follow this link.
https://til.hashrocket.com/posts/sxbrscjuqu-share-scss-variables-with-javascript
I use a similar structure to organize my .scss files. I like having the styles in the same folder as the component. However, I import all scss files to my main.scss file. This helps avoid style conflicts in the DOM.
main.scss
import "./scss/helpers.scss"
import "./variables.scss"
import "./Footer/style.scss"
import "./Header/styles.scss"
Make sure to name your files with an underscore so that all the files get merged on compilation. Note you don't need to name the underscore in the import.
_helpers.scss
_variable.scss
_style.scss
Using this method you only need to import styles once into your app. index.jsx
There are different ways I can recomend you to tackle this.
1- Duplicate the values of those variables. Add them both on your variables.scss and as constants in some other file, maybe config.js or constants.js that way you'll be able to reference these values from your react components, the downside to this, is you'll have to remember to change them in two places if you have to modify the value.
2- Consider using styled-components. With styled components you can define your styles within your components, using variables or props within the styles.
3- Use some mechanism to define these variables in a single file or as environment variables, and setup your build process to be able to import these values into js and scss files.
It is possible to use custom variables with that project structure using css-vars mixin.
After proposing the option to evaluate custom variables before executing the SCSS function, a guy suggested me this mixin. I have just tested and works pretty nice.

Keep classnames with CSS loader or organize code in React?

How can I use my own class names when using CSS and Style loaders? I'm using React and i often get confused with all the class names and the related components. If it is not recommended to keep the class names, how can I organize my code in a manner that it don't get messy?
You can use normal classNames and then import the relative .css file that has the style for those classes. Something like this:
MyComponent.js
...
import '/path/to/css/style.css'
...
render() {
return(<div className="MyComponent">Hello</div>);
}
...
style.css
...
.MyComponent {
width: 100px;
background-color: red;
...
}
...
And this would work just fine, with this approach though you are in charge of naming your classes and making sure there are no collisions and everything is named properly (you can then follow BEM techinque or others as you prefer).
Otherwise there are other approaches that I am not gonna explain into details because the relative docs are great and don't need any addition.
You can use Css Modules or Styled Components. There is also this article that has a good overview of these methods and can help you out make a final decision.

Resources