a5cb684d34
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
64 lines
1.4 KiB
Vue
64 lines
1.4 KiB
Vue
<template>
|
|
<div class="fc-post-grid">
|
|
<button
|
|
v-for="(t, idx) in thumbnails"
|
|
:key="t.image_id"
|
|
type="button"
|
|
class="fc-post-grid__cell"
|
|
:aria-label="`Open image ${idx + 1} of ${thumbnails.length}`"
|
|
@click="openImage(t.image_id, idx)"
|
|
>
|
|
<img
|
|
:src="t.thumbnail_url"
|
|
:alt="`thumbnail ${idx + 1}`"
|
|
loading="lazy"
|
|
/>
|
|
</button>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { computed } from 'vue'
|
|
import { useModalStore } from '../../stores/modal.js'
|
|
|
|
const props = defineProps({
|
|
thumbnails: { type: Array, required: true }, // [{ image_id, thumbnail_url, ... }]
|
|
})
|
|
|
|
const modal = useModalStore()
|
|
|
|
const imageIds = computed(() => props.thumbnails.map(t => t.image_id))
|
|
|
|
function openImage (id, idx) {
|
|
modal.open(id, { postImageIds: imageIds.value, initialIndex: idx })
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.fc-post-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
|
gap: 6px;
|
|
}
|
|
.fc-post-grid__cell {
|
|
aspect-ratio: 4 / 3;
|
|
overflow: hidden;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
border: 0;
|
|
padding: 0;
|
|
background: rgb(var(--v-theme-background));
|
|
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
|
}
|
|
.fc-post-grid__cell:hover {
|
|
transform: scale(1.02);
|
|
box-shadow: 0 0 0 2px rgb(var(--v-theme-accent));
|
|
}
|
|
.fc-post-grid__cell img {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
display: block;
|
|
}
|
|
</style>
|