feat(ui): Popover icon prop

This commit is contained in:
ArneBo 2025-01-20 13:59:40 +01:00
parent d4dfac84a2
commit e52f0a8230
3 changed files with 63 additions and 19 deletions

View File

@ -94,57 +94,60 @@ const open = ref(false)
<template #items> <template #items>
<PopoverItem <PopoverItem
v-if="domain != store.getters['instance/domain']" v-if="domain != store.getters['instance/domain']"
:href="object.fid" :to="object.fid"
icon="bi-box-arrow-up-right"
target="_blank" target="_blank"
> >
<i class="bi bi-box-arrow-up-right" />
{{ t('components.library.AlbumDropdown.link.domain') }} {{ t('components.library.AlbumDropdown.link.domain') }}
</PopoverItem> </PopoverItem>
<PopoverItem <PopoverItem
v-if="isEmbedable" v-if="isEmbedable"
@click="showEmbedModal = !showEmbedModal" @click="showEmbedModal = !showEmbedModal"
icon="bi-code"
> >
<i class="bi bi-code" />
{{ t('components.library.AlbumDropdown.button.embed') }} {{ t('components.library.AlbumDropdown.button.embed') }}
</PopoverItem> </PopoverItem>
<PopoverItem <PopoverItem
v-if="isAlbum && musicbrainzUrl" v-if="isAlbum && musicbrainzUrl"
:href="musicbrainzUrl" :to="musicbrainzUrl"
icon="bi-box-arrow-up-right"
target="_blank" target="_blank"
rel="noreferrer noopener" rel="noreferrer noopener"
> >
<i class="bi bi-box-arrow-up-right" />
{{ t('components.library.AlbumDropdown.link.musicbrainz') }} {{ t('components.library.AlbumDropdown.link.musicbrainz') }}
</PopoverItem> </PopoverItem>
<PopoverItem <PopoverItem
v-if="!isChannel && isAlbum" v-if="!isChannel && isAlbum"
:href="discogsUrl" :to="discogsUrl"
icon="bi-box-arrow-up-right"
target="_blank" target="_blank"
rel="noreferrer noopener" rel="noreferrer noopener"
> >
<i class="bi bi-box-arrow-up-right" />
{{ t('components.library.AlbumDropdown.link.discogs') }} {{ t('components.library.AlbumDropdown.link.discogs') }}
</PopoverItem> </PopoverItem>
<PopoverItem <PopoverItem
v-if="object.is_local" v-if="object.is_local"
:to="{ name: 'library.albums.edit', params: { id: object.id } }" :to="{ name: 'library.albums.edit', params: { id: object.id } }"
icon="bi-pencil"
> >
<i class="bi bi-pencil" />
{{ t('components.library.AlbumDropdown.button.edit') }} {{ t('components.library.AlbumDropdown.button.edit') }}
</PopoverItem> </PopoverItem>
<PopoverItem <PopoverItem
v-if="artistCredit[0] && store.state.auth.authenticated && artistCredit[0].artist.channel && artistCredit[0].artist.attributed_to?.full_username === store.state.auth.fullUsername" v-if="artistCredit[0] &&
store.state.auth.authenticated &&
artistCredit[0].artist.channel &&
artistCredit[0].artist.attributed_to?.full_username === store.state.auth.fullUsername"
> >
<DangerousButton <DangerousButton
:is-loading="isLoading" :is-loading="isLoading"
@confirm="remove()" @confirm="remove()"
icon="bi-trash"
> >
<i class="bi bi-trash" />
{{ t('components.library.AlbumDropdown.button.delete') }} {{ t('components.library.AlbumDropdown.button.delete') }}
</DangerousButton> </DangerousButton>
</PopoverItem> </PopoverItem>
@ -152,11 +155,14 @@ const open = ref(false)
<hr> <hr>
<PopoverItem <PopoverItem
v-for="obj in getReportableObjects({album: object, channel: artistCredit[0]?.artist.channel})" v-for="obj in getReportableObjects({
album: object,
channel: artistCredit[0]?.artist.channel
})"
:key="obj.target.type + obj.target.id" :key="obj.target.type + obj.target.id"
@click="report(obj)" @click="report(obj)"
icon="bi-flag"
> >
<i class="bi bi-flag" />
{{ obj.label }} {{ obj.label }}
</PopoverItem> </PopoverItem>
@ -164,19 +170,22 @@ const open = ref(false)
<PopoverItem <PopoverItem
v-if="store.state.auth.availablePermissions['library']" v-if="store.state.auth.availablePermissions['library']"
:to="{name: 'manage.library.albums.detail', params: {id: object.id}}" :to="{
name: 'manage.library.albums.detail',
params: { id: object.id }
}"
icon="bi-wrench"
> >
<i class="bi bi-wrench" />
{{ t('components.library.AlbumDropdown.link.moderation') }} {{ t('components.library.AlbumDropdown.link.moderation') }}
</PopoverItem> </PopoverItem>
<PopoverItem <PopoverItem
v-if="store.state.auth.profile && store.state.auth.profile?.is_superuser" v-if="store.state.auth.profile?.is_superuser"
:href="store.getters['instance/absoluteUrl'](`/api/admin/music/album/${object.id}`)" :to="store.getters['instance/absoluteUrl'](`/api/admin/music/album/${object.id}`)"
icon="bi-wrench"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
> >
<i class="bi bi-wrench" />
{{ t('components.library.AlbumDropdown.link.django') }} {{ t('components.library.AlbumDropdown.link.django') }}
</PopoverItem> </PopoverItem>
</template> </template>

View File

@ -10,6 +10,7 @@ const emit = defineEmits<{'internal:id': [value: number]}>()
const { parentPopoverContext, to } = defineProps<{ const { parentPopoverContext, to } = defineProps<{
parentPopoverContext?: PopoverContext; parentPopoverContext?: PopoverContext;
to?:RouterLinkProps['to']; to?:RouterLinkProps['to'];
icon?: string;
}>() }>()
const { items, hoveredItem } = parentPopoverContext ?? inject(POPOVER_CONTEXT_INJECTION_KEY, { const { items, hoveredItem } = parentPopoverContext ?? inject(POPOVER_CONTEXT_INJECTION_KEY, {
items: ref(0), items: ref(0),
@ -26,6 +27,7 @@ emit('internal:id', id)
class="popover-item" class="popover-item"
target="_blank" target="_blank"
> >
<i v-if="icon" :class="['bi', icon]" />
<slot /> <slot />
<div class="after" /> <div class="after" />
@ -34,6 +36,7 @@ emit('internal:id', id)
<RouterLink v-else-if="to" <RouterLink v-else-if="to"
:to="to" :to="to"
class="popover-item" class="popover-item"
:icon="icon"
@mouseover="hoveredItem = id" @mouseover="hoveredItem = id"
> >
<slot /> <slot />
@ -49,6 +52,7 @@ emit('internal:id', id)
textAlign: left; textAlign: left;
gap: 8px; gap: 8px;
" "
:icon="icon"
@mouseover="hoveredItem = id" @mouseover="hoveredItem = id"
class="popover-item" class="popover-item"
> >

View File

@ -359,6 +359,37 @@ const open = ref(false)
</template> </template>
</Popover> </Popover>
### Icon Prop
PopoverItem supports an `icon` prop to easily add icons to menu items. The icon prop accepts standard Bootstrap icon classes.
| Prop | Data type | Required? | Description |
|--------|-----------|-----------|------------------------------------------------|
| `icon` | String | No | Bootstrap icon class to display before the item |
```vue-html
<PopoverItem icon="bi-music-note-list">
Play next
</PopoverItem>
<PopoverItem icon="right bi-share">
Share
</PopoverItem>
```
<Popover v-model:open="isOpen">
<OptionsButton @click="isOpen = !isOpen" />
<template #items>
<PopoverItem icon="bi-music-note-list">
Play next
</PopoverItem>
<PopoverItem icon="right bi-share">
Share
</PopoverItem>
</template>
</Popover>
```
## Submenus ## Submenus
To create more complex menus, you can use submenus (`PopoverSubmenu`). Submenus are menu items which contain other menu items. To create more complex menus, you can use submenus (`PopoverSubmenu`). Submenus are menu items which contain other menu items.