mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
feat(ConfigProvider): add icon-prefix prop (#8986)
This commit is contained in:
parent
b5ea1cd3ad
commit
2a74d88c91
@ -1,14 +1,22 @@
|
|||||||
import { computed, CSSProperties, defineComponent, PropType } from 'vue';
|
import {
|
||||||
import { createNamespace } from '../utils';
|
provide,
|
||||||
|
computed,
|
||||||
|
PropType,
|
||||||
|
CSSProperties,
|
||||||
|
InjectionKey,
|
||||||
|
defineComponent,
|
||||||
|
} from 'vue';
|
||||||
|
import { createNamespace, kebabCase } from '../utils';
|
||||||
|
|
||||||
const [name, bem] = createNamespace('config-provider');
|
const [name, bem] = createNamespace('config-provider');
|
||||||
|
|
||||||
export function kebabCase(word: string) {
|
export type ConfigProviderProvide = {
|
||||||
return word
|
iconPrefix?: string;
|
||||||
.replace(/([A-Z])/g, '-$1')
|
};
|
||||||
.toLowerCase()
|
|
||||||
.replace(/^-/, '');
|
export const CONFIG_PROVIDER_KEY: InjectionKey<ConfigProviderProvide> = Symbol(
|
||||||
}
|
name
|
||||||
|
);
|
||||||
|
|
||||||
function mapThemeVarsToCSSVars(themeVars: Record<string, string | number>) {
|
function mapThemeVarsToCSSVars(themeVars: Record<string, string | number>) {
|
||||||
const cssVars: Record<string, string | number> = {};
|
const cssVars: Record<string, string | number> = {};
|
||||||
@ -23,6 +31,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
props: {
|
props: {
|
||||||
themeVars: Object as PropType<Record<string, string | number>>,
|
themeVars: Object as PropType<Record<string, string | number>>,
|
||||||
|
iconPrefix: String,
|
||||||
tag: {
|
tag: {
|
||||||
type: String as PropType<keyof HTMLElementTagNameMap>,
|
type: String as PropType<keyof HTMLElementTagNameMap>,
|
||||||
default: 'div',
|
default: 'div',
|
||||||
@ -36,6 +45,8 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
provide(CONFIG_PROVIDER_KEY, props);
|
||||||
|
|
||||||
return () => (
|
return () => (
|
||||||
<props.tag class={bem()} style={style.value}>
|
<props.tag class={bem()} style={style.value}>
|
||||||
{slots.default?.()}
|
{slots.default?.()}
|
||||||
|
@ -196,6 +196,7 @@ There are some **Basic Variables** below, for component CSS Variables, please re
|
|||||||
### Props
|
### Props
|
||||||
|
|
||||||
| Attribute | Description | Type | Default |
|
| Attribute | Description | Type | Default |
|
||||||
| ------------ | ------------------------ | -------- | ------- |
|
| -------------------- | ------------------------ | -------- | ---------- |
|
||||||
| theme-vars | Theme variables | _object_ | - |
|
| theme-vars | Theme variables | _object_ | - |
|
||||||
| tag `v3.1.2` | HTML Tag of root element | _string_ | `div` |
|
| tag `v3.1.2` | HTML Tag of root element | _string_ | `div` |
|
||||||
|
| icon-prefix `v3.1.3` | Icon className prefix | _string_ | `van-icon` |
|
||||||
|
@ -196,6 +196,7 @@ export default {
|
|||||||
### Props
|
### Props
|
||||||
|
|
||||||
| 参数 | 说明 | 类型 | 默认值 |
|
| 参数 | 说明 | 类型 | 默认值 |
|
||||||
| ------------ | ------------------------ | -------- | ------ |
|
| --- | --- | --- | --- |
|
||||||
| theme-vars | 自定义主题变量 | _object_ | - |
|
| theme-vars | 自定义主题变量 | _object_ | - |
|
||||||
| tag `v3.1.2` | 根节点对应的 HTML 标签名 | _string_ | `div` |
|
| tag `v3.1.2` | 根节点对应的 HTML 标签名 | _string_ | `div` |
|
||||||
|
| icon-prefix `v3.1.3` | 所有图标的类名前缀,同 Icon 组件的 [class-prefix 属性](#/zh-CN/icon#props) | _string_ | `van-icon` |
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`should render tag prop correctly 1`] = `
|
|
||||||
<section class="van-config-provider">
|
|
||||||
</section>
|
|
||||||
`;
|
|
13
src/config-provider/test/__snapshots__/index.spec.tsx.snap
Normal file
13
src/config-provider/test/__snapshots__/index.spec.tsx.snap
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`should change icon class-prefix when using icon-prefix prop 1`] = `
|
||||||
|
<div class="van-config-provider">
|
||||||
|
<i class="van-badge__wrapper foo foo-success">
|
||||||
|
</i>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`should render tag prop correctly 1`] = `
|
||||||
|
<section class="van-config-provider">
|
||||||
|
</section>
|
||||||
|
`;
|
@ -1,11 +0,0 @@
|
|||||||
import { ConfigProvider } from '..';
|
|
||||||
import { mount } from '../../../test';
|
|
||||||
|
|
||||||
test('should render tag prop correctly', () => {
|
|
||||||
const wrapper = mount(ConfigProvider, {
|
|
||||||
props: {
|
|
||||||
tag: 'section',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(wrapper.html()).toMatchSnapshot();
|
|
||||||
});
|
|
25
src/config-provider/test/index.spec.tsx
Normal file
25
src/config-provider/test/index.spec.tsx
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { ConfigProvider } from '..';
|
||||||
|
import { Icon } from '../../icon';
|
||||||
|
import { mount } from '../../../test';
|
||||||
|
|
||||||
|
test('should render tag prop correctly', () => {
|
||||||
|
const wrapper = mount(ConfigProvider, {
|
||||||
|
props: {
|
||||||
|
tag: 'section',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(wrapper.html()).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should change icon class-prefix when using icon-prefix prop', () => {
|
||||||
|
const wrapper = mount({
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<ConfigProvider iconPrefix="foo">
|
||||||
|
<Icon name="success" />
|
||||||
|
</ConfigProvider>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(wrapper.html()).toMatchSnapshot();
|
||||||
|
});
|
@ -1,11 +1,12 @@
|
|||||||
import { PropType, defineComponent } from 'vue';
|
import { PropType, defineComponent, inject, computed } from 'vue';
|
||||||
import { addUnit, createNamespace } from '../utils';
|
import { addUnit, createNamespace } from '../utils';
|
||||||
import { Badge } from '../badge';
|
import { Badge } from '../badge';
|
||||||
|
import { CONFIG_PROVIDER_KEY } from '../config-provider/ConfigProvider';
|
||||||
|
|
||||||
const [name, bem] = createNamespace('icon');
|
const [name, bem] = createNamespace('icon');
|
||||||
|
|
||||||
function isImage(name?: string) {
|
function isImage(name?: string) {
|
||||||
return name ? name.includes('/') : false;
|
return name?.includes('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
@ -17,19 +18,22 @@ export default defineComponent({
|
|||||||
size: [Number, String],
|
size: [Number, String],
|
||||||
badge: [Number, String],
|
badge: [Number, String],
|
||||||
color: String,
|
color: String,
|
||||||
|
classPrefix: String,
|
||||||
tag: {
|
tag: {
|
||||||
type: String as PropType<keyof HTMLElementTagNameMap>,
|
type: String as PropType<keyof HTMLElementTagNameMap>,
|
||||||
default: 'i',
|
default: 'i',
|
||||||
},
|
},
|
||||||
classPrefix: {
|
|
||||||
type: String,
|
|
||||||
default: bem(),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
setup(props, { slots }) {
|
setup(props, { slots }) {
|
||||||
|
const config = inject(CONFIG_PROVIDER_KEY, null);
|
||||||
|
|
||||||
|
const classPrefix = computed(
|
||||||
|
() => props.classPrefix || config?.iconPrefix || bem()
|
||||||
|
);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
const { tag, dot, name, size, badge, color, classPrefix } = props;
|
const { tag, dot, name, size, badge, color } = props;
|
||||||
const isImageIcon = isImage(name);
|
const isImageIcon = isImage(name);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -37,7 +41,10 @@ export default defineComponent({
|
|||||||
dot={dot}
|
dot={dot}
|
||||||
tag={tag}
|
tag={tag}
|
||||||
content={badge}
|
content={badge}
|
||||||
class={[classPrefix, isImageIcon ? '' : `${classPrefix}-${name}`]}
|
class={[
|
||||||
|
classPrefix.value,
|
||||||
|
isImageIcon ? '' : `${classPrefix.value}-${name}`,
|
||||||
|
]}
|
||||||
style={{
|
style={{
|
||||||
color,
|
color,
|
||||||
fontSize: addUnit(size),
|
fontSize: addUnit(size),
|
||||||
|
@ -4,6 +4,13 @@ export function camelize(str: string): string {
|
|||||||
return str.replace(camelizeRE, (_, c) => c.toUpperCase());
|
return str.replace(camelizeRE, (_, c) => c.toUpperCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function kebabCase(str: string) {
|
||||||
|
return str
|
||||||
|
.replace(/([A-Z])/g, '-$1')
|
||||||
|
.toLowerCase()
|
||||||
|
.replace(/^-/, '');
|
||||||
|
}
|
||||||
|
|
||||||
export function padZero(num: number | string, targetLength = 2): string {
|
export function padZero(num: number | string, targetLength = 2): string {
|
||||||
let str = num + '';
|
let str = num + '';
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user