# 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>