@umituz/react-native-design-system 2.11.2 → 2.11.4

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 (55) hide show
  1. package/package.json +1 -1
  2. package/src/atoms/AtomicFab.tsx +1 -1
  3. package/src/atoms/EmptyState.tsx +1 -1
  4. package/src/atoms/{AtomicBadge.tsx → badge/AtomicBadge.tsx} +3 -3
  5. package/src/atoms/badge/index.ts +6 -0
  6. package/src/atoms/button/AtomicButton.tsx +1 -1
  7. package/src/atoms/button/types/index.ts +1 -1
  8. package/src/atoms/card/AtomicCard.tsx +3 -2
  9. package/src/atoms/chip/AtomicChip.tsx +1 -1
  10. package/src/atoms/chip/types/index.ts +1 -1
  11. package/src/atoms/datepicker/components/DatePickerButton.tsx +3 -2
  12. package/src/atoms/{AtomicIcon.tsx → icon/AtomicIcon.tsx} +2 -2
  13. package/src/atoms/icon/iconStore.ts +119 -0
  14. package/src/atoms/icon/index.ts +35 -0
  15. package/src/atoms/index.ts +14 -9
  16. package/src/atoms/input/components/InputIcon.tsx +1 -1
  17. package/src/atoms/input/types.ts +1 -1
  18. package/src/atoms/picker/components/PickerChips.tsx +3 -2
  19. package/src/atoms/picker/components/PickerIcons.tsx +6 -3
  20. package/src/atoms/picker/components/PickerModal.tsx +10 -6
  21. package/src/atoms/picker/types/index.ts +1 -1
  22. package/src/exception/presentation/components/ExceptionErrorState.tsx +7 -3
  23. package/src/exports/atoms.ts +6 -3
  24. package/src/image/presentation/components/editor/FilterPickerSheet.tsx +6 -5
  25. package/src/image/presentation/components/editor/TextEditorSheet.tsx +1 -1
  26. package/src/image/presentation/components/editor/TextEditorTabs.tsx +1 -2
  27. package/src/media/infrastructure/services/MediaSaveService.ts +1 -2
  28. package/src/molecules/SearchBar/SearchBar.tsx +5 -3
  29. package/src/molecules/SearchBar/SearchHistory.tsx +5 -3
  30. package/src/molecules/action-footer/ActionFooter.tsx +1 -1
  31. package/src/molecules/alerts/AlertBanner.tsx +3 -2
  32. package/src/molecules/alerts/AlertToast.tsx +3 -2
  33. package/src/molecules/bottom-sheet/components/filter/FilterBottomSheet.tsx +5 -3
  34. package/src/molecules/bottom-sheet/components/filter/FilterSheetComponents/FilterSheetHeader.tsx +13 -9
  35. package/src/molecules/bottom-sheet/components/filter/FilterSheetComponents/FilterSheetOption.tsx +8 -4
  36. package/src/molecules/circular-menu/CircularMenuCloseButton.tsx +3 -2
  37. package/src/molecules/countdown/components/Countdown.tsx +1 -1
  38. package/src/molecules/countdown/components/CountdownHeader.tsx +4 -3
  39. package/src/molecules/info-grid/InfoGrid.tsx +1 -1
  40. package/src/molecules/navigation/components/NavigationHeader.tsx +3 -2
  41. package/src/molecules/navigation/hooks/useTabConfig.ts +1 -1
  42. package/src/molecules/navigation/types.ts +1 -1
  43. package/src/molecules/navigation/utils/IconRenderer.ts +1 -2
  44. package/src/onboarding/presentation/components/OnboardingHeader.tsx +3 -2
  45. package/src/onboarding/presentation/components/OnboardingResetSetting.tsx +1 -2
  46. package/src/onboarding/presentation/components/OnboardingSlide.tsx +3 -2
  47. package/src/onboarding/presentation/components/QuestionSlideHeader.tsx +1 -2
  48. package/src/onboarding/presentation/components/questions/QuestionOptionItem.tsx +1 -2
  49. package/src/onboarding/presentation/components/questions/RatingQuestion.tsx +1 -2
  50. package/src/onboarding/presentation/components/questions/SingleChoiceQuestion.tsx +1 -2
  51. package/src/theme/core/TokenFactory.ts +1 -1
  52. package/src/theme/index.ts +1 -1
  53. package/src/theme/infrastructure/providers/DesignSystemProvider.tsx +15 -85
  54. package/src/atoms/IconRegistry.tsx +0 -102
  55. /package/src/atoms/{AtomicIcon.types.ts → icon/AtomicIcon.types.ts} +0 -0
@@ -8,71 +8,29 @@ import { useDesignSystemTheme, type ThemeMode } from '../globalThemeStore';
8
8
  import type { CustomThemeColors } from '../../core/CustomColors';
9
9
  import { SplashScreen } from '../../../molecules/splash';
10
10
  import type { SplashScreenProps } from '../../../molecules/splash/types';
11
- import { IconProvider, type IconRenderer } from '../../../atoms/IconRegistry';
11
+ import { useIconStore, type IconRenderer, type IconNames } from '../../../atoms/icon';
12
12
 
13
13
 
14
14
  interface DesignSystemProviderProps {
15
- /** App content */
16
15
  children: ReactNode;
17
- /**
18
- * Custom theme colors to override defaults
19
- * Apps can override ANY color key from the palette
20
- * @example
21
- * customColors={{
22
- * primary: '#FF6B6B',
23
- * onPrimary: '#FFFFFF',
24
- * backgroundPrimary: '#FFFFFF',
25
- * textPrimary: '#1A1A1A',
26
- * }}
27
- */
28
16
  customColors?: CustomThemeColors;
29
- /**
30
- * Initial theme mode for the app
31
- * Apps control whether they start in light or dark mode
32
- * @default 'light'
33
- */
34
17
  initialThemeMode?: ThemeMode;
35
- /** Custom fonts to load (name -> source map) */
36
18
  fonts?: Record<string, any>;
37
- /** Show loading indicator while initializing (default: true) */
38
19
  showLoadingIndicator?: boolean;
39
- /** Splash screen configuration (used when showLoadingIndicator is true) */
40
20
  splashConfig?: Pick<SplashScreenProps, 'appName' | 'tagline' | 'icon' | 'colors'>;
41
- /** Custom loading component (overrides splash screen) */
42
21
  loadingComponent?: ReactNode;
43
- /** Callback when initialization completes */
44
22
  onInitialized?: () => void;
45
- /** Callback when initialization fails */
46
23
  onError?: (error: unknown) => void;
47
- /**
48
- * Custom icon renderer function
49
- * Allows apps to use their own icon library
50
- * @example
51
- * iconRenderer={({ name, size, color }) => (
52
- * <LucideIcons name={name} size={size} color={color} />
53
- * )}
54
- */
55
- iconRenderer?: IconRenderer;
24
+ /** Icon renderer - REQUIRED */
25
+ iconRenderer: IconRenderer;
26
+ /** Icon names mapping - REQUIRED */
27
+ iconNames: IconNames;
56
28
  }
57
29
 
58
- /**
59
- * DesignSystemProvider
60
- *
61
- * Main provider for the design system. Wraps your app and provides:
62
- * - Theme (colors, spacing, typography)
63
- * - Custom icon rendering
64
- * - Safe area handling
65
- * - Gesture handling
66
- *
67
- * ARCHITECTURE (based on Shopify Restyle, React Native Paper, Tamagui):
68
- * - Apps provide customColors to override default palette
69
- * - Apps set initialThemeMode to control light/dark mode
70
- * - All design system components use these values via useAppDesignTokens
71
- */
72
30
  export const DesignSystemProvider: React.FC<DesignSystemProviderProps> = ({
73
31
  children,
74
32
  customColors,
75
- initialThemeMode = 'light', // Default to light mode (most common)
33
+ initialThemeMode = 'light',
76
34
  fonts,
77
35
  showLoadingIndicator = true,
78
36
  splashConfig,
@@ -80,75 +38,54 @@ export const DesignSystemProvider: React.FC<DesignSystemProviderProps> = ({
80
38
  onInitialized,
81
39
  onError,
82
40
  iconRenderer,
83
- }: DesignSystemProviderProps) => {
41
+ iconNames,
42
+ }) => {
84
43
  const [isInitialized, setIsInitialized] = useState(false);
85
-
86
- // Load fonts if provided
87
44
  const [fontsLoaded, fontError] = fonts ? useFonts(fonts) : [true, null];
88
45
 
89
46
  const initialize = useThemeStore((state) => state.initialize);
90
47
  const setThemeMode = useThemeStore((state) => state.setThemeMode);
91
48
  const setCustomColors = useDesignSystemTheme((state) => state.setCustomColors);
92
49
  const setGlobalThemeMode = useDesignSystemTheme((state) => state.setThemeMode);
50
+ const setIconConfig = useIconStore((state) => state.setConfig);
93
51
 
94
52
  useEffect(() => {
95
- // WARN: customColors is required for proper theming
96
- if (__DEV__ && !customColors) {
97
- console.warn(
98
- '[DesignSystem] ⚠️ customColors is REQUIRED!\n' +
99
- 'Your app must provide theme colors to DesignSystemProvider.\n' +
100
- 'Example:\n' +
101
- '<DesignSystemProvider\n' +
102
- ' customColors={{\n' +
103
- ' primary: "#FF6B6B",\n' +
104
- ' onPrimary: "#FFFFFF",\n' +
105
- ' backgroundPrimary: "#FFFFFF",\n' +
106
- ' textPrimary: "#1A1A1A",\n' +
107
- ' }}\n' +
108
- ' initialThemeMode="light"\n' +
109
- '>'
110
- );
53
+ // Set icon config (required)
54
+ if (iconRenderer && iconNames) {
55
+ setIconConfig(iconNames, iconRenderer);
111
56
  }
112
57
 
113
- // Apply custom colors if provided
114
58
  if (customColors) {
115
59
  setCustomColors(customColors);
116
60
  }
117
61
 
118
- // Set initial theme mode from app
119
62
  setGlobalThemeMode(initialThemeMode);
120
63
 
121
- // Initialize theme store with the initial theme mode
122
64
  initialize()
123
65
  .then(async () => {
124
- // After initialization, set the theme mode from app config
125
66
  await setThemeMode(initialThemeMode);
126
67
  setIsInitialized(true);
127
68
  })
128
69
  .catch((error) => {
129
- setIsInitialized(true); // Still render app even on error
70
+ setIsInitialized(true);
130
71
  onError?.(error);
131
72
  });
132
- }, [initialize, customColors, initialThemeMode, setCustomColors, setGlobalThemeMode, setThemeMode, onError]);
73
+ }, [initialize, customColors, iconNames, iconRenderer, initialThemeMode, setCustomColors, setGlobalThemeMode, setThemeMode, setIconConfig, onError]);
133
74
 
134
- // Handle initialization completion when both theme and fonts are ready
135
75
  useEffect(() => {
136
76
  if (isInitialized && fontsLoaded) {
137
77
  onInitialized?.();
138
78
  }
139
79
  }, [isInitialized, fontsLoaded, onInitialized]);
140
80
 
141
- // Handle font errors
142
81
  useEffect(() => {
143
82
  if (fontError) {
144
83
  onError?.(fontError);
145
84
  }
146
85
  }, [fontError, onError]);
147
86
 
148
- // Determine if we should show loading state
149
87
  const isLoading = showLoadingIndicator && (!isInitialized || !fontsLoaded);
150
88
 
151
- // Determine content to render based on loading state
152
89
  let content: ReactNode;
153
90
 
154
91
  if (isLoading) {
@@ -167,17 +104,10 @@ export const DesignSystemProvider: React.FC<DesignSystemProviderProps> = ({
167
104
  content = children;
168
105
  }
169
106
 
170
- // Wrap with IconProvider if custom renderer provided
171
- const wrappedContent = iconRenderer ? (
172
- <IconProvider renderIcon={iconRenderer}>{content}</IconProvider>
173
- ) : (
174
- content
175
- );
176
-
177
107
  return (
178
108
  <GestureHandlerRootView style={{ flex: 1 }}>
179
109
  <SafeAreaProvider initialMetrics={initialWindowMetrics}>
180
- {wrappedContent}
110
+ {content}
181
111
  </SafeAreaProvider>
182
112
  </GestureHandlerRootView>
183
113
  );
@@ -1,102 +0,0 @@
1
- /**
2
- * IconRegistry - Customizable Icon Rendering
3
- *
4
- * Allows apps to inject their own icon renderer instead of using
5
- * the default Ionicons. This enables design system adoption without
6
- * forcing a specific icon library.
7
- *
8
- * @example
9
- * // App provides custom renderer
10
- * import { MaterialIcons } from '@expo/vector-icons';
11
- *
12
- * const myRenderer = ({ name, size, color }) => (
13
- * <MaterialIcons name={name} size={size} color={color} />
14
- * );
15
- *
16
- * <DesignSystemProvider iconRenderer={myRenderer}>
17
- * <App />
18
- * </DesignSystemProvider>
19
- */
20
-
21
- import React, { createContext, useContext, ReactNode } from "react";
22
- import type { StyleProp, ViewStyle } from "react-native";
23
-
24
- /**
25
- * Props passed to the icon renderer function
26
- * These are generic and not tied to any specific icon library
27
- */
28
- export interface IconRenderProps {
29
- /** Icon name - app interprets this based on their icon library */
30
- name: string;
31
- /** Size in pixels */
32
- size: number;
33
- /** Color (hex, rgba, named color, etc.) */
34
- color: string;
35
- /** Optional style */
36
- style?: StyleProp<ViewStyle>;
37
- /** Test ID for testing */
38
- testID?: string;
39
- /** Accessibility label */
40
- accessibilityLabel?: string;
41
- }
42
-
43
- /**
44
- * Icon renderer function type
45
- * Apps provide this function to render icons with their preferred library
46
- */
47
- export type IconRenderer = (props: IconRenderProps) => ReactNode;
48
-
49
- /**
50
- * Internal registry store
51
- */
52
- interface IconRegistryValue {
53
- renderIcon: IconRenderer;
54
- }
55
-
56
- const IconRegistryStore = createContext<IconRegistryValue | null>(null);
57
-
58
- /**
59
- * Icon provider props
60
- */
61
- interface IconProviderProps {
62
- /** Icon renderer function */
63
- renderIcon: IconRenderer;
64
- /** Children */
65
- children: ReactNode;
66
- }
67
-
68
- /**
69
- * IconProvider - Provides custom icon renderer to the component tree
70
- *
71
- * @example
72
- * <IconProvider renderIcon={myCustomRenderer}>
73
- * <App />
74
- * </IconProvider>
75
- */
76
- export const IconProvider: React.FC<IconProviderProps> = ({
77
- renderIcon,
78
- children,
79
- }) => {
80
- return (
81
- <IconRegistryStore.Provider value={{ renderIcon }}>
82
- {children}
83
- </IconRegistryStore.Provider>
84
- );
85
- };
86
-
87
- /**
88
- * Hook to access the icon renderer
89
- * Returns null if no custom renderer is provided (fallback to Ionicons)
90
- */
91
- export const useIconRenderer = (): IconRenderer | null => {
92
- const registry = useContext(IconRegistryStore);
93
- return registry?.renderIcon ?? null;
94
- };
95
-
96
- /**
97
- * Hook to check if a custom icon renderer is available
98
- */
99
- export const useHasCustomIconRenderer = (): boolean => {
100
- const registry = useContext(IconRegistryStore);
101
- return registry !== null;
102
- };