56 lines
1.7 KiB
Svelte
56 lines
1.7 KiB
Svelte
<script lang="ts">
|
|
import { Button } from '$lib/components/ui/button';
|
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '$lib/components/ui/card';
|
|
import type { Snippet } from 'svelte';
|
|
import { getCardStyle } from '$lib/utils/colors';
|
|
import ThemeCard from '$lib/components/themes/ThemeCard.svelte';
|
|
|
|
let {
|
|
title,
|
|
description,
|
|
itemCount,
|
|
color = null,
|
|
theme = null,
|
|
fallbackColor = null,
|
|
fallbackTheme = null,
|
|
children
|
|
}: {
|
|
title: string;
|
|
description?: string | null;
|
|
itemCount: number;
|
|
color?: string | null;
|
|
theme?: string | null;
|
|
fallbackColor?: string | null;
|
|
fallbackTheme?: string | null;
|
|
children?: Snippet;
|
|
} = $props();
|
|
|
|
const finalColor = $derived(color || fallbackColor);
|
|
const finalTheme = $derived(theme || fallbackTheme);
|
|
const cardStyle = $derived(getCardStyle(color, fallbackColor));
|
|
</script>
|
|
|
|
<Card style={cardStyle} class="h-full flex flex-col relative overflow-hidden">
|
|
<ThemeCard themeName={finalTheme} color={finalColor} />
|
|
<CardHeader class="flex-shrink-0 relative z-10">
|
|
<div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-1 sm:gap-2">
|
|
<CardTitle class="text-lg flex items-center gap-2 flex-1 min-w-0">
|
|
<span class="truncate">{title}</span>
|
|
</CardTitle>
|
|
<span class="text-sm text-muted-foreground flex-shrink-0">
|
|
{itemCount} item{itemCount === 1 ? '' : 's'}
|
|
</span>
|
|
</div>
|
|
{#if description}
|
|
<CardDescription class="line-clamp-3 whitespace-pre-line">{description}</CardDescription>
|
|
{/if}
|
|
</CardHeader>
|
|
<CardContent class="space-y-2 flex-1 flex flex-col justify-end relative z-10">
|
|
{#if children}
|
|
<div>
|
|
{@render children()}
|
|
</div>
|
|
{/if}
|
|
</CardContent>
|
|
</Card>
|