@xetwa/design-system 1.0.38 → 1.0.39
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
|
@@ -75,6 +75,19 @@ export const ActiveDark: Story = {
|
|
|
75
75
|
subtitle: 'Regatear, números, comida',
|
|
76
76
|
subtext: '• 3/5',
|
|
77
77
|
tagLabel: 'AULA MARCADA',
|
|
78
|
+
onSchedulePress: () => console.log('Agendar Aula'),
|
|
79
|
+
onReviewPress: () => console.log('Rever'),
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export const ExamMode: Story = {
|
|
84
|
+
args: {
|
|
85
|
+
status: 'active-dark',
|
|
86
|
+
title: 'No mercado de Dakar',
|
|
87
|
+
subtitle: 'Exame de módulo',
|
|
88
|
+
subtext: '• 3/5',
|
|
89
|
+
tagLabel: 'POR FAZER',
|
|
90
|
+
onExamPress: () => console.log('Fazer Exame'),
|
|
78
91
|
},
|
|
79
92
|
};
|
|
80
93
|
|
|
@@ -129,6 +142,16 @@ export const Grid: Story = {
|
|
|
129
142
|
subtitle="Conversação e prática"
|
|
130
143
|
subtext="• 4/4"
|
|
131
144
|
tagLabel="AULA MARCADA"
|
|
145
|
+
onSchedulePress={() => {}}
|
|
146
|
+
onReviewPress={() => {}}
|
|
147
|
+
/>
|
|
148
|
+
<ModuleCard
|
|
149
|
+
status="active-dark"
|
|
150
|
+
title="No mercado de Dakar"
|
|
151
|
+
subtitle="Exame de módulo"
|
|
152
|
+
subtext="• 3/5"
|
|
153
|
+
tagLabel="POR FAZER"
|
|
154
|
+
onExamPress={() => {}}
|
|
132
155
|
/>
|
|
133
156
|
</View>
|
|
134
157
|
),
|
|
@@ -4,7 +4,7 @@ import { theme } from '../../../styles/theme';
|
|
|
4
4
|
import { Tag } from '../../DataDisplay/Tag/Tag';
|
|
5
5
|
import { ProgressBar } from '../../DataDisplay/ProgressBar/ProgressBar';
|
|
6
6
|
import { Badge } from '../../DataDisplay/Badge/Badge';
|
|
7
|
-
import { Lock, Check, GraduationCap, RotateCcw, CalendarPlus } from 'lucide-react-native';
|
|
7
|
+
import { Lock, Check, GraduationCap, RotateCcw, CalendarPlus, PenTool } from 'lucide-react-native';
|
|
8
8
|
import { useResponsive } from '../../../hooks/useResponsive';
|
|
9
9
|
import { Typography } from '../../Typography/Typography';
|
|
10
10
|
import React, { useRef } from 'react';
|
|
@@ -16,7 +16,7 @@ export type ModuleCardStatus = 'active' | 'locked' | 'completed' | 'dark' | 'act
|
|
|
16
16
|
*
|
|
17
17
|
* Regras de Animação e Clique:
|
|
18
18
|
* - `active`: O cartão como um todo tem animação de escala e é clicável via `onPress`.
|
|
19
|
-
* - `active-dark`: O cartão é estático. Apenas os botões internos de "Agendar" (`onSchedulePress`) e "Rever" (`onReviewPress`) têm animação individual.
|
|
19
|
+
* - `active-dark`: O cartão é estático. Apenas os botões internos de "Agendar" (`onSchedulePress`), "Exame" (`onExamPress`) e "Rever" (`onReviewPress`) têm animação individual quando fornecidos.
|
|
20
20
|
* - `completed`: O cartão é estático. Apenas o ícone/botão superior direito de "Rever" (`onReviewPress`) tem animação individual.
|
|
21
21
|
* - `locked` / `dark`: O cartão não é interativo.
|
|
22
22
|
*/
|
|
@@ -47,6 +47,8 @@ export interface ModuleCardProps {
|
|
|
47
47
|
style?: ViewStyle | ViewStyle[];
|
|
48
48
|
/** Função de clique no botão de Agendar (modo active/dark). */
|
|
49
49
|
onSchedulePress?: () => void;
|
|
50
|
+
/** Função de clique no botão principal de Exame (modo active/dark). */
|
|
51
|
+
onExamPress?: () => void;
|
|
50
52
|
/** Função de clique no botão de Rever (modo completed/active/dark). */
|
|
51
53
|
onReviewPress?: () => void;
|
|
52
54
|
}
|
|
@@ -66,12 +68,14 @@ export const ModuleCard = ({
|
|
|
66
68
|
onPress,
|
|
67
69
|
style,
|
|
68
70
|
onSchedulePress,
|
|
71
|
+
onExamPress,
|
|
69
72
|
onReviewPress,
|
|
70
73
|
}: ModuleCardProps) => {
|
|
71
74
|
const { scale, scaleText, width } = useResponsive();
|
|
72
75
|
const isMobileScreen = width < 400;
|
|
73
76
|
|
|
74
77
|
const scheduleScale = useRef(new Animated.Value(1)).current;
|
|
78
|
+
const examScale = useRef(new Animated.Value(1)).current;
|
|
75
79
|
const reviewScale = useRef(new Animated.Value(1)).current;
|
|
76
80
|
const completedReviewScale = useRef(new Animated.Value(1)).current;
|
|
77
81
|
const scaleAnim = useRef(new Animated.Value(1)).current;
|
|
@@ -329,31 +333,52 @@ export const ModuleCard = ({
|
|
|
329
333
|
|
|
330
334
|
{status === 'active-dark' && (
|
|
331
335
|
<View style={styles.compactDarkFooter}>
|
|
332
|
-
<
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
336
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', gap: scale(8) }}>
|
|
337
|
+
{onSchedulePress && (
|
|
338
|
+
<Animated.View style={{ transform: [{ scale: scheduleScale }] }}>
|
|
339
|
+
<Pressable
|
|
340
|
+
onPress={onSchedulePress}
|
|
341
|
+
onPressIn={() => animateBtnIn(scheduleScale)}
|
|
342
|
+
onPressOut={() => animateBtnOut(scheduleScale)}
|
|
343
|
+
hitSlop={8}
|
|
344
|
+
style={{ flexDirection: 'row', alignItems: 'center', backgroundColor: theme.colors.primary, paddingHorizontal: scale(14), paddingVertical: scale(6), borderRadius: 100 }}
|
|
345
|
+
>
|
|
346
|
+
<CalendarPlus stroke={theme.colors.white} strokeWidth={2.5} size={scale(14)} />
|
|
347
|
+
<Typography variant="label" style={{ color: theme.colors.white, fontSize: scaleText(12), fontWeight: 'bold', marginLeft: scale(6) }}>Agendar Aula</Typography>
|
|
348
|
+
</Pressable>
|
|
349
|
+
</Animated.View>
|
|
350
|
+
)}
|
|
344
351
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
352
|
+
{onExamPress && (
|
|
353
|
+
<Animated.View style={{ transform: [{ scale: examScale }] }}>
|
|
354
|
+
<Pressable
|
|
355
|
+
onPress={onExamPress}
|
|
356
|
+
onPressIn={() => animateBtnIn(examScale)}
|
|
357
|
+
onPressOut={() => animateBtnOut(examScale)}
|
|
358
|
+
hitSlop={8}
|
|
359
|
+
style={{ flexDirection: 'row', alignItems: 'center', backgroundColor: theme.colors.primary, paddingHorizontal: scale(14), paddingVertical: scale(6), borderRadius: 100 }}
|
|
360
|
+
>
|
|
361
|
+
<PenTool stroke={theme.colors.white} strokeWidth={2.5} size={scale(14)} />
|
|
362
|
+
<Typography variant="label" style={{ color: theme.colors.white, fontSize: scaleText(12), fontWeight: 'bold', marginLeft: scale(6) }}>Fazer Exame</Typography>
|
|
363
|
+
</Pressable>
|
|
364
|
+
</Animated.View>
|
|
365
|
+
)}
|
|
366
|
+
</View>
|
|
367
|
+
|
|
368
|
+
{onReviewPress && (
|
|
369
|
+
<Animated.View style={{ transform: [{ scale: reviewScale }] }}>
|
|
370
|
+
<Pressable
|
|
371
|
+
style={styles.compactReviewBtn}
|
|
372
|
+
onPress={onReviewPress}
|
|
373
|
+
onPressIn={() => animateBtnIn(reviewScale)}
|
|
374
|
+
onPressOut={() => animateBtnOut(reviewScale)}
|
|
375
|
+
hitSlop={8}
|
|
376
|
+
>
|
|
377
|
+
<RotateCcw stroke={theme.colors.primary} strokeWidth={2.5} size={scale(16)} />
|
|
378
|
+
<Typography variant="label" style={[styles.reviewIconText, { color: theme.colors.primary, fontSize: scaleText(10), marginLeft: scale(4), marginTop: 0 }]}>REVER</Typography>
|
|
379
|
+
</Pressable>
|
|
380
|
+
</Animated.View>
|
|
381
|
+
)}
|
|
357
382
|
</View>
|
|
358
383
|
)}
|
|
359
384
|
|