@dropi/react-native-design-system 0.3.9 → 0.3.10

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.
@@ -22,6 +22,10 @@ const ToastProvider = ({
22
22
  const timeoutRef = (0, _react.useRef)(null);
23
23
  const animationRef = (0, _react.useRef)(null);
24
24
  const toastIdCounter = (0, _react.useRef)(0);
25
+ const isAnimatingRef = (0, _react.useRef)(false);
26
+ const processQueueRef = (0, _react.useRef)(null);
27
+ const animateInRef = (0, _react.useRef)(null);
28
+ const animateOutRef = (0, _react.useRef)(null);
25
29
 
26
30
  // Cleanup timers on unmount
27
31
  (0, _react.useEffect)(() => {
@@ -35,33 +39,31 @@ const ToastProvider = ({
35
39
  };
36
40
  }, []);
37
41
 
38
- // Animate in the toast
39
- const animateIn = (0, _react.useCallback)(() => {
40
- if (isAnimating) return;
41
- setIsAnimating(true);
42
- slideAnim.setValue(-200); // Reset to initial position
42
+ // Keep isAnimatingRef in sync
43
+ (0, _react.useEffect)(() => {
44
+ isAnimatingRef.current = isAnimating;
45
+ }, [isAnimating]);
43
46
 
44
- animationRef.current = _reactNative.Animated.sequence([_reactNative.Animated.timing(slideAnim, {
45
- toValue: _reactNative.Platform.OS === 'ios' ? 100 : 50 + _utils.statusBarHeight,
46
- duration: 300,
47
- useNativeDriver: true
48
- }), _reactNative.Animated.timing(slideAnim, {
49
- toValue: _reactNative.Platform.OS === 'ios' ? 80 : 30 + _utils.statusBarHeight,
50
- duration: 120,
51
- useNativeDriver: true
52
- })]);
53
- animationRef.current.start(({
54
- finished
55
- }) => {
56
- if (finished) {
57
- setIsAnimating(false);
58
- }
59
- });
60
- }, [slideAnim, isAnimating]);
47
+ // Process the next toast in the queue
48
+ const processQueue = (0, _react.useCallback)(() => {
49
+ setTimeout(() => {
50
+ setQueue(prevQueue => {
51
+ if (prevQueue.length === 0) return prevQueue;
52
+ const [nextToast, ...remainingQueue] = prevQueue;
53
+ setCurrentToast(nextToast);
54
+ return remainingQueue;
55
+ });
56
+ }, 0);
57
+ }, []);
58
+
59
+ // Keep processQueueRef updated
60
+ (0, _react.useEffect)(() => {
61
+ processQueueRef.current = processQueue;
62
+ }, [processQueue]);
61
63
 
62
- // Animate out the toast
64
+ // Animate out the toast - stable with useRef
63
65
  const animateOut = (0, _react.useCallback)(callback => {
64
- if (isAnimating && animationRef.current) {
66
+ if (animationRef.current) {
65
67
  animationRef.current.stop();
66
68
  }
67
69
  setIsAnimating(true);
@@ -75,7 +77,6 @@ const ToastProvider = ({
75
77
  }) => {
76
78
  if (finished) {
77
79
  setIsAnimating(false);
78
- // Defer state updates to avoid useInsertionEffect error
79
80
  requestAnimationFrame(() => {
80
81
  setCurrentToast(null);
81
82
  if (callback) {
@@ -84,22 +85,57 @@ const ToastProvider = ({
84
85
  });
85
86
  }
86
87
  });
87
- }, [slideAnim, isAnimating]);
88
+ }, [slideAnim]);
88
89
 
89
- // Process the next toast in the queue
90
- const processQueue = (0, _react.useCallback)(() => {
91
- // Use setTimeout to defer state update
92
- setTimeout(() => {
93
- setQueue(prevQueue => {
94
- if (prevQueue.length === 0) return prevQueue;
95
- const [nextToast, ...remainingQueue] = prevQueue;
96
- setCurrentToast(nextToast);
97
- return remainingQueue;
98
- });
99
- }, 0);
100
- }, []);
90
+ // Keep animateOutRef updated
91
+ (0, _react.useEffect)(() => {
92
+ animateOutRef.current = animateOut;
93
+ }, [animateOut]);
94
+
95
+ // Animate in the toast - stable with useRef
96
+ const animateIn = (0, _react.useCallback)(() => {
97
+ if (isAnimatingRef.current) return;
98
+ setIsAnimating(true);
99
+ slideAnim.setValue(-200);
100
+ animationRef.current = _reactNative.Animated.sequence([_reactNative.Animated.timing(slideAnim, {
101
+ toValue: _reactNative.Platform.OS === 'ios' ? 100 : 50 + _utils.statusBarHeight,
102
+ duration: 300,
103
+ useNativeDriver: true
104
+ }), _reactNative.Animated.timing(slideAnim, {
105
+ toValue: _reactNative.Platform.OS === 'ios' ? 80 : 30 + _utils.statusBarHeight,
106
+ duration: 120,
107
+ useNativeDriver: true
108
+ })]);
109
+ animationRef.current.start(({
110
+ finished
111
+ }) => {
112
+ if (finished) {
113
+ setIsAnimating(false);
114
+ }
115
+ });
116
+ }, [slideAnim]);
117
+
118
+ // Keep animateInRef updated
119
+ (0, _react.useEffect)(() => {
120
+ animateInRef.current = animateIn;
121
+ }, [animateIn]);
122
+
123
+ // Auto-process queue when currentToast is null and queue has items
124
+ (0, _react.useEffect)(() => {
125
+ if (!currentToast && !isAnimating && queue.length > 0) {
126
+ // Defer to avoid state update during render
127
+ setTimeout(() => {
128
+ setQueue(prevQueue => {
129
+ if (prevQueue.length === 0) return prevQueue;
130
+ const [nextToast, ...remainingQueue] = prevQueue;
131
+ setCurrentToast(nextToast);
132
+ return remainingQueue;
133
+ });
134
+ }, 0);
135
+ }
136
+ }, [currentToast, isAnimating, queue.length]);
101
137
 
102
- // Handle auto-dismiss
138
+ // Handle auto-dismiss - only depends on currentToast
103
139
  (0, _react.useEffect)(() => {
104
140
  if (!currentToast) return;
105
141
 
@@ -109,14 +145,14 @@ const ToastProvider = ({
109
145
  timeoutRef.current = null;
110
146
  }
111
147
 
112
- // Animate in
113
- animateIn();
148
+ // Animate in using ref
149
+ animateInRef.current?.();
114
150
 
115
151
  // Set auto-dismiss if duration > 0
116
152
  if (currentToast.duration && currentToast.duration > 0) {
117
153
  timeoutRef.current = setTimeout(() => {
118
- animateOut(() => {
119
- processQueue();
154
+ animateOutRef.current?.(() => {
155
+ processQueueRef.current?.();
120
156
  });
121
157
  }, currentToast.duration);
122
158
  }
@@ -126,7 +162,7 @@ const ToastProvider = ({
126
162
  timeoutRef.current = null;
127
163
  }
128
164
  };
129
- }, [currentToast, animateIn, animateOut, processQueue]);
165
+ }, [currentToast]); // Solo depende de currentToast para evitar bucle infinito
130
166
 
131
167
  // Handle manual close
132
168
  const handleClose = (0, _react.useCallback)(() => {
@@ -135,9 +171,9 @@ const ToastProvider = ({
135
171
  timeoutRef.current = null;
136
172
  }
137
173
  animateOut(() => {
138
- processQueue();
174
+ processQueueRef.current?.();
139
175
  });
140
- }, [animateOut, processQueue]);
176
+ }, [animateOut]);
141
177
 
142
178
  // Public API: showToast
143
179
  const showToast = (0, _react.useCallback)(params => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dropi/react-native-design-system",
3
- "version": "0.3.9",
3
+ "version": "0.3.10",
4
4
  "description": "A React Native package built from scratch",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",