IconButton.svelte
1 <script lang="ts"> 2 import { createEventDispatcher } from "svelte"; 3 4 import Loading from "./Loading.svelte"; 5 6 export let ariaLabel: string | undefined = undefined; 7 export let inline: boolean = false; 8 export let loading: boolean = false; 9 export let title: string | undefined = undefined; 10 export let stylePadding: string | undefined = undefined; 11 export let disabled: boolean = false; 12 export let stopPropagation: boolean = false; 13 14 const dispatch = createEventDispatcher<{ click: MouseEvent }>(); 15 </script> 16 17 <style> 18 .button { 19 user-select: none; 20 background-color: transparent; 21 border-radius: var(--border-radius-tiny); 22 color: var(--color-foreground-dim); 23 cursor: pointer; 24 display: flex; 25 align-items: center; 26 justify-content: center; 27 padding: 8px 6px; 28 gap: 0.25rem; 29 font-size: var(--font-size-small); 30 } 31 .inline { 32 display: inline-flex; 33 } 34 .button:hover { 35 color: var(--color-foreground-contrast); 36 background-color: var(--color-fill-ghost); 37 } 38 .disabled, 39 .disabled:hover { 40 color: var(--color-fill-counter); 41 background-color: unset; 42 } 43 </style> 44 45 {#if loading} 46 <Loading small noDelay /> 47 {:else} 48 <!-- svelte-ignore a11y-click-events-have-key-events --> 49 <div 50 class:disabled 51 aria-label={ariaLabel} 52 class:inline 53 class="button" 54 on:click={ev => { 55 if (stopPropagation) { 56 ev.stopPropagation(); 57 } 58 if (disabled) { 59 return; 60 } 61 dispatch("click", ev); 62 }} 63 role="button" 64 style:padding={stylePadding} 65 tabindex="0" 66 {title}> 67 <slot /> 68 </div> 69 {/if}