# ZeenNavDroplist

Компонент выпадающего списка для меню в шапке сайта.

Меню бывает двух видов:

  • Динамическое название (меняется в зависимости от выбранного пункта)
  • Со статичным названием (не меняется от выбранного пункта)

# Example

  • Статический заголовок без иконки

    Выбранный пункт:

    {}
  • Динамический заголовок с иконкой

    props:

    isIcon - если есть иконка,

    isTitleBySelected - динамический заголовок из выбранного в дроплисте

    Выбранный пункт:

    {
      "text": "Динамический заголовок",
      "icon": ""
    }
  • Disabled

    props:

    disabled - Неактивные пункты дроплиста

  • Дроплист со скроллбаром

# Source Code

<template lang="pug">
  .nav-droplist(
    :id="`nav-droplist-${componentId}`"
    :class="{'nav-droplist_disabled' : disabled, open: open} "
    :tabindex="tabindex"
    @blur="open = false"
    @click="open = !open"
  )
    .nav-droplist__title-item
      template(v-if="isTitleBySelected")
        span(v-if="isIcon && selected.icon")
          img.nav-droplist__title-icon(:src="selected.icon" alt="icon")
        span.nav-droplist__title(
        ) {{ selected.text }}
      template(v-else-if="title && !isTitleBySelected")
        span(v-if="title.icon")
          img.nav-droplist__title-icon(:src="title.icon" :alt="title")
        span.nav-droplist__title(
        ) {{ title.text }}
      .nav-droplist__title-arrow
        slot(name="icon-arrow")
          svg.nav-droplist__title-arrow__svg(
            width="12"
            height="7"
            viewBox="0 0 26 14"
            fill="none"
            xmlns="http://www.w3.org/2000/svg"
          )
            path(
              d="M1 1L13 13L25 1"
              fill="none"
              stroke-width="3"
              stroke-linecap="round"
              stroke-linejoin="round"
            )
    .nav-droplist__items(
      v-if="open"
    )
      ZeenScrollBar
        a.nav-droplist__items-link(
          v-for="(option, i) of options"
          :key="i"
          @click.stop="optionClick(option)"
        )
          img.nav-droplist__icon(v-if="isIcon" :src="option.icon" :alt="option")
          span {{ option.text }}
</template>

<script>
import ZeenScrollBar from '../ZeenScrollBar/ZeenScrollBar'

export default {
  name: 'ZeenNavDroplist',
  components: {ZeenScrollBar},
  data() {
    return {
      open: false,
    }
  },
  props: {
    options: {
      type: Array,
      required: true,
    },
    tabindex: {
      type: Number,
      required: false,
      default: 0,
    },
    title: Object,
    selected: Object,
    isTitleBySelected: Boolean,
    disabled: Boolean,
    isIcon: Boolean,
  },
  computed: {
    componentId() {
      return this._uid
    },
  },
  methods: {
    optionClick(option) {
      if (!this.disabled) {
        this.open = false
        this.$emit('changeOption', option)
        // todo - что это за хуйня - это реашет не компонент а ядро
        // this.$router.push(`${option.link}`)
      }
    },
  },
}
</script>

<style lang="scss">
:root {
  /* Размеры */
  --nav-drop-list-max-width: 100%;
  --nav-drop-list-border-radius: var(--main-input-radius);
  --nav-drop-list-max-height: 14em;
  --nav-drop-list-font-weight: normal;
  --nav-drop-list-font-size: var(--main-text-size);
  --nav-drop-list-title-font-size: var(--main-small-text);
  --nav-drop-list-title-font-weight: 600;
  --nav-drop-list-linet-height: 1.5;
  --nav-drop-list-border-width: 1px;
  --nav-drop-list-title-right-offset: 7px;
  --nav-drop-list-text-hover-font-weight: var(--nav-drop-list-font-weight);
  --nav-drop-list-title-icon-size: 13px;
  --nav-drop-list-title-icon-right-offset: 5px;
  --nav-drop-list-icon-size: 15px;
  --nav-drop-list-icon-right-offset: 10px;
  --nav-drop-list-item-link-vertical-padding: 7px;
  --nav-drop-list-item-link-horizontal-padding: 15px;
  --nav-drop-list-top: calc(50% + 100%);
  --nav-drop-list-left: 0;
  --nav-drop-list-right: 0;

  /* Цвета */
  --nav-drop-list-title-color: var(--main-text-color);
  --nav-drop-list-background-color: var(--gray-1);
  --nav-drop-list-text-color: var(--main-text-color);
  --nav-drop-list-border-color: var(--gray-2);
  --nav-drop-list-background-hover-color: var(--gray-3);
  --nav-drop-list-text-hover-color: var(--dark-1);
  --nav-drop-list-text-color-disabled: var(--gray-2);
  --nav-drop-list-background-color-disabled: var(--gray-1);
  --nav-drop-list-arrow-color: var(--main-text-color);
}
</style>

<style lang="scss" scoped>
.nav-droplist {
  position: relative;
  width: inherit;
  text-align: left;
  outline: none;
  display: flex;
  align-items: center;

  &__title-arrow {
    display: flex;
    transition: 0.3s;
    &__svg {
      stroke: var(--nav-drop-list-arrow-color);
    }
  }

  &__title-item {
    display: flex;
    align-items: center;
    cursor: pointer;
  }

  &__title {
    font-weight: var(--nav-drop-list-title-font-weight);
    font-size: var(--nav-drop-list-title-font-size);
    line-height: 1.4;
    margin-right: var(--nav-drop-list-title-right-offset);
    color: var(--nav-drop-list-title-color);
  }

  &__title-icon {
    width: var(--nav-drop-list-title-icon-size);
    height: var(--nav-drop-list-title-icon-size);
    margin-right: var(--nav-drop-list-title-icon-right-offset);
  }

  &__icon {
    width: var(--nav-drop-list-icon-size);
    height: var(--nav-drop-list-icon-size);
    margin-right: var(--nav-drop-list-icon-right-offset);
  }

  &__items {
    display: flex;
    flex-direction: column;
    width: max-content;
    overflow: hidden;
    position: absolute;
    top: var(--nav-drop-list-top);
    left: var(--nav-drop-list-left);
    right: var(--nav-drop-list-right);
    z-index: 2;
    background: var(--nav-drop-list-background-color);
    max-width: var(--nav-drop-list-max-width);
    border-radius: var(--nav-drop-list-border-radius);
    max-height: var(--nav-drop-list-max-height);
  }

  &__items-link {
    display: flex;
    align-items: center;
    background: transparent;
    border: none;
    text-align: left;
    padding: var(--nav-drop-list-item-link-vertical-padding) var(--nav-drop-list-item-link-horizontal-padding);
    cursor: pointer;
    user-select: none;
    border-bottom: solid transparent;
    text-decoration: none !important;

    color: var(--nav-drop-list-text-color);
    border-bottom-color: var(--nav-drop-list-border-color);
    font-weight: var(--nav-drop-list-font-weight);
    font-size: var(--nav-drop-list-font-size);
    line-height: var(--nav-drop-list-linet-height);
    border-bottom-width: var(--nav-drop-list-border-width);

    &:hover {
      background-color: var(--nav-drop-list-background-hover-color);
      color: var(--nav-drop-list-text-hover-color);
      font-weight: var(--nav-drop-list-text-hover-font-weight);
    }

    &:last-of-type {
      border-bottom: none;
    }
  }

  &_disabled {
    .nav-droplist__icon {
      filter: grayscale(100%);
    }

    .nav-droplist__items-link {
      color: var(--nav-drop-list-text-color-disabled);
    }

    .nav-droplist__items {
      background: var(--nav-drop-list-background-color-disabled);
    }
  }
}

.open {
  & .nav-droplist__title-arrow {
    transform: rotate(180deg);
  }
}

.selectHide {
  display: none;
}
</style>

# slots

v-slot:icon-arrow - переопределяет иконку стрелочки в заголовке

# props

Название Тип Обязательный По умолчанию Описание
options Array + - принимает массив с данными - text, icon - иконка для пункта дроп листа, link - ссылка
title Object - - заголовок для статического дроп листа. Так же принимает иконку - icon
selected Object - - объект с выбранным пунктом
isTitleBySelected Boolean - - динамический заголовок из выбранного пункта в дроп листе
disabled Boolean - - если дроп лист неактивный
isIcon Boolean - - если дроп лист с иконками

# Кастомные цвета и стили

Название По умолчанию Описание
nav-drop-list-max-width 100% максимальная ширина выпадающего списка
nav-drop-list-border-radius main-input-radius border-radius выпадающего списка
nav-drop-list-max-height 14em максимальная высота дроп листа до появления скроллбара
nav-drop-list-font-weight normal толщина шрифта пункта выпадающего списка
nav-drop-list-font-size main-text-size размер шрифта
nav-drop-list-linet-height 1.5 устанавливает интерлиньяж (межстрочный интервал) текста
nav-drop-list-text-hover-font-weight nav-drop-list-font-weight толщина шрифта пункта выпадающего списка при наведении
nav-drop-list-border-width 1px толщина бордера между пунктами выпадающего списка
nav-drop-list-title-right-offset 7px margin-right у заголовка списка
nav-drop-list-title-icon-size 13px размер иконки у заголовка списка
nav-drop-list-title-icon-right-offset 5px margin-right у иконки в заголовке списка
nav-drop-list-icon-size 15px замер иконок в пунктах выпадающего списка
nav-drop-list-icon-right-offset 10px margin-right у иконок в пунктах выпадающего списка
nav-drop-list-item-link-vertical-padding 7px верхний и нижний padding у пункта в выпадающем списке
nav-drop-list-item-link-horizontal-padding 15px левый и правый padding у пункта в выпадающем списке
nav-drop-list-top calc(50% + 100%) отступ выпадающего списка сверху от заголовка
nav-drop-list-left 0 отступ выпадающего списка слева от заголовка
nav-drop-list-right 0 отступ выпадающего списка справа от заголовка
nav-drop-list-border-color gray-2 цвет бордера между пунктами выпадающего списка
nav-drop-list-title-color main-text-color цвет заголовка списка
nav-drop-list-background-color gray-1 цвет фона выпадающего списка
nav-drop-list-background-hover-color gray-3 цвет фона при наведении на один из пунктов выпадающего списка
nav-drop-list-text-color main-text-color цвет текста выпадающего списка
nav-drop-list-text-hover-color dark-1 цвет текста при наведении на один из пунктов выпадающего списка
nav-drop-list-text-color-disabled gray-2 цвет текста при неактивном пункте выпадающего списка
nav-drop-list-background-color-disabled gray-1 цвет фона выпадающего списка при неактивном состоянии
nav-drop-list-arrow-color main-text-color цвет иконки (стрелочки) выпадающего списка