Files
windwiderstand/src/lib/components/IconButton.svelte
T
Peter Meier c8334dbd6c
Deploy / verify (push) Successful in 1m27s
Deploy / deploy (push) Successful in 1m44s
feat(calendar): CalendarCompact nutzt SectionHeader; fix IconButton-Typing
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>
2026-07-12 11:18:02 +02:00

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}