@umituz/react-native-design-system 1.0.0

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 (80) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +157 -0
  3. package/package.json +43 -0
  4. package/src/index.ts +345 -0
  5. package/src/presentation/atoms/AtomicAvatar.tsx +157 -0
  6. package/src/presentation/atoms/AtomicAvatarGroup.tsx +169 -0
  7. package/src/presentation/atoms/AtomicBadge.tsx +232 -0
  8. package/src/presentation/atoms/AtomicButton.tsx +124 -0
  9. package/src/presentation/atoms/AtomicCard.tsx +112 -0
  10. package/src/presentation/atoms/AtomicChip.tsx +223 -0
  11. package/src/presentation/atoms/AtomicDatePicker.tsx +347 -0
  12. package/src/presentation/atoms/AtomicDivider.tsx +114 -0
  13. package/src/presentation/atoms/AtomicFab.tsx +104 -0
  14. package/src/presentation/atoms/AtomicFilter.tsx +154 -0
  15. package/src/presentation/atoms/AtomicFormError.tsx +105 -0
  16. package/src/presentation/atoms/AtomicIcon.tsx +29 -0
  17. package/src/presentation/atoms/AtomicImage.tsx +149 -0
  18. package/src/presentation/atoms/AtomicInput.tsx +232 -0
  19. package/src/presentation/atoms/AtomicNumberInput.tsx +182 -0
  20. package/src/presentation/atoms/AtomicPicker.tsx +458 -0
  21. package/src/presentation/atoms/AtomicProgress.tsx +143 -0
  22. package/src/presentation/atoms/AtomicSearchBar.tsx +114 -0
  23. package/src/presentation/atoms/AtomicSkeleton.tsx +146 -0
  24. package/src/presentation/atoms/AtomicSort.tsx +145 -0
  25. package/src/presentation/atoms/AtomicSwitch.tsx +166 -0
  26. package/src/presentation/atoms/AtomicText.tsx +50 -0
  27. package/src/presentation/atoms/AtomicTextArea.tsx +198 -0
  28. package/src/presentation/atoms/AtomicTouchable.tsx +233 -0
  29. package/src/presentation/atoms/fab/styles/fabStyles.ts +69 -0
  30. package/src/presentation/atoms/fab/types/index.ts +88 -0
  31. package/src/presentation/atoms/filter/styles/filterStyles.ts +32 -0
  32. package/src/presentation/atoms/filter/types/index.ts +89 -0
  33. package/src/presentation/atoms/index.ts +378 -0
  34. package/src/presentation/atoms/input/hooks/useInputState.ts +15 -0
  35. package/src/presentation/atoms/input/styles/inputStyles.ts +66 -0
  36. package/src/presentation/atoms/input/types/index.ts +25 -0
  37. package/src/presentation/atoms/picker/styles/pickerStyles.ts +200 -0
  38. package/src/presentation/atoms/picker/types/index.ts +40 -0
  39. package/src/presentation/atoms/touchable/styles/touchableStyles.ts +71 -0
  40. package/src/presentation/atoms/touchable/types/index.ts +162 -0
  41. package/src/presentation/hooks/useAppDesignTokens.ts +78 -0
  42. package/src/presentation/hooks/useResponsive.ts +180 -0
  43. package/src/presentation/loading/index.ts +40 -0
  44. package/src/presentation/loading/presentation/components/LoadingSpinner.tsx +116 -0
  45. package/src/presentation/loading/presentation/components/LoadingState.tsx +200 -0
  46. package/src/presentation/loading/presentation/hooks/useLoading.ts +100 -0
  47. package/src/presentation/molecules/AtomicConfirmationModal.tsx +263 -0
  48. package/src/presentation/molecules/EmptyState.tsx +130 -0
  49. package/src/presentation/molecules/FormField.tsx +128 -0
  50. package/src/presentation/molecules/GridContainer.tsx +124 -0
  51. package/src/presentation/molecules/IconContainer.tsx +94 -0
  52. package/src/presentation/molecules/LanguageSwitcher.tsx +42 -0
  53. package/src/presentation/molecules/ListItem.tsx +36 -0
  54. package/src/presentation/molecules/ScreenHeader.tsx +140 -0
  55. package/src/presentation/molecules/SearchBar.tsx +85 -0
  56. package/src/presentation/molecules/SectionCard.tsx +74 -0
  57. package/src/presentation/molecules/SectionContainer.tsx +106 -0
  58. package/src/presentation/molecules/SectionHeader.tsx +125 -0
  59. package/src/presentation/molecules/confirmation-modal/styles/confirmationModalStyles.ts +133 -0
  60. package/src/presentation/molecules/confirmation-modal/types/index.ts +107 -0
  61. package/src/presentation/molecules/index.ts +42 -0
  62. package/src/presentation/molecules/languageswitcher/config/languageSwitcherConfig.ts +5 -0
  63. package/src/presentation/molecules/languageswitcher/hooks/useLanguageNavigation.ts +15 -0
  64. package/src/presentation/molecules/listitem/styles/listItemStyles.ts +19 -0
  65. package/src/presentation/molecules/listitem/types/index.ts +17 -0
  66. package/src/presentation/organisms/AppHeader.tsx +136 -0
  67. package/src/presentation/organisms/FormContainer.tsx +180 -0
  68. package/src/presentation/organisms/ScreenLayout.tsx +209 -0
  69. package/src/presentation/organisms/index.ts +25 -0
  70. package/src/presentation/tokens/AppDesignTokens.ts +57 -0
  71. package/src/presentation/tokens/commonStyles.ts +253 -0
  72. package/src/presentation/tokens/core/BaseTokens.ts +394 -0
  73. package/src/presentation/tokens/core/ColorPalette.ts +398 -0
  74. package/src/presentation/tokens/core/TokenFactory.ts +120 -0
  75. package/src/presentation/utils/platformConstants.ts +124 -0
  76. package/src/presentation/utils/responsive.ts +516 -0
  77. package/src/presentation/utils/variants/compound.ts +29 -0
  78. package/src/presentation/utils/variants/core.ts +39 -0
  79. package/src/presentation/utils/variants/helpers.ts +13 -0
  80. package/src/presentation/utils/variants.ts +3 -0
@@ -0,0 +1,398 @@
1
+ /**
2
+ * COLOR PALETTE - THEME-SPECIFIC COLORS
3
+ *
4
+ * ✅ Light and Dark theme color definitions
5
+ * ✅ Semantic color naming for clarity
6
+ * ✅ Template placeholders for factory generation
7
+ * ✅ Type-safe color definitions
8
+ *
9
+ * @module ColorPalette
10
+ */
11
+
12
+ // =============================================================================
13
+ // COLOR UTILITIES
14
+ // =============================================================================
15
+
16
+ /**
17
+ * Add alpha transparency to hex color
18
+ * @param hexColor - Hex color string (#RRGGBB or #RGB)
19
+ * @param alpha - Alpha value 0-1
20
+ * @returns Hex color with alpha (#RRGGBBAA)
21
+ */
22
+ export const withAlpha = (hexColor: string, alpha: number): string => {
23
+ if (!hexColor.startsWith('#') || (hexColor.length !== 7 && hexColor.length !== 4)) {
24
+ return hexColor;
25
+ }
26
+
27
+ if (alpha < 0 || alpha > 1) {
28
+ return hexColor;
29
+ }
30
+
31
+ const alphaHex = Math.round(alpha * 255)
32
+ .toString(16)
33
+ .padStart(2, '0');
34
+
35
+ return hexColor + alphaHex;
36
+ };
37
+
38
+ // =============================================================================
39
+ // LIGHT THEME COLORS
40
+ // =============================================================================
41
+
42
+ export const lightColors = {
43
+ // =============================================================================
44
+ // PRIMARY BRAND COLORS (from theme template)
45
+ // =============================================================================
46
+ primary: '{{PRIMARY_COLOR}}',
47
+ primaryLight: '{{PRIMARY_LIGHT_COLOR}}',
48
+ primaryDark: '{{PRIMARY_DARK_COLOR}}',
49
+
50
+ secondary: '{{SECONDARY_COLOR}}',
51
+ secondaryLight: '{{SECONDARY_LIGHT_COLOR}}',
52
+ secondaryDark: '{{SECONDARY_DARK_COLOR}}',
53
+
54
+ accent: '{{ACCENT_COLOR}}',
55
+ accentLight: '{{ACCENT_LIGHT_COLOR}}',
56
+ accentDark: '{{ACCENT_DARK_COLOR}}',
57
+
58
+ // =============================================================================
59
+ // MATERIAL DESIGN 3 - ON COLORS (Text on colored backgrounds)
60
+ // =============================================================================
61
+ onPrimary: '#FFFFFF', // Text on primary background
62
+ onSecondary: '#FFFFFF', // Text on secondary background
63
+ onSuccess: '#FFFFFF', // Text on success background
64
+ onError: '#FFFFFF', // Text on error background
65
+ onWarning: '#000000', // Text on warning background
66
+ onInfo: '#FFFFFF', // Text on info background
67
+ onSurface: '#1E293B', // Text on surface
68
+ onBackground: '#1E293B', // Text on background
69
+ onSurfaceDisabled: '#CBD5E1', // Disabled text color
70
+
71
+ // =============================================================================
72
+ // MATERIAL DESIGN 3 - CONTAINER COLORS (Lighter versions for containers)
73
+ // =============================================================================
74
+ primaryContainer: '#DBEAFE', // Light container using primary
75
+ onPrimaryContainer: '#1E40AF', // Text on primary container
76
+ secondaryContainer: '#E0E7FF', // Light container using secondary
77
+ onSecondaryContainer: '#3730A3', // Text on secondary container
78
+ errorContainer: '#FEE2E2', // Light container using error
79
+ onErrorContainer: '#991B1B', // Text on error container
80
+
81
+ // =============================================================================
82
+ // MATERIAL DESIGN 3 - OUTLINE
83
+ // =============================================================================
84
+ outline: '#CBD5E1', // Default outline color
85
+ outlineVariant: '#E2E8F0', // Lighter outline variant
86
+ outlineDisabled: '#E2E8F0', // Disabled outline color
87
+
88
+ // =============================================================================
89
+ // SEMANTIC UI COLORS
90
+ // =============================================================================
91
+ success: '#10B981',
92
+ successLight: '#34D399',
93
+ successDark: '#059669',
94
+
95
+ error: '#EF4444',
96
+ errorLight: '#F87171',
97
+ errorDark: '#DC2626',
98
+
99
+ warning: '#F59E0B',
100
+ warningLight: '#FBBF24',
101
+ warningDark: '#D97706',
102
+
103
+ info: '#3B82F6',
104
+ infoLight: '#60A5FA',
105
+ infoDark: '#2563EB',
106
+
107
+ // =============================================================================
108
+ // SEMANTIC CONTAINER COLORS (Light mode)
109
+ // =============================================================================
110
+ successContainer: '#D1FAE5', // Light container for success states
111
+ onSuccessContainer: '#065F46', // Text on success container
112
+ warningContainer: '#FEF3C7', // Light container for warning states
113
+ onWarningContainer: '#92400E', // Text on warning container
114
+ infoContainer: '#DBEAFE', // Light container for info states
115
+ onInfoContainer: '#1E40AF', // Text on info container
116
+
117
+ // =============================================================================
118
+ // GRAYSCALE PALETTE
119
+ // =============================================================================
120
+ gray50: '#FAFAFA',
121
+ gray100: '#F4F4F5',
122
+ gray200: '#E4E4E7',
123
+ gray300: '#D4D4D8',
124
+ gray400: '#A1A1AA',
125
+ gray500: '#71717A',
126
+ gray600: '#52525B',
127
+ gray700: '#3F3F46',
128
+ gray800: '#27272A',
129
+ gray900: '#18181B',
130
+
131
+ // =============================================================================
132
+ // BACKGROUND COLORS (from theme template)
133
+ // =============================================================================
134
+ backgroundPrimary: '{{BACKGROUND_COLOR}}',
135
+ backgroundSecondary: '{{BACKGROUND_SECONDARY_COLOR}}',
136
+
137
+ surface: '{{SURFACE_COLOR}}',
138
+ surfaceVariant: '{{SURFACE_SECONDARY_COLOR}}',
139
+ surfaceSecondary: '{{SURFACE_SECONDARY_COLOR}}', // Alias
140
+ surfaceDisabled: '#F4F4F5', // Disabled surface color
141
+
142
+ // =============================================================================
143
+ // TEXT COLORS (from theme template)
144
+ // =============================================================================
145
+ textPrimary: '{{TEXT_PRIMARY_COLOR}}',
146
+ textSecondary: '{{TEXT_SECONDARY_COLOR}}',
147
+ textTertiary: '{{TEXT_TERTIARY_COLOR}}',
148
+ textDisabled: '{{TEXT_DISABLED_COLOR}}',
149
+ textInverse: '{{TEXT_INVERSE_COLOR}}',
150
+
151
+ // =============================================================================
152
+ // BORDER COLORS (from theme template)
153
+ // =============================================================================
154
+ border: '{{BORDER_COLOR}}',
155
+ borderLight: '{{BORDER_LIGHT_COLOR}}',
156
+ borderMedium: '{{BORDER_MEDIUM_COLOR}}',
157
+ borderFocus: '{{BORDER_FOCUS_COLOR}}',
158
+
159
+ // =============================================================================
160
+ // COMPONENT-SPECIFIC COLORS
161
+ // =============================================================================
162
+ buttonPrimary: '{{PRIMARY_COLOR}}',
163
+ buttonSecondary: '{{SECONDARY_COLOR}}',
164
+
165
+ inputBackground: '{{SURFACE_COLOR}}',
166
+ inputBorder: '{{BORDER_COLOR}}',
167
+
168
+ cardBackground: '{{SURFACE_COLOR}}',
169
+
170
+ // =============================================================================
171
+ // SPECIAL COLORS
172
+ // =============================================================================
173
+ transparent: 'transparent',
174
+ black: '#000000',
175
+ white: '#FFFFFF',
176
+
177
+ // =============================================================================
178
+ // RGBA OVERLAY COLORS (for modals, cards, etc.)
179
+ // =============================================================================
180
+ modalOverlay: 'rgba(0, 0, 0, 0.5)',
181
+ overlaySubtle: 'rgba(0, 0, 0, 0.05)',
182
+ overlayLight: 'rgba(0, 0, 0, 0.1)',
183
+ overlayMedium: 'rgba(0, 0, 0, 0.3)',
184
+ overlayBackground: 'rgba(0, 0, 0, 0.05)',
185
+
186
+ whiteOverlay: 'rgba(255, 255, 255, 0.2)',
187
+ whiteOverlayStrong: 'rgba(255, 255, 255, 0.95)',
188
+ whiteOverlayBorder: 'rgba(255, 255, 255, 0.5)',
189
+
190
+ textWhiteOpacity: 'rgba(255, 255, 255, 0.8)',
191
+
192
+ errorBackground: 'rgba(239, 68, 68, 0.1)',
193
+ primaryBackground: 'rgba(99, 102, 241, 0.1)',
194
+
195
+ cardOverlay: 'rgba(0, 0, 0, 0.15)',
196
+
197
+ inputBackground_RGBA: 'rgba(248, 250, 252, 0.9)',
198
+
199
+ // =============================================================================
200
+ // SHADOW COLORS - REMOVED (React Native Web incompatibility)
201
+ // NOTE: Use borders and background colors for depth instead
202
+ // =============================================================================
203
+
204
+ // =============================================================================
205
+ // GRADIENTS
206
+ // =============================================================================
207
+ gradient: ['{{PRIMARY_COLOR}}', '{{SECONDARY_COLOR}}'],
208
+ };
209
+
210
+ // =============================================================================
211
+ // DARK THEME COLORS
212
+ // =============================================================================
213
+
214
+ export const darkColors = {
215
+ // =============================================================================
216
+ // PRIMARY BRAND COLORS (dark mode specific colors)
217
+ // =============================================================================
218
+ primary: '{{PRIMARY_COLOR}}',
219
+ primaryLight: '{{PRIMARY_LIGHT_COLOR}}',
220
+ primaryDark: '{{PRIMARY_DARK_COLOR}}',
221
+
222
+ secondary: '{{SECONDARY_COLOR}}',
223
+ secondaryLight: '{{SECONDARY_LIGHT_COLOR}}',
224
+ secondaryDark: '{{SECONDARY_DARK_COLOR}}',
225
+
226
+ accent: '{{ACCENT_COLOR}}',
227
+ accentLight: '{{ACCENT_LIGHT_COLOR}}',
228
+ accentDark: '{{ACCENT_DARK_COLOR}}',
229
+
230
+ // =============================================================================
231
+ // MATERIAL DESIGN 3 - ON COLORS (Same as light mode for type consistency)
232
+ // =============================================================================
233
+ onPrimary: '#FFFFFF', // Text on primary background (consistent)
234
+ onSecondary: '#FFFFFF', // Text on secondary background (consistent)
235
+ onSuccess: '#FFFFFF', // Text on success background
236
+ onError: '#FFFFFF', // Text on error background
237
+ onWarning: '#000000', // Text on warning background
238
+ onInfo: '#FFFFFF', // Text on info background
239
+ onSurface: '#1E293B', // Text on surface (same as light mode for type consistency)
240
+ onBackground: '#1E293B', // Text on background (same as light mode for type consistency)
241
+ onSurfaceDisabled: '#CBD5E1', // Disabled text color (same as light mode for type consistency)
242
+
243
+ // =============================================================================
244
+ // MATERIAL DESIGN 3 - CONTAINER COLORS (Same as light mode for type consistency)
245
+ // =============================================================================
246
+ primaryContainer: '#DBEAFE', // Same as light mode for type consistency
247
+ onPrimaryContainer: '#1E40AF', // Same as light mode for type consistency
248
+ secondaryContainer: '#E0E7FF', // Same as light mode for type consistency
249
+ onSecondaryContainer: '#3730A3', // Same as light mode for type consistency
250
+ errorContainer: '#FEE2E2', // Same as light mode for type consistency
251
+ onErrorContainer: '#991B1B', // Same as light mode for type consistency
252
+
253
+ // =============================================================================
254
+ // MATERIAL DESIGN 3 - OUTLINE (Same as light mode for type consistency)
255
+ // =============================================================================
256
+ outline: '#CBD5E1', // Same as light mode for type consistency
257
+ outlineVariant: '#E2E8F0', // Same as light mode for type consistency
258
+ outlineDisabled: '#E2E8F0', // Same as light mode for type consistency
259
+
260
+ // =============================================================================
261
+ // SEMANTIC UI COLORS (same as light)
262
+ // =============================================================================
263
+ success: '#10B981',
264
+ successLight: '#34D399',
265
+ successDark: '#059669',
266
+
267
+ error: '#EF4444',
268
+ errorLight: '#F87171',
269
+ errorDark: '#DC2626',
270
+
271
+ warning: '#F59E0B',
272
+ warningLight: '#FBBF24',
273
+ warningDark: '#D97706',
274
+
275
+ info: '#3B82F6',
276
+ infoLight: '#60A5FA',
277
+ infoDark: '#2563EB',
278
+
279
+ // =============================================================================
280
+ // SEMANTIC CONTAINER COLORS (Same as light mode for type consistency)
281
+ // =============================================================================
282
+ successContainer: '#D1FAE5', // Same as light mode for type consistency
283
+ onSuccessContainer: '#065F46', // Same as light mode for type consistency
284
+ warningContainer: '#FEF3C7', // Same as light mode for type consistency
285
+ onWarningContainer: '#92400E', // Same as light mode for type consistency
286
+ infoContainer: '#DBEAFE', // Same as light mode for type consistency
287
+ onInfoContainer: '#1E40AF', // Same as light mode for type consistency
288
+
289
+ // =============================================================================
290
+ // GRAYSCALE PALETTE (Same as light mode for type consistency)
291
+ // =============================================================================
292
+ gray50: '#FAFAFA',
293
+ gray100: '#F4F4F5',
294
+ gray200: '#E4E4E7',
295
+ gray300: '#D4D4D8',
296
+ gray400: '#A1A1AA',
297
+ gray500: '#71717A',
298
+ gray600: '#52525B',
299
+ gray700: '#3F3F46',
300
+ gray800: '#27272A',
301
+ gray900: '#18181B',
302
+
303
+ // =============================================================================
304
+ // BACKGROUND COLORS (dark mode specific colors)
305
+ // =============================================================================
306
+ backgroundPrimary: '{{BACKGROUND_COLOR}}',
307
+ backgroundSecondary: '{{BACKGROUND_SECONDARY_COLOR}}',
308
+
309
+ surface: '{{SURFACE_COLOR}}',
310
+ surfaceVariant: '{{SURFACE_SECONDARY_COLOR}}',
311
+ surfaceSecondary: '{{SURFACE_SECONDARY_COLOR}}', // Alias
312
+ surfaceDisabled: '#F4F4F5', // Same as light mode for type consistency
313
+
314
+ // =============================================================================
315
+ // TEXT COLORS (same as light mode for type consistency)
316
+ // =============================================================================
317
+ textPrimary: '{{TEXT_PRIMARY_COLOR}}',
318
+ textSecondary: '{{TEXT_SECONDARY_COLOR}}',
319
+ textTertiary: '{{TEXT_TERTIARY_COLOR}}',
320
+ textDisabled: '{{TEXT_DISABLED_COLOR}}',
321
+ textInverse: '{{TEXT_INVERSE_COLOR}}',
322
+
323
+ // =============================================================================
324
+ // BORDER COLORS (same as light mode for type consistency)
325
+ // =============================================================================
326
+ border: '{{BORDER_COLOR}}',
327
+ borderLight: '{{BORDER_LIGHT_COLOR}}',
328
+ borderMedium: '{{BORDER_MEDIUM_COLOR}}',
329
+ borderFocus: '{{BORDER_FOCUS_COLOR}}',
330
+
331
+ // =============================================================================
332
+ // COMPONENT-SPECIFIC COLORS (same as light mode for type consistency)
333
+ // =============================================================================
334
+ buttonPrimary: '{{PRIMARY_COLOR}}',
335
+ buttonSecondary: '{{SECONDARY_COLOR}}',
336
+
337
+ inputBackground: '{{SURFACE_COLOR}}',
338
+ inputBorder: '{{BORDER_COLOR}}',
339
+
340
+ cardBackground: '{{SURFACE_COLOR}}',
341
+
342
+ // =============================================================================
343
+ // SPECIAL COLORS
344
+ // =============================================================================
345
+ transparent: 'transparent',
346
+ black: '#000000',
347
+ white: '#FFFFFF',
348
+
349
+ // =============================================================================
350
+ // RGBA OVERLAY COLORS (Same as light mode for type consistency)
351
+ // =============================================================================
352
+ modalOverlay: 'rgba(0, 0, 0, 0.5)',
353
+ overlaySubtle: 'rgba(0, 0, 0, 0.05)',
354
+ overlayLight: 'rgba(0, 0, 0, 0.1)',
355
+ overlayMedium: 'rgba(0, 0, 0, 0.3)',
356
+ overlayBackground: 'rgba(0, 0, 0, 0.05)',
357
+
358
+ whiteOverlay: 'rgba(255, 255, 255, 0.2)',
359
+ whiteOverlayStrong: 'rgba(255, 255, 255, 0.95)',
360
+ whiteOverlayBorder: 'rgba(255, 255, 255, 0.5)',
361
+
362
+ textWhiteOpacity: 'rgba(255, 255, 255, 0.8)',
363
+
364
+ errorBackground: 'rgba(239, 68, 68, 0.1)',
365
+ primaryBackground: 'rgba(99, 102, 241, 0.1)',
366
+
367
+ cardOverlay: 'rgba(0, 0, 0, 0.15)',
368
+
369
+ inputBackground_RGBA: 'rgba(248, 250, 252, 0.9)',
370
+
371
+ // =============================================================================
372
+ // SHADOW COLORS (Same as light mode for type consistency)
373
+ // =============================================================================
374
+ // SHADOW COLORS - REMOVED (React Native Web incompatibility)
375
+ // NOTE: Use borders and background colors for depth instead
376
+ // =============================================================================
377
+
378
+ // =============================================================================
379
+ // GRADIENTS (Same as light mode for type consistency)
380
+ // =============================================================================
381
+ gradient: ['{{PRIMARY_COLOR}}', '{{SECONDARY_COLOR}}'],
382
+ };
383
+
384
+ // =============================================================================
385
+ // TYPE EXPORTS
386
+ // =============================================================================
387
+
388
+ export type ColorPalette = typeof lightColors;
389
+ export type ThemeMode = 'light' | 'dark';
390
+
391
+ /**
392
+ * Get color palette for specific theme mode
393
+ * @param mode - 'light' or 'dark'
394
+ * @returns Color palette object
395
+ */
396
+ export const getColorPalette = (mode: ThemeMode): ColorPalette => {
397
+ return mode === 'dark' ? darkColors : lightColors;
398
+ };
@@ -0,0 +1,120 @@
1
+ /**
2
+ * TOKEN FACTORY - THEME INJECTION LOGIC
3
+ *
4
+ * ✅ Factory Pattern for creating complete design tokens
5
+ * ✅ Combines static tokens (BaseTokens) + dynamic colors (ColorPalette)
6
+ * ✅ Type-safe token generation
7
+ * ✅ Zero duplication - SINGLE SOURCE OF TRUTH
8
+ *
9
+ * @module TokenFactory
10
+ */
11
+
12
+ import { BASE_TOKENS } from './BaseTokens';
13
+ import { getColorPalette, withAlpha, type ThemeMode, type ColorPalette } from './ColorPalette';
14
+
15
+ // =============================================================================
16
+ // DESIGN TOKENS TYPE
17
+ // =============================================================================
18
+
19
+ /**
20
+ * Complete design tokens shape
21
+ * Combines static tokens (spacing, typography, animations, borders) + dynamic colors
22
+ */
23
+ export type DesignTokens = {
24
+ colors: ColorPalette;
25
+ spacing: typeof BASE_TOKENS.spacing;
26
+ typography: typeof BASE_TOKENS.typography;
27
+ animations: typeof BASE_TOKENS.animations;
28
+ iconSizes: typeof BASE_TOKENS.iconSizes;
29
+ opacity: typeof BASE_TOKENS.opacity;
30
+ avatarSizes: typeof BASE_TOKENS.avatarSizes;
31
+ borders: typeof BASE_TOKENS.borders & {
32
+ card: typeof BASE_TOKENS.borders.card & { borderColor: string };
33
+ input: typeof BASE_TOKENS.borders.input & { borderColor: string };
34
+ };
35
+ };
36
+
37
+ // =============================================================================
38
+ // TOKEN FACTORY FUNCTION
39
+ // =============================================================================
40
+
41
+ /**
42
+ * Create complete design tokens for a specific theme mode
43
+ *
44
+ * @param mode - Theme mode ('light' or 'dark')
45
+ * @returns Complete design tokens object
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * const lightTokens = createDesignTokens('light');
50
+ * const darkTokens = createDesignTokens('dark');
51
+ *
52
+ * // Use in components
53
+ * <View style={{ backgroundColor: lightTokens.colors.primary }}>
54
+ * <Text style={lightTokens.typography.bodyLarge}>Hello!</Text>
55
+ * </View>
56
+ * ```
57
+ */
58
+ export const createDesignTokens = (mode: ThemeMode): DesignTokens => {
59
+ // Get color palette for theme mode
60
+ const colors = getColorPalette(mode);
61
+
62
+ // Combine static tokens + dynamic colors
63
+ return {
64
+ // ✅ DYNAMIC: Colors from theme mode
65
+ colors,
66
+
67
+ // ✅ STATIC: These don't change with theme
68
+ spacing: BASE_TOKENS.spacing,
69
+ typography: BASE_TOKENS.typography,
70
+ animations: BASE_TOKENS.animations,
71
+ iconSizes: BASE_TOKENS.iconSizes,
72
+ opacity: BASE_TOKENS.opacity,
73
+ avatarSizes: BASE_TOKENS.avatarSizes,
74
+
75
+ // ✅ BORDERS: Static + injected border colors from theme
76
+ borders: {
77
+ ...BASE_TOKENS.borders,
78
+ card: {
79
+ ...BASE_TOKENS.borders.card,
80
+ borderColor: colors.border,
81
+ },
82
+ input: {
83
+ ...BASE_TOKENS.borders.input,
84
+ borderColor: colors.border,
85
+ },
86
+ },
87
+ };
88
+ };
89
+
90
+ // =============================================================================
91
+ // STATIC TOKEN INSTANCES (for non-React contexts)
92
+ // =============================================================================
93
+
94
+ /**
95
+ * STATIC DESIGN TOKENS - LIGHT THEME ONLY
96
+ *
97
+ * ⚠️ WARNING: These are STATIC and use light theme colors only!
98
+ * ⚠️ DO NOT USE in React components - use useAppDesignTokens() hook instead
99
+ *
100
+ * Only use these in:
101
+ * - Utility functions
102
+ * - Constants files
103
+ * - Non-React JavaScript code
104
+ *
105
+ * @deprecated Use useAppDesignTokens() hook in React components
106
+ */
107
+ export const STATIC_DESIGN_TOKENS = createDesignTokens('light');
108
+
109
+ /**
110
+ * STATIC TOKENS (spacing, typography, animations, borders)
111
+ * These DON'T change with theme - safe to use anywhere
112
+ */
113
+ export const STATIC_TOKENS = BASE_TOKENS;
114
+
115
+ // =============================================================================
116
+ // UTILITY EXPORTS
117
+ // =============================================================================
118
+
119
+ export { withAlpha };
120
+ export type { ThemeMode, ColorPalette };
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Platform-Specific Constants
3
+ *
4
+ * Design system constants that ensure compliance with platform guidelines.
5
+ * These values are based on official Human Interface Guidelines (HIG) from Apple and Material Design from Google.
6
+ */
7
+
8
+ /**
9
+ * iOS Human Interface Guidelines (HIG) Constants
10
+ *
11
+ * @see https://developer.apple.com/design/human-interface-guidelines/layout
12
+ */
13
+ export const IOS_HIG = {
14
+ /**
15
+ * Minimum Touch Target Size
16
+ *
17
+ * Apple requires a minimum tappable area of 44pt x 44pt for ALL interactive controls.
18
+ * This is enforced during App Store review.
19
+ *
20
+ * @critical Violating this can result in App Store rejection
21
+ */
22
+ MIN_TOUCH_TARGET: 44,
23
+
24
+ /**
25
+ * Recommended Minimum Touch Target Size
26
+ *
27
+ * For better accessibility and usability, Apple recommends 48pt x 48pt.
28
+ */
29
+ RECOMMENDED_TOUCH_TARGET: 48,
30
+
31
+ /**
32
+ * Minimum Text Size
33
+ *
34
+ * Minimum font size for body text to ensure readability.
35
+ */
36
+ MIN_TEXT_SIZE: 17,
37
+
38
+ /**
39
+ * Minimum Contrast Ratio
40
+ *
41
+ * WCAG AA compliance requires 4.5:1 for normal text.
42
+ */
43
+ MIN_CONTRAST_RATIO: 4.5,
44
+ } as const;
45
+
46
+ /**
47
+ * Android Material Design Guidelines Constants
48
+ *
49
+ * @see https://m3.material.io/foundations/layout/applying-layout/window-size-classes
50
+ */
51
+ export const ANDROID_MATERIAL = {
52
+ /**
53
+ * Minimum Touch Target Size
54
+ *
55
+ * Material Design 3 recommends a minimum of 48dp x 48dp.
56
+ */
57
+ MIN_TOUCH_TARGET: 48,
58
+
59
+ /**
60
+ * Minimum Text Size
61
+ *
62
+ * Minimum font size for body text.
63
+ */
64
+ MIN_TEXT_SIZE: 14,
65
+ } as const;
66
+
67
+ /**
68
+ * Universal Platform Constants
69
+ *
70
+ * These values work across both iOS and Android, taking the more restrictive requirement.
71
+ */
72
+ export const PLATFORM_CONSTANTS = {
73
+ /**
74
+ * Minimum Touch Target Size
75
+ *
76
+ * Uses iOS requirement (44pt) as it's more restrictive than Android (48dp).
77
+ * This ensures compliance on both platforms.
78
+ */
79
+ MIN_TOUCH_TARGET: Math.max(IOS_HIG.MIN_TOUCH_TARGET, ANDROID_MATERIAL.MIN_TOUCH_TARGET),
80
+
81
+ /**
82
+ * Recommended Touch Target Size
83
+ *
84
+ * Uses the higher value between iOS and Android recommendations.
85
+ */
86
+ RECOMMENDED_TOUCH_TARGET: 48,
87
+
88
+ /**
89
+ * Minimum Text Size
90
+ *
91
+ * Uses iOS requirement as it's larger.
92
+ */
93
+ MIN_TEXT_SIZE: Math.max(IOS_HIG.MIN_TEXT_SIZE, ANDROID_MATERIAL.MIN_TEXT_SIZE),
94
+ } as const;
95
+
96
+ /**
97
+ * Helper function to validate touch target size
98
+ *
99
+ * @param size - The size to validate (in pt/dp)
100
+ * @returns true if size meets platform requirements
101
+ */
102
+ export const isValidTouchTarget = (size: number): boolean => {
103
+ return size >= IOS_HIG.MIN_TOUCH_TARGET;
104
+ };
105
+
106
+ /**
107
+ * Helper function to get minimum touch target for component
108
+ *
109
+ * @param componentType - The type of component ('button' | 'input' | 'icon' | 'generic')
110
+ * @returns The minimum touch target size for that component type
111
+ */
112
+ export const getMinTouchTarget = (componentType: 'button' | 'input' | 'icon' | 'generic' = 'generic'): number => {
113
+ switch (componentType) {
114
+ case 'button':
115
+ return PLATFORM_CONSTANTS.RECOMMENDED_TOUCH_TARGET; // 48pt recommended for buttons
116
+ case 'input':
117
+ return PLATFORM_CONSTANTS.RECOMMENDED_TOUCH_TARGET; // 48pt recommended for inputs
118
+ case 'icon':
119
+ return IOS_HIG.MIN_TOUCH_TARGET; // 44pt minimum for icon buttons
120
+ case 'generic':
121
+ default:
122
+ return IOS_HIG.MIN_TOUCH_TARGET; // 44pt minimum for all other interactive elements
123
+ }
124
+ };