File size: 3,765 Bytes
db66673
2961a5b
 
 
db66673
 
f60772d
db66673
 
211077d
 
 
 
db66673
2961a5b
db66673
2d9278d
2961a5b
f60772d
 
f9489c3
3109fce
 
afa49b3
3109fce
822d5b9
7cc4906
 
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 dark:bg-card dark:hover:brightness-120 hover:bg-accent hover:text-accent-foreground border shadow-xs text-primary',
				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-muted dark:bg-muted/60 text-muted-foreground hover:brightness-95 dark:hover:brightness-100 dark:hover:bg-muted border-transparent!'
			},
			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}