Files
website/src/lib/components/ui/Panel.svelte
T

70 lines
1.5 KiB
Svelte

<script lang="ts">
import type { Snippet } from 'svelte';
import Icon from '@iconify/svelte';
let {
title,
icon,
href,
onclick,
children
}: { title?: string; icon?: string; href?: string; onclick?: () => void; children?: Snippet } = $props();
function handleKeydown(event: KeyboardEvent) {
if (!onclick || (event.key !== 'Enter' && event.key !== ' ')) return;
event.preventDefault();
onclick();
}
</script>
<svelte:element
this={href ? 'a' : 'article'}
class="panel"
class:linked={!!href || !!onclick}
{href}
role={onclick ? 'button' : undefined}
tabindex={onclick ? 0 : undefined}
{onclick}
onkeydown={onclick ? handleKeydown : undefined}
target={href?.startsWith('http') ? '_blank' : undefined}
rel={href?.startsWith('http') ? 'noopener noreferrer' : undefined}
>
{#if title}
<header class="panel-title">
{#if icon}
<Icon {icon} width="16" />
{/if}
<span>{title}</span>
</header>
{/if}
{@render children?.()}
</svelte:element>
<style>
.panel {
display: flex;
flex-direction: column;
gap: 0.5rem;
padding: 0.8rem 0.9rem;
border: 1px solid color-mix(in srgb, var(--foreground) 22%, transparent);
background: color-mix(in srgb, var(--foreground) 3%, transparent);
}
.linked {
cursor: pointer;
}
.linked:hover {
border-color: var(--accent);
background: color-mix(in srgb, var(--foreground) 7%, transparent);
}
.panel-title {
display: flex;
align-items: center;
gap: 0.5rem;
color: var(--accent);
font-weight: 700;
}
</style>