@zag-js/toast 0.82.2 → 1.0.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/dist/index.d.mts +198 -134
- package/dist/index.d.ts +198 -134
- package/dist/index.js +757 -624
- package/dist/index.mjs +757 -625
- 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
|
|
224
|
-
},
|
|
225
|
-
getPlacements() {
|
|
226
|
-
const toasts = getState().context.toasts;
|
|
227
|
-
const placements = toasts.map((toast) => toast.state.context.placement);
|
|
228
|
-
return Array.from(new Set(placements));
|
|
229
|
-
},
|
|
230
|
-
getToastsByPlacement: getToastsByPlacementImpl,
|
|
231
|
-
isVisible,
|
|
232
|
-
create,
|
|
233
|
-
update,
|
|
234
|
-
upsert,
|
|
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
|
-
}
|
|
197
|
+
return context.get("toasts").length;
|
|
242
198
|
},
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
toasts.forEach((toast) => dismiss(toast.id));
|
|
199
|
+
getToasts() {
|
|
200
|
+
return context.get("toasts");
|
|
246
201
|
},
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
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,292 @@ function groupConnect(serviceOrState, send, normalize) {
|
|
|
307
227
|
send({ type: "REGION.FOCUS", target: event.relatedTarget });
|
|
308
228
|
},
|
|
309
229
|
onBlur(event) {
|
|
310
|
-
if (
|
|
311
|
-
send({ type: "REGION.BLUR" });
|
|
230
|
+
if (refs.get("isFocusWithin") && !contains(event.currentTarget, event.relatedTarget)) {
|
|
231
|
+
queueMicrotask(() => send({ type: "REGION.BLUR" }));
|
|
312
232
|
}
|
|
313
233
|
}
|
|
314
234
|
});
|
|
315
235
|
},
|
|
316
236
|
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
|
-
});
|
|
237
|
+
const store = prop("store");
|
|
238
|
+
return store.subscribe(() => fn(context.get("toasts")));
|
|
323
239
|
}
|
|
324
240
|
};
|
|
325
241
|
}
|
|
326
|
-
var
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
242
|
+
var groupMachine = createMachine({
|
|
243
|
+
props({ props }) {
|
|
244
|
+
return {
|
|
245
|
+
dir: "ltr",
|
|
246
|
+
id: uuid(),
|
|
247
|
+
...props,
|
|
248
|
+
store: props.store
|
|
249
|
+
};
|
|
250
|
+
},
|
|
251
|
+
initialState({ prop }) {
|
|
252
|
+
return prop("store").attrs.overlap ? "overlap" : "stack";
|
|
253
|
+
},
|
|
254
|
+
refs() {
|
|
255
|
+
return {
|
|
256
|
+
lastFocusedEl: null,
|
|
257
|
+
isFocusWithin: false,
|
|
258
|
+
dismissableCleanup: void 0
|
|
259
|
+
};
|
|
260
|
+
},
|
|
261
|
+
context({ bindable }) {
|
|
262
|
+
return {
|
|
263
|
+
toasts: bindable(() => ({
|
|
264
|
+
defaultValue: [],
|
|
265
|
+
sync: true,
|
|
266
|
+
hash: (toasts) => toasts.map((t) => t.id).join(",")
|
|
267
|
+
})),
|
|
268
|
+
heights: bindable(() => ({
|
|
269
|
+
defaultValue: [],
|
|
270
|
+
sync: true
|
|
271
|
+
}))
|
|
272
|
+
};
|
|
273
|
+
},
|
|
274
|
+
computed: {
|
|
275
|
+
count: ({ context }) => context.get("toasts").length,
|
|
276
|
+
overlap: ({ prop }) => prop("store").attrs.overlap,
|
|
277
|
+
placement: ({ prop }) => prop("store").attrs.placement
|
|
278
|
+
},
|
|
279
|
+
effects: ["subscribeToStore", "trackDocumentVisibility", "trackHotKeyPress"],
|
|
280
|
+
watch({ track, context, action }) {
|
|
281
|
+
track([() => context.hash("toasts")], () => {
|
|
282
|
+
queueMicrotask(() => {
|
|
283
|
+
action(["collapsedIfEmpty", "setDismissableBranch"]);
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
},
|
|
287
|
+
exit: ["clearDismissableBranch", "clearLastFocusedEl"],
|
|
288
|
+
on: {
|
|
289
|
+
"DOC.HOTKEY": {
|
|
290
|
+
actions: ["focusRegionEl"]
|
|
291
|
+
},
|
|
292
|
+
"REGION.BLUR": [
|
|
293
|
+
{
|
|
294
|
+
guard: "isOverlapping",
|
|
295
|
+
target: "overlap",
|
|
296
|
+
actions: ["collapseToasts", "resumeToasts", "restoreLastFocusedEl"]
|
|
349
297
|
},
|
|
350
|
-
|
|
298
|
+
{
|
|
299
|
+
target: "stack",
|
|
300
|
+
actions: ["resumeToasts", "restoreLastFocusedEl"]
|
|
301
|
+
}
|
|
302
|
+
],
|
|
303
|
+
"TOAST.REMOVE": {
|
|
304
|
+
actions: ["removeToast", "removeHeight"]
|
|
305
|
+
},
|
|
306
|
+
"TOAST.PAUSE": {
|
|
307
|
+
actions: ["pauseToasts"]
|
|
308
|
+
}
|
|
309
|
+
},
|
|
310
|
+
states: {
|
|
311
|
+
stack: {
|
|
351
312
|
on: {
|
|
352
|
-
|
|
353
|
-
{
|
|
354
|
-
guard: and("hasTypeChanged", "isChangingToLoading"),
|
|
355
|
-
target: "visible:persist",
|
|
356
|
-
actions: ["setContext"]
|
|
357
|
-
},
|
|
313
|
+
"REGION.POINTER_LEAVE": [
|
|
358
314
|
{
|
|
359
|
-
guard:
|
|
360
|
-
target: "
|
|
361
|
-
actions: ["
|
|
315
|
+
guard: "isOverlapping",
|
|
316
|
+
target: "overlap",
|
|
317
|
+
actions: ["resumeToasts", "collapseToasts"]
|
|
362
318
|
},
|
|
363
319
|
{
|
|
364
|
-
actions: ["
|
|
320
|
+
actions: ["resumeToasts"]
|
|
365
321
|
}
|
|
366
322
|
],
|
|
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
|
-
}
|
|
323
|
+
"REGION.OVERLAP": {
|
|
324
|
+
target: "overlap",
|
|
325
|
+
actions: ["collapseToasts"]
|
|
379
326
|
},
|
|
380
|
-
"
|
|
381
|
-
|
|
382
|
-
on: {
|
|
383
|
-
RESUME: {
|
|
384
|
-
guard: not("isLoadingType"),
|
|
385
|
-
target: "visible",
|
|
386
|
-
actions: ["setCreatedAt"]
|
|
387
|
-
},
|
|
388
|
-
DISMISS: "dismissing"
|
|
389
|
-
}
|
|
327
|
+
"REGION.FOCUS": {
|
|
328
|
+
actions: ["setLastFocusedEl", "pauseToasts"]
|
|
390
329
|
},
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
}
|
|
402
|
-
}
|
|
330
|
+
"REGION.POINTER_ENTER": {
|
|
331
|
+
actions: ["pauseToasts"]
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
},
|
|
335
|
+
overlap: {
|
|
336
|
+
on: {
|
|
337
|
+
"REGION.STACK": {
|
|
338
|
+
target: "stack",
|
|
339
|
+
actions: ["expandToasts"]
|
|
403
340
|
},
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
REMOVE_DELAY: {
|
|
408
|
-
target: "unmounted",
|
|
409
|
-
actions: "notifyParentToRemove"
|
|
410
|
-
}
|
|
411
|
-
}
|
|
341
|
+
"REGION.POINTER_ENTER": {
|
|
342
|
+
target: "stack",
|
|
343
|
+
actions: ["pauseToasts", "expandToasts"]
|
|
412
344
|
},
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
345
|
+
"REGION.FOCUS": {
|
|
346
|
+
target: "stack",
|
|
347
|
+
actions: ["setLastFocusedEl", "pauseToasts", "expandToasts"]
|
|
416
348
|
}
|
|
417
349
|
}
|
|
350
|
+
}
|
|
351
|
+
},
|
|
352
|
+
implementations: {
|
|
353
|
+
guards: {
|
|
354
|
+
isOverlapping: ({ computed }) => computed("overlap")
|
|
418
355
|
},
|
|
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();
|
|
356
|
+
effects: {
|
|
357
|
+
subscribeToStore({ context, prop }) {
|
|
358
|
+
return prop("store").subscribe((toast) => {
|
|
359
|
+
if (toast.dismiss) {
|
|
360
|
+
context.set("toasts", (prev) => prev.filter((t) => t.id !== toast.id));
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
context.set("toasts", (prev) => {
|
|
364
|
+
const index = prev.findIndex((t) => t.id === toast.id);
|
|
365
|
+
if (index !== -1) {
|
|
366
|
+
return [...prev.slice(0, index), { ...prev[index], ...toast }, ...prev.slice(index + 1)];
|
|
367
|
+
}
|
|
368
|
+
return [toast, ...prev];
|
|
445
369
|
});
|
|
446
|
-
|
|
370
|
+
});
|
|
371
|
+
},
|
|
372
|
+
trackHotKeyPress({ prop, send }) {
|
|
373
|
+
const handleKeyDown = (event) => {
|
|
374
|
+
const { hotkey } = prop("store").attrs;
|
|
375
|
+
const isHotkeyPressed = hotkey.every((key) => event[key] || event.code === key);
|
|
376
|
+
if (!isHotkeyPressed) return;
|
|
377
|
+
send({ type: "DOC.HOTKEY" });
|
|
378
|
+
};
|
|
379
|
+
return addDomEvent(document, "keydown", handleKeyDown, { capture: true });
|
|
380
|
+
},
|
|
381
|
+
trackDocumentVisibility({ prop, send, scope }) {
|
|
382
|
+
const { pauseOnPageIdle } = prop("store").attrs;
|
|
383
|
+
if (!pauseOnPageIdle) return;
|
|
384
|
+
const doc = scope.getDoc();
|
|
385
|
+
return addDomEvent(doc, "visibilitychange", () => {
|
|
386
|
+
const isHidden = doc.visibilityState === "hidden";
|
|
387
|
+
send({ type: isHidden ? "PAUSE_ALL" : "RESUME_ALL" });
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
},
|
|
391
|
+
actions: {
|
|
392
|
+
setDismissableBranch({ refs, context, computed, scope }) {
|
|
393
|
+
const toasts = context.get("toasts");
|
|
394
|
+
const placement = computed("placement");
|
|
395
|
+
const hasToasts = toasts.length > 0;
|
|
396
|
+
if (!hasToasts) {
|
|
397
|
+
refs.get("dismissableCleanup")?.();
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
if (hasToasts && refs.get("dismissableCleanup")) {
|
|
401
|
+
return;
|
|
447
402
|
}
|
|
403
|
+
const groupEl = () => getRegionEl(scope, placement);
|
|
404
|
+
const cleanup = trackDismissableBranch(groupEl, { defer: true });
|
|
405
|
+
refs.set("dismissableCleanup", cleanup);
|
|
448
406
|
},
|
|
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
|
|
407
|
+
clearDismissableBranch({ refs }) {
|
|
408
|
+
refs.get("dismissableCleanup")?.();
|
|
454
409
|
},
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
410
|
+
focusRegionEl({ scope, computed }) {
|
|
411
|
+
queueMicrotask(() => {
|
|
412
|
+
getRegionEl(scope, computed("placement"))?.focus();
|
|
413
|
+
});
|
|
458
414
|
},
|
|
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: []
|
|
415
|
+
pauseToasts({ prop }) {
|
|
416
|
+
prop("store").pause();
|
|
527
417
|
},
|
|
528
|
-
|
|
529
|
-
|
|
418
|
+
resumeToasts({ prop }) {
|
|
419
|
+
prop("store").resume();
|
|
530
420
|
},
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
toasts: ["collapsedIfEmpty", "setDismissableBranch"]
|
|
421
|
+
expandToasts({ prop }) {
|
|
422
|
+
prop("store").expand();
|
|
534
423
|
},
|
|
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
|
-
]
|
|
424
|
+
collapseToasts({ prop }) {
|
|
425
|
+
prop("store").collapse();
|
|
584
426
|
},
|
|
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
|
|
427
|
+
removeToast({ prop, event }) {
|
|
428
|
+
prop("store").remove(event.id);
|
|
632
429
|
},
|
|
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
|
-
}
|
|
430
|
+
removeHeight({ event, context }) {
|
|
431
|
+
if (event?.id == null) return;
|
|
432
|
+
queueMicrotask(() => {
|
|
433
|
+
context.set("heights", (heights) => heights.filter((height) => height.id !== event.id));
|
|
434
|
+
});
|
|
649
435
|
},
|
|
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
|
-
}
|
|
436
|
+
collapsedIfEmpty({ send, computed }) {
|
|
437
|
+
if (!computed("overlap") || computed("count") > 1) return;
|
|
438
|
+
send({ type: "REGION.OVERLAP" });
|
|
439
|
+
},
|
|
440
|
+
setLastFocusedEl({ refs, event }) {
|
|
441
|
+
if (refs.get("isFocusWithin") || !event.target) return;
|
|
442
|
+
refs.set("isFocusWithin", true);
|
|
443
|
+
refs.set("lastFocusedEl", event.target);
|
|
444
|
+
},
|
|
445
|
+
restoreLastFocusedEl({ refs }) {
|
|
446
|
+
if (!refs.get("lastFocusedEl")) return;
|
|
447
|
+
refs.get("lastFocusedEl")?.focus({ preventScroll: true });
|
|
448
|
+
refs.set("lastFocusedEl", null);
|
|
449
|
+
refs.set("isFocusWithin", false);
|
|
450
|
+
},
|
|
451
|
+
clearLastFocusedEl({ refs }) {
|
|
452
|
+
if (!refs.get("lastFocusedEl")) return;
|
|
453
|
+
refs.get("lastFocusedEl")?.focus({ preventScroll: true });
|
|
454
|
+
refs.set("lastFocusedEl", null);
|
|
455
|
+
refs.set("isFocusWithin", false);
|
|
782
456
|
}
|
|
783
457
|
}
|
|
784
|
-
|
|
785
|
-
}
|
|
786
|
-
function
|
|
787
|
-
const
|
|
788
|
-
currentToasts.forEach(fn);
|
|
789
|
-
}
|
|
790
|
-
function connect(state, send, normalize) {
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
function connect(service, normalize) {
|
|
461
|
+
const { state, send, prop, scope, context, computed } = service;
|
|
791
462
|
const visible = state.hasTag("visible");
|
|
792
463
|
const paused = state.hasTag("paused");
|
|
793
|
-
const
|
|
794
|
-
const
|
|
464
|
+
const mounted = context.get("mounted");
|
|
465
|
+
const frontmost = computed("frontmost");
|
|
466
|
+
const placement = prop("parent").computed("placement");
|
|
467
|
+
const type = prop("type");
|
|
468
|
+
const stacked = prop("stacked");
|
|
469
|
+
const title = prop("title");
|
|
470
|
+
const description = prop("description");
|
|
471
|
+
const action = prop("action");
|
|
795
472
|
const [side, align = "center"] = placement.split("-");
|
|
796
473
|
return {
|
|
797
474
|
type,
|
|
798
|
-
title
|
|
799
|
-
description
|
|
475
|
+
title,
|
|
476
|
+
description,
|
|
800
477
|
placement,
|
|
801
478
|
visible,
|
|
802
479
|
paused,
|
|
480
|
+
closable: !!prop("closable"),
|
|
803
481
|
pause() {
|
|
804
|
-
send("PAUSE");
|
|
482
|
+
send({ type: "PAUSE" });
|
|
805
483
|
},
|
|
806
484
|
resume() {
|
|
807
|
-
send("RESUME");
|
|
485
|
+
send({ type: "RESUME" });
|
|
808
486
|
},
|
|
809
487
|
dismiss() {
|
|
810
|
-
send("DISMISS");
|
|
488
|
+
send({ type: "DISMISS", src: "programmatic" });
|
|
811
489
|
},
|
|
812
490
|
getRootProps() {
|
|
813
491
|
return normalize.element({
|
|
814
492
|
...parts.root.attrs,
|
|
815
|
-
dir:
|
|
816
|
-
id:
|
|
493
|
+
dir: prop("dir"),
|
|
494
|
+
id: getRootId(scope),
|
|
817
495
|
"data-state": visible ? "open" : "closed",
|
|
818
496
|
"data-type": type,
|
|
819
497
|
"data-placement": placement,
|
|
820
498
|
"data-align": align,
|
|
821
499
|
"data-side": side,
|
|
822
|
-
"data-mounted": dataAttr(
|
|
500
|
+
"data-mounted": dataAttr(mounted),
|
|
823
501
|
"data-paused": dataAttr(paused),
|
|
824
|
-
"data-first": dataAttr(
|
|
825
|
-
"data-sibling": dataAttr(!
|
|
826
|
-
"data-stack": dataAttr(
|
|
827
|
-
"data-overlap": dataAttr(!
|
|
502
|
+
"data-first": dataAttr(frontmost),
|
|
503
|
+
"data-sibling": dataAttr(!frontmost),
|
|
504
|
+
"data-stack": dataAttr(stacked),
|
|
505
|
+
"data-overlap": dataAttr(!stacked),
|
|
828
506
|
role: "status",
|
|
829
507
|
"aria-atomic": "true",
|
|
830
|
-
"aria-describedby":
|
|
831
|
-
"aria-labelledby":
|
|
508
|
+
"aria-describedby": description ? getDescriptionId(scope) : void 0,
|
|
509
|
+
"aria-labelledby": title ? getTitleId(scope) : void 0,
|
|
832
510
|
tabIndex: 0,
|
|
833
|
-
style: getPlacementStyle(
|
|
511
|
+
style: getPlacementStyle(service, visible),
|
|
834
512
|
onKeyDown(event) {
|
|
835
513
|
if (event.defaultPrevented) return;
|
|
836
514
|
if (event.key == "Escape") {
|
|
837
|
-
send("DISMISS");
|
|
515
|
+
send({ type: "DISMISS", src: "keyboard" });
|
|
838
516
|
event.preventDefault();
|
|
839
517
|
}
|
|
840
518
|
}
|
|
@@ -844,7 +522,7 @@ function connect(state, send, normalize) {
|
|
|
844
522
|
getGhostBeforeProps() {
|
|
845
523
|
return normalize.element({
|
|
846
524
|
"data-ghost": "before",
|
|
847
|
-
style: getGhostBeforeStyle(
|
|
525
|
+
style: getGhostBeforeStyle(service, visible)
|
|
848
526
|
});
|
|
849
527
|
},
|
|
850
528
|
/* Needed to avoid setting hover to false when in between toasts */
|
|
@@ -857,13 +535,13 @@ function connect(state, send, normalize) {
|
|
|
857
535
|
getTitleProps() {
|
|
858
536
|
return normalize.element({
|
|
859
537
|
...parts.title.attrs,
|
|
860
|
-
id:
|
|
538
|
+
id: getTitleId(scope)
|
|
861
539
|
});
|
|
862
540
|
},
|
|
863
541
|
getDescriptionProps() {
|
|
864
542
|
return normalize.element({
|
|
865
543
|
...parts.description.attrs,
|
|
866
|
-
id:
|
|
544
|
+
id: getDescriptionId(scope)
|
|
867
545
|
});
|
|
868
546
|
},
|
|
869
547
|
getActionTriggerProps() {
|
|
@@ -872,25 +550,479 @@ function connect(state, send, normalize) {
|
|
|
872
550
|
type: "button",
|
|
873
551
|
onClick(event) {
|
|
874
552
|
if (event.defaultPrevented) return;
|
|
875
|
-
|
|
876
|
-
send("DISMISS");
|
|
553
|
+
action?.onClick?.();
|
|
554
|
+
send({ type: "DISMISS", src: "user" });
|
|
877
555
|
}
|
|
878
556
|
});
|
|
879
557
|
},
|
|
880
558
|
getCloseTriggerProps() {
|
|
881
559
|
return normalize.button({
|
|
882
|
-
id:
|
|
560
|
+
id: getCloseTriggerId(scope),
|
|
883
561
|
...parts.closeTrigger.attrs,
|
|
884
562
|
type: "button",
|
|
885
563
|
"aria-label": "Dismiss notification",
|
|
886
564
|
onClick(event) {
|
|
887
565
|
if (event.defaultPrevented) return;
|
|
888
|
-
send("DISMISS");
|
|
566
|
+
send({ type: "DISMISS", src: "user" });
|
|
567
|
+
}
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
};
|
|
571
|
+
}
|
|
572
|
+
var { not } = createGuards();
|
|
573
|
+
var machine = createMachine({
|
|
574
|
+
props({ props }) {
|
|
575
|
+
return {
|
|
576
|
+
...props,
|
|
577
|
+
id: props.id,
|
|
578
|
+
type: props.type,
|
|
579
|
+
parent: props.parent,
|
|
580
|
+
closable: props.closable ?? true,
|
|
581
|
+
duration: getToastDuration(props.duration, props.type)
|
|
582
|
+
};
|
|
583
|
+
},
|
|
584
|
+
initialState({ prop }) {
|
|
585
|
+
const persist = prop("type") === "loading" || prop("duration") === Infinity;
|
|
586
|
+
return persist ? "visible:persist" : "visible";
|
|
587
|
+
},
|
|
588
|
+
context({ prop, bindable }) {
|
|
589
|
+
return {
|
|
590
|
+
remainingTime: bindable(() => ({
|
|
591
|
+
defaultValue: getToastDuration(prop("duration"), prop("type"))
|
|
592
|
+
})),
|
|
593
|
+
createdAt: bindable(() => ({
|
|
594
|
+
defaultValue: Date.now()
|
|
595
|
+
})),
|
|
596
|
+
mounted: bindable(() => ({
|
|
597
|
+
defaultValue: false
|
|
598
|
+
})),
|
|
599
|
+
initialHeight: bindable(() => ({
|
|
600
|
+
defaultValue: 0
|
|
601
|
+
}))
|
|
602
|
+
};
|
|
603
|
+
},
|
|
604
|
+
refs() {
|
|
605
|
+
return {
|
|
606
|
+
closeTimerStartTime: Date.now(),
|
|
607
|
+
lastCloseStartTimerStartTime: 0
|
|
608
|
+
};
|
|
609
|
+
},
|
|
610
|
+
computed: {
|
|
611
|
+
zIndex: ({ prop }) => {
|
|
612
|
+
const toasts = prop("parent").context.get("toasts");
|
|
613
|
+
const index = toasts.findIndex((toast) => toast.id === prop("id"));
|
|
614
|
+
return toasts.length - index;
|
|
615
|
+
},
|
|
616
|
+
height: ({ prop }) => {
|
|
617
|
+
const heights = prop("parent").context.get("heights");
|
|
618
|
+
const height = heights.find((height2) => height2.id === prop("id"));
|
|
619
|
+
return height?.height ?? 0;
|
|
620
|
+
},
|
|
621
|
+
heightIndex: ({ prop }) => {
|
|
622
|
+
const heights = prop("parent").context.get("heights");
|
|
623
|
+
return heights.findIndex((height) => height.id === prop("id"));
|
|
624
|
+
},
|
|
625
|
+
frontmost: ({ prop }) => prop("index") === 0,
|
|
626
|
+
heightBefore: ({ prop }) => {
|
|
627
|
+
const heights = prop("parent").context.get("heights");
|
|
628
|
+
const heightIndex = heights.findIndex((height) => height.id === prop("id"));
|
|
629
|
+
return heights.reduce((prev, curr, reducerIndex) => {
|
|
630
|
+
if (reducerIndex >= heightIndex) return prev;
|
|
631
|
+
return prev + curr.height;
|
|
632
|
+
}, 0);
|
|
633
|
+
},
|
|
634
|
+
shouldPersist: ({ prop }) => prop("type") === "loading" || prop("duration") === Infinity
|
|
635
|
+
},
|
|
636
|
+
watch({ track, prop, send }) {
|
|
637
|
+
track([() => prop("message")], () => {
|
|
638
|
+
const message = prop("message");
|
|
639
|
+
if (message) send({ type: message, src: "programmatic" });
|
|
640
|
+
});
|
|
641
|
+
track([() => prop("type"), () => prop("duration")], () => {
|
|
642
|
+
send({ type: "UPDATE" });
|
|
643
|
+
});
|
|
644
|
+
},
|
|
645
|
+
on: {
|
|
646
|
+
UPDATE: [
|
|
647
|
+
{
|
|
648
|
+
guard: "shouldPersist",
|
|
649
|
+
target: "visible:persist",
|
|
650
|
+
actions: ["resetCloseTimer"]
|
|
651
|
+
},
|
|
652
|
+
{
|
|
653
|
+
target: "visible:updating",
|
|
654
|
+
actions: ["resetCloseTimer"]
|
|
655
|
+
}
|
|
656
|
+
],
|
|
657
|
+
MEASURE: {
|
|
658
|
+
actions: ["measureHeight"]
|
|
659
|
+
}
|
|
660
|
+
},
|
|
661
|
+
entry: ["setMounted", "measureHeight", "invokeOnVisible"],
|
|
662
|
+
effects: ["trackHeight"],
|
|
663
|
+
states: {
|
|
664
|
+
"visible:updating": {
|
|
665
|
+
tags: ["visible", "updating"],
|
|
666
|
+
effects: ["waitForNextTick"],
|
|
667
|
+
on: {
|
|
668
|
+
SHOW: {
|
|
669
|
+
target: "visible"
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
},
|
|
673
|
+
"visible:persist": {
|
|
674
|
+
tags: ["visible", "paused"],
|
|
675
|
+
on: {
|
|
676
|
+
RESUME: {
|
|
677
|
+
guard: not("isLoadingType"),
|
|
678
|
+
target: "visible",
|
|
679
|
+
actions: ["setCloseTimer"]
|
|
680
|
+
},
|
|
681
|
+
DISMISS: {
|
|
682
|
+
target: "dismissing"
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
},
|
|
686
|
+
visible: {
|
|
687
|
+
tags: ["visible"],
|
|
688
|
+
effects: ["waitForDuration"],
|
|
689
|
+
on: {
|
|
690
|
+
DISMISS: {
|
|
691
|
+
target: "dismissing"
|
|
692
|
+
},
|
|
693
|
+
PAUSE: {
|
|
694
|
+
target: "visible:persist",
|
|
695
|
+
actions: ["syncRemainingTime"]
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
},
|
|
699
|
+
dismissing: {
|
|
700
|
+
entry: ["invokeOnDismiss"],
|
|
701
|
+
effects: ["waitForRemoveDelay"],
|
|
702
|
+
on: {
|
|
703
|
+
REMOVE: {
|
|
704
|
+
target: "unmounted",
|
|
705
|
+
actions: ["notifyParentToRemove"]
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
},
|
|
709
|
+
unmounted: {
|
|
710
|
+
entry: ["invokeOnUnmount"]
|
|
711
|
+
}
|
|
712
|
+
},
|
|
713
|
+
implementations: {
|
|
714
|
+
effects: {
|
|
715
|
+
waitForRemoveDelay({ prop, send }) {
|
|
716
|
+
return setRafTimeout(() => {
|
|
717
|
+
send({ type: "REMOVE", src: "timer" });
|
|
718
|
+
}, prop("removeDelay"));
|
|
719
|
+
},
|
|
720
|
+
waitForDuration({ send, context, computed }) {
|
|
721
|
+
if (computed("shouldPersist")) return;
|
|
722
|
+
return setRafTimeout(() => {
|
|
723
|
+
send({ type: "DISMISS", src: "timer" });
|
|
724
|
+
}, context.get("remainingTime"));
|
|
725
|
+
},
|
|
726
|
+
waitForNextTick({ send }) {
|
|
727
|
+
return setRafTimeout(() => {
|
|
728
|
+
send({ type: "SHOW", src: "timer" });
|
|
729
|
+
}, 0);
|
|
730
|
+
},
|
|
731
|
+
trackHeight({ scope, prop }) {
|
|
732
|
+
let cleanup;
|
|
733
|
+
raf(() => {
|
|
734
|
+
const rootEl = getRootEl(scope);
|
|
735
|
+
if (!rootEl) return;
|
|
736
|
+
const syncHeight = () => {
|
|
737
|
+
const originalHeight = rootEl.style.height;
|
|
738
|
+
rootEl.style.height = "auto";
|
|
739
|
+
const height = rootEl.getBoundingClientRect().height;
|
|
740
|
+
rootEl.style.height = originalHeight;
|
|
741
|
+
const item = { id: prop("id"), height };
|
|
742
|
+
setHeight(prop("parent"), item);
|
|
743
|
+
};
|
|
744
|
+
const win = scope.getWin();
|
|
745
|
+
const observer = new win.MutationObserver(syncHeight);
|
|
746
|
+
observer.observe(rootEl, {
|
|
747
|
+
childList: true,
|
|
748
|
+
subtree: true,
|
|
749
|
+
characterData: true
|
|
750
|
+
});
|
|
751
|
+
cleanup = () => observer.disconnect();
|
|
752
|
+
});
|
|
753
|
+
return () => cleanup?.();
|
|
754
|
+
}
|
|
755
|
+
},
|
|
756
|
+
guards: {
|
|
757
|
+
isLoadingType: ({ prop }) => prop("type") === "loading",
|
|
758
|
+
shouldPersist: ({ computed }) => computed("shouldPersist")
|
|
759
|
+
},
|
|
760
|
+
actions: {
|
|
761
|
+
setMounted({ context }) {
|
|
762
|
+
raf(() => {
|
|
763
|
+
context.set("mounted", true);
|
|
764
|
+
});
|
|
765
|
+
},
|
|
766
|
+
measureHeight({ scope, prop, context }) {
|
|
767
|
+
queueMicrotask(() => {
|
|
768
|
+
const rootEl = getRootEl(scope);
|
|
769
|
+
if (!rootEl) return;
|
|
770
|
+
const originalHeight = rootEl.style.height;
|
|
771
|
+
rootEl.style.height = "auto";
|
|
772
|
+
const height = rootEl.getBoundingClientRect().height;
|
|
773
|
+
rootEl.style.height = originalHeight;
|
|
774
|
+
context.set("initialHeight", height);
|
|
775
|
+
const item = { id: prop("id"), height };
|
|
776
|
+
setHeight(prop("parent"), item);
|
|
777
|
+
});
|
|
778
|
+
},
|
|
779
|
+
setCloseTimer({ refs }) {
|
|
780
|
+
refs.set("closeTimerStartTime", Date.now());
|
|
781
|
+
},
|
|
782
|
+
resetCloseTimer({ context, refs, prop }) {
|
|
783
|
+
refs.set("closeTimerStartTime", Date.now());
|
|
784
|
+
context.set("remainingTime", getToastDuration(prop("duration"), prop("type")));
|
|
785
|
+
},
|
|
786
|
+
syncRemainingTime({ context, refs }) {
|
|
787
|
+
context.set("remainingTime", (prev) => {
|
|
788
|
+
const closeTimerStartTime = refs.get("closeTimerStartTime");
|
|
789
|
+
const elapsedTime = Date.now() - closeTimerStartTime;
|
|
790
|
+
refs.set("lastCloseStartTimerStartTime", Date.now());
|
|
791
|
+
return prev - elapsedTime;
|
|
792
|
+
});
|
|
793
|
+
},
|
|
794
|
+
notifyParentToRemove({ prop }) {
|
|
795
|
+
const parent = prop("parent");
|
|
796
|
+
parent.send({ type: "TOAST.REMOVE", id: prop("id") });
|
|
797
|
+
},
|
|
798
|
+
invokeOnDismiss({ prop, event }) {
|
|
799
|
+
prop("onStatusChange")?.({ status: "dismissing", src: event.src });
|
|
800
|
+
},
|
|
801
|
+
invokeOnUnmount({ prop }) {
|
|
802
|
+
prop("onStatusChange")?.({ status: "unmounted" });
|
|
803
|
+
},
|
|
804
|
+
invokeOnVisible({ prop }) {
|
|
805
|
+
prop("onStatusChange")?.({ status: "visible" });
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
});
|
|
810
|
+
function setHeight(parent, item) {
|
|
811
|
+
const { id, height } = item;
|
|
812
|
+
parent.context.set("heights", (prev) => {
|
|
813
|
+
const alreadyExists = prev.find((i) => i.id === id);
|
|
814
|
+
if (!alreadyExists) {
|
|
815
|
+
return [{ id, height }, ...prev];
|
|
816
|
+
} else {
|
|
817
|
+
return prev.map((i) => i.id === id ? { ...i, height } : i);
|
|
818
|
+
}
|
|
819
|
+
});
|
|
820
|
+
}
|
|
821
|
+
var withDefaults = (options, defaults) => {
|
|
822
|
+
return { ...defaults, ...options };
|
|
823
|
+
};
|
|
824
|
+
function createToastStore(props) {
|
|
825
|
+
const attrs = withDefaults(props, {
|
|
826
|
+
placement: "bottom",
|
|
827
|
+
overlap: false,
|
|
828
|
+
max: 24,
|
|
829
|
+
gap: 16,
|
|
830
|
+
offsets: "1rem",
|
|
831
|
+
hotkey: ["altKey", "KeyT"],
|
|
832
|
+
removeDelay: 200,
|
|
833
|
+
pauseOnPageIdle: true
|
|
834
|
+
});
|
|
835
|
+
let subscribers = [];
|
|
836
|
+
let toasts = [];
|
|
837
|
+
let dismissedToasts = /* @__PURE__ */ new Set();
|
|
838
|
+
const subscribe = (subscriber) => {
|
|
839
|
+
subscribers.push(subscriber);
|
|
840
|
+
return () => {
|
|
841
|
+
const index = subscribers.indexOf(subscriber);
|
|
842
|
+
subscribers.splice(index, 1);
|
|
843
|
+
};
|
|
844
|
+
};
|
|
845
|
+
const publish = (data) => {
|
|
846
|
+
subscribers.forEach((subscriber) => subscriber(data));
|
|
847
|
+
return data;
|
|
848
|
+
};
|
|
849
|
+
const addToast = (data) => {
|
|
850
|
+
if (toasts.length >= attrs.max) return;
|
|
851
|
+
publish(data);
|
|
852
|
+
toasts.unshift(data);
|
|
853
|
+
};
|
|
854
|
+
const create = (data) => {
|
|
855
|
+
const id = data.id ?? `toast:${uuid()}`;
|
|
856
|
+
const exists = toasts.find((toast) => toast.id === id);
|
|
857
|
+
if (dismissedToasts.has(id)) dismissedToasts.delete(id);
|
|
858
|
+
if (exists) {
|
|
859
|
+
toasts = toasts.map((toast) => {
|
|
860
|
+
if (toast.id === id) {
|
|
861
|
+
return publish({ ...toast, ...data, id });
|
|
889
862
|
}
|
|
863
|
+
return toast;
|
|
864
|
+
});
|
|
865
|
+
} else {
|
|
866
|
+
addToast({
|
|
867
|
+
id,
|
|
868
|
+
duration: attrs.duration,
|
|
869
|
+
removeDelay: attrs.removeDelay,
|
|
870
|
+
type: "info",
|
|
871
|
+
...data,
|
|
872
|
+
stacked: !attrs.overlap,
|
|
873
|
+
gap: attrs.gap
|
|
890
874
|
});
|
|
891
875
|
}
|
|
876
|
+
return id;
|
|
877
|
+
};
|
|
878
|
+
const remove = (id) => {
|
|
879
|
+
dismissedToasts.add(id);
|
|
880
|
+
if (!id) {
|
|
881
|
+
toasts.forEach((toast) => {
|
|
882
|
+
subscribers.forEach((subscriber) => subscriber({ id: toast.id, dismiss: true }));
|
|
883
|
+
});
|
|
884
|
+
toasts = [];
|
|
885
|
+
} else {
|
|
886
|
+
subscribers.forEach((subscriber) => subscriber({ id, dismiss: true }));
|
|
887
|
+
toasts = toasts.filter((toast) => toast.id !== id);
|
|
888
|
+
}
|
|
889
|
+
return id;
|
|
890
|
+
};
|
|
891
|
+
const error = (data) => {
|
|
892
|
+
return create({ ...data, type: "error" });
|
|
893
|
+
};
|
|
894
|
+
const success = (data) => {
|
|
895
|
+
return create({ ...data, type: "success" });
|
|
896
|
+
};
|
|
897
|
+
const info = (data) => {
|
|
898
|
+
return create({ ...data, type: "info" });
|
|
899
|
+
};
|
|
900
|
+
const warning = (data) => {
|
|
901
|
+
return create({ ...data, type: "warning" });
|
|
902
|
+
};
|
|
903
|
+
const loading = (data) => {
|
|
904
|
+
return create({ ...data, type: "loading" });
|
|
905
|
+
};
|
|
906
|
+
const getVisibleToasts = () => {
|
|
907
|
+
return toasts.filter((toast) => !dismissedToasts.has(toast.id));
|
|
908
|
+
};
|
|
909
|
+
const getCount = () => {
|
|
910
|
+
return toasts.length;
|
|
911
|
+
};
|
|
912
|
+
const promise = (promise2, options, shared = {}) => {
|
|
913
|
+
if (!options) return;
|
|
914
|
+
let id = void 0;
|
|
915
|
+
if (options.loading !== void 0) {
|
|
916
|
+
id = create({
|
|
917
|
+
...shared,
|
|
918
|
+
...options.loading,
|
|
919
|
+
promise: promise2,
|
|
920
|
+
type: "loading"
|
|
921
|
+
});
|
|
922
|
+
}
|
|
923
|
+
let removable = id !== void 0;
|
|
924
|
+
let result;
|
|
925
|
+
const prom = runIfFn(promise2).then(async (response) => {
|
|
926
|
+
result = ["resolve", response];
|
|
927
|
+
if (isHttpResponse(response) && !response.ok) {
|
|
928
|
+
removable = false;
|
|
929
|
+
const errorOptions = runIfFn(options.error, `HTTP Error! status: ${response.status}`);
|
|
930
|
+
create({ ...shared, ...errorOptions, id, type: "error" });
|
|
931
|
+
} else if (options.success !== void 0) {
|
|
932
|
+
removable = false;
|
|
933
|
+
const successOptions = runIfFn(options.success, response);
|
|
934
|
+
create({ ...shared, ...successOptions, id, type: "success" });
|
|
935
|
+
}
|
|
936
|
+
}).catch(async (error2) => {
|
|
937
|
+
result = ["reject", error2];
|
|
938
|
+
if (options.error !== void 0) {
|
|
939
|
+
removable = false;
|
|
940
|
+
const errorOptions = runIfFn(options.error, error2);
|
|
941
|
+
create({ ...shared, ...errorOptions, id, type: "error" });
|
|
942
|
+
}
|
|
943
|
+
}).finally(() => {
|
|
944
|
+
if (removable) {
|
|
945
|
+
remove(id);
|
|
946
|
+
id = void 0;
|
|
947
|
+
}
|
|
948
|
+
options.finally?.();
|
|
949
|
+
});
|
|
950
|
+
const unwrap = () => new Promise(
|
|
951
|
+
(resolve, reject) => prom.then(() => result[0] === "reject" ? reject(result[1]) : resolve(result[1])).catch(reject)
|
|
952
|
+
);
|
|
953
|
+
return { id, unwrap };
|
|
954
|
+
};
|
|
955
|
+
const update = (id, data) => {
|
|
956
|
+
return create({ id, ...data });
|
|
957
|
+
};
|
|
958
|
+
const pause = (id) => {
|
|
959
|
+
if (id != null) {
|
|
960
|
+
toasts = toasts.map((toast) => {
|
|
961
|
+
if (toast.id === id) return publish({ ...toast, message: "PAUSE" });
|
|
962
|
+
return toast;
|
|
963
|
+
});
|
|
964
|
+
} else {
|
|
965
|
+
toasts = toasts.map((toast) => publish({ ...toast, message: "PAUSE" }));
|
|
966
|
+
}
|
|
967
|
+
};
|
|
968
|
+
const resume = (id) => {
|
|
969
|
+
if (id != null) {
|
|
970
|
+
toasts = toasts.map((toast) => {
|
|
971
|
+
if (toast.id === id) return publish({ ...toast, message: "RESUME" });
|
|
972
|
+
return toast;
|
|
973
|
+
});
|
|
974
|
+
} else {
|
|
975
|
+
toasts = toasts.map((toast) => publish({ ...toast, message: "RESUME" }));
|
|
976
|
+
}
|
|
977
|
+
};
|
|
978
|
+
const dismiss = (id) => {
|
|
979
|
+
if (id != null) {
|
|
980
|
+
toasts = toasts.map((toast) => {
|
|
981
|
+
if (toast.id === id) return publish({ ...toast, message: "DISMISS" });
|
|
982
|
+
return toast;
|
|
983
|
+
});
|
|
984
|
+
} else {
|
|
985
|
+
toasts = toasts.map((toast) => publish({ ...toast, message: "DISMISS" }));
|
|
986
|
+
}
|
|
987
|
+
};
|
|
988
|
+
const isVisible = (id) => {
|
|
989
|
+
return !dismissedToasts.has(id) && !!toasts.find((toast) => toast.id === id);
|
|
990
|
+
};
|
|
991
|
+
const isDismissed = (id) => {
|
|
992
|
+
return dismissedToasts.has(id);
|
|
993
|
+
};
|
|
994
|
+
const expand = () => {
|
|
995
|
+
toasts = toasts.map((toast) => publish({ ...toast, stacked: true }));
|
|
996
|
+
};
|
|
997
|
+
const collapse = () => {
|
|
998
|
+
toasts = toasts.map((toast) => publish({ ...toast, stacked: false }));
|
|
999
|
+
};
|
|
1000
|
+
return {
|
|
1001
|
+
attrs,
|
|
1002
|
+
subscribe,
|
|
1003
|
+
create,
|
|
1004
|
+
update,
|
|
1005
|
+
remove,
|
|
1006
|
+
dismiss,
|
|
1007
|
+
error,
|
|
1008
|
+
success,
|
|
1009
|
+
info,
|
|
1010
|
+
warning,
|
|
1011
|
+
loading,
|
|
1012
|
+
getVisibleToasts,
|
|
1013
|
+
getCount,
|
|
1014
|
+
promise,
|
|
1015
|
+
pause,
|
|
1016
|
+
resume,
|
|
1017
|
+
isVisible,
|
|
1018
|
+
isDismissed,
|
|
1019
|
+
expand,
|
|
1020
|
+
collapse
|
|
892
1021
|
};
|
|
893
1022
|
}
|
|
1023
|
+
var isHttpResponse = (data) => {
|
|
1024
|
+
return data && typeof data === "object" && "ok" in data && typeof data.ok === "boolean" && "status" in data && typeof data.status === "number";
|
|
1025
|
+
};
|
|
894
1026
|
|
|
895
1027
|
// src/index.ts
|
|
896
1028
|
var group = {
|
|
@@ -898,4 +1030,4 @@ var group = {
|
|
|
898
1030
|
machine: groupMachine
|
|
899
1031
|
};
|
|
900
1032
|
|
|
901
|
-
export { anatomy, connect,
|
|
1033
|
+
export { anatomy, connect, createToastStore as createStore, group, machine };
|