varsel 0.5.0 → 0.5.1
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/package.json +1 -1
- package/dist/VarselItem.svelte +0 -900
- package/dist/VarselItem.svelte.d.ts +0 -23
- package/dist/VarselItem.svelte.d.ts.map +0 -1
- package/dist/VarselManager.svelte +0 -431
- package/dist/VarselManager.svelte.d.ts +0 -18
- package/dist/VarselManager.svelte.d.ts.map +0 -1
- package/dist/VarselToaster.svelte +0 -98
- package/dist/VarselToaster.svelte.d.ts +0 -32
- package/dist/VarselToaster.svelte.d.ts.map +0 -1
- package/dist/core/accessibility.d.ts +0 -6
- package/dist/core/accessibility.d.ts.map +0 -1
- package/dist/core/accessibility.js +0 -12
- package/dist/core/animations.d.ts +0 -29
- package/dist/core/animations.d.ts.map +0 -1
- package/dist/core/animations.js +0 -28
- package/dist/core/positions.d.ts +0 -71
- package/dist/core/positions.d.ts.map +0 -1
- package/dist/core/positions.js +0 -30
- package/dist/core/swipe.d.ts +0 -20
- package/dist/core/swipe.d.ts.map +0 -1
- package/dist/core/swipe.js +0 -30
- package/dist/core/toast-factory.d.ts +0 -3
- package/dist/core/toast-factory.d.ts.map +0 -1
- package/dist/core/toast-factory.js +0 -123
- package/dist/core/toast-state.d.ts +0 -49
- package/dist/core/toast-state.d.ts.map +0 -1
- package/dist/core/toast-state.js +0 -80
- package/dist/core/toaster-instances.d.ts +0 -27
- package/dist/core/toaster-instances.d.ts.map +0 -1
- package/dist/core/toaster-instances.js +0 -38
- package/dist/core/types.d.ts +0 -144
- package/dist/core/types.d.ts.map +0 -1
- package/dist/core/types.js +0 -1
- package/dist/core/utils.d.ts +0 -10
- package/dist/core/utils.d.ts.map +0 -1
- package/dist/core/utils.js +0 -9
- package/dist/core/variants.d.ts +0 -18
- package/dist/core/variants.d.ts.map +0 -1
- package/dist/core/variants.js +0 -56
- package/dist/index.d.ts +0 -10
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -8
- package/dist/internals.d.ts +0 -16
- package/dist/internals.d.ts.map +0 -1
- package/dist/internals.js +0 -14
- package/dist/styles.css +0 -195
- package/dist/variant-icons.d.ts +0 -108
- package/dist/variant-icons.d.ts.map +0 -1
- package/dist/variant-icons.js +0 -45
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { type PositionedToast } from "./internals";
|
|
2
|
-
type $$ComponentProps = {
|
|
3
|
-
toast: PositionedToast;
|
|
4
|
-
onRemove: (id: string) => void;
|
|
5
|
-
isGroupHovered?: boolean;
|
|
6
|
-
expandedOffset?: number;
|
|
7
|
-
expandedGap?: number;
|
|
8
|
-
collapsedOffset?: number;
|
|
9
|
-
hiddenCollapsedOffset?: number;
|
|
10
|
-
onHeightChange?: (id: string, height: number) => void;
|
|
11
|
-
onGroupHoverEnter?: () => void;
|
|
12
|
-
onGroupHoldChange?: (holding: boolean) => void;
|
|
13
|
-
defaultDuration?: number;
|
|
14
|
-
defaultShowClose?: boolean;
|
|
15
|
-
pauseOnHover?: boolean;
|
|
16
|
-
offset?: number | string;
|
|
17
|
-
expand?: boolean;
|
|
18
|
-
visibleToasts?: number;
|
|
19
|
-
};
|
|
20
|
-
declare const VarselItem: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
21
|
-
type VarselItem = ReturnType<typeof VarselItem>;
|
|
22
|
-
export default VarselItem;
|
|
23
|
-
//# sourceMappingURL=VarselItem.svelte.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"VarselItem.svelte.d.ts","sourceRoot":"","sources":["../src/lib/VarselItem.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,EAYN,KAAK,eAAe,EAIpB,MAAM,aAAa,CAAC;AAUpB,KAAK,gBAAgB,GAAI;IACzB,KAAK,EAAE,eAAe,CAAC;IACvB,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,cAAc,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACtD,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAywBF,QAAA,MAAM,UAAU,sDAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
|
|
@@ -1,431 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
/**
|
|
3
|
-
* @component
|
|
4
|
-
* @description
|
|
5
|
-
* Internal component responsible for grouping toasts by position and calculating
|
|
6
|
-
* their stacking offsets (both collapsed and expanded).
|
|
7
|
-
* It handles the "hover to expand" logic and manages the lifecycle of toast groups.
|
|
8
|
-
*/
|
|
9
|
-
import VarselItem from "./VarselItem.svelte";
|
|
10
|
-
import {
|
|
11
|
-
ANIMATION_CONFIG,
|
|
12
|
-
type PositionedToast,
|
|
13
|
-
type ToastData,
|
|
14
|
-
type ToastPosition,
|
|
15
|
-
} from "./internals";
|
|
16
|
-
|
|
17
|
-
let {
|
|
18
|
-
toasts = [],
|
|
19
|
-
onRemove,
|
|
20
|
-
expandedGap = ANIMATION_CONFIG.EXPANDED_GAP,
|
|
21
|
-
position: defaultPosition = 'bottom-center',
|
|
22
|
-
visibleToasts = 3,
|
|
23
|
-
expand = true,
|
|
24
|
-
duration = 5000,
|
|
25
|
-
closeButton = true,
|
|
26
|
-
pauseOnHover = true,
|
|
27
|
-
offset = undefined,
|
|
28
|
-
dir = 'auto'
|
|
29
|
-
}: {
|
|
30
|
-
toasts?: ToastData[];
|
|
31
|
-
onRemove: (id: string) => void;
|
|
32
|
-
expandedGap?: number;
|
|
33
|
-
position?: ToastPosition;
|
|
34
|
-
visibleToasts?: number;
|
|
35
|
-
expand?: boolean;
|
|
36
|
-
duration?: number;
|
|
37
|
-
closeButton?: boolean;
|
|
38
|
-
pauseOnHover?: boolean;
|
|
39
|
-
offset?: number | string;
|
|
40
|
-
dir?: 'ltr' | 'rtl' | 'auto';
|
|
41
|
-
} = $props();
|
|
42
|
-
|
|
43
|
-
const createPositionMap = <T>(value: () => T): Record<ToastPosition, T> => ({
|
|
44
|
-
"top-left": value(),
|
|
45
|
-
"top-center": value(),
|
|
46
|
-
"top-right": value(),
|
|
47
|
-
"bottom-left": value(),
|
|
48
|
-
"bottom-center": value(),
|
|
49
|
-
"bottom-right": value(),
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
let heights = $state<Record<string, number>>({});
|
|
53
|
-
let hovered = $state<Record<ToastPosition, boolean>>(
|
|
54
|
-
createPositionMap(() => false),
|
|
55
|
-
);
|
|
56
|
-
let heldToasts = $state<Record<ToastPosition, Set<string>>>(
|
|
57
|
-
createPositionMap(() => new Set<string>()),
|
|
58
|
-
);
|
|
59
|
-
|
|
60
|
-
// Non-reactive internal state for "previous" values (mimicking legacy behavior)
|
|
61
|
-
let previousStackIndex: Record<string, number> = {};
|
|
62
|
-
let previousCollapsedOffsets: Record<string, number> = {};
|
|
63
|
-
let previousExpandedOffsets: Record<string, number> = {};
|
|
64
|
-
|
|
65
|
-
let toastsByPosition = $state<Record<ToastPosition, PositionedToast[]>>(
|
|
66
|
-
createPositionMap<PositionedToast[]>(() => []),
|
|
67
|
-
);
|
|
68
|
-
|
|
69
|
-
let collapsedOffsetData = $state<{
|
|
70
|
-
byPosition: Record<ToastPosition, number[]>;
|
|
71
|
-
byId: Record<string, number>;
|
|
72
|
-
}>({ byPosition: createPositionMap<number[]>(() => []), byId: {} });
|
|
73
|
-
|
|
74
|
-
let expandedOffsetData = $state<{
|
|
75
|
-
byPosition: Record<ToastPosition, number[]>;
|
|
76
|
-
byId: Record<string, number>;
|
|
77
|
-
}>({ byPosition: createPositionMap<number[]>(() => []), byId: {} });
|
|
78
|
-
|
|
79
|
-
let positionEntries = $derived(
|
|
80
|
-
Object.entries(toastsByPosition) as [ToastPosition, PositionedToast[]][],
|
|
81
|
-
);
|
|
82
|
-
let latestPositionEntries = $derived(positionEntries);
|
|
83
|
-
let latestHovered = $derived(hovered);
|
|
84
|
-
|
|
85
|
-
const updateHoldState = (
|
|
86
|
-
position: ToastPosition,
|
|
87
|
-
toastId: string,
|
|
88
|
-
isHolding: boolean,
|
|
89
|
-
) => {
|
|
90
|
-
const current = heldToasts[position] ?? new Set<string>();
|
|
91
|
-
const next = new Set(current);
|
|
92
|
-
if (isHolding) {
|
|
93
|
-
next.add(toastId);
|
|
94
|
-
} else {
|
|
95
|
-
next.delete(toastId);
|
|
96
|
-
}
|
|
97
|
-
if (next.size !== current.size) {
|
|
98
|
-
heldToasts = { ...heldToasts, [position]: next };
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
// Calculate toastsByPosition based on toasts
|
|
103
|
-
$effect(() => {
|
|
104
|
-
const grouped = createPositionMap<ToastData[]>(() => []);
|
|
105
|
-
for (const toast of toasts) {
|
|
106
|
-
const pos = toast.position || defaultPosition;
|
|
107
|
-
grouped[pos].push(toast);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const nextStackIndices: Record<string, number> = {};
|
|
111
|
-
const positioned = createPositionMap<PositionedToast[]>(() => []);
|
|
112
|
-
|
|
113
|
-
for (const position of Object.keys(grouped) as ToastPosition[]) {
|
|
114
|
-
const list = grouped[position];
|
|
115
|
-
const activeToasts = list.filter(
|
|
116
|
-
(toast) => !toast.isLeaving && !toast.shouldClose,
|
|
117
|
-
);
|
|
118
|
-
const activeIndexMap = new Map<string, number>();
|
|
119
|
-
activeToasts.forEach((toast, activeIndex) => {
|
|
120
|
-
activeIndexMap.set(toast.id, activeIndex);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
positioned[position] = list.map((toast, orderIndex) => {
|
|
124
|
-
let stackIndex =
|
|
125
|
-
activeIndexMap.get(toast.id) ?? previousStackIndex[toast.id];
|
|
126
|
-
if (stackIndex == null || Number.isNaN(stackIndex)) {
|
|
127
|
-
stackIndex = orderIndex;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
nextStackIndices[toast.id] = stackIndex;
|
|
131
|
-
|
|
132
|
-
return {
|
|
133
|
-
...toast,
|
|
134
|
-
position: position,
|
|
135
|
-
index: stackIndex,
|
|
136
|
-
renderIndex: orderIndex,
|
|
137
|
-
total: list.length,
|
|
138
|
-
};
|
|
139
|
-
}) as PositionedToast[];
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
previousStackIndex = nextStackIndices;
|
|
143
|
-
toastsByPosition = positioned;
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
// Update hovered state based on empty groups
|
|
147
|
-
$effect(() => {
|
|
148
|
-
const next = { ...hovered };
|
|
149
|
-
let changed = false;
|
|
150
|
-
for (const pos of Object.keys(hovered) as ToastPosition[]) {
|
|
151
|
-
const hasToast = (toastsByPosition[pos]?.length ?? 0) > 0;
|
|
152
|
-
if (!hasToast && next[pos]) {
|
|
153
|
-
next[pos] = false;
|
|
154
|
-
changed = true;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
if (changed) {
|
|
158
|
-
hovered = next;
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
// Calculate collapsedOffsetData
|
|
163
|
-
$effect(() => {
|
|
164
|
-
const byPosition = createPositionMap<number[]>(() => []);
|
|
165
|
-
const byId: Record<string, number> = {};
|
|
166
|
-
|
|
167
|
-
for (const [pos, group] of positionEntries) {
|
|
168
|
-
const isTopPosition = pos.startsWith("top-");
|
|
169
|
-
const activeToasts = group.filter((toast) => !toast.shouldClose);
|
|
170
|
-
const offsetsForActive: number[] = [];
|
|
171
|
-
|
|
172
|
-
for (let i = 0; i < activeToasts.length; i++) {
|
|
173
|
-
if (i === 0) {
|
|
174
|
-
offsetsForActive.push(0);
|
|
175
|
-
continue;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
const prevToast = activeToasts[i - 1];
|
|
179
|
-
const currentToast = activeToasts[i];
|
|
180
|
-
const prevOffset = offsetsForActive[i - 1] ?? 0;
|
|
181
|
-
if (!prevToast || !currentToast) {
|
|
182
|
-
offsetsForActive.push(prevOffset);
|
|
183
|
-
continue;
|
|
184
|
-
}
|
|
185
|
-
const prevHeight = heights[prevToast.id];
|
|
186
|
-
const currentHeight = heights[currentToast.id];
|
|
187
|
-
const fallbackOffset =
|
|
188
|
-
prevOffset + (isTopPosition ? 1 : -1) * ANIMATION_CONFIG.STACK_OFFSET;
|
|
189
|
-
|
|
190
|
-
if (
|
|
191
|
-
prevHeight == null ||
|
|
192
|
-
currentHeight == null ||
|
|
193
|
-
Number.isNaN(prevHeight) ||
|
|
194
|
-
Number.isNaN(currentHeight)
|
|
195
|
-
) {
|
|
196
|
-
offsetsForActive.push(fallbackOffset);
|
|
197
|
-
continue;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if (isTopPosition) {
|
|
201
|
-
offsetsForActive.push(
|
|
202
|
-
prevOffset +
|
|
203
|
-
(prevHeight - currentHeight + ANIMATION_CONFIG.STACK_OFFSET),
|
|
204
|
-
);
|
|
205
|
-
} else {
|
|
206
|
-
offsetsForActive.push(
|
|
207
|
-
prevOffset +
|
|
208
|
-
(currentHeight - prevHeight - ANIMATION_CONFIG.STACK_OFFSET),
|
|
209
|
-
);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
for (let i = 0; i < activeToasts.length; i++) {
|
|
214
|
-
const toast = activeToasts[i];
|
|
215
|
-
if (!toast) continue;
|
|
216
|
-
byId[toast.id] = offsetsForActive[i] ?? 0;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
for (const toast of group) {
|
|
220
|
-
if (byId[toast.id] != null) continue;
|
|
221
|
-
const previousOffset = previousCollapsedOffsets[toast.id];
|
|
222
|
-
if (typeof previousOffset === "number") {
|
|
223
|
-
byId[toast.id] = previousOffset;
|
|
224
|
-
continue;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
const defaultOffset = isTopPosition
|
|
228
|
-
? toast.index * ANIMATION_CONFIG.STACK_OFFSET
|
|
229
|
-
: -(toast.index * ANIMATION_CONFIG.STACK_OFFSET);
|
|
230
|
-
byId[toast.id] = defaultOffset;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
byPosition[pos] = group.map((toast) => byId[toast.id] ?? 0);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
previousCollapsedOffsets = byId;
|
|
237
|
-
collapsedOffsetData = { byPosition, byId };
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
// Calculate expandedOffsetData
|
|
241
|
-
$effect(() => {
|
|
242
|
-
const byPosition = createPositionMap<number[]>(() => []);
|
|
243
|
-
const byId: Record<string, number> = {};
|
|
244
|
-
|
|
245
|
-
for (const [pos, group] of positionEntries) {
|
|
246
|
-
const offsets: number[] = [];
|
|
247
|
-
const activeToasts = group.filter((toast) => !toast.shouldClose);
|
|
248
|
-
let acc = 0;
|
|
249
|
-
|
|
250
|
-
for (let i = 0; i < activeToasts.length; i++) {
|
|
251
|
-
if (i === 0) {
|
|
252
|
-
offsets.push(0);
|
|
253
|
-
continue;
|
|
254
|
-
}
|
|
255
|
-
const prevToast = activeToasts[i - 1];
|
|
256
|
-
const prevHeight = prevToast ? (heights[prevToast.id] ?? 0) : 0;
|
|
257
|
-
acc += prevHeight + expandedGap;
|
|
258
|
-
offsets.push(acc);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
for (let i = 0; i < activeToasts.length; i++) {
|
|
262
|
-
const toast = activeToasts[i];
|
|
263
|
-
if (!toast) continue;
|
|
264
|
-
byId[toast.id] = offsets[i] ?? 0;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
for (const toast of group) {
|
|
268
|
-
if (byId[toast.id] != null) continue;
|
|
269
|
-
|
|
270
|
-
const previousOffset = previousExpandedOffsets[toast.id];
|
|
271
|
-
if (typeof previousOffset === "number") {
|
|
272
|
-
byId[toast.id] = previousOffset;
|
|
273
|
-
continue;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
let fallback = 0;
|
|
277
|
-
for (const candidate of group) {
|
|
278
|
-
if (candidate.id === toast.id) break;
|
|
279
|
-
const height = heights[candidate.id] ?? 0;
|
|
280
|
-
fallback += height + expandedGap;
|
|
281
|
-
}
|
|
282
|
-
byId[toast.id] = fallback;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
byPosition[pos] = group.map((toast) => byId[toast.id] ?? 0);
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
previousExpandedOffsets = byId;
|
|
289
|
-
expandedOffsetData = { byPosition, byId };
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
$effect(() => {
|
|
293
|
-
const handleMouseMove = (event: MouseEvent) => {
|
|
294
|
-
if (latestPositionEntries.length === 0) return;
|
|
295
|
-
const { clientX: x, clientY: y } = event;
|
|
296
|
-
const next: Record<ToastPosition, boolean> = {
|
|
297
|
-
...latestHovered,
|
|
298
|
-
};
|
|
299
|
-
for (const [pos, group] of latestPositionEntries) {
|
|
300
|
-
let top = Number.POSITIVE_INFINITY;
|
|
301
|
-
let left = Number.POSITIVE_INFINITY;
|
|
302
|
-
let right = Number.NEGATIVE_INFINITY;
|
|
303
|
-
let bottom = Number.NEGATIVE_INFINITY;
|
|
304
|
-
let any = false;
|
|
305
|
-
for (const t of group) {
|
|
306
|
-
if (t.index >= visibleToasts) continue;
|
|
307
|
-
const el = document.querySelector(
|
|
308
|
-
`[data-toast-id="${t.id}"]`,
|
|
309
|
-
) as HTMLElement | null;
|
|
310
|
-
if (!el) continue;
|
|
311
|
-
const rect = el.getBoundingClientRect();
|
|
312
|
-
top = Math.min(top, rect.top);
|
|
313
|
-
left = Math.min(left, rect.left);
|
|
314
|
-
right = Math.max(right, rect.right);
|
|
315
|
-
bottom = Math.max(bottom, rect.bottom);
|
|
316
|
-
any = true;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
if (!any) {
|
|
320
|
-
next[pos] = false;
|
|
321
|
-
continue;
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
const inside = x >= left && x <= right && y >= top && y <= bottom;
|
|
325
|
-
next[pos] = inside;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
const changed = (Object.keys(next) as ToastPosition[]).some(
|
|
329
|
-
(key) => next[key] !== hovered[key],
|
|
330
|
-
);
|
|
331
|
-
if (changed) {
|
|
332
|
-
hovered = next;
|
|
333
|
-
}
|
|
334
|
-
};
|
|
335
|
-
|
|
336
|
-
const handleKeyDown = (event: KeyboardEvent) => {
|
|
337
|
-
if (event.key !== "Escape") return;
|
|
338
|
-
for (const [, group] of latestPositionEntries) {
|
|
339
|
-
const latestToast = group?.[0];
|
|
340
|
-
if (!latestToast) continue;
|
|
341
|
-
const container = document.querySelector(
|
|
342
|
-
`[data-toast-id="${latestToast.id}"]`,
|
|
343
|
-
) as HTMLElement | null;
|
|
344
|
-
if (!container) continue;
|
|
345
|
-
const active = document.activeElement as HTMLElement | null;
|
|
346
|
-
if (active && container.contains(active)) {
|
|
347
|
-
const closeBtn = container.querySelector(
|
|
348
|
-
'[aria-label="Close toast"]',
|
|
349
|
-
) as HTMLButtonElement | null;
|
|
350
|
-
if (closeBtn) {
|
|
351
|
-
event.preventDefault();
|
|
352
|
-
closeBtn.click();
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
};
|
|
357
|
-
|
|
358
|
-
document.addEventListener("mousemove", handleMouseMove);
|
|
359
|
-
document.addEventListener("keydown", handleKeyDown);
|
|
360
|
-
return () => {
|
|
361
|
-
document.removeEventListener("mousemove", handleMouseMove);
|
|
362
|
-
document.removeEventListener("keydown", handleKeyDown);
|
|
363
|
-
};
|
|
364
|
-
});
|
|
365
|
-
|
|
366
|
-
const handleHeightChange = (id: string, height: number) => {
|
|
367
|
-
if (heights[id] === height) return;
|
|
368
|
-
heights = { ...heights, [id]: height };
|
|
369
|
-
};
|
|
370
|
-
</script>
|
|
371
|
-
|
|
372
|
-
{#if toasts.length > 0}
|
|
373
|
-
<div
|
|
374
|
-
class="pointer-events-none fixed inset-0 z-50"
|
|
375
|
-
{dir}
|
|
376
|
-
>
|
|
377
|
-
{#each positionEntries as [position, positionToasts]}
|
|
378
|
-
{@const pos = position}
|
|
379
|
-
{@const expandedOffsets = expandedOffsetData.byPosition[pos]}
|
|
380
|
-
{@const collapsedOffsets = collapsedOffsetData.byPosition[pos]}
|
|
381
|
-
{@const isHovered = hovered[pos]}
|
|
382
|
-
{@const isHeld = (heldToasts[pos]?.size ?? 0) > 0}
|
|
383
|
-
{@const isGroupActive = isHovered || isHeld}
|
|
384
|
-
{@const activeToasts = positionToasts.filter((toast) => !toast.shouldClose)}
|
|
385
|
-
{@const visibleStackLimit = Math.max(visibleToasts - 1, 0)}
|
|
386
|
-
{@const maxVisibleStackIndex = Math.min(
|
|
387
|
-
Math.max(activeToasts.length - 1, 0),
|
|
388
|
-
visibleStackLimit,
|
|
389
|
-
)}
|
|
390
|
-
{@const lastVisibleToastId = activeToasts[maxVisibleStackIndex]?.id}
|
|
391
|
-
{@const lastVisibleRenderIndex = lastVisibleToastId != null
|
|
392
|
-
? positionToasts.findIndex(
|
|
393
|
-
(candidate) => candidate.id === lastVisibleToastId,
|
|
394
|
-
)
|
|
395
|
-
: -1}
|
|
396
|
-
{@const sharedHiddenCollapsedOffset =
|
|
397
|
-
lastVisibleRenderIndex >= 0
|
|
398
|
-
? collapsedOffsets?.[lastVisibleRenderIndex]
|
|
399
|
-
: undefined}
|
|
400
|
-
{#each positionToasts as toast, idx (toast.id)}
|
|
401
|
-
{@const toastIsHidden =
|
|
402
|
-
toast.index >= visibleToasts}
|
|
403
|
-
{@const hiddenCollapsedOffset = toastIsHidden
|
|
404
|
-
? sharedHiddenCollapsedOffset ?? collapsedOffsets?.[idx]
|
|
405
|
-
: collapsedOffsets?.[idx]}
|
|
406
|
-
{@const collapsedOffsetValue = collapsedOffsets?.[idx]}
|
|
407
|
-
<VarselItem
|
|
408
|
-
{toast}
|
|
409
|
-
{onRemove}
|
|
410
|
-
isGroupHovered={isGroupActive}
|
|
411
|
-
expandedOffset={expandedOffsets?.[idx] ?? 0}
|
|
412
|
-
{expandedGap}
|
|
413
|
-
onHeightChange={handleHeightChange}
|
|
414
|
-
onGroupHoverEnter={() => {
|
|
415
|
-
hovered = { ...hovered, [pos]: true };
|
|
416
|
-
}}
|
|
417
|
-
onGroupHoldChange={(holding) =>
|
|
418
|
-
updateHoldState(pos, toast.id, holding)}
|
|
419
|
-
collapsedOffset={collapsedOffsetValue}
|
|
420
|
-
hiddenCollapsedOffset={hiddenCollapsedOffset}
|
|
421
|
-
defaultDuration={duration}
|
|
422
|
-
defaultShowClose={closeButton}
|
|
423
|
-
{pauseOnHover}
|
|
424
|
-
{offset}
|
|
425
|
-
{expand}
|
|
426
|
-
{visibleToasts}
|
|
427
|
-
/>
|
|
428
|
-
{/each}
|
|
429
|
-
{/each}
|
|
430
|
-
</div>
|
|
431
|
-
{/if}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { type ToastData, type ToastPosition } from "./internals";
|
|
2
|
-
type $$ComponentProps = {
|
|
3
|
-
toasts?: ToastData[];
|
|
4
|
-
onRemove: (id: string) => void;
|
|
5
|
-
expandedGap?: number;
|
|
6
|
-
position?: ToastPosition;
|
|
7
|
-
visibleToasts?: number;
|
|
8
|
-
expand?: boolean;
|
|
9
|
-
duration?: number;
|
|
10
|
-
closeButton?: boolean;
|
|
11
|
-
pauseOnHover?: boolean;
|
|
12
|
-
offset?: number | string;
|
|
13
|
-
dir?: 'ltr' | 'rtl' | 'auto';
|
|
14
|
-
};
|
|
15
|
-
declare const VarselManager: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
16
|
-
type VarselManager = ReturnType<typeof VarselManager>;
|
|
17
|
-
export default VarselManager;
|
|
18
|
-
//# sourceMappingURL=VarselManager.svelte.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
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;AAuYF,QAAA,MAAM,aAAa,sDAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
<script lang="ts" module>
|
|
2
|
-
/**
|
|
3
|
-
* Main module exports for the Varsel library.
|
|
4
|
-
*/
|
|
5
|
-
export {
|
|
6
|
-
toast,
|
|
7
|
-
type ToastData,
|
|
8
|
-
type ToastInvoker,
|
|
9
|
-
type ToastPosition,
|
|
10
|
-
} from "./internals";
|
|
11
|
-
</script>
|
|
12
|
-
|
|
13
|
-
<script lang="ts">
|
|
14
|
-
/**
|
|
15
|
-
* @component
|
|
16
|
-
* @description
|
|
17
|
-
* The root component for the Varsel notification system.
|
|
18
|
-
* It subscribes to the global toast state and renders the `VarselManager`
|
|
19
|
-
* which handles the positioning and layout of individual toasts.
|
|
20
|
-
*
|
|
21
|
-
* Place this component once in your application's root layout (e.g., `+layout.svelte`).
|
|
22
|
-
*/
|
|
23
|
-
import VarselManager from './VarselManager.svelte';
|
|
24
|
-
import {
|
|
25
|
-
toastState,
|
|
26
|
-
toasterInstanceManager,
|
|
27
|
-
type ToastData,
|
|
28
|
-
type ToastPosition,
|
|
29
|
-
} from './internals';
|
|
30
|
-
|
|
31
|
-
let {
|
|
32
|
-
expandedGap = undefined,
|
|
33
|
-
position = 'bottom-center',
|
|
34
|
-
visibleToasts = 3,
|
|
35
|
-
expand = true,
|
|
36
|
-
duration = 5000,
|
|
37
|
-
closeButton = true,
|
|
38
|
-
pauseOnHover = true,
|
|
39
|
-
offset = undefined,
|
|
40
|
-
dir = 'auto'
|
|
41
|
-
}: {
|
|
42
|
-
/**
|
|
43
|
-
* The gap (in pixels) between expanded toasts when hovering over the stack.
|
|
44
|
-
* If undefined, uses the default value from animation config.
|
|
45
|
-
*/
|
|
46
|
-
expandedGap?: number;
|
|
47
|
-
/** Default position for toasts. */
|
|
48
|
-
position?: ToastPosition;
|
|
49
|
-
/** Maximum number of visible toasts in the stack. */
|
|
50
|
-
visibleToasts?: number;
|
|
51
|
-
/** Whether to expand the stack on hover. */
|
|
52
|
-
expand?: boolean;
|
|
53
|
-
/** Default duration in milliseconds. */
|
|
54
|
-
duration?: number;
|
|
55
|
-
/** Whether to show the close button by default. */
|
|
56
|
-
closeButton?: boolean;
|
|
57
|
-
/** Whether to pause the timer on hover. */
|
|
58
|
-
pauseOnHover?: boolean;
|
|
59
|
-
/** Offset from the edge of the screen. */
|
|
60
|
-
offset?: number | string;
|
|
61
|
-
/** Directionality of the text. */
|
|
62
|
-
dir?: 'ltr' | 'rtl' | 'auto';
|
|
63
|
-
} = $props();
|
|
64
|
-
|
|
65
|
-
let toasts = $state<ToastData[]>([]);
|
|
66
|
-
const instanceId = toasterInstanceManager.registerInstance();
|
|
67
|
-
|
|
68
|
-
const handleRemove = (id: string) => {
|
|
69
|
-
toastState.remove(id);
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
$effect(() => {
|
|
73
|
-
toasts = toastState.getToasts();
|
|
74
|
-
const unsubscribe = toastState.subscribe((value) => {
|
|
75
|
-
toasts = value;
|
|
76
|
-
});
|
|
77
|
-
return () => {
|
|
78
|
-
unsubscribe();
|
|
79
|
-
toasterInstanceManager.unregisterInstance(instanceId);
|
|
80
|
-
};
|
|
81
|
-
});
|
|
82
|
-
</script>
|
|
83
|
-
|
|
84
|
-
{#if toasterInstanceManager.isActiveInstance(instanceId)}
|
|
85
|
-
<VarselManager
|
|
86
|
-
{toasts}
|
|
87
|
-
onRemove={handleRemove}
|
|
88
|
-
{expandedGap}
|
|
89
|
-
{position}
|
|
90
|
-
{visibleToasts}
|
|
91
|
-
{expand}
|
|
92
|
-
{duration}
|
|
93
|
-
{closeButton}
|
|
94
|
-
{pauseOnHover}
|
|
95
|
-
{offset}
|
|
96
|
-
{dir}
|
|
97
|
-
/>
|
|
98
|
-
{/if}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Main module exports for the Varsel library.
|
|
3
|
-
*/
|
|
4
|
-
export { toast, type ToastData, type ToastInvoker, type ToastPosition, } from "./internals";
|
|
5
|
-
import { type ToastPosition } from './internals';
|
|
6
|
-
type $$ComponentProps = {
|
|
7
|
-
/**
|
|
8
|
-
* The gap (in pixels) between expanded toasts when hovering over the stack.
|
|
9
|
-
* If undefined, uses the default value from animation config.
|
|
10
|
-
*/
|
|
11
|
-
expandedGap?: number;
|
|
12
|
-
/** Default position for toasts. */
|
|
13
|
-
position?: ToastPosition;
|
|
14
|
-
/** Maximum number of visible toasts in the stack. */
|
|
15
|
-
visibleToasts?: number;
|
|
16
|
-
/** Whether to expand the stack on hover. */
|
|
17
|
-
expand?: boolean;
|
|
18
|
-
/** Default duration in milliseconds. */
|
|
19
|
-
duration?: number;
|
|
20
|
-
/** Whether to show the close button by default. */
|
|
21
|
-
closeButton?: boolean;
|
|
22
|
-
/** Whether to pause the timer on hover. */
|
|
23
|
-
pauseOnHover?: boolean;
|
|
24
|
-
/** Offset from the edge of the screen. */
|
|
25
|
-
offset?: number | string;
|
|
26
|
-
/** Directionality of the text. */
|
|
27
|
-
dir?: 'ltr' | 'rtl' | 'auto';
|
|
28
|
-
};
|
|
29
|
-
declare const VarselToaster: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
30
|
-
type VarselToaster = ReturnType<typeof VarselToaster>;
|
|
31
|
-
export default VarselToaster;
|
|
32
|
-
//# sourceMappingURL=VarselToaster.svelte.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
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;AAarB,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;AA6CH,QAAA,MAAM,aAAa,sDAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"accessibility.d.ts","sourceRoot":"","sources":["../../src/lib/core/accessibility.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,mBAAmB,QAOpB,CAAC"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CSS selectors used to identify focusable elements within a toast.
|
|
3
|
-
* Used for managing keyboard focus when interacting with toasts containing actions.
|
|
4
|
-
*/
|
|
5
|
-
export const FOCUSABLE_SELECTORS = [
|
|
6
|
-
"button:not([disabled])",
|
|
7
|
-
"input:not([disabled])",
|
|
8
|
-
"textarea:not([disabled])",
|
|
9
|
-
"select:not([disabled])",
|
|
10
|
-
"a[href]",
|
|
11
|
-
'[tabindex]:not([tabindex="-1"])',
|
|
12
|
-
].join(", ");
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Global configuration constants for toast animations and stacking behavior.
|
|
3
|
-
* These values control timing, spacing, scaling, and easing of toast transitions.
|
|
4
|
-
*/
|
|
5
|
-
export declare const ANIMATION_CONFIG: {
|
|
6
|
-
/** Duration of the entry animation in seconds. */
|
|
7
|
-
readonly ENTER_DURATION: 0.75;
|
|
8
|
-
/** Duration of the exit animation in seconds. */
|
|
9
|
-
readonly EXIT_DURATION: 0.75;
|
|
10
|
-
/** Duration of the stack reorganization animation in seconds. */
|
|
11
|
-
readonly STACK_DURATION: 0.75;
|
|
12
|
-
/** Vertical offset (in pixels) between stacked toasts in collapsed state. */
|
|
13
|
-
readonly STACK_OFFSET: 16;
|
|
14
|
-
/** Vertical gap (in pixels) between toasts in expanded (hover) state. */
|
|
15
|
-
readonly EXPANDED_GAP: 12;
|
|
16
|
-
/** Scale reduction factor for each subsequent toast in the stack. */
|
|
17
|
-
readonly SCALE_FACTOR: 0.04;
|
|
18
|
-
/** Minimum scale value for the furthest toast in the stack. */
|
|
19
|
-
readonly MIN_SCALE: 0.92;
|
|
20
|
-
/** Maximum number of toasts visible in the stack at once. */
|
|
21
|
-
readonly MAX_VISIBLE_TOASTS: 3;
|
|
22
|
-
/** Base z-index for the toast layer. */
|
|
23
|
-
readonly Z_INDEX_BASE: 50;
|
|
24
|
-
/** Default cubic-bezier easing function for animations. */
|
|
25
|
-
readonly EASING_DEFAULT: "var(--ease-vs-toast)";
|
|
26
|
-
/** Easing function for exit animations. */
|
|
27
|
-
readonly EASING_EXIT: "var(--ease-vs-toast)";
|
|
28
|
-
};
|
|
29
|
-
//# sourceMappingURL=animations.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"animations.d.ts","sourceRoot":"","sources":["../../src/lib/core/animations.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,gBAAgB;IAC5B,kDAAkD;;IAElD,iDAAiD;;IAEjD,iEAAiE;;IAEjE,6EAA6E;;IAE7E,yEAAyE;;IAEzE,qEAAqE;;IAErE,+DAA+D;;IAE/D,6DAA6D;;IAE7D,wCAAwC;;IAExC,2DAA2D;;IAE3D,2CAA2C;;CAElC,CAAC"}
|