summaryrefslogtreecommitdiffstatshomepage
path: root/frontend/src/lib/components/Card.svelte
blob: 2384799ceca0878d871bd84ff54cb91bee081de2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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>