UNPKG

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.

164 lines (160 loc) 3.59 kB
import idMixin from '../../mixins/id' import formMixin from '../../mixins/form' import formSizeMixin from '../../mixins/form-size' import formStateMixin from '../../mixins/form-state' import { arrayIncludes } from '../../utils/array' // Import styles import './form-input.css' // Valid supported input types const TYPES = [ 'text', 'password', 'email', 'number', 'url', 'tel', 'search', 'range', 'color', `date`, `time`, `datetime`, `datetime-local`, `month`, `week` ] export default { mixins: [idMixin, formMixin, formSizeMixin, formStateMixin], render (h) { const t = this return h('input', { ref: 'input', class: t.inputClass, domProps: { value: t.localValue }, attrs: { id: t.safeId(), name: t.name, type: t.localType, disabled: t.disabled, required: t.required, readonly: t.readonly || t.plaintext, placeholder: t.placeholder, autocomplete: t.autocomplete || null, 'aria-required': t.required ? 'true' : null, 'aria-invalid': t.computedAriaInvalid }, on: { input: t.onInput, change: t.onChange } }) }, data () { return { localValue: this.value } }, props: { value: { default: null }, type: { type: String, default: 'text', validator: type => arrayIncludes(TYPES, type) }, 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 }, formatter: { type: Function }, lazyFormatter: { type: Boolean, default: false } }, computed: { localType () { // We only allow certain types return arrayIncludes(TYPES, this.type) ? this.type : 'text' }, inputClass () { return [ this.plaintext ? 'form-control-plaintext' : 'form-control', this.sizeFormClass, this.stateClass ] }, 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 'true') return this.ariaInvalid } }, watch: { value (newVal, oldVal) { if (newVal !== oldVal) { this.localValue = newVal } }, localValue (newVal, oldVal) { if (newVal !== oldVal) { this.$emit('input', newVal) } } }, methods: { format (value, e) { if (this.formatter) { const formattedValue = this.formatter(value, e) if (formattedValue !== value) { return formattedValue } } return value }, onInput (evt) { const value = evt.target.value if (this.lazyFormatter) { // Update the model with the current unformated value this.localValue = value } else { this.localValue = this.format(value, evt) } }, onChange (evt) { this.localValue = this.format(evt.target.value, evt) this.$emit('change', this.localValue) }, focus () { if (!this.disabled) { this.$el.focus() } } } }