diff options
Diffstat (limited to '')
-rw-r--r-- | frontend/src/lib/components/Card.svelte | 74 |
1 files changed, 39 insertions, 35 deletions
diff --git a/frontend/src/lib/components/Card.svelte b/frontend/src/lib/components/Card.svelte index 2384799..8a2b047 100644 --- a/frontend/src/lib/components/Card.svelte +++ b/frontend/src/lib/components/Card.svelte @@ -1,5 +1,8 @@ -<script lang="ts" context="module"> - import type { ComicFragment, ImageFragment } from '$gql/graphql'; +<script lang="ts"> + import type { ImageFragment } from '$gql/graphql'; + import { src } from '$lib/Utils'; + import Star from '$lib/icons/Star.svelte'; + import type { Snippet } from 'svelte'; interface CardDetails { title: string; @@ -8,41 +11,40 @@ cover?: ImageFragment; } - export function comicCard(comic: ComicFragment) { - return { - href: `/comics/${comic.id.toString()}`, - details: { - title: comic.title, - subtitle: comic.originalTitle, - favourite: comic.favourite, - cover: comic.cover - } - }; + interface Props { + href: string; + details: CardDetails; + compact?: boolean; + coverOnly?: boolean; + overlay?: Snippet; + children?: Snippet; + footer?: Snippet; + onclick?: (event: MouseEvent) => void; } -</script> -<script lang="ts"> - import { src } from '$lib/Utils'; - import Star from '$lib/icons/Star.svelte'; - - export let href: string; - export let details: CardDetails; - export let compact = false; - export let coverOnly = false; - export let ellipsis = true; + let { + href, + details, + compact = false, + coverOnly = false, + overlay, + children, + footer, + onclick + }: Props = $props(); </script> <a {href} - class="grid-card-v sm:grid-card-h relative grid overflow-hidden rounded bg-slate-900 shadow-md shadow-slate-950/30" + class="grid-card-v sm:grid-card-h relative grid overflow-hidden rounded-sm bg-slate-900 shadow-md shadow-slate-950/30 focus-visible:outline-4 focus-visible:outline-blue-600" class:compact class:grid-card-cover-only={coverOnly} - on:click + {onclick} > - <slot name="overlay" /> + {@render overlay?.()} {#if details.cover} <img - class="h-full w-full object-cover object-[center_top]" + class="h-full w-full object-cover object-[left_top]" width={details.cover.width} height={details.cover.height} src={src(details.cover)} @@ -51,13 +53,9 @@ /> {/if} {#if !coverOnly} - <article class="flex h-full flex-col gap-2 p-2"> - <header> - <h2 - class:ellipsis-nowrap={ellipsis} - class="self-center text-sm font-medium [grid-area:title]" - title={details.title} - > + <article class="p flex h-full flex-col p-2 pb-1"> + <header class="mb-2"> + <h2 class="self-center text-sm font-medium [grid-area:title]" title={details.title}> {details.title} </h2> {#if details.subtitle} @@ -75,9 +73,15 @@ {/if} </header> - <section class="max-h-full grow overflow-auto border-t border-slate-800/80 pt-2 text-xs"> - <slot /> + <section class="max-h-full grow overflow-auto border-y border-slate-800/80 pt-2 text-xs"> + {@render children?.()} </section> + + {#if footer} + <div class="mt-1 text-xs"> + {@render footer()} + </div> + {/if} </article> {/if} </a> |