Import style dictionary into styled components - css

I'm currently deciding which technologies to use in a project. I always liked sass, and the main reasons are the nesting of css and the possibility of creating dicionaty classes to hold all design information, such as pallet, margins, etc. Such as below:
$primary-color: #fff;
$seconady-color: #eee;
And then, in the actual .scss file I can import this dictionary and have easy access to pallete, thus achieving standartization and facilitating the creation of style sheets:
#import "dictionary.scss";
Styled components are a great thing, and I totally agree with their website stated advatanged. However, I do not like the idea of losing this dictionary functionality I have with sass. I know I can pass data to styled components from state and props, but that also means that, in some point, I will have to pass those props or state from somewhere. Like:
<Foo primaryColor="#fff" secondaryColor="#eee"/>
Is there a way I can conciliate this dictionary functionality I have with sass with styled components? Someway to import a dictionary.sass into my styledComponent.js file or even a .json or something. A way to import static pallet, fonts, margins data that is not React props or state.

You can declare the variables in plain Javascript in a file and import them where you style components.
Dictionary file would look something like this:
export const primaryColor = '#fff';
export const seconadyColor = '#eee';
Then interpolate them when you apply styling:
import { primaryColor } from './variables.js';
const Button = styled.button`
border-radius: 3px;
border: none;
color: ${primaryColor};
`
You can also import Sass variables to JS: https://til.hashrocket.com/posts/sxbrscjuqu-share-scss-variables-with-javascript

Related

Is there a way to scope css of my react library at runtime with rollup loaders?

I have 2 micro frontends using the same css library, and it is causing issues. Styles from one micro frontend bleed into the other. So I need for all of the css that gets out of the library to be scoped.
But I need to have a different scope for each library import.
Basically I have style files like
some-component.module.scss
.some-class {
color: red;
}
And I want people who use the library to be able to import components from the library, and have it scoped to something they choose. For example in microFrontend 1:
import SomeComponent from "my-library"
const SomePage = () => {
<SomeComponent/>
}
In this scenario I want styles for SomeComponent to look like:
.microfrontend-1 {
.some-class {
color: red;
}
}
Basically I need to wrap all styles that are imported from the library on a different scope depending on which microfrontend I'm in.
Some possible solutions:
Add a variable to .env file with the right wrapper name, and somehow read it from the library, and scope css at runtime (which loader could help me here?)
Use ES6 module query parameters to provide the wrapper name at import time (I would need to do this for every component, so it is not ideal)

Why does CSS styling disappear in React when directly changing route in browser URI?

I have a simple front-end React app created using npx create-react-app. The app is using react-router-dom routes. When I directly change the URI in the browser from say, localhost:3000/ to localhost:3000/search it will navigate to the <Route>but with no CSS rendered; just HTML from the component.
How can I make sure CSS is rendered in the new route when directly navigating in the browser? My future goal is to be able to copy and paste a route in a new tab and navigate to the correct page and display results from an API.
Css style sheets will need to be imported either at the root level or within the file itself.
style sheets need to be imported when used and then the corresponding classname will need to be used within the component or tag.
Another useful way to set react css without style sheets is by using in line styles
e.g
<div style ={{float: "right", textAlign : "center"}}> </div>
EDIT
A really easy way to get styles going within a react project is install bootstrap.
then buttons and stuff can be assigned classNames such as
<div className = "jumbotron"></>
this will leave a grey box around the items.
<div className = "btn btn-primary"></>
this will give you a blue styled button.
Any more information or help within your application let me know and provide some code snippets.
You can use styled-components. styled-components are widely used in ReactJs and React Native and it's a perfect choice.
styled-component : https://www.npmjs.com/package/styled-components
I realized that react apps created using npx create-react-app allow you to import a css module for components.
Given the component, Button.jsx, you can simply create a css module with the convention, [module-name].module.css. For the case of Button.jsx, create a file named Button.module.css, import "styles" from the module. Styles will be an object containing all the CSS styles.
I if I had a folder named "components" with all my components, I could make a folder within "components", say called "compStyles", and create all the [module-name].module.css files in there.
Button.module.css:
/* class names must be camelCased */
.myButton {
margin: 0 auto;
}
span {
fontSize: 20px;
}
If I had the above mentioned file structure, I could import and use like so:
import React from 'react';
import styles from './styles/Button.module.css';
const Button = () => {
return (
<div className={styles.myButton}>
<button><span>Some Button</span></button>
</div>
)
}
export default Button;
Styles for the span will be automatically applied, and any other class will be referenced by styles.className. Create one file for every component, and each component's CSS will take care of itself and not break like it would if it was in the public folder.

CSS splitting per page in Next.js

I need my css stylesheet split into many files, one per each Next.js page. How to implement this?
I tried to use next-css and just import a css-file into each page. It almost works. However the css-file is not loaded on Link navigation. Authors of Next say it's not implemented:
https://github.com/zeit/next-plugins/issues/282#issuecomment-523128645
I also tried using styled-jsx. It has several problems for me. It has many bugs on its Issues page. I also failed to make styles visible throughout child components with this approach.
You can import a module.css (import style from 'root/styles/MyStyle.module.css) and use as follows.
This is your component:
import style from '../../styles/components/Header.module.css'
export default function Header() {
return (
<h1 className={style.header}>
Hello World
</h1>
);
}
This is your CSS:
.header{
color: #fff;
width: 100%;
height: 80px;
}
Note that the CSS class is used as the components className;
Or, inside the react component, you can try adding the tag <style jsx>{ your_CSS_here }</style>.
According to Next documentation each page uses the styled-jsx library. But you can still use other CSS-in-JS libraries such as Styled Components and Emotion.
Next apps has also support for using sass that allow you to import .css and .scss files.
For more information you can check the Vercel Docs. I also recommend you to check the Learning area.
You can create your seperate css files and on each component that you need specific styling you import the css file that is unique to that component. so for example say you have a Component in file file1.js then you can import styles specific to this component in the file file1.css same happens for another file file2 with css file2.css
import './file1.css'; //importing the style specific only for this component
function File1(){
const [processing, setProcessing] = useState(false)
return (
<> </>
)
}
export default File1
Similarly for the second file
import './file2.css'; //css file specific to this component
function File2(){
const [processing, setProcessing] = useState(false)
return (
<> </>
)
}
export default File2

Using global variables for Less in Angular

I set up my project as Less in Angular to use the benefits of variables and such in my CSS. But the problem is that I have to define those variables in each component which doesn't make it as efficient. Is there a way to set the variables globaly?
So I want to get rid of this:
In my component less:
#pink-color: #FC9DB5; // I want to get this from a single
// file which I import on each component
header {
background-color: #pink-color;
height: 100px;
}
This is what #import is for; it lets you import files of variables.

CSS architecture with React that also can be themed

I'm currently building out a large React app. Css, has never been my strong point. But now CSS has sass / cssNext / inline styles with React. I've been using BEM with sass, but as my other applications have grown huge even that starts to break down. Especially when you had on the ability to "re-skin" or "theme" the pages outside of the primary color schemes etc..
so -- can someone point me to a proven way to create css with react that can scale very well, and allows for custome theme'ing when people want to borrow my components. For instance,
<MyComponent />
// this component has its styles but lets say Joe Schmoe wants be import
// it? But, Joe wants to overlay his custom styles?
// Is there a new paradigm that allows for an overlay or reskin within the component?
Or even the idea of the whole application being skinnable some time down the line. I know this is sorta a very base question, but whenever I build out projects my pain points also seem to be the CSS - so I want to know what really works.
This was, until recently, not a solved problem in the React world.
I'm one of the maintainers of ElementalUI, a React component library, and we've been trying out all the different ways of styling for the past 6-12 months. (!) You name it, we've tried it. (I talked about my experiences with some of the most popular libraries during my ReactNL keynote and where they break down)
The issue is that none of the current styling libraries have built-in support for theming at all. You can do it with most of them in a very hacky, non user-friendly way, but that's not what you want when you distribute a component, right?
That's why we built styled-components. styled-components has a bunch of interesting properties, and one of them is that theming is directly built into the library, making it the perfect choice for building distributable components!
Here is the short explanation, though I encourage you to go through our documentation which explains everything!
This is what the basic usage of styled-components looks like:
import React from 'react';
import styled from 'styled-components';
// Create a <Wrapper> react component that renders a <section> with
// some padding and a papayawhip background
const Wrapper = styled.section`
padding: 4em;
background: papayawhip;
`;
This variable, Wrapper, is now React components you can render:
// Use them like any other React component – except they're styled!
<Wrapper>
<Title>Hello World, this is my first styled component!</Title>
</Wrapper>
(if you click on the image you'll get a live playground)
When you pass an interpolated function into the tagged template literal, we pass you the properties passed to the component. This means you can adapt to the props:
import styled from 'styled-components';
const Button = styled.button`
/* Adapt the colors based on primary prop */
background: ${props => props.primary ? 'palevioletred' : 'white'};
color: ${props => props.primary ? 'white' : 'palevioletred'};
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border: 2px solid palevioletred;
border-radius: 3px;
`;
Here, we've created a Button component that you can make primary like any other React component:
<Button>Normal</Button>
<Button primary>Primary</Button>
Now comes the theming aspect. We export a component called ThemeProvider that you can pass a theme to and wrap your app (or parts of the app) in:
import { ThemeProvider } from 'styled-components';
const theme = {
main: 'mediumseagreen',
};
ReactDOM.render(
<ThemeProvider theme={theme}>
<MyApp />
</ThemeProvider>,
myElem
);
Now any styled component within that ThemeProvider, no matter how deep thanks to context, will get this theme injected into the props.
This is what a themable Button would look like:
import styled from 'styled-components';
const Button = styled.button`
/* Color the background and border with theme.main */
background: ${props => props.theme.main};
border: 2px solid ${props => props.theme.main};
/* …more styles here… */
`;
Now your Button will take the theme it gets passed and change it's styling based on that! (you can also provide defaults via defaultProps)
That's the gist of styled-components and how it helps to build distributable components!
We have a currently WIP doc about writing third-party component libraries which I'd encourage you to check out, and of course the normal documentation is a good read too. We've tried to cover all the bases, so if you see anything you dislike or that you think is missing please immediately let us know and we'll discuss!
If you have any other questions about styled-components feel free to reply here or reach out on Twitter. (#mxstbr)
I don't know what is the best way. I think it's more like a personal preference. I will just share the tools that I'm using. What I'm using is css-modules with postcss.
css-modules gives you the power to create a local-scoped identifier with a global unique name for each of your CSS classes and also enable a modular and reusable CSS! You can also use postcss-modules-values to create a global settings file which contains all the settings variables. So that you can change the theme for your website.
Here's how I structure the components. Each of my component will have one css file which is very easy to maintain or make changes.
Here's the code for the Button component.
function Button(props) {
const className = props.className ? `${styles.button} ${props.className}` : styles.button;
return (
<button disabled={props.disabled} className={`${className}`} type="button" onClick={props.onClick}>
{Children.toArray(props.children)}
</button>
);
}
Notice that I have a className for the component which allows other component to pass in the class for the button component. So that when someone borrow your component they can extend or override your button styles.
If you need to create a customisable website, I will also recommend to use Less.js which provides the live preview of the customised website.

Resources