47 lines
1.4 KiB
Svelte
47 lines
1.4 KiB
Svelte
<script lang="ts">
|
|
type Variant = 'primary' | 'secondary' | 'ghost';
|
|
type Size = 'sm' | 'md' | 'large';
|
|
|
|
let {
|
|
variant = 'primary',
|
|
size = 'md',
|
|
disabled = false,
|
|
loading = false,
|
|
type = 'button' as 'button' | 'submit' | 'reset',
|
|
label = '',
|
|
} = $props();
|
|
|
|
const base =
|
|
'inline-flex items-center justify-center gap-2 rounded-lg font-semibold transition-colors duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-wald-300 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-40';
|
|
|
|
const sizeClasses = $derived(
|
|
{ sm: 'h-9 px-4 py-2 text-sm', md: 'h-12 min-w-[120px] px-6 py-3 text-base', large: 'h-14 px-8 py-4 text-lg' }[
|
|
size
|
|
]
|
|
);
|
|
|
|
const variantClasses = $derived(
|
|
{
|
|
primary: 'bg-wald-500 text-white hover:bg-wald-600 active:bg-wald-700',
|
|
secondary:
|
|
'border-[1.5px] border-wald-500 bg-transparent text-wald-500 hover:bg-wald-50 active:bg-wald-100',
|
|
ghost: 'bg-transparent px-4 py-3 text-stein-700 hover:bg-stein-100 active:bg-stein-200',
|
|
}[variant]
|
|
);
|
|
|
|
const allClasses = $derived([base, sizeClasses, variantClasses].filter(Boolean).join(' '));
|
|
</script>
|
|
|
|
<button
|
|
{type}
|
|
{disabled}
|
|
class={allClasses}
|
|
>
|
|
{#if loading}
|
|
<span class="inline-block h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent"></span>
|
|
<span>Laden...</span>
|
|
{:else}
|
|
<slot>{label}</slot>
|
|
{/if}
|
|
</button>
|