File size: 3,812 Bytes
db66673
2961a5b
 
 
db66673
 
f60772d
db66673
 
211077d
 
 
 
db66673
2961a5b
db66673
39cd443
2961a5b
f60772d
 
f9489c3
3109fce
 
afa49b3
3109fce
822d5b9
 
 
db66673
 
2961a5b
 
f9489c3
bd63612
 
2961a5b
 
 
 
 
90ab305
2961a5b
 
db66673
 
2961a5b
 
 
db66673
 
2961a5b
 
db66673
 
 
 
 
 
 
 
 
 
 
2961a5b
 
db66673
 
2961a5b
db66673
 
 
 
 
 
 
 
 
 
 
 
 
2961a5b
db66673
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
<script lang="ts" module>
	import { cn, type WithElementRef } from '$lib/utils.js';
	import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements';
	import { type VariantProps, tv } from 'tailwind-variants';

	export const buttonVariants = tv({
		base: "focus-visible:border-ring cursor-pointer border border-border focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
		variants: {
			variant: {
				default:
					'bg-primary text-primary-foreground hover:bg-primary/90 shadow-xs disabled:bg-primary/50!',
				highlight:
					'bg-linear-to-br from-blue-500 to-sky-400 text-white hover:brightness-110 shadow-xs',
				destructive:
					'bg-destructive hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60 text-white shadow-xs',
				outline:
					'bg-background hover:bg-accent hover:text-accent-foreground dark:bg-gray-900/70 dark:border-border dark:hover:bg-gray-800/70 border shadow-xs text-gray-600 dark:text-gray-400',
				secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80 shadow-xs',
				ghost:
					'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50 border-transparent!',
				link: 'text-primary underline-offset-4 hover:underline',
				'outline-blue':
					'bg-blue-500/10 text-blue-500 border border-blue-500/20 hover:bg-blue-500/20 shadow-xs',
				'outline-destructive':
					'bg-rose-500/10 hover:bg-rose-500/20 text-rose-600 border border-rose-500/20 shadow-xs',
				amber: 'bg-amber-500 text-white hover:brightness-110 shadow-xs',
				transparent:
					'bg-gray-200/50 text-gray-500 hover:bg-gray-200/80 border-transparent! dark:bg-gray-800/50 dark:text-gray-400 dark:hover:bg-gray-800/80'
			},
			size: {
				default: 'h-9 px-4 py-2 has-[>svg]:px-3',
				sm: 'h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5',
				xs: 'h-7 gap-1 rounded-md px-2.5 has-[>svg]:px-2 text-xs!',
				'2xs': 'h-6 gap-1 rounded-md px-2 has-[>svg]:px-2 text-xs!',
				'3xs': 'h-5 gap-1 rounded-md px-2 has-[>svg]:px-2 text-[10px]!',
				lg: 'h-10 rounded-md px-6 has-[>svg]:px-4',
				icon: 'size-9',
				'icon-sm': 'size-8',
				'icon-lg': 'size-10',
				'icon-xs': 'size-7',
				'icon-2xs': 'size-6',
				'icon-3xs': 'size-4'
			}
		},
		defaultVariants: {
			variant: 'default',
			size: 'default'
		}
	});

	export type ButtonVariant = VariantProps<typeof buttonVariants>['variant'];
	export type ButtonSize = VariantProps<typeof buttonVariants>['size'];

	export type ButtonProps = WithElementRef<HTMLButtonAttributes> &
		WithElementRef<HTMLAnchorAttributes> & {
			variant?: ButtonVariant;
			size?: ButtonSize;
		};
</script>

<script lang="ts">
	let {
		class: className,
		variant = 'default',
		size = 'default',
		ref = $bindable(null),
		href = undefined,
		type = 'button',
		disabled,
		children,
		...restProps
	}: ButtonProps = $props();
</script>

{#if href}
	<a
		bind:this={ref}
		data-slot="button"
		class={cn(buttonVariants({ variant, size }), className)}
		href={disabled ? undefined : href}
		aria-disabled={disabled}
		role={disabled ? 'link' : undefined}
		tabindex={disabled ? -1 : undefined}
		{...restProps}
	>
		{@render children?.()}
	</a>
{:else}
	<button
		bind:this={ref}
		data-slot="button"
		class={cn(buttonVariants({ variant, size }), className)}
		{type}
		{disabled}
		{...restProps}
	>
		{@render children?.()}
	</button>
{/if}