181 lines
3.6 KiB
JavaScript

import dotProp from 'dot-prop'
import Schema from 'async-validator'
// Temporary Mixins from external styleguide
/**
* @mixin
*/
export default {
inject: {
$parentForm: {
default: null
}
},
provide() {
return {
$parentInput: this
}
},
props: {
/**
* The value of the input. Can be passed via v-model.
*/
value: {
type: [String, Object, Number, Array],
default: null
},
/**
* The model name when used within a form component. Uses dot notation.
*/
model: {
type: String,
default: null
},
/**
* Name to use on the input for accessibility
*/
name: {
type: String,
default: null
},
/**
* The label of the input.
*/
label: {
type: String,
default: null
},
/**
* The id of the input.
*/
id: {
type: String,
default: null
},
/**
* Whether the input is disabled or not.
*/
disabled: {
type: Boolean,
default: false
},
/**
* Whether the input should be read-only
*/
readonly: {
type: Boolean,
default: false
},
/**
* The async-validator schema used for the input.
* @default null
*/
schema: {
type: Object,
default: () => null
},
/**
* The input's size.
* @options small|base|large
*/
size: {
type: String,
default: 'base',
validator: value => {
return value.match(/(small|base|large)/)
}
},
tabindex: {
type: Number,
default: 0
}
},
data() {
return {
innerValue: null,
error: null,
focus: false
}
},
computed: {
stateClasses() {
return [
this.size && `ds-input-size-${this.size}`,
this.disabled && 'ds-input-is-disabled',
this.readonly && 'ds-input-is-readonly',
this.error && 'ds-input-has-error',
this.focus && 'ds-input-has-focus'
]
}
},
watch: {
value: {
handler(value) {
this.innerValue = value
},
deep: true,
immediate: true
}
},
created() {
if (this.$parentForm) {
this.$parentForm.subscribe(this.handleFormUpdate)
}
},
beforeDestroy() {
if (this.$parentForm) {
this.$parentForm.unsubscribe(this.handleFormUpdate)
}
},
methods: {
handleInput(event) {
this.input(event.target.value)
},
input(value) {
this.innerValue = value
if (this.$parentForm) {
this.$parentForm.update(this.model, value)
} else {
/**
* Fires after user input.
* Receives the value as the only argument.
*
* @event input
*/
this.$emit('input', value)
this.validate(value)
}
},
handleFormUpdate(data, errors) {
this.innerValue = dotProp.get(data, this.model)
this.error = errors ? errors[this.model] : null
},
validate(value) {
if (!this.schema) {
return
}
const validator = new Schema({ input: this.schema })
// Prevent validator from printing to console
// eslint-disable-next-line
const warn = console.warn;
// eslint-disable-next-line
console.warn = () => {};
validator.validate({ input: value }, errors => {
if (errors) {
this.error = errors[0].message
} else {
this.error = null
}
// eslint-disable-next-line
console.warn = warn;
})
},
handleFocus() {
this.focus = true
},
handleBlur() {
this.focus = false
}
}
}