-
-
Notifications
You must be signed in to change notification settings - Fork 7k
/
Copy pathVTextarea.ts
109 lines (94 loc) · 2.37 KB
/
VTextarea.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// Styles
import './VTextarea.sass'
// Extensions
import VTextField from '../VTextField/VTextField'
// Utilities
import mixins from '../../util/mixins'
// Types
import Vue from 'vue'
interface options extends Vue {
$refs: {
input: HTMLTextAreaElement
}
}
const baseMixins = mixins<options &
InstanceType<typeof VTextField>
>(
VTextField
)
/* @vue/component */
export default baseMixins.extend({
name: 'v-textarea',
props: {
autoGrow: Boolean,
noResize: Boolean,
rowHeight: {
type: [Number, String],
default: 24,
validator: (v: any) => !isNaN(parseFloat(v)),
},
rows: {
type: [Number, String],
default: 5,
validator: (v: any) => !isNaN(parseInt(v, 10)),
},
},
computed: {
classes (): object {
return {
'v-textarea': true,
'v-textarea--auto-grow': this.autoGrow,
'v-textarea--no-resize': this.noResizeHandle,
...VTextField.options.computed.classes.call(this),
}
},
noResizeHandle (): boolean {
return this.noResize || this.autoGrow
},
},
watch: {
lazyValue () {
this.autoGrow && this.$nextTick(this.calculateInputHeight)
},
rowHeight () {
this.autoGrow && this.$nextTick(this.calculateInputHeight)
},
},
mounted () {
setTimeout(() => {
this.autoGrow && this.calculateInputHeight()
}, 0)
},
methods: {
calculateInputHeight () {
const input = this.$refs.input
if (!input) return
input.style.height = '0'
const height = input.scrollHeight
const minHeight = parseInt(this.rows, 10) * parseFloat(this.rowHeight)
// This has to be done ASAP, waiting for Vue
// to update the DOM causes ugly layout jumping
input.style.height = Math.max(minHeight, height) + 'px'
},
genInput () {
const input = VTextField.options.methods.genInput.call(this)
input.tag = 'textarea'
delete input.data!.attrs!.type
input.data!.attrs!.rows = this.rows
return input
},
onInput (e: Event) {
VTextField.options.methods.onInput.call(this, e)
this.autoGrow && this.calculateInputHeight()
},
onKeyDown (e: KeyboardEvent) {
// Prevents closing of a
// dialog when pressing
// enter
if (this.isFocused && e.keyCode === 13) {
e.stopPropagation()
}
this.$emit('keydown', e)
},
},
})