react-native-bread 0.1.1 → 0.1.2
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/README.md +2 -1
- package/lib/commonjs/icons/CloseIcon.js +1 -22
- package/lib/commonjs/icons/GreenCheck.js +1 -27
- package/lib/commonjs/icons/InfoIcon.js +1 -24
- package/lib/commonjs/icons/RedX.js +1 -27
- package/lib/commonjs/icons/index.js +1 -34
- package/lib/commonjs/index.js +1 -59
- package/lib/commonjs/toast-api.js +1 -127
- package/lib/commonjs/toast-provider.js +1 -66
- package/lib/commonjs/toast-store.js +1 -278
- package/lib/commonjs/toast.js +1 -481
- package/lib/commonjs/types.js +1 -6
- package/lib/module/icons/CloseIcon.js +1 -16
- package/lib/module/icons/GreenCheck.js +1 -21
- package/lib/module/icons/InfoIcon.js +1 -18
- package/lib/module/icons/RedX.js +1 -21
- package/lib/module/icons/index.js +1 -7
- package/lib/module/index.js +1 -14
- package/lib/module/toast-api.js +1 -124
- package/lib/module/toast-provider.js +1 -62
- package/lib/module/toast-store.js +1 -274
- package/lib/module/toast.js +1 -475
- package/lib/module/types.js +1 -4
- package/package.json +7 -6
- package/lib/commonjs/icons/CloseIcon.js.map +0 -1
- package/lib/commonjs/icons/GreenCheck.js.map +0 -1
- package/lib/commonjs/icons/InfoIcon.js.map +0 -1
- package/lib/commonjs/icons/RedX.js.map +0 -1
- package/lib/commonjs/icons/index.js.map +0 -1
- package/lib/commonjs/index.js.map +0 -1
- package/lib/commonjs/toast-api.js.map +0 -1
- package/lib/commonjs/toast-provider.js.map +0 -1
- package/lib/commonjs/toast-store.js.map +0 -1
- package/lib/commonjs/toast.js.map +0 -1
- package/lib/commonjs/types.js.map +0 -1
- package/lib/module/icons/CloseIcon.js.map +0 -1
- package/lib/module/icons/GreenCheck.js.map +0 -1
- package/lib/module/icons/InfoIcon.js.map +0 -1
- package/lib/module/icons/RedX.js.map +0 -1
- package/lib/module/icons/index.js.map +0 -1
- package/lib/module/index.js.map +0 -1
- package/lib/module/toast-api.js.map +0 -1
- package/lib/module/toast-provider.js.map +0 -1
- package/lib/module/toast-store.js.map +0 -1
- package/lib/module/toast.js.map +0 -1
- package/lib/module/types.js.map +0 -1
- package/lib/typescript/icons/CloseIcon.d.ts.map +0 -1
- package/lib/typescript/icons/GreenCheck.d.ts.map +0 -1
- package/lib/typescript/icons/InfoIcon.d.ts.map +0 -1
- package/lib/typescript/icons/RedX.d.ts.map +0 -1
- package/lib/typescript/icons/index.d.ts.map +0 -1
- package/lib/typescript/index.d.ts.map +0 -1
- package/lib/typescript/toast-api.d.ts.map +0 -1
- package/lib/typescript/toast-provider.d.ts.map +0 -1
- package/lib/typescript/toast-store.d.ts.map +0 -1
- package/lib/typescript/toast.d.ts.map +0 -1
- package/lib/typescript/types.d.ts.map +0 -1
- package/src/icons/CloseIcon.tsx +0 -10
- package/src/icons/GreenCheck.tsx +0 -16
- package/src/icons/InfoIcon.tsx +0 -12
- package/src/icons/RedX.tsx +0 -16
- package/src/icons/index.ts +0 -4
- package/src/index.ts +0 -26
- package/src/toast-api.ts +0 -213
- package/src/toast-provider.tsx +0 -77
- package/src/toast-store.ts +0 -270
- package/src/toast.tsx +0 -466
- package/src/types.ts +0 -121
package/lib/module/toast-api.js
CHANGED
|
@@ -1,124 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import { toastStore } from "./toast-store.js";
|
|
4
|
-
|
|
5
|
-
/** Second parameter can be a string (description) or options object */
|
|
6
|
-
|
|
7
|
-
const _toast = (title, description, type, duration) => {
|
|
8
|
-
toastStore.show(title, description, type, duration);
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
/** Helper to parse the second argument which can be string or options */
|
|
12
|
-
const parseDescriptionOrOptions = arg => {
|
|
13
|
-
if (!arg) return {};
|
|
14
|
-
if (typeof arg === "string") return {
|
|
15
|
-
description: arg
|
|
16
|
-
};
|
|
17
|
-
return {
|
|
18
|
-
description: arg.description,
|
|
19
|
-
duration: arg.duration,
|
|
20
|
-
options: arg
|
|
21
|
-
};
|
|
22
|
-
};
|
|
23
|
-
const parseMessage = input => typeof input === "string" ? {
|
|
24
|
-
title: input
|
|
25
|
-
} : input;
|
|
26
|
-
const parseErrorMessage = (input, error) => {
|
|
27
|
-
if (typeof input === "function") {
|
|
28
|
-
return parseMessage(input(error));
|
|
29
|
-
}
|
|
30
|
-
return parseMessage(input);
|
|
31
|
-
};
|
|
32
|
-
const promiseToast = async (promise, messages) => {
|
|
33
|
-
const loadingCfg = parseMessage(messages.loading);
|
|
34
|
-
|
|
35
|
-
// Very long duration so it stays visible until we resolve/reject
|
|
36
|
-
const toastId = toastStore.show(loadingCfg.title, loadingCfg.description, "loading", loadingCfg.duration ?? 60 * 60 * 1000);
|
|
37
|
-
try {
|
|
38
|
-
const result = await promise;
|
|
39
|
-
const successCfg = parseMessage(messages.success);
|
|
40
|
-
toastStore.updateToast(toastId, {
|
|
41
|
-
title: successCfg.title,
|
|
42
|
-
description: successCfg.description,
|
|
43
|
-
type: "success",
|
|
44
|
-
duration: successCfg.duration ?? 4000
|
|
45
|
-
});
|
|
46
|
-
return {
|
|
47
|
-
data: result,
|
|
48
|
-
success: true
|
|
49
|
-
};
|
|
50
|
-
} catch (err) {
|
|
51
|
-
const error = err instanceof Error ? err : new Error(String(err));
|
|
52
|
-
const errorCfg = parseErrorMessage(messages.error, error);
|
|
53
|
-
toastStore.updateToast(toastId, {
|
|
54
|
-
title: errorCfg.title,
|
|
55
|
-
description: errorCfg.description,
|
|
56
|
-
type: "error",
|
|
57
|
-
duration: errorCfg.duration ?? 4000
|
|
58
|
-
});
|
|
59
|
-
return {
|
|
60
|
-
error,
|
|
61
|
-
success: false
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
// Build the toast API
|
|
66
|
-
const toastFn = _toast;
|
|
67
|
-
toastFn.success = (title, descriptionOrOptions, duration) => {
|
|
68
|
-
const {
|
|
69
|
-
description,
|
|
70
|
-
duration: optDuration,
|
|
71
|
-
options
|
|
72
|
-
} = parseDescriptionOrOptions(descriptionOrOptions);
|
|
73
|
-
toastStore.show(title, description, "success", duration ?? optDuration, options);
|
|
74
|
-
};
|
|
75
|
-
toastFn.error = (title, descriptionOrOptions, duration) => {
|
|
76
|
-
const {
|
|
77
|
-
description,
|
|
78
|
-
duration: optDuration,
|
|
79
|
-
options
|
|
80
|
-
} = parseDescriptionOrOptions(descriptionOrOptions);
|
|
81
|
-
toastStore.show(title, description, "error", duration ?? optDuration, options);
|
|
82
|
-
};
|
|
83
|
-
toastFn.info = (title, descriptionOrOptions, duration) => {
|
|
84
|
-
const {
|
|
85
|
-
description,
|
|
86
|
-
duration: optDuration,
|
|
87
|
-
options
|
|
88
|
-
} = parseDescriptionOrOptions(descriptionOrOptions);
|
|
89
|
-
toastStore.show(title, description, "info", duration ?? optDuration, options);
|
|
90
|
-
};
|
|
91
|
-
toastFn.promise = promiseToast;
|
|
92
|
-
toastFn.dismiss = id => {
|
|
93
|
-
toastStore.hide(id);
|
|
94
|
-
};
|
|
95
|
-
toastFn.dismissAll = () => {
|
|
96
|
-
toastStore.hideAll();
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Toast API for showing notifications.
|
|
101
|
-
*
|
|
102
|
-
* @example
|
|
103
|
-
* ```ts
|
|
104
|
-
* import { toast } from 'react-native-bread';
|
|
105
|
-
*
|
|
106
|
-
* // Basic toasts
|
|
107
|
-
* toast.success("Saved!", "Your changes have been saved");
|
|
108
|
-
* toast.error("Error", "Something went wrong");
|
|
109
|
-
* toast.info("Tip", "Swipe up to dismiss");
|
|
110
|
-
*
|
|
111
|
-
* // Promise toast (loading → success/error)
|
|
112
|
-
* toast.promise(apiCall(), {
|
|
113
|
-
* loading: { title: "Loading..." },
|
|
114
|
-
* success: { title: "Done!" },
|
|
115
|
-
* error: (err) => ({ title: "Failed", description: err.message }),
|
|
116
|
-
* });
|
|
117
|
-
*
|
|
118
|
-
* // Dismiss toasts
|
|
119
|
-
* toast.dismiss(id);
|
|
120
|
-
* toast.dismissAll();
|
|
121
|
-
* ```
|
|
122
|
-
*/
|
|
123
|
-
export const toast = toastFn;
|
|
124
|
-
//# sourceMappingURL=toast-api.js.map
|
|
1
|
+
"use strict";import{toastStore as t}from"./toast-store.js";const o=t=>t?"string"==typeof t?{description:t}:{description:t.description,duration:t.duration,options:t}:{},s=t=>"string"==typeof t?{title:t}:t,i=(o,s,i,r)=>{t.show(o,s,i,r)};i.success=(s,i,r)=>{const{description:e,duration:n,options:c}=o(i);t.show(s,e,"success",r??n,c)},i.error=(s,i,r)=>{const{description:e,duration:n,options:c}=o(i);t.show(s,e,"error",r??n,c)},i.info=(s,i,r)=>{const{description:e,duration:n,options:c}=o(i);t.show(s,e,"info",r??n,c)},i.promise=async(o,i)=>{const r=s(i.loading),e=t.show(r.title,r.description,"loading",r.duration??36e5);try{const r=await o,n=s(i.success);return t.updateToast(e,{title:n.title,description:n.description,type:"success",duration:n.duration??4e3}),{data:r,success:!0}}catch(o){const r=o instanceof Error?o:new Error(String(o)),n=((t,o)=>s("function"==typeof t?t(o):t))(i.error,r);return t.updateToast(e,{title:n.title,description:n.description,type:"error",duration:n.duration??4e3}),{error:r,success:!1}}},i.dismiss=o=>{t.hide(o)},i.dismissAll=()=>{t.hideAll()};export const toast=i;
|
|
@@ -1,62 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import { useEffect } from "react";
|
|
4
|
-
import { StyleSheet, View } from "react-native";
|
|
5
|
-
import { ToastContainer } from "./toast.js";
|
|
6
|
-
import { toastStore } from "./toast-store.js";
|
|
7
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
|
-
/**
|
|
9
|
-
* Toast component that enables toast notifications in your app.
|
|
10
|
-
* Add `<BreadLoaf />` to your root layout to start showing toasts.
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```tsx
|
|
14
|
-
* import { BreadLoaf } from 'react-native-bread';
|
|
15
|
-
*
|
|
16
|
-
* // Basic usage - add to your root layout
|
|
17
|
-
* export default function RootLayout() {
|
|
18
|
-
* return (
|
|
19
|
-
* <>
|
|
20
|
-
* <Stack />
|
|
21
|
-
* <BreadLoaf />
|
|
22
|
-
* </>
|
|
23
|
-
* );
|
|
24
|
-
* }
|
|
25
|
-
*
|
|
26
|
-
* // With configuration
|
|
27
|
-
* <BreadLoaf
|
|
28
|
-
* config={{
|
|
29
|
-
* position: 'bottom',
|
|
30
|
-
* stacking: false,
|
|
31
|
-
* defaultDuration: 5000,
|
|
32
|
-
* colors: {
|
|
33
|
-
* success: { accent: '#22c55e', background: '#f0fdf4' },
|
|
34
|
-
* error: { accent: '#ef4444', background: '#fef2f2' },
|
|
35
|
-
* },
|
|
36
|
-
* toastStyle: { borderRadius: 12 },
|
|
37
|
-
* }}
|
|
38
|
-
* />
|
|
39
|
-
* ```
|
|
40
|
-
*/
|
|
41
|
-
export function BreadLoaf({
|
|
42
|
-
config
|
|
43
|
-
}) {
|
|
44
|
-
useEffect(() => {
|
|
45
|
-
toastStore.setConfig(config);
|
|
46
|
-
return () => {
|
|
47
|
-
toastStore.setConfig(undefined);
|
|
48
|
-
};
|
|
49
|
-
}, [config]);
|
|
50
|
-
return /*#__PURE__*/_jsx(View, {
|
|
51
|
-
style: styles.container,
|
|
52
|
-
pointerEvents: "box-none",
|
|
53
|
-
children: /*#__PURE__*/_jsx(ToastContainer, {})
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
const styles = StyleSheet.create({
|
|
57
|
-
container: {
|
|
58
|
-
...StyleSheet.absoluteFillObject,
|
|
59
|
-
zIndex: 9999
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
//# sourceMappingURL=toast-provider.js.map
|
|
1
|
+
"use strict";import{useEffect as t}from"react";import{StyleSheet as o,View as r}from"react-native";import{ToastContainer as e}from"./toast.js";import{toastStore as n}from"./toast-store.js";import{jsx as i}from"react/jsx-runtime";export function BreadLoaf({config:o}){return t(()=>(n.setConfig(o),()=>{n.setConfig(void 0)}),[o]),i(r,{style:s.container,pointerEvents:"box-none",children:i(e,{})})}const s=o.create({container:{...o.absoluteFillObject,zIndex:9999}});
|
|
@@ -1,274 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const EXIT_DURATION = 350;
|
|
4
|
-
|
|
5
|
-
/** Default theme values */
|
|
6
|
-
const DEFAULT_THEME = {
|
|
7
|
-
position: "top",
|
|
8
|
-
offset: 0,
|
|
9
|
-
stacking: true,
|
|
10
|
-
maxStack: 3,
|
|
11
|
-
dismissible: true,
|
|
12
|
-
showCloseButton: true,
|
|
13
|
-
colors: {
|
|
14
|
-
success: {
|
|
15
|
-
accent: "#28B770",
|
|
16
|
-
background: "#FFFFFF"
|
|
17
|
-
},
|
|
18
|
-
error: {
|
|
19
|
-
accent: "#F05964",
|
|
20
|
-
background: "#FFFFFF"
|
|
21
|
-
},
|
|
22
|
-
info: {
|
|
23
|
-
accent: "#EDBE43",
|
|
24
|
-
background: "#FFFFFF"
|
|
25
|
-
},
|
|
26
|
-
loading: {
|
|
27
|
-
accent: "#232323",
|
|
28
|
-
background: "#FFFFFF"
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
icons: {},
|
|
32
|
-
toastStyle: {},
|
|
33
|
-
titleStyle: {},
|
|
34
|
-
descriptionStyle: {},
|
|
35
|
-
defaultDuration: 4000
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
/** Deep merge user config with defaults */
|
|
39
|
-
function mergeConfig(config) {
|
|
40
|
-
if (!config) return DEFAULT_THEME;
|
|
41
|
-
const mergedColors = {
|
|
42
|
-
...DEFAULT_THEME.colors
|
|
43
|
-
};
|
|
44
|
-
if (config.colors) {
|
|
45
|
-
for (const type of Object.keys(config.colors)) {
|
|
46
|
-
const userColors = config.colors[type];
|
|
47
|
-
if (userColors) {
|
|
48
|
-
mergedColors[type] = {
|
|
49
|
-
...DEFAULT_THEME.colors[type],
|
|
50
|
-
...userColors
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return {
|
|
56
|
-
position: config.position ?? DEFAULT_THEME.position,
|
|
57
|
-
offset: config.offset ?? DEFAULT_THEME.offset,
|
|
58
|
-
stacking: config.stacking ?? DEFAULT_THEME.stacking,
|
|
59
|
-
maxStack: config.maxStack ?? DEFAULT_THEME.maxStack,
|
|
60
|
-
dismissible: config.dismissible ?? DEFAULT_THEME.dismissible,
|
|
61
|
-
showCloseButton: config.showCloseButton ?? DEFAULT_THEME.showCloseButton,
|
|
62
|
-
colors: mergedColors,
|
|
63
|
-
icons: {
|
|
64
|
-
...DEFAULT_THEME.icons,
|
|
65
|
-
...config.icons
|
|
66
|
-
},
|
|
67
|
-
toastStyle: {
|
|
68
|
-
...DEFAULT_THEME.toastStyle,
|
|
69
|
-
...config.toastStyle
|
|
70
|
-
},
|
|
71
|
-
titleStyle: {
|
|
72
|
-
...DEFAULT_THEME.titleStyle,
|
|
73
|
-
...config.titleStyle
|
|
74
|
-
},
|
|
75
|
-
descriptionStyle: {
|
|
76
|
-
...DEFAULT_THEME.descriptionStyle,
|
|
77
|
-
...config.descriptionStyle
|
|
78
|
-
},
|
|
79
|
-
defaultDuration: config.defaultDuration ?? DEFAULT_THEME.defaultDuration
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
class ToastStore {
|
|
83
|
-
state = {
|
|
84
|
-
visibleToasts: []
|
|
85
|
-
};
|
|
86
|
-
theme = DEFAULT_THEME;
|
|
87
|
-
listeners = new Set();
|
|
88
|
-
toastIdCounter = 0;
|
|
89
|
-
timeouts = new Map();
|
|
90
|
-
subscribe = listener => {
|
|
91
|
-
this.listeners.add(listener);
|
|
92
|
-
return () => {
|
|
93
|
-
this.listeners.delete(listener);
|
|
94
|
-
};
|
|
95
|
-
};
|
|
96
|
-
emit() {
|
|
97
|
-
for (const listener of this.listeners) {
|
|
98
|
-
listener(this.state);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
setState(partial) {
|
|
102
|
-
this.state = {
|
|
103
|
-
...this.state,
|
|
104
|
-
...partial
|
|
105
|
-
};
|
|
106
|
-
this.emit();
|
|
107
|
-
}
|
|
108
|
-
getState = () => this.state;
|
|
109
|
-
getTheme = () => this.theme;
|
|
110
|
-
setConfig = config => {
|
|
111
|
-
this.theme = mergeConfig(config);
|
|
112
|
-
};
|
|
113
|
-
show = (title, description, type = "success", duration, options) => {
|
|
114
|
-
const actualDuration = duration ?? options?.duration ?? this.theme.defaultDuration;
|
|
115
|
-
const maxToasts = this.theme.stacking ? this.theme.maxStack : 1;
|
|
116
|
-
const id = `toast-${++this.toastIdCounter}`;
|
|
117
|
-
const newToast = {
|
|
118
|
-
id,
|
|
119
|
-
title,
|
|
120
|
-
description: description ?? options?.description,
|
|
121
|
-
type,
|
|
122
|
-
duration: actualDuration,
|
|
123
|
-
createdAt: Date.now(),
|
|
124
|
-
isExiting: false,
|
|
125
|
-
options
|
|
126
|
-
};
|
|
127
|
-
const {
|
|
128
|
-
visibleToasts
|
|
129
|
-
} = this.state;
|
|
130
|
-
|
|
131
|
-
// Get only non-exiting toasts for count
|
|
132
|
-
const activeToasts = visibleToasts.filter(t => !t.isExiting);
|
|
133
|
-
if (activeToasts.length >= maxToasts) {
|
|
134
|
-
const toastsToRemove = activeToasts.slice(maxToasts - 1);
|
|
135
|
-
for (const toast of toastsToRemove) {
|
|
136
|
-
// Clear auto-dismiss timeout
|
|
137
|
-
const timeout = this.timeouts.get(toast.id);
|
|
138
|
-
if (timeout) {
|
|
139
|
-
clearTimeout(timeout);
|
|
140
|
-
this.timeouts.delete(toast.id);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
const removeIds = new Set(toastsToRemove.map(t => t.id));
|
|
144
|
-
if (this.theme.stacking) {
|
|
145
|
-
// When stacking is ON: remove old toasts from state immediately (no animation for stack overflow)
|
|
146
|
-
this.setState({
|
|
147
|
-
visibleToasts: visibleToasts.filter(t => !removeIds.has(t.id))
|
|
148
|
-
});
|
|
149
|
-
} else {
|
|
150
|
-
// When stacking is OFF: animate out the old toast, wait, then show new one
|
|
151
|
-
this.setState({
|
|
152
|
-
visibleToasts: visibleToasts.map(t => removeIds.has(t.id) ? {
|
|
153
|
-
...t,
|
|
154
|
-
isExiting: true
|
|
155
|
-
} : t)
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
// Delay showing the new toast until the old one has animated out
|
|
159
|
-
setTimeout(() => {
|
|
160
|
-
for (const toast of toastsToRemove) {
|
|
161
|
-
this.removeToast(toast.id);
|
|
162
|
-
}
|
|
163
|
-
this.addToast(newToast, actualDuration);
|
|
164
|
-
}, EXIT_DURATION - 220);
|
|
165
|
-
return id;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// Add new toast immediately (stacking ON or no existing toasts)
|
|
170
|
-
this.addToast(newToast, actualDuration);
|
|
171
|
-
return id;
|
|
172
|
-
};
|
|
173
|
-
addToast(toast, duration) {
|
|
174
|
-
this.setState({
|
|
175
|
-
visibleToasts: [toast, ...this.state.visibleToasts.filter(t => !t.isExiting)]
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
// Schedule auto-dismiss with duration multiplier based on position
|
|
179
|
-
this.scheduleTimeout(toast.id, duration, 0);
|
|
180
|
-
|
|
181
|
-
// Reschedule timeouts for other toasts based on their new positions
|
|
182
|
-
this.rescheduleAllTimeouts();
|
|
183
|
-
}
|
|
184
|
-
scheduleTimeout(id, baseDuration, index) {
|
|
185
|
-
const existingTimeout = this.timeouts.get(id);
|
|
186
|
-
if (existingTimeout) {
|
|
187
|
-
clearTimeout(existingTimeout);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// Duration multiplier: index 0 = 1x, index 1 = 2x, index 2 = 3x
|
|
191
|
-
const duration = baseDuration * (index + 1);
|
|
192
|
-
const timeout = setTimeout(() => {
|
|
193
|
-
this.hide(id);
|
|
194
|
-
}, duration);
|
|
195
|
-
this.timeouts.set(id, timeout);
|
|
196
|
-
}
|
|
197
|
-
rescheduleAllTimeouts() {
|
|
198
|
-
const {
|
|
199
|
-
visibleToasts
|
|
200
|
-
} = this.state;
|
|
201
|
-
visibleToasts.forEach((toast, index) => {
|
|
202
|
-
// Skip if already exiting or index 0 (just scheduled)
|
|
203
|
-
if (toast.isExiting || index === 0) return;
|
|
204
|
-
this.scheduleTimeout(toast.id, toast.duration, index);
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
hide = id => {
|
|
208
|
-
const {
|
|
209
|
-
visibleToasts
|
|
210
|
-
} = this.state;
|
|
211
|
-
const toast = visibleToasts.find(t => t.id === id);
|
|
212
|
-
if (!toast || toast.isExiting) return;
|
|
213
|
-
|
|
214
|
-
// Clear the auto-dismiss timeout
|
|
215
|
-
const timeout = this.timeouts.get(id);
|
|
216
|
-
if (timeout) {
|
|
217
|
-
clearTimeout(timeout);
|
|
218
|
-
this.timeouts.delete(id);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// Mark as exiting (triggers exit animation in component)
|
|
222
|
-
this.setState({
|
|
223
|
-
visibleToasts: visibleToasts.map(t => t.id === id ? {
|
|
224
|
-
...t,
|
|
225
|
-
isExiting: true
|
|
226
|
-
} : t)
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
// After exit animation, actually remove the toast
|
|
230
|
-
setTimeout(() => {
|
|
231
|
-
this.removeToast(id);
|
|
232
|
-
}, EXIT_DURATION);
|
|
233
|
-
};
|
|
234
|
-
removeToast(id) {
|
|
235
|
-
const timeout = this.timeouts.get(id);
|
|
236
|
-
if (timeout) {
|
|
237
|
-
clearTimeout(timeout);
|
|
238
|
-
this.timeouts.delete(id);
|
|
239
|
-
}
|
|
240
|
-
this.setState({
|
|
241
|
-
visibleToasts: this.state.visibleToasts.filter(t => t.id !== id)
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
// Reschedule remaining toasts with updated positions
|
|
245
|
-
this.rescheduleAllTimeouts();
|
|
246
|
-
}
|
|
247
|
-
updateToast = (id, data) => {
|
|
248
|
-
const {
|
|
249
|
-
visibleToasts
|
|
250
|
-
} = this.state;
|
|
251
|
-
const index = visibleToasts.findIndex(t => t.id === id);
|
|
252
|
-
if (index === -1) return;
|
|
253
|
-
this.setState({
|
|
254
|
-
visibleToasts: visibleToasts.map(t => t.id === id ? {
|
|
255
|
-
...t,
|
|
256
|
-
...data
|
|
257
|
-
} : t)
|
|
258
|
-
});
|
|
259
|
-
if (data.duration !== undefined) {
|
|
260
|
-
this.scheduleTimeout(id, data.duration, index);
|
|
261
|
-
}
|
|
262
|
-
};
|
|
263
|
-
hideAll = () => {
|
|
264
|
-
for (const timeout of this.timeouts.values()) {
|
|
265
|
-
clearTimeout(timeout);
|
|
266
|
-
}
|
|
267
|
-
this.timeouts.clear();
|
|
268
|
-
this.setState({
|
|
269
|
-
visibleToasts: []
|
|
270
|
-
});
|
|
271
|
-
};
|
|
272
|
-
}
|
|
273
|
-
export const toastStore = new ToastStore();
|
|
274
|
-
//# sourceMappingURL=toast-store.js.map
|
|
1
|
+
"use strict";const t={position:"top",offset:0,stacking:!0,maxStack:3,dismissible:!0,showCloseButton:!0,colors:{success:{accent:"#28B770",background:"#FFFFFF"},error:{accent:"#F05964",background:"#FFFFFF"},info:{accent:"#EDBE43",background:"#FFFFFF"},loading:{accent:"#232323",background:"#FFFFFF"}},icons:{},toastStyle:{},titleStyle:{},descriptionStyle:{},defaultDuration:4e3};export const toastStore=new class{state={visibleToasts:[]};theme=t;listeners=new Set;toastIdCounter=0;timeouts=new Map;subscribe=t=>(this.listeners.add(t),()=>{this.listeners.delete(t)});emit(){for(const t of this.listeners)t(this.state)}setState(t){this.state={...this.state,...t},this.emit()}getState=()=>this.state;getTheme=()=>this.theme;setConfig=s=>{this.theme=function(s){if(!s)return t;const e={...t.colors};if(s.colors)for(const i of Object.keys(s.colors)){const o=s.colors[i];o&&(e[i]={...t.colors[i],...o})}return{position:s.position??t.position,offset:s.offset??t.offset,stacking:s.stacking??t.stacking,maxStack:s.maxStack??t.maxStack,dismissible:s.dismissible??t.dismissible,showCloseButton:s.showCloseButton??t.showCloseButton,colors:e,icons:{...t.icons,...s.icons},toastStyle:{...t.toastStyle,...s.toastStyle},titleStyle:{...t.titleStyle,...s.titleStyle},descriptionStyle:{...t.descriptionStyle,...s.descriptionStyle},defaultDuration:s.defaultDuration??t.defaultDuration}}(s)};show=(t,s,e="success",i,o)=>{const a=i??o?.duration??this.theme.defaultDuration,n=this.theme.stacking?this.theme.maxStack:1,l="toast-"+ ++this.toastIdCounter,c={id:l,title:t,description:s??o?.description,type:e,duration:a,createdAt:Date.now(),isExiting:!1,options:o},{visibleToasts:h}=this.state,r=h.filter(t=>!t.isExiting);if(r.length>=n){const t=r.slice(n-1);for(const s of t){const t=this.timeouts.get(s.id);t&&(clearTimeout(t),this.timeouts.delete(s.id))}const s=new Set(t.map(t=>t.id));if(!this.theme.stacking)return this.setState({visibleToasts:h.map(t=>s.has(t.id)?{...t,isExiting:!0}:t)}),setTimeout(()=>{for(const s of t)this.removeToast(s.id);this.addToast(c,a)},130),l;this.setState({visibleToasts:h.filter(t=>!s.has(t.id))})}return this.addToast(c,a),l};addToast(t,s){this.setState({visibleToasts:[t,...this.state.visibleToasts.filter(t=>!t.isExiting)]}),this.scheduleTimeout(t.id,s,0),this.rescheduleAllTimeouts()}scheduleTimeout(t,s,e){const i=this.timeouts.get(t);i&&clearTimeout(i);const o=setTimeout(()=>{this.hide(t)},s*(e+1));this.timeouts.set(t,o)}rescheduleAllTimeouts(){const{visibleToasts:t}=this.state;t.forEach((t,s)=>{t.isExiting||0===s||this.scheduleTimeout(t.id,t.duration,s)})}hide=t=>{const{visibleToasts:s}=this.state,e=s.find(s=>s.id===t);if(!e||e.isExiting)return;const i=this.timeouts.get(t);i&&(clearTimeout(i),this.timeouts.delete(t)),this.setState({visibleToasts:s.map(s=>s.id===t?{...s,isExiting:!0}:s)}),setTimeout(()=>{this.removeToast(t)},350)};removeToast(t){const s=this.timeouts.get(t);s&&(clearTimeout(s),this.timeouts.delete(t)),this.setState({visibleToasts:this.state.visibleToasts.filter(s=>s.id!==t)}),this.rescheduleAllTimeouts()}updateToast=(t,s)=>{const{visibleToasts:e}=this.state,i=e.findIndex(s=>s.id===t);-1!==i&&(this.setState({visibleToasts:e.map(e=>e.id===t?{...e,...s}:e)}),void 0!==s.duration&&this.scheduleTimeout(t,s.duration,i))};hideAll=()=>{for(const t of this.timeouts.values())clearTimeout(t);this.timeouts.clear(),this.setState({visibleToasts:[]})}};
|