# 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 | цвет иконки (стрелочки) выпадающего списка |