/
TextInput.vue
135 lines (129 loc) · 2.39 KB
/
TextInput.vue
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
<template>
<input
ref="input"
v-bind="{
autocomplete,
autofocus,
disabled,
id,
minlength,
name,
pattern,
placeholder,
required,
spellcheck,
type,
value
}"
class="k-text-input"
v-on="listeners"
>
</template>
<script>
import {
required,
minLength,
maxLength,
email,
url
} from "vuelidate/lib/validators";
export default {
inheritAttrs: false,
class: "k-text-input",
props: {
autocomplete: {
type: [Boolean, String],
default: "off"
},
autofocus: Boolean,
disabled: Boolean,
id: [Number, String],
maxlength: Number,
minlength: Number,
name: [Number, String],
pattern: String,
placeholder: String,
preselect: Boolean,
required: Boolean,
spellcheck: {
type: [Boolean, String],
default: "off"
},
type: {
type: String,
default: "text"
},
value: String
},
data() {
return {
listeners: {
...this.$listeners,
input: event => this.onInput(event.target.value)
}
};
},
watch: {
value() {
this.onInvalid();
}
},
mounted() {
this.onInvalid();
if (this.$props.autofocus) {
this.focus();
}
if (this.$props.preselect) {
this.select();
}
},
methods: {
focus() {
this.$refs.input.focus();
},
onInput(value) {
this.$emit("input", value);
},
onInvalid() {
this.$emit("invalid", this.$v.$invalid, this.$v);
},
select() {
this.$refs.input.select();
}
},
validations() {
const match = (value) => {
return (!this.required && value.length === 0) || !this.$refs.input.validity.patternMismatch;
};
return {
value: {
required: this.required ? required : true,
minLength: this.minlength ? minLength(this.minlength) : true,
maxLength: this.maxlength ? maxLength(this.maxlength) : true,
email: this.type === "email" ? email : true,
url: this.type === "url" ? url : true,
pattern: this.pattern ? match: true,
}
};
}
};
</script>
<style lang="scss">
.k-text-input {
width: 100%;
border: 0;
background: none;
font: inherit;
color: inherit;
}
.k-text-input::placeholder {
color: $color-light-grey;
}
.k-text-input:focus {
outline: 0;
}
.k-text-input:invalid {
box-shadow: none;
outline: 0;
}
</style>