@zag-js/toast 0.82.1 → 1.0.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/index.d.mts +196 -134
- package/dist/index.d.ts +196 -134
- package/dist/index.js +760 -625
- package/dist/index.mjs +760 -626
- package/package.json +15 -10
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { createScope, raf, queryAll, dataAttr, contains, addDomEvent, MAX_Z_INDEX } from '@zag-js/dom-query';
|
|
3
|
-
import { compact, warn, runIfFn, uuid } from '@zag-js/utils';
|
|
1
|
+
import { addDomEvent, raf, dataAttr, contains, MAX_Z_INDEX } from '@zag-js/dom-query';
|
|
4
2
|
import { createAnatomy } from '@zag-js/anatomy';
|
|
3
|
+
import { createMachine, createGuards } from '@zag-js/core';
|
|
5
4
|
import { trackDismissableBranch } from '@zag-js/dismissable';
|
|
5
|
+
import { uuid, setRafTimeout, runIfFn } from '@zag-js/utils';
|
|
6
6
|
|
|
7
7
|
// src/toast-group.connect.ts
|
|
8
8
|
var anatomy = createAnatomy("toast").parts(
|
|
@@ -14,18 +14,15 @@ var anatomy = createAnatomy("toast").parts(
|
|
|
14
14
|
"closeTrigger"
|
|
15
15
|
);
|
|
16
16
|
var parts = anatomy.build();
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
function getToastsByPlacement(toasts, placement) {
|
|
27
|
-
return toasts.filter((toast) => toast.state.context.placement === placement);
|
|
28
|
-
}
|
|
17
|
+
|
|
18
|
+
// src/toast.dom.ts
|
|
19
|
+
var getRegionId = (placement) => `toast-group:${placement}`;
|
|
20
|
+
var getRegionEl = (ctx, placement) => ctx.getById(`toast-group:${placement}`);
|
|
21
|
+
var getRootId = (ctx) => `toast:${ctx.id}`;
|
|
22
|
+
var getRootEl = (ctx) => ctx.getById(getRootId(ctx));
|
|
23
|
+
var getTitleId = (ctx) => `toast:${ctx.id}:title`;
|
|
24
|
+
var getDescriptionId = (ctx) => `toast:${ctx.id}:description`;
|
|
25
|
+
var getCloseTriggerId = (ctx) => `toast${ctx.id}:close`;
|
|
29
26
|
var defaultTimeouts = {
|
|
30
27
|
info: 5e3,
|
|
31
28
|
error: 5e3,
|
|
@@ -36,20 +33,23 @@ var defaultTimeouts = {
|
|
|
36
33
|
function getToastDuration(duration, type) {
|
|
37
34
|
return duration ?? defaultTimeouts[type] ?? defaultTimeouts.DEFAULT;
|
|
38
35
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const
|
|
42
|
-
const
|
|
36
|
+
var getOffsets = (offsets) => typeof offsets === "string" ? { left: offsets, right: offsets, bottom: offsets, top: offsets } : offsets;
|
|
37
|
+
function getGroupPlacementStyle(service, placement) {
|
|
38
|
+
const { prop, computed, context } = service;
|
|
39
|
+
const { offsets, gap } = prop("store").attrs;
|
|
40
|
+
const heights = context.get("heights");
|
|
41
|
+
const computedOffset = getOffsets(offsets);
|
|
42
|
+
const rtl = prop("dir") === "rtl";
|
|
43
43
|
const computedPlacement = placement.replace("-start", rtl ? "-right" : "-left").replace("-end", rtl ? "-left" : "-right");
|
|
44
44
|
const isRighty = computedPlacement.includes("right");
|
|
45
45
|
const isLefty = computedPlacement.includes("left");
|
|
46
46
|
const styles = {
|
|
47
47
|
position: "fixed",
|
|
48
|
-
pointerEvents:
|
|
48
|
+
pointerEvents: computed("count") > 0 ? void 0 : "none",
|
|
49
49
|
display: "flex",
|
|
50
50
|
flexDirection: "column",
|
|
51
|
-
"--gap": `${
|
|
52
|
-
"--first-height": `${
|
|
51
|
+
"--gap": `${gap}px`,
|
|
52
|
+
"--first-height": `${heights[0]?.height || 0}px`,
|
|
53
53
|
zIndex: MAX_Z_INDEX
|
|
54
54
|
};
|
|
55
55
|
let alignItems = "center";
|
|
@@ -57,37 +57,49 @@ function getGroupPlacementStyle(ctx, placement) {
|
|
|
57
57
|
if (isLefty) alignItems = "flex-start";
|
|
58
58
|
styles.alignItems = alignItems;
|
|
59
59
|
if (computedPlacement.includes("top")) {
|
|
60
|
-
const
|
|
61
|
-
styles.top = `max(env(safe-area-inset-top, 0px), ${
|
|
60
|
+
const offset = computedOffset.top;
|
|
61
|
+
styles.top = `max(env(safe-area-inset-top, 0px), ${offset})`;
|
|
62
62
|
}
|
|
63
63
|
if (computedPlacement.includes("bottom")) {
|
|
64
|
-
const
|
|
65
|
-
styles.bottom = `max(env(safe-area-inset-bottom, 0px), ${
|
|
64
|
+
const offset = computedOffset.bottom;
|
|
65
|
+
styles.bottom = `max(env(safe-area-inset-bottom, 0px), ${offset})`;
|
|
66
66
|
}
|
|
67
67
|
if (!computedPlacement.includes("left")) {
|
|
68
|
-
const
|
|
69
|
-
styles.insetInlineEnd = `calc(env(safe-area-inset-right, 0px) + ${
|
|
68
|
+
const offset = computedOffset.right;
|
|
69
|
+
styles.insetInlineEnd = `calc(env(safe-area-inset-right, 0px) + ${offset})`;
|
|
70
70
|
}
|
|
71
71
|
if (!computedPlacement.includes("right")) {
|
|
72
|
-
const
|
|
73
|
-
styles.insetInlineStart = `calc(env(safe-area-inset-left, 0px) + ${
|
|
72
|
+
const offset = computedOffset.left;
|
|
73
|
+
styles.insetInlineStart = `calc(env(safe-area-inset-left, 0px) + ${offset})`;
|
|
74
74
|
}
|
|
75
75
|
return styles;
|
|
76
76
|
}
|
|
77
|
-
function getPlacementStyle(
|
|
78
|
-
const
|
|
79
|
-
const
|
|
80
|
-
const
|
|
77
|
+
function getPlacementStyle(service, visible) {
|
|
78
|
+
const { prop, context, computed } = service;
|
|
79
|
+
const parent = prop("parent");
|
|
80
|
+
const placement = parent.computed("placement");
|
|
81
|
+
const { gap } = parent.prop("store").attrs;
|
|
82
|
+
const [side] = placement.split("-");
|
|
83
|
+
const mounted = context.get("mounted");
|
|
84
|
+
const remainingTime = context.get("remainingTime");
|
|
85
|
+
const height = computed("height");
|
|
86
|
+
const frontmost = computed("frontmost");
|
|
87
|
+
const sibling = !frontmost;
|
|
88
|
+
const overlap = !prop("stacked");
|
|
89
|
+
const stacked = prop("stacked");
|
|
90
|
+
const type = prop("type");
|
|
91
|
+
const duration = type === "loading" ? Number.MAX_SAFE_INTEGER : remainingTime;
|
|
92
|
+
const offset = computed("heightIndex") * gap + computed("heightBefore");
|
|
81
93
|
const styles = {
|
|
82
94
|
position: "absolute",
|
|
83
95
|
pointerEvents: "auto",
|
|
84
96
|
"--opacity": "0",
|
|
85
|
-
"--remove-delay": `${
|
|
86
|
-
"--duration": `${
|
|
87
|
-
"--initial-height": `${
|
|
88
|
-
"--offset": `${
|
|
89
|
-
"--index":
|
|
90
|
-
"--z-index":
|
|
97
|
+
"--remove-delay": `${prop("removeDelay")}ms`,
|
|
98
|
+
"--duration": `${duration}ms`,
|
|
99
|
+
"--initial-height": `${height}px`,
|
|
100
|
+
"--offset": `${offset}px`,
|
|
101
|
+
"--index": prop("index"),
|
|
102
|
+
"--z-index": computed("zIndex"),
|
|
91
103
|
"--lift-amount": "calc(var(--lift) * var(--gap))",
|
|
92
104
|
"--y": "100%",
|
|
93
105
|
"--x": "0"
|
|
@@ -108,12 +120,12 @@ function getPlacementStyle(ctx, visible) {
|
|
|
108
120
|
"--lift": "-1"
|
|
109
121
|
});
|
|
110
122
|
}
|
|
111
|
-
if (
|
|
123
|
+
if (mounted) {
|
|
112
124
|
assign({
|
|
113
125
|
"--y": "0",
|
|
114
126
|
"--opacity": "1"
|
|
115
127
|
});
|
|
116
|
-
if (
|
|
128
|
+
if (stacked) {
|
|
117
129
|
assign({
|
|
118
130
|
"--y": "calc(var(--lift) * var(--offset))",
|
|
119
131
|
"--height": "var(--initial-height)"
|
|
@@ -139,19 +151,20 @@ function getPlacementStyle(ctx, visible) {
|
|
|
139
151
|
});
|
|
140
152
|
}
|
|
141
153
|
}
|
|
142
|
-
if (sibling &&
|
|
154
|
+
if (sibling && stacked && !visible) {
|
|
143
155
|
assign({
|
|
144
156
|
"--y": "calc(var(--lift) * var(--offset) + var(--lift) * -100%)"
|
|
145
157
|
});
|
|
146
158
|
}
|
|
147
|
-
if (
|
|
159
|
+
if (frontmost && !visible) {
|
|
148
160
|
assign({
|
|
149
161
|
"--y": "calc(var(--lift) * -100%)"
|
|
150
162
|
});
|
|
151
163
|
}
|
|
152
164
|
return styles;
|
|
153
165
|
}
|
|
154
|
-
function getGhostBeforeStyle(
|
|
166
|
+
function getGhostBeforeStyle(service, visible) {
|
|
167
|
+
const { computed } = service;
|
|
155
168
|
const styles = {
|
|
156
169
|
position: "absolute",
|
|
157
170
|
inset: "0",
|
|
@@ -159,14 +172,14 @@ function getGhostBeforeStyle(ctx, visible) {
|
|
|
159
172
|
pointerEvents: visible ? "none" : "auto"
|
|
160
173
|
};
|
|
161
174
|
const assign = (overrides) => Object.assign(styles, overrides);
|
|
162
|
-
if (
|
|
175
|
+
if (computed("frontmost") && !visible) {
|
|
163
176
|
assign({
|
|
164
177
|
height: "calc(var(--initial-height) + 80%)"
|
|
165
178
|
});
|
|
166
179
|
}
|
|
167
180
|
return styles;
|
|
168
181
|
}
|
|
169
|
-
function getGhostAfterStyle(
|
|
182
|
+
function getGhostAfterStyle() {
|
|
170
183
|
return {
|
|
171
184
|
position: "absolute",
|
|
172
185
|
left: "0",
|
|
@@ -177,126 +190,33 @@ function getGhostAfterStyle(_ctx, _visible) {
|
|
|
177
190
|
}
|
|
178
191
|
|
|
179
192
|
// src/toast-group.connect.ts
|
|
180
|
-
function groupConnect(
|
|
181
|
-
|
|
182
|
-
const result = isMachine(serviceOrState) ? serviceOrState.getState() : serviceOrState;
|
|
183
|
-
return result;
|
|
184
|
-
}
|
|
185
|
-
function getToastsByPlacementImpl(placement) {
|
|
186
|
-
return getToastsByPlacement(getState().context.toasts, placement);
|
|
187
|
-
}
|
|
188
|
-
function isVisible(id) {
|
|
189
|
-
const toasts = getState().context.toasts;
|
|
190
|
-
if (!toasts.length) return false;
|
|
191
|
-
return !!toasts.find((toast) => toast.id == id);
|
|
192
|
-
}
|
|
193
|
-
function create(options) {
|
|
194
|
-
const uid = `toast:${uuid()}`;
|
|
195
|
-
const id = options.id ? options.id : uid;
|
|
196
|
-
if (isVisible(id)) return id;
|
|
197
|
-
send({ type: "ADD_TOAST", toast: { ...options, id } });
|
|
198
|
-
return id;
|
|
199
|
-
}
|
|
200
|
-
function update(id, options) {
|
|
201
|
-
if (!isVisible(id)) return id;
|
|
202
|
-
send({ type: "UPDATE_TOAST", id, toast: options });
|
|
203
|
-
return id;
|
|
204
|
-
}
|
|
205
|
-
function upsert(options) {
|
|
206
|
-
const { id } = options;
|
|
207
|
-
const visible = id ? isVisible(id) : false;
|
|
208
|
-
if (visible && id != null) {
|
|
209
|
-
return update(id, options);
|
|
210
|
-
} else {
|
|
211
|
-
return create(options);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
function dismiss(id) {
|
|
215
|
-
if (id == null) {
|
|
216
|
-
send("DISMISS_ALL");
|
|
217
|
-
} else if (isVisible(id)) {
|
|
218
|
-
send({ type: "DISMISS_TOAST", id });
|
|
219
|
-
}
|
|
220
|
-
}
|
|
193
|
+
function groupConnect(service, normalize) {
|
|
194
|
+
const { context, prop, send, refs, computed } = service;
|
|
221
195
|
return {
|
|
222
196
|
getCount() {
|
|
223
|
-
return
|
|
197
|
+
return context.get("toasts").length;
|
|
224
198
|
},
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
const placements = toasts.map((toast) => toast.state.context.placement);
|
|
228
|
-
return Array.from(new Set(placements));
|
|
199
|
+
getToasts() {
|
|
200
|
+
return context.get("toasts");
|
|
229
201
|
},
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
dismiss,
|
|
236
|
-
remove(id) {
|
|
237
|
-
if (id == null) {
|
|
238
|
-
send("REMOVE_ALL");
|
|
239
|
-
} else if (isVisible(id)) {
|
|
240
|
-
send({ type: "REMOVE_TOAST", id });
|
|
241
|
-
}
|
|
242
|
-
},
|
|
243
|
-
dismissByPlacement(placement) {
|
|
244
|
-
const toasts = getToastsByPlacementImpl(placement);
|
|
245
|
-
toasts.forEach((toast) => dismiss(toast.id));
|
|
246
|
-
},
|
|
247
|
-
loading(options) {
|
|
248
|
-
return upsert({ ...options, type: "loading" });
|
|
249
|
-
},
|
|
250
|
-
success(options) {
|
|
251
|
-
return upsert({ ...options, type: "success" });
|
|
252
|
-
},
|
|
253
|
-
error(options) {
|
|
254
|
-
return upsert({ ...options, type: "error" });
|
|
255
|
-
},
|
|
256
|
-
promise(promise, options, shared = {}) {
|
|
257
|
-
const id = upsert({ ...shared, ...options.loading, type: "loading" });
|
|
258
|
-
runIfFn(promise).then((response) => {
|
|
259
|
-
const successOptions = runIfFn(options.success, response);
|
|
260
|
-
upsert({ ...shared, ...successOptions, id, type: "success" });
|
|
261
|
-
}).catch((error) => {
|
|
262
|
-
const errorOptions = runIfFn(options.error, error);
|
|
263
|
-
upsert({ ...shared, ...errorOptions, id, type: "error" });
|
|
264
|
-
}).finally(() => {
|
|
265
|
-
options.finally?.();
|
|
266
|
-
});
|
|
267
|
-
return id;
|
|
268
|
-
},
|
|
269
|
-
pause(id) {
|
|
270
|
-
if (id == null) {
|
|
271
|
-
send("PAUSE_ALL");
|
|
272
|
-
} else if (isVisible(id)) {
|
|
273
|
-
send({ type: "PAUSE_TOAST", id });
|
|
274
|
-
}
|
|
275
|
-
},
|
|
276
|
-
resume(id) {
|
|
277
|
-
if (id == null) {
|
|
278
|
-
send("RESUME_ALL");
|
|
279
|
-
} else if (isVisible(id)) {
|
|
280
|
-
send({ type: "RESUME_TOAST", id });
|
|
281
|
-
}
|
|
282
|
-
},
|
|
283
|
-
getGroupProps(options) {
|
|
284
|
-
const { placement, label = "Notifications" } = options;
|
|
285
|
-
const state = getState();
|
|
286
|
-
const hotkeyLabel = state.context.hotkey.join("+").replace(/Key/g, "").replace(/Digit/g, "");
|
|
202
|
+
getGroupProps(options = {}) {
|
|
203
|
+
const { label = "Notifications" } = options;
|
|
204
|
+
const { hotkey } = prop("store").attrs;
|
|
205
|
+
const hotkeyLabel = hotkey.join("+").replace(/Key/g, "").replace(/Digit/g, "");
|
|
206
|
+
const placement = computed("placement");
|
|
287
207
|
const [side, align = "center"] = placement.split("-");
|
|
288
208
|
return normalize.element({
|
|
289
209
|
...parts.group.attrs,
|
|
290
|
-
dir:
|
|
210
|
+
dir: prop("dir"),
|
|
291
211
|
tabIndex: -1,
|
|
292
212
|
"aria-label": `${placement} ${label} ${hotkeyLabel}`,
|
|
293
|
-
id:
|
|
213
|
+
id: getRegionId(placement),
|
|
294
214
|
"data-placement": placement,
|
|
295
215
|
"data-side": side,
|
|
296
216
|
"data-align": align,
|
|
297
217
|
"aria-live": "polite",
|
|
298
218
|
role: "region",
|
|
299
|
-
style: getGroupPlacementStyle(
|
|
219
|
+
style: getGroupPlacementStyle(service, placement),
|
|
300
220
|
onMouseMove() {
|
|
301
221
|
send({ type: "REGION.POINTER_ENTER", placement });
|
|
302
222
|
},
|
|
@@ -307,534 +227,294 @@ function groupConnect(serviceOrState, send, normalize) {
|
|
|
307
227
|
send({ type: "REGION.FOCUS", target: event.relatedTarget });
|
|
308
228
|
},
|
|
309
229
|
onBlur(event) {
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
230
|
+
queueMicrotask(() => {
|
|
231
|
+
if (refs.get("isFocusWithin") && !contains(event.currentTarget, event.relatedTarget)) {
|
|
232
|
+
send({ type: "REGION.BLUR" });
|
|
233
|
+
}
|
|
234
|
+
});
|
|
313
235
|
}
|
|
314
236
|
});
|
|
315
237
|
},
|
|
316
238
|
subscribe(fn) {
|
|
317
|
-
const
|
|
318
|
-
return subscribe(
|
|
319
|
-
const toasts = getToastsByPlacementImpl(state.context.placement);
|
|
320
|
-
const contexts = toasts.map((toast) => toast.getState().context);
|
|
321
|
-
fn(contexts);
|
|
322
|
-
});
|
|
239
|
+
const store = prop("store");
|
|
240
|
+
return store.subscribe(() => fn(context.get("toasts")));
|
|
323
241
|
}
|
|
324
242
|
};
|
|
325
243
|
}
|
|
326
|
-
var
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
244
|
+
var groupMachine = createMachine({
|
|
245
|
+
props({ props }) {
|
|
246
|
+
return {
|
|
247
|
+
dir: "ltr",
|
|
248
|
+
id: uuid(),
|
|
249
|
+
...props,
|
|
250
|
+
store: props.store
|
|
251
|
+
};
|
|
252
|
+
},
|
|
253
|
+
initialState({ prop }) {
|
|
254
|
+
return prop("store").attrs.overlap ? "overlap" : "stack";
|
|
255
|
+
},
|
|
256
|
+
refs() {
|
|
257
|
+
return {
|
|
258
|
+
lastFocusedEl: null,
|
|
259
|
+
isFocusWithin: false,
|
|
260
|
+
dismissableCleanup: void 0
|
|
261
|
+
};
|
|
262
|
+
},
|
|
263
|
+
context({ bindable }) {
|
|
264
|
+
return {
|
|
265
|
+
toasts: bindable(() => ({
|
|
266
|
+
defaultValue: [],
|
|
267
|
+
sync: true,
|
|
268
|
+
hash: (toasts) => toasts.map((t) => t.id).join(",")
|
|
269
|
+
})),
|
|
270
|
+
heights: bindable(() => ({
|
|
271
|
+
defaultValue: [],
|
|
272
|
+
sync: true
|
|
273
|
+
}))
|
|
274
|
+
};
|
|
275
|
+
},
|
|
276
|
+
computed: {
|
|
277
|
+
count: ({ context }) => context.get("toasts").length,
|
|
278
|
+
overlap: ({ prop }) => prop("store").attrs.overlap,
|
|
279
|
+
placement: ({ prop }) => prop("store").attrs.placement
|
|
280
|
+
},
|
|
281
|
+
effects: ["subscribeToStore", "trackDocumentVisibility", "trackHotKeyPress"],
|
|
282
|
+
watch({ track, context, action }) {
|
|
283
|
+
track([() => context.hash("toasts")], () => {
|
|
284
|
+
queueMicrotask(() => {
|
|
285
|
+
action(["collapsedIfEmpty", "setDismissableBranch"]);
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
},
|
|
289
|
+
exit: ["clearDismissableBranch", "clearLastFocusedEl"],
|
|
290
|
+
on: {
|
|
291
|
+
"DOC.HOTKEY": {
|
|
292
|
+
actions: ["focusRegionEl"]
|
|
293
|
+
},
|
|
294
|
+
"REGION.BLUR": [
|
|
295
|
+
{
|
|
296
|
+
guard: "isOverlapping",
|
|
297
|
+
target: "overlap",
|
|
298
|
+
actions: ["collapseToasts", "resumeToasts", "restoreLastFocusedEl"]
|
|
349
299
|
},
|
|
350
|
-
|
|
300
|
+
{
|
|
301
|
+
target: "stack",
|
|
302
|
+
actions: ["resumeToasts", "restoreLastFocusedEl"]
|
|
303
|
+
}
|
|
304
|
+
],
|
|
305
|
+
"TOAST.REMOVE": {
|
|
306
|
+
actions: ["removeToast", "removeHeight"]
|
|
307
|
+
},
|
|
308
|
+
"TOAST.PAUSE": {
|
|
309
|
+
actions: ["pauseToasts"]
|
|
310
|
+
}
|
|
311
|
+
},
|
|
312
|
+
states: {
|
|
313
|
+
stack: {
|
|
351
314
|
on: {
|
|
352
|
-
|
|
315
|
+
"REGION.POINTER_LEAVE": [
|
|
353
316
|
{
|
|
354
|
-
guard:
|
|
355
|
-
target: "
|
|
356
|
-
actions: ["
|
|
357
|
-
},
|
|
358
|
-
{
|
|
359
|
-
guard: or("hasDurationChanged", "hasTypeChanged"),
|
|
360
|
-
target: "visible:updating",
|
|
361
|
-
actions: ["setContext"]
|
|
317
|
+
guard: "isOverlapping",
|
|
318
|
+
target: "overlap",
|
|
319
|
+
actions: ["resumeToasts", "collapseToasts"]
|
|
362
320
|
},
|
|
363
321
|
{
|
|
364
|
-
actions: ["
|
|
322
|
+
actions: ["resumeToasts"]
|
|
365
323
|
}
|
|
366
324
|
],
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
},
|
|
371
|
-
entry: ["invokeOnVisible"],
|
|
372
|
-
activities: ["trackHeight"],
|
|
373
|
-
states: {
|
|
374
|
-
"visible:updating": {
|
|
375
|
-
tags: ["visible", "updating"],
|
|
376
|
-
after: {
|
|
377
|
-
0: "visible"
|
|
378
|
-
}
|
|
325
|
+
"REGION.OVERLAP": {
|
|
326
|
+
target: "overlap",
|
|
327
|
+
actions: ["collapseToasts"]
|
|
379
328
|
},
|
|
380
|
-
"
|
|
381
|
-
|
|
382
|
-
on: {
|
|
383
|
-
RESUME: {
|
|
384
|
-
guard: not("isLoadingType"),
|
|
385
|
-
target: "visible",
|
|
386
|
-
actions: ["setCreatedAt"]
|
|
387
|
-
},
|
|
388
|
-
DISMISS: "dismissing"
|
|
389
|
-
}
|
|
329
|
+
"REGION.FOCUS": {
|
|
330
|
+
actions: ["setLastFocusedEl", "pauseToasts"]
|
|
390
331
|
},
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
}
|
|
402
|
-
}
|
|
332
|
+
"REGION.POINTER_ENTER": {
|
|
333
|
+
actions: ["pauseToasts"]
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
},
|
|
337
|
+
overlap: {
|
|
338
|
+
on: {
|
|
339
|
+
"REGION.STACK": {
|
|
340
|
+
target: "stack",
|
|
341
|
+
actions: ["expandToasts"]
|
|
403
342
|
},
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
REMOVE_DELAY: {
|
|
408
|
-
target: "unmounted",
|
|
409
|
-
actions: "notifyParentToRemove"
|
|
410
|
-
}
|
|
411
|
-
}
|
|
343
|
+
"REGION.POINTER_ENTER": {
|
|
344
|
+
target: "stack",
|
|
345
|
+
actions: ["pauseToasts", "expandToasts"]
|
|
412
346
|
},
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
347
|
+
"REGION.FOCUS": {
|
|
348
|
+
target: "stack",
|
|
349
|
+
actions: ["setLastFocusedEl", "pauseToasts", "expandToasts"]
|
|
416
350
|
}
|
|
417
351
|
}
|
|
352
|
+
}
|
|
353
|
+
},
|
|
354
|
+
implementations: {
|
|
355
|
+
guards: {
|
|
356
|
+
isOverlapping: ({ computed }) => computed("overlap")
|
|
418
357
|
},
|
|
419
|
-
{
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
const
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
const syncHeight = () => {
|
|
433
|
-
const originalHeight = rootEl.style.height;
|
|
434
|
-
rootEl.style.height = "auto";
|
|
435
|
-
const newHeight = rootEl.getBoundingClientRect().height;
|
|
436
|
-
rootEl.style.height = originalHeight;
|
|
437
|
-
ctx2.height = newHeight;
|
|
438
|
-
self.sendParent({ type: "UPDATE_HEIGHT", id: self.id, height: newHeight, placement: ctx2.placement });
|
|
439
|
-
};
|
|
440
|
-
syncHeight();
|
|
441
|
-
const win = dom.getWin(ctx2);
|
|
442
|
-
const observer = new win.MutationObserver(syncHeight);
|
|
443
|
-
observer.observe(rootEl, { childList: true, subtree: true, characterData: true });
|
|
444
|
-
cleanup = () => observer.disconnect();
|
|
358
|
+
effects: {
|
|
359
|
+
subscribeToStore({ context, prop }) {
|
|
360
|
+
return prop("store").subscribe((toast) => {
|
|
361
|
+
if (toast.dismiss) {
|
|
362
|
+
context.set("toasts", (prev) => prev.filter((t) => t.id !== toast.id));
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
context.set("toasts", (prev) => {
|
|
366
|
+
const index = prev.findIndex((t) => t.id === toast.id);
|
|
367
|
+
if (index !== -1) {
|
|
368
|
+
return [...prev.slice(0, index), { ...prev[index], ...toast }, ...prev.slice(index + 1)];
|
|
369
|
+
}
|
|
370
|
+
return [toast, ...prev];
|
|
445
371
|
});
|
|
446
|
-
|
|
372
|
+
});
|
|
373
|
+
},
|
|
374
|
+
trackHotKeyPress({ prop, send }) {
|
|
375
|
+
const handleKeyDown = (event) => {
|
|
376
|
+
const { hotkey } = prop("store").attrs;
|
|
377
|
+
const isHotkeyPressed = hotkey.every((key) => event[key] || event.code === key);
|
|
378
|
+
if (!isHotkeyPressed) return;
|
|
379
|
+
send({ type: "DOC.HOTKEY" });
|
|
380
|
+
};
|
|
381
|
+
return addDomEvent(document, "keydown", handleKeyDown, { capture: true });
|
|
382
|
+
},
|
|
383
|
+
trackDocumentVisibility({ prop, send, scope }) {
|
|
384
|
+
const { pauseOnPageIdle } = prop("store").attrs;
|
|
385
|
+
if (!pauseOnPageIdle) return;
|
|
386
|
+
const doc = scope.getDoc();
|
|
387
|
+
return addDomEvent(doc, "visibilitychange", () => {
|
|
388
|
+
const isHidden = doc.visibilityState === "hidden";
|
|
389
|
+
send({ type: isHidden ? "PAUSE_ALL" : "RESUME_ALL" });
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
},
|
|
393
|
+
actions: {
|
|
394
|
+
setDismissableBranch({ refs, context, computed, scope }) {
|
|
395
|
+
const toasts = context.get("toasts");
|
|
396
|
+
const placement = computed("placement");
|
|
397
|
+
const hasToasts = toasts.length > 0;
|
|
398
|
+
if (!hasToasts) {
|
|
399
|
+
refs.get("dismissableCleanup")?.();
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
if (hasToasts && refs.get("dismissableCleanup")) {
|
|
403
|
+
return;
|
|
447
404
|
}
|
|
405
|
+
const groupEl = () => getRegionEl(scope, placement);
|
|
406
|
+
const cleanup = trackDismissableBranch(groupEl, { defer: true });
|
|
407
|
+
refs.set("dismissableCleanup", cleanup);
|
|
448
408
|
},
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
isLoadingType: (ctx2) => ctx2.type === "loading",
|
|
452
|
-
hasTypeChanged: (ctx2, evt) => evt.toast?.type != null && evt.toast.type !== ctx2.type,
|
|
453
|
-
hasDurationChanged: (ctx2, evt) => evt.toast?.duration != null && evt.toast.duration !== ctx2.duration
|
|
409
|
+
clearDismissableBranch({ refs }) {
|
|
410
|
+
refs.get("dismissableCleanup")?.();
|
|
454
411
|
},
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
412
|
+
focusRegionEl({ scope, computed }) {
|
|
413
|
+
queueMicrotask(() => {
|
|
414
|
+
getRegionEl(scope, computed("placement"))?.focus();
|
|
415
|
+
});
|
|
458
416
|
},
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
raf(() => {
|
|
462
|
-
const rootEl = dom.getRootEl(ctx2);
|
|
463
|
-
if (!rootEl) return;
|
|
464
|
-
ctx2.mounted = true;
|
|
465
|
-
const originalHeight = rootEl.style.height;
|
|
466
|
-
rootEl.style.height = "auto";
|
|
467
|
-
const newHeight = rootEl.getBoundingClientRect().height;
|
|
468
|
-
rootEl.style.height = originalHeight;
|
|
469
|
-
ctx2.height = newHeight;
|
|
470
|
-
self.sendParent({ type: "UPDATE_HEIGHT", id: self.id, height: newHeight, placement: ctx2.placement });
|
|
471
|
-
});
|
|
472
|
-
},
|
|
473
|
-
setRemainingDuration(ctx2) {
|
|
474
|
-
ctx2.remaining -= Date.now() - ctx2.createdAt;
|
|
475
|
-
},
|
|
476
|
-
setCreatedAt(ctx2) {
|
|
477
|
-
ctx2.createdAt = Date.now();
|
|
478
|
-
},
|
|
479
|
-
notifyParentToRemove(_ctx, _evt, { self }) {
|
|
480
|
-
self.sendParent({ type: "REMOVE_TOAST", id: self.id });
|
|
481
|
-
},
|
|
482
|
-
invokeOnDismiss(ctx2) {
|
|
483
|
-
ctx2.onStatusChange?.({ status: "dismissing" });
|
|
484
|
-
},
|
|
485
|
-
invokeOnUnmount(ctx2) {
|
|
486
|
-
ctx2.onStatusChange?.({ status: "unmounted" });
|
|
487
|
-
},
|
|
488
|
-
invokeOnVisible(ctx2) {
|
|
489
|
-
ctx2.onStatusChange?.({ status: "visible" });
|
|
490
|
-
},
|
|
491
|
-
setContext(ctx2, evt) {
|
|
492
|
-
const duration2 = evt.toast?.duration;
|
|
493
|
-
const type2 = evt.toast?.type ?? ctx2.type;
|
|
494
|
-
const computedDuration2 = getToastDuration(duration2, type2);
|
|
495
|
-
Object.assign(ctx2, {
|
|
496
|
-
...evt.toast,
|
|
497
|
-
duration: computedDuration2,
|
|
498
|
-
remaining: computedDuration2
|
|
499
|
-
});
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
);
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
// src/toast-group.machine.ts
|
|
507
|
-
function groupMachine(userContext) {
|
|
508
|
-
const ctx = compact(userContext);
|
|
509
|
-
return createMachine(
|
|
510
|
-
{
|
|
511
|
-
id: "toaster",
|
|
512
|
-
initial: ctx.overlap ? "overlap" : "stack",
|
|
513
|
-
context: {
|
|
514
|
-
dir: "ltr",
|
|
515
|
-
max: Number.MAX_SAFE_INTEGER,
|
|
516
|
-
gap: 16,
|
|
517
|
-
pauseOnPageIdle: false,
|
|
518
|
-
hotkey: ["altKey", "KeyT"],
|
|
519
|
-
offsets: "1rem",
|
|
520
|
-
placement: "bottom",
|
|
521
|
-
removeDelay: 200,
|
|
522
|
-
...ctx,
|
|
523
|
-
toasts: [],
|
|
524
|
-
lastFocusedEl: null,
|
|
525
|
-
isFocusWithin: false,
|
|
526
|
-
heights: []
|
|
417
|
+
pauseToasts({ prop }) {
|
|
418
|
+
prop("store").pause();
|
|
527
419
|
},
|
|
528
|
-
|
|
529
|
-
|
|
420
|
+
resumeToasts({ prop }) {
|
|
421
|
+
prop("store").resume();
|
|
530
422
|
},
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
toasts: ["collapsedIfEmpty", "setDismissableBranch"]
|
|
423
|
+
expandToasts({ prop }) {
|
|
424
|
+
prop("store").expand();
|
|
534
425
|
},
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
PAUSE_TOAST: {
|
|
538
|
-
actions: ["pauseToast"]
|
|
539
|
-
},
|
|
540
|
-
PAUSE_ALL: {
|
|
541
|
-
actions: ["pauseToasts"]
|
|
542
|
-
},
|
|
543
|
-
RESUME_TOAST: {
|
|
544
|
-
actions: ["resumeToast"]
|
|
545
|
-
},
|
|
546
|
-
RESUME_ALL: {
|
|
547
|
-
actions: ["resumeToasts"]
|
|
548
|
-
},
|
|
549
|
-
ADD_TOAST: {
|
|
550
|
-
guard: "isWithinRange",
|
|
551
|
-
actions: ["createToast", "syncToastIndex"]
|
|
552
|
-
},
|
|
553
|
-
UPDATE_TOAST: {
|
|
554
|
-
actions: ["updateToast"]
|
|
555
|
-
},
|
|
556
|
-
DISMISS_TOAST: {
|
|
557
|
-
actions: ["dismissToast"]
|
|
558
|
-
},
|
|
559
|
-
DISMISS_ALL: {
|
|
560
|
-
actions: ["dismissToasts"]
|
|
561
|
-
},
|
|
562
|
-
REMOVE_TOAST: {
|
|
563
|
-
actions: ["removeToast", "syncToastIndex", "syncToastOffset"]
|
|
564
|
-
},
|
|
565
|
-
REMOVE_ALL: {
|
|
566
|
-
actions: ["removeToasts"]
|
|
567
|
-
},
|
|
568
|
-
UPDATE_HEIGHT: {
|
|
569
|
-
actions: ["syncHeights", "syncToastOffset"]
|
|
570
|
-
},
|
|
571
|
-
"DOC.HOTKEY": {
|
|
572
|
-
actions: ["focusRegionEl"]
|
|
573
|
-
},
|
|
574
|
-
"REGION.BLUR": [
|
|
575
|
-
{
|
|
576
|
-
guard: "isOverlapping",
|
|
577
|
-
target: "overlap",
|
|
578
|
-
actions: ["resumeToasts", "restoreLastFocusedEl"]
|
|
579
|
-
},
|
|
580
|
-
{
|
|
581
|
-
actions: ["resumeToasts", "restoreLastFocusedEl"]
|
|
582
|
-
}
|
|
583
|
-
]
|
|
426
|
+
collapseToasts({ prop }) {
|
|
427
|
+
prop("store").collapse();
|
|
584
428
|
},
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
entry: ["expandToasts"],
|
|
588
|
-
on: {
|
|
589
|
-
"REGION.POINTER_LEAVE": [
|
|
590
|
-
{
|
|
591
|
-
guard: "isOverlapping",
|
|
592
|
-
target: "overlap",
|
|
593
|
-
actions: ["resumeToasts"]
|
|
594
|
-
},
|
|
595
|
-
{
|
|
596
|
-
actions: ["resumeToasts"]
|
|
597
|
-
}
|
|
598
|
-
],
|
|
599
|
-
"REGION.OVERLAP": {
|
|
600
|
-
target: "overlap"
|
|
601
|
-
},
|
|
602
|
-
"REGION.FOCUS": {
|
|
603
|
-
actions: ["setLastFocusedEl", "pauseToasts"]
|
|
604
|
-
},
|
|
605
|
-
"REGION.POINTER_ENTER": {
|
|
606
|
-
actions: ["pauseToasts"]
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
},
|
|
610
|
-
overlap: {
|
|
611
|
-
entry: ["collapseToasts"],
|
|
612
|
-
on: {
|
|
613
|
-
"REGION.STACK": {
|
|
614
|
-
target: "stack"
|
|
615
|
-
},
|
|
616
|
-
"REGION.POINTER_ENTER": {
|
|
617
|
-
target: "stack",
|
|
618
|
-
actions: ["pauseToasts"]
|
|
619
|
-
},
|
|
620
|
-
"REGION.FOCUS": {
|
|
621
|
-
target: "stack",
|
|
622
|
-
actions: ["setLastFocusedEl", "pauseToasts"]
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
},
|
|
628
|
-
{
|
|
629
|
-
guards: {
|
|
630
|
-
isWithinRange: (ctx2) => ctx2.toasts.length < ctx2.max,
|
|
631
|
-
isOverlapping: (ctx2) => !!ctx2.overlap
|
|
429
|
+
removeToast({ prop, event }) {
|
|
430
|
+
prop("store").remove(event.id);
|
|
632
431
|
},
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
send({ type: "DOC.HOTKEY" });
|
|
639
|
-
};
|
|
640
|
-
return addDomEvent(document, "keydown", handleKeyDown, { capture: true });
|
|
641
|
-
},
|
|
642
|
-
trackDocumentVisibility(ctx2, _evt, { send }) {
|
|
643
|
-
if (!ctx2.pauseOnPageIdle) return;
|
|
644
|
-
const doc = dom.getDoc(ctx2);
|
|
645
|
-
return addDomEvent(doc, "visibilitychange", () => {
|
|
646
|
-
send(doc.visibilityState === "hidden" ? "PAUSE_ALL" : "RESUME_ALL");
|
|
647
|
-
});
|
|
648
|
-
}
|
|
432
|
+
removeHeight({ event, context }) {
|
|
433
|
+
if (event?.id == null) return;
|
|
434
|
+
queueMicrotask(() => {
|
|
435
|
+
context.set("heights", (heights) => heights.filter((height) => height.id !== event.id));
|
|
436
|
+
});
|
|
649
437
|
},
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
});
|
|
671
|
-
},
|
|
672
|
-
expandToasts(ctx2) {
|
|
673
|
-
each(ctx2, (toast) => {
|
|
674
|
-
toast.state.context.stacked = true;
|
|
675
|
-
});
|
|
676
|
-
},
|
|
677
|
-
collapseToasts(ctx2) {
|
|
678
|
-
each(ctx2, (toast) => {
|
|
679
|
-
toast.state.context.stacked = false;
|
|
680
|
-
});
|
|
681
|
-
},
|
|
682
|
-
collapsedIfEmpty(ctx2, _evt, { send }) {
|
|
683
|
-
if (!ctx2.overlap || ctx2.toasts.length > 1) return;
|
|
684
|
-
send("REGION.OVERLAP");
|
|
685
|
-
},
|
|
686
|
-
pauseToast(_ctx, evt, { self }) {
|
|
687
|
-
self.sendChild("PAUSE", evt.id);
|
|
688
|
-
},
|
|
689
|
-
pauseToasts(ctx2) {
|
|
690
|
-
ctx2.toasts.forEach((toast) => toast.send("PAUSE"));
|
|
691
|
-
},
|
|
692
|
-
resumeToast(_ctx, evt, { self }) {
|
|
693
|
-
self.sendChild("RESUME", evt.id);
|
|
694
|
-
},
|
|
695
|
-
resumeToasts(ctx2) {
|
|
696
|
-
ctx2.toasts.forEach((toast) => toast.send("RESUME"));
|
|
697
|
-
},
|
|
698
|
-
measureToasts(ctx2) {
|
|
699
|
-
ctx2.toasts.forEach((toast) => toast.send("MEASURE"));
|
|
700
|
-
},
|
|
701
|
-
createToast(ctx2, evt, { self, getState }) {
|
|
702
|
-
const options = {
|
|
703
|
-
placement: ctx2.placement,
|
|
704
|
-
duration: ctx2.duration,
|
|
705
|
-
removeDelay: ctx2.removeDelay,
|
|
706
|
-
...evt.toast,
|
|
707
|
-
dir: ctx2.dir,
|
|
708
|
-
getRootNode: ctx2.getRootNode,
|
|
709
|
-
stacked: getState().matches("stack")
|
|
710
|
-
};
|
|
711
|
-
const toast = createToastMachine(options);
|
|
712
|
-
const actor = self.spawn(toast);
|
|
713
|
-
ctx2.toasts = [actor, ...ctx2.toasts];
|
|
714
|
-
},
|
|
715
|
-
updateToast(_ctx, evt, { self }) {
|
|
716
|
-
self.sendChild({ type: "UPDATE", toast: evt.toast }, evt.id);
|
|
717
|
-
},
|
|
718
|
-
dismissToast(_ctx, evt, { self }) {
|
|
719
|
-
self.sendChild("DISMISS", evt.id);
|
|
720
|
-
},
|
|
721
|
-
dismissToasts(ctx2) {
|
|
722
|
-
ctx2.toasts.forEach((toast) => toast.send("DISMISS"));
|
|
723
|
-
},
|
|
724
|
-
removeToast(ctx2, evt, { self }) {
|
|
725
|
-
self.stopChild(evt.id);
|
|
726
|
-
ctx2.toasts = ctx2.toasts.filter((toast) => toast.id !== evt.id);
|
|
727
|
-
ctx2.heights = ctx2.heights.filter((height) => height.id !== evt.id);
|
|
728
|
-
},
|
|
729
|
-
removeToasts(ctx2, _evt, { self }) {
|
|
730
|
-
ctx2.toasts.forEach((toast) => self.stopChild(toast.id));
|
|
731
|
-
ctx2.toasts = [];
|
|
732
|
-
ctx2.heights = [];
|
|
733
|
-
},
|
|
734
|
-
syncHeights(ctx2, evt) {
|
|
735
|
-
const existing = ctx2.heights.find((height) => height.id === evt.id);
|
|
736
|
-
if (existing) {
|
|
737
|
-
existing.height = evt.height;
|
|
738
|
-
existing.placement = evt.placement;
|
|
739
|
-
} else {
|
|
740
|
-
const newHeight = { id: evt.id, height: evt.height, placement: evt.placement };
|
|
741
|
-
ctx2.heights = [newHeight, ...ctx2.heights];
|
|
742
|
-
}
|
|
743
|
-
},
|
|
744
|
-
syncToastIndex(ctx2) {
|
|
745
|
-
each(ctx2, (toast, index, toasts) => {
|
|
746
|
-
toast.state.context.index = index;
|
|
747
|
-
toast.state.context.frontmost = index === 0;
|
|
748
|
-
toast.state.context.zIndex = toasts.length - index;
|
|
749
|
-
});
|
|
750
|
-
},
|
|
751
|
-
syncToastOffset(ctx2, evt) {
|
|
752
|
-
const placement = evt.placement ?? ctx2.placement;
|
|
753
|
-
each({ ...ctx2, placement }, (toast) => {
|
|
754
|
-
const heightIndex = Math.max(
|
|
755
|
-
ctx2.heights.findIndex((height) => height.id === toast.id),
|
|
756
|
-
0
|
|
757
|
-
);
|
|
758
|
-
const toastsHeightBefore = ctx2.heights.reduce((prev, curr, reducerIndex) => {
|
|
759
|
-
if (reducerIndex >= heightIndex) return prev;
|
|
760
|
-
return prev + curr.height;
|
|
761
|
-
}, 0);
|
|
762
|
-
toast.state.context.offset = heightIndex * ctx2.gap + toastsHeightBefore;
|
|
763
|
-
});
|
|
764
|
-
},
|
|
765
|
-
setLastFocusedEl(ctx2, evt) {
|
|
766
|
-
if (ctx2.isFocusWithin || !evt.target) return;
|
|
767
|
-
ctx2.isFocusWithin = true;
|
|
768
|
-
ctx2.lastFocusedEl = ref(evt.target);
|
|
769
|
-
},
|
|
770
|
-
restoreLastFocusedEl(ctx2) {
|
|
771
|
-
ctx2.isFocusWithin = false;
|
|
772
|
-
if (!ctx2.lastFocusedEl) return;
|
|
773
|
-
ctx2.lastFocusedEl.focus({ preventScroll: true });
|
|
774
|
-
ctx2.lastFocusedEl = null;
|
|
775
|
-
},
|
|
776
|
-
clearLastFocusedEl(ctx2) {
|
|
777
|
-
if (!ctx2.lastFocusedEl) return;
|
|
778
|
-
ctx2.lastFocusedEl.focus({ preventScroll: true });
|
|
779
|
-
ctx2.lastFocusedEl = null;
|
|
780
|
-
ctx2.isFocusWithin = false;
|
|
781
|
-
}
|
|
438
|
+
collapsedIfEmpty({ send, computed }) {
|
|
439
|
+
if (!computed("overlap") || computed("count") > 1) return;
|
|
440
|
+
send({ type: "REGION.OVERLAP" });
|
|
441
|
+
},
|
|
442
|
+
setLastFocusedEl({ refs, event }) {
|
|
443
|
+
if (refs.get("isFocusWithin") || !event.target) return;
|
|
444
|
+
refs.set("isFocusWithin", true);
|
|
445
|
+
refs.set("lastFocusedEl", event.target);
|
|
446
|
+
},
|
|
447
|
+
restoreLastFocusedEl({ refs }) {
|
|
448
|
+
if (!refs.get("lastFocusedEl")) return;
|
|
449
|
+
refs.get("lastFocusedEl")?.focus({ preventScroll: true });
|
|
450
|
+
refs.set("lastFocusedEl", null);
|
|
451
|
+
refs.set("isFocusWithin", false);
|
|
452
|
+
},
|
|
453
|
+
clearLastFocusedEl({ refs }) {
|
|
454
|
+
if (!refs.get("lastFocusedEl")) return;
|
|
455
|
+
refs.get("lastFocusedEl")?.focus({ preventScroll: true });
|
|
456
|
+
refs.set("lastFocusedEl", null);
|
|
457
|
+
refs.set("isFocusWithin", false);
|
|
782
458
|
}
|
|
783
459
|
}
|
|
784
|
-
|
|
785
|
-
}
|
|
786
|
-
function
|
|
787
|
-
const
|
|
788
|
-
currentToasts.forEach(fn);
|
|
789
|
-
}
|
|
790
|
-
function connect(state, send, normalize) {
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
function connect(service, normalize) {
|
|
463
|
+
const { state, send, prop, scope, context, computed } = service;
|
|
791
464
|
const visible = state.hasTag("visible");
|
|
792
465
|
const paused = state.hasTag("paused");
|
|
793
|
-
const
|
|
794
|
-
const
|
|
466
|
+
const mounted = context.get("mounted");
|
|
467
|
+
const frontmost = computed("frontmost");
|
|
468
|
+
const placement = prop("parent").computed("placement");
|
|
469
|
+
const type = prop("type");
|
|
470
|
+
const stacked = prop("stacked");
|
|
471
|
+
const title = prop("title");
|
|
472
|
+
const description = prop("description");
|
|
473
|
+
const action = prop("action");
|
|
795
474
|
const [side, align = "center"] = placement.split("-");
|
|
796
475
|
return {
|
|
797
476
|
type,
|
|
798
|
-
title
|
|
799
|
-
description
|
|
477
|
+
title,
|
|
478
|
+
description,
|
|
800
479
|
placement,
|
|
801
480
|
visible,
|
|
802
481
|
paused,
|
|
482
|
+
closable: !!prop("closable"),
|
|
803
483
|
pause() {
|
|
804
|
-
send("PAUSE");
|
|
484
|
+
send({ type: "PAUSE" });
|
|
805
485
|
},
|
|
806
486
|
resume() {
|
|
807
|
-
send("RESUME");
|
|
487
|
+
send({ type: "RESUME" });
|
|
808
488
|
},
|
|
809
489
|
dismiss() {
|
|
810
|
-
send("DISMISS");
|
|
490
|
+
send({ type: "DISMISS", src: "programmatic" });
|
|
811
491
|
},
|
|
812
492
|
getRootProps() {
|
|
813
493
|
return normalize.element({
|
|
814
494
|
...parts.root.attrs,
|
|
815
|
-
dir:
|
|
816
|
-
id:
|
|
495
|
+
dir: prop("dir"),
|
|
496
|
+
id: getRootId(scope),
|
|
817
497
|
"data-state": visible ? "open" : "closed",
|
|
818
498
|
"data-type": type,
|
|
819
499
|
"data-placement": placement,
|
|
820
500
|
"data-align": align,
|
|
821
501
|
"data-side": side,
|
|
822
|
-
"data-mounted": dataAttr(
|
|
502
|
+
"data-mounted": dataAttr(mounted),
|
|
823
503
|
"data-paused": dataAttr(paused),
|
|
824
|
-
"data-first": dataAttr(
|
|
825
|
-
"data-sibling": dataAttr(!
|
|
826
|
-
"data-stack": dataAttr(
|
|
827
|
-
"data-overlap": dataAttr(!
|
|
504
|
+
"data-first": dataAttr(frontmost),
|
|
505
|
+
"data-sibling": dataAttr(!frontmost),
|
|
506
|
+
"data-stack": dataAttr(stacked),
|
|
507
|
+
"data-overlap": dataAttr(!stacked),
|
|
828
508
|
role: "status",
|
|
829
509
|
"aria-atomic": "true",
|
|
830
|
-
"aria-describedby":
|
|
831
|
-
"aria-labelledby":
|
|
510
|
+
"aria-describedby": description ? getDescriptionId(scope) : void 0,
|
|
511
|
+
"aria-labelledby": title ? getTitleId(scope) : void 0,
|
|
832
512
|
tabIndex: 0,
|
|
833
|
-
style: getPlacementStyle(
|
|
513
|
+
style: getPlacementStyle(service, visible),
|
|
834
514
|
onKeyDown(event) {
|
|
835
515
|
if (event.defaultPrevented) return;
|
|
836
516
|
if (event.key == "Escape") {
|
|
837
|
-
send("DISMISS");
|
|
517
|
+
send({ type: "DISMISS", src: "keyboard" });
|
|
838
518
|
event.preventDefault();
|
|
839
519
|
}
|
|
840
520
|
}
|
|
@@ -844,7 +524,7 @@ function connect(state, send, normalize) {
|
|
|
844
524
|
getGhostBeforeProps() {
|
|
845
525
|
return normalize.element({
|
|
846
526
|
"data-ghost": "before",
|
|
847
|
-
style: getGhostBeforeStyle(
|
|
527
|
+
style: getGhostBeforeStyle(service, visible)
|
|
848
528
|
});
|
|
849
529
|
},
|
|
850
530
|
/* Needed to avoid setting hover to false when in between toasts */
|
|
@@ -857,13 +537,13 @@ function connect(state, send, normalize) {
|
|
|
857
537
|
getTitleProps() {
|
|
858
538
|
return normalize.element({
|
|
859
539
|
...parts.title.attrs,
|
|
860
|
-
id:
|
|
540
|
+
id: getTitleId(scope)
|
|
861
541
|
});
|
|
862
542
|
},
|
|
863
543
|
getDescriptionProps() {
|
|
864
544
|
return normalize.element({
|
|
865
545
|
...parts.description.attrs,
|
|
866
|
-
id:
|
|
546
|
+
id: getDescriptionId(scope)
|
|
867
547
|
});
|
|
868
548
|
},
|
|
869
549
|
getActionTriggerProps() {
|
|
@@ -872,25 +552,479 @@ function connect(state, send, normalize) {
|
|
|
872
552
|
type: "button",
|
|
873
553
|
onClick(event) {
|
|
874
554
|
if (event.defaultPrevented) return;
|
|
875
|
-
|
|
876
|
-
send("DISMISS");
|
|
555
|
+
action?.onClick?.();
|
|
556
|
+
send({ type: "DISMISS", src: "user" });
|
|
877
557
|
}
|
|
878
558
|
});
|
|
879
559
|
},
|
|
880
560
|
getCloseTriggerProps() {
|
|
881
561
|
return normalize.button({
|
|
882
|
-
id:
|
|
562
|
+
id: getCloseTriggerId(scope),
|
|
883
563
|
...parts.closeTrigger.attrs,
|
|
884
564
|
type: "button",
|
|
885
565
|
"aria-label": "Dismiss notification",
|
|
886
566
|
onClick(event) {
|
|
887
567
|
if (event.defaultPrevented) return;
|
|
888
|
-
send("DISMISS");
|
|
568
|
+
send({ type: "DISMISS", src: "user" });
|
|
569
|
+
}
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
var { not } = createGuards();
|
|
575
|
+
var machine = createMachine({
|
|
576
|
+
props({ props }) {
|
|
577
|
+
return {
|
|
578
|
+
...props,
|
|
579
|
+
id: props.id,
|
|
580
|
+
type: props.type,
|
|
581
|
+
parent: props.parent,
|
|
582
|
+
closable: props.closable ?? true,
|
|
583
|
+
duration: getToastDuration(props.duration, props.type)
|
|
584
|
+
};
|
|
585
|
+
},
|
|
586
|
+
initialState({ prop }) {
|
|
587
|
+
const persist = prop("type") === "loading" || prop("duration") === Infinity;
|
|
588
|
+
return persist ? "visible:persist" : "visible";
|
|
589
|
+
},
|
|
590
|
+
context({ prop, bindable }) {
|
|
591
|
+
return {
|
|
592
|
+
remainingTime: bindable(() => ({
|
|
593
|
+
defaultValue: getToastDuration(prop("duration"), prop("type"))
|
|
594
|
+
})),
|
|
595
|
+
createdAt: bindable(() => ({
|
|
596
|
+
defaultValue: Date.now()
|
|
597
|
+
})),
|
|
598
|
+
mounted: bindable(() => ({
|
|
599
|
+
defaultValue: false
|
|
600
|
+
})),
|
|
601
|
+
initialHeight: bindable(() => ({
|
|
602
|
+
defaultValue: 0
|
|
603
|
+
}))
|
|
604
|
+
};
|
|
605
|
+
},
|
|
606
|
+
refs() {
|
|
607
|
+
return {
|
|
608
|
+
closeTimerStartTime: Date.now(),
|
|
609
|
+
lastCloseStartTimerStartTime: 0
|
|
610
|
+
};
|
|
611
|
+
},
|
|
612
|
+
computed: {
|
|
613
|
+
zIndex: ({ prop }) => {
|
|
614
|
+
const toasts = prop("parent").context.get("toasts");
|
|
615
|
+
const index = toasts.findIndex((toast) => toast.id === prop("id"));
|
|
616
|
+
return toasts.length - index;
|
|
617
|
+
},
|
|
618
|
+
height: ({ prop }) => {
|
|
619
|
+
const heights = prop("parent").context.get("heights");
|
|
620
|
+
const height = heights.find((height2) => height2.id === prop("id"));
|
|
621
|
+
return height?.height ?? 0;
|
|
622
|
+
},
|
|
623
|
+
heightIndex: ({ prop }) => {
|
|
624
|
+
const heights = prop("parent").context.get("heights");
|
|
625
|
+
return heights.findIndex((height) => height.id === prop("id"));
|
|
626
|
+
},
|
|
627
|
+
frontmost: ({ prop }) => prop("index") === 0,
|
|
628
|
+
heightBefore: ({ prop }) => {
|
|
629
|
+
const heights = prop("parent").context.get("heights");
|
|
630
|
+
const heightIndex = heights.findIndex((height) => height.id === prop("id"));
|
|
631
|
+
return heights.reduce((prev, curr, reducerIndex) => {
|
|
632
|
+
if (reducerIndex >= heightIndex) return prev;
|
|
633
|
+
return prev + curr.height;
|
|
634
|
+
}, 0);
|
|
635
|
+
},
|
|
636
|
+
shouldPersist: ({ prop }) => prop("type") === "loading" || prop("duration") === Infinity
|
|
637
|
+
},
|
|
638
|
+
watch({ track, prop, send }) {
|
|
639
|
+
track([() => prop("message")], () => {
|
|
640
|
+
const message = prop("message");
|
|
641
|
+
if (message) send({ type: message, src: "programmatic" });
|
|
642
|
+
});
|
|
643
|
+
track([() => prop("type"), () => prop("duration")], () => {
|
|
644
|
+
send({ type: "UPDATE" });
|
|
645
|
+
});
|
|
646
|
+
},
|
|
647
|
+
on: {
|
|
648
|
+
UPDATE: [
|
|
649
|
+
{
|
|
650
|
+
guard: "shouldPersist",
|
|
651
|
+
target: "visible:persist",
|
|
652
|
+
actions: ["resetCloseTimer"]
|
|
653
|
+
},
|
|
654
|
+
{
|
|
655
|
+
target: "visible:updating",
|
|
656
|
+
actions: ["resetCloseTimer"]
|
|
657
|
+
}
|
|
658
|
+
],
|
|
659
|
+
MEASURE: {
|
|
660
|
+
actions: ["measureHeight"]
|
|
661
|
+
}
|
|
662
|
+
},
|
|
663
|
+
entry: ["setMounted", "measureHeight", "invokeOnVisible"],
|
|
664
|
+
effects: ["trackHeight"],
|
|
665
|
+
states: {
|
|
666
|
+
"visible:updating": {
|
|
667
|
+
tags: ["visible", "updating"],
|
|
668
|
+
effects: ["waitForNextTick"],
|
|
669
|
+
on: {
|
|
670
|
+
SHOW: {
|
|
671
|
+
target: "visible"
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
},
|
|
675
|
+
"visible:persist": {
|
|
676
|
+
tags: ["visible", "paused"],
|
|
677
|
+
on: {
|
|
678
|
+
RESUME: {
|
|
679
|
+
guard: not("isLoadingType"),
|
|
680
|
+
target: "visible",
|
|
681
|
+
actions: ["setCloseTimer"]
|
|
682
|
+
},
|
|
683
|
+
DISMISS: {
|
|
684
|
+
target: "dismissing"
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
},
|
|
688
|
+
visible: {
|
|
689
|
+
tags: ["visible"],
|
|
690
|
+
effects: ["waitForDuration"],
|
|
691
|
+
on: {
|
|
692
|
+
DISMISS: {
|
|
693
|
+
target: "dismissing"
|
|
694
|
+
},
|
|
695
|
+
PAUSE: {
|
|
696
|
+
target: "visible:persist",
|
|
697
|
+
actions: ["syncRemainingTime"]
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
},
|
|
701
|
+
dismissing: {
|
|
702
|
+
entry: ["invokeOnDismiss"],
|
|
703
|
+
effects: ["waitForRemoveDelay"],
|
|
704
|
+
on: {
|
|
705
|
+
REMOVE: {
|
|
706
|
+
target: "unmounted",
|
|
707
|
+
actions: ["notifyParentToRemove"]
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
},
|
|
711
|
+
unmounted: {
|
|
712
|
+
entry: ["invokeOnUnmount"]
|
|
713
|
+
}
|
|
714
|
+
},
|
|
715
|
+
implementations: {
|
|
716
|
+
effects: {
|
|
717
|
+
waitForRemoveDelay({ prop, send }) {
|
|
718
|
+
return setRafTimeout(() => {
|
|
719
|
+
send({ type: "REMOVE", src: "timer" });
|
|
720
|
+
}, prop("removeDelay"));
|
|
721
|
+
},
|
|
722
|
+
waitForDuration({ send, context, computed }) {
|
|
723
|
+
if (computed("shouldPersist")) return;
|
|
724
|
+
return setRafTimeout(() => {
|
|
725
|
+
send({ type: "DISMISS", src: "timer" });
|
|
726
|
+
}, context.get("remainingTime"));
|
|
727
|
+
},
|
|
728
|
+
waitForNextTick({ send }) {
|
|
729
|
+
return setRafTimeout(() => {
|
|
730
|
+
send({ type: "SHOW", src: "timer" });
|
|
731
|
+
}, 0);
|
|
732
|
+
},
|
|
733
|
+
trackHeight({ scope, prop }) {
|
|
734
|
+
let cleanup;
|
|
735
|
+
raf(() => {
|
|
736
|
+
const rootEl = getRootEl(scope);
|
|
737
|
+
if (!rootEl) return;
|
|
738
|
+
const syncHeight = () => {
|
|
739
|
+
const originalHeight = rootEl.style.height;
|
|
740
|
+
rootEl.style.height = "auto";
|
|
741
|
+
const height = rootEl.getBoundingClientRect().height;
|
|
742
|
+
rootEl.style.height = originalHeight;
|
|
743
|
+
const item = { id: prop("id"), height };
|
|
744
|
+
setHeight(prop("parent"), item);
|
|
745
|
+
};
|
|
746
|
+
const win = scope.getWin();
|
|
747
|
+
const observer = new win.MutationObserver(syncHeight);
|
|
748
|
+
observer.observe(rootEl, {
|
|
749
|
+
childList: true,
|
|
750
|
+
subtree: true,
|
|
751
|
+
characterData: true
|
|
752
|
+
});
|
|
753
|
+
cleanup = () => observer.disconnect();
|
|
754
|
+
});
|
|
755
|
+
return () => cleanup?.();
|
|
756
|
+
}
|
|
757
|
+
},
|
|
758
|
+
guards: {
|
|
759
|
+
isLoadingType: ({ prop }) => prop("type") === "loading",
|
|
760
|
+
shouldPersist: ({ computed }) => computed("shouldPersist")
|
|
761
|
+
},
|
|
762
|
+
actions: {
|
|
763
|
+
setMounted({ context }) {
|
|
764
|
+
raf(() => {
|
|
765
|
+
context.set("mounted", true);
|
|
766
|
+
});
|
|
767
|
+
},
|
|
768
|
+
measureHeight({ scope, prop, context }) {
|
|
769
|
+
queueMicrotask(() => {
|
|
770
|
+
const rootEl = getRootEl(scope);
|
|
771
|
+
if (!rootEl) return;
|
|
772
|
+
const originalHeight = rootEl.style.height;
|
|
773
|
+
rootEl.style.height = "auto";
|
|
774
|
+
const height = rootEl.getBoundingClientRect().height;
|
|
775
|
+
rootEl.style.height = originalHeight;
|
|
776
|
+
context.set("initialHeight", height);
|
|
777
|
+
const item = { id: prop("id"), height };
|
|
778
|
+
setHeight(prop("parent"), item);
|
|
779
|
+
});
|
|
780
|
+
},
|
|
781
|
+
setCloseTimer({ refs }) {
|
|
782
|
+
refs.set("closeTimerStartTime", Date.now());
|
|
783
|
+
},
|
|
784
|
+
resetCloseTimer({ context, refs, prop }) {
|
|
785
|
+
refs.set("closeTimerStartTime", Date.now());
|
|
786
|
+
context.set("remainingTime", getToastDuration(prop("duration"), prop("type")));
|
|
787
|
+
},
|
|
788
|
+
syncRemainingTime({ context, refs }) {
|
|
789
|
+
context.set("remainingTime", (prev) => {
|
|
790
|
+
const closeTimerStartTime = refs.get("closeTimerStartTime");
|
|
791
|
+
const elapsedTime = Date.now() - closeTimerStartTime;
|
|
792
|
+
refs.set("lastCloseStartTimerStartTime", Date.now());
|
|
793
|
+
return prev - elapsedTime;
|
|
794
|
+
});
|
|
795
|
+
},
|
|
796
|
+
notifyParentToRemove({ prop }) {
|
|
797
|
+
const parent = prop("parent");
|
|
798
|
+
parent.send({ type: "TOAST.REMOVE", id: prop("id") });
|
|
799
|
+
},
|
|
800
|
+
invokeOnDismiss({ prop, event }) {
|
|
801
|
+
prop("onStatusChange")?.({ status: "dismissing", src: event.src });
|
|
802
|
+
},
|
|
803
|
+
invokeOnUnmount({ prop }) {
|
|
804
|
+
prop("onStatusChange")?.({ status: "unmounted" });
|
|
805
|
+
},
|
|
806
|
+
invokeOnVisible({ prop }) {
|
|
807
|
+
prop("onStatusChange")?.({ status: "visible" });
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
});
|
|
812
|
+
function setHeight(parent, item) {
|
|
813
|
+
const { id, height } = item;
|
|
814
|
+
parent.context.set("heights", (prev) => {
|
|
815
|
+
const alreadyExists = prev.find((i) => i.id === id);
|
|
816
|
+
if (!alreadyExists) {
|
|
817
|
+
return [{ id, height }, ...prev];
|
|
818
|
+
} else {
|
|
819
|
+
return prev.map((i) => i.id === id ? { ...i, height } : i);
|
|
820
|
+
}
|
|
821
|
+
});
|
|
822
|
+
}
|
|
823
|
+
var withDefaults = (options, defaults) => {
|
|
824
|
+
return { ...defaults, ...options };
|
|
825
|
+
};
|
|
826
|
+
function createToastStore(props) {
|
|
827
|
+
const attrs = withDefaults(props, {
|
|
828
|
+
placement: "bottom",
|
|
829
|
+
overlap: false,
|
|
830
|
+
max: 24,
|
|
831
|
+
gap: 16,
|
|
832
|
+
offsets: "1rem",
|
|
833
|
+
hotkey: ["altKey", "KeyT"],
|
|
834
|
+
removeDelay: 200,
|
|
835
|
+
pauseOnPageIdle: true
|
|
836
|
+
});
|
|
837
|
+
let subscribers = [];
|
|
838
|
+
let toasts = [];
|
|
839
|
+
let dismissedToasts = /* @__PURE__ */ new Set();
|
|
840
|
+
const subscribe = (subscriber) => {
|
|
841
|
+
subscribers.push(subscriber);
|
|
842
|
+
return () => {
|
|
843
|
+
const index = subscribers.indexOf(subscriber);
|
|
844
|
+
subscribers.splice(index, 1);
|
|
845
|
+
};
|
|
846
|
+
};
|
|
847
|
+
const publish = (data) => {
|
|
848
|
+
subscribers.forEach((subscriber) => subscriber(data));
|
|
849
|
+
return data;
|
|
850
|
+
};
|
|
851
|
+
const addToast = (data) => {
|
|
852
|
+
if (toasts.length >= attrs.max) return;
|
|
853
|
+
publish(data);
|
|
854
|
+
toasts.unshift(data);
|
|
855
|
+
};
|
|
856
|
+
const create = (data) => {
|
|
857
|
+
const id = data.id ?? `toast:${uuid()}`;
|
|
858
|
+
const exists = toasts.find((toast) => toast.id === id);
|
|
859
|
+
if (dismissedToasts.has(id)) dismissedToasts.delete(id);
|
|
860
|
+
if (exists) {
|
|
861
|
+
toasts = toasts.map((toast) => {
|
|
862
|
+
if (toast.id === id) {
|
|
863
|
+
return publish({ ...toast, ...data, id });
|
|
889
864
|
}
|
|
865
|
+
return toast;
|
|
866
|
+
});
|
|
867
|
+
} else {
|
|
868
|
+
addToast({
|
|
869
|
+
id,
|
|
870
|
+
duration: attrs.duration,
|
|
871
|
+
removeDelay: attrs.removeDelay,
|
|
872
|
+
type: "info",
|
|
873
|
+
...data,
|
|
874
|
+
stacked: !attrs.overlap,
|
|
875
|
+
gap: attrs.gap
|
|
876
|
+
});
|
|
877
|
+
}
|
|
878
|
+
return id;
|
|
879
|
+
};
|
|
880
|
+
const remove = (id) => {
|
|
881
|
+
dismissedToasts.add(id);
|
|
882
|
+
if (!id) {
|
|
883
|
+
toasts.forEach((toast) => {
|
|
884
|
+
subscribers.forEach((subscriber) => subscriber({ id: toast.id, dismiss: true }));
|
|
885
|
+
});
|
|
886
|
+
toasts = [];
|
|
887
|
+
} else {
|
|
888
|
+
subscribers.forEach((subscriber) => subscriber({ id, dismiss: true }));
|
|
889
|
+
toasts = toasts.filter((toast) => toast.id !== id);
|
|
890
|
+
}
|
|
891
|
+
return id;
|
|
892
|
+
};
|
|
893
|
+
const error = (data) => {
|
|
894
|
+
return create({ ...data, type: "error" });
|
|
895
|
+
};
|
|
896
|
+
const success = (data) => {
|
|
897
|
+
return create({ ...data, type: "success" });
|
|
898
|
+
};
|
|
899
|
+
const info = (data) => {
|
|
900
|
+
return create({ ...data, type: "info" });
|
|
901
|
+
};
|
|
902
|
+
const warning = (data) => {
|
|
903
|
+
return create({ ...data, type: "warning" });
|
|
904
|
+
};
|
|
905
|
+
const loading = (data) => {
|
|
906
|
+
return create({ ...data, type: "loading" });
|
|
907
|
+
};
|
|
908
|
+
const getVisibleToasts = () => {
|
|
909
|
+
return toasts.filter((toast) => !dismissedToasts.has(toast.id));
|
|
910
|
+
};
|
|
911
|
+
const getCount = () => {
|
|
912
|
+
return toasts.length;
|
|
913
|
+
};
|
|
914
|
+
const promise = (promise2, options, shared = {}) => {
|
|
915
|
+
if (!options) return;
|
|
916
|
+
let id = void 0;
|
|
917
|
+
if (options.loading !== void 0) {
|
|
918
|
+
id = create({
|
|
919
|
+
...shared,
|
|
920
|
+
...options.loading,
|
|
921
|
+
promise: promise2,
|
|
922
|
+
type: "loading"
|
|
923
|
+
});
|
|
924
|
+
}
|
|
925
|
+
let removable = id !== void 0;
|
|
926
|
+
let result;
|
|
927
|
+
const prom = runIfFn(promise2).then(async (response) => {
|
|
928
|
+
result = ["resolve", response];
|
|
929
|
+
if (isHttpResponse(response) && !response.ok) {
|
|
930
|
+
removable = false;
|
|
931
|
+
const errorOptions = runIfFn(options.error, `HTTP Error! status: ${response.status}`);
|
|
932
|
+
create({ ...shared, ...errorOptions, id, type: "error" });
|
|
933
|
+
} else if (options.success !== void 0) {
|
|
934
|
+
removable = false;
|
|
935
|
+
const successOptions = runIfFn(options.success, response);
|
|
936
|
+
create({ ...shared, ...successOptions, id, type: "success" });
|
|
937
|
+
}
|
|
938
|
+
}).catch(async (error2) => {
|
|
939
|
+
result = ["reject", error2];
|
|
940
|
+
if (options.error !== void 0) {
|
|
941
|
+
removable = false;
|
|
942
|
+
const errorOptions = runIfFn(options.error, error2);
|
|
943
|
+
create({ ...shared, ...errorOptions, id, type: "error" });
|
|
944
|
+
}
|
|
945
|
+
}).finally(() => {
|
|
946
|
+
if (removable) {
|
|
947
|
+
remove(id);
|
|
948
|
+
id = void 0;
|
|
949
|
+
}
|
|
950
|
+
options.finally?.();
|
|
951
|
+
});
|
|
952
|
+
const unwrap = () => new Promise(
|
|
953
|
+
(resolve, reject) => prom.then(() => result[0] === "reject" ? reject(result[1]) : resolve(result[1])).catch(reject)
|
|
954
|
+
);
|
|
955
|
+
return { id, unwrap };
|
|
956
|
+
};
|
|
957
|
+
const update = (id, data) => {
|
|
958
|
+
return create({ id, ...data });
|
|
959
|
+
};
|
|
960
|
+
const pause = (id) => {
|
|
961
|
+
if (id != null) {
|
|
962
|
+
toasts = toasts.map((toast) => {
|
|
963
|
+
if (toast.id === id) return publish({ ...toast, message: "PAUSE" });
|
|
964
|
+
return toast;
|
|
965
|
+
});
|
|
966
|
+
} else {
|
|
967
|
+
toasts = toasts.map((toast) => publish({ ...toast, message: "PAUSE" }));
|
|
968
|
+
}
|
|
969
|
+
};
|
|
970
|
+
const resume = (id) => {
|
|
971
|
+
if (id != null) {
|
|
972
|
+
toasts = toasts.map((toast) => {
|
|
973
|
+
if (toast.id === id) return publish({ ...toast, message: "RESUME" });
|
|
974
|
+
return toast;
|
|
890
975
|
});
|
|
976
|
+
} else {
|
|
977
|
+
toasts = toasts.map((toast) => publish({ ...toast, message: "RESUME" }));
|
|
891
978
|
}
|
|
892
979
|
};
|
|
980
|
+
const dismiss = (id) => {
|
|
981
|
+
if (id != null) {
|
|
982
|
+
toasts = toasts.map((toast) => {
|
|
983
|
+
if (toast.id === id) return publish({ ...toast, message: "DISMISS" });
|
|
984
|
+
return toast;
|
|
985
|
+
});
|
|
986
|
+
} else {
|
|
987
|
+
toasts = toasts.map((toast) => publish({ ...toast, message: "DISMISS" }));
|
|
988
|
+
}
|
|
989
|
+
};
|
|
990
|
+
const isVisible = (id) => {
|
|
991
|
+
return !dismissedToasts.has(id) && !!toasts.find((toast) => toast.id === id);
|
|
992
|
+
};
|
|
993
|
+
const isDismissed = (id) => {
|
|
994
|
+
return dismissedToasts.has(id);
|
|
995
|
+
};
|
|
996
|
+
const expand = () => {
|
|
997
|
+
toasts = toasts.map((toast) => publish({ ...toast, stacked: true }));
|
|
998
|
+
};
|
|
999
|
+
const collapse = () => {
|
|
1000
|
+
toasts = toasts.map((toast) => publish({ ...toast, stacked: false }));
|
|
1001
|
+
};
|
|
1002
|
+
return {
|
|
1003
|
+
attrs,
|
|
1004
|
+
subscribe,
|
|
1005
|
+
create,
|
|
1006
|
+
update,
|
|
1007
|
+
remove,
|
|
1008
|
+
dismiss,
|
|
1009
|
+
error,
|
|
1010
|
+
success,
|
|
1011
|
+
info,
|
|
1012
|
+
warning,
|
|
1013
|
+
loading,
|
|
1014
|
+
getVisibleToasts,
|
|
1015
|
+
getCount,
|
|
1016
|
+
promise,
|
|
1017
|
+
pause,
|
|
1018
|
+
resume,
|
|
1019
|
+
isVisible,
|
|
1020
|
+
isDismissed,
|
|
1021
|
+
expand,
|
|
1022
|
+
collapse
|
|
1023
|
+
};
|
|
893
1024
|
}
|
|
1025
|
+
var isHttpResponse = (data) => {
|
|
1026
|
+
return data && typeof data === "object" && "ok" in data && typeof data.ok === "boolean" && "status" in data && typeof data.status === "number";
|
|
1027
|
+
};
|
|
894
1028
|
|
|
895
1029
|
// src/index.ts
|
|
896
1030
|
var group = {
|
|
@@ -898,4 +1032,4 @@ var group = {
|
|
|
898
1032
|
machine: groupMachine
|
|
899
1033
|
};
|
|
900
1034
|
|
|
901
|
-
export { anatomy, connect,
|
|
1035
|
+
export { anatomy, connect, createToastStore as createStore, group, machine };
|