Themes in React.js
My name is Thomas. People usually call me Tom. I have worked as a web developer for more than 16 years in South Korea and I really enjoy programming. That’s also why I love open source. I have created and operated several open source projects.
In this blog, I want to share my experience and opions on Themes in React.
I’ve been developing with jQuery for over 10 years, and with it I’ve built many websites and libraries. But now I’ve fallen in love with React. There are many reasons why I love React. But today I’d like to share the top two reasons:
1️⃣ First, React makes developing enjoyable and using JSX is plain fun. Hot Module Replacement is the best function to use, in my opinion. With HRM, you can save a lot of time as you can run your application without refreshing. You can also exchange, add and remove modules while the app is running.
2️⃣ The second reason is the great UI components made with React. Many useful components can conveniently be found at NPM, so that speeds up development drastically.
Using JSX and Styled Components
Let’s look at how to develop using JSX and Styled Components.
Without Styled Components, you need to enter
className in the node when styling. And to create or modify a CSS Class you will need to open the CSS file.
But what happens? Usually there are so many files already open on your screen and it’s just chaotic to open another one. You can try adding the style property in the next line, but it generally ends up looking messy.
I think it is better to avoid complicating the body of the render function.
Then what if we just used Styled Components?
We can just create a Styled function that can be used directly in JSX with the styled-component syntax and use it according to the JSX syntax in the render. And If you use VSCode you can also use a styled-component plugin which auto-completes the CSS.
If you have a Styled-Component that needs to be re-used or needs to be redefined, you can define it in a separate file and export it.
I like to make image assets into styled components as well. Usually each image is defined in a different style, but that allows me to manage image assets efficiently.
Like this, you can import the exported components to the specific location that you want and use JSX in your render. It’s very simple and easy to follow! So I like to code semantically in the render with no attributes unless it is really necessary.
This is a graph from the NPM annual report in 2017. As you can see React is growing rapidly every year, and has beaten all the other framework.
You can find almost all the components free for your development if you use React. Creating UI for sites like these components by yourself can be very time-consuming, but if you install NPM you can apply these components to your projects easily by importing them.
I think the reason why so many great components are available is because of the well-made life cycle of React and JSX.
And I am also making and distributing some React components myself.
One of my components is named Datagrid.
Datagrid is designed to print only parts of data that are represented in tables. This way you can print, scroll, and modify data very quickly.
Thanks in advance for clapping for my blog.. You’ll clap, won’t you? :)
Okay, back to React. One of the most powerful UI frameworks in recent years is Ant Design. I have tried Bootstrap, Materialize and Semantic UI. But Ant is the most enjoyable to use so far. Here are a few reasons why:
First, it’s made of React and Typescript.
Second, the variety of components available and its excellent features make it easy to create complex and large web applications.
Third, Ant Design has no problem using Styled Components. (Style components are not usually available for components that don’t support className props.)
Fourth, it is well documented and has many examples.
And last, it has more than thirty-four thousand stars on Github.
Now let’s get to the main point.
If you’re a front-end developer working on a web application, you might be thinking about how to create a theme. But themes are hard to make and even harder to maintain.
As I mentioned earlier, I like to use Styled Components and Ant Design. To manage Themes using these two, you need to use “LESS” to change the theme for AntD and use the “ThemeProvider” for Styled Components.
So if you want to change the “primaryColor” value, you must change both the “theme.less” file and the “theme.ts” files. Even if you don’t use AntD, you will have similar issues when you are using Styled Components on other frameworks.
So how can you change the primaryColor value in one go?
This would be the main problem if you work in a team with others. I’ve tried many ways to solve the issue, and today I want to share 3 of them with you.
First Method: Using the LESS file
In the CSS module loader, you can use the export selector in the LESS file. The CSS-module allows variables in export to be used as variables in JS. In this example, I defined primary_color and info_color.
Then import the LESS file as a theme variable. After that… create ‘styled’ and ‘ThemeProvider’ according to the Styled Component theme guide.
Wrap it with a ThemeProvider that has theme props.
Now you can use the theme variable when you use styled on a component.
To summarize, in the theme in file ‘antd-theme.less’ is exported to ‘ThemeProvider’ from ‘styledComponents’. This way the components that are wrapped in the ThemeProvider can use the value of the theme. And there is nothing to change in Ant Design!
The advantage of this method is being able to use the color value from the Theme variable value as a function of LESS. For example, you can use color functions such as lighten, darken, and fade-in with LESS.
But there is a small problem with this method. IDE doesn’t support auto-completion because it doesn’t know the type of the theme that I brought from the LESS file. (To resolve this issue, you must create a d.ts file of the LESS file. I tried to create a d.ts. file every time the LESS file was changed, but it wasn’t a smooth transition.)
While it is usable, I wasn’t satisfied with it since I use Typescript.
So I tried something else.
Second Method: Building a LESS file with a TS file
First, make a “theme.ts” file. Then create a theme object and add primary_color and info_color keys. Export!
Now make the ‘theme.ts’ file as a theme variable. Follow this method to create a ThemeProvider as well.
Create a “theme.ts” file and when you update it, the “theme-vars.less” file is also updated. So styled-components uses the “theme.ts file” as the theme, and Ant uses the “theme-vars.less file” as the theme.
The most difficult part is how to watch your files.
So I decided to use a node. Define the source path to the TS file and the target path to the LESS file.
Next, create a function called “buildLessVar”. Have the function read the “theme.ts” file and replace it with a dash from underscore to create the file.
Use “watchFile” in the “nodeJS” to run the “buildLessVar” function whenever the “theme.ts” file updates.
Then create a script to run the “package.json” file when NPM starts. We used “ts-node” since we have a TS file.
So if you enter the “NPM start” command into the terminal, “build-watch” and “WEBPACK services” will be running simultaneously and go on standby.
This is what it looks like when the “theme-vars.less” file is created. Once you import from “index.less”, the theme for Ant is resolved.
Nice! Now you can use AutoComplete with Styled Components.
Not only is AutoComplete available, but TypeScript also gives a notification when the developer accidentally uses the wrong variable name. This really helps avoid mistakes. Convenient, isn’t it? :)
styling-reactjs-demo. Contribute to thomasJang/styling-reactjs-demo development by creating an account on GitHub.github.com
Alright, let’s take a look at the demo.
The source code for this demo can be found in more detail here.
Enter the “NPM start” command in the terminal to start the server. Let’s open the “theme.ts” file and change the value of primary_color. As you can see, the color of all the controls have changed.
If you look closely, you will see the color of the title differs from the label color of Form control. And the text-color on the bottom is inverted according to the background color.
To allow color representation to be detailed, we used the color function from the “npm plugin” to modify the color values defined in the theme. Because the way of the color function is a little longer, it would be cleaner to make it simple like in the second line.
Finally, the text at the bottom of the page is inverted by determining if the background color is a Dark color.
This will allow any color to respond to the background color.
Third Method: Creating a theme using only CSS
Make the variable in the theme into CSS custom properties. You can create a color variable using a keyword in :root selector.
Then use the “VAR” function where it’s needed. You can use this feature with any modern browsers except Internet Explorer.
As you can see, CSS overrides AntD.
Earlier, we used a function to modify the color values. The problem will be solved if you use the “color-mod” that is defined to CSS4 spec.
Sadly no browsers are supporting this feature yet. But it’s only a matter of time before we can use this feature because it’s rapidly being developed.
Ok then…. let’s look at a demo of a theme that was created this way.
It’s still challenging to use this technology, but it has a promising future.