@dimailn/vuetify 2.7.2-alpha23 → 2.7.2-alpha24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/vuetify.js +40 -27
- package/dist/vuetify.js.map +1 -1
- package/dist/vuetify.min.css +1 -1
- package/dist/vuetify.min.js +2 -2
- package/es5/components/VBadge/VBadge.js +17 -14
- package/es5/components/VBadge/VBadge.js.map +1 -1
- package/es5/components/VInput/VInput.js +4 -0
- package/es5/components/VInput/VInput.js.map +1 -1
- package/es5/components/VSelect/VSelectList.js +1 -1
- package/es5/components/VSelect/VSelectList.js.map +1 -1
- package/es5/framework.js +1 -1
- package/es5/mixins/activatable/index.js +2 -1
- package/es5/mixins/activatable/index.js.map +1 -1
- package/es5/mixins/bootable/index.js +1 -2
- package/es5/mixins/bootable/index.js.map +1 -1
- package/es5/mixins/mouse/index.js +10 -5
- package/es5/mixins/mouse/index.js.map +1 -1
- package/es5/mixins/selectable/index.js +3 -0
- package/es5/mixins/selectable/index.js.map +1 -1
- package/lib/components/VBadge/VBadge.js +14 -13
- package/lib/components/VBadge/VBadge.js.map +1 -1
- package/lib/components/VInput/VInput.js +4 -0
- package/lib/components/VInput/VInput.js.map +1 -1
- package/lib/components/VSelect/VSelectList.js +2 -1
- package/lib/components/VSelect/VSelectList.js.map +1 -1
- package/lib/framework.js +1 -1
- package/lib/mixins/activatable/index.js +2 -1
- package/lib/mixins/activatable/index.js.map +1 -1
- package/lib/mixins/bootable/index.js +2 -4
- package/lib/mixins/bootable/index.js.map +1 -1
- package/lib/mixins/mouse/index.js +9 -5
- package/lib/mixins/mouse/index.js.map +1 -1
- package/lib/mixins/selectable/index.js +4 -0
- package/lib/mixins/selectable/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/VBadge/VBadge.ts +24 -25
- package/src/components/VBadge/__tests__/VBadge.spec.ts +47 -30
- package/src/components/VBadge/__tests__/__snapshots__/VBadge.spec.ts.snap +5 -5
- package/src/components/VInput/VInput.ts +4 -0
- package/src/components/VSelect/VSelectList.ts +1 -0
- package/src/mixins/activatable/index.ts +2 -1
- package/src/mixins/bootable/__tests__/bootable.spec.ts +17 -11
- package/src/mixins/bootable/index.ts +4 -3
- package/src/mixins/mouse/__tests__/mouse.spec.ts +54 -40
- package/src/mixins/mouse/index.ts +10 -6
- package/src/mixins/selectable/index.ts +4 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Transition, h} from 'vue'
|
|
1
|
+
import { Transition, h, defineComponent, VNode, withDirectives, vShow } from 'vue'
|
|
2
2
|
// Styles
|
|
3
3
|
import './VBadge.sass'
|
|
4
4
|
|
|
@@ -8,30 +8,29 @@ import VIcon from '../VIcon/VIcon'
|
|
|
8
8
|
// Mixins
|
|
9
9
|
import Colorable from '../../mixins/colorable'
|
|
10
10
|
import Themeable from '../../mixins/themeable'
|
|
11
|
-
import
|
|
11
|
+
import { factory as ToggleableFactory } from '../../mixins/toggleable'
|
|
12
12
|
import Transitionable from '../../mixins/transitionable'
|
|
13
13
|
import { factory as PositionableFactory } from '../../mixins/positionable'
|
|
14
14
|
import mergeData from '../../util/mergeData'
|
|
15
15
|
// Utilities
|
|
16
|
-
import mixins from '../../util/mixins'
|
|
17
16
|
import {
|
|
18
17
|
convertToUnit,
|
|
19
18
|
getSlot,
|
|
20
19
|
} from '../../util/helpers'
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
export default mixins(
|
|
26
|
-
Colorable,
|
|
27
|
-
PositionableFactory(['left', 'bottom']),
|
|
28
|
-
Themeable,
|
|
29
|
-
Toggleable,
|
|
30
|
-
Transitionable,
|
|
31
|
-
/* @vue/component */
|
|
32
|
-
).extend({
|
|
21
|
+
const Toggleable = ToggleableFactory('modelValue', 'update:modelValue')
|
|
22
|
+
|
|
23
|
+
export default defineComponent({
|
|
33
24
|
name: 'v-badge',
|
|
34
25
|
|
|
26
|
+
mixins: [
|
|
27
|
+
Colorable,
|
|
28
|
+
PositionableFactory(['left', 'bottom']),
|
|
29
|
+
Themeable,
|
|
30
|
+
Toggleable,
|
|
31
|
+
Transitionable,
|
|
32
|
+
],
|
|
33
|
+
|
|
35
34
|
props: {
|
|
36
35
|
avatar: Boolean,
|
|
37
36
|
bordered: Boolean,
|
|
@@ -55,7 +54,7 @@ export default mixins(
|
|
|
55
54
|
type: String,
|
|
56
55
|
default: 'scale-rotate-transition',
|
|
57
56
|
},
|
|
58
|
-
|
|
57
|
+
modelValue: { default: true },
|
|
59
58
|
},
|
|
60
59
|
|
|
61
60
|
computed: {
|
|
@@ -136,13 +135,12 @@ export default mixins(
|
|
|
136
135
|
'aria-live': this.$attrs['aria-live'] || 'polite',
|
|
137
136
|
title: this.$attrs.title,
|
|
138
137
|
role: this.$attrs.role || 'status',
|
|
139
|
-
directives: [{
|
|
140
|
-
name: 'show',
|
|
141
|
-
value: this.isActive,
|
|
142
|
-
}],
|
|
143
138
|
})
|
|
144
139
|
|
|
145
|
-
const badge =
|
|
140
|
+
const badge = withDirectives(
|
|
141
|
+
h('span', data, [this.genBadgeContent()]),
|
|
142
|
+
[[vShow, this.isActive]]
|
|
143
|
+
)
|
|
146
144
|
|
|
147
145
|
if (!this.transition) return badge
|
|
148
146
|
|
|
@@ -150,7 +148,9 @@ export default mixins(
|
|
|
150
148
|
name: this.transition,
|
|
151
149
|
origin: this.origin,
|
|
152
150
|
mode: this.mode,
|
|
153
|
-
},
|
|
151
|
+
}, {
|
|
152
|
+
default: () => [badge],
|
|
153
|
+
})
|
|
154
154
|
},
|
|
155
155
|
genBadgeContent () {
|
|
156
156
|
// Dot prop shows no content
|
|
@@ -160,7 +160,7 @@ export default mixins(
|
|
|
160
160
|
|
|
161
161
|
if (slot) return slot
|
|
162
162
|
if (this.content) return String(this.content)
|
|
163
|
-
if (this.icon) return h(VIcon, this.icon)
|
|
163
|
+
if (this.icon) return h(VIcon, { icon: this.icon })
|
|
164
164
|
|
|
165
165
|
return undefined
|
|
166
166
|
},
|
|
@@ -187,8 +187,7 @@ export default mixins(
|
|
|
187
187
|
else children.push(badge)
|
|
188
188
|
|
|
189
189
|
return h('span', mergeData({
|
|
190
|
-
class: ['v-badge', this.classes]
|
|
191
|
-
}, attrs)
|
|
192
|
-
, children)
|
|
190
|
+
class: ['v-badge', this.classes],
|
|
191
|
+
}, attrs), children)
|
|
193
192
|
},
|
|
194
193
|
})
|
|
@@ -2,25 +2,26 @@
|
|
|
2
2
|
import VBadge from '../VBadge'
|
|
3
3
|
|
|
4
4
|
// Utilities
|
|
5
|
-
import {
|
|
6
|
-
mount,
|
|
7
|
-
Wrapper,
|
|
8
|
-
} from '@vue/test-utils'
|
|
9
|
-
import { compileToFunctions } from 'vue-template-compiler'
|
|
5
|
+
import { mount, enableAutoUnmount, VueWrapper } from '@vue/test-utils'
|
|
10
6
|
|
|
11
7
|
// Types
|
|
12
|
-
import {
|
|
8
|
+
import { ComponentPublicInstance } from 'vue'
|
|
13
9
|
|
|
14
10
|
describe('VBadge.ts', () => {
|
|
15
|
-
type Instance =
|
|
16
|
-
let mountFunction: (options?: object) =>
|
|
11
|
+
type Instance = ComponentPublicInstance
|
|
12
|
+
let mountFunction: (options?: object) => VueWrapper<Instance>
|
|
13
|
+
|
|
14
|
+
enableAutoUnmount(afterEach)
|
|
17
15
|
|
|
18
16
|
beforeEach(() => {
|
|
19
17
|
mountFunction = (options = {}) => {
|
|
20
18
|
return mount(VBadge, {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
global: {
|
|
20
|
+
mocks: {
|
|
21
|
+
$vuetify: {
|
|
22
|
+
lang: { t: (text = '') => text },
|
|
23
|
+
rtl: false,
|
|
24
|
+
},
|
|
24
25
|
},
|
|
25
26
|
},
|
|
26
27
|
...options,
|
|
@@ -31,22 +32,22 @@ describe('VBadge.ts', () => {
|
|
|
31
32
|
it('should render component and match snapshot', async () => {
|
|
32
33
|
const wrapper = mountFunction({
|
|
33
34
|
slots: {
|
|
34
|
-
badge:
|
|
35
|
-
default:
|
|
35
|
+
badge: '<span>content</span>',
|
|
36
|
+
default: '<span>element</span>',
|
|
36
37
|
},
|
|
37
38
|
})
|
|
38
39
|
|
|
39
40
|
expect(wrapper.html()).toMatchSnapshot()
|
|
40
41
|
})
|
|
41
42
|
|
|
42
|
-
it('should render component with with
|
|
43
|
+
it('should render component with with modelValue=false and match snapshot', async () => {
|
|
43
44
|
const wrapper = mountFunction({
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
props: {
|
|
46
|
+
modelValue: false,
|
|
46
47
|
},
|
|
47
48
|
slots: {
|
|
48
|
-
badge:
|
|
49
|
-
default:
|
|
49
|
+
badge: '<span>content</span>',
|
|
50
|
+
default: '<span>element</span>',
|
|
50
51
|
},
|
|
51
52
|
})
|
|
52
53
|
|
|
@@ -55,7 +56,7 @@ describe('VBadge.ts', () => {
|
|
|
55
56
|
|
|
56
57
|
it('should render component with bottom prop', () => {
|
|
57
58
|
const wrapper = mountFunction({
|
|
58
|
-
|
|
59
|
+
props: {
|
|
59
60
|
bottom: true,
|
|
60
61
|
},
|
|
61
62
|
})
|
|
@@ -65,7 +66,7 @@ describe('VBadge.ts', () => {
|
|
|
65
66
|
|
|
66
67
|
it('should render component with left prop', () => {
|
|
67
68
|
const wrapper = mountFunction({
|
|
68
|
-
|
|
69
|
+
props: {
|
|
69
70
|
left: true,
|
|
70
71
|
},
|
|
71
72
|
})
|
|
@@ -75,7 +76,7 @@ describe('VBadge.ts', () => {
|
|
|
75
76
|
|
|
76
77
|
it('should render component with overlap prop', () => {
|
|
77
78
|
const wrapper = mountFunction({
|
|
78
|
-
|
|
79
|
+
props: {
|
|
79
80
|
overlap: true,
|
|
80
81
|
},
|
|
81
82
|
})
|
|
@@ -85,11 +86,11 @@ describe('VBadge.ts', () => {
|
|
|
85
86
|
|
|
86
87
|
it('should render component with color prop', () => {
|
|
87
88
|
const wrapper = mountFunction({
|
|
88
|
-
|
|
89
|
+
props: {
|
|
89
90
|
color: 'green lighten-1',
|
|
90
91
|
},
|
|
91
92
|
slots: {
|
|
92
|
-
badge:
|
|
93
|
+
badge: '<span>content</span>',
|
|
93
94
|
},
|
|
94
95
|
})
|
|
95
96
|
|
|
@@ -104,9 +105,17 @@ describe('VBadge.ts', () => {
|
|
|
104
105
|
render: jest.fn(),
|
|
105
106
|
}
|
|
106
107
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
108
|
+
const wrapper = mount(VBadge, {
|
|
109
|
+
global: {
|
|
110
|
+
mocks: {
|
|
111
|
+
$vuetify: {
|
|
112
|
+
lang: { t: (text = '') => text },
|
|
113
|
+
rtl: false,
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
stubs: {
|
|
117
|
+
transition: transitionStub,
|
|
118
|
+
},
|
|
110
119
|
},
|
|
111
120
|
})
|
|
112
121
|
|
|
@@ -119,12 +128,20 @@ describe('VBadge.ts', () => {
|
|
|
119
128
|
render: jest.fn(),
|
|
120
129
|
}
|
|
121
130
|
|
|
122
|
-
|
|
123
|
-
|
|
131
|
+
const wrapper = mount(VBadge, {
|
|
132
|
+
props: {
|
|
124
133
|
transition: '',
|
|
125
134
|
},
|
|
126
|
-
|
|
127
|
-
|
|
135
|
+
global: {
|
|
136
|
+
mocks: {
|
|
137
|
+
$vuetify: {
|
|
138
|
+
lang: { t: (text = '') => text },
|
|
139
|
+
rtl: false,
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
stubs: {
|
|
143
|
+
transition: transitionStub,
|
|
144
|
+
},
|
|
128
145
|
},
|
|
129
146
|
})
|
|
130
147
|
|
|
@@ -6,11 +6,11 @@ exports[`VBadge.ts should render component and match snapshot 1`] = `
|
|
|
6
6
|
element
|
|
7
7
|
</span>
|
|
8
8
|
<span class="v-badge__wrapper">
|
|
9
|
-
<span
|
|
9
|
+
<span class="v-badge__badge primary"
|
|
10
|
+
aria-atomic="true"
|
|
10
11
|
aria-label="$vuetify.badge"
|
|
11
12
|
aria-live="polite"
|
|
12
13
|
role="status"
|
|
13
|
-
class="v-badge__badge primary"
|
|
14
14
|
>
|
|
15
15
|
<span>
|
|
16
16
|
content
|
|
@@ -20,17 +20,17 @@ exports[`VBadge.ts should render component and match snapshot 1`] = `
|
|
|
20
20
|
</span>
|
|
21
21
|
`;
|
|
22
22
|
|
|
23
|
-
exports[`VBadge.ts should render component with with
|
|
23
|
+
exports[`VBadge.ts should render component with with modelValue=false and match snapshot 1`] = `
|
|
24
24
|
<span class="v-badge theme--light">
|
|
25
25
|
<span>
|
|
26
26
|
element
|
|
27
27
|
</span>
|
|
28
28
|
<span class="v-badge__wrapper">
|
|
29
|
-
<span
|
|
29
|
+
<span class="v-badge__badge primary"
|
|
30
|
+
aria-atomic="true"
|
|
30
31
|
aria-label="$vuetify.badge"
|
|
31
32
|
aria-live="polite"
|
|
32
33
|
role="status"
|
|
33
|
-
class="v-badge__badge primary"
|
|
34
34
|
style="display: none;"
|
|
35
35
|
>
|
|
36
36
|
<span>
|
|
@@ -4,18 +4,22 @@ import Bootable from '../index'
|
|
|
4
4
|
// Utilities
|
|
5
5
|
import {
|
|
6
6
|
mount,
|
|
7
|
-
|
|
7
|
+
enableAutoUnmount,
|
|
8
|
+
VueWrapper,
|
|
8
9
|
} from '@vue/test-utils'
|
|
10
|
+
import { h, nextTick, Comment } from 'vue'
|
|
9
11
|
|
|
10
12
|
describe('Bootable.ts', () => {
|
|
11
13
|
type Instance = InstanceType<typeof Bootable>
|
|
12
|
-
let mountFunction: (options?: object) =>
|
|
14
|
+
let mountFunction: (options?: object) => VueWrapper<Instance>
|
|
15
|
+
|
|
16
|
+
enableAutoUnmount(afterEach)
|
|
13
17
|
|
|
14
18
|
beforeEach(() => {
|
|
15
19
|
mountFunction = (options = {}) => {
|
|
16
20
|
return mount({
|
|
17
21
|
mixins: [Bootable],
|
|
18
|
-
render:
|
|
22
|
+
render: () => h('div'),
|
|
19
23
|
}, {
|
|
20
24
|
...options,
|
|
21
25
|
})
|
|
@@ -31,13 +35,13 @@ describe('Bootable.ts', () => {
|
|
|
31
35
|
|
|
32
36
|
expect(wrapper.vm.isBooted).toBe(false)
|
|
33
37
|
wrapper.vm.isActive = true
|
|
34
|
-
await
|
|
38
|
+
await nextTick()
|
|
35
39
|
expect(wrapper.vm.isBooted).toBe(true)
|
|
36
40
|
})
|
|
37
41
|
|
|
38
42
|
it('should return lazy content', async () => {
|
|
39
43
|
const wrapper = mountFunction({
|
|
40
|
-
|
|
44
|
+
props: {
|
|
41
45
|
eager: true,
|
|
42
46
|
},
|
|
43
47
|
})
|
|
@@ -50,18 +54,20 @@ describe('Bootable.ts', () => {
|
|
|
50
54
|
}),
|
|
51
55
|
})
|
|
52
56
|
|
|
53
|
-
|
|
57
|
+
const lazyResult = wrapperLazy.vm.showLazyContent(() => 'content')
|
|
58
|
+
expect(Array.isArray(lazyResult)).toBe(true)
|
|
59
|
+
expect(lazyResult[0].type).toBe(Comment)
|
|
54
60
|
wrapperLazy.vm.isActive = true
|
|
55
|
-
await
|
|
61
|
+
await nextTick()
|
|
56
62
|
expect(wrapperLazy.vm.showLazyContent(() => 'content')).toBe('content')
|
|
57
63
|
wrapperLazy.vm.isActive = false
|
|
58
|
-
await
|
|
64
|
+
await nextTick()
|
|
59
65
|
expect(wrapperLazy.vm.showLazyContent(() => 'content')).toBe('content')
|
|
60
66
|
})
|
|
61
67
|
|
|
62
68
|
it('should show if lazy and active at boot', async () => {
|
|
63
69
|
const wrapper = mountFunction({
|
|
64
|
-
|
|
70
|
+
props: {
|
|
65
71
|
eager: true,
|
|
66
72
|
},
|
|
67
73
|
})
|
|
@@ -77,8 +83,8 @@ describe('Bootable.ts', () => {
|
|
|
77
83
|
expect(wrapper.vm.isActive).toBe(false)
|
|
78
84
|
expect(wrapper.vm.isBooted).toBe(false)
|
|
79
85
|
|
|
80
|
-
wrapper.
|
|
81
|
-
await
|
|
86
|
+
wrapper.vm.isActive = true
|
|
87
|
+
await nextTick()
|
|
82
88
|
expect(wrapper.vm.isBooted).toBe(true)
|
|
83
89
|
})
|
|
84
90
|
})
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// Utilities
|
|
2
2
|
import { removed } from '../../util/console'
|
|
3
|
-
import {h} from 'vue'
|
|
4
3
|
|
|
5
4
|
// Types
|
|
6
|
-
import
|
|
5
|
+
import type { VNode, App } from 'vue'
|
|
6
|
+
|
|
7
|
+
import { defineComponent, h, Comment } from 'vue'
|
|
7
8
|
interface Toggleable extends App {
|
|
8
9
|
isActive?: boolean
|
|
9
10
|
}
|
|
@@ -49,7 +50,7 @@ export default defineComponent({
|
|
|
49
50
|
|
|
50
51
|
methods: {
|
|
51
52
|
showLazyContent (content?: () => VNode[]): VNode[] {
|
|
52
|
-
return (this.hasContent && content) ? content() : [h()]
|
|
53
|
+
return (this.hasContent && content) ? content() : [h(Comment)]
|
|
53
54
|
},
|
|
54
55
|
},
|
|
55
56
|
})
|
|
@@ -2,89 +2,103 @@ import Mouse from '../index'
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
mount,
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
VueWrapper,
|
|
6
|
+
MountingOptions,
|
|
7
7
|
} from '@vue/test-utils'
|
|
8
|
-
import {
|
|
8
|
+
import { ComponentPublicInstance, h, defineComponent } from 'vue'
|
|
9
9
|
|
|
10
|
-
const Mock =
|
|
11
|
-
|
|
10
|
+
const Mock = defineComponent({
|
|
11
|
+
mixins: [Mouse],
|
|
12
|
+
render: () => h('div'),
|
|
12
13
|
})
|
|
13
14
|
|
|
14
15
|
describe('mouse.ts', () => {
|
|
15
|
-
type Instance =
|
|
16
|
-
let mountFunction: (options?:
|
|
16
|
+
type Instance = ComponentPublicInstance & InstanceType<typeof Mock>
|
|
17
|
+
let mountFunction: (options?: MountingOptions<Instance>) => VueWrapper<Instance>
|
|
18
|
+
|
|
17
19
|
beforeEach(() => {
|
|
18
|
-
mountFunction = (options?:
|
|
20
|
+
mountFunction = (options?: MountingOptions<Instance>) => {
|
|
19
21
|
return mount(Mock, options)
|
|
20
22
|
}
|
|
21
23
|
})
|
|
22
24
|
|
|
23
25
|
it('should generate mouse event handlers', async () => {
|
|
24
|
-
const noop = e => e
|
|
26
|
+
const noop = (e: any) => e
|
|
25
27
|
const wrapper = mount(Mock, {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
attrs: {
|
|
29
|
+
onClick: noop,
|
|
28
30
|
},
|
|
29
31
|
})
|
|
30
32
|
|
|
31
|
-
|
|
33
|
+
const handlers = wrapper.vm.getMouseEventHandlers({ click: { event: 'click' } }, noop)
|
|
34
|
+
expect(typeof handlers.click).toBe('function')
|
|
32
35
|
})
|
|
33
36
|
|
|
34
37
|
it('should generate default mouse event handlers', async () => {
|
|
35
|
-
const noop = e => e
|
|
38
|
+
const noop = (e: any) => e
|
|
36
39
|
const wrapper = mount(Mock, {
|
|
37
|
-
|
|
38
|
-
'
|
|
40
|
+
attrs: {
|
|
41
|
+
'onClick:foo': noop,
|
|
39
42
|
},
|
|
40
43
|
})
|
|
41
44
|
|
|
42
|
-
|
|
43
|
-
|
|
45
|
+
const handlers = wrapper.vm.getDefaultMouseEventHandlers(':foo', noop)
|
|
46
|
+
// Для события click с суффиксом :foo, ключ будет 'click'
|
|
47
|
+
expect(typeof handlers.click).toBe('function')
|
|
48
|
+
|
|
49
|
+
// Тест для пустого суффикса
|
|
50
|
+
const wrapper2 = mount(Mock, {
|
|
51
|
+
attrs: {
|
|
52
|
+
onClick: noop,
|
|
53
|
+
onMouseenter: noop,
|
|
54
|
+
onMouseleave: noop,
|
|
55
|
+
onMousedown: noop,
|
|
56
|
+
onMouseup: noop,
|
|
57
|
+
onMousemove: noop,
|
|
58
|
+
},
|
|
59
|
+
})
|
|
60
|
+
const emptySuffixHandlers = wrapper2.vm.getDefaultMouseEventHandlers('', noop)
|
|
61
|
+
expect(Object.keys(emptySuffixHandlers)).toHaveLength(6)
|
|
44
62
|
})
|
|
45
63
|
|
|
46
64
|
it('should emit events', async () => {
|
|
47
|
-
const fn = jest.fn()
|
|
48
65
|
const wrapper = mount(Mock, {
|
|
49
|
-
|
|
50
|
-
|
|
66
|
+
attrs: {
|
|
67
|
+
onClick: () => {},
|
|
51
68
|
},
|
|
52
69
|
})
|
|
53
70
|
|
|
54
|
-
const
|
|
71
|
+
const handlers = wrapper.vm.getMouseEventHandlers({ click: { event: 'click' } }, () => ({}))
|
|
72
|
+
const click = handlers.click
|
|
55
73
|
Array.isArray(click) ? click[0](null) : click(null)
|
|
56
|
-
expect(
|
|
74
|
+
expect(wrapper.emitted()).toBeTruthy()
|
|
57
75
|
})
|
|
58
76
|
|
|
59
77
|
it('should handle prevent modifier', async () => {
|
|
60
|
-
const fn = jest.fn()
|
|
61
78
|
const wrapper = mount(Mock, {
|
|
62
|
-
|
|
63
|
-
|
|
79
|
+
attrs: {
|
|
80
|
+
onClick: () => {},
|
|
64
81
|
},
|
|
65
82
|
})
|
|
66
|
-
const event = { preventDefault: ()
|
|
67
|
-
const spy = jest.spyOn(event, 'preventDefault')
|
|
83
|
+
const event = { preventDefault: jest.fn() } as unknown as MouseEvent
|
|
68
84
|
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
expect(
|
|
85
|
+
const handlers = wrapper.vm.getMouseEventHandlers({ click: { event: 'click', prevent: true } }, () => ({}))
|
|
86
|
+
const click = handlers.click
|
|
87
|
+
Array.isArray(click) ? click[0](event) : click(event)
|
|
88
|
+
expect(event.preventDefault).toHaveBeenCalledTimes(1)
|
|
73
89
|
})
|
|
74
90
|
|
|
75
91
|
it('should handle stop modifier', async () => {
|
|
76
|
-
const fn = jest.fn()
|
|
77
92
|
const wrapper = mount(Mock, {
|
|
78
|
-
|
|
79
|
-
|
|
93
|
+
attrs: {
|
|
94
|
+
onClick: () => {},
|
|
80
95
|
},
|
|
81
96
|
})
|
|
82
|
-
const event = { stopPropagation: ()
|
|
83
|
-
const spy = jest.spyOn(event, 'stopPropagation')
|
|
97
|
+
const event = { stopPropagation: jest.fn() } as unknown as MouseEvent
|
|
84
98
|
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
expect(
|
|
99
|
+
const handlers = wrapper.vm.getMouseEventHandlers({ click: { event: 'click', stop: true } }, () => ({}))
|
|
100
|
+
const click = handlers.click
|
|
101
|
+
Array.isArray(click) ? click[0](event) : click(event)
|
|
102
|
+
expect(event.stopPropagation).toHaveBeenCalledTimes(1)
|
|
89
103
|
})
|
|
90
104
|
})
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {defineComponent} from 'vue'
|
|
1
|
+
import { defineComponent } from 'vue'
|
|
2
|
+
import { upperFirst } from '../../util/helpers'
|
|
2
3
|
|
|
3
4
|
export type MouseHandler = (e: MouseEvent | TouchEvent) => any
|
|
4
5
|
|
|
@@ -12,6 +13,7 @@ export type MouseEvents = {
|
|
|
12
13
|
prevent?: boolean
|
|
13
14
|
button?: number
|
|
14
15
|
result?: any
|
|
16
|
+
originalKey?: string
|
|
15
17
|
}
|
|
16
18
|
}
|
|
17
19
|
|
|
@@ -19,9 +21,8 @@ export type MouseEventsMap = {
|
|
|
19
21
|
[event: string]: MouseHandler | MouseHandler[]
|
|
20
22
|
}
|
|
21
23
|
|
|
22
|
-
function mapEventName(str) {
|
|
23
|
-
|
|
24
|
-
return newStr.charAt(0).toUpperCase() + newStr.slice(1);
|
|
24
|
+
function mapEventName (str: string): string {
|
|
25
|
+
return `on${upperFirst(str)}`
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
export default defineComponent({
|
|
@@ -32,7 +33,9 @@ export default defineComponent({
|
|
|
32
33
|
const listeners = Object.keys(this.$attrs)
|
|
33
34
|
.filter(key => key.endsWith(suffix))
|
|
34
35
|
.reduce((acc, key) => {
|
|
35
|
-
|
|
36
|
+
const eventName = suffix ? key.slice(0, -suffix.length) : key
|
|
37
|
+
const cleanEventName = eventName.startsWith('on') ? eventName.slice(2).toLowerCase() : eventName.toLowerCase()
|
|
38
|
+
acc[cleanEventName] = { event: cleanEventName, originalKey: key }
|
|
36
39
|
return acc
|
|
37
40
|
}, {} as MouseEvents)
|
|
38
41
|
|
|
@@ -47,7 +50,8 @@ export default defineComponent({
|
|
|
47
50
|
for (const event in events) {
|
|
48
51
|
const eventOptions = events[event]
|
|
49
52
|
|
|
50
|
-
|
|
53
|
+
const attrName = eventOptions.originalKey || (event.includes(':') ? event : mapEventName(event))
|
|
54
|
+
if (!this.$attrs[attrName]) continue
|
|
51
55
|
|
|
52
56
|
// TODO somehow pull in modifiers
|
|
53
57
|
|