diff options
Diffstat (limited to '')
-rw-r--r-- | frontend/src/lib/components/Card.svelte | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/frontend/src/lib/components/Card.svelte b/frontend/src/lib/components/Card.svelte new file mode 100644 index 0000000..2384799 --- /dev/null +++ b/frontend/src/lib/components/Card.svelte @@ -0,0 +1,106 @@ +<script lang="ts" context="module"> + import type { ComicFragment, ImageFragment } from '$gql/graphql'; + + interface CardDetails { + title: string; + favourite?: boolean; + subtitle?: string | null; + 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 + } + }; + } +</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; +</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:compact + class:grid-card-cover-only={coverOnly} + on:click +> + <slot name="overlay" /> + {#if details.cover} + <img + class="h-full w-full object-cover object-[center_top]" + width={details.cover.width} + height={details.cover.height} + src={src(details.cover)} + alt="" + title={details.title} + /> + {/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} + > + {details.title} + </h2> + {#if details.subtitle} + <h3 + class="ellipsis-nowrap text-xs opacity-60 [grid-area:subtitle]" + title={details.subtitle} + > + {details.subtitle} + </h3> + {/if} + {#if details.favourite} + <div class="flex items-center text-lg [grid-area:fav]"> + <Star favourite /> + </div> + {/if} + </header> + + <section class="max-h-full grow overflow-auto border-t border-slate-800/80 pt-2 text-xs"> + <slot /> + </section> + </article> + {/if} +</a> + +<style> + a.compact { + grid-template-columns: 175px 1fr; + grid-template-rows: 250px; + } + + img { + border-start-start-radius: inherit; + border-end-start-radius: inherit; + } + + article > header { + display: grid; + + grid-template-columns: 1fr auto; + grid-template-rows: auto; + + grid-template-areas: + 'title fav' + 'subtitle fav'; + } +</style> |