Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to customize dynamic theme in Ant Design

2025-01-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

Editor to share with you how to customize the dynamic theme in Ant Design, I believe that most people do not know much about it, so share this article for your reference, I hope you can learn a lot after reading this article, let's go to know it!

Environmental preparation

For convenience, the example in this article uses the create-react-app + caco + craco-less implementation:

# to create a project create-react-app demo# installation must rely on yarn add antd # remember to install the latest version of yarn add-D @ craco/craco craco-less babel-plugin-import

Just modify the npm-script in package.json:

{scripts: {"start": "craco start"}}

By the way, add the initial craco.config.js:

Const CracoLessPlugin = require ('craco-less'); module.exports = {plugins: [{plugin: CracoLessPlugin}],}

Then, change the App.js:

Import {useState} from 'react';import {Avatar, Card, Button, Space, Switch} from' antd';function App () {const [theme, setTheme] = useState ('light'); const checked = theme = =' light'; const handleThemeChange = (checked) = > {setTheme (checked? 'light':' dark');}; return (dynamic theme);} export default App

Then start it and you can see the following interface:

How to introduce a theme?

In Ant Design, there are many kinds of poses to introduce the theme, so let's briefly sort it out first.

1. Bring in style files

Introduce style files directly into App.js:

/ / App.jsimport 'antd/dist/antd.css'

But now that you use craco-less, use Ant Design's less file, but when you introduce antd.less directly, you get the following error:

To solve this problem, you can simply open javascriptEnabled in lessOption:

Const CracoLessPlugin = require ('craco-less'); module.exports = {plugins: [{plugin: CracoLessPlugin, options: {lessLoaderOptions: {lessOptions: {javascriptEnabled: true,},},],}

Then you can see the following interface:

Of course, you can also choose to introduce it into App.less:

@ import'~ antd/dist/antd.less'

2. Babel-plugin-import

The previous article talked about how to use babel-plugin-import. The steps for using craco are the same, except that you need to add the corresponding configuration to craco.config.js:

/ / craco.config.jsmodule.exports = {babel: {plugins: [['import', {libraryName:' antd', libraryDirectory: 'es', style: true}],],}, / /...}

This allows you to delete the styles introduced in App.js/App.less above.

How to implement custom theme and dynamic theme?

The above two ways are the most commonly used ways to introduce Ant Design style, the following is based on the above way to explain how to modify and overwrite the original style.

You can actually find that there are many style files available in antd/dist:

├── antd.compact.less ├── antd.dark.less ├── antd.less ├── antd.variable.less ├── compact-theme.js ├── dark-theme.js ├── default-theme.js ├── theme.js └── variable-theme.js

Antd. (dark | compact). Less files are dark and compact mode respectively, while antd.variable.less files are only available in the latest version of Ant Design. What's the use of it? in addition to .less style files, you will find that there are several xxx-theme.js files. If you open them, you will find that they are actually variables of various themes. Take dark-theme.js as an example:

Const darkThemeSingle = {"theme": "dark", "popover-background": "# 1f1f1f", "popover-customize-border-color": "# 3a3a3a", "body-background": "@ black", "component-background": "# 141414", / /.}

How to use the following, let's start with the topic of this article: implementing custom themes and dynamic themes.

1. Custom theme

If you want to achieve a custom theme, it is very simple, simply style overlay, such as using a dark theme to directly introduce the dark mode of the style file, for example, under the default theme, there are two ways to modify the main tone: by modifying the style file or through lessOption.

/ / 1. By modifying the style file / / App.less@import'~ antd/dist/antd.less';@primary-color: green

/ / 2. Through lessOptions// craco.config.jsmodule.exports = {/ /... Plugins: [{plugin: CracoLessPlugin, options: {lessLoaderOptions: {lessOptions: {modifyVars: {'primary-color':' cyan',}, javascriptEnabled: true,},},],}

It is important to say that if both ways of customizing the theme are used, only the second type of content set through modifyVars will be applied. If you ask me why, I'll give you an extra lecture on less.

Less small class

Premise: introduce antd.less into App.less and override @ primary-color (take the green configured above as an example)

Less provides a command line that allows us to escape .less files to CSS through the Terminal command:

# escape less file npx lessc. / src/App.less. / src/App.css-- js

Let's take a look at what primary-color is in App.css:

.ant-btn-primary {border-color: green; background: green;}

You can see that primary-color is set to green, and let's add modifyVars to take a look.

Npx lessc. / src/App.less. / src/App.css-js-modify-var= "primary-color: cyan"

Take a look at the generated App.css:

.ant-btn-primary {border-color: cyan; background: cyan;}

Wow~ has been replaced with the same content in modifyVars as when we developed it locally! And why is that?

We go to the node_modules/.bin/lessc file and console the data and options contents in parseLessFile to get the source file string and some configuration on the command line, where we get:

# data@import 'antd/dist/antd.less';@primary-color: green;.App {text-align: center;} # options {javascriptEnabled: true, modifyVars: {' primary-color': 'cyan'}}

Then we go to the node_modules/less/lib/less/render.js file and enter the render method to see:

Var parseTree = new ParseTree (root, imports)

This step is to convert less to AST. Let's take a look at the converted AST:

Console.log (parseTree.root.rules); / / Rules AST [/ /... Node {name:'@ primary-color', value: Node {value: 'green'}}, Node {name:' @ primary-color', value: Node {value: 'cyan'}}, / /.]

Is that understandable? It is the variables in modifyVars that override the variables in the style file. Class dismissed!

Let's go back to the content related to the custom theme. Now let's talk about how to use the darkSingleTheme mentioned above. We can take a look at the content of theme.js:

Function getThemeVariables (options = {}) {let themeVar = {'hack': `true;@import "${require.resolve (' antd/lib/style/color/colorPalette.less')}"; `,... defaultTheme}; if (options.dark) {themeVar = {... themeVar,... darkThemeSingle}} if (options.compact) {themeVar = {... themeVar,... compactThemeSingle}} return themeVar;}

As you can see, if we set dark or compact to true when using getThemeVariables, we can apply the corresponding style. Let's try it:

/ / craco.config.jsmodule.exports = {/ /... Plugins: [{plugin: CracoLessPlugin, options: {lessLoaderOptions: {lessOptions: {modifyVars: {... getThemeVariables ({dark: true,}),}, javascriptEnabled: true,},},],}

As simple as that, when using getThemeVariables, you can also override the style with the modifyVars mentioned above. This is the common way to customize the theme, which is the override variable mentioned earlier. Let's sum up these two ways:

Introduce the theme style file and overwrite the corresponding Less variable

Use getThemeVariables to introduce the corresponding topic and override the variable value through modifyVars

two。 Dynamic theme

Up to now, Ant Design documents do not have the function of switching light / dark mode, but the corresponding function is mentioned in the document. This paper mainly introduces three ways, one of which is the official dynamic theme (experimental).

i. Dynamically switch style files

Switch style files, this should be the easiest way to think of, Ant Design already provides styles such as default/dark/compact themes, we just need to save these files in our project, switch on demand, this program does not go into detail, and it is very easy to implement.

II. ConfigProvider

ConfigProvider is an experimental dynamic theme scheme provided by Ant Design. It is easy to use. Introduce the variable.less file into the entry .less file, and then overwrite the corresponding variables in ConfigProvider, using the following:

/ / App.less@import 'antd/dist/antd.variable.less'

The default style is the same as primary, and then we use ConfigProvider to modify the theme color (again take primaryColor as an example):

/ / App.js// add the following line ConfigProvider.config ({theme: {primaryColor: 'aquamarine'}})

Dynamic switching We use it in the same way as above:

/ / App.jsConfigProvider.config ({theme: {primaryColor: checked? 'aquamarine':' darkgreen',},})

So convenient, so easy to use, is there any deficiency in him? Yes, but as long as you don't mind, it's not a big problem. The number of colors that can be configured through ConfigProvider is limited:

/ / node_modules/antd/es/config-provider/context.d.tsinterface Theme {primaryColor?: string; infoColor?: string; successColor?: string; processingColor?: string; errorColor?: string; warningColor?: string;}

As you can see, there are only six colors configured in this way, but if you want to extends Theme to add other fields, I'm sorry, it won't work, let's take a look at how it handles these colors:

/ * * @ param {string} colorVal * @ param {string} type * / var fillColor = function fillColor (colorVal, type) {var baseColor = new TinyColor (colorVal); var colorPalettes = generate (baseColor.toRgbString ()); variables [".concat (type,"-color ")] = formatColor (baseColor); variables [" .concat (type, "- color-disabled")] = colorPalettes [1]; variables [".concat (type,"-color-hover ")] = colorPalettes [4] Variables [".concat (type,"-color-active ")] = colorPalettes [7]; variables [".concat (type,"-color-outline ")] = baseColor.clone (). SetAlpha (0.2). ToRgbString (); variables [" .concat (type, "- color-deprecated-bg")] = colorPalettes [1]; variables [".concat (type,"-color-deprecated-border ")] = colorPalettes [3];} / / use the following fillColor (theme.successColor, 'success')

So he only has a specific treatment for these colors, but not for other colors (such as component background color), but even if some colors are named in accordance with this specification, it will not work. After all, Ant Design uses if (theme.successColor) to conditionally modify these colors.

III. CSS Variables

I intend to introduce the contents of antd.variable.less in II. ConfigProvider in this section, because this method is essentially similar to the ConfigProvider provided by Ant Design: changing the global color through CSS Variables. Let's open the corresponding file and take a brief look at the contents:

/ / node_modules/antd/lib/style/themes/variable.lesshtml {@ base-primary: @ blue-6;-- @ {ant-prefix}-primary-color: @ base-primary;-- @ {ant-prefix}-primary-color-hover: color (~ `colorPalette ('@ {base-primary}', 5) `);-@ {ant-prefix}-primary-color-active: color (~ `colorPalette ('@ {base-primary}', 7)`) -- @ {ant-prefix}-primary-color-outline: fade (@ base-primary, @ outline-fade); / /.

The above code involves several basic syntax in less: Variable Interpolation and Escaping.

You can see the screenshot above, and I won't repeat it. Ant Design implements the dynamic theme in this way, setting the color value to a variable CSS Variables. Since the ConfigProvider variable color is limited, let's define these colors ourselves ~ it's complicated to implement this way, but customizability is infinitely possible.

/ / App.less:root {--main-color: green;}. Ant-btn {& .ant-btn-primary {border-color: ~ 'var (--main-color)'; background: ~ 'var (--main-color)';}}

Take a look at the effect achieved in this way:

How to modify: styles in root? The specific implementation of Ant Design you can see node_modules/antd/es/config-provider/cssVariable.js and node_modules/rc-util/es/Dom/dynamicCSS.js two files, the content is very simple. I first wrote a simple version:

Const dark = {'- main-color': 'darkgray',}; const light = {'-main-color': 'green',}; const themes = {dark, light}; const changeTheme = (theme) = > {const nextTheme = themes [theme]; Object.keys (nextTheme). ForEach ((key) = > {document.documentElement.style.setProperty (key, nextTheme [key]);});}

The changeTheme method is the way to modify the style in root.

But why not just use the form @ primary-color: ~ 'var (--main-color)' in App.less, instead of rewriting the component style?

If you look at the source code of the style file in Ant Design, you will find that a lot of function is used, such as the fade function in less:

Set the absolute opacity of a color. Can be applied to colors whether they already have an opacity value or not.

From Less official website: https://lesscss.org/functions/#color-operations-fade

If we modify styles such as @ primary-color in the form we just mentioned, less will throw an exception: Argument cannot be evaluated to a color:

/ / node_modules/less/lib/less/functions/color.js// fade method function fade (color, amount) {var hsl = toHSL (color); hsl.a = amount.value / 100; hsl.a = clamp (hsl.a); return hsla (color, hsl);} / / toHSL method function toHSL (color) {/ / the color.toHSL function here is the toHSL function if (color.toHSL) {return color.toHSL () in color.js below } else {throw new Error ('Argument cannot be evaluated to a color');} / / node_modules/less/lib/less/tree/color.jsfunction toHSL () {var r = this.rgb [0] / 255, g = this.rgb [1] / 255, b = this.rgb [2] / 255, a = this.alpha; / /.}

In this way, we can see that if what we pass to the fade function is not an accurate color value, we can't get the rgb [0] equivalent in color.js, so an error will be reported directly in the less compilation process.

The above is all the content of the article "how to customize dynamic themes in Ant Design". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report