# ZeenPhoneInput
Компонент ZeenPhoneInput
# Примеры:
Примеры использования ZeenPhoneInput
# props
Название | Тип | Обязательный | По умолчанию | Описание |
---|---|---|---|---|
required | Boolean | - | false | Обязательный или нет |
disabled | Boolean | - | false | Отключить инпут |
error | String | - | '' | Текст ошибки |
hideDropdown | Boolean | - | false | Откл выбор маски |
placeholder | String | - | '+7 (999) 999-99-99' | placeholder |
mask | String | - | '+7 (999) 999-99-99' | маска инпута |
imgCode | String | - | 'RU' | Код активной иконки |
masksList | Array | - | смотреть в masksList | Массив масок |
# Source Code - исходный код компонента
<template lang="pug">
.zeen-phone-input(
:id='`zeen-phone-input-${componentId}`'
:key='componentId'
:class='classParent'
v-click-outside='closeDropdown'
)
.zeen-phone-input__wrapper
input.zeen-phone-input__input-real(
ref='phone'
:class='classInput'
:placeholder='placeholder'
:required='required'
:disabled='disabled'
name='phone'
type='text'
@input='onInput'
v-bind='$attrs'
:id='componentId'
:key='`input-${componentId}`'
)
span.zeen-phone-input__btn(v-if='!hideDropdown' @click.prevent='dropdownSwitch' v-html='activeFlag')
.zeen-phone-input__drop(v-show='dropdownHandler')
.zeen-phone-input__drop-item(
v-for='item in masksListUpdate'
@click.prevent='changeMask(item.mask, item.placeholder, item.imgCode)'
)
span.zeen-phone-input__drop-text {{item.country}}
span.zeen-phone-input__drop-code {{item.code}}
span.zeen-phone-input__drop-svg(v-html='item.img')
label.zeen-phone-input__label(v-if='error' :for='componentId') {{ error }}
</template>
<script>
import componentIdSsr from '../../mixins/componentIdSsr'
import masksList from './masksList'
import * as Flags from 'country-flag-icons/string/3x2'
export default {
name: 'ZeenPhoneInput',
mixins: [componentIdSsr],
props: {
required: Boolean,
disabled: Boolean,
error: {
type: String,
default: '',
},
hideDropdown: {
type: Boolean,
default: false,
},
placeholder: {
type: String,
default: '+7 (999) 999-99-99',
},
mask: {
type: String,
default: '+7 (999) 999-99-99',
},
imgCode: {
type: String,
default: 'RU',
},
masksList: {
type: Array,
default: () => [...masksList],
},
},
data() {
return {
dropdownHandler: false,
inputMaskInstance: null,
}
},
async mounted() {
if (typeof window !== 'undefined') {
const Inputmask = (await import('inputmask')).default
this.inputMaskInstance = Inputmask
this.initMask()
}
},
methods: {
onInput(e) {
this.$emit('input', e.target.value)
},
initMask(mask = this.mask) {
if (this.$refs.phone && this.inputMaskInstance) {
new this.inputMaskInstance({
mask: mask,
showMaskOnHover: false,
showMaskOnFocus: false,
}).mask(this.$refs.phone)
}
},
dropdownSwitch() {
this.dropdownHandler = !this.dropdownHandler
this.$emit('dropdownSwitch')
},
closeDropdown() {
this.dropdownHandler = false
this.$emit('closeDropdown')
},
changeMask(mask, placeholder, img) {
this.$emit('changeMask', {mask, placeholder, img})
this.initMask(mask)
this.closeDropdown()
},
},
computed: {
masksListUpdate() {
return this.masksList.map((item) => {
return {
...item,
img: Flags[item.imgCode],
}
})
},
activeFlag() {
return Flags[this.imgCode]
},
classParent() {
return {'zeen-phone-input_error': this.error}
},
classInput() {
return {'zeen-phone-input__input-real_with-btn': !this.hideDropdown}
},
},
}
</script>
<style lang="scss">
:root {
/* Размеры кнопки */
--phone-input-flag-size: 20px;
--phone-input-drop-radius: 10px;
--phone-input-drop-padding-vertical: 8px;
--phone-input-drop-padding-horizontal: 30px;
--phone-input-drop-border-size: 1px;
--phone-input-flag-margin: 7px;
--phone-input-drop-text-size: var(--main-size);
--phone-input-drop-padding-vertical-first: 24px;
--phone-input-drop-padding-vertical-last: var(--phone-input-drop-padding-vertical-first);
--phone-input-scrollbar-width: var(--zeen-chat-scrollbar-width);
--phone-input-scrollbar-radius: var(--zeen-chat-scrollbar-thumb-borderradius);
--phone-input-drop-text-code-size: var(--main-smallest-text);
/* Цвета кнопки */
--phone-input-drop-background: var(--gray-1);
--phone-input-drop-text-color: var(--main-positive-color);
--phone-input-drop-border-color: transparent;
--phone-input-drop-background-hover: var(--gray-2);
--phone-input-drop-text-color-hover: var(--main-positive-color);
--phone-input-scrollbar-thumb-color: var(--input-main-placeholder-color);
}
</style>
<style lang="scss" scoped>
.zeen-phone-input {
--text-input-label-color: var(--text-input-label-base-color);
--text-input-border-focus-color: var(--text-input-border-base-focus-color);
&_error {
--text-input-label-color: var(--text-input-label-error-color);
--text-input-border-focus-color: var(--text-input-border-error-color);
--text-input-border-color: var(--text-input-border-focus-color);
}
&__label {
display: block;
font-size: var(--text-input-label-size);
line-height: var(--text-input-label-line-height);
color: var(--text-input-label-color);
margin: var(--main-input-label-offset-bottom) 0 0 var(--main-input-label-offset-left);
}
&__wrapper {
position: relative;
}
&__input-real {
width: 100%;
box-sizing: border-box;
border-radius: var(--text-input-border-radius);
border: var(--text-input-border-width) solid var(--text-input-border-color);
padding: var(--text-input-vertical-padding) var(--text-input-horizontal-padding);
font-size: var(--text-input-text-size);
line-height: 1.5;
-webkit-appearance: none;
outline: none;
color: var(--text-input-color);
background: var(--text-input-background);
&::placeholder {
font-size: inherit;
line-height: inherit;
color: var(--text-input-placeholder-color);
}
&:focus {
border-color: var(--text-input-border-focus-color);
}
&:disabled {
--text-input-border-color: transparent;
&::placeholder {
--text-input-placeholder-color: var(--text-input-placeholder-disable-color);
}
}
&_with-btn {
padding-left: 65px;
}
}
&__btn {
position: absolute;
padding-right: 10px;
left: 20px;
top: 50%;
transform: translate(0, -50%);
display: flex;
align-items: center;
cursor: pointer;
background-color: transparent;
border: none;
width: calc(var(--phone-input-flag-size) + 10px);
height: var(--phone-input-flag-size);
&::after {
content: '';
position: absolute;
left: 25px;
top: 7px;
width: 0;
height: 0;
border-left: 3px solid transparent;
border-right: 3px solid transparent;
border-top: 6px solid var(--text-input-placeholder-color);
}
}
&__drop {
position: absolute;
top: calc(100% + 10px);
display: flex;
flex-direction: column;
left: 0;
background: var(--phone-input-drop-background);
border-radius: var(--phone-input-drop-radius);
overflow-y: auto;
width: 100%;
max-height: 240px;
z-index: 10;
scrollbar-color: transparent;
scrollbar-width: var(--phone-input-scrollbar-width);
&::-webkit-scrollbar {
width: var(--phone-input-scrollbar-width);
}
&::-webkit-scrollbar-track {
background: transparent;
}
&::-webkit-scrollbar-thumb {
background: var(--phone-input-scrollbar-thumb-color);
border-radius: var(--phone-input-scrollbar-radius);
}
&::-webkit-scrollbar-button {
background: transparent;
height: 3px;
}
}
&__drop-text {
flex: 1 1 auto;
font-weight: normal;
font-size: var(--phone-input-drop-text-size);
line-height: 1.4;
color: var(--phone-input-drop-text-color);
}
&__drop-code {
font-weight: normal;
font-size: var(--phone-input-drop-text-code-size);
line-height: 1.5;
color: var(--phone-input-drop-text-color);
}
&__drop-item {
padding: var(--phone-input-drop-padding-vertical) var(--phone-input-drop-padding-horizontal);
border-bottom: var(--phone-input-drop-border-size) solid var(--phone-input-drop-border-color);
display: flex;
width: 100%;
align-items: center;
justify-content: space-between;
cursor: pointer;
transition: 0.2s;
&:hover,
&:active {
background: var(--phone-input-drop-background-hover);
.zeen-phone-input__drop-text {
color: var(--phone-input-drop-text-color-hover);
}
}
&:first-child {
padding-top: var(--phone-input-drop-padding-vertical-first);
}
&:last-child {
border-bottom: 0;
padding-bottom: var(--phone-input-drop-padding-vertical-last);
}
}
&__drop-svg {
width: var(--phone-input-flag-size);
height: var(--phone-input-flag-size);
margin-left: var(--phone-input-flag-margin);
}
}
</style>