1
0

chore: use the <dropdown> and <dropdown-item> components everywhere

Resolves https://kolaente.dev/vikunja/frontend/issues/2176
This commit is contained in:
kolaente
2022-07-20 17:08:46 +02:00
parent d6a10b01dd
commit cdb63b578d
11 changed files with 146 additions and 76 deletions

View File

@ -1,25 +1,95 @@
<template>
<router-link
<component
:is="componentNodeName"
v-bind="elementBindings"
:to="to"
class="dropdown-item">
<span class="icon" v-if="icon !== ''">
<span class="icon" v-if="icon">
<icon :icon="icon"/>
</span>
<span>
<slot></slot>
</span>
</router-link>
</component>
</template>
<script lang="ts" setup>
defineProps({
to: {
required: true,
},
icon: {
type: String,
required: false,
default: '',
},
import {ref, useAttrs, watchEffect} from 'vue'
const props = defineProps<{
to?: object,
icon?: string | string[],
}>()
const componentNodeName = ref<Node['nodeName']>('a')
const elementBindings = ref({})
const attrs = useAttrs()
watchEffect(() => {
let nodeName = 'a'
if (props.to) {
nodeName = 'router-link'
}
if ('href' in attrs) {
nodeName = 'BaseButton'
}
componentNodeName.value = nodeName
elementBindings.value = {
...attrs,
}
})
</script>
<style scoped lang="scss">
.dropdown-item {
color: var(--text);
display: block;
font-size: 0.875rem;
line-height: 1.5;
padding: $item-padding;
position: relative;
}
a.dropdown-item,
button.dropdown-item {
text-align: inherit;
white-space: nowrap;
width: 100%;
display: flex;
align-items: center;
justify-content: left !important;
&:hover {
background-color: var(--grey-100) !important;
}
&.is-active {
background-color: var(--link);
color: var(--link-invert);
}
.icon {
padding-right: .5rem;
}
.icon:not(.has-text-success) {
color: var(--grey-300) !important;
}
&.has-text-danger .icon {
color: var(--danger) !important;
}
&.is-disabled {
cursor: not-allowed;
&:hover {
background-color: transparent;
}
}
}
</style>

View File

@ -1,5 +1,5 @@
<template>
<div class="dropdown is-right is-active" ref="dropdown">
<div class="dropdown" ref="dropdown">
<slot name="trigger" :close="close" :toggleOpen="toggleOpen">
<BaseButton class="dropdown-trigger is-flex" @click="toggleOpen">
<icon :icon="triggerIcon" class="icon"/>
@ -51,7 +51,36 @@ onClickOutside(dropdown, (e: Event) => {
</script>
<style lang="scss" scoped>
.dropdown-menu .dropdown-content {
.dropdown {
display: inline-flex;
position: relative;
vertical-align: top;
}
.dropdown-menu {
min-width: 12rem;
padding-top: 4px;
position: absolute;
top: 100%;
z-index: 20;
display: block;
left: auto;
right: 0;
}
.dropdown-content {
background-color: var(--scheme-main);
border-radius: $radius;
padding-bottom: .5rem;
padding-top: .5rem;
box-shadow: var(--shadow-md);
}
</style>
.dropdown-divider {
background-color: var(--border-light);
border: none;
display: block;
height: 1px;
margin: 0.5rem 0;
}
</style>

View File

@ -1,6 +1,6 @@
<template>
<x-button
v-if="isButton"
v-if="type === 'button'"
variant="secondary"
:icon="iconName"
v-tooltip="tooltipText"
@ -9,6 +9,15 @@
>
{{ buttonText }}
</x-button>
<DropdownItem
v-else-if="type === 'dropdown'"
v-tooltip="tooltipText"
@click="changeSubscription"
:class="{'is-disabled': disabled}"
:icon="iconName"
>
{{ buttonText }}
</DropdownItem>
<BaseButton
v-else
v-tooltip="tooltipText"
@ -27,6 +36,7 @@ import {computed, shallowRef} from 'vue'
import {useI18n} from 'vue-i18n'
import BaseButton from '@/components/base/BaseButton.vue'
import DropdownItem from '@/components/misc/dropdown-item.vue'
import SubscriptionService from '@/services/subscription'
import SubscriptionModel from '@/models/subscription'
@ -34,15 +44,15 @@ import SubscriptionModel from '@/models/subscription'
import {success} from '@/message'
interface Props {
entity: string
entityId: number
subscription: SubscriptionModel | null
isButton?: boolean
entity: string
entityId: number
subscription: SubscriptionModel | null
type?: 'button' | 'dropdown' | null
}
const props = withDefaults(defineProps<Props>(), {
isButton: true,
subscription: null,
type: 'button',
})
const subscriptionEntity = computed<string | null>(() => props.subscription?.entity ?? null)