vuetify
Version:
Vue Material Component Framework
110 lines (94 loc) • 2.43 kB
text/typescript
// 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)
},
},
})