React + Antd implements dynamic switching theme function

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.xthe update logs of the last few versions, and found that 4.17.0the 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.0the 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.0the 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 ConfigProviderset a unified style prefix through global configuration. For specific ConfigProviderrelated documents, please see here: https://ant-design.gitee.io/components/config-provider-cn/#API .
For example, the antd button control, after the parameter typeis set to 'primary', will be added after the actual rendering class="ant-btn ant-btn-primary", in which ant-btn-primarythe style controls the background color and border line color of the button. As shown in the figure below: ant-btn-primary-style
For the class name ant-btnand ant-btn-primary, antin 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

  1. According to the official documentation, by ConfigProfidermodifying at the top level prefixCls:

    import {
          
           ConfigProvider } from 'antd';
    
    export default () => (
      <ConfigProvider prefixCls="custom">
        <MyApp />
      </ConfigProvider>
    );
    
  2. Compile less
    Because in step 1, by ConfigProfideradjusting the style class name prefix to custom, 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 --jsparameters to the above command and execute:

    lessc --js --modify-var="ant-prefix=custom" node_modules/antd/dist/antd.variable.less custom.css	
    
  3. 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-coloris 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;
    
  4. index.jsFile imports the files from the above steps custom.css. ※Note: The default antd style file antd/dist/antd.cssalso needs to be imported. index.jsThe 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

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.default stylemodified style

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

Guess you like

Origin blog.csdn.net/m0_58016522/article/details/121751043