Ant Design toggling dynamically custom theme
Hey there who are using ant design, If you wanna add one more theme to your application, this information can be useful. When I faced this task I think that it would be easy solution because antd has a configuration with variables and support it in dynamically should be ease. But I forgot for the .less and live compilation for the product. And as an additional, I'm using a create react app, that hasn't access to the webpack configuration from the box.
Tools
During some research and googling, was find several examples and articles that already solving this problem.
Most common solution that I've met its npm module: https://github.com/mzohaibqc/antd-theme-webpack-plugin
Here is one alternative package: https://www.npmjs.com/package/antd-theme-generator , I haven't tried antd-theme-generator, who wants to try alternative here is a article with example how to configure: https://annacoding.com/article/gVcF6qCZkfnM3JOnPxBqx/Change-Ant-Design-Theme-dynamically-in-React-Create-React-App
And to implement both of these solutions with Create react app we need, add additional webpack configuration module customize-cra
.
Solution
Main packages that I'm using:
- antd v3 (with v4 works the same)
- customize-cra
- create-react-app
- antd-theme-webpack-plugin
Project Configuration
To our root directory we are adding file config-overrides.js
//config-overrides.jsconst path = require("path");const {override,fixBabelImports,addLessLoader,addWebpackPlugin,} = require("customize-cra");const AntDesignThemePlugin = require("antd-theme-webpack-plugin");const options = {stylesDir: path.join(__dirname, "./src/antd-custom-style"),antDir: path.join(__dirname, "./node_modules/antd"),varFile: path.join(__dirname, "./src/antd-custom-style/vars.less"),// list of variables that will be listeningthemeVariables: ["@primary-color", "@body-background"],generateOnce: false, // generate color.less on each compilation};module.exports = override(fixBabelImports("import", {libraryName: "antd",libraryDirectory: "es",style: true,}),addWebpackPlugin(new AntDesignThemePlugin(options)),addLessLoader({javascriptEnabled: true,}));
themeVariables: ['@primary-color', '@body-background'] depends on our example application will be listening just these two variables
You can generate a list of all antd variables and paste it to the themeVariables
field, here is code implementation example from antd-theme-webpack-plugin : https://github.com/mzohaibqc/antd-theme-webpack-plugin/blob/ebc9eb92c9ea7cbe3e703470bfc9ede131a7f2cc/examples/customize-cra/config-overrides.js#L21
Main fields that should be configured depending on your project varFile
, stylesDir
, themeVariables
, everything else it's boilerplate.
Add toggler inside the Component
To any of your component add this two button, two trigger theme dynamic
<buttontype="button"onClick={() => {window.less.modifyVars({'@primary-color': 'red','@body-background': 'yellow',});}}>Red Theme</button><buttontype="button"onClick={() => {window.less.modifyVars({'@primary-color': 'blue','@body-background': 'purple',});}}>Blue Theme</button>
In multiple sources, I was found examples of where to the /public
folder was added color.less
, I cannot reproduce this examples, there were some mistakes, I assume it's a pretty old approach.
That's all now you have antd with ability to configure theming dynamically and improve you user experience.
References:
- https://github.com/mzohaibqc/antd-theme-webpack-plugin
- https://ant.design/docs/react/customize-theme
- https://github.com/ant-design/ant-design-pro/blob/56e648ec14bdb9f6724169fd64830447e224ccb1/config/config.js#L45
- https://github.com/arackaf/customize-cra
- https://medium.com/@mzohaib.qc/ant-design-dynamic-runtime-theme-1f9a1a030ba0
- https://github.com/YumcoderCom/antd-them-switch-cra