@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.
- package/LICENSE +21 -0
- package/README.md +157 -0
- package/package.json +43 -0
- package/src/index.ts +345 -0
- package/src/presentation/atoms/AtomicAvatar.tsx +157 -0
- package/src/presentation/atoms/AtomicAvatarGroup.tsx +169 -0
- package/src/presentation/atoms/AtomicBadge.tsx +232 -0
- package/src/presentation/atoms/AtomicButton.tsx +124 -0
- package/src/presentation/atoms/AtomicCard.tsx +112 -0
- package/src/presentation/atoms/AtomicChip.tsx +223 -0
- package/src/presentation/atoms/AtomicDatePicker.tsx +347 -0
- package/src/presentation/atoms/AtomicDivider.tsx +114 -0
- package/src/presentation/atoms/AtomicFab.tsx +104 -0
- package/src/presentation/atoms/AtomicFilter.tsx +154 -0
- package/src/presentation/atoms/AtomicFormError.tsx +105 -0
- package/src/presentation/atoms/AtomicIcon.tsx +29 -0
- package/src/presentation/atoms/AtomicImage.tsx +149 -0
- package/src/presentation/atoms/AtomicInput.tsx +232 -0
- package/src/presentation/atoms/AtomicNumberInput.tsx +182 -0
- package/src/presentation/atoms/AtomicPicker.tsx +458 -0
- package/src/presentation/atoms/AtomicProgress.tsx +143 -0
- package/src/presentation/atoms/AtomicSearchBar.tsx +114 -0
- package/src/presentation/atoms/AtomicSkeleton.tsx +146 -0
- package/src/presentation/atoms/AtomicSort.tsx +145 -0
- package/src/presentation/atoms/AtomicSwitch.tsx +166 -0
- package/src/presentation/atoms/AtomicText.tsx +50 -0
- package/src/presentation/atoms/AtomicTextArea.tsx +198 -0
- package/src/presentation/atoms/AtomicTouchable.tsx +233 -0
- package/src/presentation/atoms/fab/styles/fabStyles.ts +69 -0
- package/src/presentation/atoms/fab/types/index.ts +88 -0
- package/src/presentation/atoms/filter/styles/filterStyles.ts +32 -0
- package/src/presentation/atoms/filter/types/index.ts +89 -0
- package/src/presentation/atoms/index.ts +378 -0
- package/src/presentation/atoms/input/hooks/useInputState.ts +15 -0
- package/src/presentation/atoms/input/styles/inputStyles.ts +66 -0
- package/src/presentation/atoms/input/types/index.ts +25 -0
- package/src/presentation/atoms/picker/styles/pickerStyles.ts +200 -0
- package/src/presentation/atoms/picker/types/index.ts +40 -0
- package/src/presentation/atoms/touchable/styles/touchableStyles.ts +71 -0
- package/src/presentation/atoms/touchable/types/index.ts +162 -0
- package/src/presentation/hooks/useAppDesignTokens.ts +78 -0
- package/src/presentation/hooks/useResponsive.ts +180 -0
- package/src/presentation/loading/index.ts +40 -0
- package/src/presentation/loading/presentation/components/LoadingSpinner.tsx +116 -0
- package/src/presentation/loading/presentation/components/LoadingState.tsx +200 -0
- package/src/presentation/loading/presentation/hooks/useLoading.ts +100 -0
- package/src/presentation/molecules/AtomicConfirmationModal.tsx +263 -0
- package/src/presentation/molecules/EmptyState.tsx +130 -0
- package/src/presentation/molecules/FormField.tsx +128 -0
- package/src/presentation/molecules/GridContainer.tsx +124 -0
- package/src/presentation/molecules/IconContainer.tsx +94 -0
- package/src/presentation/molecules/LanguageSwitcher.tsx +42 -0
- package/src/presentation/molecules/ListItem.tsx +36 -0
- package/src/presentation/molecules/ScreenHeader.tsx +140 -0
- package/src/presentation/molecules/SearchBar.tsx +85 -0
- package/src/presentation/molecules/SectionCard.tsx +74 -0
- package/src/presentation/molecules/SectionContainer.tsx +106 -0
- package/src/presentation/molecules/SectionHeader.tsx +125 -0
- package/src/presentation/molecules/confirmation-modal/styles/confirmationModalStyles.ts +133 -0
- package/src/presentation/molecules/confirmation-modal/types/index.ts +107 -0
- package/src/presentation/molecules/index.ts +42 -0
- package/src/presentation/molecules/languageswitcher/config/languageSwitcherConfig.ts +5 -0
- package/src/presentation/molecules/languageswitcher/hooks/useLanguageNavigation.ts +15 -0
- package/src/presentation/molecules/listitem/styles/listItemStyles.ts +19 -0
- package/src/presentation/molecules/listitem/types/index.ts +17 -0
- package/src/presentation/organisms/AppHeader.tsx +136 -0
- package/src/presentation/organisms/FormContainer.tsx +180 -0
- package/src/presentation/organisms/ScreenLayout.tsx +209 -0
- package/src/presentation/organisms/index.ts +25 -0
- package/src/presentation/tokens/AppDesignTokens.ts +57 -0
- package/src/presentation/tokens/commonStyles.ts +253 -0
- package/src/presentation/tokens/core/BaseTokens.ts +394 -0
- package/src/presentation/tokens/core/ColorPalette.ts +398 -0
- package/src/presentation/tokens/core/TokenFactory.ts +120 -0
- package/src/presentation/utils/platformConstants.ts +124 -0
- package/src/presentation/utils/responsive.ts +516 -0
- package/src/presentation/utils/variants/compound.ts +29 -0
- package/src/presentation/utils/variants/core.ts +39 -0
- package/src/presentation/utils/variants/helpers.ts +13 -0
- 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
|
+
};
|