/ src / components / IconButton.svelte
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}