@dimailn/vuetify 2.7.2-alpha58 → 2.7.2-alpha59

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 (71) hide show
  1. package/dist/vuetify.js +101 -60
  2. package/dist/vuetify.js.map +1 -1
  3. package/dist/vuetify.min.css +1 -1
  4. package/dist/vuetify.min.js +2 -2
  5. package/es5/components/VAutocomplete/VAutocomplete.js +1 -2
  6. package/es5/components/VAutocomplete/VAutocomplete.js.map +1 -1
  7. package/es5/components/VColorPicker/VColorPickerEdit.js +8 -3
  8. package/es5/components/VColorPicker/VColorPickerEdit.js.map +1 -1
  9. package/es5/components/VContent/VContent.js +12 -12
  10. package/es5/components/VContent/VContent.js.map +1 -1
  11. package/es5/components/VInput/VInput.js +17 -4
  12. package/es5/components/VInput/VInput.js.map +1 -1
  13. package/es5/components/VLabel/VLabel.js +16 -9
  14. package/es5/components/VLabel/VLabel.js.map +1 -1
  15. package/es5/components/VOverflowBtn/VOverflowBtn.js +8 -3
  16. package/es5/components/VOverflowBtn/VOverflowBtn.js.map +1 -1
  17. package/es5/components/VRadioGroup/VRadioGroup.js +19 -8
  18. package/es5/components/VRadioGroup/VRadioGroup.js.map +1 -1
  19. package/es5/components/VRangeSlider/VRangeSlider.js +4 -4
  20. package/es5/components/VRangeSlider/VRangeSlider.js.map +1 -1
  21. package/es5/components/VSelect/VSelect.js +1 -1
  22. package/es5/components/VSelect/VSelect.js.map +1 -1
  23. package/es5/components/VTextField/VTextField.js +5 -4
  24. package/es5/components/VTextField/VTextField.js.map +1 -1
  25. package/es5/framework.js +1 -1
  26. package/lib/components/VAutocomplete/VAutocomplete.js +1 -2
  27. package/lib/components/VAutocomplete/VAutocomplete.js.map +1 -1
  28. package/lib/components/VColorPicker/VColorPickerEdit.js +6 -3
  29. package/lib/components/VColorPicker/VColorPickerEdit.js.map +1 -1
  30. package/lib/components/VContent/VContent.js +12 -12
  31. package/lib/components/VContent/VContent.js.map +1 -1
  32. package/lib/components/VInput/VInput.js +17 -3
  33. package/lib/components/VInput/VInput.js.map +1 -1
  34. package/lib/components/VLabel/VLabel.js +11 -3
  35. package/lib/components/VLabel/VLabel.js.map +1 -1
  36. package/lib/components/VOverflowBtn/VOverflowBtn.js +8 -3
  37. package/lib/components/VOverflowBtn/VOverflowBtn.js.map +1 -1
  38. package/lib/components/VRadioGroup/VRadioGroup.js +13 -7
  39. package/lib/components/VRadioGroup/VRadioGroup.js.map +1 -1
  40. package/lib/components/VRangeSlider/VRangeSlider.js +4 -4
  41. package/lib/components/VRangeSlider/VRangeSlider.js.map +1 -1
  42. package/lib/components/VSelect/VSelect.js +1 -1
  43. package/lib/components/VSelect/VSelect.js.map +1 -1
  44. package/lib/components/VTextField/VTextField.js +3 -2
  45. package/lib/components/VTextField/VTextField.js.map +1 -1
  46. package/lib/framework.js +1 -1
  47. package/package.json +1 -1
  48. package/src/components/VAutocomplete/VAutocomplete.ts +2 -4
  49. package/src/components/VAutocomplete/__tests__/VAutocomplete.spec.ts +17 -0
  50. package/src/components/VColorPicker/VColorPickerEdit.ts +7 -3
  51. package/src/components/VColorPicker/__tests__/VColorPickerEdit.spec.ts +11 -0
  52. package/src/components/VContent/VContent.ts +9 -7
  53. package/src/components/VContent/__tests__/VContent.spec.ts +40 -0
  54. package/src/components/VInput/VInput.ts +13 -4
  55. package/src/components/VInput/__tests__/VInput.spec.ts +28 -1
  56. package/src/components/VInput/__tests__/__snapshots__/VInput.spec.ts.snap +4 -4
  57. package/src/components/VLabel/VLabel.ts +7 -3
  58. package/src/components/VLabel/__tests__/VLabel.spec.ts +10 -0
  59. package/src/components/VOverflowBtn/VOverflowBtn.ts +9 -4
  60. package/src/components/VOverflowBtn/__tests__/VOverflowBtn.spec.ts +15 -0
  61. package/src/components/VOverflowBtn/__tests__/__snapshots__/VOverflowBtn.spec.ts.snap +6 -8
  62. package/src/components/VRadioGroup/VRadioGroup.ts +14 -10
  63. package/src/components/VRadioGroup/__tests__/VRadioGroup.spec.ts +19 -0
  64. package/src/components/VRangeSlider/VRangeSlider.ts +5 -4
  65. package/src/components/VRangeSlider/__tests__/VRangeSlider.spec.ts +4 -1
  66. package/src/components/VRangeSlider/__tests__/__snapshots__/VRangeSlider.spec.ts.snap +8 -8
  67. package/src/components/VSelect/VSelect.ts +1 -1
  68. package/src/components/VSelect/__tests__/VSelect.spec.ts +1 -0
  69. package/src/components/VSlider/__tests__/__snapshots__/VSlider.spec.ts.snap +3 -3
  70. package/src/components/VTextField/VTextField.ts +2 -3
  71. package/src/components/VTextarea/__tests__/VTextarea.spec.ts +15 -0
@@ -45,6 +45,10 @@ export const modes = {
45
45
  }
46
46
  } as { [key: string]: Mode }
47
47
 
48
+ export function getValidMode (mode?: string | null): string {
49
+ return mode && Object.keys(modes).includes(mode) ? mode : 'rgba'
50
+ }
51
+
48
52
  export default defineComponent({
49
53
  name: 'v-color-picker-edit',
50
54
 
@@ -67,19 +71,19 @@ export default defineComponent({
67
71
 
68
72
  data () {
69
73
  return {
70
- internalMode: this.mode
74
+ internalMode: getValidMode(this.mode)
71
75
  }
72
76
  },
73
77
 
74
78
  computed: {
75
79
  currentMode (): Mode {
76
- return modes[this.internalMode]
80
+ return modes[this.internalMode] || modes.rgba
77
81
  }
78
82
  },
79
83
 
80
84
  watch: {
81
85
  mode (mode: string) {
82
- this.internalMode = mode
86
+ this.internalMode = getValidMode(mode)
83
87
  }
84
88
  },
85
89
 
@@ -132,6 +132,17 @@ describe('VColorPickerEdit.ts', () => {
132
132
  expect(wrapper.html()).toMatchSnapshot()
133
133
  })
134
134
 
135
+ it('should fallback to rgba mode when mode is null', () => {
136
+ const wrapper = mountFunction({
137
+ props: {
138
+ color: fromRGBA({ r: 0, g: 0, b: 0, a: 0 }),
139
+ mode: null as any
140
+ }
141
+ })
142
+
143
+ expect(wrapper.findAll('input')).toHaveLength(4)
144
+ })
145
+
135
146
  it('should hide mode switch button', () => {
136
147
  const wrapper = mountFunction({
137
148
  props: {
@@ -21,16 +21,18 @@ export default defineComponent({
21
21
  // Add the legacy class names
22
22
  const node = VMain.render.call(this, h)
23
23
 
24
- const existingClasses = node.data?.class || ''
24
+ const existingClasses = node.props?.class || ''
25
25
  const contentClasses = normalizeClasses(`${existingClasses} v-content`)
26
- node.data = { ...node.data, class: contentClasses }
27
26
 
28
- if (node.children && node.children[0] && node.children[0].data) {
29
- const childExistingClasses = node.children[0].data.class || ''
27
+ const children = (node.children as VNode[] | undefined)?.map((child, i) => {
28
+ if (i !== 0) return child
29
+
30
+ const childExistingClasses = child.props?.class || ''
30
31
  const wrapClasses = normalizeClasses(`${childExistingClasses} v-content__wrap`)
31
- node.children[0].data = { ...node.children[0].data, class: wrapClasses }
32
- }
33
32
 
34
- return h(getTagValue(this.tag), node.data, node.children)
33
+ return h('div', { ...child.props, class: wrapClasses }, child.children as any)
34
+ })
35
+
36
+ return h(getTagValue(this.tag), { ...node.props, class: contentClasses }, children ?? node.children)
35
37
  }
36
38
  })
@@ -0,0 +1,40 @@
1
+ // Components
2
+ import VContent from '../VContent'
3
+
4
+ // Utilities
5
+ import { mount } from '@vue/test-utils'
6
+
7
+ describe('VContent.ts', () => {
8
+ let mountFunction: (options?: any) => any
9
+
10
+ beforeEach(() => {
11
+ mountFunction = (options = {}) => {
12
+ return mount(VContent, {
13
+ ...options,
14
+ global: {
15
+ mocks: {
16
+ $vuetify: {
17
+ application: {
18
+ bar: 24,
19
+ top: 64,
20
+ left: 256,
21
+ right: 256,
22
+ footer: 48,
23
+ insetFooter: 32,
24
+ bottom: 56
25
+ }
26
+ }
27
+ }
28
+ }
29
+ })
30
+ }
31
+ })
32
+
33
+ it('should apply legacy v-content classes', () => {
34
+ const wrapper = mountFunction()
35
+
36
+ expect('[Vuetify] [UPGRADE] \'v-content\' is deprecated, use \'v-main\' instead.').toHaveBeenTipped()
37
+ expect(wrapper.classes()).toContain('v-content')
38
+ expect(wrapper.find('.v-content__wrap').exists()).toBe(true)
39
+ })
40
+ })
@@ -58,14 +58,15 @@ export default baseMixins.extend({
58
58
  loading: Boolean,
59
59
  persistentHint: Boolean,
60
60
  prependIcon: String,
61
- modelValue: null as any as PropType<any>
61
+ modelValue: null as any as PropType<any>,
62
+ value: null as any as PropType<any>
62
63
  },
63
64
 
64
65
  emits: ['click', 'mousedown', 'mouseup', 'touchstart', 'touchend', 'update:error', 'change', 'update:modelValue'],
65
66
 
66
67
  data () {
67
68
  return {
68
- lazyValue: this.modelValue,
69
+ lazyValue: this.modelValue ?? this.value,
69
70
  hasMouseDown: false
70
71
  }
71
72
  },
@@ -145,12 +146,20 @@ export default baseMixins.extend({
145
146
  watch: {
146
147
  modelValue (val) {
147
148
  this.lazyValue = val
149
+ },
150
+ value (val) {
151
+ if (this.modelValue == null) {
152
+ this.lazyValue = val
153
+ }
148
154
  }
149
155
  },
150
156
 
151
157
  created () {
158
+ if (this.modelValue == null && this.value == null && this.$attrs.hasOwnProperty('value')) {
159
+ this.lazyValue = this.$attrs.value
160
+ }
161
+
152
162
  const breakingProps = [
153
- ['value', 'modelValue'],
154
163
  ['onInput', 'onUpdate:modelValue']
155
164
  ]
156
165
 
@@ -339,7 +348,7 @@ export default baseMixins.extend({
339
348
  },
340
349
 
341
350
  render (): VNode {
342
- const { class: additionalClasses, ...restAttrs } = this.$attrs as Record<string, any>
351
+ const { class: additionalClasses, value: _value, ...restAttrs } = this.$attrs as Record<string, any>
343
352
 
344
353
  return h('div', this.setTextColor(this.validationState, {
345
354
  class: { 'v-input': true, ...this.classes, ...normalizeClasses(additionalClasses) },
@@ -68,6 +68,32 @@ describe('VInput.ts', () => {
68
68
  expect(wrapper.vm.lazyValue).toBe('bar')
69
69
  })
70
70
 
71
+ it('should initialize lazyValue from legacy value prop', async () => {
72
+ const wrapper = mountFunction({
73
+ props: {
74
+ value: 'foo'
75
+ }
76
+ })
77
+
78
+ expect(wrapper.vm.lazyValue).toBe('foo')
79
+ expect(wrapper.element.classList).toContain('v-input--is-dirty')
80
+
81
+ await wrapper.setProps({ value: 'bar' })
82
+
83
+ expect(wrapper.vm.lazyValue).toBe('bar')
84
+ })
85
+
86
+ it('should prefer modelValue over legacy value prop', async () => {
87
+ const wrapper = mountFunction({
88
+ props: {
89
+ modelValue: 'model',
90
+ value: 'legacy'
91
+ }
92
+ })
93
+
94
+ expect(wrapper.vm.lazyValue).toBe('model')
95
+ })
96
+
71
97
  it('should generate append and prepend slots', () => {
72
98
  const el = (slot: string) => h('div', slot)
73
99
  const wrapper = mountFunction({
@@ -180,7 +206,7 @@ describe('VInput.ts', () => {
180
206
 
181
207
  it('should render a label', () => {
182
208
  const wrapper = mountFunction({
183
- props: { label: 'foo' }
209
+ props: { label: 'foo', id: 'test' }
184
210
  })
185
211
 
186
212
  expect(wrapper.vm.hasLabel).toBe(true)
@@ -190,6 +216,7 @@ describe('VInput.ts', () => {
190
216
  it('should apply theme to label, counter, messages and icons', () => {
191
217
  const wrapper = mountFunction({
192
218
  props: {
219
+ id: 'test',
193
220
  label: 'foo',
194
221
  hint: 'bar',
195
222
  persistentHint: true,
@@ -32,9 +32,9 @@ exports[`VInput.ts should apply theme to label, counter, messages and icons 1`]
32
32
  <div class="v-input__control">
33
33
  <div class="v-input__slot">
34
34
  <label class="v-label theme--light"
35
- for="input-48"
35
+ for="test"
36
36
  aria-hidden="false"
37
- style="left: 0px; position: relative;"
37
+ style="left: 0px;"
38
38
  >
39
39
  foo
40
40
  </label>
@@ -193,9 +193,9 @@ exports[`VInput.ts should render a label 1`] = `
193
193
  <div class="v-input__control">
194
194
  <div class="v-input__slot">
195
195
  <label class="v-label theme--light"
196
- for="input-43"
196
+ for="test"
197
197
  aria-hidden="false"
198
- style="left: 0px; position: relative;"
198
+ style="left: 0px;"
199
199
  >
200
200
  foo
201
201
  </label>
@@ -36,6 +36,10 @@ export default mixins(Themeable).extend({
36
36
  type: [Number, String],
37
37
  default: 'auto'
38
38
  },
39
+ tag: {
40
+ type: String,
41
+ default: 'label'
42
+ },
39
43
  value: Boolean
40
44
  },
41
45
 
@@ -50,16 +54,16 @@ export default mixins(Themeable).extend({
50
54
  'v-label--is-disabled': this.disabled,
51
55
  ...functionalThemeClasses(this)
52
56
  },
53
- for: props.for,
57
+ ...(props.tag === 'label' ? { for: props.for } : {}),
54
58
  'aria-hidden': !props.for,
55
59
  style: {
56
60
  left: convertToUnit(props.left),
57
61
  right: convertToUnit(props.right),
58
- position: props.absolute ? 'absolute' : 'relative'
62
+ ...(props.absolute ? { position: 'absolute' } : {})
59
63
  },
60
64
  ref: 'label'
61
65
  }, data)
62
66
 
63
- return h('label', Colorable.methods.setTextColor(props.focused && props.color, newData), this.$slots.default?.())
67
+ return h(props.tag, Colorable.methods.setTextColor(props.focused && props.color, newData), this.$slots.default?.())
64
68
  }
65
69
  })
@@ -40,6 +40,16 @@ describe('VLabel', () => {
40
40
  expect(wrapper.element.style.position).toBe('absolute')
41
41
  })
42
42
 
43
+ it('should not set position when absolute is false', () => {
44
+ const wrapper = mountFunction({
45
+ props: {
46
+ absolute: false
47
+ }
48
+ })
49
+
50
+ expect(wrapper.element.style.position).toBe('')
51
+ })
52
+
43
53
  it('should render default slot content', () => {
44
54
  const wrapper = mountFunction({
45
55
  slots: {
@@ -82,10 +82,15 @@ export default defineComponent({
82
82
 
83
83
  if (!label) return label
84
84
 
85
- label.data = label.data || {}
86
-
87
- // Reset previously set styles from parent
88
- label.data.style = {}
85
+ label.props ||= {}
86
+
87
+ // Label must stay in document flow to size the control
88
+ // (.v-select__selections has width: 0).
89
+ // Do not use position:relative — it activates CSS `top` and breaks alignment.
90
+ label.props.absolute = false
91
+ label.props.left = ''
92
+ label.props.right = ''
93
+ label.props.style = {}
89
94
 
90
95
  return label
91
96
  },
@@ -109,6 +109,21 @@ describe('VOverflowBtn.js', () => {
109
109
  expect(callback).toHaveBeenCalled()
110
110
  })
111
111
 
112
+ it('should keep label in document flow without relative positioning', () => {
113
+ const wrapper = mountFunction({
114
+ props: {
115
+ items: ['foo'],
116
+ label: 'Select font'
117
+ }
118
+ })
119
+
120
+ const label = wrapper.find('label')
121
+
122
+ expect(label.exists()).toBe(true)
123
+ expect(label.element.style.position).toBe('')
124
+ expect(label.element.style.left).toBe('')
125
+ })
126
+
112
127
  it('should show label with persistentPlaceholder property set to true', async () => {
113
128
  const wrapper = mountFunction({
114
129
  props: {
@@ -6,19 +6,18 @@ exports[`VOverflowBtn.js should show label with persistentPlaceholder property s
6
6
  <div role="combobox"
7
7
  aria-haspopup="listbox"
8
8
  aria-expanded="false"
9
- aria-owns="list-15"
9
+ aria-owns="list-22"
10
10
  class="v-input__slot"
11
11
  >
12
12
  <div class="v-select__slot">
13
13
  <label class="v-label theme--light"
14
- for="input-15"
14
+ for="input-22"
15
15
  aria-hidden="false"
16
- style="left: 0px; position: absolute;"
17
16
  >
18
17
  Some label
19
18
  </label>
20
19
  <div class="v-select__selections">
21
- <input id="input-15"
20
+ <input id="input-22"
22
21
  readonly
23
22
  type="text"
24
23
  value
@@ -53,19 +52,18 @@ exports[`VOverflowBtn.js should show label with persistentPlaceholder property s
53
52
  <div role="combobox"
54
53
  aria-haspopup="listbox"
55
54
  aria-expanded="true"
56
- aria-owns="list-15"
55
+ aria-owns="list-22"
57
56
  class="v-input__slot"
58
57
  >
59
58
  <div class="v-select__slot">
60
59
  <label class="v-label theme--light"
61
- for="input-15"
60
+ for="input-22"
62
61
  aria-hidden="false"
63
- style="left: 0px; position: absolute;"
64
62
  >
65
63
  Some label
66
64
  </label>
67
65
  <div class="v-select__selections">
68
- <input id="input-15"
66
+ <input id="input-22"
69
67
  readonly
70
68
  type="text"
71
69
  value
@@ -4,12 +4,14 @@ import './VRadioGroup.sass'
4
4
 
5
5
  // Extensions
6
6
  import VInput from '../VInput'
7
+ import VLabel from '../VLabel'
7
8
  import { BaseItemGroup } from '../VItemGroup/VItemGroup'
8
9
 
9
10
  // Utilities
10
11
  import { mergeProps, h } from 'vue'
11
12
  import mixins from '../../util/mixins'
12
13
  import { breaking } from '../../util/console'
14
+ import { getSlot } from '../../util/helpers'
13
15
 
14
16
  // Types
15
17
  import type { PropType } from 'vue'
@@ -87,16 +89,18 @@ export default baseMixins.extend({
87
89
  return render
88
90
  },
89
91
  genLabel () {
90
- const label = VInput.methods.genLabel.call(this)
91
-
92
- if (!label) return null
93
-
94
- label.data!.attrs!.id = this.computedId
95
- // WAI considers this an orphaned label
96
- delete label.data!.attrs!.for
97
- label.tag = 'legend'
98
-
99
- return label
92
+ if (!this.hasLabel) return null
93
+
94
+ return h(VLabel, {
95
+ id: this.computedId,
96
+ color: this.validationState,
97
+ dark: this.dark,
98
+ disabled: this.isDisabled,
99
+ focused: this.hasState,
100
+ for: this.computedId,
101
+ light: this.light,
102
+ tag: 'legend'
103
+ }, () => getSlot(this, 'label') || this.label)
100
104
  },
101
105
  onClick: BaseItemGroup.methods.onClick
102
106
  },
@@ -37,4 +37,23 @@ describe('VRadioGroup.ts', () => {
37
37
 
38
38
  expect(wrapper.html()).toMatchSnapshot()
39
39
  })
40
+
41
+ it('should render group label as legend without for attribute', () => {
42
+ const wrapper = mountFunction({
43
+ props: {
44
+ label: 'Radio group label'
45
+ },
46
+ slots: {
47
+ default: [VRadio]
48
+ }
49
+ })
50
+
51
+ const legend = wrapper.find('legend')
52
+
53
+ expect(legend.exists()).toBe(true)
54
+ expect(legend.text()).toBe('Radio group label')
55
+ expect(legend.attributes('id')).toBeTruthy()
56
+ expect(legend.attributes('for')).toBeUndefined()
57
+ expect(legend.attributes('aria-hidden')).toBe('false')
58
+ })
40
59
  })
@@ -112,10 +112,11 @@ export default defineComponent({
112
112
  return createRange(2).map(i => {
113
113
  const input = VSlider.methods.genInput.call(this)
114
114
 
115
- input.data = input.data || {}
116
- input.data.attrs = input.data.attrs || {}
117
- input.data.attrs.value = this.internalValue[i]
118
- input.data.attrs.id = `input-${i ? 'max' : 'min'}-${this.$.uid}`
115
+ input.props = {
116
+ ...input.props,
117
+ value: this.internalValue[i],
118
+ id: `input-${i ? 'max' : 'min'}-${this.$.uid}`
119
+ }
119
120
 
120
121
  return input
121
122
  })
@@ -191,7 +191,10 @@ describe('VRangeSlider', () => {
191
191
  const wrapper = mountFunction()
192
192
  const [min, max] = wrapper.vm.genInput()
193
193
 
194
- expect(min.data.attrs.id).not.toEqual(max.data.attrs.id)
194
+ expect(min.props!.id).not.toEqual(max.props!.id)
195
+
196
+ const inputs = wrapper.findAll('input')
197
+ expect(inputs[0].attributes('id')).not.toEqual(inputs[1].attributes('id'))
195
198
  })
196
199
 
197
200
  // https://github.com/vuetifyjs/vuetify/issues/12733
@@ -5,17 +5,17 @@ exports[`VRangeSlider should render a vertical slider 1`] = `
5
5
  <div class="v-input__control">
6
6
  <div class="v-input__slot">
7
7
  <div class="v-slider v-slider--vertical theme--light">
8
- <input id="input-25"
8
+ <input id="input-min-25"
9
9
  disabled
10
10
  readonly
11
11
  tabindex="-1"
12
- value="0,0"
12
+ value="0"
13
13
  >
14
- <input id="input-25"
14
+ <input id="input-max-25"
15
15
  disabled
16
16
  readonly
17
17
  tabindex="-1"
18
- value="0,0"
18
+ value="0"
19
19
  >
20
20
  <div class="v-slider__track-container">
21
21
  <div class="v-slider__track-background primary lighten-3">
@@ -66,17 +66,17 @@ exports[`VRangeSlider should render disabled slider 1`] = `
66
66
  <div class="v-input__control">
67
67
  <div class="v-input__slot">
68
68
  <div class="v-slider v-slider--horizontal v-slider--disabled theme--light">
69
- <input id="input-29"
69
+ <input id="input-min-29"
70
70
  disabled
71
71
  readonly
72
72
  tabindex="-1"
73
- value="0,0"
73
+ value="0"
74
74
  >
75
- <input id="input-29"
75
+ <input id="input-max-29"
76
76
  disabled
77
77
  readonly
78
78
  tabindex="-1"
79
- value="0,0"
79
+ value="0"
80
80
  >
81
81
  <div class="v-slider__track-container">
82
82
  <div class="v-slider__track-background">
@@ -505,7 +505,7 @@ export default baseMixins.extend({
505
505
  type: 'text',
506
506
  'aria-readonly': String(this.isReadonly),
507
507
  'aria-activedescendant': getObjectValueByPath(this.$refs.menu, 'activeTile.id'),
508
- autocomplete: getObjectValueByPath(input.data!, 'attrs.autocomplete', 'off'),
508
+ autocomplete: getObjectValueByPath(input.props, 'autocomplete', 'off'),
509
509
  placeholder: (!this.isDirty && (this.persistentPlaceholder || this.isFocused || !this.hasLabel)) ? this.placeholder : undefined,
510
510
  onKeypress: this.onKeyPress
511
511
  })
@@ -490,6 +490,7 @@ describe('VSelect.ts', () => {
490
490
  })
491
491
 
492
492
  expect(wrapper.vm.$attrs.autocomplete).toBe('on')
493
+ expect(wrapper.find('input').attributes('autocomplete')).toBe('on')
493
494
  })
494
495
 
495
496
  // Based on issue: https://github.com/vuetifyjs/vuetify/issues/12769
@@ -317,7 +317,7 @@ exports[`VSlider.ts should display label and have different aria-label 1`] = `
317
317
  <label class="v-label theme--light"
318
318
  for="input-98"
319
319
  aria-hidden="false"
320
- style="left: 0px; position: relative;"
320
+ style="left: 0px;"
321
321
  >
322
322
  foo
323
323
  </label>
@@ -704,7 +704,7 @@ exports[`VSlider.ts should reverse label location when inverse 1`] = `
704
704
  <label class="v-label theme--light"
705
705
  for="input-89"
706
706
  aria-hidden="false"
707
- style="left: 0px; position: relative;"
707
+ style="left: 0px;"
708
708
  >
709
709
  foo
710
710
  </label>
@@ -788,7 +788,7 @@ exports[`VSlider.ts should reverse label location when inverse 2`] = `
788
788
  <label class="v-label theme--light"
789
789
  for="input-89"
790
790
  aria-hidden="false"
791
- style="left: 0px; position: relative;"
791
+ style="left: 0px;"
792
792
  >
793
793
  foo
794
794
  </label>
@@ -216,7 +216,6 @@ export default baseMixins.extend({
216
216
 
217
217
  created () {
218
218
  const breakingProps = [
219
- ['value', 'modelValue'],
220
219
  ['onInput', 'onUpdate:modelValue']
221
220
  ]
222
221
 
@@ -391,12 +390,12 @@ export default baseMixins.extend({
391
390
  genInput () {
392
391
  const listeners = Object.assign({}, this.listeners$)
393
392
  delete listeners.change // Change should not be bound externally
394
- const { title, onChange: _onChange, class: _class, style: _style, ...inputAttrs } = this.attrs$ as Record<string, any>
393
+ const { title, onChange: _onChange, class: _class, style: _style, value: _value, ...inputAttrs } = this.attrs$ as Record<string, any>
395
394
 
396
395
  const node = h('input', {
397
396
  style: {},
398
- value: (this.type === 'number' && Object.is(this.lazyValue, -0)) ? '-0' : this.lazyValue,
399
397
  ...inputAttrs,
398
+ value: (this.type === 'number' && Object.is(this.lazyValue, -0)) ? '-0' : this.lazyValue,
400
399
  autofocus: this.autofocus,
401
400
  disabled: this.isDisabled,
402
401
  id: this.computedId,
@@ -272,4 +272,19 @@ describe('VTextarea.ts', () => {
272
272
  const textarea = wrapper.find('textarea')
273
273
  expect(textarea.attributes('rows')).toBe('5')
274
274
  })
275
+
276
+ it('should activate label when using legacy value prop with auto-grow', () => {
277
+ const wrapper = mountFunction({
278
+ props: {
279
+ autoGrow: true,
280
+ filled: true,
281
+ label: 'Label',
282
+ value: 'The Woodman set to work at once, and so sharp was his axe that the tree was soon chopped nearly through.'
283
+ }
284
+ })
285
+
286
+ expect(wrapper.element.classList).toContain('v-input--is-label-active')
287
+ expect(wrapper.element.classList).toContain('v-input--is-dirty')
288
+ expect(wrapper.find('.v-label').element.classList).toContain('v-label--active')
289
+ })
275
290
  })