varsel 0.5.2 → 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/VarselManager.svelte +23 -3
- package/dist/VarselManager.svelte.d.ts.map +1 -1
- package/dist/VarselToaster.svelte +12 -6
- package/dist/VarselToaster.svelte.d.ts.map +1 -1
- package/dist/core/toast-factory.d.ts.map +1 -1
- package/dist/core/toast-factory.js +29 -8
- package/dist/core/toaster-instances.d.ts +1 -0
- package/dist/core/toaster-instances.d.ts.map +1 -1
- package/dist/core/toaster-instances.js +10 -2
- package/package.json +2 -1
|
@@ -290,9 +290,12 @@ $effect(() => {
|
|
|
290
290
|
});
|
|
291
291
|
|
|
292
292
|
$effect(() => {
|
|
293
|
-
|
|
293
|
+
let hoverFrameId: number | null = null;
|
|
294
|
+
let pointerX = 0;
|
|
295
|
+
let pointerY = 0;
|
|
296
|
+
|
|
297
|
+
const updateHoverState = (x: number, y: number) => {
|
|
294
298
|
if (latestPositionEntries.length === 0) return;
|
|
295
|
-
const { clientX: x, clientY: y } = event;
|
|
296
299
|
const next: Record<ToastPosition, boolean> = {
|
|
297
300
|
...latestHovered,
|
|
298
301
|
};
|
|
@@ -333,6 +336,19 @@ $effect(() => {
|
|
|
333
336
|
}
|
|
334
337
|
};
|
|
335
338
|
|
|
339
|
+
const flushHoverUpdate = () => {
|
|
340
|
+
hoverFrameId = null;
|
|
341
|
+
updateHoverState(pointerX, pointerY);
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
const handleMouseMove = (event: MouseEvent) => {
|
|
345
|
+
pointerX = event.clientX;
|
|
346
|
+
pointerY = event.clientY;
|
|
347
|
+
if (hoverFrameId == null) {
|
|
348
|
+
hoverFrameId = requestAnimationFrame(flushHoverUpdate);
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
|
|
336
352
|
const handleKeyDown = (event: KeyboardEvent) => {
|
|
337
353
|
if (event.key !== "Escape") return;
|
|
338
354
|
for (const [, group] of latestPositionEntries) {
|
|
@@ -358,6 +374,10 @@ $effect(() => {
|
|
|
358
374
|
document.addEventListener("mousemove", handleMouseMove);
|
|
359
375
|
document.addEventListener("keydown", handleKeyDown);
|
|
360
376
|
return () => {
|
|
377
|
+
if (hoverFrameId != null) {
|
|
378
|
+
cancelAnimationFrame(hoverFrameId);
|
|
379
|
+
hoverFrameId = null;
|
|
380
|
+
}
|
|
361
381
|
document.removeEventListener("mousemove", handleMouseMove);
|
|
362
382
|
document.removeEventListener("keydown", handleKeyDown);
|
|
363
383
|
};
|
|
@@ -428,4 +448,4 @@ const handleHeightChange = (id: string, height: number) => {
|
|
|
428
448
|
{/each}
|
|
429
449
|
{/each}
|
|
430
450
|
</div>
|
|
431
|
-
{/if}
|
|
451
|
+
{/if}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VarselManager.svelte.d.ts","sourceRoot":"","sources":["../src/lib/VarselManager.svelte.ts"],"names":[],"mappings":"AAWA,OAAO,EAGN,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,MAAM,aAAa,CAAC;AAEpB,KAAK,gBAAgB,GAAI;IACzB,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IACrB,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;CAC7B,CAAC;
|
|
1
|
+
{"version":3,"file":"VarselManager.svelte.d.ts","sourceRoot":"","sources":["../src/lib/VarselManager.svelte.ts"],"names":[],"mappings":"AAWA,OAAO,EAGN,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,MAAM,aAAa,CAAC;AAEpB,KAAK,gBAAgB,GAAI;IACzB,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IACrB,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;CAC7B,CAAC;AA4ZF,QAAA,MAAM,aAAa,sDAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
|
|
@@ -18,8 +18,9 @@ export {
|
|
|
18
18
|
* It subscribes to the global toast state and renders the `VarselManager`
|
|
19
19
|
* which handles the positioning and layout of individual toasts.
|
|
20
20
|
*
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
* Place this component once in your application's root layout (e.g., `+layout.svelte`).
|
|
22
|
+
*/
|
|
23
|
+
import { onMount } from 'svelte';
|
|
23
24
|
import VarselManager from './VarselManager.svelte';
|
|
24
25
|
import {
|
|
25
26
|
toastState,
|
|
@@ -63,25 +64,30 @@ export {
|
|
|
63
64
|
} = $props();
|
|
64
65
|
|
|
65
66
|
let toasts = $state<ToastData[]>([]);
|
|
66
|
-
|
|
67
|
+
let instanceId = $state<string | null>(null);
|
|
67
68
|
|
|
68
69
|
const handleRemove = (id: string) => {
|
|
69
70
|
toastState.remove(id);
|
|
70
71
|
};
|
|
71
72
|
|
|
72
|
-
|
|
73
|
+
onMount(() => {
|
|
74
|
+
const registeredInstanceId = toasterInstanceManager.registerInstance();
|
|
75
|
+
instanceId = registeredInstanceId;
|
|
73
76
|
toasts = toastState.getToasts();
|
|
74
77
|
const unsubscribe = toastState.subscribe((value) => {
|
|
75
78
|
toasts = value;
|
|
76
79
|
});
|
|
77
80
|
return () => {
|
|
78
81
|
unsubscribe();
|
|
79
|
-
toasterInstanceManager.unregisterInstance(
|
|
82
|
+
toasterInstanceManager.unregisterInstance(registeredInstanceId);
|
|
83
|
+
if (instanceId === registeredInstanceId) {
|
|
84
|
+
instanceId = null;
|
|
85
|
+
}
|
|
80
86
|
};
|
|
81
87
|
});
|
|
82
88
|
</script>
|
|
83
89
|
|
|
84
|
-
{#if toasterInstanceManager.isActiveInstance(instanceId)}
|
|
90
|
+
{#if instanceId && toasterInstanceManager.isActiveInstance(instanceId)}
|
|
85
91
|
<VarselManager
|
|
86
92
|
{toasts}
|
|
87
93
|
onRemove={handleRemove}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VarselToaster.svelte.d.ts","sourceRoot":"","sources":["../src/lib/VarselToaster.svelte.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,OAAO,EACN,KAAK,EACL,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,aAAa,GAClB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"VarselToaster.svelte.d.ts","sourceRoot":"","sources":["../src/lib/VarselToaster.svelte.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,OAAO,EACN,KAAK,EACL,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,aAAa,GAClB,MAAM,aAAa,CAAC;AAcrB,OAAO,EAIL,KAAK,aAAa,EAClB,MAAM,aAAa,CAAC;AAErB,KAAK,gBAAgB,GAAI;IACxB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mCAAmC;IACnC,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,qDAAqD;IACrD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2CAA2C;IAC3C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,kCAAkC;IAClC,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;CAC7B,CAAC;AAmDH,QAAA,MAAM,aAAa,sDAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toast-factory.d.ts","sourceRoot":"","sources":["../../src/lib/core/toast-factory.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAGX,YAAY,EAEZ,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"toast-factory.d.ts","sourceRoot":"","sources":["../../src/lib/core/toast-factory.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAGX,YAAY,EAEZ,MAAM,SAAS,CAAC;AAuLjB,eAAO,MAAM,KAAK,cAAc,CAAC"}
|
|
@@ -15,6 +15,15 @@ const resolvePromiseState = async (value, state) => {
|
|
|
15
15
|
const resolvedValue = typeof state === "function" ? await state(value) : await state;
|
|
16
16
|
return normalizeToastData(resolvedValue);
|
|
17
17
|
};
|
|
18
|
+
const getPromiseFallbackDescription = (error) => {
|
|
19
|
+
if (error instanceof Error) {
|
|
20
|
+
return error.message;
|
|
21
|
+
}
|
|
22
|
+
if (typeof error === "string") {
|
|
23
|
+
return error;
|
|
24
|
+
}
|
|
25
|
+
return "An unknown error occurred while updating the notification.";
|
|
26
|
+
};
|
|
18
27
|
/**
|
|
19
28
|
* The main entry point for creating toasts.
|
|
20
29
|
* @param data - Toast configuration object or description string.
|
|
@@ -86,7 +95,7 @@ createToast.promise = (promise, options) => {
|
|
|
86
95
|
...loadingData,
|
|
87
96
|
duration: loadingData.duration ?? 0,
|
|
88
97
|
isLoading: true,
|
|
89
|
-
showClose: loadingData.showClose ??
|
|
98
|
+
showClose: loadingData.showClose ?? true,
|
|
90
99
|
});
|
|
91
100
|
const handleResult = async (state, value, defaultVariant) => {
|
|
92
101
|
const payload = await resolvePromiseState(value, state);
|
|
@@ -95,16 +104,28 @@ createToast.promise = (promise, options) => {
|
|
|
95
104
|
isLoading: false,
|
|
96
105
|
duration: payload.duration,
|
|
97
106
|
variant: payload.variant ?? defaultVariant,
|
|
98
|
-
showClose: payload.showClose ??
|
|
107
|
+
showClose: payload.showClose ?? true,
|
|
108
|
+
});
|
|
109
|
+
};
|
|
110
|
+
const applyPromiseFallback = (error) => {
|
|
111
|
+
toastState.update(toastId, {
|
|
112
|
+
title: "Operation failed",
|
|
113
|
+
description: getPromiseFallbackDescription(error),
|
|
114
|
+
variant: "destructive",
|
|
115
|
+
isLoading: false,
|
|
116
|
+
showClose: true,
|
|
117
|
+
duration: 5000,
|
|
99
118
|
});
|
|
100
119
|
};
|
|
101
|
-
Promise.resolve(promise)
|
|
102
|
-
.then(
|
|
103
|
-
|
|
104
|
-
|
|
120
|
+
void Promise.resolve(promise)
|
|
121
|
+
.then((value) => {
|
|
122
|
+
return handleResult(options.success, value, "success");
|
|
123
|
+
})
|
|
124
|
+
.catch((error) => {
|
|
125
|
+
return handleResult(options.error, error, "destructive");
|
|
105
126
|
})
|
|
106
|
-
.catch(
|
|
107
|
-
|
|
127
|
+
.catch((error) => {
|
|
128
|
+
applyPromiseFallback(error);
|
|
108
129
|
});
|
|
109
130
|
return toastId;
|
|
110
131
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toaster-instances.d.ts","sourceRoot":"","sources":["../../src/lib/core/toaster-instances.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAM,sBAAsB;IAC3B,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,eAAe,CAAK;
|
|
1
|
+
{"version":3,"file":"toaster-instances.d.ts","sourceRoot":"","sources":["../../src/lib/core/toaster-instances.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAM,sBAAsB;IAC3B,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,WAAW,CAAgB;IAEnC;;;OAGG;IACH,gBAAgB,IAAI,MAAM;IAY1B;;;OAGG;IACH,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAY5C;;;;OAIG;IACH,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;CAG7C;AAED,eAAO,MAAM,sBAAsB,wBAA+B,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
|
|
@@ -5,13 +5,16 @@
|
|
|
5
5
|
class ToasterInstanceManager {
|
|
6
6
|
activeInstanceId = null;
|
|
7
7
|
instanceCounter = 0;
|
|
8
|
+
instanceIds = [];
|
|
8
9
|
/**
|
|
9
10
|
* Registers a new toaster instance.
|
|
10
11
|
* @returns A unique instance ID.
|
|
11
12
|
*/
|
|
12
13
|
registerInstance() {
|
|
13
14
|
const instanceId = `toaster-${++this.instanceCounter}`;
|
|
14
|
-
|
|
15
|
+
this.instanceIds.push(instanceId);
|
|
16
|
+
if (!this.activeInstanceId ||
|
|
17
|
+
!this.instanceIds.includes(this.activeInstanceId)) {
|
|
15
18
|
this.activeInstanceId = instanceId;
|
|
16
19
|
}
|
|
17
20
|
return instanceId;
|
|
@@ -21,8 +24,13 @@ class ToasterInstanceManager {
|
|
|
21
24
|
* @param instanceId - The ID of the instance to unregister.
|
|
22
25
|
*/
|
|
23
26
|
unregisterInstance(instanceId) {
|
|
27
|
+
this.instanceIds = this.instanceIds.filter((id) => id !== instanceId);
|
|
24
28
|
if (this.activeInstanceId === instanceId) {
|
|
25
|
-
this.activeInstanceId = null;
|
|
29
|
+
this.activeInstanceId = this.instanceIds[0] ?? null;
|
|
30
|
+
}
|
|
31
|
+
else if (this.activeInstanceId &&
|
|
32
|
+
!this.instanceIds.includes(this.activeInstanceId)) {
|
|
33
|
+
this.activeInstanceId = this.instanceIds[0] ?? null;
|
|
26
34
|
}
|
|
27
35
|
}
|
|
28
36
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "varsel",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"description": "Headless yet opinionated toast notifications for Svelte apps.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"build": "bun run build:css && svelte-package",
|
|
42
42
|
"check": "svelte-check --tsconfig ./tsconfig.json",
|
|
43
43
|
"dev": "bun run build:css:watch & svelte-package --watch",
|
|
44
|
+
"test": "vitest run",
|
|
44
45
|
"lint": "tsc -p tsconfig.json --noEmit",
|
|
45
46
|
"prepublishOnly": "bun run build"
|
|
46
47
|
},
|