68 lines
2.2 KiB
Svelte
68 lines
2.2 KiB
Svelte
<script lang="ts">
|
|
import { createEventDispatcher } from "svelte";
|
|
import { cva, type VariantProps } from "class-variance-authority";
|
|
import { cn } from "$lib/utils";
|
|
|
|
export let href: string | undefined = undefined;
|
|
export let type: "button" | "submit" | "reset" = "button";
|
|
export let variant: ButtonVariant = "default";
|
|
export let size: ButtonSize = "default";
|
|
export let disabled = false;
|
|
export let className = "";
|
|
|
|
const dispatch = createEventDispatcher<{ click: MouseEvent }>();
|
|
|
|
const buttonVariants = cva(
|
|
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors ring-offset-[var(--background)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
|
|
{
|
|
variants: {
|
|
variant: {
|
|
default: "bg-[var(--primary)] text-[var(--primary-foreground)] shadow-sm hover:opacity-95",
|
|
secondary: "bg-[var(--secondary)] text-[var(--secondary-foreground)] shadow-sm hover:opacity-95",
|
|
ghost: "hover:bg-[var(--accent)] text-[var(--foreground)]",
|
|
destructive: "bg-red-700 text-white shadow-sm hover:bg-red-800",
|
|
outline: "border border-[var(--border)] bg-[var(--background)] shadow-sm hover:bg-[var(--accent)]"
|
|
},
|
|
size: {
|
|
default: "h-10 px-4 py-2",
|
|
sm: "h-9 rounded-md px-3",
|
|
lg: "h-11 rounded-md px-8",
|
|
icon: "h-10 w-10"
|
|
}
|
|
},
|
|
defaultVariants: {
|
|
variant: "default",
|
|
size: "default"
|
|
}
|
|
}
|
|
);
|
|
|
|
type ButtonVariant = VariantProps<typeof buttonVariants>["variant"];
|
|
type ButtonSize = VariantProps<typeof buttonVariants>["size"];
|
|
|
|
function handleClick(event: MouseEvent) {
|
|
dispatch("click", event);
|
|
}
|
|
</script>
|
|
|
|
{#if href}
|
|
<a
|
|
class={cn(buttonVariants({ variant, size }), className)}
|
|
{href}
|
|
{...$$restProps}
|
|
on:click={handleClick}
|
|
>
|
|
<slot />
|
|
</a>
|
|
{:else}
|
|
<button
|
|
class={cn(buttonVariants({ variant, size }), className)}
|
|
{type}
|
|
{disabled}
|
|
{...$$restProps}
|
|
on:click={handleClick}
|
|
>
|
|
<slot />
|
|
</button>
|
|
{/if}
|