11<template >
2- <component
3- :is =" interactive ? 'button' : 'div'"
2+ <div
43 data-component-id =" AssetCard"
54 :data-asset-id =" asset.id"
6- v-bind =" elementProps"
5+ :aria-labelledby =" titleId"
6+ :aria-describedby =" descId"
7+ tabindex =" 1"
78 :class ="
89 cn(
910 'rounded-2xl overflow-hidden transition-all duration-200 bg-modal-card-background p-2',
1011 interactive &&
11- 'group appearance-none bg-transparent m-0 outline-none cursor-pointer text-left hover:bg-secondary-background focus:bg-secondary-background border-none focus:outline-solid outline-base-foreground outline-4'
12+ 'group appearance-none bg-transparent m-0 outline-none text-left hover:bg-secondary-background focus:bg-secondary-background border-none focus:outline-solid outline-base-foreground outline-4'
1213 )
1314 "
14- @click =" interactive && $emit('select', asset)"
1515 @keydown.enter =" interactive && $emit('select', asset)"
1616 >
1717 <div class =" relative aspect-square w-full overflow-hidden rounded-xl" >
18+ <div
19+ v-if =" isLoading || error"
20+ class =" flex size-full cursor-pointer items-center justify-center bg-gradient-to-br from-smoke-400 via-smoke-800 to-charcoal-400"
21+ role =" button"
22+ @click =" interactive && $emit('select', asset)"
23+ />
1824 <img
19- v-if = " shouldShowImage "
25+ v-else
2026 :src =" asset.preview_url"
21- class =" size-full object-contain"
27+ class =" size-full object-contain cursor-pointer"
28+ role =" button"
29+ @click =" interactive && $emit('select', asset)"
2230 />
23- <div
24- v-else
25- class =" flex size-full items-center justify-center bg-gradient-to-br from-smoke-400 via-smoke-800 to-charcoal-400"
26- ></div >
31+
2732 <AssetBadgeGroup :badges =" asset.badges" />
33+ <IconGroup
34+ ref =" card-buttons"
35+ :class ="
36+ cn(
37+ 'absolute top-2 right-2 invisible group-hover:visible',
38+ dropdownMenuButton?.isOpen && 'visible'
39+ )
40+ "
41+ >
42+ <IconButton >
43+ <i class =" icon-[lucide--file-text]" />
44+ </IconButton >
45+ <MoreButton ref =" dropdown-menu-button" size =" sm" >
46+ <template #default =" {} " >
47+ <IconTextButton :label =" $t('g.rename')" type =" secondary" size =" md" >
48+ <template #icon >
49+ <i class =" icon-[lucide--pencil]" />
50+ </template >
51+ </IconTextButton >
52+ <IconTextButton :label =" $t('g.delete')" type =" secondary" size =" md" >
53+ <template #icon >
54+ <i class =" icon-[lucide--trash-2]" />
55+ </template >
56+ </IconTextButton >
57+ </template >
58+ </MoreButton >
59+ </IconGroup >
2860 </div >
2961 <div :class =" cn('p-4 h-32 flex flex-col justify-between')" >
3062 <div >
68100 </span >
69101 </div >
70102 </div >
71- </component >
103+ </div >
72104</template >
73105
74106<script setup lang="ts">
75107import { useImage } from ' @vueuse/core'
76- import { computed , useId } from ' vue'
108+ import { computed , useId , useTemplateRef } from ' vue'
77109
110+ import IconButton from ' @/components/button/IconButton.vue'
111+ import IconGroup from ' @/components/button/IconGroup.vue'
112+ import IconTextButton from ' @/components/button/IconTextButton.vue'
113+ import MoreButton from ' @/components/button/MoreButton.vue'
78114import AssetBadgeGroup from ' @/platform/assets/components/AssetBadgeGroup.vue'
79115import type { AssetDisplayItem } from ' @/platform/assets/composables/useAssetBrowser'
80116import { useSettingStore } from ' @/platform/settings/settingStore'
@@ -91,30 +127,19 @@ defineEmits<{
91127
92128const settingStore = useSettingStore ()
93129
130+ const dropdownMenuButton = useTemplateRef <typeof MoreButton >(
131+ ' dropdown-menu-button'
132+ )
133+
94134const titleId = useId ()
95135const descId = useId ()
96136
97137const tooltipDelay = computed <number >(() =>
98138 settingStore .get (' LiteGraph.Node.TooltipDelay' )
99139)
100140
101- const { error } = useImage ({
141+ const { isLoading, error } = useImage ({
102142 src: asset .preview_url ?? ' ' ,
103143 alt: asset .name
104144})
105-
106- const shouldShowImage = computed (() => asset .preview_url && ! error .value )
107-
108- const elementProps = computed (() =>
109- interactive
110- ? {
111- type: ' button' ,
112- ' aria-labelledby' : titleId ,
113- ' aria-describedby' : descId
114- }
115- : {
116- ' aria-labelledby' : titleId ,
117- ' aria-describedby' : descId
118- }
119- )
120145 </script >
0 commit comments