vuetify 2.6.0-beta.0 → 2.6.0

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.
Files changed (166) hide show
  1. package/dist/json/attributes.json +64 -60
  2. package/dist/json/tags.json +1 -0
  3. package/dist/json/web-types.json +128 -92
  4. package/dist/vuetify.css +37 -33
  5. package/dist/vuetify.css.map +1 -1
  6. package/dist/vuetify.js +244 -146
  7. package/dist/vuetify.js.map +1 -1
  8. package/dist/vuetify.min.css +2 -2
  9. package/dist/vuetify.min.js +2 -2
  10. package/es5/components/VAutocomplete/VAutocomplete.js +20 -2
  11. package/es5/components/VAutocomplete/VAutocomplete.js.map +1 -1
  12. package/es5/components/VCalendar/VCalendarDaily.js +13 -15
  13. package/es5/components/VCalendar/VCalendarDaily.js.map +1 -1
  14. package/es5/components/VCalendar/mixins/calendar-with-events.js +4 -2
  15. package/es5/components/VCalendar/mixins/calendar-with-events.js.map +1 -1
  16. package/es5/components/VCalendar/mixins/mouse.js +1 -1
  17. package/es5/components/VCalendar/mixins/mouse.js.map +1 -1
  18. package/es5/components/VCombobox/VCombobox.js +0 -5
  19. package/es5/components/VCombobox/VCombobox.js.map +1 -1
  20. package/es5/components/VDialog/VDialog.js +4 -2
  21. package/es5/components/VDialog/VDialog.js.map +1 -1
  22. package/es5/components/VList/VListItem.js +8 -1
  23. package/es5/components/VList/VListItem.js.map +1 -1
  24. package/es5/components/VMenu/VMenu.js +1 -1
  25. package/es5/components/VMenu/VMenu.js.map +1 -1
  26. package/es5/components/VOtpInput/VOtpInput.js +14 -25
  27. package/es5/components/VOtpInput/VOtpInput.js.map +1 -1
  28. package/es5/components/VOverlay/VOverlay.js +1 -0
  29. package/es5/components/VOverlay/VOverlay.js.map +1 -1
  30. package/es5/components/VRadioGroup/VRadioGroup.js +7 -0
  31. package/es5/components/VRadioGroup/VRadioGroup.js.map +1 -1
  32. package/es5/components/VRangeSlider/VRangeSlider.js +4 -1
  33. package/es5/components/VRangeSlider/VRangeSlider.js.map +1 -1
  34. package/es5/components/VSelect/VSelect.js +1 -1
  35. package/es5/components/VSelect/VSelect.js.map +1 -1
  36. package/es5/components/VTabs/VTab.js +15 -4
  37. package/es5/components/VTabs/VTab.js.map +1 -1
  38. package/es5/components/VTextField/VTextField.js +6 -1
  39. package/es5/components/VTextField/VTextField.js.map +1 -1
  40. package/es5/components/VTreeview/VTreeviewNode.js +3 -1
  41. package/es5/components/VTreeview/VTreeviewNode.js.map +1 -1
  42. package/es5/components/transitions/createTransition.js +0 -20
  43. package/es5/components/transitions/createTransition.js.map +1 -1
  44. package/es5/directives/click-outside/index.js +21 -10
  45. package/es5/directives/click-outside/index.js.map +1 -1
  46. package/es5/directives/intersect/index.js +16 -12
  47. package/es5/directives/intersect/index.js.map +1 -1
  48. package/es5/directives/mutate/index.js +10 -8
  49. package/es5/directives/mutate/index.js.map +1 -1
  50. package/es5/directives/resize/index.js +11 -8
  51. package/es5/directives/resize/index.js.map +1 -1
  52. package/es5/directives/scroll/index.js +13 -10
  53. package/es5/directives/scroll/index.js.map +1 -1
  54. package/es5/framework.js +1 -1
  55. package/es5/locale/fr.js +1 -1
  56. package/es5/locale/fr.js.map +1 -1
  57. package/es5/mixins/detachable/index.js +32 -14
  58. package/es5/mixins/detachable/index.js.map +1 -1
  59. package/es5/mixins/intersectable/index.js +11 -2
  60. package/es5/mixins/intersectable/index.js.map +1 -1
  61. package/es5/mixins/overlayable/index.js +21 -11
  62. package/es5/mixins/overlayable/index.js.map +1 -1
  63. package/es5/mixins/routable/index.js +9 -3
  64. package/es5/mixins/routable/index.js.map +1 -1
  65. package/lib/components/VAutocomplete/VAutocomplete.js +18 -2
  66. package/lib/components/VAutocomplete/VAutocomplete.js.map +1 -1
  67. package/lib/components/VCalendar/VCalendarDaily.js +9 -9
  68. package/lib/components/VCalendar/VCalendarDaily.js.map +1 -1
  69. package/lib/components/VCalendar/mixins/calendar-with-events.js +4 -2
  70. package/lib/components/VCalendar/mixins/calendar-with-events.js.map +1 -1
  71. package/lib/components/VCalendar/mixins/mouse.js +1 -1
  72. package/lib/components/VCalendar/mixins/mouse.js.map +1 -1
  73. package/lib/components/VCombobox/VCombobox.js +0 -5
  74. package/lib/components/VCombobox/VCombobox.js.map +1 -1
  75. package/lib/components/VDialog/VDialog.js +5 -2
  76. package/lib/components/VDialog/VDialog.js.map +1 -1
  77. package/lib/components/VList/VListItem.js +9 -1
  78. package/lib/components/VList/VListItem.js.map +1 -1
  79. package/lib/components/VMenu/VMenu.js +1 -1
  80. package/lib/components/VMenu/VMenu.js.map +1 -1
  81. package/lib/components/VOtpInput/VOtpInput.js +14 -25
  82. package/lib/components/VOtpInput/VOtpInput.js.map +1 -1
  83. package/lib/components/VOverlay/VOverlay.js +1 -0
  84. package/lib/components/VOverlay/VOverlay.js.map +1 -1
  85. package/lib/components/VRadioGroup/VRadioGroup.js +9 -0
  86. package/lib/components/VRadioGroup/VRadioGroup.js.map +1 -1
  87. package/lib/components/VRangeSlider/VRangeSlider.js +4 -1
  88. package/lib/components/VRangeSlider/VRangeSlider.js.map +1 -1
  89. package/lib/components/VSelect/VSelect.js +1 -1
  90. package/lib/components/VSelect/VSelect.js.map +1 -1
  91. package/lib/components/VTabs/VTab.js +16 -6
  92. package/lib/components/VTabs/VTab.js.map +1 -1
  93. package/lib/components/VTextField/VTextField.js +8 -1
  94. package/lib/components/VTextField/VTextField.js.map +1 -1
  95. package/lib/components/VTreeview/VTreeviewNode.js +3 -1
  96. package/lib/components/VTreeview/VTreeviewNode.js.map +1 -1
  97. package/lib/components/transitions/createTransition.js +0 -6
  98. package/lib/components/transitions/createTransition.js.map +1 -1
  99. package/lib/directives/click-outside/index.js +22 -10
  100. package/lib/directives/click-outside/index.js.map +1 -1
  101. package/lib/directives/intersect/index.js +16 -12
  102. package/lib/directives/intersect/index.js.map +1 -1
  103. package/lib/directives/mutate/index.js +10 -8
  104. package/lib/directives/mutate/index.js.map +1 -1
  105. package/lib/directives/resize/index.js +9 -6
  106. package/lib/directives/resize/index.js.map +1 -1
  107. package/lib/directives/scroll/index.js +9 -6
  108. package/lib/directives/scroll/index.js.map +1 -1
  109. package/lib/framework.js +1 -1
  110. package/lib/locale/fr.js +1 -1
  111. package/lib/locale/fr.js.map +1 -1
  112. package/lib/mixins/detachable/index.js +28 -13
  113. package/lib/mixins/detachable/index.js.map +1 -1
  114. package/lib/mixins/intersectable/index.js +9 -2
  115. package/lib/mixins/intersectable/index.js.map +1 -1
  116. package/lib/mixins/overlayable/index.js +21 -11
  117. package/lib/mixins/overlayable/index.js.map +1 -1
  118. package/lib/mixins/routable/index.js +12 -3
  119. package/lib/mixins/routable/index.js.map +1 -1
  120. package/package.json +2 -2
  121. package/src/components/VAutocomplete/VAutocomplete.ts +15 -2
  122. package/src/components/VCalendar/VCalendarDaily.ts +7 -7
  123. package/src/components/VCalendar/mixins/calendar-with-events.sass +7 -1
  124. package/src/components/VCalendar/mixins/calendar-with-events.ts +3 -3
  125. package/src/components/VCalendar/mixins/mouse.ts +1 -1
  126. package/src/components/VCombobox/VCombobox.ts +0 -5
  127. package/src/components/VCombobox/__tests__/VCombobox-multiple.spec.ts +113 -0
  128. package/src/components/VCombobox/__tests__/VCombobox.spec.ts +30 -0
  129. package/src/components/VDialog/VDialog.ts +4 -2
  130. package/src/components/VImg/__tests__/VImg.spec.ts +1 -1
  131. package/src/components/VList/VListItem.sass +2 -1
  132. package/src/components/VList/VListItem.ts +7 -1
  133. package/src/components/VList/__tests__/VListItem.spec.ts +16 -0
  134. package/src/components/VMenu/VMenu.ts +1 -1
  135. package/src/components/VOtpInput/VOtpInput.sass +13 -16
  136. package/src/components/VOtpInput/VOtpInput.ts +12 -28
  137. package/src/components/VOtpInput/_variables.scss +2 -4
  138. package/src/components/VOverlay/VOverlay.ts +1 -0
  139. package/src/components/VRadioGroup/VRadioGroup.ts +8 -0
  140. package/src/components/VRangeSlider/VRangeSlider.ts +3 -1
  141. package/src/components/VSelect/VSelect.ts +1 -1
  142. package/src/components/VTabs/VTab.ts +14 -4
  143. package/src/components/VTabs/VTabs.sass +5 -2
  144. package/src/components/VTextField/VTextField.ts +8 -3
  145. package/src/components/VTreeview/VTreeviewNode.ts +3 -1
  146. package/src/components/transitions/createTransition.ts +0 -8
  147. package/src/directives/click-outside/__tests__/click-outside-shadow-dom.spec.ts +9 -6
  148. package/src/directives/click-outside/__tests__/click-outside.spec.ts +7 -4
  149. package/src/directives/click-outside/index.ts +19 -10
  150. package/src/directives/intersect/__tests__/intersect.spec.ts +13 -10
  151. package/src/directives/intersect/index.ts +15 -13
  152. package/src/directives/mutate/__tests__/mutate.spec.ts +36 -17
  153. package/src/directives/mutate/index.ts +9 -9
  154. package/src/directives/resize/__tests__/resize.spec.ts +4 -4
  155. package/src/directives/resize/index.ts +11 -6
  156. package/src/directives/scroll/__tests__/scroll.spec.ts +9 -9
  157. package/src/directives/scroll/index.ts +8 -7
  158. package/src/globals.d.ts +10 -12
  159. package/src/locale/fr.ts +1 -1
  160. package/src/mixins/detachable/index.ts +32 -15
  161. package/src/mixins/intersectable/index.ts +11 -2
  162. package/src/mixins/overlayable/index.ts +22 -11
  163. package/src/mixins/routable/__tests__/routable.spec.ts +82 -5
  164. package/src/mixins/routable/index.ts +10 -3
  165. package/src/styles/generic/_transitions.scss +219 -215
  166. package/src/styles/settings/_variables.scss +10 -9
@@ -38,17 +38,14 @@ export default baseMixins.extend<options>().extend({
38
38
 
39
39
  props: {
40
40
  length: {
41
- type: Number,
41
+ type: [Number, String],
42
42
  default: 6,
43
43
  },
44
44
  type: {
45
45
  type: String,
46
46
  default: 'text',
47
47
  },
48
- plain: {
49
- type: Boolean,
50
- default: false,
51
- },
48
+ plain: Boolean,
52
49
  },
53
50
 
54
51
  data: () => ({
@@ -123,26 +120,13 @@ export default baseMixins.extend<options>().extend({
123
120
  this.genTextFieldSlot(otpIdx),
124
121
  ]
125
122
  },
126
- genCol (otpIdx: number) {
127
- const node = this.$createElement('div', this.setTextColor(this.validationState, {
128
- staticClass: 'v-input',
129
- class: this.classes,
130
- }), [this.genControl(otpIdx)])
131
-
132
- return this.$createElement('div', {
133
- staticClass: 'col-input',
134
- }, [
135
- node,
136
- ])
137
- },
138
123
  genContent () {
139
- const cols = [...Array(this.length).keys()].map(x => {
140
- return this.genCol(x)
124
+ return Array.from({ length: +this.length }, (_, i) => {
125
+ return this.$createElement('div', this.setTextColor(this.validationState, {
126
+ staticClass: 'v-input',
127
+ class: this.classes,
128
+ }), [this.genControl(i)])
141
129
  })
142
-
143
- return [this.$createElement('div', {
144
- staticClass: 'row-container',
145
- }, cols)]
146
130
  },
147
131
  genFieldset () {
148
132
  return this.$createElement('fieldset', {
@@ -237,7 +221,7 @@ export default baseMixins.extend<options>().extend({
237
221
 
238
222
  const nextIndex = otpIdx + 1
239
223
  if (value) {
240
- if (nextIndex < this.length) {
224
+ if (nextIndex < +this.length) {
241
225
  this.changeFocus(nextIndex)
242
226
  } else {
243
227
  this.clearFocus(otpIdx)
@@ -271,7 +255,7 @@ export default baseMixins.extend<options>().extend({
271
255
  VInput.options.methods.onMouseUp.call(this, e)
272
256
  },
273
257
  onPaste (event: ClipboardEvent, index: number) {
274
- const maxCursor = this.length - 1
258
+ const maxCursor = +this.length - 1
275
259
  const inputVal = event?.clipboardData?.getData('Text')
276
260
  const inputDataArray = inputVal?.split('') || []
277
261
  event.preventDefault()
@@ -285,7 +269,7 @@ export default baseMixins.extend<options>().extend({
285
269
  const targetFocus = Math.min(index + inputDataArray.length, maxCursor)
286
270
  this.changeFocus(targetFocus)
287
271
 
288
- if (newOtp.length === this.length) { this.onCompleted(); this.clearFocus(targetFocus) }
272
+ if (newOtp.length === +this.length) { this.onCompleted(); this.clearFocus(targetFocus) }
289
273
  },
290
274
  applyValue (index: number, inputVal: string, next: Function) {
291
275
  const newOtp: string[] = [...this.otp]
@@ -319,12 +303,12 @@ export default baseMixins.extend<options>().extend({
319
303
  return index > 0 && this.changeFocus(index - 1)
320
304
  }
321
305
  if (eventKey === 'ArrowRight') {
322
- return index + 1 < this.length && this.changeFocus(index + 1)
306
+ return index + 1 < +this.length && this.changeFocus(index + 1)
323
307
  }
324
308
  },
325
309
  onCompleted () {
326
310
  const rsp = this.otp.join('')
327
- if (rsp.length === this.length) {
311
+ if (rsp.length === +this.length) {
328
312
  this.$emit('finish', rsp)
329
313
  }
330
314
  },
@@ -1,6 +1,4 @@
1
1
  @import '../../styles/styles.sass';
2
2
 
3
- $otp-row-container-margin-x: -4px !default;
4
- $otp-col-flex-grow: 1 !default;
5
- $otp-col-width: 100% !default;
6
- $otp-col-padding: 4px !default;
3
+ $otp-gutter: 4px !default;
4
+ $otp-width: 24px !default;
@@ -86,6 +86,7 @@ export default mixins(
86
86
 
87
87
  return h('div', {
88
88
  staticClass: 'v-overlay',
89
+ on: this.$listeners,
89
90
  class: this.classes,
90
91
  style: this.styles,
91
92
  }, children)
@@ -89,4 +89,12 @@ export default baseMixins.extend({
89
89
  },
90
90
  onClick: BaseItemGroup.options.methods.onClick,
91
91
  },
92
+
93
+ render (h) {
94
+ const vnode = VInput.options.render.call(this, h)
95
+
96
+ this._b(vnode.data!, 'div', this.attrs$)
97
+
98
+ return vnode
99
+ },
92
100
  })
@@ -229,7 +229,9 @@ export default VSlider.extend({
229
229
  this.thumbPressed = true
230
230
  }
231
231
 
232
- this.activeThumb = this.getIndexOfClosestValue(this.internalValue, value)
232
+ if (this.activeThumb === null) {
233
+ this.activeThumb = this.getIndexOfClosestValue(this.internalValue, value)
234
+ }
233
235
 
234
236
  this.setInternalValue(value)
235
237
  },
@@ -664,7 +664,7 @@ export default baseMixins.extend<options>().extend({
664
664
 
665
665
  // If menu is active, allow default
666
666
  // listIndex change from menu
667
- if (this.isMenuActive && keyCode !== keyCodes.tab) {
667
+ if (this.isMenuActive && [keyCodes.up, keyCodes.down, keyCodes.home, keyCodes.end, keyCodes.enter].includes(keyCode)) {
668
668
  this.$nextTick(() => {
669
669
  menu.changeListIndex(e)
670
670
  this.$emit('update:list-index', menu.listIndex)
@@ -67,12 +67,16 @@ export default baseMixins.extend<options>().extend(
67
67
  },
68
68
  },
69
69
 
70
- mounted () {
71
- this.onRouteChange()
72
- },
73
-
74
70
  methods: {
75
71
  click (e: KeyboardEvent | MouseEvent): void {
72
+ // Prevent keyboard actions
73
+ // from children elements
74
+ // within disabled tabs
75
+ if (this.disabled) {
76
+ e.preventDefault()
77
+ return
78
+ }
79
+
76
80
  // If user provides an
77
81
  // actual link, do not
78
82
  // prevent default
@@ -86,6 +90,12 @@ export default baseMixins.extend<options>().extend(
86
90
 
87
91
  this.to || this.toggle()
88
92
  },
93
+ toggle () {
94
+ // VItemGroup treats a change event as a click
95
+ if (!this.isActive) {
96
+ this.$emit('change')
97
+ }
98
+ },
89
99
  },
90
100
 
91
101
  render (h): VNode {
@@ -36,7 +36,7 @@
36
36
 
37
37
  .v-menu__activator
38
38
  height: 100%
39
-
39
+
40
40
  &.v.tabs--vertical.v-tabs--right
41
41
  flex-direction: row-reverse
42
42
 
@@ -221,5 +221,8 @@
221
221
  color: inherit
222
222
 
223
223
  .v-tab--disabled
224
- pointer-events: none
225
224
  opacity: $tab-disabled-opacity
225
+
226
+ &,
227
+ & *
228
+ pointer-events: none
@@ -231,10 +231,15 @@ export default baseMixins.extend<options>().extend({
231
231
  mounted () {
232
232
  // #11533
233
233
  this.$watch(() => this.labelValue, this.setLabelWidth)
234
-
235
234
  this.autofocus && this.tryAutofocus()
236
-
237
- requestAnimationFrame(() => (this.isBooted = true))
235
+ requestAnimationFrame(() => {
236
+ this.isBooted = true
237
+ requestAnimationFrame(() => {
238
+ if (!this.isIntersecting) {
239
+ this.onResize()
240
+ }
241
+ })
242
+ })
238
243
  },
239
244
 
240
245
  methods: {
@@ -36,6 +36,7 @@ export const VTreeviewNodeProps = {
36
36
  type: String,
37
37
  default: 'primary',
38
38
  },
39
+ disablePerNode: Boolean,
39
40
  expandIcon: {
40
41
  type: String,
41
42
  default: '$subgroup',
@@ -122,7 +123,7 @@ const VTreeviewNode = baseMixins.extend<options>().extend({
122
123
  disabled (): boolean {
123
124
  return (
124
125
  getObjectValueByPath(this.item, this.itemDisabled) ||
125
- (this.parentIsDisabled && this.selectionType === 'leaf')
126
+ (!this.disablePerNode && (this.parentIsDisabled && this.selectionType === 'leaf'))
126
127
  )
127
128
  },
128
129
  key (): string {
@@ -310,6 +311,7 @@ const VTreeviewNode = baseMixins.extend<options>().extend({
310
311
  selectable: this.selectable,
311
312
  selectedColor: this.selectedColor,
312
313
  color: this.color,
314
+ disablePerNode: this.disablePerNode,
313
315
  expandIcon: this.expandIcon,
314
316
  indeterminateIcon: this.indeterminateIcon,
315
317
  offIcon: this.offIcon,
@@ -87,16 +87,8 @@ export function createSimpleTransition (
87
87
  }
88
88
  if (context.props.hideOnLeave) {
89
89
  data.on!.leave = mergeTransitions(data.on!.leave, (el: HTMLElement) => {
90
- el._initialDisplay = [el.style.display, el.style.getPropertyPriority('display')]
91
90
  el.style.setProperty('display', 'none', 'important')
92
91
  })
93
- data.on!.afterLeave = mergeTransitions(data.on!.afterLeave, (el?: HTMLElement) => {
94
- if (el) {
95
- el._initialDisplay
96
- ? el.style.setProperty('display', ...el._initialDisplay)
97
- : el.style.removeProperty('display')
98
- }
99
- })
100
92
  }
101
93
 
102
94
  return h(tag, mergeData(context.data, data), context.children)
@@ -13,7 +13,8 @@ function bootstrap (args?: object) {
13
13
  handler: jest.fn(),
14
14
  ...args,
15
15
  },
16
- }
16
+ } as any
17
+ const vnode = { context: { _uid: 1 } } as any
17
18
 
18
19
  let shadowClickHandler
19
20
  let outsideClickHandler
@@ -37,9 +38,11 @@ function bootstrap (args?: object) {
37
38
  jest.spyOn(window.document, 'removeEventListener')
38
39
  jest.spyOn(shadowRoot, 'removeEventListener')
39
40
 
40
- ClickOutside.inserted(shadowEl as HTMLElement, binding as any)
41
+ ClickOutside.inserted(shadowEl as HTMLElement, binding, vnode)
41
42
 
42
43
  return {
44
+ binding,
45
+ vnode,
43
46
  callback: binding.value.handler,
44
47
  shadowEl: shadowEl as HTMLElement,
45
48
  outsideEl: outsideEl as HTMLElement,
@@ -53,18 +56,18 @@ function bootstrap (args?: object) {
53
56
 
54
57
  describe('click-outside.js within the Shadow DOM', () => {
55
58
  it('should register and unregister handler outside of the shadow DOM', () => {
56
- const { outsideClickHandler, shadowEl } = bootstrap()
59
+ const { outsideClickHandler, shadowEl, binding, vnode } = bootstrap()
57
60
  expect(window.document.addEventListener).toHaveBeenCalledWith('click', outsideClickHandler, true)
58
61
 
59
- ClickOutside.unbind(shadowEl)
62
+ ClickOutside.unbind(shadowEl, binding, vnode)
60
63
  expect(window.document.removeEventListener).toHaveBeenCalledWith('click', outsideClickHandler, true)
61
64
  })
62
65
 
63
66
  it('should register and unregister handler within the shadow DOM', () => {
64
- const { shadowClickHandler, shadowRoot, shadowEl } = bootstrap()
67
+ const { shadowClickHandler, shadowRoot, shadowEl, binding, vnode } = bootstrap()
65
68
  expect(shadowRoot.addEventListener).toHaveBeenCalledWith('click', shadowClickHandler, true)
66
69
 
67
- ClickOutside.unbind(shadowEl)
70
+ ClickOutside.unbind(shadowEl, binding, vnode)
68
71
  expect(shadowRoot.removeEventListener).toHaveBeenCalledWith('click', shadowClickHandler, true)
69
72
  })
70
73
 
@@ -10,7 +10,8 @@ function bootstrap (args?: object) {
10
10
  handler: jest.fn(),
11
11
  ...args,
12
12
  },
13
- }
13
+ } as any
14
+ const vnode = { context: { _uid: 1 } } as any
14
15
 
15
16
  let clickHandler
16
17
  let mousedownHandler
@@ -20,9 +21,11 @@ function bootstrap (args?: object) {
20
21
  })
21
22
  jest.spyOn(window.document, 'removeEventListener')
22
23
 
23
- ClickOutside.inserted(el as HTMLElement, binding as any)
24
+ ClickOutside.inserted(el as HTMLElement, binding, vnode)
24
25
 
25
26
  return {
27
+ binding,
28
+ vnode,
26
29
  callback: binding.value.handler,
27
30
  el: el as HTMLElement,
28
31
  clickHandler,
@@ -32,10 +35,10 @@ function bootstrap (args?: object) {
32
35
 
33
36
  describe('click-outside', () => {
34
37
  it('should register and unregister handler', () => {
35
- const { clickHandler, el } = bootstrap()
38
+ const { clickHandler, el, binding, vnode } = bootstrap()
36
39
  expect(window.document.addEventListener).toHaveBeenCalledWith('click', clickHandler, true)
37
40
 
38
- ClickOutside.unbind(el)
41
+ ClickOutside.unbind(el, binding, vnode)
39
42
  expect(window.document.removeEventListener).toHaveBeenCalledWith('click', clickHandler, true)
40
43
  })
41
44
 
@@ -1,5 +1,6 @@
1
1
  import { attachedRoot } from '../../util/dom'
2
2
  import { VNodeDirective } from 'vue/types/vnode'
3
+ import { VNode } from 'vue'
3
4
 
4
5
  interface ClickOutsideBindingArgs {
5
6
  handler: (e: Event) => void
@@ -52,7 +53,7 @@ function checkIsActive (e: PointerEvent, binding: ClickOutsideDirective): boolea
52
53
  return isActive(e)
53
54
  }
54
55
 
55
- function directive (e: PointerEvent, el: HTMLElement, binding: ClickOutsideDirective) {
56
+ function directive (e: PointerEvent, el: HTMLElement, binding: ClickOutsideDirective, vnode: VNode) {
56
57
  const handler = typeof binding.value === 'function' ? binding.value : binding.value!.handler
57
58
 
58
59
  el._clickOutside!.lastMousedownWasOutside && checkEvent(e, el, binding) && setTimeout(() => {
@@ -76,8 +77,8 @@ export const ClickOutside = {
76
77
  // sure that the root element is
77
78
  // available, iOS does not support
78
79
  // clicks on body
79
- inserted (el: HTMLElement, binding: ClickOutsideDirective) {
80
- const onClick = (e: Event) => directive(e as PointerEvent, el, binding)
80
+ inserted (el: HTMLElement, binding: ClickOutsideDirective, vnode: VNode) {
81
+ const onClick = (e: Event) => directive(e as PointerEvent, el, binding, vnode)
81
82
  const onMousedown = (e: Event) => {
82
83
  el._clickOutside!.lastMousedownWasOutside = checkEvent(e as PointerEvent, el, binding)
83
84
  }
@@ -87,23 +88,31 @@ export const ClickOutside = {
87
88
  app.addEventListener('mousedown', onMousedown, true)
88
89
  })
89
90
 
90
- el._clickOutside = {
91
- lastMousedownWasOutside: true,
91
+ if (!el._clickOutside) {
92
+ el._clickOutside = {
93
+ lastMousedownWasOutside: true,
94
+ }
95
+ }
96
+
97
+ el._clickOutside[vnode.context!._uid] = {
92
98
  onClick,
93
99
  onMousedown,
94
100
  }
95
101
  },
96
102
 
97
- unbind (el: HTMLElement) {
103
+ unbind (el: HTMLElement, binding: ClickOutsideDirective, vnode: VNode) {
98
104
  if (!el._clickOutside) return
99
105
 
100
106
  handleShadow(el, (app: HTMLElement) => {
101
- if (!app || !el._clickOutside) return
102
- app.removeEventListener('click', el._clickOutside.onClick, true)
103
- app.removeEventListener('mousedown', el._clickOutside.onMousedown, true)
107
+ if (!app || !el._clickOutside?.[vnode.context!._uid]) return
108
+
109
+ const { onClick, onMousedown } = el._clickOutside[vnode.context!._uid]!
110
+
111
+ app.removeEventListener('click', onClick, true)
112
+ app.removeEventListener('mousedown', onMousedown, true)
104
113
  })
105
114
 
106
- delete el._clickOutside
115
+ delete el._clickOutside[vnode.context!._uid]
107
116
  },
108
117
  }
109
118
 
@@ -10,16 +10,19 @@ describe('intersect', () => {
10
10
  Intersect.inserted(el, {
11
11
  value: callback,
12
12
  modifiers: { quiet: true },
13
- } as any)
13
+ } as any, { context: { _uid: 1 } } as any)
14
14
 
15
15
  expect((el as any)._observe).toBeTruthy()
16
16
  expect(callback).not.toHaveBeenCalled()
17
17
 
18
18
  document.body.removeChild(el)
19
19
 
20
- Intersect.unbind(el)
20
+ Intersect.unbind(el, {
21
+ value: callback,
22
+ modifiers: { quiet: true },
23
+ } as any, { context: { _uid: 1 } } as any)
21
24
 
22
- expect((el as any)._observe).toBeFalsy()
25
+ expect((el as any)._observe[1]).toBeFalsy()
23
26
  })
24
27
 
25
28
  it('should invoke callback once and unbind', () => {
@@ -32,19 +35,19 @@ describe('intersect', () => {
32
35
  Intersect.inserted(el, {
33
36
  value: callback,
34
37
  modifiers: { once: true },
35
- } as any)
38
+ } as any, { context: { _uid: 1 } } as any)
36
39
 
37
- expect(callback).toHaveBeenCalledTimes(1)
38
- expect((el as any)._observe).toBeTruthy()
40
+ expect(callback).toHaveBeenCalledTimes(0)
41
+ expect((el as any)._observe[1]).toBeTruthy()
39
42
 
40
- ;(el as any)._observe.observer.callback([{ isIntersecting: false }])
43
+ ;(el as any)._observe[1].observer.callback([{ isIntersecting: false }])
41
44
 
42
45
  expect(callback).toHaveBeenCalledTimes(1)
43
- expect((el as any)._observe).toBeTruthy()
46
+ expect((el as any)._observe[1]).toBeTruthy()
44
47
 
45
- ;(el as any)._observe.observer.callback([{ isIntersecting: true }])
48
+ ;(el as any)._observe[1].observer.callback([{ isIntersecting: true }])
46
49
 
47
50
  expect(callback).toHaveBeenCalledTimes(2)
48
- expect((el as any)._observe).toBeFalsy()
51
+ expect((el as any)._observe[1]).toBeFalsy()
49
52
  })
50
53
  })
@@ -1,4 +1,5 @@
1
1
  import { VNodeDirective } from 'vue/types/vnode'
2
+ import { VNode } from 'vue'
2
3
 
3
4
  type ObserveHandler = (
4
5
  entries: IntersectionObserverEntry[],
@@ -14,7 +15,7 @@ interface ObserveVNodeDirective extends Omit<VNodeDirective, 'modifiers'> {
14
15
  }
15
16
  }
16
17
 
17
- function inserted (el: HTMLElement, binding: ObserveVNodeDirective) {
18
+ function inserted (el: HTMLElement, binding: ObserveVNodeDirective, vnode: VNode) {
18
19
  if (typeof window === 'undefined' || !('IntersectionObserver' in window)) return
19
20
 
20
21
  const modifiers = binding.modifiers || {}
@@ -26,8 +27,8 @@ function inserted (el: HTMLElement, binding: ObserveVNodeDirective) {
26
27
  entries: IntersectionObserverEntry[] = [],
27
28
  observer: IntersectionObserver
28
29
  ) => {
29
- /* istanbul ignore if */
30
- if (!el._observe) return // Just in case, should never fire
30
+ const _observe = el._observe?.[vnode.context!._uid]
31
+ if (!_observe) return // Just in case, should never fire
31
32
 
32
33
  const isIntersecting = entries.some(entry => entry.isIntersecting)
33
34
 
@@ -36,31 +37,32 @@ function inserted (el: HTMLElement, binding: ObserveVNodeDirective) {
36
37
  if (
37
38
  handler && (
38
39
  !modifiers.quiet ||
39
- el._observe.init
40
+ _observe.init
40
41
  ) && (
41
42
  !modifiers.once ||
42
43
  isIntersecting ||
43
- !el._observe.init
44
+ _observe.init
44
45
  )
45
46
  ) {
46
47
  handler(entries, observer, isIntersecting)
47
48
  }
48
49
 
49
- if (isIntersecting && modifiers.once) unbind(el)
50
- else el._observe.init = true
50
+ if (isIntersecting && modifiers.once) unbind(el, binding, vnode)
51
+ else _observe.init = true
51
52
  }, options)
52
53
 
53
- el._observe = { init: false, observer }
54
+ el._observe = Object(el._observe)
55
+ el._observe![vnode.context!._uid] = { init: false, observer }
54
56
 
55
57
  observer.observe(el)
56
58
  }
57
59
 
58
- function unbind (el: HTMLElement) {
59
- /* istanbul ignore if */
60
- if (!el._observe) return
60
+ function unbind (el: HTMLElement, binding: ObserveVNodeDirective, vnode: VNode) {
61
+ const observe = el._observe?.[vnode.context!._uid]
62
+ if (!observe) return
61
63
 
62
- el._observe.observer.unobserve(el)
63
- delete el._observe
64
+ observe.observer.unobserve(el)
65
+ delete el._observe![vnode.context!._uid]
64
66
  }
65
67
 
66
68
  export const Intersect = {
@@ -29,16 +29,18 @@ describe('mutate.ts', () => {
29
29
 
30
30
  Mutate.inserted(el, {
31
31
  value: callback,
32
- } as any)
32
+ } as any, { context: { _uid: 1 } } as any)
33
33
 
34
34
  expect(el._mutate).toBeTruthy()
35
35
  expect(callback).not.toHaveBeenCalled()
36
36
 
37
37
  document.body.removeChild(el)
38
38
 
39
- Mutate.unbind(el)
39
+ Mutate.unbind(el, {
40
+ value: callback,
41
+ } as any, { context: { _uid: 1 } } as any)
40
42
 
41
- expect(el._mutate).toBeFalsy()
43
+ expect(el._mutate[1]).toBeFalsy()
42
44
  })
43
45
 
44
46
  it('should fire event on mutation', () => {
@@ -48,15 +50,17 @@ describe('mutate.ts', () => {
48
50
 
49
51
  Mutate.inserted(el, {
50
52
  value: callback,
51
- } as any)
53
+ } as any, { context: { _uid: 1 } } as any)
52
54
 
53
- el._mutate.observer.trigger([{}])
55
+ el._mutate[1].observer.trigger([{}])
54
56
 
55
57
  expect(callback).toHaveBeenCalledTimes(1)
56
58
 
57
59
  document.body.removeChild(el)
58
60
 
59
- Mutate.unbind(el)
61
+ Mutate.unbind(el, {
62
+ value: callback,
63
+ } as any, { context: { _uid: 1 } } as any)
60
64
  })
61
65
 
62
66
  it('should fire event once', () => {
@@ -69,12 +73,12 @@ describe('mutate.ts', () => {
69
73
  modifiers: {
70
74
  once: true,
71
75
  },
72
- } as any)
76
+ } as any, { context: { _uid: 1 } } as any)
73
77
 
74
- el._mutate.observer.trigger([{}])
78
+ el._mutate[1].observer.trigger([{}])
75
79
 
76
80
  expect(callback).toHaveBeenCalledTimes(1)
77
- expect(el._mutate).toBeFalsy()
81
+ expect(el._mutate[1]).toBeFalsy()
78
82
 
79
83
  document.body.removeChild(el)
80
84
  })
@@ -92,16 +96,24 @@ describe('mutate.ts', () => {
92
96
  },
93
97
  handler: callback,
94
98
  },
95
- } as any)
99
+ } as any, { context: { _uid: 1 } } as any)
96
100
 
97
- el._mutate.observer.trigger([{}])
101
+ el._mutate[1].observer.trigger([{}])
98
102
 
99
103
  expect(callback).toHaveBeenCalledTimes(1)
100
- expect(el._mutate.observer._observe).toHaveBeenLastCalledWith({ attributes: false, subtree: true })
104
+ expect(el._mutate[1].observer._observe).toHaveBeenLastCalledWith({ attributes: false, subtree: true })
101
105
 
102
106
  document.body.removeChild(el)
103
107
 
104
- Mutate.unbind(el)
108
+ Mutate.unbind(el, {
109
+ value: {
110
+ options: {
111
+ attributes: false,
112
+ subtree: true,
113
+ },
114
+ handler: callback,
115
+ },
116
+ } as any, { context: { _uid: 1 } } as any)
105
117
  })
106
118
 
107
119
  it('should work with observer modifiers', () => {
@@ -116,15 +128,22 @@ describe('mutate.ts', () => {
116
128
  child: true,
117
129
  sub: true,
118
130
  },
119
- } as any)
131
+ } as any, { context: { _uid: 1 } } as any)
120
132
 
121
- el._mutate.observer.trigger([{}])
133
+ el._mutate[1].observer.trigger([{}])
122
134
 
123
135
  expect(callback).toHaveBeenCalledTimes(1)
124
- expect(el._mutate.observer._observe).toHaveBeenLastCalledWith({ attributes: true, childList: true, subtree: true })
136
+ expect(el._mutate[1].observer._observe).toHaveBeenLastCalledWith({ attributes: true, childList: true, subtree: true })
125
137
 
126
138
  document.body.removeChild(el)
127
139
 
128
- Mutate.unbind(el)
140
+ Mutate.unbind(el, {
141
+ value: callback,
142
+ modifiers: {
143
+ attr: true,
144
+ child: true,
145
+ sub: true,
146
+ },
147
+ } as any, { context: { _uid: 1 } } as any)
129
148
  })
130
149
  })