Square Library modal thumbs and add stage previous/next.

This commit is contained in:
Towsty
2026-09-28 20:40:45 -05:00
parent a33cadb6c2
commit f9903ed76e
4 changed files with 203 additions and 34 deletions
+90 -12
View File
@@ -54,20 +54,20 @@
<article
v-for="entry in entries"
:key="entry.key"
class="library-thumb group relative cursor-pointer overflow-hidden rounded-2xl border bg-zinc-950"
:class="entry.key === focusedKey ? 'border-amber-300 ring-2 ring-amber-300/70' : 'border-white/10'"
class="lib-modal-tile"
:data-active="entry.key === focusedKey ? 'true' : undefined"
@click="pickEntry(entry)"
>
<div class="relative aspect-[4/5] bg-zinc-900">
<div class="lib-modal-media">
<div
v-if="entry.kind === 'track'"
class="flex h-full w-full items-end gap-0.5 bg-zinc-900 px-4 py-8"
class="lib-modal-track"
aria-hidden="true"
>
<span
v-for="n in 16"
:key="n"
class="flex-1 rounded-full bg-amber-400/70"
class="lib-modal-bar"
:style="{ height: `${20 + ((n * 17) % 60)}%` }"
/>
</div>
@@ -77,16 +77,15 @@
alt=""
decoding="async"
draggable="false"
class="h-full w-full object-cover"
>
<span v-else class="block h-full w-full bg-zinc-800" />
<span class="absolute left-2 top-2 rounded-md bg-black/60 px-1.5 py-0.5 text-[10px] uppercase tracking-wide text-zinc-200">
<span v-else class="lib-modal-fallback" />
<span class="lib-modal-kind">
{{ entry.kind === 'clip' ? 'Video' : entry.kind === 'track' ? 'Music' : 'Image' }}
</span>
</div>
<div class="px-2.5 py-2">
<p class="truncate text-xs font-medium text-zinc-100">{{ entry.name }}</p>
<p class="truncate text-[11px] text-zinc-500">{{ cardMeta(entry) }}</p>
<div class="lib-modal-caption">
<p class="lib-modal-name">{{ entry.name }}</p>
<p class="lib-modal-meta">{{ cardMeta(entry) }}</p>
</div>
</article>
</div>
@@ -435,11 +434,90 @@ onBeforeUnmount(() => {
min-height: 0;
height: 100%;
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
gap: 10px;
gap: 8px;
align-content: start;
overflow: auto;
padding: 14px 16px;
}
.lib-modal-tile {
display: flex;
min-height: 120px;
flex-direction: column;
overflow: hidden;
border: 2px solid #2a2a2e;
border-radius: 8px;
background: #0b0b0d;
cursor: pointer;
}
.lib-modal-tile[data-active='true'] {
border-color: #f5a524;
box-shadow: 0 0 0 2px #f5a524;
}
.lib-modal-media {
position: relative;
aspect-ratio: 1 / 1;
min-height: 120px;
width: 100%;
overflow: hidden;
background: #18181b;
}
.lib-modal-media > img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
.lib-modal-fallback {
display: block;
width: 100%;
height: 100%;
background: #27272a;
}
.lib-modal-track {
display: flex;
height: 100%;
width: 100%;
align-items: flex-end;
gap: 2px;
padding: 16px;
}
.lib-modal-bar {
flex: 1;
border-radius: 999px;
background: rgba(245, 165, 36, 0.7);
}
.lib-modal-kind {
position: absolute;
top: 8px;
left: 8px;
border-radius: 4px;
background: #000a;
padding: 2px 6px;
color: #e4e4e7;
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.04em;
}
.lib-modal-caption {
padding: 6px 8px 8px;
}
.lib-modal-name {
margin: 0;
overflow: hidden;
color: #f4f4f5;
font-size: 12px;
font-weight: 600;
text-overflow: ellipsis;
white-space: nowrap;
}
.lib-modal-meta {
margin: 2px 0 0;
overflow: hidden;
color: #71717a;
font-size: 11px;
text-overflow: ellipsis;
white-space: nowrap;
}
.lib-modal-empty {
grid-column: 1 / -1;
color: #9a9588;