Compare commits

...

5 Commits

Author SHA1 Message Date
chenjiahan
32920ba0f2 release: vant v4.6.7 2023-09-04 22:23:23 +08:00
ShuGang Zhou
f553a87037
chore(ConfigProvider): update var name and init execute the sync function twice (#12248) 2023-09-04 22:21:56 +08:00
neverland
91a92b2b06
docs(ConfigProvider): update the guide of modify CSS vars (#12246)
* docs(ConfigProvider): update the guide of modify CSS vars

* docs: update
2023-09-04 08:23:51 +08:00
MrXwq
d6d90925d0
fix(eslint): using ignorePatterns to replace .eslintignore (#12237)
Co-authored-by: xuwenqiang <xuwenqiang@kanzhun.com>
2023-09-04 07:57:38 +08:00
ShuGang Zhou
5bcd41cfef
feat(ConfigProvider): add theme-vars-scope props enable root affects (#12240)
* feat(ConfigProvider): add theme-vars-in-root props enable root affects

* feat(ConfigProvider): add theme-vars-in-root props enable root affects

* feat(ConfigProvider): add theme-vars-in-root props enable root affects
2023-09-04 07:56:21 +08:00
8 changed files with 258 additions and 21 deletions

View File

@ -1,4 +0,0 @@
es
lib
dist
node_modules

View File

@ -7,6 +7,11 @@
"globals": {
"vi": true
},
"ignorePatterns": [
"es",
"lib",
"node_modules"
],
"overrides": [
{
"files": ["src/**/*"],

View File

@ -1,6 +1,6 @@
{
"name": "vant",
"version": "4.6.6",
"version": "4.6.7",
"description": "Mobile UI Components built on Vue",
"main": "lib/vant.cjs.js",
"module": "es/index.mjs",

View File

@ -26,6 +26,8 @@ const [name, bem] = createNamespace('config-provider');
export type ConfigProviderTheme = 'light' | 'dark';
export type ConfigProviderThemeVarsScope = 'local' | 'global';
export type ConfigProviderProvide = {
iconPrefix?: string;
};
@ -42,6 +44,7 @@ export const configProviderProps = {
themeVars: Object as ThemeVars,
themeVarsDark: Object as ThemeVars,
themeVarsLight: Object as ThemeVars,
themeVarsScope: makeStringProp<ConfigProviderThemeVarsScope>('local'),
iconPrefix: String,
};
@ -55,6 +58,22 @@ function mapThemeVarsToCSSVars(themeVars: Record<string, Numeric>) {
return cssVars;
}
function syncThemeVarsOnRoot(
newStyle: Record<string, Numeric> = {},
oldStyle: Record<string, Numeric> = {},
) {
Object.keys(newStyle).forEach((key) => {
if (newStyle[key] !== oldStyle[key]) {
document.documentElement.style.setProperty(key, newStyle[key] as string);
}
});
Object.keys(oldStyle).forEach((key) => {
if (!newStyle[key]) {
document.documentElement.style.removeProperty(key);
}
});
}
export default defineComponent({
name,
@ -93,6 +112,34 @@ export default defineComponent({
onActivated(addTheme);
onDeactivated(removeTheme);
onBeforeUnmount(removeTheme);
watch(style, (newStyle, oldStyle) => {
if (props.themeVarsScope === 'global') {
syncThemeVarsOnRoot(
newStyle as Record<string, Numeric>,
oldStyle as Record<string, Numeric>,
);
}
});
watch(
() => props.themeVarsScope,
(newScope, oldScope) => {
if (oldScope === 'global') {
// remove on Root
syncThemeVarsOnRoot({}, style.value as Record<string, Numeric>);
}
if (newScope === 'global') {
// add on root
syncThemeVarsOnRoot(style.value as Record<string, Numeric>, {});
}
},
);
if (props.themeVarsScope === 'global') {
// add on root
syncThemeVarsOnRoot(style.value as Record<string, Numeric>, {});
}
}
provide(CONFIG_PROVIDER_KEY, props);
@ -104,7 +151,10 @@ export default defineComponent({
});
return () => (
<props.tag class={bem()} style={style.value}>
<props.tag
class={bem()}
style={props.themeVarsScope === 'local' ? style.value : undefined}
>
{slots.default?.()}
</props.tag>
);

View File

@ -161,7 +161,17 @@ export default {
};
```
> Tips: ConfigProvider only affects its child components.
#### Scope of CSS Variables
By default, the CSS variables generated by `themeVars` are applied to the root node of the component, thereby only affecting the styles of its child components and not the entire page.
You can modify the scope of CSS variables using the `theme-vars-scope` prop. For example, by setting `theme-vars-scope` to `global`, the CSS variables generated by `themeVars` will be applied to the root node of the HTML and affect all components within the entire page.
```html
<van-config-provider :theme-vars="themeVars" theme-vars-scope="global">
...
</van-config-provider>
```
#### Use In TypeScript
@ -214,20 +224,64 @@ export default {
};
```
#### Using Class Names
In addition, you can also use the class selectors `.van-theme-light` and `.van-theme-dark` to individually modify the base variables and component variables in the light or dark mode.
```css
.van-theme-light {
--van-white: white;
}
.van-theme-dark {
--van-white: black;
}
```
## Variables
### Basic Variables
### Variable Types
CSS variables in Vant are divided into **basic variables** and **component variables**. Component variables will inherit the basic variables. After modifying the basic variables, all related components will be affected.
In Vant, CSS variables are divided into **basic variables** and **component variables**. Component variables inherit from basic variables, so modifying a basic variable will affect all related components.
#### Modify Basic Variables
#### Modifying Variables
- The basic variables can only be modified through the `:root` selector.
- The component variables can be modified through the `:root` selector and `ConfigProvider` component.
CSS variables have an inheritance relationship, where component variables inherit from the nearest parent basic variable.
You can also use the `.van-theme-light` and `.van-theme-dark` class selector to modify basic or component variables in light or dark mode individually.
Therefore, there are certain limitations when modifying basic variables. You need to use the `:root` selector or the global mode of the ConfigProvider component to modify basic variables. Otherwise, component variables may not inherit basic variables correctly.
#### Variables List
Taking the `--van-primary-color` basic variable as an example:
- You can modify it using the `:root` selector:
```css
:root {
--van-primary-color: red;
}
```
- You can modify it using the global mode of the ConfigProvider component:
```html
<van-config-provider
:theme-vars="{ primaryColor: 'red' }"
theme-vars-scope="global"
>
...
</van-config-provider>
```
- You cannot modify it using the default `local` mode of the ConfigProvider component:
```html
<van-config-provider :theme-vars="{ primaryColor: 'red' }">
...
</van-config-provider>
```
As for component variables, there are no such limitations, and you can modify them in any way you want.
### Basic Variables List
There are all **Basic Variables** below, for component CSS Variables, please refer to the documentation of each component.
@ -316,6 +370,7 @@ There are all **Basic Variables** below, for component CSS Variables, please ref
| theme-vars | Theme variables | _object_ | - |
| theme-vars-dark | Theme variables that work in dark modewill override `theme-vars` | _object_ | - |
| theme-vars-light | Theme variables that work in light mode, will override `theme-vars` | _object_ | - |
| theme-vars-scope | by default only affects its child componentsset to `global` for the entire page to take effect | _ConfigProviderThemeVarsScope_ | `local` |
| z-index | Set the z-index of all popup components, this property takes effect globally | _number_ | `2000` |
| tag | HTML Tag of root element | _string_ | `div` |
| icon-prefix | Icon className prefix | _string_ | `van-icon` |
@ -329,5 +384,6 @@ import type {
ConfigProviderProps,
ConfigProviderTheme,
ConfigProviderThemeVars,
ConfigProviderThemeVarsScope,
} from 'vant';
```

View File

@ -159,7 +159,17 @@ export default {
};
```
> 注意ConfigProvider 仅影响它的子组件的样式,不影响全局 root 节点。
#### CSS 变量生效范围
默认情况下themeVars 产生的 CSS 变量是设置在组件根节点上的,因此只会影响它的子组件的样式,不会影响整个页面。
你可以通过 `theme-vars-scope` 属性来修改 CSS 变量的生效范围。比如将 `theme-vars-scope` 设置为 `global`,此时 themeVars 产生的 CSS 变量会设置到 HTML 的根节点,并对整个页面内的所有组件生效。
```html
<van-config-provider :theme-vars="themeVars" theme-vars-scope="global">
...
</van-config-provider>
```
#### 在 TypeScript 中使用
@ -212,22 +222,64 @@ export default {
};
```
#### 使用类名
此外,你也可以使用 `.van-theme-light``.van-theme-dark` 这两个类名选择器来单独修改浅色或深色模式下的基础变量和组件变量。
```css
.van-theme-light {
--van-white: white;
}
.van-theme-dark {
--van-white: black;
}
```
## 主题变量
### 基础变量
### 变量类型
Vant 中的 CSS 变量分为 **基础变量****组件变量**。组件变量会继承基础变量,因此在修改基础变量后,会影响所有相关的组件。
#### 修改变量
由于 CSS 变量继承机制的原因,两者的修改方式有一定差异:
CSS 变量存在继承关系,组件变量会寻找最近的父级基础变量进行继承。
- 基础变量只能通过 `:root 选择器` 修改,不能通过 `ConfigProvider 组件` 修改。
- 组件变量可以通过 `:root 选择器``ConfigProvider 组件` 修改。
因此修改基础变量存在一定限制,你需要使用 `:root` 选择器或 ConfigProvider 组件的 global 模式来修改基础变量。否则,组件变量可能会无法正确继承基础变量。
你也可以使用 `.van-theme-light``.van-theme-dark` 这两个类名选择器来单独修改浅色或深色模式下的基础变量和组件变量。
`--van-primary-color` 这个基础变量为例:
#### 变量列表
- 可以通过 `:root` 选择器修改:
```css
:root {
--van-primary-color: red;
}
```
- 可以通过 ConfigProvider 组件的 global 模式修改:
```html
<van-config-provider
:theme-vars="{ primaryColor: 'red' }"
theme-vars-scope="global"
>
...
</van-config-provider>
```
- 不可以通过 ConfigProvider 组件默认的 `local` 模式修改:
```html
<van-config-provider :theme-vars="{ primaryColor: 'red' }">
...
</van-config-provider>
```
对于组件变量,则没有上述限制,可以通过任意方式修改。
### 基础变量列表
下面是所有的基础变量:
@ -318,6 +370,7 @@ Vant 中的 CSS 变量分为 **基础变量** 和 **组件变量**。组件变
| theme-vars | 自定义主题变量,局部生效 | _object_ | - |
| theme-vars-dark | 仅在深色模式下生效的主题变量,优先级高于 `theme-vars` | _object_ | - |
| theme-vars-light | 仅在浅色模式下生效的主题变量,优先级高于 `theme-vars` | _object_ | - |
| theme-vars-scope | 默认仅影响子组件的样式,设置为 `global` 整个页面生效 | _ConfigProviderThemeVarsScope_ | `local` |
| tag | 根节点对应的 HTML 标签名 | _string_ | `div` |
| z-index | 设置所有弹窗类组件的 z-index该属性对全局生效 | _number_ | `2000` |
| icon-prefix | 所有图标的类名前缀,等同于 Icon 组件的 [class-prefix 属性](#/zh-CN/icon#props) | _string_ | `van-icon` |
@ -331,5 +384,6 @@ import type {
ConfigProviderProps,
ConfigProviderTheme,
ConfigProviderThemeVars,
ConfigProviderThemeVarsScope,
} from 'vant';
```

View File

@ -7,6 +7,7 @@ export { configProviderProps } from './ConfigProvider';
export type {
ConfigProviderProps,
ConfigProviderTheme,
ConfigProviderThemeVarsScope,
} from './ConfigProvider';
export type { ConfigProviderThemeVars } from './types';

View File

@ -78,3 +78,78 @@ test('should apply theme-vars-dark in dark mode', () => {
'--van-rate-icon-full-color: green;',
);
});
test('should apply theme-vars-scope enable root affects', async () => {
const wrapper = mount({
render() {
return (
<ConfigProvider
theme="dark"
themeVars={{ rateIconFullColor: 'red' }}
themeVarsDark={{ rateIconFullColor: 'green' }}
themeVarsLight={{ rateIconFullColor: 'blue' }}
themeVarsScope="global"
/>
);
},
});
expect(document.documentElement.getAttribute('style')).toEqual(
'--van-rate-icon-full-color: green;',
);
expect(
wrapper.element.getAttribute('style') ===
'--van-rate-icon-full-color: green;',
).toBeFalsy();
await wrapper.setProps({
themeVarsScope: 'local',
});
expect(wrapper.element.getAttribute('style')).toEqual(
'--van-rate-icon-full-color: green;',
);
expect(
document.documentElement.getAttribute('style') ===
'--van-rate-icon-full-color: green;',
).toBeFalsy();
});
test('should apply theme-vars-scope enable root affects and sync theme vars', async () => {
const wrapper = mount({
render() {
return (
<ConfigProvider
theme="dark"
themeVars={{ rateIconFullColor: 'red' }}
themeVarsScope="global"
/>
);
},
});
expect(document.documentElement.getAttribute('style')).toEqual(
'--van-rate-icon-full-color: red;',
);
await wrapper.setProps({
themeVars: {
rateIconFullColor: 'red',
buttonPrimaryColor: 'red',
},
});
expect(document.documentElement.getAttribute('style')).toEqual(
'--van-rate-icon-full-color: red; --van-button-primary-color: red;',
);
await wrapper.setProps({
themeVars: {
buttonPrimaryColor: 'red',
},
});
expect(document.documentElement.getAttribute('style')).toEqual(
'--van-button-primary-color: red;',
);
});