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 / Link.svelte
2.9 kB 108 lines
1<script module lang="ts"> 2 import { tv, type VariantProps } from "tailwind-variants"; 3 4 export const link = tv({ 5 base: "inline-flex cursor-pointer select-none items-center gap-1 no-underline transition-colors duration-150 ease-in-out hover:underline focus-visible:outline-2 focus-visible:outline-offset-2", 6 variants: { 7 variant: { 8 default: 9 "text-foreground-link-default hover:text-foreground-link-hover focus-visible:outline-border-focus", 10 success: 11 "text-foreground-link-success hover:text-foreground-link-success-hover focus-visible:outline-foreground-link-success", 12 warning: 13 "text-foreground-link-warning hover:text-foreground-link-warning-hover focus-visible:outline-foreground-link-warning", 14 danger: 15 "text-foreground-link-danger hover:text-foreground-link-danger-hover focus-visible:outline-foreground-link-danger" 16 }, 17 size: { 18 regular: "text-sm", 19 small: "text-xs" 20 }, 21 disabled: { 22 true: "pointer-events-none opacity-50", 23 false: "" 24 } 25 }, 26 defaultVariants: { 27 variant: "default", 28 size: "regular", 29 disabled: false 30 } 31 }); 32 33 export type LinkVariants = VariantProps<typeof link>; 34</script> 35 36<script lang="ts"> 37 import type { ResolvedPathname } from "$app/types"; 38 import type { Component, Snippet } from "svelte"; 39 import type { 40 HTMLAnchorAttributes, 41 HTMLButtonAttributes, 42 SvelteHTMLElements 43 } from "svelte/elements"; 44 45 interface Props extends Omit<HTMLAnchorAttributes & HTMLButtonAttributes, "class" | "children"> { 46 variant?: LinkVariants["variant"]; 47 size?: LinkVariants["size"]; 48 href?: ResolvedPathname; 49 type?: "button" | "submit" | "reset"; 50 disabled?: boolean; 51 iconLeft?: Component<SvelteHTMLElements["svg"]>; 52 iconRight?: Component<SvelteHTMLElements["svg"]>; 53 class?: string; 54 children?: Snippet; 55 } 56 57 let { 58 variant = "default", 59 size = "regular", 60 href, 61 type = "button", 62 disabled = false, 63 iconLeft, 64 iconRight, 65 class: className, 66 children, 67 ...rest 68 }: Props = $props(); 69 70 const classes = $derived(link({ variant, size, disabled, class: className })); 71 const iconSize = $derived(size === "small" ? "size-3" : "size-4"); 72</script> 73 74{#if href} 75 <a 76 {href} 77 class={classes} 78 aria-disabled={disabled ? "true" : undefined} 79 tabindex={disabled ? -1 : undefined} 80 {...rest} 81 > 82 {#if iconLeft} 83 {@const IconLeft = iconLeft} 84 <IconLeft class={iconSize} aria-hidden="true" /> 85 {/if} 86 {#if children} 87 {@render children()} 88 {/if} 89 {#if iconRight} 90 {@const IconRight = iconRight} 91 <IconRight class={iconSize} aria-hidden="true" /> 92 {/if} 93 </a> 94{:else} 95 <button {type} {disabled} class={classes} {...rest}> 96 {#if iconLeft} 97 {@const IconLeft = iconLeft} 98 <IconLeft class={iconSize} aria-hidden="true" /> 99 {/if} 100 {#if children} 101 {@render children()} 102 {/if} 103 {#if iconRight} 104 {@const IconRight = iconRight} 105 <IconRight class={iconSize} aria-hidden="true" /> 106 {/if} 107 </button> 108{/if}