Spaces:
Running on Zero
Running on Zero
| <script lang="ts"> | |
| import type { GalleryImage, GalleryVideo, GalleryAudio, GalleryData } from "./types"; | |
| export let value: GalleryData[] | null; | |
| export let type: "gallery" | "table"; | |
| export let selected = false; | |
| </script> | |
| <div | |
| class="container" | |
| class:table={type === "table"} | |
| class:gallery={type === "gallery"} | |
| class:selected | |
| > | |
| {#if value && value.length > 0} | |
| <div class="images-wrapper"> | |
| {#each value.slice(0, 5) as item} | |
| {#if "image" in item && item.image} | |
| <div class="image-container"> | |
| <img src={item.image.url} alt={item.caption || ""} /> | |
| </div> | |
| {:else if "video" in item && item.video} | |
| <div class="image-container"> | |
| <video | |
| src={item.video.url} | |
| controls={false} | |
| muted | |
| preload="metadata" | |
| /> | |
| </div> | |
| {:else if "audio" in item && item.audio} | |
| <div class="image-container audio"> | |
| <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> | |
| <path d="M9 18V5l12-2v13"></path> | |
| <circle cx="6" cy="18" r="3"></circle> | |
| <circle cx="18" cy="16" r="3"></circle> | |
| </svg> | |
| </div> | |
| {/if} | |
| {/each} | |
| {#if value.length > 5} | |
| <div class="more-indicator">+{value.length - 5}</div> | |
| {/if} | |
| </div> | |
| {/if} | |
| </div> | |
| <style> | |
| .container { | |
| border-radius: var(--radius-lg); | |
| overflow: hidden; | |
| border: 2px solid transparent; | |
| box-sizing: border-box; | |
| } | |
| .container.selected { | |
| border-color: var(--border-color-accent); | |
| } | |
| /* Prevent any parent hover effects from causing shifts */ | |
| :global(tr:hover) .container, | |
| :global(tr:hover) .images-wrapper, | |
| :global(tr:hover) .image-container, | |
| :global(tr:hover) .image-container img, | |
| :global(tr:hover) .image-container video { | |
| transform: none !important; | |
| scale: none !important; | |
| } | |
| .container *, | |
| .images-wrapper, | |
| .image-container { | |
| box-sizing: border-box; | |
| } | |
| .images-wrapper { | |
| display: flex; | |
| gap: var(--spacing-sm); | |
| } | |
| .container.table .images-wrapper { | |
| flex-direction: row; | |
| align-items: center; | |
| padding: var(--spacing-sm); | |
| border: 1px solid var(--border-color-primary); | |
| border-radius: var(--radius-lg); | |
| background: var(--background-fill-secondary); | |
| } | |
| .container.gallery .images-wrapper { | |
| flex-direction: row; | |
| gap: 0; | |
| } | |
| .image-container { | |
| position: relative; | |
| flex-shrink: 0; | |
| } | |
| .container.table .image-container { | |
| width: var(--size-12); | |
| height: var(--size-12); | |
| } | |
| .container.gallery .image-container { | |
| width: var(--size-20); | |
| height: var(--size-20); | |
| margin-left: calc(-1 * var(--size-8)); | |
| } | |
| .container.gallery .image-container:first-child { | |
| margin-left: 0; | |
| } | |
| .more-indicator { | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: var(--text-sm); | |
| font-weight: bold; | |
| color: var(--body-text-color-subdued); | |
| background: var(--background-fill-secondary); | |
| border-radius: var(--radius-md); | |
| } | |
| .container.table .more-indicator { | |
| width: var(--size-12); | |
| height: var(--size-12); | |
| } | |
| .container.gallery .more-indicator { | |
| width: var(--size-20); | |
| height: var(--size-20); | |
| margin-left: calc(-1 * var(--size-8)); | |
| } | |
| .image-container img, | |
| .image-container video { | |
| width: 100%; | |
| height: 100%; | |
| object-fit: cover; | |
| border-radius: var(--radius-md); | |
| } | |
| .image-container.audio { | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| border-radius: var(--radius-md); | |
| color: white; | |
| } | |
| /* Remove hover effects */ | |
| .container, | |
| .container *, | |
| .image-container, | |
| .image-container img, | |
| .image-container video { | |
| transition: none !important; | |
| } | |
| .container:hover, | |
| .image-container:hover, | |
| .image-container:hover img, | |
| .image-container:hover video { | |
| transform: none !important; | |
| filter: none !important; | |
| opacity: 1 !important; | |
| } | |
| </style> | |