Skip to content
File

Blob: ui/shared/Button.svelte

1.4 KB
1<script lang="ts">
2 import type { Snippet } from 'svelte';
3 import type { HTMLButtonAttributes } from 'svelte/elements';
4 
5 type Props = HTMLButtonAttributes & {
6 variant?: 'primary' | 'secondary' | 'danger' | 'ghost';
7 size?: 'sm' | 'md';
8 element?: HTMLButtonElement;
9 children?: Snippet;
10 };
11 
12 let {
13 variant = 'secondary',
14 size = 'md',
15 element = $bindable(),
16 type = 'button',
17 class: className,
18 children,
19 ...attributes
20 }: Props = $props();
21 
22 const variants = {
23 primary: 'border-accent-500 bg-accent-500 text-chrome hover:border-accent-400 hover:bg-accent-400',
24 secondary: 'border-zinc-500 bg-surface text-foreground hover:border-zinc-400 hover:bg-zinc-700',
25 danger: 'border-danger/70 bg-danger/10 text-danger hover:border-danger hover:bg-danger/20',
26 ghost: 'border-transparent bg-transparent text-muted hover:bg-surface hover:text-foreground',
27 };
28 const sizes = {
29 sm: 'min-h-9 px-2.5 py-1 text-sm',
30 md: 'min-h-10 px-3 py-1.5 text-sm',
31 };
32</script>
33 
34<button
35 bind:this={element}
36 {type}
37 class={[
38 'inline-flex shrink-0 items-center justify-center gap-2 rounded-md border font-semibold leading-5 transition-transform active:scale-[0.98] disabled:pointer-events-none disabled:opacity-50',
39 variants[variant],
40 sizes[size],
41 className,
42 ]}
43 {...attributes}
44>
45 {@render children?.()}
46</button>