react-native-bread 0.5.2 → 0.5.3
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/lib/commonjs/constants.js +25 -1
- package/lib/commonjs/icons/CloseIcon.js +22 -1
- package/lib/commonjs/icons/GreenCheck.js +27 -1
- package/lib/commonjs/icons/InfoIcon.js +24 -1
- package/lib/commonjs/icons/RedX.js +27 -1
- package/lib/commonjs/icons/index.js +34 -1
- package/lib/commonjs/index.js +59 -1
- package/lib/commonjs/pool.js +53 -1
- package/lib/commonjs/toast-api.js +127 -1
- package/lib/commonjs/toast-icons.js +80 -1
- package/lib/commonjs/toast-provider.js +66 -1
- package/lib/commonjs/toast-store.js +252 -1
- package/lib/commonjs/toast.js +351 -1
- package/lib/commonjs/types.js +6 -1
- package/lib/commonjs/use-toast-state.js +72 -1
- package/lib/module/constants.js +21 -1
- package/lib/module/icons/CloseIcon.js +16 -1
- package/lib/module/icons/GreenCheck.js +21 -1
- package/lib/module/icons/InfoIcon.js +18 -1
- package/lib/module/icons/RedX.js +21 -1
- package/lib/module/icons/index.js +7 -1
- package/lib/module/index.js +14 -1
- package/lib/module/pool.js +47 -1
- package/lib/module/toast-api.js +123 -1
- package/lib/module/toast-icons.js +74 -1
- package/lib/module/toast-provider.js +62 -1
- package/lib/module/toast-store.js +248 -1
- package/lib/module/toast.js +345 -1
- package/lib/module/types.js +4 -1
- package/lib/module/use-toast-state.js +67 -1
- package/package.json +2 -3
|
@@ -1 +1,72 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useToastState = void 0;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var _reactNativeReanimated = require("react-native-reanimated");
|
|
9
|
+
var _toastStore = require("./toast-store.js");
|
|
10
|
+
const useToastState = () => {
|
|
11
|
+
const [visibleToasts, setVisibleToasts] = (0, _react.useState)([]);
|
|
12
|
+
const [theme, setTheme] = (0, _react.useState)(() => _toastStore.toastStore.getTheme());
|
|
13
|
+
const topToastRef = (0, _react.useRef)((0, _reactNativeReanimated.makeMutable)(null));
|
|
14
|
+
const isBottomRef = (0, _react.useRef)((0, _reactNativeReanimated.makeMutable)(theme.position === "bottom"));
|
|
15
|
+
const isDismissibleRef = (0, _react.useRef)((0, _reactNativeReanimated.makeMutable)(true));
|
|
16
|
+
const isBottom = theme.position === "bottom";
|
|
17
|
+
const topToast = visibleToasts.find(t => !t.isExiting);
|
|
18
|
+
const isTopDismissible = topToast?.options?.dismissible ?? theme.dismissible;
|
|
19
|
+
(0, _react.useEffect)(() => {
|
|
20
|
+
const initialToasts = _toastStore.toastStore.getState().visibleToasts;
|
|
21
|
+
const initialTheme = _toastStore.toastStore.getTheme();
|
|
22
|
+
setVisibleToasts(initialToasts);
|
|
23
|
+
const initialTopToast = initialToasts.find(t => !t.isExiting);
|
|
24
|
+
isBottomRef.current.value = initialTheme.position === "bottom";
|
|
25
|
+
isDismissibleRef.current.value = initialTopToast?.options?.dismissible ?? initialTheme.dismissible;
|
|
26
|
+
let pendingToasts = null;
|
|
27
|
+
let rafId = null;
|
|
28
|
+
const unsubscribe = _toastStore.toastStore.subscribe(state => {
|
|
29
|
+
pendingToasts = state.visibleToasts;
|
|
30
|
+
if (rafId === null) {
|
|
31
|
+
rafId = requestAnimationFrame(() => {
|
|
32
|
+
const currentToasts = pendingToasts ?? _toastStore.toastStore.getState().visibleToasts;
|
|
33
|
+
const currentTheme = _toastStore.toastStore.getTheme();
|
|
34
|
+
if (pendingToasts) {
|
|
35
|
+
setVisibleToasts(pendingToasts);
|
|
36
|
+
pendingToasts = null;
|
|
37
|
+
}
|
|
38
|
+
rafId = null;
|
|
39
|
+
setTheme(prev => prev === currentTheme ? prev : currentTheme);
|
|
40
|
+
const topToast = currentToasts.find(t => !t.isExiting);
|
|
41
|
+
isBottomRef.current.value = currentTheme.position === "bottom";
|
|
42
|
+
isDismissibleRef.current.value = topToast?.options?.dismissible ?? currentTheme.dismissible;
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
return unsubscribe;
|
|
47
|
+
}, []);
|
|
48
|
+
const toastsWithIndex = (0, _react.useMemo)(() => {
|
|
49
|
+
const indices = new Map();
|
|
50
|
+
let visualIndex = 0;
|
|
51
|
+
for (const t of visibleToasts) {
|
|
52
|
+
indices.set(t.id, t.isExiting ? -1 : visualIndex);
|
|
53
|
+
if (!t.isExiting) visualIndex++;
|
|
54
|
+
}
|
|
55
|
+
return [...visibleToasts].reverse().map(t => ({
|
|
56
|
+
toast: t,
|
|
57
|
+
index: indices.get(t.id) ?? 0
|
|
58
|
+
}));
|
|
59
|
+
}, [visibleToasts]);
|
|
60
|
+
return {
|
|
61
|
+
visibleToasts,
|
|
62
|
+
theme,
|
|
63
|
+
toastsWithIndex,
|
|
64
|
+
isBottom,
|
|
65
|
+
isTopDismissible,
|
|
66
|
+
topToastRef,
|
|
67
|
+
isBottomRef,
|
|
68
|
+
isDismissibleRef
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
exports.useToastState = useToastState;
|
|
72
|
+
//# sourceMappingURL=use-toast-state.js.map
|
package/lib/module/constants.js
CHANGED
|
@@ -1 +1,21 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { Easing } from "react-native-reanimated";
|
|
4
|
+
export const ICON_SIZE = 28;
|
|
5
|
+
export const POOL_SIZE = 5;
|
|
6
|
+
export const ENTRY_DURATION = 400;
|
|
7
|
+
export const EXIT_DURATION = 350;
|
|
8
|
+
export const STACK_TRANSITION_DURATION = 300;
|
|
9
|
+
export const SPRING_BACK_DURATION = 650;
|
|
10
|
+
export const ICON_ANIMATION_DURATION = 350;
|
|
11
|
+
export const ENTRY_OFFSET = 80;
|
|
12
|
+
export const EXIT_OFFSET = 100;
|
|
13
|
+
export const SWIPE_EXIT_OFFSET = 200;
|
|
14
|
+
export const MAX_DRAG_CLAMP = 180;
|
|
15
|
+
export const MAX_DRAG_RESISTANCE = 60;
|
|
16
|
+
export const DISMISS_THRESHOLD = 40;
|
|
17
|
+
export const DISMISS_VELOCITY_THRESHOLD = 300;
|
|
18
|
+
export const STACK_OFFSET_PER_ITEM = 10;
|
|
19
|
+
export const STACK_SCALE_PER_ITEM = 0.05;
|
|
20
|
+
export const EASING = Easing.bezier(0.25, 0.1, 0.25, 1.0);
|
|
21
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +1,16 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import Svg, { Path } from "react-native-svg";
|
|
4
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
5
|
+
export const CloseIcon = props => /*#__PURE__*/_jsx(Svg, {
|
|
6
|
+
viewBox: "0 0 24 24",
|
|
7
|
+
width: 24,
|
|
8
|
+
height: 24,
|
|
9
|
+
fill: "none",
|
|
10
|
+
...props,
|
|
11
|
+
children: /*#__PURE__*/_jsx(Path, {
|
|
12
|
+
fill: props.fill ?? "#8993A4",
|
|
13
|
+
d: "M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41Z"
|
|
14
|
+
})
|
|
15
|
+
});
|
|
16
|
+
//# sourceMappingURL=CloseIcon.js.map
|
|
@@ -1 +1,21 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import Svg, { Path } from "react-native-svg";
|
|
4
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
5
|
+
export const GreenCheck = props => /*#__PURE__*/_jsxs(Svg, {
|
|
6
|
+
viewBox: "0 0 30 31",
|
|
7
|
+
width: 30,
|
|
8
|
+
height: 31,
|
|
9
|
+
fill: "none",
|
|
10
|
+
...props,
|
|
11
|
+
children: [/*#__PURE__*/_jsx(Path, {
|
|
12
|
+
fill: props.fill ?? "#28B770",
|
|
13
|
+
fillRule: "evenodd",
|
|
14
|
+
d: "m19.866 13.152-5.772 5.773a.933.933 0 0 1-1.326 0L9.88 16.039a.938.938 0 0 1 1.325-1.327l2.225 2.224 5.109-5.11a.938.938 0 1 1 1.326 1.326Zm.28-9.652H9.602C5.654 3.5 3 6.276 3 10.409v9.935c0 4.131 2.654 6.906 6.602 6.906h10.543c3.95 0 6.605-2.775 6.605-6.906v-9.935c0-4.133-2.654-6.909-6.604-6.909Z",
|
|
15
|
+
clipRule: "evenodd"
|
|
16
|
+
}), /*#__PURE__*/_jsx(Path, {
|
|
17
|
+
fill: "#fff",
|
|
18
|
+
d: "m19.866 13.152-5.772 5.773a.933.933 0 0 1-1.326 0L9.88 16.039a.938.938 0 0 1 1.325-1.327l2.225 2.224 5.109-5.11a.938.938 0 1 1 1.326 1.326Z"
|
|
19
|
+
})]
|
|
20
|
+
});
|
|
21
|
+
//# sourceMappingURL=GreenCheck.js.map
|
|
@@ -1 +1,18 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import Svg, { Path } from "react-native-svg";
|
|
4
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
5
|
+
export const InfoIcon = props => /*#__PURE__*/_jsx(Svg, {
|
|
6
|
+
viewBox: "0 0 24 24",
|
|
7
|
+
width: 24,
|
|
8
|
+
height: 24,
|
|
9
|
+
fill: "none",
|
|
10
|
+
...props,
|
|
11
|
+
children: /*#__PURE__*/_jsx(Path, {
|
|
12
|
+
fill: props.fill ?? "#EDBE43",
|
|
13
|
+
fillRule: "evenodd",
|
|
14
|
+
d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2Zm1 15h-2v-6h2v6Zm0-8h-2V7h2v2Z",
|
|
15
|
+
clipRule: "evenodd"
|
|
16
|
+
})
|
|
17
|
+
});
|
|
18
|
+
//# sourceMappingURL=InfoIcon.js.map
|
package/lib/module/icons/RedX.js
CHANGED
|
@@ -1 +1,21 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import Svg, { Path } from "react-native-svg";
|
|
4
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
5
|
+
export const RedX = props => /*#__PURE__*/_jsxs(Svg, {
|
|
6
|
+
viewBox: "0 0 24 24",
|
|
7
|
+
width: 24,
|
|
8
|
+
height: 24,
|
|
9
|
+
fill: "none",
|
|
10
|
+
...props,
|
|
11
|
+
children: [/*#__PURE__*/_jsx(Path, {
|
|
12
|
+
fill: props.fill ?? "#F05964",
|
|
13
|
+
fillRule: "evenodd",
|
|
14
|
+
d: "M15.58 15.572a.935.935 0 0 1-1.326 0l-2.258-2.258-2.251 2.252a.938.938 0 0 1-1.326-1.325l2.251-2.252-2.252-2.254A.936.936 0 1 1 9.742 8.41l2.253 2.252 2.252-2.25a.939.939 0 0 1 1.325 1.325l-2.25 2.252 2.257 2.257a.938.938 0 0 1 0 1.326ZM17.271.126H6.727C2.777.125.125 2.9.125 7.032v9.936c0 4.13 2.652 6.907 6.603 6.907H17.27c3.95 0 6.605-2.776 6.605-6.907V7.032c0-4.132-2.654-6.907-6.604-6.907Z",
|
|
15
|
+
clipRule: "evenodd"
|
|
16
|
+
}), /*#__PURE__*/_jsx(Path, {
|
|
17
|
+
fill: "#fff",
|
|
18
|
+
d: "M15.58 15.572a.935.935 0 0 1-1.326 0l-2.258-2.258-2.251 2.252a.938.938 0 0 1-1.326-1.325l2.251-2.252-2.252-2.254A.936.936 0 1 1 9.742 8.41l2.253 2.252 2.252-2.25a.939.939 0 0 1 1.325 1.325l-2.25 2.252 2.257 2.257a.938.938 0 0 1 0 1.326Z"
|
|
19
|
+
})]
|
|
20
|
+
});
|
|
21
|
+
//# sourceMappingURL=RedX.js.map
|
|
@@ -1 +1,7 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
export { CloseIcon } from "./CloseIcon.js";
|
|
4
|
+
export { GreenCheck } from "./GreenCheck.js";
|
|
5
|
+
export { InfoIcon } from "./InfoIcon.js";
|
|
6
|
+
export { RedX } from "./RedX.js";
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
package/lib/module/index.js
CHANGED
|
@@ -1 +1,14 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// Main exports
|
|
4
|
+
|
|
5
|
+
// Icons (for customization)
|
|
6
|
+
export { CloseIcon, GreenCheck, InfoIcon, RedX } from "./icons/index.js";
|
|
7
|
+
export { ToastContainer } from "./toast.js";
|
|
8
|
+
export { toast } from "./toast-api.js";
|
|
9
|
+
export { BreadLoaf } from "./toast-provider.js";
|
|
10
|
+
|
|
11
|
+
// Store (for advanced usage)
|
|
12
|
+
export { toastStore } from "./toast-store.js";
|
|
13
|
+
// Types
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
package/lib/module/pool.js
CHANGED
|
@@ -1 +1,47 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { makeMutable } from "react-native-reanimated";
|
|
4
|
+
import { POOL_SIZE } from "./constants.js";
|
|
5
|
+
export const animationPool = Array.from({
|
|
6
|
+
length: POOL_SIZE
|
|
7
|
+
}, () => ({
|
|
8
|
+
progress: makeMutable(0),
|
|
9
|
+
translationY: makeMutable(0),
|
|
10
|
+
stackIndex: makeMutable(0)
|
|
11
|
+
}));
|
|
12
|
+
export const slotTrackers = Array.from({
|
|
13
|
+
length: POOL_SIZE
|
|
14
|
+
}, () => ({
|
|
15
|
+
wasExiting: false,
|
|
16
|
+
prevIndex: 0,
|
|
17
|
+
initialized: false
|
|
18
|
+
}));
|
|
19
|
+
const slotAssignments = new Map();
|
|
20
|
+
const usedSlots = new Set();
|
|
21
|
+
export const getSlotIndex = toastId => {
|
|
22
|
+
if (slotAssignments.has(toastId)) {
|
|
23
|
+
return slotAssignments.get(toastId) ?? 0;
|
|
24
|
+
}
|
|
25
|
+
for (let i = 0; i < POOL_SIZE; i++) {
|
|
26
|
+
if (!usedSlots.has(i)) {
|
|
27
|
+
slotAssignments.set(toastId, i);
|
|
28
|
+
usedSlots.add(i);
|
|
29
|
+
slotTrackers[i].initialized = false;
|
|
30
|
+
slotTrackers[i].wasExiting = false;
|
|
31
|
+
slotTrackers[i].prevIndex = 0;
|
|
32
|
+
return i;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return 0;
|
|
36
|
+
};
|
|
37
|
+
export const releaseSlot = toastId => {
|
|
38
|
+
const idx = slotAssignments.get(toastId);
|
|
39
|
+
if (idx !== undefined) {
|
|
40
|
+
usedSlots.delete(idx);
|
|
41
|
+
slotAssignments.delete(toastId);
|
|
42
|
+
slotTrackers[idx].initialized = false;
|
|
43
|
+
slotTrackers[idx].wasExiting = false;
|
|
44
|
+
slotTrackers[idx].prevIndex = 0;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
//# sourceMappingURL=pool.js.map
|
package/lib/module/toast-api.js
CHANGED
|
@@ -1 +1,123 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { toastStore } from "./toast-store.js";
|
|
4
|
+
const _toast = (title, description, type, duration) => {
|
|
5
|
+
toastStore.show(title, description, type, duration);
|
|
6
|
+
};
|
|
7
|
+
const parseDescriptionOrOptions = arg => {
|
|
8
|
+
if (!arg) return {};
|
|
9
|
+
if (typeof arg === "string") return {
|
|
10
|
+
description: arg
|
|
11
|
+
};
|
|
12
|
+
return {
|
|
13
|
+
description: arg.description,
|
|
14
|
+
duration: arg.duration,
|
|
15
|
+
options: arg
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
const parseMessage = input => typeof input === "string" ? {
|
|
19
|
+
title: input
|
|
20
|
+
} : input;
|
|
21
|
+
const parseErrorMessage = (input, error) => {
|
|
22
|
+
if (typeof input === "function") {
|
|
23
|
+
return parseMessage(input(error));
|
|
24
|
+
}
|
|
25
|
+
return parseMessage(input);
|
|
26
|
+
};
|
|
27
|
+
const promiseToast = async (promise, messages) => {
|
|
28
|
+
const loadingCfg = parseMessage(messages.loading);
|
|
29
|
+
const toastId = toastStore.show(loadingCfg.title, loadingCfg.description, "loading", loadingCfg.duration ?? 60 * 60 * 1000);
|
|
30
|
+
try {
|
|
31
|
+
const result = await promise;
|
|
32
|
+
const successCfg = parseMessage(messages.success);
|
|
33
|
+
toastStore.updateToast(toastId, {
|
|
34
|
+
title: successCfg.title,
|
|
35
|
+
description: successCfg.description,
|
|
36
|
+
type: "success",
|
|
37
|
+
duration: successCfg.duration ?? 4000
|
|
38
|
+
});
|
|
39
|
+
return {
|
|
40
|
+
data: result,
|
|
41
|
+
success: true
|
|
42
|
+
};
|
|
43
|
+
} catch (err) {
|
|
44
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
45
|
+
const errorCfg = parseErrorMessage(messages.error, error);
|
|
46
|
+
toastStore.updateToast(toastId, {
|
|
47
|
+
title: errorCfg.title,
|
|
48
|
+
description: errorCfg.description,
|
|
49
|
+
type: "error",
|
|
50
|
+
duration: errorCfg.duration ?? 4000
|
|
51
|
+
});
|
|
52
|
+
return {
|
|
53
|
+
error,
|
|
54
|
+
success: false
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
const toastFn = _toast;
|
|
59
|
+
toastFn.custom = (content, options) => {
|
|
60
|
+
const type = options?.type ?? "info";
|
|
61
|
+
return toastStore.show("", undefined, type, options?.duration, {
|
|
62
|
+
...options,
|
|
63
|
+
customContent: content
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
toastFn.success = (title, descriptionOrOptions, duration) => {
|
|
67
|
+
const {
|
|
68
|
+
description,
|
|
69
|
+
duration: optDuration,
|
|
70
|
+
options
|
|
71
|
+
} = parseDescriptionOrOptions(descriptionOrOptions);
|
|
72
|
+
toastStore.show(title, description, "success", duration ?? optDuration, options);
|
|
73
|
+
};
|
|
74
|
+
toastFn.error = (title, descriptionOrOptions, duration) => {
|
|
75
|
+
const {
|
|
76
|
+
description,
|
|
77
|
+
duration: optDuration,
|
|
78
|
+
options
|
|
79
|
+
} = parseDescriptionOrOptions(descriptionOrOptions);
|
|
80
|
+
toastStore.show(title, description, "error", duration ?? optDuration, options);
|
|
81
|
+
};
|
|
82
|
+
toastFn.info = (title, descriptionOrOptions, duration) => {
|
|
83
|
+
const {
|
|
84
|
+
description,
|
|
85
|
+
duration: optDuration,
|
|
86
|
+
options
|
|
87
|
+
} = parseDescriptionOrOptions(descriptionOrOptions);
|
|
88
|
+
toastStore.show(title, description, "info", duration ?? optDuration, options);
|
|
89
|
+
};
|
|
90
|
+
toastFn.promise = promiseToast;
|
|
91
|
+
toastFn.dismiss = id => {
|
|
92
|
+
toastStore.hide(id);
|
|
93
|
+
};
|
|
94
|
+
toastFn.dismissAll = () => {
|
|
95
|
+
toastStore.hideAll();
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Toast API for showing notifications.
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```ts
|
|
103
|
+
* import { toast } from 'react-native-bread';
|
|
104
|
+
*
|
|
105
|
+
* // Basic toasts
|
|
106
|
+
* toast.success("Saved!", "Your changes have been saved");
|
|
107
|
+
* toast.error("Error", "Something went wrong");
|
|
108
|
+
* toast.info("Tip", "Swipe up to dismiss");
|
|
109
|
+
*
|
|
110
|
+
* // Promise toast (loading → success/error)
|
|
111
|
+
* toast.promise(apiCall(), {
|
|
112
|
+
* loading: { title: "Loading..." },
|
|
113
|
+
* success: { title: "Done!" },
|
|
114
|
+
* error: (err) => ({ title: "Failed", description: err.message }),
|
|
115
|
+
* });
|
|
116
|
+
*
|
|
117
|
+
* // Dismiss toasts
|
|
118
|
+
* toast.dismiss(id);
|
|
119
|
+
* toast.dismissAll();
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
export const toast = toastFn;
|
|
123
|
+
//# sourceMappingURL=toast-api.js.map
|
|
@@ -1 +1,74 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { memo, useEffect } from "react";
|
|
4
|
+
import { ActivityIndicator } from "react-native";
|
|
5
|
+
import Animated, { Easing, useAnimatedStyle, useSharedValue, withTiming } from "react-native-reanimated";
|
|
6
|
+
import { ICON_ANIMATION_DURATION, ICON_SIZE } from "./constants.js";
|
|
7
|
+
import { GreenCheck, InfoIcon, RedX } from "./icons/index.js";
|
|
8
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
9
|
+
export const resolveIcon = (type, color, custom, config) => {
|
|
10
|
+
if (custom) return typeof custom === "function" ? custom({
|
|
11
|
+
color,
|
|
12
|
+
size: ICON_SIZE
|
|
13
|
+
}) : custom;
|
|
14
|
+
if (config) return config({
|
|
15
|
+
color,
|
|
16
|
+
size: ICON_SIZE
|
|
17
|
+
});
|
|
18
|
+
switch (type) {
|
|
19
|
+
case "success":
|
|
20
|
+
return /*#__PURE__*/_jsx(GreenCheck, {
|
|
21
|
+
width: 36,
|
|
22
|
+
height: 36,
|
|
23
|
+
fill: color
|
|
24
|
+
});
|
|
25
|
+
case "error":
|
|
26
|
+
return /*#__PURE__*/_jsx(RedX, {
|
|
27
|
+
width: ICON_SIZE,
|
|
28
|
+
height: ICON_SIZE,
|
|
29
|
+
fill: color
|
|
30
|
+
});
|
|
31
|
+
case "loading":
|
|
32
|
+
return /*#__PURE__*/_jsx(ActivityIndicator, {
|
|
33
|
+
size: ICON_SIZE,
|
|
34
|
+
color: color
|
|
35
|
+
});
|
|
36
|
+
case "info":
|
|
37
|
+
return /*#__PURE__*/_jsx(InfoIcon, {
|
|
38
|
+
width: ICON_SIZE,
|
|
39
|
+
height: ICON_SIZE,
|
|
40
|
+
fill: color
|
|
41
|
+
});
|
|
42
|
+
default:
|
|
43
|
+
return /*#__PURE__*/_jsx(GreenCheck, {
|
|
44
|
+
width: 36,
|
|
45
|
+
height: 36,
|
|
46
|
+
fill: color
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
export const AnimatedIcon = /*#__PURE__*/memo(({
|
|
51
|
+
type,
|
|
52
|
+
color,
|
|
53
|
+
custom,
|
|
54
|
+
config
|
|
55
|
+
}) => {
|
|
56
|
+
const progress = useSharedValue(0);
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
progress.value = withTiming(1, {
|
|
59
|
+
duration: ICON_ANIMATION_DURATION,
|
|
60
|
+
easing: Easing.out(Easing.back(1.5))
|
|
61
|
+
});
|
|
62
|
+
}, [progress]);
|
|
63
|
+
const style = useAnimatedStyle(() => ({
|
|
64
|
+
opacity: progress.value,
|
|
65
|
+
transform: [{
|
|
66
|
+
scale: 0.7 + progress.value * 0.3
|
|
67
|
+
}]
|
|
68
|
+
}));
|
|
69
|
+
return /*#__PURE__*/_jsx(Animated.View, {
|
|
70
|
+
style: style,
|
|
71
|
+
children: resolveIcon(type, color, custom, config)
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
//# sourceMappingURL=toast-icons.js.map
|
|
@@ -1 +1,62 @@
|
|
|
1
|
-
"use strict";
|
|
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
|