frontend/components: introduce a dashed ghost button to the new entry
Pedro Lucas Porcellis porcellis@eletrotupi.com · 5 months ago
9671ed464961e554cd1fcbecdee8ef718000e49c Browse filesParents
b1af73dChanged files
3
Additions
+39
Deletions
-5
frontend/app/(tabs)/new/entry.tsx
1 1
import { useState, useEffect } from 'react';
2 2
import {
3 3
Link, router, useLocalSearchParams
4 4
} from 'expo-router';
5 5
25 25
export default function NewMoodEntry() {
26 26
const { user } = useAuth();
27 27
// TODO: transform this into a specific mood component
28 28
const { initialMood } = useLocalSearchParams();
29 29
30 +
const editComponents = () => {
31 +
console.log("Wants to open the components");
32 +
}
33 +
30 34
return (
31 35
<View>
32 36
<ScrollView
33 37
scrollEventThrottle={16}>
34 38
<View style={styles.container}>
51 55
type="text"
52 56
variant="darkGhost"
53 57
onChangeText={(val) => console.log(val)}
54 58
minRows={4}
55 59
maxRows={6}
56 -
placeholder="Escreva uma nota rápida sobre o seu dia..."
60 +
placeholder="Escreva uma nota rápida sobre o seu dia até o momento..."
57 61
/>
58 62
</Card>
59 63
60 64
<Section>
61 65
<SectionHeader title="Componentes do Humor" info="Editar" />
62 66
<Grid gap={4}>
63 67
<Card style={{height: 38}} />
64 68
<Card style={{height: 38}} />
65 69
</Grid>
70 +
71 +
<Button title="Adicionar Componentes"
72 +
onPress={editComponents}
73 +
textStyle={{ fontWeight: 500 }}
74 +
variant="dashed"
75 +
/>
66 76
</Section>
67 77
</View>
68 78
</ScrollView>
69 79
</View>
70 80
);
87 97
},
88 98
resumeCard: {
89 99
height: 361
90 100
}
91 101
});
frontend/components/ui/Button.tsx
1 1
import React from 'react';
2 2
import {
3 3
TouchableOpacity,
4 4
Text,
5 5
StyleSheet,
10 10
} from 'react-native';
11 11
import { useThemeColor } from '@/hooks/use-theme-color';
12 12
13 13
interface ButtonProps extends TouchableOpacityProps {
14 14
title: string;
15 -
variant?: 'primary' | 'secondary' | 'outline' | 'ghost';
15 +
variant?: 'primary' | 'secondary' | 'outline' | 'ghost' | 'dashed';
16 16
size?: 'small' | 'medium' | 'large';
17 17
loading?: boolean;
18 18
disabled?: boolean;
19 19
style?: ViewStyle;
20 20
textStyle?: TextStyle;
31 31
onPress,
32 32
...props
33 33
}) => {
34 34
const primaryColor = useThemeColor({}, 'tint');
35 35
const textColor = useThemeColor({}, 'text');
36 +
const textSecondaryColor = useThemeColor({}, 'textSecondary');
36 37
const backgroundColor = useThemeColor({}, 'background');
37 38
const borderColor = useThemeColor({}, 'border');
39 +
const borderDashedColor = useThemeColor({}, 'borderDashed');
38 40
39 41
const getBackgroundColor = () => {
40 42
if (disabled) return useThemeColor({ light: '#e5e5e5', dark: '#404040' }, 'background');
41 43
switch (variant) {
42 44
case 'primary':
43 45
return primaryColor;
44 46
case 'secondary':
45 47
return useThemeColor({ light: '#f3f4f6', dark: '#374151' }, 'background');
46 48
case 'outline':
47 49
case 'ghost':
50 +
case 'dashed':
48 51
return 'transparent';
49 52
default:
50 53
return primaryColor;
51 54
}
52 55
};
53 56
54 57
const getTextColor = () => {
55 58
if (disabled) return useThemeColor({}, 'text');
59 +
56 60
switch (variant) {
57 61
case 'primary':
58 62
case 'secondary':
59 63
case 'outline':
60 64
case 'ghost':
61 65
return textColor;
66 +
case 'dashed':
67 +
return textSecondaryColor;
62 68
default:
63 69
return '#fff';
64 70
}
65 71
};
66 72
67 73
const getBorderWidth = () => {
68 -
return variant === 'outline' ? 1 : 0;
74 +
if (variant === 'outline' || variant === 'dashed') {
75 +
return 1;
76 +
} else {
77 +
return 0;
78 +
}
69 79
};
70 80
71 81
const getBorderColor = () => {
72 -
if (variant === 'outline') {
73 -
return disabled ? borderColor : primaryColor;
82 +
if (variant === 'outline' || variant === 'dashed') {
83 +
if (disabled) {
84 +
return borderColor;
85 +
} else if (variant === 'dashed') {
86 +
return borderDashedColor;
87 +
} else {
88 +
return primaryColor;
89 +
}
74 90
}
91 +
75 92
return 'transparent';
76 93
};
94 +
95 +
const getBorderStyle = () => {
96 +
return variant === 'dashed' ? 'dashed' : 'solid';
97 +
}
77 98
78 99
const getHeight = () => {
79 100
switch (size) {
80 101
case 'small':
81 102
return 36;
107 128
styles.button,
108 129
{
109 130
backgroundColor: getBackgroundColor(),
110 131
borderWidth: getBorderWidth(),
111 132
borderColor: getBorderColor(),
133 +
borderStyle: getBorderStyle(),
112 134
height: getHeight(),
113 135
opacity: disabled || loading ? 0.6 : 1,
114 136
},
115 137
style,
116 138
]}
148 170
},
149 171
text: {
150 172
fontWeight: '600',
151 173
},
152 174
});
frontend/constants/theme.ts
1 1
/**
2 2
* Below are the colors that are used in the app. The colors are defined in the light and dark mode.
3 3
* There are many other ways to style your app. For example, [Nativewind](https://www.nativewind.dev/), [Tamagui](https://tamagui.dev/), [unistyles](https://reactnativeunistyles.vercel.app), etc.
4 4
*/
5 5
20 20
const TEXT_PLACEHOLDER = '#94A3B8';
21 21
22 22
// Borders & Accents
23 23
const BORDER_SUBTLE = '#f1f5f9';
24 24
const BORDER_SUBTLE_GRAY = '#E5E7EB';
25 +
const BORDER_SUBTLE_LIGHT_GRAY = '#CBD5E1';
25 26
const STATUS_ACTIVE_BG = 'rgba(19, 236, 91, 0.1)';
26 27
27 28
// Semantic Color Pills and stuff
28 29
const PILL_BLUE = '#dbeafe';
29 30
const PILL_INDIGO = '#e0e7ff';
42 43
textSecondary: TEXT_SECONDARY,
43 44
background: BACKGROUND_LIGHT,
44 45
surface: SURFACE_LIGHT,
45 46
tint: NEON_GREEN,
46 47
backgroundDarkGhost: BACKGROUND_DARK_GHOST,
48 +
borderDashed: BORDER_SUBTLE_LIGHT_GRAY,
47 49
48 50
// Interactive States
49 51
icon: TEXT_SECONDARY,
50 52
tabIconDefault: TEXT_SECONDARY,
51 53
tabIconSelected: NEON_GREEN,
187 189
serif: 'serif',
188 190
rounded: 'Inter',
189 191
mono: 'monospace',
190 192
},
191 193
});