This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / web / src / lib / components / ui / Button.svelte
3.9 kB 104 lines
1<script module lang="ts"> 2 import { tv, type VariantProps } from 'tailwind-variants'; 3 4 export const button = tv({ 5 base: 'inline-flex cursor-pointer select-none items-center justify-center overflow-hidden rounded no-underline transition-[background-color,border-color,color] duration-150 ease-[cubic-bezier(0.4,0,0.2,1)] hover:no-underline focus-visible:outline-2 focus-visible:outline-offset-2 disabled:pointer-events-none disabled:opacity-50', 6 variants: { 7 variant: { 8 default: 9 'border border-border bg-surface text-fg hover:bg-surface-hover focus-visible:outline-ring', 10 primary: 11 'border border-primary-border bg-primary text-primary-fg hover:bg-primary-hover focus-visible:outline-primary', 12 ghost: 'bg-transparent text-fg-muted hover:bg-surface-muted focus-visible:outline-ring', 13 flat: 'bg-gray-50 text-fg hover:bg-gray-100 focus-visible:outline-ring dark:bg-gray-900 dark:hover:bg-gray-700', 14 danger: 15 'border border-danger-border bg-danger text-danger-fg hover:bg-danger-hover focus-visible:outline-danger', 16 success: 17 'border border-success-border bg-success text-success-fg hover:bg-success-hover focus-visible:outline-success' 18 }, 19 size: { 20 sm: 'min-h-8 gap-1.5 px-2 py-1.5 text-sm', 21 md: 'min-h-9 gap-2 px-4 py-2 text-sm', 22 lg: 'min-h-10 gap-2.5 px-6 py-2 text-base' 23 } 24 }, 25 compoundVariants: [ 26 // raised variants draw inset depth via a ::before layer. 27 { 28 variant: 'default', 29 class: 30 "relative z-0 before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:content-[''] before:shadow-[inset_0_-2px_0_0_var(--color-raised-depth)] before:transition-all before:duration-150 hover:before:shadow-[inset_0_-2px_0_0_var(--color-raised-depth-hover)] active:translate-y-0.5 active:before:shadow-[inset_0_2px_2px_0_var(--color-raised-depth)] disabled:active:translate-y-0" 31 }, 32 { 33 variant: ['primary', 'danger', 'success'], 34 class: 35 "relative z-0 before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:content-[''] before:shadow-[inset_0_-2px_0_0_var(--color-raised-accent-depth)] before:transition-all before:duration-150 active:translate-y-0.5 active:before:shadow-[inset_0_2px_2px_0_var(--color-raised-accent-depth-active)] disabled:active:translate-y-0" 36 } 37 ], 38 defaultVariants: { 39 variant: 'default', 40 size: 'md' 41 } 42 }); 43 44 export type ButtonVariants = VariantProps<typeof button>; 45</script> 46 47<script lang="ts"> 48 import { resolve } from '$app/paths'; 49 import type { Snippet } from 'svelte'; 50 import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements'; 51 import Spinner from './Spinner.svelte'; 52 53 interface Props extends Omit<HTMLAnchorAttributes & HTMLButtonAttributes, 'class' | 'children'> { 54 variant?: ButtonVariants['variant']; 55 size?: ButtonVariants['size']; 56 href?: string; 57 type?: 'button' | 'submit' | 'reset'; 58 disabled?: boolean; 59 class?: string; 60 loading?: boolean; 61 spinnerClass?: string; 62 children?: Snippet; 63 } 64 65 let { 66 variant = 'default', 67 size = 'md', 68 href, 69 type = 'button', 70 disabled = false, 71 class: className, 72 loading = false, 73 spinnerClass, 74 children, 75 ...rest 76 }: Props = $props(); 77 78 const classes = $derived(button({ variant, size, class: className })); 79 const spinnerSize = $derived(spinnerClass ?? (size === 'lg' ? 'size-5' : 'size-4')); 80</script> 81 82{#if href} 83 <a 84 href={resolve(href as '/')} 85 class={classes} 86 aria-disabled={disabled || loading ? 'true' : undefined} 87 tabindex={disabled ? -1 : undefined} 88 {...rest} 89 > 90 {#if loading} 91 <Spinner class={spinnerSize} /> 92 {:else if children} 93 {@render children()} 94 {/if} 95 </a> 96{:else} 97 <button {type} disabled={disabled || loading} class={classes} aria-busy={loading} {...rest}> 98 {#if loading} 99 <Spinner class={spinnerSize} /> 100 {:else if children} 101 {@render children()} 102 {/if} 103 </button> 104{/if}