Skip to content

Instantly share code, notes, and snippets.

@S-Maxime
Created May 26, 2021 16:27
Show Gist options
  • Select an option

  • Save S-Maxime/6d88f7f77aa629a54bc43d549053ad34 to your computer and use it in GitHub Desktop.

Select an option

Save S-Maxime/6d88f7f77aa629a54bc43d549053ad34 to your computer and use it in GitHub Desktop.
<template>
<div>
<div class="zv-text-input">
<div class="label-input"
:class="error">
<input :ref="name"
v-mask="config"
:usingMask="usingMask"
:mask="mask"
:masked="masked"
:tokens="tokens"
:class="classes"
:value="displayValue"
:type="typing"
:readonly="readOnly"
:name="name"
:autocomplete="autocomplete"
:autofocus="autofocus"
:placeholder="placeholder"
:aria-labelledby="name"
v-on="listeners">
<label :for="name">
{{ label }}
</label>
</div>
<button v-if="iconActive"
type="button"
:aria-label="ariaLabel"
:title="title"
@click="togglePassType()">
<img :src="require(`../assets/images/password/${icon}.svg`)"
alt="password">
</button>
</div>
<div class="forgot-password">
<zv-validation-input v-if="validations"
:validations="validations" />
<slot name="forgotPassword" />
</div>
</div>
</template>
<script>
import './text-input.scss'
import mask from '../../utils/directive'
import masker from '../../utils/masker'
import tokens from '../../utils/tokens'
import ZvValidationInput from '../Messages/ValidationInput'
export default {
name: 'ZvTextInput',
components: {
ZvValidationInput,
},
directives: {
mask,
},
props: {
value: {
type: [String, Number],
required: false,
default: '',
},
usingMask: {
type: Boolean,
required: false,
default: false,
},
mask: {
type: [String, Array],
required: false,
default: '',
},
masked: {
type: Boolean,
required: false,
default: true,
},
tokens: {
type: Object,
default: () => tokens,
},
label: {
type: String,
required: false,
default: '',
},
type: {
type: String,
required: false,
default: 'text',
},
name: {
type: String,
required: true,
},
placeholder: {
type: String,
required: false,
default: '',
},
ariaLabel: {
type: String,
required: false,
default: '',
},
title: {
type: String,
required: false,
default: '',
},
autocomplete: {
type: Boolean,
required: false,
default: true,
},
focus: {
type: Boolean,
required: false,
default: false,
},
autofocus: {
type: Boolean,
required: false,
default: false,
},
readOnly: {
type: Boolean,
required: false,
default: false,
},
validations: {
type: Array,
required: false,
default: () => [],
},
},
data () {
return {
lastValue: null, // avoid unecessary emit when has no change
displayValue: this.value,
passType: 'password',
iconActive: false,
icon: 'eye_close',
}
},
computed: {
error () {
return this.validations[0]?.condition ? 'error' : ''
},
classes () {
const t = this.type === 'password' ? 'remove-icon-width' : ''
const empty = this.value === '' ? 'empty' : ''
return { t, empty }
},
typing () {
return this.type === 'password' ? this.passType : this.type
},
config () {
return {
mask: this.mask,
tokens: this.tokens,
masked: this.masked,
usingMask: this.usingMask,
}
},
listeners () {
const vm = this
return {
...vm.$listeners,
input (e) {
vm.onInput(e)
},
}
},
},
watch: {
value (newValue) {
if (newValue !== this.lastValue) {
this.displayValue = newValue
}
},
masked () {
this.refresh(this.displayValue)
},
},
created () {
this.iconActive = this.type === 'password'
},
mounted () {
if (this.focus) {
this.$refs[this.name].focus()
}
},
methods: {
togglePassType () {
this.icon = this.passType === 'password' ? 'eye_open' : 'eye_close'
this.passType = this.passType === 'password' ? 'text' : 'password'
},
// setFocus sets focus on a field which has a value of 'ref' tag equal to fieldName
setFocus (fieldName) {
if (this.name === fieldName) {
this.$refs[this.name].focus()
}
},
onInput (e) {
if (e.isTrusted) return // ignore native event
this.refresh(e.target.value)
},
refresh (value) {
this.displayValue = value
const sValue = masker(value, this.mask, this.masked, this.tokens)
if (sValue !== this.lastValue) {
this.lastValue = sValue
this.$emit('input', sValue)
}
},
},
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment