2021-08-04 13:59:51 +02:00
|
|
|
<template>
|
|
|
|
<div class="dropdown-wrapper">
|
2021-10-02 16:16:58 +02:00
|
|
|
<div class="dropdown-selected" @click="toggleDropdown">
|
2021-08-04 13:59:51 +02:00
|
|
|
<slot></slot>
|
|
|
|
</div>
|
|
|
|
<ul class="dropdown-list" v-if="isOpen">
|
|
|
|
<li
|
|
|
|
class="dropdown-item"
|
|
|
|
:class="{ selected: option.value === selected }"
|
|
|
|
v-for="(option, index) in dropdownOptions"
|
|
|
|
:key="index"
|
|
|
|
@click="updateSelected(option)"
|
|
|
|
>
|
|
|
|
{{ option.label }}
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script lang="ts">
|
|
|
|
import { PropType, defineComponent, ref } from 'vue'
|
2021-08-11 22:21:26 +02:00
|
|
|
|
2021-08-21 18:36:44 +02:00
|
|
|
import { IDropdownOption, TDropdownOptions } from '@/types/forms'
|
2021-08-04 13:59:51 +02:00
|
|
|
|
|
|
|
export default defineComponent({
|
|
|
|
name: 'Dropdown',
|
|
|
|
props: {
|
|
|
|
options: {
|
|
|
|
type: Object as PropType<TDropdownOptions>,
|
|
|
|
required: true,
|
|
|
|
},
|
|
|
|
selected: {
|
|
|
|
type: String,
|
|
|
|
required: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
emits: {
|
|
|
|
selected: (option: IDropdownOption) => option,
|
|
|
|
},
|
|
|
|
setup(props, { emit }) {
|
|
|
|
let isOpen = ref(false)
|
|
|
|
let dropdownOptions = props.options.map((option) => option)
|
|
|
|
|
2021-10-02 16:16:58 +02:00
|
|
|
function toggleDropdown() {
|
|
|
|
isOpen.value = !isOpen.value
|
2021-08-04 13:59:51 +02:00
|
|
|
}
|
|
|
|
function updateSelected(option: IDropdownOption) {
|
|
|
|
emit('selected', option)
|
|
|
|
isOpen.value = false
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
dropdownOptions,
|
|
|
|
isOpen,
|
2021-10-02 16:16:58 +02:00
|
|
|
toggleDropdown,
|
|
|
|
updateSelected,
|
2021-08-04 13:59:51 +02:00
|
|
|
}
|
|
|
|
},
|
|
|
|
})
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
.dropdown-list {
|
|
|
|
list-style-type: none;
|
|
|
|
background-color: #ffffff;
|
|
|
|
padding: 0;
|
|
|
|
margin: 5px 0;
|
|
|
|
position: absolute;
|
|
|
|
text-align: left;
|
|
|
|
border: solid 1px lightgrey;
|
|
|
|
box-shadow: 2px 2px 5px lightgrey;
|
|
|
|
|
|
|
|
li {
|
|
|
|
padding-top: 5px;
|
|
|
|
}
|
|
|
|
li:last-child {
|
|
|
|
padding-bottom: 5px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.dropdown-item {
|
|
|
|
cursor: default;
|
|
|
|
|
|
|
|
&.selected {
|
|
|
|
font-weight: bold;
|
|
|
|
}
|
|
|
|
|
|
|
|
&.selected::after {
|
|
|
|
content: ' ✔';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</style>
|