feat(ui): Splittable playbutton with consistent popover
This commit is contained in:
parent
b20456e427
commit
c443593619
|
@ -2,14 +2,17 @@
|
||||||
import type { Track, Artist, Album, Playlist, Library, Channel, Actor } from '~/types'
|
import type { Track, Artist, Album, Playlist, Library, Channel, Actor } from '~/types'
|
||||||
import type { PlayOptionsProps } from '~/composables/audio/usePlayOptions'
|
import type { PlayOptionsProps } from '~/composables/audio/usePlayOptions'
|
||||||
|
|
||||||
import { computed } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import usePlayOptions from '~/composables/audio/usePlayOptions'
|
import usePlayOptions from '~/composables/audio/usePlayOptions'
|
||||||
import useReport from '~/composables/moderation/useReport'
|
import useReport from '~/composables/moderation/useReport'
|
||||||
// import { useCurrentElement } from '@vueuse/core'
|
|
||||||
// import { setupDropdown } from '~/utils/fomantic'
|
|
||||||
import { useStore } from '~/store'
|
import { useStore } from '~/store'
|
||||||
import { useRouter, useRoute } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
|
import { color } from "~/composables/color.ts";
|
||||||
|
|
||||||
|
import Button from '~/components/ui/Button.vue'
|
||||||
|
import Popover from '~/components/ui/Popover.vue'
|
||||||
|
import PopoverItem from '~/components/ui/popover/PopoverItem.vue'
|
||||||
|
|
||||||
|
|
||||||
interface Props extends PlayOptionsProps {
|
interface Props extends PlayOptionsProps {
|
||||||
|
@ -43,8 +46,8 @@ const props = withDefaults(defineProps<Props>(), {
|
||||||
library: null,
|
library: null,
|
||||||
channel: null,
|
channel: null,
|
||||||
account: null,
|
account: null,
|
||||||
dropdownIconClasses: () => ['dropdown'],
|
dropdownIconClasses: () => ['bi-caret-down-fill'],
|
||||||
playIconClass: () => 'play icon',
|
playIconClass: () => 'bi bi-play-fill',
|
||||||
buttonClasses: () => ['button'],
|
buttonClasses: () => ['button'],
|
||||||
discrete: () => false,
|
discrete: () => false,
|
||||||
dropdownOnly: () => false,
|
dropdownOnly: () => false,
|
||||||
|
@ -102,141 +105,118 @@ const title = computed(() => {
|
||||||
return ''
|
return ''
|
||||||
})
|
})
|
||||||
|
|
||||||
// const el = useCurrentElement()
|
const isOpen = ref(false)
|
||||||
// const dropdown = ref()
|
|
||||||
// onMounted(() => {
|
|
||||||
// dropdown.value = setupDropdown('.ui.dropdown', el.value)
|
|
||||||
// })
|
|
||||||
|
|
||||||
const openMenu = () => {
|
|
||||||
// little magic to ensure the menu is always visible in the viewport
|
|
||||||
// By default, try to display it on the right if there is enough room
|
|
||||||
|
|
||||||
// TODO: Re-implement with `Popover` component instead of fomantic dropdown
|
|
||||||
|
|
||||||
// const menu = dropdown.value.find('.menu')
|
|
||||||
|
|
||||||
// if (menu.hasClass('visible')) return
|
|
||||||
// const viewportOffset = menu.get(0)?.getBoundingClientRect() ?? { right: 0, left: 0 }
|
|
||||||
// const viewportWidth = document.documentElement.clientWidth
|
|
||||||
// const rightOverflow = viewportOffset.right - viewportWidth
|
|
||||||
// const leftOverflow = -viewportOffset.left
|
|
||||||
|
|
||||||
// menu.css({
|
|
||||||
// cssText: rightOverflow > 0
|
|
||||||
// ? `left: ${-rightOverflow - 5}px !important;`
|
|
||||||
// : `right: ${-leftOverflow + 5}px !important;`
|
|
||||||
// })
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<span
|
<Popover v-if="!discrete && !iconOnly" v-model:open="isOpen">
|
||||||
:title="title"
|
<Button
|
||||||
:class="['ui', {'tiny': discrete, 'icon': !discrete, 'buttons': !dropdownOnly && !iconOnly}, 'play-button component-play-button']"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
v-if="!dropdownOnly"
|
v-if="!dropdownOnly"
|
||||||
:disabled="!playable"
|
v-bind="{outline: playable, disabled: !playable, solid: !playable}"
|
||||||
|
split
|
||||||
|
splitIcon="bi-caret-down-fill"
|
||||||
:aria-label="labels.replacePlay"
|
:aria-label="labels.replacePlay"
|
||||||
:class="[...buttonClasses, 'ui', {loading: isLoading, 'mini': discrete, disabled: !playable}]"
|
:class="[...buttonClasses, 'ui', {loading: isLoading, 'mini': discrete}]"
|
||||||
@click.stop.prevent="replacePlay()"
|
@click.stop.prevent="replacePlay()"
|
||||||
|
@split-click="isOpen = !isOpen"
|
||||||
|
:split-title="title"
|
||||||
>
|
>
|
||||||
|
<template #main>
|
||||||
<i
|
<i
|
||||||
v-if="playing"
|
v-if="playing"
|
||||||
class="pause icon"
|
class="bi bi-pause-fill"
|
||||||
/>
|
/>
|
||||||
<i
|
<i
|
||||||
v-else
|
v-else
|
||||||
:class="[playIconClass, 'icon']"
|
:class="[playIconClass, 'icon']"
|
||||||
/>
|
/>
|
||||||
<template v-if="!discrete && !iconOnly"> <slot>{{ t('components.audio.PlayButton.button.discretePlay') }}</slot></template>
|
<template v-if="!discrete && !iconOnly"> <slot>{{ t('components.audio.PlayButton.button.discretePlay') }}</slot></template>
|
||||||
</button>
|
</template>
|
||||||
<button
|
</Button>
|
||||||
v-if="!discrete && !iconOnly"
|
|
||||||
:class="['ui', {disabled: !playable && !filterableArtist}, 'floating', 'dropdown', {'icon': !dropdownOnly}, {'button': !dropdownOnly}]"
|
<template #items>
|
||||||
@click.stop.prevent="openMenu"
|
<PopoverItem
|
||||||
>
|
|
||||||
<i
|
|
||||||
:class="dropdownIconClasses.concat(['icon'])"
|
|
||||||
:title="title"
|
|
||||||
/>
|
|
||||||
<div class="menu">
|
|
||||||
<button
|
|
||||||
class="item basic"
|
|
||||||
:disabled="!playable"
|
:disabled="!playable"
|
||||||
:title="labels.addToQueue"
|
:title="labels.addToQueue"
|
||||||
@click.stop.prevent="enqueue"
|
@click.stop.prevent="enqueue"
|
||||||
>
|
>
|
||||||
<i class="plus icon" />{{ labels.addToQueue }}
|
<i class="bi bi-plus" />{{ labels.addToQueue }}
|
||||||
</button>
|
</PopoverItem>
|
||||||
<button
|
|
||||||
|
<PopoverItem
|
||||||
class="item basic"
|
class="item basic"
|
||||||
:disabled="!playable"
|
:disabled="!playable"
|
||||||
:title="labels.playNext"
|
:title="labels.playNext"
|
||||||
@click.stop.prevent="enqueueNext()"
|
@click.stop.prevent="enqueueNext()"
|
||||||
>
|
>
|
||||||
<i class="step forward icon" />{{ labels.playNext }}
|
<i class="bi bi-skip-forward-fill" />{{ labels.playNext }}
|
||||||
</button>
|
</PopoverItem>
|
||||||
<button
|
|
||||||
|
<PopoverItem
|
||||||
class="item basic"
|
class="item basic"
|
||||||
:disabled="!playable"
|
:disabled="!playable"
|
||||||
:title="labels.playNow"
|
:title="labels.playNow"
|
||||||
@click.stop.prevent="enqueueNext(true)"
|
@click.stop.prevent="enqueueNext(true)"
|
||||||
>
|
>
|
||||||
<i class="play icon" />{{ labels.playNow }}
|
<i class="bi bi-play-fill" />{{ labels.playNow }}
|
||||||
</button>
|
</PopoverItem>
|
||||||
<button
|
|
||||||
|
<PopoverItem
|
||||||
v-if="track"
|
v-if="track"
|
||||||
class="item basic"
|
class="item basic"
|
||||||
:disabled="!playable"
|
:disabled="!playable"
|
||||||
:title="labels.startRadio"
|
:title="labels.startRadio"
|
||||||
@click.stop.prevent="store.dispatch('radios/start', {type: 'similar', objectId: track?.id})"
|
@click.stop.prevent="store.dispatch('radios/start', {type: 'similar', objectId: track?.id})"
|
||||||
>
|
>
|
||||||
<i class="feed icon" />{{ labels.startRadio }}
|
<i class="bi bi-broadcast" />{{ labels.startRadio }}
|
||||||
</button>
|
</PopoverItem>
|
||||||
<button
|
|
||||||
|
<PopoverItem
|
||||||
v-if="track"
|
v-if="track"
|
||||||
class="item basic"
|
class="item basic"
|
||||||
:disabled="!playable"
|
:disabled="!playable"
|
||||||
@click.stop="store.commit('playlists/chooseTrack', track)"
|
@click.stop="store.commit('playlists/chooseTrack', track)"
|
||||||
>
|
>
|
||||||
<i class="list icon" />
|
<i class="bi bi-list" />
|
||||||
{{ labels.addToPlaylist }}
|
{{ labels.addToPlaylist }}
|
||||||
</button>
|
</PopoverItem>
|
||||||
<button
|
|
||||||
|
<PopoverItem
|
||||||
v-if="track && route.name !== 'library.tracks.detail'"
|
v-if="track && route.name !== 'library.tracks.detail'"
|
||||||
class="item basic"
|
class="item basic"
|
||||||
@click.stop.prevent="router.push(`/library/tracks/${track?.id}/`)"
|
@click.stop.prevent="router.push(`/library/tracks/${track?.id}/`)"
|
||||||
>
|
>
|
||||||
<i class="info icon" />
|
<i class="bi bi-info-circle" />
|
||||||
<span v-if="track.artist_credit?.some(ac => ac.artist.content_category === 'podcast')">
|
<span v-if="track.artist_credit?.some(ac => ac.artist.content_category === 'podcast')">
|
||||||
{{ t('components.audio.PlayButton.button.episodeDetails') }}
|
{{ t('components.audio.PlayButton.button.episodeDetails') }}
|
||||||
</span>
|
</span>
|
||||||
<span v-else>
|
<span v-else>
|
||||||
{{ t('components.audio.PlayButton.button.trackDetails') }}
|
{{ t('components.audio.PlayButton.button.trackDetails') }}
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</PopoverItem>
|
||||||
<div class="divider" />
|
|
||||||
<button
|
<hr>
|
||||||
|
|
||||||
|
<PopoverItem
|
||||||
v-if="filterableArtist"
|
v-if="filterableArtist"
|
||||||
class="item basic"
|
class="item basic"
|
||||||
:disabled="!filterableArtist"
|
:disabled="!filterableArtist"
|
||||||
:title="labels.hideArtist"
|
:title="labels.hideArtist"
|
||||||
@click.stop.prevent="filterArtist"
|
@click.stop.prevent="filterArtist"
|
||||||
>
|
>
|
||||||
<i class="eye slash outline icon" />
|
<i class="bi bi-eye-slash" />
|
||||||
{{ labels.hideArtist }}
|
{{ labels.hideArtist }}
|
||||||
</button>
|
</PopoverItem>
|
||||||
<button
|
|
||||||
|
<PopoverItem
|
||||||
v-for="obj in getReportableObjects({track, album, artist, playlist, account, channel})"
|
v-for="obj in getReportableObjects({track, album, artist, playlist, account, channel})"
|
||||||
:key="obj.target.type + obj.target.id"
|
:key="obj.target.type + obj.target.id"
|
||||||
class="item basic"
|
class="item basic"
|
||||||
@click.stop.prevent="report(obj)"
|
@click.stop.prevent="report(obj)"
|
||||||
>
|
>
|
||||||
<i class="share icon" /> {{ obj.label }}
|
<i class="bi bi-share" /> {{ obj.label }}
|
||||||
</button>
|
</PopoverItem>
|
||||||
</div>
|
</template>
|
||||||
</button>
|
</Popover>
|
||||||
</span>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -20,6 +20,11 @@ const props = defineProps<{
|
||||||
|
|
||||||
onClick?: (...args: any[]) => void | Promise<void>
|
onClick?: (...args: any[]) => void | Promise<void>
|
||||||
|
|
||||||
|
split?: boolean // Add this prop for split button support
|
||||||
|
splitIcon?: string // Add this prop for the split button icon
|
||||||
|
splitTitle?: string // Add this prop
|
||||||
|
onSplitClick?: (...args: any[]) => void | Promise<void> // Add click handler for split part
|
||||||
|
|
||||||
autofocus? : boolean
|
autofocus? : boolean
|
||||||
ariaPressed? : true
|
ariaPressed? : true
|
||||||
} & (ColorProps | DefaultProps)
|
} & (ColorProps | DefaultProps)
|
||||||
|
@ -53,7 +58,51 @@ onMounted(() => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<button ref="button"
|
<div v-if="split" class="funkwhale button-group">
|
||||||
|
<button
|
||||||
|
ref="button"
|
||||||
|
v-bind="color(props, ['interactive'])(
|
||||||
|
width(props, isIconOnly ? ['square'] : ['normalHeight', 'buttonWidth'])(
|
||||||
|
align(props, { alignSelf:'start', alignText:'center' })(
|
||||||
|
)))"
|
||||||
|
class="funkwhale button split-main"
|
||||||
|
:aria-pressed="props.ariaPressed"
|
||||||
|
:class="{
|
||||||
|
'is-loading': isLoading,
|
||||||
|
'is-icon-only': isIconOnly,
|
||||||
|
'has-icon': !!icon,
|
||||||
|
'is-round': round,
|
||||||
|
'is-shadow': shadow,
|
||||||
|
}"
|
||||||
|
@click="click"
|
||||||
|
>
|
||||||
|
|
||||||
|
<slot name="main">
|
||||||
|
<i v-if="icon && !icon.startsWith('right ')" :class="['bi', icon]" />
|
||||||
|
|
||||||
|
<span>
|
||||||
|
<slot />
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<i v-if="icon && icon.startsWith('right ')" :class="['bi', icon.replace('right ', '')]" />
|
||||||
|
</slot>
|
||||||
|
<Loader v-if="isLoading" :container="false" />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
v-bind="color(props, ['interactive'])(
|
||||||
|
width(props, ['square'])(
|
||||||
|
align(props, { alignSelf:'start', alignText:'center' })(
|
||||||
|
)))"
|
||||||
|
class="funkwhale button split-toggle"
|
||||||
|
:title="splitTitle"
|
||||||
|
@click="onSplitClick"
|
||||||
|
>
|
||||||
|
<i :class="['bi', splitIcon]" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
v-else
|
||||||
|
ref="button"
|
||||||
v-bind="color(props, ['interactive'])(
|
v-bind="color(props, ['interactive'])(
|
||||||
width(props, isIconOnly ? ['square'] : ['normalHeight', 'buttonWidth'])(
|
width(props, isIconOnly ? ['square'] : ['normalHeight', 'buttonWidth'])(
|
||||||
align(props, { alignSelf:'start', alignText:'center' })(
|
align(props, { alignSelf:'start', alignText:'center' })(
|
||||||
|
@ -70,19 +119,38 @@ onMounted(() => {
|
||||||
@click="click"
|
@click="click"
|
||||||
>
|
>
|
||||||
<i v-if="icon && !icon.startsWith('right ')" :class="['bi', icon]" />
|
<i v-if="icon && !icon.startsWith('right ')" :class="['bi', icon]" />
|
||||||
|
|
||||||
<span>
|
<span>
|
||||||
<slot />
|
<slot />
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<i v-if="icon && icon.startsWith('right ')" :class="['bi', icon.replace('right ', '')]" />
|
<i v-if="icon && icon.startsWith('right ')" :class="['bi', icon.replace('right ', '')]" />
|
||||||
|
|
||||||
<Loader v-if="isLoading" :container="false" />
|
<Loader v-if="isLoading" :container="false" />
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.funkwhale {
|
.funkwhale {
|
||||||
|
&.button-group {
|
||||||
|
display: inline-flex;
|
||||||
|
|
||||||
|
.button {
|
||||||
|
display: inline-flex; // Ensure consistent display
|
||||||
|
align-items: center;
|
||||||
|
&.split-main {
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
border-right: 1px solid var(--fw-color);
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.split-toggle {
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
padding: 8px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.button {
|
&.button {
|
||||||
|
|
||||||
// Layout
|
// Layout
|
||||||
|
|
|
@ -122,8 +122,8 @@ watch(open, (isOpen) => {
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
ref="slot"
|
ref="slot"
|
||||||
class="funkwhale popover-container"
|
:class="['funkwhale popover-container', { 'split-button': $slots.default?.$el?.classList?.contains('button-group') }]"
|
||||||
style="display:contents;"
|
:style="$slots.default?.$el?.classList?.contains('button-group') ? 'display: inline-flex' : 'display: contents'"
|
||||||
>
|
>
|
||||||
<slot
|
<slot
|
||||||
:isOpen="open"
|
:isOpen="open"
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
.funkwhale.popover-container {
|
.funkwhale.popover-container {
|
||||||
width: max-content;
|
width: max-content;
|
||||||
|
|
||||||
|
&.split-button {
|
||||||
|
display: inline-flex;
|
||||||
|
gap: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.funkwhale.popover-outer {
|
.funkwhale.popover-outer {
|
||||||
|
@ -19,9 +24,6 @@
|
||||||
&.popover {
|
&.popover {
|
||||||
border: 1px solid var(--fw-border-color);
|
border: 1px solid var(--fw-border-color);
|
||||||
background-color: color-mix(in oklab, var(--background-color) 98%, var(--color));
|
background-color: color-mix(in oklab, var(--background-color) 98%, var(--color));
|
||||||
.popover-item:hover {
|
|
||||||
background-color: color-mix(in oklab, var(--hover-background-color) 98%, var(--color));
|
|
||||||
}
|
|
||||||
|
|
||||||
hr {
|
hr {
|
||||||
border-bottom: 1px solid var(--fw-border-color);
|
border-bottom: 1px solid var(--fw-border-color);
|
||||||
|
@ -62,29 +64,5 @@
|
||||||
padding-top: 12px;
|
padding-top: 12px;
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.popover-item {
|
|
||||||
cursor: pointer;
|
|
||||||
color: var(--color) !important;
|
|
||||||
text-decoration: none;
|
|
||||||
padding-left: 8px;
|
|
||||||
height: 32px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
border-radius: var(--fw-border-radius);
|
|
||||||
white-space: nowrap;
|
|
||||||
|
|
||||||
> .bi:first-child {
|
|
||||||
margin-right: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .bi:last-child {
|
|
||||||
margin-right: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .after {
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ import { inject, ref } from 'vue'
|
||||||
import { type RouterLinkProps, RouterLink } from 'vue-router'
|
import { type RouterLinkProps, RouterLink } from 'vue-router'
|
||||||
import { POPOVER_CONTEXT_INJECTION_KEY, type PopoverContext } from '~/injection-keys'
|
import { POPOVER_CONTEXT_INJECTION_KEY, type PopoverContext } from '~/injection-keys'
|
||||||
|
|
||||||
|
import Button from '~/components/ui/Button.vue'
|
||||||
|
|
||||||
const emit = defineEmits<{'internal:id': [value: number]}>()
|
const emit = defineEmits<{'internal:id': [value: number]}>()
|
||||||
|
|
||||||
const { parentPopoverContext, to } = defineProps<{
|
const { parentPopoverContext, to } = defineProps<{
|
||||||
|
@ -39,18 +41,78 @@ emit('internal:id', id)
|
||||||
<div class="after" />
|
<div class="after" />
|
||||||
<slot name="after" />
|
<slot name="after" />
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
<button v-else
|
<Button v-else
|
||||||
|
ghost
|
||||||
|
thinFont
|
||||||
|
style="
|
||||||
|
width: 100%;
|
||||||
|
textAlign: left;
|
||||||
|
gap: 8px;
|
||||||
|
"
|
||||||
@mouseover="hoveredItem = id"
|
@mouseover="hoveredItem = id"
|
||||||
class="popover-item ghost"
|
class="popover-item"
|
||||||
>
|
>
|
||||||
<slot />
|
<slot />
|
||||||
|
|
||||||
<div class="after">
|
<div class="after">
|
||||||
<slot name="after" />
|
<slot name="after" />
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
div { color:var(--fw-text-color); }
|
div { color:var(--fw-text-color); }
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.popover .popover-item {
|
||||||
|
cursor: pointer;
|
||||||
|
color: var(--color) !important;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 0px 8px;
|
||||||
|
height: 32px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: var(--fw-border-radius);
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--hover-background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
> .bi:first-child {
|
||||||
|
margin-right: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .bi:last-child {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .after {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.popover .popover-item.button {
|
||||||
|
justify-content: flex-start !important;
|
||||||
|
height: 32px !important;
|
||||||
|
padding: 0px 8px;
|
||||||
|
border: none;
|
||||||
|
align-items: center;
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--hover-background-color) !important;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
width: 100%;
|
||||||
|
i {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
> i {
|
||||||
|
margin-right: 14px !important;
|
||||||
|
}
|
||||||
|
.after {
|
||||||
|
margin-right: 0px;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
Loading…
Reference in New Issue