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

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 (54) 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/molecules/SearchBar/SearchBar.tsx +5 -3
  28. package/src/molecules/SearchBar/SearchHistory.tsx +5 -3
  29. package/src/molecules/action-footer/ActionFooter.tsx +1 -1
  30. package/src/molecules/alerts/AlertBanner.tsx +3 -2
  31. package/src/molecules/alerts/AlertToast.tsx +3 -2
  32. package/src/molecules/bottom-sheet/components/filter/FilterBottomSheet.tsx +5 -3
  33. package/src/molecules/bottom-sheet/components/filter/FilterSheetComponents/FilterSheetHeader.tsx +13 -9
  34. package/src/molecules/bottom-sheet/components/filter/FilterSheetComponents/FilterSheetOption.tsx +8 -4
  35. package/src/molecules/circular-menu/CircularMenuCloseButton.tsx +3 -2
  36. package/src/molecules/countdown/components/Countdown.tsx +1 -1
  37. package/src/molecules/countdown/components/CountdownHeader.tsx +4 -3
  38. package/src/molecules/info-grid/InfoGrid.tsx +1 -1
  39. package/src/molecules/navigation/components/NavigationHeader.tsx +3 -2
  40. package/src/molecules/navigation/hooks/useTabConfig.ts +1 -1
  41. package/src/molecules/navigation/types.ts +1 -1
  42. package/src/molecules/navigation/utils/IconRenderer.ts +1 -2
  43. package/src/onboarding/presentation/components/OnboardingHeader.tsx +3 -2
  44. package/src/onboarding/presentation/components/OnboardingResetSetting.tsx +1 -2
  45. package/src/onboarding/presentation/components/OnboardingSlide.tsx +3 -2
  46. package/src/onboarding/presentation/components/QuestionSlideHeader.tsx +1 -2
  47. package/src/onboarding/presentation/components/questions/QuestionOptionItem.tsx +1 -2
  48. package/src/onboarding/presentation/components/questions/RatingQuestion.tsx +1 -2
  49. package/src/onboarding/presentation/components/questions/SingleChoiceQuestion.tsx +1 -2
  50. package/src/theme/core/TokenFactory.ts +1 -1
  51. package/src/theme/index.ts +1 -1
  52. package/src/theme/infrastructure/providers/DesignSystemProvider.tsx +15 -85
  53. package/src/atoms/IconRegistry.tsx +0 -102
  54. /package/src/atoms/{AtomicIcon.types.ts → icon/AtomicIcon.types.ts} +0 -0
@@ -5,7 +5,7 @@ import {
5
5
  StyleSheet,
6
6
  } from 'react-native';
7
7
  import { AtomicText } from '../../atoms/AtomicText';
8
- import { AtomicIcon } from '../../atoms/AtomicIcon';
8
+ import { AtomicIcon, useIconName } from '../../atoms';
9
9
  import { useAppDesignTokens } from '../../theme';
10
10
  import type { SearchHistoryProps } from './types';
11
11
 
@@ -20,6 +20,8 @@ export const SearchHistory: React.FC<SearchHistoryProps> = ({
20
20
  clearLabel = 'Clear All',
21
21
  }) => {
22
22
  const tokens = useAppDesignTokens();
23
+ const clockIcon = useIconName('clock');
24
+ const closeIcon = useIconName('close');
23
25
 
24
26
  if (!history || history.length === 0) {
25
27
  return null;
@@ -58,7 +60,7 @@ export const SearchHistory: React.FC<SearchHistoryProps> = ({
58
60
  >
59
61
  <View style={styles.itemLeft}>
60
62
  <AtomicIcon
61
- name="time-outline"
63
+ name={clockIcon}
62
64
  size="sm"
63
65
  customColor={tokens.colors.textSecondary}
64
66
  />
@@ -80,7 +82,7 @@ export const SearchHistory: React.FC<SearchHistoryProps> = ({
80
82
  hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
81
83
  >
82
84
  <AtomicIcon
83
- name="close"
85
+ name={closeIcon}
84
86
  size="sm"
85
87
  customColor={tokens.colors.textSecondary}
86
88
  />
@@ -2,7 +2,7 @@
2
2
  import React from 'react';
3
3
  import { View, StyleSheet, TouchableOpacity } from 'react-native';
4
4
  import { AtomicText } from '../../atoms/AtomicText';
5
- import { AtomicIcon } from '../../atoms/AtomicIcon';
5
+ import { AtomicIcon } from '../../atoms';
6
6
  import { useAppDesignTokens } from '../../theme';
7
7
  import type { ActionFooterProps } from './types';
8
8
 
@@ -9,7 +9,7 @@
9
9
  import React, { useEffect } from 'react';
10
10
  import { StyleSheet, View, Pressable } from 'react-native';
11
11
  import { useSafeAreaInsets } from '../../safe-area';
12
- import { AtomicText, AtomicIcon } from '../../atoms';
12
+ import { AtomicText, AtomicIcon, useIconName } from '../../atoms';
13
13
  import { useAppDesignTokens } from '../../theme';
14
14
  import { Alert, AlertType, AlertPosition } from './AlertTypes';
15
15
  import { useAlertStore } from './AlertStore';
@@ -24,6 +24,7 @@ export function AlertBanner({ alert }: AlertBannerProps) {
24
24
  const dismissAlert = useAlertStore((state: { dismissAlert: (id: string) => void }) => state.dismissAlert);
25
25
  const insets = useSafeAreaInsets();
26
26
  const tokens = useAppDesignTokens();
27
+ const closeIcon = useIconName('close');
27
28
 
28
29
  const handleDismiss = () => {
29
30
  dismissAlert(alert.id);
@@ -111,7 +112,7 @@ export function AlertBanner({ alert }: AlertBannerProps) {
111
112
  style={[styles.closeButton, { marginLeft: tokens.spacing.sm }]}
112
113
  hitSlop={8}
113
114
  >
114
- <AtomicIcon name="close" customSize={20} customColor={textColor} />
115
+ <AtomicIcon name={closeIcon} customSize={20} customColor={textColor} />
115
116
  </Pressable>
116
117
  )}
117
118
  </View>
@@ -7,7 +7,7 @@
7
7
 
8
8
  import React, { useEffect } from 'react';
9
9
  import { StyleSheet, View, Pressable, StyleProp, ViewStyle } from 'react-native';
10
- import { AtomicText, AtomicIcon } from '../../atoms';
10
+ import { AtomicText, AtomicIcon, useIconName } from '../../atoms';
11
11
  import { useAppDesignTokens } from '../../theme';
12
12
  import { Alert, AlertType } from './AlertTypes';
13
13
  import { useAlertStore } from './AlertStore';
@@ -21,6 +21,7 @@ interface AlertToastProps {
21
21
  export function AlertToast({ alert }: AlertToastProps) {
22
22
  const dismissAlert = useAlertStore((state: { dismissAlert: (id: string) => void }) => state.dismissAlert);
23
23
  const tokens = useAppDesignTokens();
24
+ const closeIcon = useIconName('close');
24
25
 
25
26
  const dismiss = () => {
26
27
  dismissAlert(alert.id);
@@ -126,7 +127,7 @@ export function AlertToast({ alert }: AlertToastProps) {
126
127
  style={[styles.closeButton, { marginLeft: tokens.spacing.sm }]}
127
128
  hitSlop={8}
128
129
  >
129
- <AtomicIcon name="close" customSize={20} customColor={textColor} />
130
+ <AtomicIcon name={closeIcon} customSize={20} customColor={textColor} />
130
131
  </Pressable>
131
132
  )}
132
133
  </View>
@@ -8,7 +8,7 @@ import React, { forwardRef, useCallback } from 'react';
8
8
  import { View, StyleSheet, TouchableOpacity, ScrollView } from 'react-native';
9
9
  import { BottomSheetModal } from '../BottomSheetModal';
10
10
  import type { BottomSheetModalRef } from '../../types/BottomSheet';
11
- import { AtomicText, AtomicIcon, AtomicButton } from '../../../../atoms';
11
+ import { AtomicText, AtomicIcon, AtomicButton, useIconName } from '../../../../atoms';
12
12
  import { useAppDesignTokens } from '../../../../theme';
13
13
  import type { FilterOption, FilterCategory } from '../../types/Filter';
14
14
  import { FilterUtils } from '../../types/Filter';
@@ -33,6 +33,8 @@ export const FilterBottomSheet = forwardRef<BottomSheetModalRef, FilterBottomShe
33
33
  defaultId = 'all'
34
34
  }, ref) => {
35
35
  const tokens = useAppDesignTokens();
36
+ const checkIcon = useIconName('check');
37
+ const closeIcon = useIconName('close');
36
38
 
37
39
  if (__DEV__) {
38
40
  console.log('[FilterBottomSheet] Component mounted/rendered', {
@@ -120,7 +122,7 @@ export const FilterBottomSheet = forwardRef<BottomSheetModalRef, FilterBottomShe
120
122
  </AtomicText>
121
123
  </View>
122
124
  {isSelected && (
123
- <AtomicIcon name="checkmark" size="sm" color="primary" />
125
+ <AtomicIcon name={checkIcon} size="sm" color="primary" />
124
126
  )}
125
127
  </TouchableOpacity>
126
128
  );
@@ -167,7 +169,7 @@ export const FilterBottomSheet = forwardRef<BottomSheetModalRef, FilterBottomShe
167
169
  <View style={styles.header}>
168
170
  <AtomicText type="headlineSmall">{title || 'Filter'}</AtomicText>
169
171
  <TouchableOpacity onPress={() => (ref as any).current?.dismiss()}>
170
- <AtomicIcon name="close" size="md" color="textPrimary" />
172
+ <AtomicIcon name={closeIcon} size="md" color="textPrimary" />
171
173
  </TouchableOpacity>
172
174
  </View>
173
175
 
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { View, StyleSheet, TouchableOpacity } from 'react-native';
3
- import { AtomicText, AtomicIcon } from '../../../../../atoms';
3
+ import { AtomicText, AtomicIcon, useIconName } from '../../../../../atoms';
4
4
  import type { useAppDesignTokens } from '../../../../../theme';
5
5
 
6
6
  interface FilterSheetHeaderProps {
@@ -9,14 +9,18 @@ interface FilterSheetHeaderProps {
9
9
  tokens: ReturnType<typeof useAppDesignTokens>;
10
10
  }
11
11
 
12
- export const FilterSheetHeader = ({ title, onClose, tokens }: FilterSheetHeaderProps) => (
13
- <View style={[styles.header, { borderBottomColor: tokens.colors.border, borderBottomWidth: tokens.borders.width.thin }]}>
14
- <AtomicText type="headlineMedium" style={styles.title}>{title}</AtomicText>
15
- <TouchableOpacity onPress={onClose} hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}>
16
- <AtomicIcon name="close" size="md" color="primary" />
17
- </TouchableOpacity>
18
- </View>
19
- );
12
+ export const FilterSheetHeader = ({ title, onClose, tokens }: FilterSheetHeaderProps) => {
13
+ const closeIcon = useIconName('close');
14
+
15
+ return (
16
+ <View style={[styles.header, { borderBottomColor: tokens.colors.border, borderBottomWidth: tokens.borders.width.thin }]}>
17
+ <AtomicText type="headlineMedium" style={styles.title}>{title}</AtomicText>
18
+ <TouchableOpacity onPress={onClose} hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}>
19
+ <AtomicIcon name={closeIcon} size="md" color="primary" />
20
+ </TouchableOpacity>
21
+ </View>
22
+ );
23
+ };
20
24
 
21
25
  const styles = StyleSheet.create({
22
26
  header: {
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { View, StyleSheet, TouchableOpacity } from 'react-native';
3
- import { AtomicText, AtomicIcon } from '../../../../../atoms';
3
+ import { AtomicText, AtomicIcon, useIconName } from '../../../../../atoms';
4
4
  import type { useAppDesignTokens } from '../../../../../theme';
5
5
  import type { FilterOption } from '../../../types/Filter';
6
6
 
@@ -11,7 +11,10 @@ interface FilterSheetOptionProps {
11
11
  tokens: ReturnType<typeof useAppDesignTokens>;
12
12
  }
13
13
 
14
- export const FilterSheetOption = ({ option, isSelected, onPress, tokens }: FilterSheetOptionProps) => (
14
+ export const FilterSheetOption = ({ option, isSelected, onPress, tokens }: FilterSheetOptionProps) => {
15
+ const checkCircleIcon = useIconName('checkCircle');
16
+
17
+ return (
15
18
  <TouchableOpacity
16
19
  onPress={() => onPress(option.id)}
17
20
  style={[
@@ -35,9 +38,10 @@ export const FilterSheetOption = ({ option, isSelected, onPress, tokens }: Filte
35
38
  {option.label}
36
39
  </AtomicText>
37
40
  </View>
38
- {isSelected && <AtomicIcon name="checkmark-circle" size="md" color="primary" />}
41
+ {isSelected && <AtomicIcon name={checkCircleIcon} size="md" color="primary" />}
39
42
  </TouchableOpacity>
40
- );
43
+ );
44
+ };
41
45
 
42
46
  const styles = StyleSheet.create({
43
47
  option: {
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import { TouchableOpacity, StyleSheet } from "react-native";
3
- import { AtomicIcon } from "../../atoms";
3
+ import { AtomicIcon, useIconName } from "../../atoms";
4
4
  import { useAppDesignTokens } from "../../theme";
5
5
  import { LAYOUT } from "./constants";
6
6
 
@@ -12,6 +12,7 @@ export const CircularMenuCloseButton: React.FC<CircularMenuCloseButtonProps> = (
12
12
  onPress,
13
13
  }) => {
14
14
  const tokens = useAppDesignTokens();
15
+ const closeIcon = useIconName('close');
15
16
 
16
17
  return (
17
18
  <TouchableOpacity
@@ -31,7 +32,7 @@ export const CircularMenuCloseButton: React.FC<CircularMenuCloseButtonProps> = (
31
32
  accessibilityRole="button"
32
33
  accessibilityLabel="Close menu"
33
34
  >
34
- <AtomicIcon name="close" size="md" color="secondary" />
35
+ <AtomicIcon name={closeIcon} size="md" color="secondary" />
35
36
  </TouchableOpacity>
36
37
  );
37
38
  };
@@ -5,7 +5,7 @@ import { useCountdown } from '../hooks/useCountdown';
5
5
  import { CountdownHeader } from './CountdownHeader';
6
6
  import { TimeUnit } from './TimeUnit';
7
7
  import type { CountdownTarget, CountdownDisplayConfig } from '../types/CountdownTypes';
8
- import type { IconName } from '../../../atoms/AtomicIcon';
8
+ import type { IconName } from '../../../atoms';
9
9
 
10
10
  export interface CountdownProps {
11
11
  target: CountdownTarget;
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
2
  import { View, StyleSheet, TouchableOpacity } from 'react-native';
3
- import { AtomicText, AtomicIcon } from '../../../atoms';
3
+ import { AtomicText, AtomicIcon, useIconName } from '../../../atoms';
4
4
  import { useAppDesignTokens } from '../../../theme';
5
- import type { IconName } from '../../../atoms/AtomicIcon';
5
+ import type { IconName } from '../../../atoms';
6
6
 
7
7
  export interface CountdownHeaderProps {
8
8
  title: string;
@@ -20,6 +20,7 @@ export const CountdownHeader: React.FC<CountdownHeaderProps> = ({
20
20
  onToggle,
21
21
  }) => {
22
22
  const tokens = useAppDesignTokens();
23
+ const swapIcon = useIconName('swap');
23
24
 
24
25
  return (
25
26
  <View style={[styles.container, { marginBottom: tokens.spacing.md }]}>
@@ -54,7 +55,7 @@ export const CountdownHeader: React.FC<CountdownHeaderProps> = ({
54
55
  onPress={onToggle}
55
56
  >
56
57
  <AtomicIcon
57
- name="swap-horizontal"
58
+ name={swapIcon}
58
59
  size="sm"
59
60
  color="onSurface"
60
61
  />
@@ -2,7 +2,7 @@
2
2
  import React from 'react';
3
3
  import { View, StyleSheet } from 'react-native';
4
4
  import { AtomicText } from '../../atoms/AtomicText';
5
- import { AtomicIcon } from '../../atoms/AtomicIcon';
5
+ import { AtomicIcon } from '../../atoms';
6
6
  import { useAppDesignTokens } from '../../theme';
7
7
  import type { InfoGridProps } from './types';
8
8
 
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { View, StyleSheet, TouchableOpacity } from 'react-native';
3
3
  import { AtomicText } from '../../../atoms';
4
- import { AtomicIcon } from '../../../atoms';
4
+ import { AtomicIcon, useIconName } from '../../../atoms';
5
5
  import { useAppDesignTokens } from '../../../theme';
6
6
  import { useSafeAreaInsets } from '../../../safe-area';
7
7
 
@@ -18,6 +18,7 @@ export const NavigationHeader: React.FC<NavigationHeaderProps> = ({
18
18
  }) => {
19
19
  const tokens = useAppDesignTokens();
20
20
  const insets = useSafeAreaInsets();
21
+ const arrowLeftIcon = useIconName('arrowLeft');
21
22
 
22
23
  const styles = StyleSheet.create({
23
24
  container: {
@@ -51,7 +52,7 @@ export const NavigationHeader: React.FC<NavigationHeaderProps> = ({
51
52
  {onBackPress && (
52
53
  <TouchableOpacity onPress={onBackPress} style={styles.backButton}>
53
54
  <AtomicIcon
54
- name="arrow-back"
55
+ name={arrowLeftIcon}
55
56
  size="md"
56
57
  color="textPrimary"
57
58
  />
@@ -1,7 +1,7 @@
1
1
  import React, { useMemo } from "react";
2
2
  import { View } from "react-native";
3
3
  import type { ParamListBase } from "@react-navigation/native";
4
- import { AtomicIcon } from "../../../atoms/AtomicIcon";
4
+ import { AtomicIcon } from "../../../atoms";
5
5
  import { useAppDesignTokens } from "../../../theme";
6
6
  import { useResponsive } from "../../../responsive";
7
7
  import type { TabNavigatorConfig, TabScreen } from "../types";
@@ -4,7 +4,7 @@ import type {
4
4
  BottomTabScreenProps,
5
5
  } from "@react-navigation/bottom-tabs";
6
6
  import type { StackNavigationOptions } from "@react-navigation/stack";
7
- import type { IconName } from "../../atoms/AtomicIcon";
7
+ import type { IconName } from "../../atoms";
8
8
 
9
9
  export type NavigationParams = Record<string, unknown>;
10
10
 
@@ -1,7 +1,6 @@
1
1
  import React from "react";
2
2
  import type { IconRendererProps } from "../types";
3
- import { AtomicIcon } from "../../../atoms/AtomicIcon";
4
- import type { IconName } from "../../../atoms/AtomicIcon";
3
+ import { AtomicIcon, type IconName } from "../../../atoms";
5
4
 
6
5
  type RenderIconFn = (
7
6
  iconName: IconName,
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import { View, TouchableOpacity, StyleSheet } from "react-native";
3
- import { AtomicIcon } from "../../../atoms/AtomicIcon";
3
+ import { AtomicIcon, useIconName } from "../../../atoms";
4
4
  import { AtomicText } from "../../../atoms/AtomicText";
5
5
  import { useLocalization } from "@umituz/react-native-localization";
6
6
  import { useOnboardingProvider } from "../providers/OnboardingProvider";
@@ -26,6 +26,7 @@ export const OnboardingHeader = ({
26
26
  const {
27
27
  theme: { colors },
28
28
  } = useOnboardingProvider();
29
+ const chevronLeftIcon = useIconName('chevronLeft');
29
30
 
30
31
  const skipText = skipButtonText || t("onboarding.skip");
31
32
 
@@ -46,7 +47,7 @@ export const OnboardingHeader = ({
46
47
  activeOpacity={0.7}
47
48
  hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
48
49
  >
49
- <AtomicIcon name="chevron-back" customSize={20} customColor={colors.iconColor} />
50
+ <AtomicIcon name={chevronLeftIcon} customSize={20} customColor={colors.iconColor} />
50
51
  </TouchableOpacity>
51
52
  ) : (
52
53
  <View style={styles.headerButton} />
@@ -1,7 +1,6 @@
1
1
  import React, { useCallback } from "react";
2
2
  import { View, TouchableOpacity, StyleSheet } from "react-native";
3
- import { AtomicIcon } from "../../../atoms/AtomicIcon";
4
- import { AtomicText } from "../../../atoms/AtomicText";
3
+ import { AtomicIcon, AtomicText } from "../../../atoms";
5
4
  import { useAppDesignTokens } from "../../../theme/hooks/useAppDesignTokens";
6
5
 
7
6
  export interface OnboardingResetSettingProps {
@@ -5,7 +5,7 @@
5
5
 
6
6
  import React from "react";
7
7
  import { View, StyleSheet } from "react-native";
8
- import { AtomicIcon } from "../../../atoms/AtomicIcon";
8
+ import { AtomicIcon, useIconName } from "../../../atoms";
9
9
  import { AtomicText } from "../../../atoms/AtomicText";
10
10
  import type { OnboardingSlide as OnboardingSlideType } from "../../domain/entities/OnboardingSlide";
11
11
  import { BaseSlide } from "./BaseSlide";
@@ -23,6 +23,7 @@ export const OnboardingSlide = ({
23
23
  const {
24
24
  theme: { colors },
25
25
  } = useOnboardingProvider();
26
+ const checkCircleIcon = useIconName('checkCircle');
26
27
 
27
28
  const shouldShowIcon = slide.icon && !slide.hideIcon;
28
29
  const isEmoji = slide.iconType === 'emoji';
@@ -72,7 +73,7 @@ export const OnboardingSlide = ({
72
73
  ]}
73
74
  >
74
75
  <AtomicIcon
75
- name="checkmark-circle"
76
+ name={checkCircleIcon}
76
77
  size="sm"
77
78
  customColor={colors.iconColor}
78
79
  />
@@ -1,7 +1,6 @@
1
1
  import React from "react";
2
2
  import { View, StyleSheet } from "react-native";
3
- import { AtomicIcon } from "../../../atoms/AtomicIcon";
4
- import { AtomicText } from "../../../atoms/AtomicText";
3
+ import { AtomicIcon, AtomicText } from "../../../atoms";
5
4
  import type { OnboardingSlide } from "../../domain/entities/OnboardingSlide";
6
5
  import { useOnboardingProvider } from "../providers/OnboardingProvider";
7
6
 
@@ -5,8 +5,7 @@
5
5
 
6
6
  import React from "react";
7
7
  import { View, TouchableOpacity, StyleSheet } from "react-native";
8
- import { AtomicIcon } from "../../../../atoms/AtomicIcon";
9
- import { AtomicText } from "../../../../atoms/AtomicText";
8
+ import { AtomicIcon, AtomicText } from "../../../../atoms";
10
9
  import type { QuestionOption } from "../../../domain/entities/OnboardingQuestion";
11
10
  import type { OnboardingColors } from "../../types/OnboardingTheme";
12
11
 
@@ -1,7 +1,6 @@
1
1
  import React from "react";
2
2
  import { View, TouchableOpacity, StyleSheet } from "react-native";
3
- import { AtomicIcon } from "../../../../atoms/AtomicIcon";
4
- import { AtomicText } from "../../../../atoms/AtomicText";
3
+ import { AtomicIcon, AtomicText } from "../../../../atoms";
5
4
  import { useOnboardingProvider } from "../../providers/OnboardingProvider";
6
5
  import type { OnboardingQuestion } from "../../../domain/entities/OnboardingQuestion";
7
6
 
@@ -1,7 +1,6 @@
1
1
  import React from "react";
2
2
  import { View, TouchableOpacity, StyleSheet } from "react-native";
3
- import { AtomicIcon } from "../../../../atoms/AtomicIcon";
4
- import { AtomicText } from "../../../../atoms/AtomicText";
3
+ import { AtomicIcon, AtomicText } from "../../../../atoms";
5
4
  import { useOnboardingProvider } from "../../providers/OnboardingProvider";
6
5
  import type { OnboardingQuestion, QuestionOption } from "../../../domain/entities/OnboardingQuestion";
7
6
 
@@ -5,7 +5,7 @@ import { type DesignTokens, type ResponsiveTypography } from '../types/ThemeType
5
5
 
6
6
  /**
7
7
  * Create complete design tokens for a specific theme mode
8
- *
8
+ *
9
9
  * ✅ Responsive by default
10
10
  * ✅ SINGLE SOURCE OF TRUTH
11
11
  *
@@ -78,7 +78,7 @@ export { useCommonStyles } from './hooks/useCommonStyles';
78
78
  export { DesignSystemProvider } from './infrastructure/providers/DesignSystemProvider';
79
79
 
80
80
  // Re-export icon types for convenience
81
- export type { IconRenderer, IconRenderProps } from '../atoms/IconRegistry';
81
+ export type { IconRenderer, IconRenderProps, IconNames } from '../atoms/icon';
82
82
 
83
83
  // =============================================================================
84
84
  // THEME OBJECTS
@@ -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
  );