@xetwa/design-system 1.0.17 → 1.0.18

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xetwa/design-system",
3
- "version": "1.0.17",
3
+ "version": "1.0.18",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -1,9 +1,12 @@
1
1
  import type { ReactNode } from 'react';
2
2
  import { View, Pressable } from 'react-native';
3
3
  import type { ViewStyle, DimensionValue } from 'react-native';
4
+ import Animated, { useAnimatedStyle, withTiming } from 'react-native-reanimated';
4
5
  import { theme } from '../../../styles/theme';
5
6
  import { useResponsive } from '../../../hooks/useResponsive';
6
7
 
8
+ const AnimatedPressable = Animated.createAnimatedComponent(Pressable);
9
+
7
10
  /**
8
11
  * Cartão base e fundacional do Design System.
9
12
  * Fornece a estrutura comum de bordas, fundos, sombras e estados interativos
@@ -112,12 +115,9 @@ export const BaseCard = ({
112
115
  }
113
116
  : getShadowStyle();
114
117
 
115
- // Consolidate card styles with responsive scaling
116
- const cardStyle: ViewStyle = {
117
- backgroundColor: activeBg,
118
+ // Consolidate static card styles with responsive scaling
119
+ const staticCardStyle: ViewStyle = {
118
120
  borderRadius: scale(borderRadius),
119
- borderWidth: borderWidth === 0 && !isSelected ? 0 : activeBorderWidth,
120
- borderColor: activeBorderColor,
121
121
  borderStyle,
122
122
  padding: padding !== undefined ? scale(padding) : undefined,
123
123
  paddingVertical: padding === undefined ? scale(paddingVertical) : undefined,
@@ -130,26 +130,35 @@ export const BaseCard = ({
130
130
  ...activeShadow,
131
131
  };
132
132
 
133
+ const animatedStyleProps = useAnimatedStyle(() => {
134
+ return {
135
+ backgroundColor: withTiming(activeBg, { duration: 250 }),
136
+ borderColor: withTiming(activeBorderColor, { duration: 250 }),
137
+ borderWidth: withTiming(borderWidth === 0 && !isSelected ? 0 : activeBorderWidth, { duration: 250 }),
138
+ };
139
+ }, [activeBg, activeBorderColor, activeBorderWidth, isSelected, borderWidth]);
140
+
133
141
  if (onPress) {
134
142
  return (
135
- <Pressable
143
+ <AnimatedPressable
136
144
  onPress={onPress}
137
145
  disabled={disabled}
138
- style={({ pressed }) => [
139
- cardStyle,
140
- pressed && !disabled && { opacity: 0.9 },
141
- ...(Array.isArray(style) ? style : [style].filter(Boolean) as ViewStyle[]),
146
+ style={(state) => [
147
+ staticCardStyle,
148
+ animatedStyleProps,
149
+ state.pressed && !disabled && { opacity: 0.9 },
150
+ ...(Array.isArray(style) ? style : [style].filter(Boolean) as any[]),
142
151
  ]}
143
152
  >
144
153
  {children}
145
- </Pressable>
154
+ </AnimatedPressable>
146
155
  );
147
156
  }
148
157
 
149
158
  return (
150
- <View style={[cardStyle, style]}>
159
+ <Animated.View style={[staticCardStyle, animatedStyleProps, style]}>
151
160
  {children}
152
- </View>
161
+ </Animated.View>
153
162
  );
154
163
  };
155
164
 
@@ -1,10 +1,13 @@
1
1
  import { View, StyleSheet, Pressable, Platform } from 'react-native';
2
2
  import type { ViewStyle } from 'react-native';
3
+ import Animated, { useAnimatedStyle, withTiming } from 'react-native-reanimated';
3
4
  import { theme } from '../../../styles/theme';
4
5
  import type { ReactNode } from 'react';
5
6
  import { useResponsive } from '../../../hooks/useResponsive';
6
7
  import { Typography } from '../../Typography/Typography';
7
8
 
9
+ const AnimatedPressable = Animated.createAnimatedComponent(Pressable);
10
+
8
11
  /**
9
12
  * Cartão genérico para selecionar opções simples, usado frequentemente em formulários de Onboarding.
10
13
  */
@@ -29,35 +32,49 @@ export const SelectionCard = ({
29
32
  }: SelectionCardProps) => {
30
33
  const { scale, scaleText } = useResponsive();
31
34
 
35
+ const containerAnimatedStyle = useAnimatedStyle(() => {
36
+ return {
37
+ backgroundColor: withTiming(selected ? theme.colors.primaryLight : theme.colors.white, { duration: 250 }),
38
+ borderColor: withTiming(selected ? theme.colors.primary : theme.colors.brown[100], { duration: 250 }),
39
+ };
40
+ }, [selected]);
41
+
42
+ const iconBoxAnimatedStyle = useAnimatedStyle(() => {
43
+ return {
44
+ backgroundColor: withTiming(selected ? theme.colors.primary : theme.colors.brown[50], { duration: 250 }),
45
+ };
46
+ }, [selected]);
47
+
32
48
  return (
33
- <Pressable
49
+ <AnimatedPressable
34
50
  style={[
35
51
  styles.container,
36
- selected ? styles.selectedContainer : styles.defaultContainer,
52
+ selected && styles.selectedShadow,
37
53
  {
38
54
  padding: scale(16),
39
55
  borderRadius: scale(16),
40
56
  },
57
+ containerAnimatedStyle,
41
58
  style,
42
59
  ]}
43
60
  onPress={onPress}
44
61
  >
45
62
  {iconNode && (
46
- <View style={[
63
+ <Animated.View style={[
47
64
  styles.iconBox,
48
- selected ? styles.selectedIconBox : styles.defaultIconBox,
49
65
  {
50
66
  width: scale(44),
51
67
  height: scale(44),
52
68
  borderRadius: scale(12),
53
69
  marginRight: scale(16),
54
- }
70
+ },
71
+ iconBoxAnimatedStyle
55
72
  ]}>
56
73
  {iconNode}
57
- </View>
74
+ </Animated.View>
58
75
  )}
59
76
  <Typography weight="bold" style={[styles.label, { fontSize: scaleText(16) }]}>{label}</Typography>
60
- </Pressable>
77
+ </AnimatedPressable>
61
78
  );
62
79
  };
63
80
 
@@ -72,12 +89,8 @@ const styles = StyleSheet.create({
72
89
  width: '100%',
73
90
  },
74
91
  defaultContainer: {
75
- borderColor: theme.colors.brown[100],
76
- backgroundColor: theme.colors.white,
77
92
  },
78
- selectedContainer: {
79
- borderColor: theme.colors.primary,
80
- backgroundColor: theme.colors.primaryLight,
93
+ selectedShadow: {
81
94
  ...Platform.select({
82
95
  web: { boxShadow: `0px 4px 0px rgba(242, 151, 75, 0.3)` },
83
96
  default: {
@@ -97,12 +110,6 @@ const styles = StyleSheet.create({
97
110
  justifyContent: 'center',
98
111
  marginRight: 16,
99
112
  },
100
- defaultIconBox: {
101
- backgroundColor: theme.colors.brown[50],
102
- },
103
- selectedIconBox: {
104
- backgroundColor: theme.colors.primary,
105
- },
106
113
  label: {
107
114
 
108
115
  fontSize: 16,