react-native-bread 0.5.2 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1,351 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ToastContainer=void 0;var t=require("react"),e=require("react-native"),i=require("react-native-gesture-handler"),o=function(t,e){if("function"==typeof WeakMap)var i=new WeakMap,o=new WeakMap;return function(t,e){if(!e&&t&&t.__esModule)return t;var n,s,a={__proto__:null,default:t};if(null===t||"object"!=typeof t&&"function"!=typeof t)return a;if(n=e?o:i){if(n.has(t))return n.get(t);n.set(t,a)}for(const e in t)"default"!==e&&{}.hasOwnProperty.call(t,e)&&((s=(n=Object.defineProperty)&&Object.getOwnPropertyDescriptor(t,e))&&(s.get||s.set)?n(a,e,s):a[e]=t[e]);return a}(t,e)}(require("react-native-reanimated")),n=require("react-native-safe-area-context"),s=require("react-native-worklets"),a=require("./constants.js"),r=require("./icons/index.js"),l=require("./pool.js"),u=require("./toast-icons.js"),c=require("./toast-store.js"),d=require("./use-toast-state.js"),p=require("react/jsx-runtime");exports.ToastContainer=()=>{const{top:r,bottom:l}=(0,n.useSafeAreaInsets)(),{visibleToasts:u,theme:c,toastsWithIndex:T,isBottom:I,topToastRef:h,isBottomRef:f,isDismissibleRef:E}=(0,d.useToastState)(),m=(0,o.useSharedValue)(!1),x=(0,t.useMemo)(()=>i.Gesture.Pan().onStart(()=>{"worklet";m.set(!1)}).onUpdate(t=>{"worklet";if(!E.current.value)return;const e=h.current.value;if(!e)return;const{slot:i}=e,o=f.current.value,n=t.translationY,s=o?n:-n,r=o?-n:n;if(s>0){const e=o?Math.min(n,a.MAX_DRAG_CLAMP):Math.max(n,-a.MAX_DRAG_CLAMP);i.translationY.value=e;const r=s>a.DISMISS_THRESHOLD||(o?t.velocityY>a.DISMISS_VELOCITY_THRESHOLD:t.velocityY<-a.DISMISS_VELOCITY_THRESHOLD);m.set(r)}else{const t=a.MAX_DRAG_RESISTANCE*(1-Math.exp(-r/250));i.translationY.value=o?-Math.min(t,a.MAX_DRAG_RESISTANCE):Math.min(t,a.MAX_DRAG_RESISTANCE),m.value=!1}}).onEnd(()=>{"worklet";if(!E.current.value)return;const t=h.current.value;if(!t)return;const{slot:e}=t,i=f.current.value;if(m.value){e.progress.value=(0,o.withTiming)(0,{duration:a.EXIT_DURATION,easing:a.EASING});const n=i?a.SWIPE_EXIT_OFFSET:-a.SWIPE_EXIT_OFFSET;e.translationY.value=(0,o.withTiming)(e.translationY.value+n,{duration:a.EXIT_DURATION,easing:a.EASING}),(0,s.scheduleOnRN)(t.dismiss)}else e.translationY.value=(0,o.withTiming)(0,{duration:a.SPRING_BACK_DURATION,easing:a.EASING})}),[m,E,h,f]),v=(0,t.useCallback)(t=>{h.current.value=t},[h]);if(0===u.length)return null;const _=I?l:r,y=I?{bottom:_+c.offset+2}:{top:_+c.offset+2};return(0,p.jsx)(i.GestureDetector,{gesture:x,children:(0,p.jsx)(e.View,{style:[S.container,y],pointerEvents:"box-none",children:T.map(({toast:t,index:e})=>(0,p.jsx)(g,{toast:t,index:e,theme:c,position:c.position,isTopToast:0===e,registerTopToast:v},t.id))})})};const T=({toast:i,index:n,theme:s,position:d,isTopToast:T,registerTopToast:g})=>{const[I]=(0,t.useState)(()=>(0,l.getSlotIndex)(i.id)),h=l.animationPool[I],f=l.slotTrackers[I],E="bottom"===d,m=E?a.ENTRY_OFFSET:-a.ENTRY_OFFSET,x=E?a.EXIT_OFFSET:-a.EXIT_OFFSET,[v,_]=(0,t.useState)("loading"===i.type),[y,A]=(0,t.useState)(!1);(0,t.useEffect)(()=>{h.progress.value=0,h.translationY.value=0,h.stackIndex.value=n,h.progress.value=(0,o.withTiming)(1,{duration:a.ENTRY_DURATION,easing:a.EASING});const t=setTimeout(()=>A(!0),50);return()=>{clearTimeout(t),(0,l.releaseSlot)(i.id)}},[]);const w=(0,t.useCallback)(()=>{c.toastStore.hide(i.id)},[i.id]);(0,t.useEffect)(()=>{let t=null;return i.isExiting&&!f.wasExiting&&(f.wasExiting=!0,h.progress.value=(0,o.withTiming)(0,{duration:a.EXIT_DURATION,easing:a.EASING}),h.translationY.value=(0,o.withTiming)(x,{duration:a.EXIT_DURATION,easing:a.EASING})),f.initialized&&n!==f.prevIndex&&(h.stackIndex.value=(0,o.withTiming)(n,{duration:a.STACK_TRANSITION_DURATION,easing:a.EASING})),f.prevIndex=n,f.initialized=!0,"loading"===i.type?_(!0):v&&(t=setTimeout(()=>_(!1),a.ICON_ANIMATION_DURATION+50)),T&&g({slot:h,dismiss:w}),()=>{t&&clearTimeout(t),T&&g(null)}},[i.isExiting,n,h,f,x,i.type,v,T,g,w]);const C=v&&"loading"!==i.type,R=(0,o.useAnimatedStyle)(()=>{const t=(0,o.interpolate)(h.progress.value,[0,1],[m,0]),e=E?h.stackIndex.value*a.STACK_OFFSET_PER_ITEM:h.stackIndex.value*-a.STACK_OFFSET_PER_ITEM,i=1-h.stackIndex.value*a.STACK_SCALE_PER_ITEM,n=t+h.translationY.value+e,s=(0,o.interpolate)(h.progress.value,[0,1],[0,1]),r=E?h.translationY.value:-h.translationY.value,l=s*(r>0?(0,o.interpolate)(r,[0,130],[1,0],"clamp"):1);return{transform:[{translateY:n},{scale:i*(0,o.interpolate)(Math.abs(h.translationY.value),[0,50],[1,.98],"clamp")}],opacity:l,zIndex:1e3-Math.round(h.stackIndex.value)}}),{options:O}=i,M=s.colors[i.type];if(void 0!==O?.customContent){const t=O.customContent;return(0,p.jsx)(o.default.View,{style:[S.toast,S.customContentToast,E?S.toastBottom:S.toastTop,{backgroundColor:M.background},s.toastStyle,O.style,R],children:"function"==typeof t?t({id:i.id,dismiss:w,type:i.type,isExiting:!!i.isExiting}):t})}const N="loading"!==i.type&&(O?.showCloseButton??s.showCloseButton);return(0,p.jsxs)(o.default.View,{style:[S.toast,E?S.toastBottom:S.toastTop,{backgroundColor:M.background},s.rtl&&S.rtl,s.toastStyle,O?.style,R],children:[(0,p.jsx)(e.View,{style:S.iconContainer,children:y&&(C?(0,p.jsx)(u.AnimatedIcon,{type:i.type,color:M.accent,custom:O?.icon,config:s.icons[i.type]},i.type):(0,u.resolveIcon)(i.type,M.accent,O?.icon,s.icons[i.type]))}),(0,p.jsxs)(e.View,{style:S.textContainer,children:[(0,p.jsx)(e.Text,{maxFontSizeMultiplier:1.35,allowFontScaling:!1,style:[S.title,{color:M.accent},s.rtl&&{textAlign:"right"},s.titleStyle,O?.titleStyle],children:i.title}),i.description&&(0,p.jsx)(e.Text,{allowFontScaling:!1,maxFontSizeMultiplier:1.35,style:[S.description,s.rtl&&{textAlign:"right"},s.descriptionStyle,O?.descriptionStyle],children:i.description})]}),N&&(0,p.jsx)(e.Pressable,{style:S.closeButton,onPress:w,hitSlop:12,children:(0,p.jsx)(r.CloseIcon,{width:20,height:20})})]})},g=(0,t.memo)(T,(t,e)=>t.toast.id===e.toast.id&&t.toast.type===e.toast.type&&t.toast.title===e.toast.title&&t.toast.description===e.toast.description&&t.toast.isExiting===e.toast.isExiting&&t.index===e.index&&t.position===e.position&&t.theme===e.theme&&t.isTopToast===e.isTopToast),S=e.StyleSheet.create({container:{position:"absolute",left:16,right:16,zIndex:1e3},toast:{flexDirection:"row",alignItems:"center",gap:12,minHeight:36,borderRadius:20,borderCurve:"continuous",position:"absolute",left:0,right:0,paddingHorizontal:12,paddingVertical:10,shadowColor:"#000",shadowOffset:{width:0,height:8},shadowOpacity:.05,shadowRadius:24,elevation:8},customContentToast:{padding:0,paddingHorizontal:0,paddingVertical:0,overflow:"hidden"},rtl:{flexDirection:"row-reverse"},toastTop:{top:0},toastBottom:{bottom:0},iconContainer:{width:48,height:48,alignItems:"center",justifyContent:"center",marginLeft:8},textContainer:{flex:1,gap:1,justifyContent:"center"},title:{fontSize:14,fontWeight:"700",lineHeight:20},description:{color:"#6B7280",fontSize:12,fontWeight:"500",lineHeight:16},closeButton:{padding:4,alignItems:"center",justifyContent:"center"}});
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.ToastContainer = void 0;
7
+ var _react = require("react");
8
+ var _reactNative = require("react-native");
9
+ var _reactNativeGestureHandler = require("react-native-gesture-handler");
10
+ var _reactNativeReanimated = _interopRequireWildcard(require("react-native-reanimated"));
11
+ var _reactNativeSafeAreaContext = require("react-native-safe-area-context");
12
+ var _reactNativeWorklets = require("react-native-worklets");
13
+ var _constants = require("./constants.js");
14
+ var _index = require("./icons/index.js");
15
+ var _pool = require("./pool.js");
16
+ var _toastIcons = require("./toast-icons.js");
17
+ var _toastStore = require("./toast-store.js");
18
+ var _useToastState = require("./use-toast-state.js");
19
+ var _jsxRuntime = require("react/jsx-runtime");
20
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
21
+ const ToastContainer = () => {
22
+ const {
23
+ top,
24
+ bottom
25
+ } = (0, _reactNativeSafeAreaContext.useSafeAreaInsets)();
26
+ const {
27
+ visibleToasts,
28
+ theme,
29
+ toastsWithIndex,
30
+ isBottom,
31
+ topToastRef,
32
+ isBottomRef,
33
+ isDismissibleRef
34
+ } = (0, _useToastState.useToastState)();
35
+ const shouldDismiss = (0, _reactNativeReanimated.useSharedValue)(false);
36
+ const panGesture = (0, _react.useMemo)(() => _reactNativeGestureHandler.Gesture.Pan().onStart(() => {
37
+ "worklet";
38
+
39
+ shouldDismiss.set(false);
40
+ }).onUpdate(event => {
41
+ "worklet";
42
+
43
+ if (!isDismissibleRef.current.value) return;
44
+ const ref = topToastRef.current.value;
45
+ if (!ref) return;
46
+ const {
47
+ slot
48
+ } = ref;
49
+ const bottom = isBottomRef.current.value;
50
+ const rawY = event.translationY;
51
+ const dismissDrag = bottom ? rawY : -rawY;
52
+ const resistDrag = bottom ? -rawY : rawY;
53
+ if (dismissDrag > 0) {
54
+ const clampedY = bottom ? Math.min(rawY, _constants.MAX_DRAG_CLAMP) : Math.max(rawY, -_constants.MAX_DRAG_CLAMP);
55
+ slot.translationY.value = clampedY;
56
+ const shouldTriggerDismiss = dismissDrag > _constants.DISMISS_THRESHOLD || (bottom ? event.velocityY > _constants.DISMISS_VELOCITY_THRESHOLD : event.velocityY < -_constants.DISMISS_VELOCITY_THRESHOLD);
57
+ shouldDismiss.set(shouldTriggerDismiss);
58
+ } else {
59
+ const exponentialDrag = _constants.MAX_DRAG_RESISTANCE * (1 - Math.exp(-resistDrag / 250));
60
+ slot.translationY.value = bottom ? -Math.min(exponentialDrag, _constants.MAX_DRAG_RESISTANCE) : Math.min(exponentialDrag, _constants.MAX_DRAG_RESISTANCE);
61
+ shouldDismiss.value = false;
62
+ }
63
+ }).onEnd(() => {
64
+ "worklet";
65
+
66
+ if (!isDismissibleRef.current.value) return;
67
+ const ref = topToastRef.current.value;
68
+ if (!ref) return;
69
+ const {
70
+ slot
71
+ } = ref;
72
+ const bottom = isBottomRef.current.value;
73
+ if (shouldDismiss.value) {
74
+ slot.progress.value = (0, _reactNativeReanimated.withTiming)(0, {
75
+ duration: _constants.EXIT_DURATION,
76
+ easing: _constants.EASING
77
+ });
78
+ const exitOffset = bottom ? _constants.SWIPE_EXIT_OFFSET : -_constants.SWIPE_EXIT_OFFSET;
79
+ slot.translationY.value = (0, _reactNativeReanimated.withTiming)(slot.translationY.value + exitOffset, {
80
+ duration: _constants.EXIT_DURATION,
81
+ easing: _constants.EASING
82
+ });
83
+ (0, _reactNativeWorklets.scheduleOnRN)(ref.dismiss);
84
+ } else {
85
+ slot.translationY.value = (0, _reactNativeReanimated.withTiming)(0, {
86
+ duration: _constants.SPRING_BACK_DURATION,
87
+ easing: _constants.EASING
88
+ });
89
+ }
90
+ }), [shouldDismiss, isDismissibleRef, topToastRef, isBottomRef]);
91
+ const registerTopToast = (0, _react.useCallback)(values => {
92
+ topToastRef.current.value = values;
93
+ }, [topToastRef]);
94
+ if (visibleToasts.length === 0) return null;
95
+ const inset = isBottom ? bottom : top;
96
+ const positionStyle = isBottom ? {
97
+ bottom: inset + theme.offset + 2
98
+ } : {
99
+ top: inset + theme.offset + 2
100
+ };
101
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeGestureHandler.GestureDetector, {
102
+ gesture: panGesture,
103
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
104
+ style: [styles.container, positionStyle],
105
+ pointerEvents: "box-none",
106
+ children: toastsWithIndex.map(({
107
+ toast,
108
+ index
109
+ }) => /*#__PURE__*/(0, _jsxRuntime.jsx)(MemoizedToastItem, {
110
+ toast: toast,
111
+ index: index,
112
+ theme: theme,
113
+ position: theme.position,
114
+ isTopToast: index === 0,
115
+ registerTopToast: registerTopToast
116
+ }, toast.id))
117
+ })
118
+ });
119
+ };
120
+ exports.ToastContainer = ToastContainer;
121
+ const ToastItem = ({
122
+ toast,
123
+ index,
124
+ theme,
125
+ position,
126
+ isTopToast,
127
+ registerTopToast
128
+ }) => {
129
+ const [slotIdx] = (0, _react.useState)(() => (0, _pool.getSlotIndex)(toast.id));
130
+ const slot = _pool.animationPool[slotIdx];
131
+ const tracker = _pool.slotTrackers[slotIdx];
132
+ const isBottom = position === "bottom";
133
+ const entryFromY = isBottom ? _constants.ENTRY_OFFSET : -_constants.ENTRY_OFFSET;
134
+ const exitToY = isBottom ? _constants.EXIT_OFFSET : -_constants.EXIT_OFFSET;
135
+ const [wasLoading, setWasLoading] = (0, _react.useState)(toast.type === "loading");
136
+ const [showIcon, setShowIcon] = (0, _react.useState)(false);
137
+
138
+ // biome-ignore lint/correctness/useExhaustiveDependencies: mount-only effect
139
+ (0, _react.useEffect)(() => {
140
+ slot.progress.value = 0;
141
+ slot.translationY.value = 0;
142
+ slot.stackIndex.value = index;
143
+ slot.progress.value = (0, _reactNativeReanimated.withTiming)(1, {
144
+ duration: _constants.ENTRY_DURATION,
145
+ easing: _constants.EASING
146
+ });
147
+ const iconTimeout = setTimeout(() => setShowIcon(true), 50);
148
+ return () => {
149
+ clearTimeout(iconTimeout);
150
+ (0, _pool.releaseSlot)(toast.id);
151
+ };
152
+ }, []);
153
+ const dismissToast = (0, _react.useCallback)(() => {
154
+ _toastStore.toastStore.hide(toast.id);
155
+ }, [toast.id]);
156
+ (0, _react.useEffect)(() => {
157
+ let loadingTimeout = null;
158
+ if (toast.isExiting && !tracker.wasExiting) {
159
+ tracker.wasExiting = true;
160
+ slot.progress.value = (0, _reactNativeReanimated.withTiming)(0, {
161
+ duration: _constants.EXIT_DURATION,
162
+ easing: _constants.EASING
163
+ });
164
+ slot.translationY.value = (0, _reactNativeReanimated.withTiming)(exitToY, {
165
+ duration: _constants.EXIT_DURATION,
166
+ easing: _constants.EASING
167
+ });
168
+ }
169
+ if (tracker.initialized && index !== tracker.prevIndex) {
170
+ slot.stackIndex.value = (0, _reactNativeReanimated.withTiming)(index, {
171
+ duration: _constants.STACK_TRANSITION_DURATION,
172
+ easing: _constants.EASING
173
+ });
174
+ }
175
+ tracker.prevIndex = index;
176
+ tracker.initialized = true;
177
+ if (toast.type === "loading") {
178
+ setWasLoading(true);
179
+ } else if (wasLoading) {
180
+ loadingTimeout = setTimeout(() => setWasLoading(false), _constants.ICON_ANIMATION_DURATION + 50);
181
+ }
182
+ if (isTopToast) {
183
+ registerTopToast({
184
+ slot: slot,
185
+ dismiss: dismissToast
186
+ });
187
+ }
188
+ return () => {
189
+ if (loadingTimeout) clearTimeout(loadingTimeout);
190
+ if (isTopToast) registerTopToast(null);
191
+ };
192
+ }, [toast.isExiting, index, slot, tracker, exitToY, toast.type, wasLoading, isTopToast, registerTopToast, dismissToast]);
193
+ const shouldAnimateIcon = wasLoading && toast.type !== "loading";
194
+ const animatedStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => {
195
+ const baseTranslateY = (0, _reactNativeReanimated.interpolate)(slot.progress.value, [0, 1], [entryFromY, 0]);
196
+ const stackOffsetY = isBottom ? slot.stackIndex.value * _constants.STACK_OFFSET_PER_ITEM : slot.stackIndex.value * -_constants.STACK_OFFSET_PER_ITEM;
197
+ const stackScale = 1 - slot.stackIndex.value * _constants.STACK_SCALE_PER_ITEM;
198
+ const finalTranslateY = baseTranslateY + slot.translationY.value + stackOffsetY;
199
+ const progressOpacity = (0, _reactNativeReanimated.interpolate)(slot.progress.value, [0, 1], [0, 1]);
200
+ const dismissDirection = isBottom ? slot.translationY.value : -slot.translationY.value;
201
+ const dragOpacity = dismissDirection > 0 ? (0, _reactNativeReanimated.interpolate)(dismissDirection, [0, 130], [1, 0], "clamp") : 1;
202
+ const opacity = progressOpacity * dragOpacity;
203
+ const dragScale = (0, _reactNativeReanimated.interpolate)(Math.abs(slot.translationY.value), [0, 50], [1, 0.98], "clamp");
204
+ const scale = stackScale * dragScale;
205
+ return {
206
+ transform: [{
207
+ translateY: finalTranslateY
208
+ }, {
209
+ scale
210
+ }],
211
+ opacity,
212
+ zIndex: 1000 - Math.round(slot.stackIndex.value)
213
+ };
214
+ });
215
+ const {
216
+ options
217
+ } = toast;
218
+ const colors = theme.colors[toast.type];
219
+ if (options?.customContent !== undefined) {
220
+ const content = options.customContent;
221
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
222
+ style: [styles.toast, styles.customContentToast, isBottom ? styles.toastBottom : styles.toastTop, {
223
+ backgroundColor: colors.background
224
+ }, theme.toastStyle, options.style, animatedStyle],
225
+ children: typeof content === "function" ? content({
226
+ id: toast.id,
227
+ dismiss: dismissToast,
228
+ type: toast.type,
229
+ isExiting: !!toast.isExiting
230
+ }) : content
231
+ });
232
+ }
233
+ const shouldShowCloseButton = toast.type !== "loading" && (options?.showCloseButton ?? theme.showCloseButton);
234
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNativeReanimated.default.View, {
235
+ style: [styles.toast, isBottom ? styles.toastBottom : styles.toastTop, {
236
+ backgroundColor: colors.background
237
+ }, theme.rtl && styles.rtl, theme.toastStyle, options?.style, animatedStyle],
238
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
239
+ style: styles.iconContainer,
240
+ children: showIcon && (shouldAnimateIcon ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_toastIcons.AnimatedIcon, {
241
+ type: toast.type,
242
+ color: colors.accent,
243
+ custom: options?.icon,
244
+ config: theme.icons[toast.type]
245
+ }, toast.type) : (0, _toastIcons.resolveIcon)(toast.type, colors.accent, options?.icon, theme.icons[toast.type]))
246
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
247
+ style: styles.textContainer,
248
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
249
+ maxFontSizeMultiplier: 1.35,
250
+ allowFontScaling: false,
251
+ style: [styles.title, {
252
+ color: colors.accent
253
+ }, theme.rtl && {
254
+ textAlign: "right"
255
+ }, theme.titleStyle, options?.titleStyle],
256
+ children: toast.title
257
+ }), toast.description && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
258
+ allowFontScaling: false,
259
+ maxFontSizeMultiplier: 1.35,
260
+ style: [styles.description, theme.rtl && {
261
+ textAlign: "right"
262
+ }, theme.descriptionStyle, options?.descriptionStyle],
263
+ children: toast.description
264
+ })]
265
+ }), shouldShowCloseButton && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
266
+ style: styles.closeButton,
267
+ onPress: dismissToast,
268
+ hitSlop: 12,
269
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.CloseIcon, {
270
+ width: 20,
271
+ height: 20
272
+ })
273
+ })]
274
+ });
275
+ };
276
+ const MemoizedToastItem = /*#__PURE__*/(0, _react.memo)(ToastItem, (prev, next) => {
277
+ return prev.toast.id === next.toast.id && prev.toast.type === next.toast.type && prev.toast.title === next.toast.title && prev.toast.description === next.toast.description && prev.toast.isExiting === next.toast.isExiting && prev.index === next.index && prev.position === next.position && prev.theme === next.theme && prev.isTopToast === next.isTopToast;
278
+ });
279
+ const styles = _reactNative.StyleSheet.create({
280
+ container: {
281
+ position: "absolute",
282
+ left: 16,
283
+ right: 16,
284
+ zIndex: 1000
285
+ },
286
+ toast: {
287
+ flexDirection: "row",
288
+ alignItems: "center",
289
+ gap: 12,
290
+ minHeight: 36,
291
+ borderRadius: 20,
292
+ borderCurve: "continuous",
293
+ position: "absolute",
294
+ left: 0,
295
+ right: 0,
296
+ paddingHorizontal: 12,
297
+ paddingVertical: 10,
298
+ shadowColor: "#000",
299
+ shadowOffset: {
300
+ width: 0,
301
+ height: 8
302
+ },
303
+ shadowOpacity: 0.05,
304
+ shadowRadius: 24,
305
+ elevation: 8
306
+ },
307
+ customContentToast: {
308
+ padding: 0,
309
+ paddingHorizontal: 0,
310
+ paddingVertical: 0,
311
+ overflow: "hidden"
312
+ },
313
+ rtl: {
314
+ flexDirection: "row-reverse"
315
+ },
316
+ toastTop: {
317
+ top: 0
318
+ },
319
+ toastBottom: {
320
+ bottom: 0
321
+ },
322
+ iconContainer: {
323
+ width: 48,
324
+ height: 48,
325
+ alignItems: "center",
326
+ justifyContent: "center",
327
+ marginLeft: 8
328
+ },
329
+ textContainer: {
330
+ flex: 1,
331
+ gap: 1,
332
+ justifyContent: "center"
333
+ },
334
+ title: {
335
+ fontSize: 14,
336
+ fontWeight: "700",
337
+ lineHeight: 20
338
+ },
339
+ description: {
340
+ color: "#6B7280",
341
+ fontSize: 12,
342
+ fontWeight: "500",
343
+ lineHeight: 16
344
+ },
345
+ closeButton: {
346
+ padding: 4,
347
+ alignItems: "center",
348
+ justifyContent: "center"
349
+ }
350
+ });
351
+ //# sourceMappingURL=toast.js.map
@@ -1 +1,6 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ //# sourceMappingURL=types.js.map
@@ -1 +1,72 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.useToastState=void 0;var t=require("react"),e=require("react-native-reanimated"),s=require("./toast-store.js");exports.useToastState=()=>{const[i,o]=(0,t.useState)([]),[n,a]=(0,t.useState)(()=>s.toastStore.getTheme()),r=(0,t.useRef)((0,e.makeMutable)(null)),u=(0,t.useRef)((0,e.makeMutable)("bottom"===n.position)),l=(0,t.useRef)((0,e.makeMutable)(!0)),m="bottom"===n.position,b=i.find(t=>!t.isExiting),c=b?.options?.dismissible??n.dismissible;(0,t.useEffect)(()=>{const t=s.toastStore.getState().visibleToasts,e=s.toastStore.getTheme();o(t);const i=t.find(t=>!t.isExiting);u.current.value="bottom"===e.position,l.current.value=i?.options?.dismissible??e.dismissible;let n=null,r=null;const m=s.toastStore.subscribe(t=>{n=t.visibleToasts,null===r&&(r=requestAnimationFrame(()=>{const t=n??s.toastStore.getState().visibleToasts,e=s.toastStore.getTheme();n&&(o(n),n=null),r=null,a(t=>t===e?t:e);const i=t.find(t=>!t.isExiting);u.current.value="bottom"===e.position,l.current.value=i?.options?.dismissible??e.dismissible}))});return m},[]);const d=(0,t.useMemo)(()=>{const t=new Map;let e=0;for(const s of i)t.set(s.id,s.isExiting?-1:e),s.isExiting||e++;return[...i].reverse().map(e=>({toast:e,index:t.get(e.id)??0}))},[i]);return{visibleToasts:i,theme:n,toastsWithIndex:d,isBottom:m,isTopDismissible:c,topToastRef:r,isBottomRef:u,isDismissibleRef:l}};
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
@@ -1 +1,21 @@
1
- "use strict";import{Easing as t}from"react-native-reanimated";export const ICON_SIZE=28;export const POOL_SIZE=5;export const ENTRY_DURATION=400;export const EXIT_DURATION=350;export const STACK_TRANSITION_DURATION=300;export const SPRING_BACK_DURATION=650;export const ICON_ANIMATION_DURATION=350;export const ENTRY_OFFSET=80;export const EXIT_OFFSET=100;export const SWIPE_EXIT_OFFSET=200;export const MAX_DRAG_CLAMP=180;export const MAX_DRAG_RESISTANCE=60;export const DISMISS_THRESHOLD=40;export const DISMISS_VELOCITY_THRESHOLD=300;export const STACK_OFFSET_PER_ITEM=10;export const STACK_SCALE_PER_ITEM=.05;export const EASING=t.bezier(.25,.1,.25,1);
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";import i,{Path as t}from"react-native-svg";import{jsx as e}from"react/jsx-runtime";export const CloseIcon=o=>e(i,{viewBox:"0 0 24 24",width:24,height:24,fill:"none",...o,children:e(t,{fill:o.fill??"#8993A4",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"})});
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";import e,{Path as l}from"react-native-svg";import{jsx as i,jsxs as t}from"react/jsx-runtime";export const GreenCheck=a=>t(e,{viewBox:"0 0 30 31",width:30,height:31,fill:"none",...a,children:[i(l,{fill:a.fill??"#28B770",fillRule:"evenodd",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",clipRule:"evenodd"}),i(l,{fill:"#fff",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"})]});
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";import e,{Path as i}from"react-native-svg";import{jsx as l}from"react/jsx-runtime";export const InfoIcon=o=>l(e,{viewBox:"0 0 24 24",width:24,height:24,fill:"none",...o,children:l(i,{fill:o.fill??"#EDBE43",fillRule:"evenodd",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",clipRule:"evenodd"})});
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
@@ -1 +1,21 @@
1
- "use strict";import l,{Path as e}from"react-native-svg";import{jsx as i,jsxs as a}from"react/jsx-runtime";export const RedX=t=>a(l,{viewBox:"0 0 24 24",width:24,height:24,fill:"none",...t,children:[i(e,{fill:t.fill??"#F05964",fillRule:"evenodd",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",clipRule:"evenodd"}),i(e,{fill:"#fff",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"})]});
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";export{CloseIcon}from"./CloseIcon.js";export{GreenCheck}from"./GreenCheck.js";export{InfoIcon}from"./InfoIcon.js";export{RedX}from"./RedX.js";
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
@@ -1 +1,14 @@
1
- "use strict";export{CloseIcon,GreenCheck,InfoIcon,RedX}from"./icons/index.js";export{ToastContainer}from"./toast.js";export{toast}from"./toast-api.js";export{BreadLoaf}from"./toast-provider.js";export{toastStore}from"./toast-store.js";
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, ToastPortal } from "./toast-provider.js";
10
+
11
+ // Store (for advanced usage)
12
+ export { toastStore } from "./toast-store.js";
13
+ // Types
14
+ //# sourceMappingURL=index.js.map
@@ -1 +1,47 @@
1
- "use strict";import{makeMutable as t}from"react-native-reanimated";import{POOL_SIZE as e}from"./constants.js";export const animationPool=Array.from({length:e},()=>({progress:t(0),translationY:t(0),stackIndex:t(0)}));export const slotTrackers=Array.from({length:e},()=>({wasExiting:!1,prevIndex:0,initialized:!1}));const r=new Map,s=new Set;export const getSlotIndex=t=>{if(r.has(t))return r.get(t)??0;for(let o=0;o<e;o++)if(!s.has(o))return r.set(t,o),s.add(o),slotTrackers[o].initialized=!1,slotTrackers[o].wasExiting=!1,slotTrackers[o].prevIndex=0,o;return 0};export const releaseSlot=t=>{const e=r.get(t);void 0!==e&&(s.delete(e),r.delete(t),slotTrackers[e].initialized=!1,slotTrackers[e].wasExiting=!1,slotTrackers[e].prevIndex=0)};
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