Import TypeScript variable in React - reactjs

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

Related

How to import SCSS on Component Level with Next.js

I am coming from a CRA background and working my way through Next.js version 9.4.2
My project tree looks something like this :-
pages/
_app.tsx
index.tsx
components/
Navbar/
index.ts
Navbar.tsx
Navbar.scss
Inside my Navbar.tsx I have a statement import './Navbar.scss';
This gives me the following error :-
./src/components/Navbar/Navbar.scss
Global CSS cannot be imported from files other than your Custom <App>. Please move all global CSS imports to src/pages/_app.tsx.
Read more: https://err.sh/next.js/css-global
Location: src/components/Navbar/Navbar.tsx
The error, as mentioned, goes away if I move the import Navbar.scss statement to pages/_app.tsx
I know I can switch to Navbar.module.scss, but I don't want to go down the route of modular scss as I expect my scss to get complex I would like to stick to the manner in which I write my scss and not keep finding work arounds to issues that might arise later. I am open to being convinced here but I have not found good read ups on this to choose it as my path.
So by the looks if it, I am stuck with importing all <component>.scss files in _app.tsx. This will leave me with a long list of <component>.scss imports in my _app.tsx and I will also be left with a lot of <component>.scss files for Components that might conditionally not render.
What are my options here ?
Your Navbar.scss file is not named properly.
Let's say your stylesheet contains something like...
$color: red;
.someclassselector {
color: $color;
}
Component stylesheet files have to be named in the following convention for next.js to compile them as addressed in next's css getting started guide
<TheComponent>.module.scss
be imported like this:
import styles from './<MyComponent>.module.scss>';
and be applied to the component like this:
<TheComponent className={styles.someclassselector} />
Not really an expert but it seems that you should stick to class selectors as global selectors can only be declared if you import them in pages/_app.js. You may name a main.scss file to use Global or Tag Element selectors like h1 {},h2{}, * {}, etc.

Global es6 module to store constants in react app - prevent garbage collection

I would like to store some variables inside a module (export) to be used as constants though out my react app. I would like to avoid context because there is no need for components to re-render and also I need those constants to be used outside my react components.
Where should I do it (where to import it), in order to prevent garbage collection?
One idea I have is to import and re-export it on top of my root component.
EDIT:
To be more precise, there will be a component that will set the constant once (mutate the variable), so that other components or files can access it.
So, what you will need is some sort of setter/getter pattern. Though I mostly don't recommend it unless you know what you are doing, because React won't re-render if the variable changes and because of that you need to be sure the variable is set before it is used.
You should have something like the example below in order for it to work the way you want. You can find an example of it working on this Codesandbox.
export let MY_VARIABLE = "";
export const setMyVariable = value => (MY_VARIABLE = value);
PS: I've added some console.log to the code in order for you to see how the import/get/set behaves.
After digging more into this I found that es6 module spec states:
When import your module it gets loaded => parsed => evaluated and cached (singleton). It also says that when you import modules its value is passed by reference (aka assignment). I didn't find anything mentioning when or how es6 modules are unloaded from that cache.
So that means, when you import a module once, it is there for as long as the program is running, and all modules access its values directly.
reference
https://hacks.mozilla.org/2018/03/es-modules-a-cartoon-deep-dive/
https://medium.com/#mivanichok/understanding-es6-modules-in-depth-article-b49612926e39
You can create an config.js inside src folder and write the your constant variable like
//config.js
module.exports = {
CONST_VAR : 'const value',
}
import config.js in your component and use it

How to export module properly so vscode can show my module in suggestion [ctrl+space]?

I have a setting style file like:
GlobalStyles.js
export const GlobalStyles={
ViewContainer:{flex:1, justifyContent:'center', alignItems:'center'},
Center:{justifyContent:'center', alignItems:'center'},
FontNormal:15,
FontMedium:18,
FontLarge:28,
FontHeader:38
}
module.export={GlobalStyles}
and when i used it in another JS file, let say Home.js. i want to vscode know every Key:Value i've defined,
with those export in GlobalStyles.js vscode suggesting an import style like this:
import { GlobalStyles } from '../Component/GlobalStyles';
and my expected result is something like:
import { ViewContainer, Center, FontMedium, [and so on]} from '../Component/GlobalStyles';
how to let vscode suggesting me Auto Import foo from path/to/GlobalStyles when i'm typing foo? where foo is like ViewContainer, Center, FontMedium, [and so on].
The feature you're talking about is called Auto Imports. To answer your question, this feature exists and works by default in VSCode.
Here is a sample of how i've used it in a React project. Here I have a component inside a folder with the same name. Outside of that folder is a file I called ModuleExports.js and it currently has the following code.
import Navbar from "./Navbar/Navbar";
export { Navbar };
For reference, export is an alias of module.export so feel free to use them interchangeably. This is a component so when I try to use it as such you can see from the screenshot I am suggested an import to use.
The same can be done without being a component. I'll declare a testObject inside the same file ModuleExports.js and export it.
Then let's see if intellisense will pick it up.
There it is. I hope this helps and do ask if you want more clarification or are running into issues.
In this case, the mistake seems to be using dynamic export. That's old CommonJs style. VSCode uses typescript tools for static analysis. To take advantage of that, you have to use ES6 export.
CommonJs: module.export={GlobalStyles}
ES6-modules: export GlobalStyles
The significant difference between two is that CommonJs variant is simply variable which is defined at runtime. Ie. there is no way to know what you are exporting without executing the code. ES6 export is reserved word. It's construct which cant be changed after definition which also means, it's type definition can be found without actually executing the code.
Typescript, Babel etc provide interoperability between two module systems but they are two very different things by spec.

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.

Migrating to Styled-Components with global SASS variables in React

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.

Resources