@xetwa/design-system 1.0.43 → 1.0.46

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.43",
3
+ "version": "1.0.46",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -0,0 +1,103 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { View } from 'react-native';
3
+ import { Chip } from './Chip';
4
+ import { theme } from '../../../styles/theme';
5
+
6
+ const meta = {
7
+ title: 'Components/Buttons/Chip',
8
+ component: Chip,
9
+ parameters: {
10
+ layout: 'centered',
11
+ docs: {
12
+ description: {
13
+ component: `O **Chip** é um elemento compacto utilizado para entrada de dados (filtros), atributos ou ações simples. É amplamente utilizado na "Wallet" para filtrar o histórico de transações.
14
+
15
+ ### Tipografia e Cores
16
+ - **Fonte:** Utiliza rigorosamente a \`Nunito-Black\` (peso 900) para garantir leitura forte.
17
+ - **Borda:** Por defeito herda a espessura de \`2.5\` e a cor standard do Design System para cartões (\`theme.colors.brown[100]\`), mas ambas podem ser sobrescritas por props.
18
+
19
+ ### Exemplo de Código (Filtros de Wallet)
20
+ \`\`\`tsx
21
+ import { Chip, theme } from '@xetwa/design-system';
22
+ import { View } from 'react-native';
23
+
24
+ export const FilterRow = () => {
25
+ return (
26
+ <View style={{ flexDirection: 'row', gap: 8 }}>
27
+ {/* Chip Ativo / Selecionado */}
28
+ <Chip
29
+ label="Tudo"
30
+ backgroundColor={theme.colors.brown[800]}
31
+ textColor={theme.colors.white}
32
+ borderColor={theme.colors.brown[800]} // Esconde a borda fundindo-a com o fundo
33
+ />
34
+
35
+ {/* Chips Inativos (Usam os defaults: Fundo branco, borda brown[100]) */}
36
+ <Chip label="Ganhas" />
37
+ <Chip label="Gastas" />
38
+ <Chip label="Compras" />
39
+ </View>
40
+ );
41
+ };
42
+ \`\`\`
43
+ `,
44
+ },
45
+ },
46
+ },
47
+ decorators: [
48
+ (Story) => (
49
+ <View style={{ padding: 20, backgroundColor: theme.colors.brown[50], flexDirection: 'row', gap: 8, flexWrap: 'wrap' }}>
50
+ <Story />
51
+ </View>
52
+ ),
53
+ ],
54
+ tags: ['autodocs'],
55
+ } satisfies Meta<typeof Chip>;
56
+
57
+ export default meta;
58
+ type Story = StoryObj<typeof meta>;
59
+
60
+ export const Default: Story = {
61
+ args: {
62
+ label: 'Ganhas',
63
+ size: 'md',
64
+ },
65
+ };
66
+
67
+ export const Active: Story = {
68
+ args: {
69
+ label: 'Tudo',
70
+ size: 'md',
71
+ backgroundColor: theme.colors.brown[800],
72
+ textColor: theme.colors.white,
73
+ borderColor: theme.colors.brown[800],
74
+ borderWidth: 2.5,
75
+ },
76
+ };
77
+
78
+ export const Sizes: Story = {
79
+ render: () => (
80
+ <View style={{ flexDirection: 'row', gap: 8, alignItems: 'center' }}>
81
+ <Chip label="Small" size="sm" />
82
+ <Chip label="Medium" size="md" />
83
+ <Chip label="Large" size="lg" />
84
+ </View>
85
+ ),
86
+ };
87
+
88
+ export const WalletExample: Story = {
89
+ render: () => (
90
+ <View style={{ flexDirection: 'row', gap: 8, alignItems: 'center' }}>
91
+ <Chip
92
+ label="Tudo"
93
+ size="md"
94
+ backgroundColor={theme.colors.brown[800]}
95
+ textColor={theme.colors.white}
96
+ borderColor={theme.colors.brown[800]}
97
+ />
98
+ <Chip label="Ganhas" size="md" />
99
+ <Chip label="Gastas" size="md" />
100
+ <Chip label="Compras" size="md" />
101
+ </View>
102
+ ),
103
+ };
@@ -0,0 +1,95 @@
1
+ import React from 'react';
2
+ import { Pressable, StyleSheet } from 'react-native';
3
+ import type { ViewStyle } from 'react-native';
4
+ import { Typography } from '../../Typography/Typography';
5
+ import { useResponsive } from '../../../hooks/useResponsive';
6
+ import { theme } from '../../../styles/theme';
7
+
8
+ export interface ChipProps {
9
+ /** Texto a ser exibido no chip */
10
+ label: string;
11
+ /** Função a executar ao pressionar */
12
+ onPress?: () => void;
13
+ /** Tamanho do chip (afeta paddings e fonte) */
14
+ size?: 'sm' | 'md' | 'lg';
15
+ /** Cor de fundo customizada */
16
+ backgroundColor?: string;
17
+ /** Cor do texto customizada */
18
+ textColor?: string;
19
+ /** Cor da borda customizada */
20
+ borderColor?: string;
21
+ /** Espessura da borda. Default: 2.5 */
22
+ borderWidth?: number;
23
+ /** Estilos adicionais do contentor */
24
+ style?: ViewStyle | ViewStyle[];
25
+ }
26
+
27
+ /**
28
+ * Componente Chip para seleção de filtros ou categorias.
29
+ * Permite costumizar cores e tamanhos via props.
30
+ */
31
+ export const Chip = ({
32
+ label,
33
+ onPress,
34
+ size = 'md',
35
+ backgroundColor = theme.colors.white,
36
+ textColor = theme.colors.brown[500],
37
+ borderColor = theme.colors.brown[100],
38
+ borderWidth = 2.5,
39
+ style,
40
+ }: ChipProps) => {
41
+ const { scale } = useResponsive();
42
+
43
+ const sizeStyles = {
44
+ sm: {
45
+ paddingVertical: scale(6),
46
+ paddingHorizontal: scale(12),
47
+ borderRadius: 999,
48
+ },
49
+ md: {
50
+ paddingVertical: scale(8),
51
+ paddingHorizontal: scale(16),
52
+ borderRadius: 999,
53
+ },
54
+ lg: {
55
+ paddingVertical: scale(12),
56
+ paddingHorizontal: scale(24),
57
+ borderRadius: 999,
58
+ },
59
+ }[size];
60
+
61
+ const typographyVariant = {
62
+ sm: 'smallHeavy',
63
+ md: 'bodySmHeavy',
64
+ lg: 'bodyMdHeavy',
65
+ }[size] as 'smallHeavy' | 'bodySmHeavy' | 'bodyMdHeavy';
66
+
67
+ return (
68
+ <Pressable
69
+ onPress={onPress}
70
+ style={({ pressed }) => [
71
+ styles.container,
72
+ sizeStyles,
73
+ {
74
+ backgroundColor,
75
+ borderColor,
76
+ borderWidth,
77
+ opacity: pressed ? 0.7 : 1,
78
+ },
79
+ style,
80
+ ]}
81
+ >
82
+ <Typography variant={typographyVariant} color={textColor} style={{ textAlign: 'center' }}>
83
+ {label}
84
+ </Typography>
85
+ </Pressable>
86
+ );
87
+ };
88
+
89
+ const styles = StyleSheet.create({
90
+ container: {
91
+ alignItems: 'center',
92
+ justifyContent: 'center',
93
+ flexDirection: 'row',
94
+ },
95
+ });
@@ -1,11 +1,10 @@
1
- import React from 'react';
2
- import { View, StyleSheet, Platform } from 'react-native';
3
1
  import type { ViewStyle } from 'react-native';
4
- import { Typography } from '../../Typography/Typography';
2
+ import { Platform, StyleSheet, View } from 'react-native';
3
+ import { useResponsive } from '../../../hooks/useResponsive';
4
+ import { theme } from '../../../styles/theme';
5
5
  import { Flag } from '../../DataDisplay/Flag/Flag';
6
6
  import { ProgressBar } from '../../DataDisplay/ProgressBar/ProgressBar';
7
- import { theme } from '../../../styles/theme';
8
- import { useResponsive } from '../../../hooks/useResponsive';
7
+ import { Typography } from '../../Typography/Typography';
9
8
 
10
9
  /**
11
10
  * Propriedades para o componente RouteHeader.
@@ -107,37 +106,37 @@ export const RouteHeader = ({
107
106
  const segments = progressType === 'segmented' ? Math.max(1, totalSegments) : 1;
108
107
 
109
108
  return (
110
- <View style={[styles.container, { paddingTop: safeAreaTop + scale(20), paddingHorizontal: scale(24), paddingBottom: scale(24) }, style]}>
109
+ <View style={[styles.container, { paddingTop: safeAreaTop + scale(12), paddingHorizontal: scale(20), paddingBottom: scale(20) }, style]}>
111
110
  {/* Top Row: Labels */}
112
- <View style={[styles.topRow, { marginBottom: scale(16) }]}>
113
- <Typography variant="bodySm" color={theme.colors.brown[500]} style={{ textTransform: 'uppercase', letterSpacing: 0.5 }}>
111
+ <View style={[styles.topRow, { marginBottom: scale(10) }]}>
112
+ <Typography variant="bodySmHeavy" color={theme.colors.brown[500]} style={{ textTransform: 'uppercase', letterSpacing: 0.5 }}>
114
113
  {routeLabel}
115
114
  </Typography>
116
115
  {stepLabel ? (
117
- <Typography variant="bodySmHeavy" color={theme.colors.brown[500]}>
116
+ <Typography variant="smallHeavy" color={theme.colors.brown[500]}>
118
117
  {stepLabel}
119
118
  </Typography>
120
119
  ) : null}
121
120
  </View>
122
121
 
123
122
  {/* Middle Row: Flag, Title, Progress Text */}
124
- <View style={[styles.middleRow, { marginBottom: scale(20) }]}>
123
+ <View style={[styles.middleRow, { marginBottom: scale(12) }]}>
125
124
  {/* Bandeira com anel "estás aqui" e shadow 3D */}
126
- <View style={[styles.flagWrapper, { width: scale(64), height: scale(64) }, styles.flagShadow]}>
127
- <Flag countryCode={countryCode} size={scale(48)} />
125
+ <View style={[styles.flagWrapper, { width: scale(44), height: scale(44) }, styles.flagShadow]}>
126
+ <Flag countryCode={countryCode} size={scale(32)} />
128
127
  </View>
129
128
 
130
- <View style={[styles.titleContainer, { marginLeft: scale(16) }]}>
131
- <Typography variant="h1" color={theme.colors.brown[800]}>
129
+ <View style={[styles.titleContainer, { marginLeft: scale(12) }]}>
130
+ <Typography variant="h3" color={theme.colors.brown[800]}>
132
131
  {title}
133
132
  </Typography>
134
- <Typography variant="bodyMdHeavy" color={theme.colors.primary}>
133
+ <Typography variant="bodySmHeavy" color={theme.colors.primary} style={{ marginTop: -2 }}>
135
134
  {subtitle}
136
135
  </Typography>
137
136
  </View>
138
137
 
139
138
  <View style={styles.progressTextContainer}>
140
- <Typography variant="h2" color={theme.colors.primary}>
139
+ <Typography variant="h4" color={theme.colors.primary}>
141
140
  {progressText}
142
141
  </Typography>
143
142
  <Typography variant="smallHeavy" color={theme.colors.brown[500]}>
@@ -150,8 +149,9 @@ export const RouteHeader = ({
150
149
  <ProgressBar
151
150
  progress={progress}
152
151
  segments={segments}
153
- size="md"
152
+ size="sm"
154
153
  variant="default" // Usa a cor primária (laranja)
154
+ trackColor={theme.colors.brown[100]} // Fundo da barra um pouco mais escuro para ser visível
155
155
  />
156
156
  </View>
157
157
  );
@@ -162,6 +162,8 @@ const styles = StyleSheet.create({
162
162
  backgroundColor: theme.colors.brown[50], // cream color matching the image
163
163
  width: '100%',
164
164
  zIndex: 10,
165
+ borderBottomWidth: 1.5,
166
+ borderBottomColor: theme.colors.brown[100],
165
167
  // Soft shadow to separate from content below
166
168
  ...Platform.select({
167
169
  web: {
@@ -187,7 +189,7 @@ const styles = StyleSheet.create({
187
189
  },
188
190
  flagWrapper: {
189
191
  borderRadius: 999,
190
- borderWidth: 2.5,
192
+ borderWidth: 2,
191
193
  borderColor: theme.colors.primary, // Anel laranja que significa "estás aqui"
192
194
  justifyContent: 'center',
193
195
  alignItems: 'center',
@@ -195,7 +195,7 @@ const styles = StyleSheet.create({
195
195
  flexDirection: 'row',
196
196
  justifyContent: 'space-around',
197
197
  alignItems: 'flex-start',
198
- backgroundColor: theme.colors.white,
198
+ backgroundColor: theme.colors.brown[50],
199
199
  borderTopWidth: 1.5,
200
200
  borderTopColor: theme.colors.brown[100],
201
201
  width: '100%',
package/src/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './components/Buttons/BackButton/BackButton';
2
2
  export * from './components/Buttons/BaseButton/BaseButton';
3
+ export * from './components/Buttons/Chip/Chip';
3
4
  export * from './components/Buttons/FabButton/FabButton';
4
5
  export * from './components/Buttons/IconButton/IconButton';
5
6
  export * from './components/Buttons/JourneyButton/JourneyButton';
@@ -52,4 +53,5 @@ export * from './components/Navigation/ProgressMap/ProgressMap';
52
53
  export * from './components/Navigation/WorldProgressMap/WorldProgressMap';
53
54
  export * from './components/Typography/Typography';
54
55
  export * from './hooks/useResponsive';
56
+ export * from './styles/countryThemes';
55
57