cdslibrary 1.2.84 → 1.2.86
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.
|
@@ -73,17 +73,24 @@ const bottomSheetRender = ({
|
|
|
73
73
|
|
|
74
74
|
useEffect(() => {
|
|
75
75
|
if (isVisible) {
|
|
76
|
+
// Animación de Entrada
|
|
76
77
|
translation.value = withTiming(0, {
|
|
77
78
|
duration: 300,
|
|
78
79
|
easing: Easing.out(Easing.exp),
|
|
79
80
|
});
|
|
80
81
|
opacity.value = withTiming(1, { duration: 200 });
|
|
82
|
+
} else {
|
|
83
|
+
// Animación de Salida (ESTO ES LO QUE FALTABA)
|
|
84
|
+
translation.value = withTiming(startPos, { duration: 300 });
|
|
85
|
+
opacity.value = withTiming(0, { duration: 300 });
|
|
81
86
|
}
|
|
82
|
-
}, [isVisible]);
|
|
87
|
+
}, [isVisible, startPos]); // Asegúrate de incluir startPos
|
|
83
88
|
|
|
84
|
-
|
|
89
|
+
const animatedStyle = useAnimatedStyle(() => {
|
|
85
90
|
return {
|
|
86
91
|
opacity: opacity.value,
|
|
92
|
+
// Ocultamos el layout completamente si terminó de salir
|
|
93
|
+
display: (translation.value >= startPos && !isVisible) ? 'none' : 'flex',
|
|
87
94
|
transform: [
|
|
88
95
|
isMobile
|
|
89
96
|
? { translateY: translation.value }
|
|
@@ -94,15 +101,24 @@ const bottomSheetRender = ({
|
|
|
94
101
|
|
|
95
102
|
const backdropStyle = useAnimatedStyle(() => {
|
|
96
103
|
const currentY = translation.value;
|
|
97
|
-
|
|
104
|
+
// Si está en la posición inicial (startPos), la opacidad es 0
|
|
105
|
+
const opacityVal = interpolate(
|
|
106
|
+
currentY,
|
|
107
|
+
[0, startPos],
|
|
108
|
+
[1, 0],
|
|
109
|
+
Extrapolation.CLAMP
|
|
110
|
+
);
|
|
111
|
+
|
|
98
112
|
return {
|
|
99
113
|
opacity: opacityVal,
|
|
114
|
+
display: opacityVal <= 0 ? 'none' : 'flex',
|
|
100
115
|
};
|
|
101
116
|
});
|
|
102
117
|
|
|
103
118
|
return (
|
|
104
119
|
<>
|
|
105
120
|
<Animated.View
|
|
121
|
+
pointerEvents={isVisible ? "auto" : "none"} // Evita clics fantasma
|
|
106
122
|
style={[
|
|
107
123
|
styles.overlay,
|
|
108
124
|
{ backgroundColor: theme.surface.special.overlay },
|
|
@@ -111,7 +127,6 @@ const bottomSheetRender = ({
|
|
|
111
127
|
>
|
|
112
128
|
<Pressable onPress={() => runOnJS(handleClose)()} style={{ flex: 1 }} />
|
|
113
129
|
</Animated.View>
|
|
114
|
-
|
|
115
130
|
<Animated.View
|
|
116
131
|
style={[
|
|
117
132
|
isMobile ? styles.container.typeBottomSheet : styles.container.typeDrawer,
|
|
@@ -213,17 +228,20 @@ const styles = StyleSheet.create({
|
|
|
213
228
|
left: 0,
|
|
214
229
|
right: 0,
|
|
215
230
|
zIndex: 99,
|
|
216
|
-
...Platform.select({web:{maxHeight: '95%'}})
|
|
231
|
+
...Platform.select({ web: { maxHeight: '95%' } })
|
|
217
232
|
},
|
|
218
233
|
typeDrawer: {
|
|
219
234
|
position: "absolute",
|
|
220
235
|
right: 0,
|
|
221
|
-
top: 0,
|
|
222
236
|
bottom: 0,
|
|
223
237
|
width: 600,
|
|
238
|
+
maxHeight: height * .95, // Evita que se salga de la pantalla si hay mucho texto
|
|
224
239
|
zIndex: 99,
|
|
225
240
|
...Platform.select({
|
|
226
|
-
web: {
|
|
241
|
+
web: {
|
|
242
|
+
boxShadow: '-10px 0px 15px rgba(0,0,0,0.1)',
|
|
243
|
+
height: 'auto', // En web forzamos que sea auto
|
|
244
|
+
}
|
|
227
245
|
})
|
|
228
246
|
},
|
|
229
247
|
},
|
|
@@ -232,7 +250,7 @@ const styles = StyleSheet.create({
|
|
|
232
250
|
width: '100%',
|
|
233
251
|
},
|
|
234
252
|
scrollArea: {
|
|
235
|
-
width: '100%',
|
|
253
|
+
width: '100%',
|
|
236
254
|
},
|
|
237
255
|
scrollContent: {
|
|
238
256
|
gap: 16,
|
|
@@ -80,6 +80,7 @@ const animatedLayout = {
|
|
|
80
80
|
backgroundColor: currentStyle.bg,
|
|
81
81
|
borderColor: currentStyle.border,
|
|
82
82
|
borderRadius: theme.radius.md,
|
|
83
|
+
borderWidth: 1,
|
|
83
84
|
paddingHorizontal: theme.space.md,
|
|
84
85
|
gap: theme.space.sm,
|
|
85
86
|
overflow: 'hidden', // Evita que el texto se salga mientras se achica
|
package/components/CDSInput.jsx
CHANGED
|
@@ -5,65 +5,84 @@ import Animated, {
|
|
|
5
5
|
useSharedValue,
|
|
6
6
|
withSequence,
|
|
7
7
|
withTiming,
|
|
8
|
+
withDelay,
|
|
8
9
|
interpolateColor
|
|
9
10
|
} from "react-native-reanimated";
|
|
10
11
|
import { useTheme } from "../context/CDSThemeContext";
|
|
11
12
|
|
|
13
|
+
const AnimatedTextInput = Animated.createAnimatedComponent(TextInput);
|
|
14
|
+
|
|
12
15
|
export const CDSInput = ({ label, type, keyboard, placeholder, value, onChangeText, animationTrigger, returnKeyType, onFocus }) => {
|
|
13
16
|
const { theme } = useTheme();
|
|
14
17
|
const [isFocused, setIsFocused] = useState(false);
|
|
15
18
|
|
|
16
19
|
const flashValue = useSharedValue(0);
|
|
20
|
+
const textHighlight = useSharedValue(0);
|
|
17
21
|
const isInternalChange = useRef(false);
|
|
18
22
|
|
|
23
|
+
const isReadOnly = type === 'readOnly';
|
|
24
|
+
|
|
25
|
+
// --- Colores de seguridad ---
|
|
26
|
+
const colorBase = theme?.text?.neutral?.primary
|
|
27
|
+
const colorReadOnlyText = theme?.text?.neutral?.secondary
|
|
28
|
+
const colorFocus = theme?.surface?.special?.progress
|
|
29
|
+
const colorTertiary = theme?.outline?.neutral?.tertiaryVariant
|
|
30
|
+
const colorPrimaryOutline = theme?.outline?.neutral?.primary
|
|
31
|
+
|
|
19
32
|
useEffect(() => {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
33
|
+
// ELIMINAMOS la restricción de !isReadOnly para que se anime siempre
|
|
34
|
+
if (!isInternalChange.current && value) {
|
|
35
|
+
flashValue.value = withDelay(400, withSequence(
|
|
36
|
+
withTiming(1, { duration: 400 }),
|
|
37
|
+
withTiming(0, { duration: 600 })
|
|
38
|
+
));
|
|
39
|
+
|
|
40
|
+
textHighlight.value = withSequence(
|
|
41
|
+
withTiming(1, { duration: 400 }),
|
|
23
42
|
withTiming(0, { duration: 600 })
|
|
24
43
|
);
|
|
25
44
|
}
|
|
26
45
|
isInternalChange.current = false;
|
|
27
|
-
}, [value, animationTrigger]);
|
|
28
|
-
|
|
29
|
-
const handleTextChange = (inputText) => {
|
|
30
|
-
isInternalChange.current = true;
|
|
31
|
-
|
|
32
|
-
if (keyboard === "numeric" || keyboard === "decimal-pad") {
|
|
33
|
-
let cleaned = inputText.replace(',', '.').replace(/[^0-9.]/g, "");
|
|
34
|
-
const parts = cleaned.split('.');
|
|
35
|
-
if (parts.length > 2) cleaned = parts[0] + '.' + parts.slice(1).join('');
|
|
36
|
-
onChangeText && onChangeText(cleaned);
|
|
37
|
-
} else {
|
|
38
|
-
onChangeText && onChangeText(inputText);
|
|
39
|
-
}
|
|
40
|
-
};
|
|
46
|
+
}, [value, animationTrigger]); // Quitamos isReadOnly de las dependencias para evitar disparos extra
|
|
41
47
|
|
|
42
48
|
const animatedBoxStyle = useAnimatedStyle(() => {
|
|
43
49
|
const borderColor = interpolateColor(
|
|
44
50
|
flashValue.value,
|
|
45
51
|
[0, 1],
|
|
46
52
|
[
|
|
47
|
-
isFocused ?
|
|
48
|
-
|
|
53
|
+
isFocused ? colorFocus : value ? colorTertiary : colorPrimaryOutline,
|
|
54
|
+
colorFocus
|
|
49
55
|
]
|
|
50
56
|
);
|
|
51
57
|
|
|
52
58
|
return {
|
|
53
|
-
borderColor
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
borderWidth: 1 + (flashValue.value * 1),
|
|
59
|
+
borderColor,
|
|
60
|
+
borderWidth: 1 + (flashValue.value * 2),
|
|
61
|
+
transform: [{ scale: 1 + (flashValue.value * 0.06) }]
|
|
57
62
|
};
|
|
58
63
|
});
|
|
59
64
|
|
|
65
|
+
const animatedTextStyle = useAnimatedStyle(() => {
|
|
66
|
+
// Definimos el color inicial según si es readOnly o no
|
|
67
|
+
const startColor = isReadOnly ? colorReadOnlyText : colorBase;
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
color: interpolateColor(
|
|
71
|
+
textHighlight.value,
|
|
72
|
+
[0, 1],
|
|
73
|
+
[startColor, colorFocus] // El color de "brillo" sigue siendo el de foco
|
|
74
|
+
),
|
|
75
|
+
letterSpacing: textHighlight.value * 1,
|
|
76
|
+
opacity: isReadOnly ? 0.85 + (textHighlight.value * 0.3) : 0.8 + (textHighlight.value * 0.2),
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
if (!theme) return null;
|
|
81
|
+
|
|
60
82
|
return (
|
|
61
83
|
<View style={styles.container}>
|
|
62
84
|
{label && (
|
|
63
|
-
<Text style={[
|
|
64
|
-
theme.typography.label,
|
|
65
|
-
{ color: theme.text.neutral.primary, marginBottom: theme.space.xs }
|
|
66
|
-
]}>
|
|
85
|
+
<Text style={[theme.typography.label, { color: colorBase, marginBottom: theme.space?.xs || 4 }]}>
|
|
67
86
|
{label}
|
|
68
87
|
</Text>
|
|
69
88
|
)}
|
|
@@ -72,35 +91,34 @@ export const CDSInput = ({ label, type, keyboard, placeholder, value, onChangeTe
|
|
|
72
91
|
styles.wrapper,
|
|
73
92
|
animatedBoxStyle,
|
|
74
93
|
{
|
|
75
|
-
backgroundColor:
|
|
76
|
-
borderRadius: theme.radius
|
|
94
|
+
backgroundColor: isReadOnly ? theme.surface.neutral.primaryVariant : theme.surface.neutral.primary,
|
|
95
|
+
borderRadius: theme.radius?.sm || 8,
|
|
77
96
|
}
|
|
78
97
|
]}>
|
|
79
|
-
<
|
|
98
|
+
<AnimatedTextInput
|
|
80
99
|
style={[
|
|
81
100
|
styles.textBox,
|
|
82
|
-
theme.typography.inputText
|
|
101
|
+
theme.typography.inputText?.value,
|
|
102
|
+
animatedTextStyle,
|
|
83
103
|
{
|
|
84
|
-
paddingHorizontal: theme.space
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
...Platform.select({
|
|
88
|
-
web: { outlineStyle: 'none' }
|
|
89
|
-
})
|
|
104
|
+
paddingHorizontal: theme.space?.sm || 12,
|
|
105
|
+
fontWeight: '600',
|
|
106
|
+
...Platform.select({ web: { outlineStyle: 'none' } })
|
|
90
107
|
},
|
|
91
108
|
]}
|
|
92
109
|
placeholder={placeholder}
|
|
93
110
|
placeholderTextColor={theme.text.neutral.placeholder}
|
|
94
|
-
keyboardType={keyboard
|
|
95
|
-
onChangeText={
|
|
111
|
+
keyboardType={keyboard}
|
|
112
|
+
onChangeText={(txt) => {
|
|
113
|
+
isInternalChange.current = true;
|
|
114
|
+
onChangeText && onChangeText(txt);
|
|
115
|
+
}}
|
|
96
116
|
value={value}
|
|
97
|
-
editable={
|
|
117
|
+
editable={!isReadOnly}
|
|
98
118
|
secureTextEntry={type === "password"}
|
|
99
|
-
onFocus={() => { setIsFocused(true); onFocus }}
|
|
119
|
+
onFocus={() => { setIsFocused(true); onFocus && onFocus(); }}
|
|
100
120
|
onBlur={() => setIsFocused(false)}
|
|
101
121
|
underlineColorAndroid="transparent"
|
|
102
|
-
returnKeyType={returnKeyType}
|
|
103
|
-
dataSet={{ lpignore: "true" }}
|
|
104
122
|
/>
|
|
105
123
|
</Animated.View>
|
|
106
124
|
</View>
|
|
@@ -108,20 +126,14 @@ export const CDSInput = ({ label, type, keyboard, placeholder, value, onChangeTe
|
|
|
108
126
|
};
|
|
109
127
|
|
|
110
128
|
const styles = StyleSheet.create({
|
|
111
|
-
container: {
|
|
112
|
-
width: "100%",
|
|
113
|
-
alignSelf: 'stretch',
|
|
114
|
-
},
|
|
129
|
+
container: { width: "100%", alignSelf: 'stretch' },
|
|
115
130
|
wrapper: {
|
|
116
131
|
width: '100%',
|
|
117
132
|
height: 48,
|
|
118
|
-
flexDirection: 'row',
|
|
133
|
+
flexDirection: 'row',
|
|
119
134
|
alignItems: 'center',
|
|
120
135
|
borderWidth: 1,
|
|
136
|
+
overflow: 'hidden'
|
|
121
137
|
},
|
|
122
|
-
textBox: {
|
|
123
|
-
flex: 1, // Esto es lo más importante: ocupa todo el espacio sobrante
|
|
124
|
-
height: '100%',
|
|
125
|
-
width: '100%',
|
|
126
|
-
},
|
|
138
|
+
textBox: { flex: 1, height: '100%', width: '100%' },
|
|
127
139
|
});
|
package/components/CDSSwitch.jsx
CHANGED
|
@@ -9,7 +9,7 @@ export const CDSSwitch = ({ label, onValueChange, value }) => {
|
|
|
9
9
|
<View style={[styles.container, { }]}>
|
|
10
10
|
{label && (
|
|
11
11
|
<Text style={[
|
|
12
|
-
theme.typography.
|
|
12
|
+
theme.typography.regular.md,
|
|
13
13
|
{ color: theme.text.neutral.primary, flex: 1, marginRight: theme.space.md }
|
|
14
14
|
]}>
|
|
15
15
|
{label}
|