Spaces:
Running
Running
| <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} | |