bootstrap-vue
Version:
BootstrapVue provides one of the most comprehensive implementations of Bootstrap 4 components and grid system for Vue.js and with extensive and automated WAI-ARIA accessibility markup.
145 lines (143 loc) • 3.92 kB
JavaScript
import idMixin from '../../mixins/id';
import formMixin from '../../mixins/form';
import formSizeMixin from '../../mixins/form-size';
import formStateMixin from '../../mixins/form-state';
export default {
mixins: [idMixin, formMixin, formSizeMixin, formStateMixin],
render: function render(h) {
var t = this;
return h('textarea', {
ref: 'input',
class: t.inputClass,
style: t.inputStyle,
directives: [{
name: 'model',
rawName: 'v-model',
value: t.localValue,
expression: 'localValue'
}],
domProps: { value: t.value },
attrs: {
id: t.safeId(),
name: t.name,
disabled: t.disabled,
placeholder: t.placeholder,
required: t.required,
autocomplete: t.autocomplete || null,
readonly: t.readonly || t.plaintext,
rows: t.rowsCount,
wrap: t.wrap || null,
'aria-required': t.required ? 'true' : null,
'aria-invalid': t.computedAriaInvalid
},
on: {
input: function input(evt) {
t.localValue = evt.target.value;
}
}
});
},
data: function data() {
return {
localValue: this.value
};
},
props: {
value: {
type: String,
default: ''
},
ariaInvalid: {
type: [Boolean, String],
default: false
},
readonly: {
type: Boolean,
default: false
},
plaintext: {
type: Boolean,
default: false
},
autocomplete: {
type: String,
default: null
},
placeholder: {
type: String,
default: null
},
rows: {
type: [Number, String],
default: null
},
maxRows: {
type: [Number, String],
default: null
},
wrap: {
// 'soft', 'hard' or 'off'. Browser default is 'soft'
type: String,
default: 'soft'
},
noResize: {
type: Boolean,
default: false
}
},
computed: {
rowsCount: function rowsCount() {
// A better option could be based on https://codepen.io/vsync/pen/frudD
// As linebreaks aren't added until the input is submitted
var rows = parseInt(this.rows, 10) || 1;
var maxRows = parseInt(this.maxRows, 10) || 0;
var lines = (this.localValue || '').toString().split('\n').length;
return maxRows ? Math.min(maxRows, Math.max(rows, lines)) : Math.max(rows, lines);
},
inputClass: function inputClass() {
return [this.plaintext ? 'form-control-plaintext' : 'form-control', this.sizeFormClass, this.stateClass];
},
inputStyle: function inputStyle() {
// We set width 100% in plaintext mode to get around a shortcoming in bootstrap CSS
// setting noResize to true will disable the ability for the user to resize the textarea
return {
width: this.plaintext ? '100%' : null,
resize: this.noResize ? 'none' : null
};
},
computedAriaInvalid: function computedAriaInvalid() {
if (!this.ariaInvalid || this.ariaInvalid === 'false') {
// this.ariaInvalid is null or false or 'false'
return this.computedState === false ? 'true' : null;
}
if (this.ariaInvalid === true) {
// User wants explicit aria-invalid=true
return 'true';
}
// Most likely a string value (which could be the string 'true')
return this.ariaInvalid;
}
},
watch: {
value: function value(newVal, oldVal) {
// Update our localValue
if (newVal !== oldVal) {
this.localValue = newVal;
}
},
localValue: function localValue(newVal, oldVal) {
// update Parent value
if (newVal !== oldVal) {
this.$emit('input', newVal);
}
}
},
methods: {
focus: function focus() {
// For external handler that may want a focus method
if (!this.disabled) {
this.$el.focus();
}
}
}
};