Thomas G. Lopes commited on
Commit
f33fa43
·
1 Parent(s): 9104321

use melt for local toasts

Browse files
package.json CHANGED
@@ -37,7 +37,7 @@
37
  "globals": "^16.0.0",
38
  "highlight.js": "^11.10.0",
39
  "jiti": "^2.4.2",
40
- "melt": "^0.20.2",
41
  "postcss": "^8.4.38",
42
  "prettier": "^3.1.1",
43
  "prettier-plugin-svelte": "^3.2.6",
 
37
  "globals": "^16.0.0",
38
  "highlight.js": "^11.10.0",
39
  "jiti": "^2.4.2",
40
+ "melt": "^0.21.0",
41
  "postcss": "^8.4.38",
42
  "prettier": "^3.1.1",
43
  "prettier-plugin-svelte": "^3.2.6",
pnpm-lock.yaml CHANGED
@@ -85,8 +85,8 @@ importers:
85
  specifier: ^2.4.2
86
  version: 2.4.2
87
  melt:
88
- specifier: ^0.20.2
89
- version: 0.20.2(@floating-ui/[email protected])([email protected])
90
  postcss:
91
  specifier: ^8.4.38
92
  version: 8.5.3
@@ -1548,8 +1548,8 @@ packages:
1548
1549
  resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
1550
 
1551
- melt@0.20.2:
1552
- resolution: {integrity: sha512-vINBKFVqFN8LVU6K7AbEwlGTOzSi5BQulxhKkIroxPWnCA3LVsQEIDZabtf9TtnzFa/th0Rm8J0N+hW1v7VJDw==}
1553
  peerDependencies:
1554
  '@floating-ui/dom': ^1.6.0
1555
  svelte: ^5.0.0
@@ -3474,7 +3474,7 @@ snapshots:
3474
  dependencies:
3475
  '@jridgewell/sourcemap-codec': 1.5.0
3476
 
3477
- melt@0.20.2(@floating-ui/[email protected])([email protected]):
3478
  dependencies:
3479
  '@floating-ui/dom': 1.6.13
3480
  jest-axe: 9.0.0
 
85
  specifier: ^2.4.2
86
  version: 2.4.2
87
  melt:
88
+ specifier: ^0.21.0
89
+ version: 0.21.0(@floating-ui/[email protected])([email protected])
90
  postcss:
91
  specifier: ^8.4.38
92
  version: 8.5.3
 
1548
1549
  resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
1550
 
1551
+ melt@0.21.0:
1552
+ resolution: {integrity: sha512-eD0gGaer3CDB8vklec8KWx9X8Gi5BqufZo4eEvRc3GNPpBvAi3i0ZCuziG+/C1jkL+a+Mi6tSKqiBMfyOdJskg==}
1553
  peerDependencies:
1554
  '@floating-ui/dom': ^1.6.0
1555
  svelte: ^5.0.0
 
3474
  dependencies:
3475
  '@jridgewell/sourcemap-codec': 1.5.0
3476
 
3477
+ melt@0.21.0(@floating-ui/[email protected])([email protected]):
3478
  dependencies:
3479
  '@floating-ui/dom': 1.6.13
3480
  jest-axe: 9.0.0
src/lib/components/local-toasts.svelte CHANGED
@@ -1,10 +1,11 @@
1
  <script lang="ts">
2
- import { onDestroy, type Snippet } from "svelte";
3
- import { computePosition, autoUpdate } from "@floating-ui/dom";
 
4
  import { fly } from "svelte/transition";
5
 
6
  interface Props {
7
- children: Snippet<[{ addToast: typeof addToast; trigger: typeof trigger }]>;
8
  closeDelay?: number;
9
  }
10
  const { children, closeDelay = 2000 }: Props = $props();
@@ -15,28 +16,14 @@
15
  id,
16
  } as const;
17
 
18
- type Toast = {
19
  content: string;
20
  variant: "info" | "danger";
21
- id: string;
22
  };
23
 
24
- let toasts = $state<Toast[]>([]);
25
- let timeouts: ReturnType<typeof window.setTimeout>[] = [];
26
-
27
- function addToast(content: string, variant?: Toast["variant"]) {
28
- const id = crypto.randomUUID();
29
- const timeout = setTimeout(() => {
30
- toasts = toasts.filter(t => t.id !== id);
31
- timeouts = timeouts.filter(t => t !== timeout);
32
- }, closeDelay);
33
-
34
- toasts.push({ content, id, variant: variant ?? "info" });
35
- timeouts.push(timeout);
36
- }
37
-
38
- onDestroy(() => {
39
- timeouts.forEach(t => clearTimeout(t));
40
  });
41
 
42
  function float(node: HTMLElement) {
@@ -59,25 +46,25 @@
59
  };
60
  }
61
 
62
- const classMap: Record<Toast["variant"], string> = {
63
  info: "border border-blue-400 bg-gradient-to-b from-blue-500 to-blue-600",
64
 
65
  danger: "border border-red-400 bg-gradient-to-b from-red-500 to-red-600",
66
  };
67
  </script>
68
 
69
- {@render children({ trigger, addToast })}
70
 
71
- {#each toasts as toast (toast.id)}
72
  <div
73
  data-local-toast
74
- data-variant={toast.variant}
75
- class="rounded-full px-2 py-1 text-xs {classMap[toast.variant]}"
76
  in:fly={{ y: 10 }}
77
  out:fly={{ y: -4 }}
78
  use:float
79
  >
80
- {toast.content}
81
  </div>
82
  {/each}
83
 
 
1
  <script lang="ts">
2
+ import { autoUpdate, computePosition } from "@floating-ui/dom";
3
+ import { Toaster } from "melt/builders";
4
+ import { type Snippet } from "svelte";
5
  import { fly } from "svelte/transition";
6
 
7
  interface Props {
8
+ children: Snippet<[{ addToast: typeof toaster.addToast; trigger: typeof trigger }]>;
9
  closeDelay?: number;
10
  }
11
  const { children, closeDelay = 2000 }: Props = $props();
 
16
  id,
17
  } as const;
18
 
19
+ type ToastData = {
20
  content: string;
21
  variant: "info" | "danger";
 
22
  };
23
 
24
+ const toaster = new Toaster<ToastData>({
25
+ hover: null,
26
+ closeDelay: () => closeDelay,
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  });
28
 
29
  function float(node: HTMLElement) {
 
46
  };
47
  }
48
 
49
+ const classMap: Record<ToastData["variant"], string> = {
50
  info: "border border-blue-400 bg-gradient-to-b from-blue-500 to-blue-600",
51
 
52
  danger: "border border-red-400 bg-gradient-to-b from-red-500 to-red-600",
53
  };
54
  </script>
55
 
56
+ {@render children({ trigger, addToast: toaster.addToast })}
57
 
58
+ {#each toaster.toasts as toast (toast.id)}
59
  <div
60
  data-local-toast
61
+ data-variant={toast.data.variant}
62
+ class="rounded-full px-2 py-1 text-xs {classMap[toast.data.variant]}"
63
  in:fly={{ y: 10 }}
64
  out:fly={{ y: -4 }}
65
  use:float
66
  >
67
+ {toast.data.content}
68
  </div>
69
  {/each}
70
 
src/lib/components/share-modal.svelte CHANGED
@@ -88,7 +88,7 @@
88
  class="btn flex items-center gap-2"
89
  onclick={() => {
90
  copyToClipboard(encoded);
91
- addToast("Copied to clipboard");
92
  }}
93
  >
94
  <IconCopy />
@@ -114,7 +114,7 @@
114
  e.preventDefault();
115
  const decoded = decodeString(pasted);
116
  if (!isProject(decoded)) {
117
- addToast("String isn't valid", "danger");
118
  return;
119
  }
120
  session.addProject({ ...decoded, name: `Saved - ${decoded.name}`, id: crypto.randomUUID() });
 
88
  class="btn flex items-center gap-2"
89
  onclick={() => {
90
  copyToClipboard(encoded);
91
+ addToast({ data: { content: "Copied to clipboard", variant: "info" } });
92
  }}
93
  >
94
  <IconCopy />
 
114
  e.preventDefault();
115
  const decoded = decodeString(pasted);
116
  if (!isProject(decoded)) {
117
+ addToast({ data: { content: "String isn't valid", variant: "danger" } });
118
  return;
119
  }
120
  session.addProject({ ...decoded, name: `Saved - ${decoded.name}`, id: crypto.randomUUID() });