Added support for dropdowns
This commit is contained in:
parent
ecbe472acc
commit
703b12428b
3 changed files with 150 additions and 0 deletions
frontend/src
86
frontend/src/components/Dropdown.vue
Normal file
86
frontend/src/components/Dropdown.vue
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
<template>
|
||||||
|
<div class="dropdown">
|
||||||
|
<button class="dropdown__button" @click="show">
|
||||||
|
<slot name="button" />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="dropdown__container" ref="container">
|
||||||
|
<div class="dropdown__content">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
container() {
|
||||||
|
return this.$refs.container as HTMLElement;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
show() {
|
||||||
|
this.container.classList.add('show');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@use "@/styles/common.scss" as *;
|
||||||
|
|
||||||
|
.dropdown {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
&__button {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:focus,
|
||||||
|
&:hover {
|
||||||
|
color: var(--color-hover);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__container {
|
||||||
|
position: absolute;
|
||||||
|
display: none;
|
||||||
|
top: 100%;
|
||||||
|
right: 0;
|
||||||
|
z-index: 20;
|
||||||
|
|
||||||
|
&.show {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__content {
|
||||||
|
min-width: 10rem;
|
||||||
|
display: flex;
|
||||||
|
background-color: var(--color-background);
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.5);
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
padding: 0.25rem;
|
||||||
|
flex-direction: column;
|
||||||
|
animation: dropdown 0.25s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes dropdown {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-0.5rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
48
frontend/src/components/DropdownItem.vue
Normal file
48
frontend/src/components/DropdownItem.vue
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
<template>
|
||||||
|
<div class="dropdown__item" @click="$emit('click')">
|
||||||
|
<div class="dropdown__item__icon">
|
||||||
|
<slot name="icon" />
|
||||||
|
</div>
|
||||||
|
<div class="dropdown__item__text">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
emits: ['click'],
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.dropdown__item {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
padding: 0.5rem 0;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--color-hover);
|
||||||
|
|
||||||
|
:deep(a) {
|
||||||
|
background-color: inherit;
|
||||||
|
color: var(--color-hover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__icon {
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
:deep(a) {
|
||||||
|
flex: 1;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
16
frontend/src/mixins/Dropdowns.vue
Normal file
16
frontend/src/mixins/Dropdowns.vue
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
methods: {
|
||||||
|
installDropdownHandler() {
|
||||||
|
document.addEventListener('click', (event) => {
|
||||||
|
if (!(event.target as HTMLElement).closest('.dropdown__button')) {
|
||||||
|
document.querySelectorAll('.dropdown__container').forEach((content) => {
|
||||||
|
content.classList.remove('show');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
Loading…
Add table
Reference in a new issue