React + Antd realizes dynamic switching theme function
foreword
I recently went to the ant design official website to check the information, and found that the latest version of ant design has been updated 4.17.x
, so I took a rough look at 4.17.x
the update logs of the last few versions, and found that 4.17.0
the version has updated a lot of content ( click to view the update log of version 4.17.0 ), in One of the things that attracted my attention is the realization of the dynamic theme function. However, if you click on the document of the dynamic theme, it is marked as an experimental function, which is really a capital embarrassment. . .
In 4.17.0
the previous version, the method of implementing dynamic themes was cumbersome (maybe I was ignorant), usually by modifying the less variable, which I personally think is rather cumbersome. After 4.17.0
the version, the official began to support the function of dynamically switching themes, which made me feel more relieved.
Precautions
The following is an excerpt from the description of the official document:
- This function is realized by dynamically modifying CSS Variable, so the page will not be displayed normally in IE. Please confirm whether your user environment needs to support IE.
- This feature is supported from version [email protected].
Realization principle
The function of dynamically switching themes is to ConfigProvider
set a unified style prefix through global configuration. For specific ConfigProvider
related documents, please see here: https://ant-design.gitee.io/components/config-provider-cn/#API .
For example, the antd button control, after the parameter type
is set to 'primary'
, will be added after the actual rendering class="ant-btn ant-btn-primary"
, in which ant-btn-primary
the style controls the background color and border line color of the button. As shown in the figure below:
For the class name ant-btn
and ant-btn-primary
, ant
in fact, as a prefix of the style. And if we dynamically replace the prefix in the style class name with other strings, we can achieve the effect of theme switching.
Implementation
-
According to the official documentation, by
ConfigProfider
modifying at the top levelprefixCls
:import { ConfigProvider } from 'antd'; export default () => ( <ConfigProvider prefixCls="custom"> <MyApp /> </ConfigProvider> );
-
Compile less
Because in step 1, byConfigProfider
adjusting the style class name prefix tocustom
, we need to re-compile the default style less file of antd to generate a css file through the lessc command. ※ Note: If less is not installed, you need to install less:npm install -g less
lessc --modify-var="ant-prefix=custom" node_modules/antd/dist/antd.variable.less custom.css
If you simply execute the above command according to the operation in the official document, the console will report an error:
SyntaxError: Inline JavaScript is not enabled. Is it set in your options? in D:\workspace\workspace_for_java\SPB-LERN\web-react-ts\node_modules\antd\lib\style\color\bezierEasing.less on line 110, column 1: 109 // https://github.com/ant-design/ant-motion/issues/44 110 .bezierEasingMixin(); 111
Because the default lessc command does not enable the javascript function, you need to enable the javascript function through parameters, refer to the link: https://lesscss.org/usage/#less-options-enable-inline-javascript-deprecated- . Add
--js
parameters to the above command and execute:lessc --js --modify-var="ant-prefix=custom" node_modules/antd/dist/antd.variable.less custom.css
-
According to the command in step 2, one will be generated
custom.css
. Since the file is too large, a few paragraphs are intercepted as follows:html { --custom-primary-color: #1890ff; --custom-primary-color-hover: #40a9ff; --custom-primary-color-active: #096dd9; --custom-primary-color-outline: rgba(24, 144, 255, 0.2); --custom-primary-1: #e6f7ff; --custom-primary-2: #bae7ff; --custom-primary-3: #91d5ff; --custom-primary-4: #69c0ff; --custom-primary-5: #40a9ff; --custom-primary-6: #1890ff; --custom-primary-7: #096dd9; --custom-primary-color-deprecated-pure: ; --custom-primary-color-deprecated-l-35: #cbe6ff; --custom-primary-color-deprecated-l-20: #7ec1ff; --custom-primary-color-deprecated-t-20: #46a6ff; --custom-primary-color-deprecated-t-50: #8cc8ff; --custom-primary-color-deprecated-f-12: rgba(24, 144, 255, 0.12); --custom-primary-color-active-deprecated-f-30: rgba(230, 247, 255, 0.3); --custom-primary-color-active-deprecated-d-02: #dcf4ff; /* 以下内容略去 */
Among them, the color in the second line
--custom-primary-color
is the primary sample color, the default is antd's default blue, which is used to test the effect, we can change the color to red:html { --custom-primary-color: #ff0000;/* 修改为红色 */ --custom-primary-color-hover: #40a9ff;
-
index.js
File imports the files from the above stepscustom.css
. ※Note: The default antd style fileantd/dist/antd.css
also needs to be imported.index.js
The complete code of the file is as follows:import React, { useState } from "react"; import ReactDOM from "react-dom"; import { Button, DatePicker, Radio, Space, version } from "antd"; import { ConfigProvider } from "antd"; import "antd/dist/antd.css"; // antd默认样式文件 import "./custom.css"; // 修改后的样式文件 import "./index.css"; const TestComponent = () => { const [prefix, setPrefix] = useState("ant"); const handlePrefixChange = (e) => { setPrefix(e.target.value); }; return ( // ConfigProvider修改prefixCls <ConfigProvider prefixCls={ prefix}> <div className="App"> <h1> <Space> Change Theme: { /* radio动态修改prefix */} <Radio.Group onChange={ handlePrefixChange} value={ prefix}> <Radio value="ant">Ant Style</Radio> <Radio value="custom">Custom Style</Radio> </Radio.Group> </Space> </h1> <h1>antd version: { version}</h1> <DatePicker /> <Button type="primary" style={ { marginLeft: 8 }}> Primary Button </Button> </div> </ConfigProvider> ); }; ReactDOM.render(<TestComponent />, document.getElementById("root"));
final effect
From the above figure, we can see that when the radio radio button selects ant style, the theme color of the page rendering is the default blue of ant at this time, and after the radio selects custom style, the theme color of the page rendering has been dynamically switched to our modified one red. Through the browser debugging window, we can find that the class name prefix of the button is ant
. After selecting custom style, the class name prefix is switched to custom
.
write at the end
Since then, we have achieved the effect of dynamically switching themes.
Click here to view the complete project code: https://codesandbox.io/s/antd-change-style-8rb12?file=/index.js
In addition, some people may have the need to dynamically switch between the default theme and the dark theme, you can refer to This article: https://blog.csdn.net/m0_58016522/article/details/122067153
Reference link:
https://ant-design.gitee.io/changelog-cn
https://ant-design.gitee.io/docs/react/customize-theme-variable-cn
Extended reading:
https://blog.csdn.net/m0_58016522/article/details/119104454