@xetwa/design-system 1.0.2

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.
Files changed (168) hide show
  1. package/.github/workflows/publish.yml +30 -0
  2. package/.storybook/main.ts +17 -0
  3. package/.storybook/preview.tsx +65 -0
  4. package/eslint.config.js +22 -0
  5. package/index.html +13 -0
  6. package/package.json +55 -0
  7. package/public/favicon.svg +1 -0
  8. package/public/icons.svg +24 -0
  9. package/src/App.css +184 -0
  10. package/src/App.tsx +122 -0
  11. package/src/BordasSombras.mdx +343 -0
  12. package/src/Colors.mdx +393 -0
  13. package/src/GrelhaLayout.mdx +375 -0
  14. package/src/Icons.mdx +42 -0
  15. package/src/MovimentoBreakpoints.mdx +379 -0
  16. package/src/Spacing.mdx +231 -0
  17. package/src/Typography.mdx +321 -0
  18. package/src/assets/Mascots/vava/estaticos/vava-acenar.svg +3 -0
  19. package/src/assets/Mascots/vava/estaticos/vava-acertou.svg +3 -0
  20. package/src/assets/Mascots/vava/estaticos/vava-celebrar.svg +3 -0
  21. package/src/assets/Mascots/vava/estaticos/vava-com-autocolantes.svg +3 -0
  22. package/src/assets/Mascots/vava/estaticos/vava-dormir.svg +3 -0
  23. package/src/assets/Mascots/vava/estaticos/vava-errou.svg +3 -0
  24. package/src/assets/Mascots/vava/estaticos/vava-feliz.svg +3 -0
  25. package/src/assets/Mascots/vava/estaticos/vava-neutra.svg +3 -0
  26. package/src/assets/Mascots/vava/estaticos/vava-original.svg +3 -0
  27. package/src/assets/Mascots/vava/estaticos/vava-pensar.svg +3 -0
  28. package/src/assets/Mascots/vava/estaticos/vava-surpresa.svg +3 -0
  29. package/src/assets/Mascots/yaya/avatar/yaya-avatar-falar.svg +7 -0
  30. package/src/assets/Mascots/yaya/avatar/yaya-avatar-feliz.svg +7 -0
  31. package/src/assets/Mascots/yaya/avatar/yaya-avatar-transparente.svg +6 -0
  32. package/src/assets/Mascots/yaya/estaticos/yaya-acertou.svg +13 -0
  33. package/src/assets/Mascots/yaya/estaticos/yaya-celebrar.svg +13 -0
  34. package/src/assets/Mascots/yaya/estaticos/yaya-dormir.svg +13 -0
  35. package/src/assets/Mascots/yaya/estaticos/yaya-errou.svg +13 -0
  36. package/src/assets/Mascots/yaya/estaticos/yaya-falar.svg +13 -0
  37. package/src/assets/Mascots/yaya/estaticos/yaya-feliz.svg +13 -0
  38. package/src/assets/Mascots/yaya/estaticos/yaya-neutra.svg +13 -0
  39. package/src/assets/Mascots/yaya/estaticos/yaya-pensar.svg +13 -0
  40. package/src/assets/Mascots/yaya/estaticos/yaya-surpresa.svg +13 -0
  41. package/src/assets/hero.png +0 -0
  42. package/src/assets/react.svg +1 -0
  43. package/src/assets/vite.svg +1 -0
  44. package/src/components/Buttons/BackButton/BackButton.stories.tsx +86 -0
  45. package/src/components/Buttons/BackButton/BackButton.tsx +107 -0
  46. package/src/components/Buttons/FabButton/FabButton.stories.tsx +74 -0
  47. package/src/components/Buttons/FabButton/FabButton.tsx +161 -0
  48. package/src/components/Buttons/IconButton/IconButton.stories.tsx +99 -0
  49. package/src/components/Buttons/IconButton/IconButton.tsx +189 -0
  50. package/src/components/Buttons/JourneyButton/JourneyButton.stories.tsx +80 -0
  51. package/src/components/Buttons/JourneyButton/JourneyButton.tsx +194 -0
  52. package/src/components/Buttons/MainButton/MainButton.stories.tsx +144 -0
  53. package/src/components/Buttons/MainButton/MainButton.tsx +258 -0
  54. package/src/components/Buttons/WordChip/WordChip.stories.tsx +84 -0
  55. package/src/components/Buttons/WordChip/WordChip.tsx +157 -0
  56. package/src/components/Buttons/WordChip/index.ts +1 -0
  57. package/src/components/Cards/AnswerOptionCard/AnswerOptionCard.stories.tsx +181 -0
  58. package/src/components/Cards/AnswerOptionCard/AnswerOptionCard.tsx +201 -0
  59. package/src/components/Cards/BaseCard/BaseCard.stories.tsx +148 -0
  60. package/src/components/Cards/BaseCard/BaseCard.tsx +181 -0
  61. package/src/components/Cards/BoardingPassCard/BoardingPassCard.stories.tsx +205 -0
  62. package/src/components/Cards/BoardingPassCard/BoardingPassCard.tsx +384 -0
  63. package/src/components/Cards/BoardingPassCard/FlightIcon.tsx +21 -0
  64. package/src/components/Cards/BoardingPassCard/FlightIcon.web.tsx +18 -0
  65. package/src/components/Cards/CountryCard/CountryCard.stories.tsx +97 -0
  66. package/src/components/Cards/CountryCard/CountryCard.tsx +185 -0
  67. package/src/components/Cards/LevelProgressCard/LevelProgressCard.stories.tsx +61 -0
  68. package/src/components/Cards/LevelProgressCard/LevelProgressCard.tsx +143 -0
  69. package/src/components/Cards/ModuleCard/ModuleCard.stories.tsx +108 -0
  70. package/src/components/Cards/ModuleCard/ModuleCard.tsx +304 -0
  71. package/src/components/Cards/ModuleCompletionCard/ModuleCompletionCard.stories.tsx +53 -0
  72. package/src/components/Cards/ModuleCompletionCard/ModuleCompletionCard.tsx +167 -0
  73. package/src/components/Cards/Passport/PassportCover.tsx +114 -0
  74. package/src/components/Cards/Passport/PassportIDPage.tsx +217 -0
  75. package/src/components/Cards/Passport/PassportStampPage.tsx +253 -0
  76. package/src/components/Cards/Passport/PassportViewer.stories.tsx +95 -0
  77. package/src/components/Cards/Passport/PassportViewer.tsx +328 -0
  78. package/src/components/Cards/PlanCard/PlanCard.stories.tsx +159 -0
  79. package/src/components/Cards/PlanCard/PlanCard.tsx +317 -0
  80. package/src/components/Cards/PricingCard/PricingCard.stories.tsx +83 -0
  81. package/src/components/Cards/PricingCard/PricingCard.tsx +144 -0
  82. package/src/components/Cards/SelectionCard/SelectionCard.stories.tsx +77 -0
  83. package/src/components/Cards/SelectionCard/SelectionCard.tsx +111 -0
  84. package/src/components/Cards/TeacherCard/TeacherCard.stories.tsx +126 -0
  85. package/src/components/Cards/TeacherCard/TeacherCard.tsx +236 -0
  86. package/src/components/Charts/WeeklyProgressChart/WeeklyProgressChart.stories.tsx +89 -0
  87. package/src/components/Charts/WeeklyProgressChart/WeeklyProgressChart.tsx +179 -0
  88. package/src/components/Charts/WeeklyProgressChart/index.ts +1 -0
  89. package/src/components/DataDisplay/Avatar/Avatar.stories.tsx +85 -0
  90. package/src/components/DataDisplay/Avatar/Avatar.tsx +118 -0
  91. package/src/components/DataDisplay/Avatar/index.ts +1 -0
  92. package/src/components/DataDisplay/Badge/Badge.stories.tsx +62 -0
  93. package/src/components/DataDisplay/Badge/Badge.tsx +146 -0
  94. package/src/components/DataDisplay/Flag/Flag.stories.tsx +98 -0
  95. package/src/components/DataDisplay/Flag/Flag.tsx +347 -0
  96. package/src/components/DataDisplay/Flag/Flag.web.tsx +334 -0
  97. package/src/components/DataDisplay/InstructionBubble/InstructionBubble.stories.tsx +80 -0
  98. package/src/components/DataDisplay/InstructionBubble/InstructionBubble.tsx +86 -0
  99. package/src/components/DataDisplay/LevelBadge/LevelBadge.stories.tsx +99 -0
  100. package/src/components/DataDisplay/LevelBadge/LevelBadge.tsx +118 -0
  101. package/src/components/DataDisplay/ProgressBar/ProgressBar.stories.tsx +95 -0
  102. package/src/components/DataDisplay/ProgressBar/ProgressBar.tsx +117 -0
  103. package/src/components/DataDisplay/StatBadge/StatBadge.stories.tsx +82 -0
  104. package/src/components/DataDisplay/StatBadge/StatBadge.tsx +135 -0
  105. package/src/components/DataDisplay/StatBadge/index.ts +1 -0
  106. package/src/components/DataDisplay/Tag/Tag.stories.tsx +63 -0
  107. package/src/components/DataDisplay/Tag/Tag.tsx +148 -0
  108. package/src/components/Feedback/FeedbackBottomSheet/FeedbackBottomSheet.stories.tsx +74 -0
  109. package/src/components/Feedback/FeedbackBottomSheet/FeedbackBottomSheet.tsx +200 -0
  110. package/src/components/Forms/Checkbox/Checkbox.stories.tsx +60 -0
  111. package/src/components/Forms/Checkbox/Checkbox.tsx +127 -0
  112. package/src/components/Forms/Checkbox/index.ts +1 -0
  113. package/src/components/Forms/DaySelector/DaySelector.stories.tsx +62 -0
  114. package/src/components/Forms/DaySelector/DaySelector.tsx +133 -0
  115. package/src/components/Forms/Radio/Radio.stories.tsx +61 -0
  116. package/src/components/Forms/Radio/Radio.tsx +141 -0
  117. package/src/components/Forms/Radio/index.ts +1 -0
  118. package/src/components/Forms/SegmentedToggle/SegmentedToggle.stories.tsx +67 -0
  119. package/src/components/Forms/SegmentedToggle/SegmentedToggle.tsx +150 -0
  120. package/src/components/Forms/SegmentedToggle/index.ts +1 -0
  121. package/src/components/Forms/Select/Select.stories.tsx +59 -0
  122. package/src/components/Forms/Select/Select.tsx +255 -0
  123. package/src/components/Forms/Select/index.ts +1 -0
  124. package/src/components/Forms/Switch/Switch.stories.tsx +57 -0
  125. package/src/components/Forms/Switch/Switch.tsx +120 -0
  126. package/src/components/Forms/Switch/index.ts +1 -0
  127. package/src/components/Forms/TimeSlot/TimeSlot.stories.tsx +62 -0
  128. package/src/components/Forms/TimeSlot/TimeSlot.tsx +116 -0
  129. package/src/components/Headers/CountryHeader/CountryHeader.stories.tsx +114 -0
  130. package/src/components/Headers/CountryHeader/CountryHeader.tsx +147 -0
  131. package/src/components/Headers/ProfileHeader/ProfileHeader.stories.tsx +141 -0
  132. package/src/components/Headers/ProfileHeader/ProfileHeader.tsx +233 -0
  133. package/src/components/Inputs/FillInTheBlank/FillInTheBlank.stories.tsx +333 -0
  134. package/src/components/Inputs/FillInTheBlank/FillInTheBlank.tsx +287 -0
  135. package/src/components/Inputs/FillInTheBlank/index.ts +1 -0
  136. package/src/components/Inputs/TextInput/TextInput.stories.tsx +103 -0
  137. package/src/components/Inputs/TextInput/TextInput.tsx +187 -0
  138. package/src/components/Mascots/Vava/Vava.stories.tsx +114 -0
  139. package/src/components/Mascots/Vava/Vava.tsx +276 -0
  140. package/src/components/Mascots/Yaya/Yaya.stories.tsx +98 -0
  141. package/src/components/Mascots/Yaya/Yaya.tsx +233 -0
  142. package/src/components/Navigation/BottomTabBar/BottomTabBar.stories.tsx +68 -0
  143. package/src/components/Navigation/BottomTabBar/BottomTabBar.tsx +85 -0
  144. package/src/components/Navigation/BottomTabBar/BottomTabBarItem.tsx +68 -0
  145. package/src/components/Navigation/BottomTabBar/index.ts +2 -0
  146. package/src/components/Navigation/PaginationDots/PaginationDots.stories.tsx +62 -0
  147. package/src/components/Navigation/PaginationDots/PaginationDots.tsx +81 -0
  148. package/src/components/Navigation/PaginationDots/index.ts +1 -0
  149. package/src/components/Navigation/ProgressMap/ProgressMap.stories.tsx +116 -0
  150. package/src/components/Navigation/ProgressMap/ProgressMap.tsx +827 -0
  151. package/src/components/Navigation/WorldProgressMap/WorldProgressMap.stories.tsx +169 -0
  152. package/src/components/Navigation/WorldProgressMap/WorldProgressMap.tsx +790 -0
  153. package/src/components/Typography/Typography.stories.tsx +127 -0
  154. package/src/components/Typography/Typography.tsx +53 -0
  155. package/src/hooks/useResponsive.ts +41 -0
  156. package/src/hooks/useTheme.ts +32 -0
  157. package/src/index.css +355 -0
  158. package/src/index.ts +28 -0
  159. package/src/main.tsx +10 -0
  160. package/src/mocks/codegenNativeComponent.ts +5 -0
  161. package/src/styles/countryThemes.ts +79 -0
  162. package/src/styles/theme.ts +297 -0
  163. package/src/utils/iconMap.ts +23 -0
  164. package/tsconfig.app.json +25 -0
  165. package/tsconfig.json +7 -0
  166. package/tsconfig.node.json +24 -0
  167. package/vite.config.ts +51 -0
  168. package/vitest.shims.d.ts +1 -0
@@ -0,0 +1,79 @@
1
+ export interface CountryThemeColors {
2
+ bg: string;
3
+ circle: string;
4
+ progressFill: string;
5
+ progressTrack: string;
6
+ }
7
+
8
+ const fallbackTheme: CountryThemeColors = {
9
+ bg: '#f2974b',
10
+ circle: '#f4a561',
11
+ progressFill: '#ffffff',
12
+ progressTrack: 'rgba(255,255,255,0.3)',
13
+ };
14
+
15
+ export const countryThemes: Record<string, CountryThemeColors> = {
16
+ // 1. Senegal
17
+ SN: { bg: '#16915a', circle: '#439c52', progressFill: '#fdef42', progressTrack: '#30a572' },
18
+ // 2. França
19
+ FR: { bg: '#00209F', circle: '#1a37a9', progressFill: '#E8001F', progressTrack: 'rgba(255, 255, 255, 0.3)' },
20
+ // 3. Bélgica
21
+ BE: { bg: '#1a1a1a', circle: '#2b2b2b', progressFill: '#FFE300', progressTrack: 'rgba(255, 255, 255, 0.2)' },
22
+ // 4. Suíça
23
+ CH: { bg: '#d52b1e', circle: '#e34034', progressFill: '#ffffff', progressTrack: 'rgba(255, 255, 255, 0.3)' },
24
+ // 5. Canadá
25
+ CA: { bg: '#d52b1e', circle: '#e34034', progressFill: '#ffffff', progressTrack: 'rgba(255, 255, 255, 0.3)' },
26
+ // 6. Côte d'Ivoire
27
+ CI: { bg: '#F77F00', circle: '#fa9020', progressFill: '#009E60', progressTrack: 'rgba(255, 255, 255, 0.3)' },
28
+ // 7. RD Congo
29
+ CD: { bg: '#00A3E0', circle: '#1bb0eb', progressFill: '#FFDC00', progressTrack: 'rgba(255, 255, 255, 0.3)' },
30
+ // 8. Luxemburgo
31
+ LU: { bg: '#00A1DE', circle: '#1bafee', progressFill: '#EF3340', progressTrack: 'rgba(255, 255, 255, 0.3)' },
32
+ // 9. Mónaco
33
+ MC: { bg: '#CE1126', circle: '#db2b3e', progressFill: '#ffffff', progressTrack: 'rgba(255, 255, 255, 0.3)' },
34
+ // 10. Camarões
35
+ CM: { bg: '#007A5E', circle: '#168a6f', progressFill: '#CE1126', progressTrack: 'rgba(255, 255, 255, 0.3)' },
36
+ // 11. Madagáscar
37
+ MG: { bg: '#007E3A', circle: '#188e4c', progressFill: '#FC3D32', progressTrack: 'rgba(255, 255, 255, 0.3)' },
38
+ // 12. Burquina Fasso
39
+ BF: { bg: '#EF2B2D', circle: '#f64042', progressFill: '#009E49', progressTrack: 'rgba(255, 255, 255, 0.3)' },
40
+ // 13. Níger
41
+ NE: { bg: '#E05206', circle: '#ec661f', progressFill: '#0DB02B', progressTrack: 'rgba(255, 255, 255, 0.3)' },
42
+ // 14. Mali
43
+ ML: { bg: '#14B53A', circle: '#2bc44e', progressFill: '#FCD116', progressTrack: 'rgba(255, 255, 255, 0.3)' },
44
+ // 15. Chade
45
+ TD: { bg: '#002664', circle: '#163a75', progressFill: '#FECB00', progressTrack: 'rgba(255, 255, 255, 0.3)' },
46
+ // 16. Guiné
47
+ GN: { bg: '#CE1126', circle: '#da293e', progressFill: '#FCD116', progressTrack: 'rgba(255, 255, 255, 0.3)' },
48
+ // 17. Ruanda
49
+ RW: { bg: '#00A1DE', circle: '#1dafee', progressFill: '#FAD201', progressTrack: 'rgba(255, 255, 255, 0.3)' },
50
+ // 18. Burundi
51
+ BI: { bg: '#CE1126', circle: '#da293e', progressFill: '#1EB53A', progressTrack: 'rgba(255, 255, 255, 0.3)' },
52
+ // 19. Benim
53
+ BJ: { bg: '#008751', circle: '#169661', progressFill: '#FCD116', progressTrack: 'rgba(255, 255, 255, 0.3)' },
54
+ // 20. Togo
55
+ TG: { bg: '#006A4E', circle: '#167b60', progressFill: '#FFCE00', progressTrack: 'rgba(255, 255, 255, 0.3)' },
56
+ // 21. República Centro-Africana
57
+ CF: { bg: '#003082', circle: '#184594', progressFill: '#289728', progressTrack: 'rgba(255, 255, 255, 0.3)' },
58
+ // 22. Congo
59
+ CG: { bg: '#009543', circle: '#18a356', progressFill: '#FBDE4A', progressTrack: 'rgba(255, 255, 255, 0.3)' },
60
+ // 23. Gabão
61
+ GA: { bg: '#009E60', circle: '#1aab70', progressFill: '#FCD116', progressTrack: 'rgba(255, 255, 255, 0.3)' },
62
+ // 24. Guiné Equatorial
63
+ GQ: { bg: '#3E9A00', circle: '#51a816', progressFill: '#E32118', progressTrack: 'rgba(255, 255, 255, 0.3)' },
64
+ // 25. Jibuti
65
+ DJ: { bg: '#6AB2E7', circle: '#7fbfef', progressFill: '#12AD2B', progressTrack: 'rgba(255, 255, 255, 0.3)' },
66
+ // 26. Comores
67
+ KM: { bg: '#3D8E33', circle: '#519e48', progressFill: '#FFC61E', progressTrack: 'rgba(255, 255, 255, 0.3)' },
68
+ // 27. Vanuatu
69
+ VU: { bg: '#D21034', circle: '#df2749', progressFill: '#FFCE00', progressTrack: 'rgba(255, 255, 255, 0.3)' },
70
+ // 28. Seicheles
71
+ SC: { bg: '#003D88', circle: '#18529b', progressFill: '#FCD856', progressTrack: 'rgba(255, 255, 255, 0.3)' },
72
+ // 29. Haiti
73
+ HT: { bg: '#00209F', circle: '#1a37a9', progressFill: '#D21034', progressTrack: 'rgba(255, 255, 255, 0.3)' },
74
+ };
75
+
76
+ export const getCountryTheme = (countryCode: string): CountryThemeColors => {
77
+ const normalized = countryCode.toUpperCase().trim();
78
+ return countryThemes[normalized] || fallbackTheme;
79
+ };
@@ -0,0 +1,297 @@
1
+ export const theme = {
2
+ colors: {
3
+ // Paleta primária
4
+ primary: '#f2974b', // CTAs, botão primário, destaque, progresso
5
+ primaryDark: '#cf7a30', // Sombra do botão primário, ícone selecionado, hover
6
+ primaryLight: '#fef6ee', // Fundo de item selecionado, chip ativo
7
+
8
+ // Escala de castanho (neutros)
9
+ brown: {
10
+ 900: '#15100d', // Cor máxima de contraste, textos ou superfícies em modo escuro
11
+ 800: '#51332d', // Texto principal, cabeçalhos e botões na variante invertida
12
+ 700: '#3f2620', // Bordas internas e sombras profundas
13
+ 600: '#6e5a4f', // Texto de apoio escuro, iconografia
14
+ 500: '#9a8478', // Texto secundário, labels, placeholders
15
+ 400: '#b9a392', // Ícones desativados, texto terciário
16
+ 300: '#c3b1a4', // Ícones de navegação não selecionada
17
+ 100: '#efe2d6', // Bordas, separadores e sombra do botão secundário
18
+ 50: '#fdf3ea', // Fundo de cards, chips neutros, áreas de destaque leve
19
+ },
20
+
21
+ cream: '#fbf6f0', // Fundo de ecrãs secundários
22
+ canvas: '#e7e5df', // Fundo do arquivo de design no Figma (não usado na app)
23
+
24
+ // Semânticas & Base
25
+ success: '#16915a', // Sucesso, acertos, módulos concluídos
26
+ error: '#cf5b48', // Erro, campo inválido
27
+ info: '#2a6fc2', // Informação, link
28
+ black: '#000000', // Preto Xetwa
29
+ white: '#ffffff', // Fundo principal de ecrãs, cards
30
+
31
+ // Light Theme
32
+ light: {
33
+ bgApp: '#fbf6f0', // cream
34
+ bgSurface: '#ffffff', // white
35
+ bgSurfaceHover: '#fdf3ea', // brown-50
36
+ borderColor: '#efe2d6', // brown-100
37
+ textPrimary: '#51332d', // brown-800
38
+ textSecondary: '#9a8478', // brown-500
39
+ textTertiary: '#b9a392', // brown-400
40
+ glassBg: 'rgba(255, 255, 255, 0.65)',
41
+ glassBorder: 'rgba(255, 255, 255, 0.4)',
42
+ primaryLight: '#fef6ee', // primaryLight
43
+ },
44
+
45
+ // Dark Theme
46
+ dark: {
47
+ bgApp: '#15100d', // brown-900
48
+ bgSurface: '#51332d', // brown-800
49
+ bgSurfaceHover: '#3f2620', // brown-700
50
+ borderColor: '#3f2620', // brown-700
51
+ textPrimary: '#efe2d6', // brown-100
52
+ textSecondary: '#b9a392', // brown-400
53
+ textTertiary: '#9a8478', // brown-500
54
+ glassBg: 'rgba(81, 51, 45, 0.65)',
55
+ glassBorder: 'rgba(255, 255, 255, 0.08)',
56
+ primaryLight: 'rgba(242, 151, 75, 0.15)', // transparent primary
57
+ }
58
+ },
59
+
60
+ spacing: {
61
+ // Relatório de espaçamento base 4px
62
+ space1: 4,
63
+ space2: 8,
64
+ space3: 12,
65
+ space4: 16,
66
+ space5: 20,
67
+ space6: 24,
68
+ space8: 32,
69
+ space10: 40,
70
+ space12: 48,
71
+ space16: 64,
72
+
73
+ // Aliases antigos para retrocompatibilidade
74
+ xs: 4,
75
+ sm: 8,
76
+ md: 12,
77
+ lg: 16,
78
+ xl: 20,
79
+ xxl: 24,
80
+ xxxl: 32,
81
+ },
82
+
83
+ radius: {
84
+ xs: 6,
85
+ sm: 10,
86
+ md: 12,
87
+ lg: 16,
88
+ xl: 20,
89
+ xxl: 24,
90
+ screen: 34,
91
+ phone: 42,
92
+ full: 9999,
93
+ },
94
+
95
+ shadows: {
96
+ xs: {
97
+ shadowColor: '#51332d',
98
+ shadowOffset: { width: 0, height: 1 },
99
+ shadowOpacity: 0.08,
100
+ shadowRadius: 3,
101
+ elevation: 1,
102
+ },
103
+ sm: {
104
+ shadowColor: '#51332d',
105
+ shadowOffset: { width: 0, height: 2 },
106
+ shadowOpacity: 0.10,
107
+ shadowRadius: 8,
108
+ elevation: 2,
109
+ },
110
+ md: {
111
+ shadowColor: '#51332d',
112
+ shadowOffset: { width: 0, height: 4 },
113
+ shadowOpacity: 0.13,
114
+ shadowRadius: 14,
115
+ elevation: 4,
116
+ },
117
+ lg: {
118
+ shadowColor: '#51332d',
119
+ shadowOffset: { width: 0, height: 8 },
120
+ shadowOpacity: 0.18,
121
+ shadowRadius: 26,
122
+ elevation: 8,
123
+ },
124
+ xl: {
125
+ shadowColor: '#51332d',
126
+ shadowOffset: { width: 0, height: 18 },
127
+ shadowOpacity: 0.28,
128
+ shadowRadius: 40,
129
+ elevation: 16,
130
+ },
131
+ btnPrimary: {
132
+ shadowColor: '#cf7a30',
133
+ shadowOffset: { width: 0, height: 4 },
134
+ shadowOpacity: 1,
135
+ shadowRadius: 0,
136
+ },
137
+ btnSecondary: {
138
+ shadowColor: '#efe2d6',
139
+ shadowOffset: { width: 0, height: 4 },
140
+ shadowOpacity: 1,
141
+ shadowRadius: 0,
142
+ },
143
+ btnDark: {
144
+ shadowColor: '#3a241f',
145
+ shadowOffset: { width: 0, height: 4 },
146
+ shadowOpacity: 1,
147
+ shadowRadius: 0,
148
+ },
149
+ focus: {
150
+ shadowColor: '#f2974b',
151
+ shadowOffset: { width: 0, height: 0 },
152
+ shadowOpacity: 0.22,
153
+ shadowRadius: 3,
154
+ elevation: 3,
155
+ }
156
+ },
157
+
158
+ fonts: {
159
+ title: 'Fredoka', // Fredoka – títulos
160
+ body: 'Nunito', // Nunito – corpo e botões
161
+ },
162
+
163
+ typography: {
164
+ display1: {
165
+ fontFamily: 'Fredoka',
166
+ fontSize: 28,
167
+ fontWeight: '700' as const,
168
+ lineHeight: 30,
169
+ },
170
+ display2: {
171
+ fontFamily: 'Fredoka',
172
+ fontSize: 24,
173
+ fontWeight: '700' as const,
174
+ lineHeight: 27,
175
+ },
176
+ h1: {
177
+ fontFamily: 'Fredoka',
178
+ fontSize: 22,
179
+ fontWeight: '700' as const,
180
+ lineHeight: 25,
181
+ },
182
+ h2: {
183
+ fontFamily: 'Fredoka',
184
+ fontSize: 18,
185
+ fontWeight: '600' as const,
186
+ lineHeight: 22,
187
+ },
188
+ h3: {
189
+ fontFamily: 'Fredoka',
190
+ fontSize: 16,
191
+ fontWeight: '600' as const,
192
+ lineHeight: 20,
193
+ },
194
+ label: {
195
+ fontFamily: 'Nunito',
196
+ fontSize: 10,
197
+ fontWeight: '800' as const,
198
+ lineHeight: 10,
199
+ letterSpacing: 1.2,
200
+ },
201
+ bodyLg: {
202
+ fontFamily: 'Nunito',
203
+ fontSize: 15,
204
+ fontWeight: '600' as const,
205
+ lineHeight: 23,
206
+ },
207
+ bodyMd: {
208
+ fontFamily: 'Nunito',
209
+ fontSize: 13.5,
210
+ fontWeight: '600' as const,
211
+ lineHeight: 20,
212
+ },
213
+ bodySm: {
214
+ fontFamily: 'Nunito',
215
+ fontSize: 12,
216
+ fontWeight: '700' as const,
217
+ lineHeight: 17,
218
+ },
219
+ caption: {
220
+ fontFamily: 'Nunito',
221
+ fontSize: 10,
222
+ fontWeight: '700' as const,
223
+ lineHeight: 14,
224
+ },
225
+ btnLg: {
226
+ fontFamily: 'Nunito',
227
+ fontSize: 16,
228
+ fontWeight: '800' as const,
229
+ lineHeight: 16,
230
+ letterSpacing: 0.64,
231
+ },
232
+ btnMd: {
233
+ fontFamily: 'Nunito',
234
+ fontSize: 14,
235
+ fontWeight: '800' as const,
236
+ lineHeight: 14,
237
+ letterSpacing: 0.56,
238
+ },
239
+ btnSm: {
240
+ fontFamily: 'Nunito',
241
+ fontSize: 12,
242
+ fontWeight: '800' as const,
243
+ lineHeight: 12,
244
+ letterSpacing: 0.48,
245
+ },
246
+ },
247
+
248
+ breakpoints: {
249
+ xs: 0,
250
+ sm: 375,
251
+ md: 430,
252
+ lg: 768,
253
+ xl: 1024,
254
+ xxl: 1280,
255
+ xxxl: 1440,
256
+ },
257
+
258
+ animations: {
259
+ easings: {
260
+ bounce: [0.34, 1.56, 0.64, 1] as [number, number, number, number],
261
+ smooth: [0.4, 0, 0.2, 1] as [number, number, number, number],
262
+ out: [0, 0, 0.2, 1] as [number, number, number, number],
263
+ },
264
+ durations: {
265
+ fast: 120,
266
+ base: 200,
267
+ medium: 300,
268
+ slow: 500,
269
+ }
270
+ },
271
+
272
+ layout: {
273
+ mobileHeaderHeight: 52,
274
+ mobileTabHeight: 56,
275
+ desktopSidebarWidth: 220,
276
+ tabletHeaderHeight: 64,
277
+ maxContentWidth: 1200,
278
+ }
279
+ };
280
+
281
+ export type Theme = typeof theme;
282
+ export type ColorTheme = typeof theme.colors.light;
283
+ export type FontsTheme = typeof theme.fonts;
284
+ export type BrownScale = typeof theme.colors.brown;
285
+ export type TypographyTheme = typeof theme.typography;
286
+ export type TypographyVariant = keyof TypographyTheme;
287
+ export type ShadowsTheme = typeof theme.shadows;
288
+ export type BreakpointsTheme = typeof theme.breakpoints;
289
+ export type AnimationsTheme = typeof theme.animations;
290
+ export type LayoutTheme = typeof theme.layout;
291
+ export type SemanticColors = {
292
+ success: string;
293
+ error: string;
294
+ info: string;
295
+ black: string;
296
+ white: string;
297
+ };
@@ -0,0 +1,23 @@
1
+ import { Play, Volume2, Volume1, ArrowRight, X, Check, ChevronRight, ChevronLeft, Info, AlertTriangle, Book } from 'lucide-react-native';
2
+
3
+ /**
4
+ * Para evitar que o Vite e o Metro (React Native) tentem empacotar os 1400+ ícones
5
+ * da biblioteca (o que causa crash de memória e aumenta muito o tamanho final da app),
6
+ * mapeamos aqui explicitamente os ícones que usamos.
7
+ *
8
+ * Se precisar de um novo ícone da \`lucide-react-native\`, basta importá-lo acima
9
+ * e adicioná-lo a este objeto.
10
+ */
11
+ export const IconMap: Record<string, any> = {
12
+ Play,
13
+ Volume1,
14
+ Volume2,
15
+ ArrowRight,
16
+ ChevronRight,
17
+ ChevronLeft,
18
+ X,
19
+ Check,
20
+ Info,
21
+ AlertTriangle,
22
+ Book,
23
+ };
@@ -0,0 +1,25 @@
1
+ {
2
+ "compilerOptions": {
3
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
4
+ "target": "es2023",
5
+ "lib": ["ES2023", "DOM"],
6
+ "module": "esnext",
7
+ "types": ["vite/client"],
8
+ "skipLibCheck": true,
9
+
10
+ /* Bundler mode */
11
+ "moduleResolution": "bundler",
12
+ "allowImportingTsExtensions": true,
13
+ "verbatimModuleSyntax": true,
14
+ "moduleDetection": "force",
15
+ "noEmit": true,
16
+ "jsx": "react-jsx",
17
+
18
+ /* Linting */
19
+ "noUnusedLocals": false,
20
+ "noUnusedParameters": false,
21
+ "erasableSyntaxOnly": true,
22
+ "noFallthroughCasesInSwitch": true
23
+ },
24
+ "include": ["src"]
25
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "files": [],
3
+ "references": [
4
+ { "path": "./tsconfig.app.json" },
5
+ { "path": "./tsconfig.node.json" }
6
+ ]
7
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "compilerOptions": {
3
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
4
+ "target": "es2023",
5
+ "lib": ["ES2023"],
6
+ "module": "esnext",
7
+ "types": ["node"],
8
+ "skipLibCheck": true,
9
+
10
+ /* Bundler mode */
11
+ "moduleResolution": "bundler",
12
+ "allowImportingTsExtensions": true,
13
+ "verbatimModuleSyntax": true,
14
+ "moduleDetection": "force",
15
+ "noEmit": true,
16
+
17
+ /* Linting */
18
+ "noUnusedLocals": true,
19
+ "noUnusedParameters": true,
20
+ "erasableSyntaxOnly": true,
21
+ "noFallthroughCasesInSwitch": true
22
+ },
23
+ "include": ["vite.config.ts"]
24
+ }
package/vite.config.ts ADDED
@@ -0,0 +1,51 @@
1
+ /// <reference types="vitest/config" />
2
+ import { defineConfig } from 'vite';
3
+ import react from '@vitejs/plugin-react';
4
+
5
+ import tailwindcss from '@tailwindcss/vite';
6
+
7
+ // https://vite.dev/config/
8
+ import path from 'node:path';
9
+ import { fileURLToPath } from 'node:url';
10
+ import { storybookTest } from '@storybook/addon-vitest/vitest-plugin';
11
+ import { playwright } from '@vitest/browser-playwright';
12
+ const dirname = typeof __dirname !== 'undefined' ? __dirname : path.dirname(fileURLToPath(import.meta.url));
13
+
14
+ // More info at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon
15
+ export default defineConfig({
16
+ plugins: [react(), tailwindcss()],
17
+ resolve: {
18
+ extensions: ['.web.tsx', '.web.ts', '.web.jsx', '.web.js', '.tsx', '.ts', '.jsx', '.js', '.json'],
19
+ alias: {
20
+ 'lucide-react-native': 'lucide-react',
21
+ 'react-native': 'react-native-web',
22
+ },
23
+ },
24
+ optimizeDeps: {
25
+ esbuildOptions: {
26
+ resolveExtensions: ['.web.tsx', '.web.ts', '.web.jsx', '.web.js', '.tsx', '.ts', '.jsx', '.js', '.json'],
27
+ },
28
+ },
29
+ test: {
30
+ projects: [{
31
+ extends: true,
32
+ plugins: [
33
+ // The plugin will run tests for the stories defined in your Storybook config
34
+ // See options at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon#storybooktest
35
+ storybookTest({
36
+ configDir: path.join(dirname, '.storybook')
37
+ })],
38
+ test: {
39
+ name: 'storybook',
40
+ browser: {
41
+ enabled: true,
42
+ headless: true,
43
+ provider: playwright({}),
44
+ instances: [{
45
+ browser: 'chromium'
46
+ }]
47
+ }
48
+ }
49
+ }]
50
+ }
51
+ });
@@ -0,0 +1 @@
1
+ /// <reference types="@vitest/browser-playwright" />