Compare commits

...

3 Commits

Author SHA1 Message Date
neverland
a1d95e685c
chore: release @vant/touch-emulator@1.3.1 (#8987) 2021-07-06 17:46:15 +08:00
Amumu
f595755484
feat(touch-emulator): 支持白名单排除 (#8984) 2021-07-06 17:26:31 +08:00
neverland
2a74d88c91
feat(ConfigProvider): add icon-prefix prop (#8986) 2021-07-06 17:24:22 +08:00
13 changed files with 120 additions and 43 deletions

View File

@ -29,3 +29,11 @@ import '@vant/touch-emulator';
```html
<script src="https://cdn.jsdelivr.net/npm/@vant/touch-emulator"></script>
```
## 禁用 touch 模拟
在标签上添加 `data-no-touch-simulate` 属性后,可以使这个标签(以及它的子元素)不触发 `touch` 模拟事件。
```html
<div data-no-touch-simulate />
```

View File

@ -1,5 +1,11 @@
# Changelog
### [v1.3.1]
`2021-07-06`
- support data-no-touch-simulate attr
### [v1.3.0]
`2021-05-26`

View File

@ -51,6 +51,19 @@
};
}
if (!Element.prototype.closest) {
Element.prototype.closest = function (s) {
var el = this;
do {
if (el.matches(s)) return el;
el = el.parentElement || el.parentNode;
} while (el !== null && el.nodeType === 1);
return null;
};
}
/**
* create an touch point
* @constructor
@ -130,7 +143,9 @@
eventTarget = ev.target;
}
triggerTouch(touchType, ev);
if (eventTarget.closest('[data-no-touch-simulate]') == null) {
triggerTouch(touchType, ev);
}
// reset
if (ev.type === 'mouseup') {

View File

@ -1,6 +1,6 @@
{
"name": "@vant/touch-emulator",
"version": "1.3.0",
"version": "1.3.1",
"description": "Vant touch emulator",
"main": "index.js",
"publishConfig": {

View File

@ -1,14 +1,22 @@
import { computed, CSSProperties, defineComponent, PropType } from 'vue';
import { createNamespace } from '../utils';
import {
provide,
computed,
PropType,
CSSProperties,
InjectionKey,
defineComponent,
} from 'vue';
import { createNamespace, kebabCase } from '../utils';
const [name, bem] = createNamespace('config-provider');
export function kebabCase(word: string) {
return word
.replace(/([A-Z])/g, '-$1')
.toLowerCase()
.replace(/^-/, '');
}
export type ConfigProviderProvide = {
iconPrefix?: string;
};
export const CONFIG_PROVIDER_KEY: InjectionKey<ConfigProviderProvide> = Symbol(
name
);
function mapThemeVarsToCSSVars(themeVars: Record<string, string | number>) {
const cssVars: Record<string, string | number> = {};
@ -23,6 +31,7 @@ export default defineComponent({
props: {
themeVars: Object as PropType<Record<string, string | number>>,
iconPrefix: String,
tag: {
type: String as PropType<keyof HTMLElementTagNameMap>,
default: 'div',
@ -36,6 +45,8 @@ export default defineComponent({
}
});
provide(CONFIG_PROVIDER_KEY, props);
return () => (
<props.tag class={bem()} style={style.value}>
{slots.default?.()}

View File

@ -195,7 +195,8 @@ There are some **Basic Variables** below, for component CSS Variables, please re
### Props
| Attribute | Description | Type | Default |
| ------------ | ------------------------ | -------- | ------- |
| theme-vars | Theme variables | _object_ | - |
| tag `v3.1.2` | HTML Tag of root element | _string_ | `div` |
| Attribute | Description | Type | Default |
| -------------------- | ------------------------ | -------- | ---------- |
| theme-vars | Theme variables | _object_ | - |
| tag `v3.1.2` | HTML Tag of root element | _string_ | `div` |
| icon-prefix `v3.1.3` | Icon className prefix | _string_ | `van-icon` |

View File

@ -195,7 +195,8 @@ export default {
### Props
| 参数 | 说明 | 类型 | 默认值 |
| ------------ | ------------------------ | -------- | ------ |
| theme-vars | 自定义主题变量 | _object_ | - |
| tag `v3.1.2` | 根节点对应的 HTML 标签名 | _string_ | `div` |
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| theme-vars | 自定义主题变量 | _object_ | - |
| tag `v3.1.2` | 根节点对应的 HTML 标签名 | _string_ | `div` |
| icon-prefix `v3.1.3` | 所有图标的类名前缀,同 Icon 组件的 [class-prefix 属性](#/zh-CN/icon#props) | _string_ | `van-icon` |

View File

@ -1,6 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render tag prop correctly 1`] = `
<section class="van-config-provider">
</section>
`;

View 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>
`;

View File

@ -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();
});

View 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();
});

View File

@ -1,11 +1,12 @@
import { PropType, defineComponent } from 'vue';
import { PropType, defineComponent, inject, computed } from 'vue';
import { addUnit, createNamespace } from '../utils';
import { Badge } from '../badge';
import { CONFIG_PROVIDER_KEY } from '../config-provider/ConfigProvider';
const [name, bem] = createNamespace('icon');
function isImage(name?: string) {
return name ? name.includes('/') : false;
return name?.includes('/');
}
export default defineComponent({
@ -17,19 +18,22 @@ export default defineComponent({
size: [Number, String],
badge: [Number, String],
color: String,
classPrefix: String,
tag: {
type: String as PropType<keyof HTMLElementTagNameMap>,
default: 'i',
},
classPrefix: {
type: String,
default: bem(),
},
},
setup(props, { slots }) {
const config = inject(CONFIG_PROVIDER_KEY, null);
const classPrefix = computed(
() => props.classPrefix || config?.iconPrefix || bem()
);
return () => {
const { tag, dot, name, size, badge, color, classPrefix } = props;
const { tag, dot, name, size, badge, color } = props;
const isImageIcon = isImage(name);
return (
@ -37,7 +41,10 @@ export default defineComponent({
dot={dot}
tag={tag}
content={badge}
class={[classPrefix, isImageIcon ? '' : `${classPrefix}-${name}`]}
class={[
classPrefix.value,
isImageIcon ? '' : `${classPrefix.value}-${name}`,
]}
style={{
color,
fontSize: addUnit(size),

View File

@ -4,6 +4,13 @@ export function camelize(str: string): string {
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 {
let str = num + '';