c8334dbd6c
CalendarCompactBlock: plain h3 → SectionHeader (title + 'Alle kommenden Termine'- Action). IconButton props via HTMLButton/AnchorAttributes statt Index-Signatur (brach Storybook-Typing). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
58 lines
1.8 KiB
Svelte
58 lines
1.8 KiB
Svelte
<script lang="ts">
|
|
/**
|
|
* IconButton — runder Icon-only Button (Carousel-Pfeile, Modal-Close, …).
|
|
* Die eine Quelle für kreisförmige Icon-Buttons. `label` = aria-label (Pflicht).
|
|
* variant: surface (weiß, Border, Shadow — z.B. Slider-Pfeile) · ghost (transparent).
|
|
*/
|
|
import Icon from "@iconify/svelte";
|
|
import "$lib/iconify-offline";
|
|
import type { HTMLButtonAttributes, HTMLAnchorAttributes } from "svelte/elements";
|
|
|
|
type Size = "sm" | "md";
|
|
type Variant = "surface" | "ghost";
|
|
|
|
let {
|
|
icon,
|
|
label,
|
|
href = undefined,
|
|
onclick = undefined,
|
|
size = "md",
|
|
variant = "surface",
|
|
disabled = false,
|
|
class: className = "",
|
|
...rest
|
|
}: {
|
|
icon: string;
|
|
label: string;
|
|
href?: string;
|
|
onclick?: (e: MouseEvent) => void;
|
|
size?: Size;
|
|
variant?: Variant;
|
|
disabled?: boolean;
|
|
class?: string;
|
|
} & HTMLButtonAttributes &
|
|
HTMLAnchorAttributes = $props();
|
|
|
|
const sizeClass: Record<Size, string> = { sm: "size-7", md: "size-9" };
|
|
const iconClass: Record<Size, string> = { sm: "size-4", md: "size-5" };
|
|
const variantClass: Record<Variant, string> = {
|
|
surface:
|
|
"border border-stein-200 bg-white text-stein-700 shadow-md hover:bg-stein-50",
|
|
ghost: "text-stein-600 hover:bg-stein-100",
|
|
};
|
|
|
|
const cls = $derived(
|
|
`inline-flex shrink-0 items-center justify-center rounded-full transition-colors disabled:cursor-not-allowed disabled:opacity-50 ${sizeClass[size]} ${variantClass[variant]} ${className}`,
|
|
);
|
|
</script>
|
|
|
|
{#if href && !disabled}
|
|
<a {href} class={cls} aria-label={label} {...rest}>
|
|
<Icon icon={icon} class={iconClass[size]} aria-hidden="true" />
|
|
</a>
|
|
{:else}
|
|
<button type="button" {disabled} {onclick} class={cls} aria-label={label} {...rest}>
|
|
<Icon icon={icon} class={iconClass[size]} aria-hidden="true" />
|
|
</button>
|
|
{/if}
|