@dimailn/vuetify 2.7.2-alpha53 → 2.7.2-alpha55

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.
@@ -0,0 +1,118 @@
1
+ // Components
2
+ import VSelect from '../VSelect'
3
+
4
+ // Utilities
5
+ import {
6
+ mount,
7
+ VueWrapper,
8
+ enableAutoUnmount
9
+ } from '@vue/test-utils'
10
+ import { h } from 'vue'
11
+
12
+ const statusItems = [{ text: 'Новый', value: 'new' }]
13
+
14
+ const baseProps = {
15
+ items: statusItems,
16
+ modelValue: 'new',
17
+ placeholder: 'Выберите статус',
18
+ label: ''
19
+ }
20
+
21
+ describe('VSelect placeholder при value', () => {
22
+ type Instance = InstanceType<typeof VSelect>
23
+ let mountFunction: (options?: object) => VueWrapper<Instance>
24
+ let el: HTMLDivElement
25
+
26
+ beforeEach(() => {
27
+ mountFunction = (options = {}) => {
28
+ el = document.createElement('div')
29
+ el.setAttribute('data-app', 'true')
30
+ document.body.appendChild(el)
31
+
32
+ return mount(VSelect, {
33
+ global: {
34
+ mocks: {
35
+ $vuetify: {
36
+ lang: {
37
+ t: (val: string) => val
38
+ },
39
+ theme: {
40
+ dark: false
41
+ },
42
+ icons: {
43
+ component: 'mdi'
44
+ }
45
+ }
46
+ }
47
+ },
48
+ attachTo: el,
49
+ ...options
50
+ })
51
+ }
52
+ })
53
+
54
+ afterEach(() => {
55
+ if (el?.parentNode) {
56
+ document.body.removeChild(el)
57
+ }
58
+ })
59
+
60
+ enableAutoUnmount(afterEach)
61
+
62
+ function textInput (wrapper: VueWrapper<Instance>) {
63
+ return wrapper.find('input[type="text"]')
64
+ }
65
+
66
+ it('при value: isDirty и текст выбора корректны', () => {
67
+ const wrapper = mountFunction({ props: baseProps })
68
+
69
+ expect(wrapper.vm.isDirty).toBe(true)
70
+ expect(wrapper.find('.v-select__selection--comma').text()).toBe('Новый')
71
+ })
72
+
73
+ it('при value: на text-input нет атрибута placeholder', () => {
74
+ const wrapper = mountFunction({ props: baseProps })
75
+ const input = textInput(wrapper)
76
+
77
+ expect(input.exists()).toBe(true)
78
+ expect(input.attributes('placeholder')).toBeUndefined()
79
+ })
80
+
81
+ it('при пустом value: placeholder на text-input есть', () => {
82
+ const wrapper = mountFunction({
83
+ props: {
84
+ ...baseProps,
85
+ modelValue: null
86
+ }
87
+ })
88
+ const input = textInput(wrapper)
89
+
90
+ expect(wrapper.vm.isDirty).toBe(false)
91
+ expect(input.attributes('placeholder')).toBe('Выберите статус')
92
+ })
93
+
94
+ it('со слотом #selection при value: placeholder на input отсутствует', () => {
95
+ const wrapper = mountFunction({
96
+ props: baseProps,
97
+ slots: {
98
+ selection: ({ item }: { item: { text: string } }) => h('span', item.text)
99
+ }
100
+ })
101
+ const input = textInput(wrapper)
102
+
103
+ expect(wrapper.text()).toContain('Новый')
104
+ expect(input.attributes('placeholder')).toBeUndefined()
105
+ })
106
+
107
+ it('при persistentPlaceholder и value: placeholder на input отсутствует', () => {
108
+ const wrapper = mountFunction({
109
+ props: {
110
+ ...baseProps,
111
+ persistentPlaceholder: true
112
+ }
113
+ })
114
+ const input = textInput(wrapper)
115
+
116
+ expect(input.attributes('placeholder')).toBeUndefined()
117
+ })
118
+ })
@@ -80,11 +80,9 @@ describe('VTab.ts', () => {
80
80
  // explicitly mock class added
81
81
  // by vue router
82
82
  if (wrapper.vm.$refs.link) {
83
- (wrapper.vm.$refs.link as any)._vnode = {
84
- data: {
85
- class: { 'bar v-tab--active': true }
86
- }
87
- }
83
+ const linkRef = wrapper.vm.$refs.link as any
84
+ const linkEl = linkRef.$el || linkRef
85
+ linkEl.classList.add('bar', 'v-tab--active')
88
86
  }
89
87
  (wrapper.vm as any).$route.path = '/foo'
90
88
 
@@ -1,5 +1,5 @@
1
1
  import type { PropType, VNode } from 'vue'
2
- import { h } from 'vue'
2
+ import { h, markRaw } from 'vue'
3
3
  import type { VNodeChildrenArrayContents } from '../../types/vue-internal'
4
4
  // Styles
5
5
  import './VTreeview.sass'
@@ -320,7 +320,7 @@ export default mixins(
320
320
  register (node: VTreeviewNodeInstance) {
321
321
  const key = getObjectValueByPath(node.item, this.itemKey)
322
322
 
323
- this.nodes[key].vnode = node
323
+ this.nodes[key].vnode = markRaw(node)
324
324
 
325
325
  this.updateVnodeState(key)
326
326
  },
@@ -168,11 +168,8 @@ describe('routable.ts', () => {
168
168
 
169
169
  expect(toggle).not.toHaveBeenCalled()
170
170
 
171
- ;(wrapper.vm.$refs.link as any)._vnode = {
172
- data: {
173
- class: { 'bar v-tab--active': true }
174
- }
175
- }
171
+ const linkEl = wrapper.vm.$refs.link as HTMLElement
172
+ linkEl.classList.add('bar', 'v-tab--active')
176
173
 
177
174
  wrapper.vm.onRouteChange()
178
175
  await nextTick()
@@ -6,7 +6,6 @@ import { defineComponent, resolveComponent } from 'vue'
6
6
  import Ripple, { RippleOptions } from '../../directives/ripple'
7
7
 
8
8
  // Utilities
9
- import { getObjectValueByPath } from '../../util/helpers'
10
9
 
11
10
  export default defineComponent({
12
11
  name: 'routable',
@@ -148,11 +147,13 @@ export default defineComponent({
148
147
  const activeClass = `${this.activeClass || ''} ${this.proxyClass || ''}`.trim()
149
148
  const exactActiveClass = `${this.exactActiveClass || ''} ${this.proxyClass || ''}`.trim() || activeClass
150
149
 
151
- const path = '_vnode.data.class.' + (this.exact ? exactActiveClass : activeClass)
150
+ const activeClasses = (this.exact ? exactActiveClass : activeClass).split(' ')
152
151
 
153
152
  this.$nextTick(() => {
154
153
  /* istanbul ignore else */
155
- const isLinkActive = Boolean(getObjectValueByPath(this.$refs.link, path))
154
+ const el = (this.$refs.link as any).$el || this.$refs.link
155
+ const isLinkActive = activeClasses.every(c => el?.classList?.contains(c))
156
+
156
157
  if (isLinkActive !== this.isActive) {
157
158
  this.toggle()
158
159
  }