@getmicdrop/svelte-components 5.21.2 → 5.22.0
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/components/Toast/ToastItem.svelte +695 -0
- package/dist/components/Toast/ToastItem.svelte.d.ts +8 -0
- package/dist/components/Toast/ToastItem.svelte.d.ts.map +1 -0
- package/dist/components/Toast/Toaster.svelte +184 -0
- package/dist/components/Toast/Toaster.svelte.d.ts +11 -0
- package/dist/components/Toast/Toaster.svelte.d.ts.map +1 -0
- package/dist/components/Toast/index.d.ts +9 -0
- package/dist/components/Toast/index.d.ts.map +1 -0
- package/dist/components/Toast/index.js +13 -0
- package/dist/components/Toast/toast.svelte.d.ts +93 -0
- package/dist/components/Toast/toast.svelte.d.ts.map +1 -0
- package/dist/components/Toast/toast.svelte.js +386 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +3 -0
- package/dist/primitives/Icons/CancelledIcon.svelte +8 -0
- package/dist/primitives/Icons/CancelledIcon.svelte.d.ts +16 -0
- package/dist/primitives/Icons/CancelledIcon.svelte.d.ts.map +1 -0
- package/dist/primitives/Icons/CartIcon.svelte +12 -0
- package/dist/primitives/Icons/CartIcon.svelte.d.ts +16 -0
- package/dist/primitives/Icons/CartIcon.svelte.d.ts.map +1 -0
- package/dist/primitives/Icons/ConfirmedIcon.svelte +8 -0
- package/dist/primitives/Icons/ConfirmedIcon.svelte.d.ts +16 -0
- package/dist/primitives/Icons/ConfirmedIcon.svelte.d.ts.map +1 -0
- package/dist/primitives/Icons/InvitedIcon.svelte +7 -0
- package/dist/primitives/Icons/InvitedIcon.svelte.d.ts +16 -0
- package/dist/primitives/Icons/InvitedIcon.svelte.d.ts.map +1 -0
- package/dist/primitives/Icons/TicketIcon.svelte +12 -0
- package/dist/primitives/Icons/TicketIcon.svelte.d.ts +16 -0
- package/dist/primitives/Icons/TicketIcon.svelte.d.ts.map +1 -0
- package/dist/primitives/Icons/ToastErrorIcon.svelte +9 -0
- package/dist/primitives/Icons/ToastErrorIcon.svelte.d.ts +16 -0
- package/dist/primitives/Icons/ToastErrorIcon.svelte.d.ts.map +1 -0
- package/dist/primitives/Icons/ToastInfoIcon.svelte +9 -0
- package/dist/primitives/Icons/ToastInfoIcon.svelte.d.ts +16 -0
- package/dist/primitives/Icons/ToastInfoIcon.svelte.d.ts.map +1 -0
- package/dist/primitives/Icons/ToastLoadingIcon.svelte +14 -0
- package/dist/primitives/Icons/ToastLoadingIcon.svelte.d.ts +16 -0
- package/dist/primitives/Icons/ToastLoadingIcon.svelte.d.ts.map +1 -0
- package/dist/primitives/Icons/ToastSuccessIcon.svelte +8 -0
- package/dist/primitives/Icons/ToastSuccessIcon.svelte.d.ts +16 -0
- package/dist/primitives/Icons/ToastSuccessIcon.svelte.d.ts.map +1 -0
- package/dist/primitives/Icons/ToastWarningIcon.svelte +9 -0
- package/dist/primitives/Icons/ToastWarningIcon.svelte.d.ts +16 -0
- package/dist/primitives/Icons/ToastWarningIcon.svelte.d.ts.map +1 -0
- package/dist/primitives/Icons/index.d.ts +10 -0
- package/dist/primitives/Icons/index.d.ts.map +1 -1
- package/dist/primitives/Icons/index.js +12 -0
- package/dist/recipes/Toaster/Toaster.stories.svelte +9 -28
- package/dist/recipes/Toaster/Toaster.stories.svelte.d.ts +1 -1
- package/dist/recipes/Toaster/Toaster.stories.svelte.d.ts.map +1 -1
- package/dist/schemas/auth.d.ts +17 -107
- package/dist/schemas/auth.d.ts.map +1 -1
- package/dist/schemas/common.d.ts +13 -41
- package/dist/schemas/common.d.ts.map +1 -1
- package/dist/schemas/event.d.ts +41 -147
- package/dist/schemas/event.d.ts.map +1 -1
- package/dist/schemas/order.d.ts +51 -208
- package/dist/schemas/order.d.ts.map +1 -1
- package/dist/schemas/performer.d.ts +44 -199
- package/dist/schemas/performer.d.ts.map +1 -1
- package/dist/schemas/promo.d.ts +55 -221
- package/dist/schemas/promo.d.ts.map +1 -1
- package/dist/schemas/ticket.d.ts +61 -187
- package/dist/schemas/ticket.d.ts.map +1 -1
- package/dist/schemas/user.d.ts +54 -114
- package/dist/schemas/user.d.ts.map +1 -1
- package/dist/schemas/venue.d.ts +20 -238
- package/dist/schemas/venue.d.ts.map +1 -1
- package/dist/stores/formSave.svelte.js +4 -4
- package/dist/stores/formSave.svelte.spec.js +10 -6
- package/dist/stores/index.d.ts +0 -1
- package/dist/stores/index.js +0 -1
- package/dist/tokens/utilities.css +2 -2
- package/package.json +5 -4
- package/dist/stores/toaster.d.ts +0 -4
- package/dist/stores/toaster.d.ts.map +0 -1
- package/dist/stores/toaster.js +0 -13
- package/dist/stores/toaster.spec.d.ts +0 -2
- package/dist/stores/toaster.spec.d.ts.map +0 -1
- package/dist/stores/toaster.spec.js +0 -59
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Micdrop Toast System
|
|
3
|
+
* A modern, macOS-style toast notification system built with Svelte 5 runes.
|
|
4
|
+
* Supports both simple toasts and rich notification-style toasts.
|
|
5
|
+
*
|
|
6
|
+
* Features:
|
|
7
|
+
* - Smart batching for sales notifications (prevents spam during busy periods)
|
|
8
|
+
* - Desktop notification support (browser API)
|
|
9
|
+
* - Swipe-to-dismiss on mobile
|
|
10
|
+
* - Haptic feedback on toast display (QOL Bible)
|
|
11
|
+
*/
|
|
12
|
+
import { triggerHaptic } from '../../utils/haptic';
|
|
13
|
+
// =============================================================================
|
|
14
|
+
// BATCHING CONFIGURATION
|
|
15
|
+
// =============================================================================
|
|
16
|
+
const BATCH_WINDOW_MS = 20000; // 20 seconds - window to aggregate similar notifications
|
|
17
|
+
// Notification types that should be batched (sales-related)
|
|
18
|
+
const BATCHABLE_STATUSES = new Set([
|
|
19
|
+
'ticket sold',
|
|
20
|
+
'order completed',
|
|
21
|
+
'event sold out',
|
|
22
|
+
'show sold out',
|
|
23
|
+
'section sold out',
|
|
24
|
+
'ticket type sold out',
|
|
25
|
+
'vip tickets sold out',
|
|
26
|
+
]);
|
|
27
|
+
const activeBatches = new Map();
|
|
28
|
+
// =============================================================================
|
|
29
|
+
// DESKTOP NOTIFICATIONS
|
|
30
|
+
// =============================================================================
|
|
31
|
+
let desktopNotificationsEnabled = $state(false);
|
|
32
|
+
let desktopNotificationPermission = $state('default');
|
|
33
|
+
// Check initial permission state
|
|
34
|
+
if (typeof window !== 'undefined' && 'Notification' in window) {
|
|
35
|
+
desktopNotificationPermission = Notification.permission;
|
|
36
|
+
desktopNotificationsEnabled = Notification.permission === 'granted';
|
|
37
|
+
}
|
|
38
|
+
async function requestDesktopPermission() {
|
|
39
|
+
if (typeof window === 'undefined' || !('Notification' in window)) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
const permission = await Notification.requestPermission();
|
|
43
|
+
desktopNotificationPermission = permission;
|
|
44
|
+
desktopNotificationsEnabled = permission === 'granted';
|
|
45
|
+
return desktopNotificationsEnabled;
|
|
46
|
+
}
|
|
47
|
+
let pushPreferenceChecker = null;
|
|
48
|
+
// Status-to-preference mapping
|
|
49
|
+
const STATUS_TO_PREFERENCE = {
|
|
50
|
+
// Admin notifications
|
|
51
|
+
'ticket sold': { category: 'admin', key: 'ticketSales' },
|
|
52
|
+
'order completed': { category: 'admin', key: 'ticketSales' },
|
|
53
|
+
'performer confirmed': { category: 'admin', key: 'performerResponses' },
|
|
54
|
+
'performer declined': { category: 'admin', key: 'performerResponses' },
|
|
55
|
+
'event sold out': { category: 'admin', key: 'eventSoldOut' },
|
|
56
|
+
'show sold out': { category: 'admin', key: 'eventSoldOut' },
|
|
57
|
+
'section sold out': { category: 'admin', key: 'eventSoldOut' },
|
|
58
|
+
'ticket type sold out': { category: 'admin', key: 'eventSoldOut' },
|
|
59
|
+
'vip tickets sold out': { category: 'admin', key: 'eventSoldOut' },
|
|
60
|
+
'event published': { category: 'admin', key: 'eventPublished' },
|
|
61
|
+
// Performer notifications
|
|
62
|
+
'avails sent': { category: 'performer', key: 'availabilityRequests' },
|
|
63
|
+
'avails sent to all': { category: 'performer', key: 'availabilityRequests' },
|
|
64
|
+
'availability request': {
|
|
65
|
+
category: 'performer',
|
|
66
|
+
key: 'availabilityRequests',
|
|
67
|
+
},
|
|
68
|
+
'performance invitation': {
|
|
69
|
+
category: 'performer',
|
|
70
|
+
key: 'performanceInvitations',
|
|
71
|
+
},
|
|
72
|
+
'invited to perform': {
|
|
73
|
+
category: 'performer',
|
|
74
|
+
key: 'performanceInvitations',
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
function setPushPreferenceChecker(checker) {
|
|
78
|
+
pushPreferenceChecker = checker;
|
|
79
|
+
}
|
|
80
|
+
function isPushEnabledForStatus(status) {
|
|
81
|
+
// If no preference checker is set, allow all (backwards compatibility)
|
|
82
|
+
if (!pushPreferenceChecker)
|
|
83
|
+
return true;
|
|
84
|
+
return pushPreferenceChecker(status);
|
|
85
|
+
}
|
|
86
|
+
function showDesktopNotification(title, options) {
|
|
87
|
+
if (!desktopNotificationsEnabled)
|
|
88
|
+
return;
|
|
89
|
+
// Check user preference for this notification type
|
|
90
|
+
if (options?.status && !isPushEnabledForStatus(options.status)) {
|
|
91
|
+
return; // User has disabled push for this category
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
new Notification(title, {
|
|
95
|
+
body: options?.body,
|
|
96
|
+
icon: options?.icon || '/favicon.png',
|
|
97
|
+
badge: '/favicon.png',
|
|
98
|
+
silent: false,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
// Desktop notifications may fail in some contexts (e.g., service workers)
|
|
103
|
+
console.warn('Desktop notification failed:', e);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Default durations by type (ms)
|
|
107
|
+
const DEFAULT_DURATIONS = {
|
|
108
|
+
success: 4000,
|
|
109
|
+
error: 6000,
|
|
110
|
+
warning: 5000,
|
|
111
|
+
info: 4000,
|
|
112
|
+
loading: Infinity,
|
|
113
|
+
notification: 6000,
|
|
114
|
+
};
|
|
115
|
+
// Maximum number of toasts before oldest are auto-dismissed
|
|
116
|
+
const MAX_TOASTS = 5;
|
|
117
|
+
// Toast store using Svelte 5 runes
|
|
118
|
+
let toasts = $state([]);
|
|
119
|
+
const timers = new Map();
|
|
120
|
+
function generateId() {
|
|
121
|
+
return `toast-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
122
|
+
}
|
|
123
|
+
// Map toast types to haptic feedback styles
|
|
124
|
+
const TOAST_HAPTIC_STYLES = {
|
|
125
|
+
success: 'success',
|
|
126
|
+
error: 'error',
|
|
127
|
+
warning: 'warning',
|
|
128
|
+
info: 'light',
|
|
129
|
+
loading: null, // No haptic for loading states
|
|
130
|
+
notification: 'light',
|
|
131
|
+
};
|
|
132
|
+
function addToast(type, title, options = {}) {
|
|
133
|
+
const id = generateId();
|
|
134
|
+
const duration = options.duration ?? DEFAULT_DURATIONS[type];
|
|
135
|
+
const newToast = {
|
|
136
|
+
id,
|
|
137
|
+
type,
|
|
138
|
+
title,
|
|
139
|
+
description: options.description,
|
|
140
|
+
duration,
|
|
141
|
+
dismissible: options.dismissible ?? true,
|
|
142
|
+
onClick: options.onClick,
|
|
143
|
+
action: options.action,
|
|
144
|
+
createdAt: Date.now(),
|
|
145
|
+
};
|
|
146
|
+
// Add to beginning so newest appears at top
|
|
147
|
+
toasts = [newToast, ...toasts];
|
|
148
|
+
// Trigger haptic feedback based on toast type (QOL Bible)
|
|
149
|
+
const hapticStyle = TOAST_HAPTIC_STYLES[type];
|
|
150
|
+
if (hapticStyle) {
|
|
151
|
+
triggerHaptic(hapticStyle);
|
|
152
|
+
}
|
|
153
|
+
// Set auto-dismiss timer if not infinite
|
|
154
|
+
if (duration !== Infinity) {
|
|
155
|
+
scheduleRemoval(id, duration);
|
|
156
|
+
}
|
|
157
|
+
// Trim overflow — keep only MAX_TOASTS
|
|
158
|
+
if (toasts.length > MAX_TOASTS) {
|
|
159
|
+
const overflow = toasts.slice(MAX_TOASTS);
|
|
160
|
+
for (const t of overflow) {
|
|
161
|
+
const timer = timers.get(t.id);
|
|
162
|
+
if (timer) {
|
|
163
|
+
clearTimeout(timer);
|
|
164
|
+
timers.delete(t.id);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
toasts = toasts.slice(0, MAX_TOASTS);
|
|
168
|
+
}
|
|
169
|
+
return id;
|
|
170
|
+
}
|
|
171
|
+
function addNotificationToast(options) {
|
|
172
|
+
const normalizedStatus = (options.status || '').trim().toLowerCase();
|
|
173
|
+
const isBatchable = BATCHABLE_STATUSES.has(normalizedStatus);
|
|
174
|
+
const batchKey = options.eventId
|
|
175
|
+
? `${options.eventId}:${normalizedStatus}`
|
|
176
|
+
: null;
|
|
177
|
+
// Check if we should batch this notification
|
|
178
|
+
if (isBatchable && batchKey) {
|
|
179
|
+
const existingBatch = activeBatches.get(batchKey);
|
|
180
|
+
if (existingBatch) {
|
|
181
|
+
// Update existing batch - increment count and update toast
|
|
182
|
+
existingBatch.count++;
|
|
183
|
+
existingBatch.lastUpdate = Date.now();
|
|
184
|
+
// Parse ticket count from message (e.g., "2x General Admission" → 2)
|
|
185
|
+
const ticketMatch = options.message?.match(/^(\d+)x/);
|
|
186
|
+
const ticketCount = ticketMatch ? parseInt(ticketMatch[1], 10) : 1;
|
|
187
|
+
existingBatch.total += ticketCount;
|
|
188
|
+
// Update the existing toast with new batch info
|
|
189
|
+
// When multiple orders are batched (count > 1), clicking goes to orders page
|
|
190
|
+
// The "View orders" text only appears when there are multiple orders batched
|
|
191
|
+
const batchedOnClick = options.eventId
|
|
192
|
+
? () => {
|
|
193
|
+
if (typeof window !== 'undefined') {
|
|
194
|
+
window.location.href = `/a/events/${options.eventId}/orders`;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
: undefined;
|
|
198
|
+
toasts = toasts.map(t => t.id === existingBatch.toastId
|
|
199
|
+
? {
|
|
200
|
+
...t,
|
|
201
|
+
notification: {
|
|
202
|
+
...t.notification,
|
|
203
|
+
batchCount: existingBatch.count,
|
|
204
|
+
batchTotal: existingBatch.total,
|
|
205
|
+
// Only show "View orders" when multiple orders are batched
|
|
206
|
+
message: `${existingBatch.total} tickets sold · View orders`,
|
|
207
|
+
},
|
|
208
|
+
onClick: batchedOnClick, // Override to go to orders list (multiple orders)
|
|
209
|
+
createdAt: Date.now(), // Reset timer visual
|
|
210
|
+
}
|
|
211
|
+
: t);
|
|
212
|
+
// Reset the dismiss timer
|
|
213
|
+
scheduleRemoval(existingBatch.toastId, options.duration ?? DEFAULT_DURATIONS.notification);
|
|
214
|
+
// Show desktop notification for batched update
|
|
215
|
+
showDesktopNotification(options.event, {
|
|
216
|
+
body: `${existingBatch.total} tickets sold`,
|
|
217
|
+
icon: options.avatar,
|
|
218
|
+
status: normalizedStatus,
|
|
219
|
+
});
|
|
220
|
+
return existingBatch.toastId;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
// Create new toast (either not batchable, or first in a new batch)
|
|
224
|
+
const id = generateId();
|
|
225
|
+
const duration = options.duration ?? DEFAULT_DURATIONS.notification;
|
|
226
|
+
// Parse initial ticket count
|
|
227
|
+
const ticketMatch = options.message?.match(/^(\d+)x/);
|
|
228
|
+
const initialTicketCount = ticketMatch ? parseInt(ticketMatch[1], 10) : 1;
|
|
229
|
+
const newToast = {
|
|
230
|
+
id,
|
|
231
|
+
type: 'notification',
|
|
232
|
+
notification: {
|
|
233
|
+
name: options.name,
|
|
234
|
+
displayName: options.displayName,
|
|
235
|
+
event: options.event,
|
|
236
|
+
status: options.status,
|
|
237
|
+
avatar: options.avatar,
|
|
238
|
+
message: options.message,
|
|
239
|
+
performerMessage: options.performerMessage,
|
|
240
|
+
eventId: options.eventId,
|
|
241
|
+
batchCount: isBatchable ? 1 : undefined,
|
|
242
|
+
batchTotal: isBatchable ? initialTicketCount : undefined,
|
|
243
|
+
},
|
|
244
|
+
duration,
|
|
245
|
+
dismissible: options.dismissible ?? true,
|
|
246
|
+
onClick: options.onClick,
|
|
247
|
+
createdAt: Date.now(),
|
|
248
|
+
};
|
|
249
|
+
toasts = [newToast, ...toasts];
|
|
250
|
+
// Trigger haptic feedback for notification toasts
|
|
251
|
+
triggerHaptic('light');
|
|
252
|
+
if (duration !== Infinity) {
|
|
253
|
+
scheduleRemoval(id, duration);
|
|
254
|
+
}
|
|
255
|
+
// Start a new batch if this is batchable
|
|
256
|
+
if (isBatchable && batchKey) {
|
|
257
|
+
const batchTimeout = setTimeout(() => {
|
|
258
|
+
activeBatches.delete(batchKey);
|
|
259
|
+
}, BATCH_WINDOW_MS);
|
|
260
|
+
activeBatches.set(batchKey, {
|
|
261
|
+
toastId: id,
|
|
262
|
+
count: 1,
|
|
263
|
+
total: initialTicketCount,
|
|
264
|
+
timeout: batchTimeout,
|
|
265
|
+
lastUpdate: Date.now(),
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
// Show desktop notification
|
|
269
|
+
const desktopTitle = options.name || options.event;
|
|
270
|
+
const desktopBody = options.name
|
|
271
|
+
? `${options.status} · ${options.event}`
|
|
272
|
+
: options.message || options.status;
|
|
273
|
+
showDesktopNotification(desktopTitle, {
|
|
274
|
+
body: desktopBody,
|
|
275
|
+
icon: options.avatar,
|
|
276
|
+
status: normalizedStatus,
|
|
277
|
+
});
|
|
278
|
+
// Trim overflow — keep only MAX_TOASTS
|
|
279
|
+
if (toasts.length > MAX_TOASTS) {
|
|
280
|
+
const overflow = toasts.slice(MAX_TOASTS);
|
|
281
|
+
for (const t of overflow) {
|
|
282
|
+
const timer = timers.get(t.id);
|
|
283
|
+
if (timer) {
|
|
284
|
+
clearTimeout(timer);
|
|
285
|
+
timers.delete(t.id);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
toasts = toasts.slice(0, MAX_TOASTS);
|
|
289
|
+
}
|
|
290
|
+
return id;
|
|
291
|
+
}
|
|
292
|
+
function scheduleRemoval(id, delay) {
|
|
293
|
+
const existingTimer = timers.get(id);
|
|
294
|
+
if (existingTimer) {
|
|
295
|
+
clearTimeout(existingTimer);
|
|
296
|
+
}
|
|
297
|
+
const timer = setTimeout(() => {
|
|
298
|
+
dismiss(id);
|
|
299
|
+
}, delay);
|
|
300
|
+
timers.set(id, timer);
|
|
301
|
+
}
|
|
302
|
+
function dismiss(id) {
|
|
303
|
+
const timer = timers.get(id);
|
|
304
|
+
if (timer) {
|
|
305
|
+
clearTimeout(timer);
|
|
306
|
+
timers.delete(id);
|
|
307
|
+
}
|
|
308
|
+
toasts = toasts.filter(t => t.id !== id);
|
|
309
|
+
}
|
|
310
|
+
function dismissAll() {
|
|
311
|
+
timers.forEach(timer => clearTimeout(timer));
|
|
312
|
+
timers.clear();
|
|
313
|
+
toasts = [];
|
|
314
|
+
}
|
|
315
|
+
function pause(id) {
|
|
316
|
+
const toast = toasts.find(t => t.id === id);
|
|
317
|
+
if (!toast || toast.duration === Infinity)
|
|
318
|
+
return;
|
|
319
|
+
const timer = timers.get(id);
|
|
320
|
+
if (timer) {
|
|
321
|
+
clearTimeout(timer);
|
|
322
|
+
timers.delete(id);
|
|
323
|
+
}
|
|
324
|
+
const elapsed = Date.now() - toast.createdAt;
|
|
325
|
+
const remaining = Math.max(0, toast.duration - elapsed);
|
|
326
|
+
toasts = toasts.map(t => t.id === id ? { ...t, pausedAt: Date.now(), remainingTime: remaining } : t);
|
|
327
|
+
}
|
|
328
|
+
function resume(id) {
|
|
329
|
+
const foundToast = toasts.find(t => t.id === id);
|
|
330
|
+
if (!foundToast || !foundToast.pausedAt || foundToast.duration === Infinity)
|
|
331
|
+
return;
|
|
332
|
+
const remaining = foundToast.remainingTime ?? foundToast.duration;
|
|
333
|
+
toasts = toasts.map(t => t.id === id
|
|
334
|
+
? {
|
|
335
|
+
...t,
|
|
336
|
+
pausedAt: undefined,
|
|
337
|
+
remainingTime: undefined,
|
|
338
|
+
createdAt: Date.now() - (foundToast.duration - remaining),
|
|
339
|
+
}
|
|
340
|
+
: t);
|
|
341
|
+
if (remaining > 0) {
|
|
342
|
+
scheduleRemoval(id, remaining);
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
dismiss(id);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
// Main toast function and methods
|
|
349
|
+
function toast(title, options) {
|
|
350
|
+
return addToast('info', title, options);
|
|
351
|
+
}
|
|
352
|
+
toast.success = (title, options) => addToast('success', title, options);
|
|
353
|
+
toast.error = (title, options) => addToast('error', title, options);
|
|
354
|
+
toast.warning = (title, options) => addToast('warning', title, options);
|
|
355
|
+
toast.info = (title, options) => addToast('info', title, options);
|
|
356
|
+
toast.loading = (title, options) => addToast('loading', title, { ...options, duration: Infinity });
|
|
357
|
+
toast.notification = (options) => addNotificationToast(options);
|
|
358
|
+
toast.dismiss = dismiss;
|
|
359
|
+
toast.dismissAll = dismissAll;
|
|
360
|
+
toast.pause = pause;
|
|
361
|
+
toast.resume = resume;
|
|
362
|
+
// Desktop notification controls
|
|
363
|
+
toast.requestDesktopPermission = requestDesktopPermission;
|
|
364
|
+
toast.getDesktopPermission = () => desktopNotificationPermission;
|
|
365
|
+
toast.isDesktopEnabled = () => desktopNotificationsEnabled;
|
|
366
|
+
toast.setPushPreferenceChecker = setPushPreferenceChecker;
|
|
367
|
+
toast.STATUS_TO_PREFERENCE = STATUS_TO_PREFERENCE;
|
|
368
|
+
toast.promise = async (promise, options) => {
|
|
369
|
+
const id = toast.loading(options.loading);
|
|
370
|
+
try {
|
|
371
|
+
const result = await promise;
|
|
372
|
+
dismiss(id);
|
|
373
|
+
toast.success(options.success);
|
|
374
|
+
return result;
|
|
375
|
+
}
|
|
376
|
+
catch (err) {
|
|
377
|
+
dismiss(id);
|
|
378
|
+
toast.error(options.error);
|
|
379
|
+
throw err;
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
// Getter for reactive access to toasts
|
|
383
|
+
export function getToasts() {
|
|
384
|
+
return toasts;
|
|
385
|
+
}
|
|
386
|
+
export { toast };
|
package/dist/components/index.js
CHANGED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
let { size = "16", color = "currentColor", class: className = "" } = $props();
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<svg class={className} width={size} height={size} viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
|
|
6
|
+
<rect width="16" height="16" rx="8" fill={color}/>
|
|
7
|
+
<path d="M6.016 5c.262-.002.515.099.703.281L8.012 6.574l1.293-1.293a1.003 1.003 0 0 1 1.402 1.414L9.426 7.988l1.293 1.293a1.003 1.003 0 0 1-1.414 1.414L8.012 9.402l-1.293 1.293a1.003 1.003 0 0 1-1.414-1.414l1.293-1.293-1.293-1.293A1.003 1.003 0 0 1 6.016 5Z" fill="white"/>
|
|
8
|
+
</svg>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export default CancelledIcon;
|
|
2
|
+
type CancelledIcon = {
|
|
3
|
+
$on?(type: string, callback: (e: any) => void): () => void;
|
|
4
|
+
$set?(props: Partial<$$ComponentProps>): void;
|
|
5
|
+
};
|
|
6
|
+
declare const CancelledIcon: import("svelte").Component<{
|
|
7
|
+
size?: string;
|
|
8
|
+
color?: string;
|
|
9
|
+
class?: string;
|
|
10
|
+
}, {}, "">;
|
|
11
|
+
type $$ComponentProps = {
|
|
12
|
+
size?: string;
|
|
13
|
+
color?: string;
|
|
14
|
+
class?: string;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=CancelledIcon.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CancelledIcon.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Icons/CancelledIcon.svelte.js"],"names":[],"mappings":";;;;;AAcA;WAV4B,MAAM;YAAU,MAAM;YAAU,MAAM;WAUN;wBAVzC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
let { size = "16", color = "currentColor", class: className = "" } = $props();
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<svg class={className} width={size} height={size} viewBox="0 0 7 7" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
|
|
6
|
+
<g clip-path="url(#cart-clip)">
|
|
7
|
+
<path d="M5.569 3.967a.348.348 0 0 0 .334-.24l.696-2.314a.34.34 0 0 0-.335-.422H1.66L1.453.247A.348.348 0 0 0 1.117 0H.348a.331.331 0 0 0 0 .661h.5l.21.746v.003l.696 2.317.26.987a.826.826 0 1 0 .402.576h.824a.826.826 0 1 0 1.329.33ZM2.784 5.62a.348.348 0 1 1-.696 0 .348.348 0 0 1 .696 0Zm2.437.33a.348.348 0 1 1 0-.695.348.348 0 0 1 0 .696Z" fill={color}/>
|
|
8
|
+
</g>
|
|
9
|
+
<defs>
|
|
10
|
+
<clipPath id="cart-clip"><rect width="6.6125" height="6.6125" fill="white"/></clipPath>
|
|
11
|
+
</defs>
|
|
12
|
+
</svg>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export default CartIcon;
|
|
2
|
+
type CartIcon = {
|
|
3
|
+
$on?(type: string, callback: (e: any) => void): () => void;
|
|
4
|
+
$set?(props: Partial<$$ComponentProps>): void;
|
|
5
|
+
};
|
|
6
|
+
declare const CartIcon: import("svelte").Component<{
|
|
7
|
+
size?: string;
|
|
8
|
+
color?: string;
|
|
9
|
+
class?: string;
|
|
10
|
+
}, {}, "">;
|
|
11
|
+
type $$ComponentProps = {
|
|
12
|
+
size?: string;
|
|
13
|
+
color?: string;
|
|
14
|
+
class?: string;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=CartIcon.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CartIcon.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Icons/CartIcon.svelte.js"],"names":[],"mappings":";;;;;AAkBA;WAd4B,MAAM;YAAU,MAAM;YAAU,MAAM;WAcX;wBAdpC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
let { size = "16", color = "currentColor", class: className = "" } = $props();
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<svg class={className} width={size} height={size} viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
|
|
6
|
+
<rect width="16" height="16" rx="8" fill={color}/>
|
|
7
|
+
<path d="M6.862 11.867a.727.727 0 0 1-.502-.242L3.999 8.847a.999.999 0 0 1 1.004-1.37.728.728 0 0 1 .512.243l1.86 2.188 4.133-4.865a.999.999 0 0 1 1.493 1.128L7.365 11.625a.727.727 0 0 1-.503.242Z" fill="white" stroke="white" stroke-width="0.4"/>
|
|
8
|
+
</svg>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export default ConfirmedIcon;
|
|
2
|
+
type ConfirmedIcon = {
|
|
3
|
+
$on?(type: string, callback: (e: any) => void): () => void;
|
|
4
|
+
$set?(props: Partial<$$ComponentProps>): void;
|
|
5
|
+
};
|
|
6
|
+
declare const ConfirmedIcon: import("svelte").Component<{
|
|
7
|
+
size?: string;
|
|
8
|
+
color?: string;
|
|
9
|
+
class?: string;
|
|
10
|
+
}, {}, "">;
|
|
11
|
+
type $$ComponentProps = {
|
|
12
|
+
size?: string;
|
|
13
|
+
color?: string;
|
|
14
|
+
class?: string;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=ConfirmedIcon.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConfirmedIcon.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Icons/ConfirmedIcon.svelte.js"],"names":[],"mappings":";;;;;AAcA;WAV4B,MAAM;YAAU,MAAM;YAAU,MAAM;WAUN;wBAVzC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
let { size = "16", color = "currentColor", class: className = "" } = $props();
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<svg class={className} width={size} height={size} viewBox="0 0 7 7" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
|
|
6
|
+
<path d="M6.402.256a1.1 1.1 0 0 0-.613-.245c-.237-.023-.521-.002-.828.038A15.44 15.44 0 0 0 2.894.54 17.7 17.7 0 0 0 .966 1.309c-.259.131-.483.264-.647.392a1.24 1.24 0 0 0-.21.206.382.382 0 0 0-.109.288c.002.314.216.535.443.684.232.152.534.266.835.356.303.09.623.16.897.218l.098.02c.166.034.249.052.327.028a.348.348 0 0 0 .258-.203l1.187-1.187a.323.323 0 0 1 .457.456L3.395 3.674a.348.348 0 0 0-.167.541c.145.653.27 1.193.396 1.556.073.212.155.396.26.531.108.141.256.248.451.257a.428.428 0 0 0 .292-.101c.073-.055.141-.127.205-.207.127-.16.262-.381.395-.636.269-.513.553-1.2.793-1.908.24-.707.441-1.445.538-2.058.048-.306.072-.59.059-.827a1.1 1.1 0 0 0-.21-.566Z" fill={color}/>
|
|
7
|
+
</svg>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export default InvitedIcon;
|
|
2
|
+
type InvitedIcon = {
|
|
3
|
+
$on?(type: string, callback: (e: any) => void): () => void;
|
|
4
|
+
$set?(props: Partial<$$ComponentProps>): void;
|
|
5
|
+
};
|
|
6
|
+
declare const InvitedIcon: import("svelte").Component<{
|
|
7
|
+
size?: string;
|
|
8
|
+
color?: string;
|
|
9
|
+
class?: string;
|
|
10
|
+
}, {}, "">;
|
|
11
|
+
type $$ComponentProps = {
|
|
12
|
+
size?: string;
|
|
13
|
+
color?: string;
|
|
14
|
+
class?: string;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=InvitedIcon.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InvitedIcon.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Icons/InvitedIcon.svelte.js"],"names":[],"mappings":";;;;;AAaA;WAT4B,MAAM;YAAU,MAAM;YAAU,MAAM;WASR;wBATvC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
let { size = "16", color = "currentColor", class: className = "" } = $props();
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<svg class={className} width={size} height={size} viewBox="0 0 7 7" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
|
|
6
|
+
<g clip-path="url(#ticket-clip)">
|
|
7
|
+
<path d="M5.951 5.786H.661a.66.66 0 0 1-.661-.709V4.192c0-.188.153-.354.33-.354a.496.496 0 0 0 .496-.532.496.496 0 0 0-.496-.531.331.331 0 0 1-.33-.354V1.535c0-.376.297-.709.661-.709h5.29c.364 0 .661.333.661.709v.886a.331.331 0 0 1-.33.354.496.496 0 0 0-.497.531c0 .294.223.532.497.532.178 0 .33.166.33.354v.886c0 .376-.297.709-.661.709Z" fill={color}/>
|
|
8
|
+
</g>
|
|
9
|
+
<defs>
|
|
10
|
+
<clipPath id="ticket-clip"><rect width="6.6125" height="6.6125" fill="white"/></clipPath>
|
|
11
|
+
</defs>
|
|
12
|
+
</svg>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export default TicketIcon;
|
|
2
|
+
type TicketIcon = {
|
|
3
|
+
$on?(type: string, callback: (e: any) => void): () => void;
|
|
4
|
+
$set?(props: Partial<$$ComponentProps>): void;
|
|
5
|
+
};
|
|
6
|
+
declare const TicketIcon: import("svelte").Component<{
|
|
7
|
+
size?: string;
|
|
8
|
+
color?: string;
|
|
9
|
+
class?: string;
|
|
10
|
+
}, {}, "">;
|
|
11
|
+
type $$ComponentProps = {
|
|
12
|
+
size?: string;
|
|
13
|
+
color?: string;
|
|
14
|
+
class?: string;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=TicketIcon.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TicketIcon.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Icons/TicketIcon.svelte.js"],"names":[],"mappings":";;;;;AAkBA;WAd4B,MAAM;YAAU,MAAM;YAAU,MAAM;WAcT;wBAdtC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
let { size = "20", color = "currentColor", class: className = "" } = $props();
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<svg class={className} xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
6
|
+
<circle cx="12" cy="12" r="10"/>
|
|
7
|
+
<line x1="15" y1="9" x2="9" y2="15"/>
|
|
8
|
+
<line x1="9" y1="9" x2="15" y2="15"/>
|
|
9
|
+
</svg>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export default ToastErrorIcon;
|
|
2
|
+
type ToastErrorIcon = {
|
|
3
|
+
$on?(type: string, callback: (e: any) => void): () => void;
|
|
4
|
+
$set?(props: Partial<$$ComponentProps>): void;
|
|
5
|
+
};
|
|
6
|
+
declare const ToastErrorIcon: import("svelte").Component<{
|
|
7
|
+
size?: string;
|
|
8
|
+
color?: string;
|
|
9
|
+
class?: string;
|
|
10
|
+
}, {}, "">;
|
|
11
|
+
type $$ComponentProps = {
|
|
12
|
+
size?: string;
|
|
13
|
+
color?: string;
|
|
14
|
+
class?: string;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=ToastErrorIcon.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToastErrorIcon.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Icons/ToastErrorIcon.svelte.js"],"names":[],"mappings":";;;;;AAeA;WAX4B,MAAM;YAAU,MAAM;YAAU,MAAM;WAWL;wBAX1C;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
let { size = "20", color = "currentColor", class: className = "" } = $props();
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<svg class={className} xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
6
|
+
<circle cx="12" cy="12" r="10"/>
|
|
7
|
+
<line x1="12" y1="16" x2="12" y2="12"/>
|
|
8
|
+
<line x1="12" y1="8" x2="12.01" y2="8"/>
|
|
9
|
+
</svg>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export default ToastInfoIcon;
|
|
2
|
+
type ToastInfoIcon = {
|
|
3
|
+
$on?(type: string, callback: (e: any) => void): () => void;
|
|
4
|
+
$set?(props: Partial<$$ComponentProps>): void;
|
|
5
|
+
};
|
|
6
|
+
declare const ToastInfoIcon: import("svelte").Component<{
|
|
7
|
+
size?: string;
|
|
8
|
+
color?: string;
|
|
9
|
+
class?: string;
|
|
10
|
+
}, {}, "">;
|
|
11
|
+
type $$ComponentProps = {
|
|
12
|
+
size?: string;
|
|
13
|
+
color?: string;
|
|
14
|
+
class?: string;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=ToastInfoIcon.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToastInfoIcon.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Icons/ToastInfoIcon.svelte.js"],"names":[],"mappings":";;;;;AAeA;WAX4B,MAAM;YAAU,MAAM;YAAU,MAAM;WAWN;wBAXzC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
let { size = "20", color = "currentColor", class: className = "" } = $props();
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<svg class={className} xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
6
|
+
<line x1="12" y1="2" x2="12" y2="6"/>
|
|
7
|
+
<line x1="12" y1="18" x2="12" y2="22"/>
|
|
8
|
+
<line x1="4.93" y1="4.93" x2="7.76" y2="7.76"/>
|
|
9
|
+
<line x1="16.24" y1="16.24" x2="19.07" y2="19.07"/>
|
|
10
|
+
<line x1="2" y1="12" x2="6" y2="12"/>
|
|
11
|
+
<line x1="18" y1="12" x2="22" y2="12"/>
|
|
12
|
+
<line x1="4.93" y1="19.07" x2="7.76" y2="16.24"/>
|
|
13
|
+
<line x1="16.24" y1="7.76" x2="19.07" y2="4.93"/>
|
|
14
|
+
</svg>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export default ToastLoadingIcon;
|
|
2
|
+
type ToastLoadingIcon = {
|
|
3
|
+
$on?(type: string, callback: (e: any) => void): () => void;
|
|
4
|
+
$set?(props: Partial<$$ComponentProps>): void;
|
|
5
|
+
};
|
|
6
|
+
declare const ToastLoadingIcon: import("svelte").Component<{
|
|
7
|
+
size?: string;
|
|
8
|
+
color?: string;
|
|
9
|
+
class?: string;
|
|
10
|
+
}, {}, "">;
|
|
11
|
+
type $$ComponentProps = {
|
|
12
|
+
size?: string;
|
|
13
|
+
color?: string;
|
|
14
|
+
class?: string;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=ToastLoadingIcon.svelte.d.ts.map
|