ikualo-ui-kit-mobile 2.1.17 → 2.1.19
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/app.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import { Icon, Text } from 'react-native-paper';
|
|
2
2
|
import { getStylesDialog } from '../../../assets/styles/elements/dialog';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
View,
|
|
5
|
+
TouchableWithoutFeedback,
|
|
6
|
+
Modal,
|
|
7
|
+
Keyboard,
|
|
8
|
+
TouchableHighlight,
|
|
9
|
+
Animated,
|
|
10
|
+
BackHandler,
|
|
11
|
+
Platform,
|
|
12
|
+
InteractionManager,
|
|
13
|
+
} from 'react-native';
|
|
4
14
|
import { useEffect, useState, useRef } from 'react';
|
|
5
15
|
import useStore from '../../store';
|
|
6
16
|
import { IDialogDown } from '../../models';
|
|
@@ -8,7 +18,7 @@ import { IDialogDown } from '../../models';
|
|
|
8
18
|
// Sistema simple de prioridades global
|
|
9
19
|
class PriorityManager {
|
|
10
20
|
private static instance: PriorityManager;
|
|
11
|
-
private currentDialog: { id: string; priority: number; onDismiss
|
|
21
|
+
private currentDialog: { id: string; priority: number; onDismiss?: () => void } | null = null;
|
|
12
22
|
private readonly listeners: Set<() => void> = new Set();
|
|
13
23
|
|
|
14
24
|
static getInstance(): PriorityManager {
|
|
@@ -27,10 +37,10 @@ class PriorityManager {
|
|
|
27
37
|
this.listeners.forEach((listener) => listener());
|
|
28
38
|
}
|
|
29
39
|
|
|
30
|
-
showDialog(id: string, priority: number, onDismiss
|
|
40
|
+
showDialog(id: string, priority: number, onDismiss?: () => void) {
|
|
31
41
|
// Si hay un diálogo actual y el nuevo tiene mayor prioridad, cerrar el actual
|
|
32
42
|
if (this.currentDialog && priority > this.currentDialog.priority) {
|
|
33
|
-
this.currentDialog.onDismiss();
|
|
43
|
+
this.currentDialog.onDismiss?.();
|
|
34
44
|
this.currentDialog = null;
|
|
35
45
|
}
|
|
36
46
|
|
|
@@ -65,6 +75,7 @@ export const DialogDown = (props: IDialogDown & { priority?: 0 | 1 | 2 | 3 | 4 |
|
|
|
65
75
|
const { isVisible, title, children, onDismiss, image, showCloseButton = true, priority = 0, id } = props;
|
|
66
76
|
const slideAnim = useRef(new Animated.Value(0)).current;
|
|
67
77
|
const [currentDialog, setCurrentDialog] = useState<{ id: string; priority: number } | null>(null);
|
|
78
|
+
const [isAnimationReady, setIsAnimationReady] = useState(false);
|
|
68
79
|
const [dialogId] = useState(() => {
|
|
69
80
|
// Si se proporciona un id, usarlo. Si no, generar uno aleatorio
|
|
70
81
|
return id || Math.random().toString(36).substring(2, 11);
|
|
@@ -103,17 +114,32 @@ export const DialogDown = (props: IDialogDown & { priority?: 0 | 1 | 2 | 3 | 4 |
|
|
|
103
114
|
};
|
|
104
115
|
}, [dialogId]);
|
|
105
116
|
|
|
106
|
-
// Animación basada en si este diálogo es el actual
|
|
107
117
|
useEffect(() => {
|
|
108
118
|
const isCurrentDialog = currentDialog?.id === dialogId;
|
|
109
119
|
if (isCurrentDialog) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
120
|
+
setIsAnimationReady(false);
|
|
121
|
+
slideAnim.setValue(0);
|
|
122
|
+
const handle = InteractionManager.runAfterInteractions(() => {
|
|
123
|
+
requestAnimationFrame(() => {
|
|
124
|
+
requestAnimationFrame(() => {
|
|
125
|
+
if (currentDialog?.id === dialogId) {
|
|
126
|
+
setIsAnimationReady(true);
|
|
127
|
+
Animated.timing(slideAnim, {
|
|
128
|
+
toValue: 1,
|
|
129
|
+
duration: 300,
|
|
130
|
+
useNativeDriver: true,
|
|
131
|
+
}).start();
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
return () => {
|
|
138
|
+
handle.cancel();
|
|
139
|
+
};
|
|
115
140
|
} else {
|
|
116
141
|
slideAnim.setValue(0);
|
|
142
|
+
setIsAnimationReady(false);
|
|
117
143
|
}
|
|
118
144
|
}, [currentDialog, slideAnim, dialogId]);
|
|
119
145
|
|
|
@@ -129,16 +155,38 @@ export const DialogDown = (props: IDialogDown & { priority?: 0 | 1 | 2 | 3 | 4 |
|
|
|
129
155
|
};
|
|
130
156
|
}, []);
|
|
131
157
|
|
|
158
|
+
useEffect(() => {
|
|
159
|
+
if (Platform.OS === 'android' && !onDismiss && isVisible) {
|
|
160
|
+
const backHandler = BackHandler.addEventListener('hardwareBackPress', () => {
|
|
161
|
+
// Si no hay onDismiss, prevenir el cierre
|
|
162
|
+
return true;
|
|
163
|
+
});
|
|
164
|
+
return () => backHandler.remove();
|
|
165
|
+
}
|
|
166
|
+
}, [isVisible, onDismiss]);
|
|
167
|
+
|
|
132
168
|
const handleDismiss = () => {
|
|
133
169
|
priorityManager.current.hideDialog(dialogId);
|
|
134
|
-
onDismiss();
|
|
170
|
+
onDismiss?.();
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
const handleRequestClose = () => {
|
|
174
|
+
if (onDismiss) {
|
|
175
|
+
handleDismiss();
|
|
176
|
+
}
|
|
177
|
+
// Si no hay onDismiss, no hacer nada - previene el cierre
|
|
135
178
|
};
|
|
136
179
|
|
|
137
180
|
// Solo renderizar si este diálogo es el actual
|
|
138
181
|
const isCurrentDialog = Boolean(isVisible && currentDialog && currentDialog.id === dialogId);
|
|
139
182
|
|
|
140
183
|
return (
|
|
141
|
-
<Modal
|
|
184
|
+
<Modal
|
|
185
|
+
visible={isCurrentDialog}
|
|
186
|
+
transparent={true}
|
|
187
|
+
animationType="none"
|
|
188
|
+
onRequestClose={handleRequestClose}
|
|
189
|
+
>
|
|
142
190
|
<TouchableWithoutFeedback onPress={handleDismissKeyboard}>
|
|
143
191
|
<View style={stylesDialog.modalBackground}>
|
|
144
192
|
<Animated.View
|
|
@@ -154,6 +202,7 @@ export const DialogDown = (props: IDialogDown & { priority?: 0 | 1 | 2 | 3 | 4 |
|
|
|
154
202
|
}),
|
|
155
203
|
},
|
|
156
204
|
],
|
|
205
|
+
opacity: isAnimationReady ? 1 : 0,
|
|
157
206
|
},
|
|
158
207
|
]}
|
|
159
208
|
>
|
|
@@ -64,8 +64,19 @@ export const DialogExamples = () => {
|
|
|
64
64
|
setIsVisible2(true);
|
|
65
65
|
}}
|
|
66
66
|
/>
|
|
67
|
-
<DialogDown
|
|
67
|
+
<DialogDown
|
|
68
|
+
isVisible={isVisible2}
|
|
69
|
+
showCloseButton={false}
|
|
70
|
+
title="Titulo de prueba"
|
|
71
|
+
//onDismiss={() => setIsVisible2(false)}
|
|
72
|
+
>
|
|
68
73
|
<Text>Texto de prueba</Text>
|
|
74
|
+
<BtnContained
|
|
75
|
+
text="Aceptar"
|
|
76
|
+
onPress={() => {
|
|
77
|
+
setIsVisible2(false);
|
|
78
|
+
}}
|
|
79
|
+
/>
|
|
69
80
|
</DialogDown>
|
|
70
81
|
<BtnContained
|
|
71
82
|
text="Modal bajo animacion"
|