@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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-design-system",
3
- "version": "2.11.2",
3
+ "version": "2.11.3",
4
4
  "description": "Universal design system for React Native apps - Consolidated package with atoms, molecules, organisms, theme, typography, responsive, safe area, exception, infinite scroll, UUID, image, timezone, offline, onboarding, and loading utilities",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import { TouchableOpacity, StyleSheet } from 'react-native';
3
3
  import { useAppDesignTokens } from '../theme';
4
4
  import { useResponsive } from '../responsive';
5
- import { AtomicIcon } from './AtomicIcon';
5
+ import { AtomicIcon } from './icon';
6
6
  import { AtomicFabProps } from './fab/types';
7
7
  import {
8
8
  FAB_SIZES,
@@ -9,7 +9,7 @@
9
9
 
10
10
  import React from 'react';
11
11
  import { View, StyleSheet, TouchableOpacity, ViewStyle } from 'react-native';
12
- import { AtomicIcon } from './AtomicIcon';
12
+ import { AtomicIcon } from './icon';
13
13
  import { AtomicText } from './AtomicText';
14
14
  import { useAppDesignTokens, STATIC_TOKENS } from '../theme';
15
15
 
@@ -5,9 +5,9 @@
5
5
 
6
6
  import React from "react";
7
7
  import { View, StyleSheet, type StyleProp, type ViewStyle, type TextStyle } from "react-native";
8
- import { AtomicText } from "./AtomicText";
9
- import { AtomicIcon, type IconName } from "./AtomicIcon";
10
- import { useAppDesignTokens } from '../theme';
8
+ import { AtomicText } from "../AtomicText";
9
+ import { AtomicIcon, type IconName } from "../icon";
10
+ import { useAppDesignTokens } from '../../theme';
11
11
 
12
12
  export type BadgeVariant = "primary" | "secondary" | "success" | "warning" | "error" | "info";
13
13
  export type BadgeSize = "sm" | "md" | "lg";
@@ -0,0 +1,6 @@
1
+ export {
2
+ AtomicBadge,
3
+ type AtomicBadgeProps,
4
+ type BadgeVariant,
5
+ type BadgeSize,
6
+ } from './AtomicBadge';
@@ -6,7 +6,7 @@
6
6
  import React from 'react';
7
7
  import { StyleProp, ViewStyle, TextStyle, TouchableOpacity } from 'react-native';
8
8
  import { AtomicText } from '../AtomicText';
9
- import { AtomicIcon } from '../AtomicIcon';
9
+ import { AtomicIcon } from '../icon';
10
10
  import { AtomicSpinner } from '../AtomicSpinner';
11
11
  import { useAppDesignTokens } from '../../theme';
12
12
  import { getButtonSizeConfig } from './configs/buttonSizeConfig';
@@ -4,7 +4,7 @@
4
4
 
5
5
  import type { StyleProp } from 'react-native';
6
6
  import type { TextStyle, ViewStyle } from 'react-native';
7
- import type { IconName } from '../../AtomicIcon';
7
+ import type { IconName } from '../../icon';
8
8
 
9
9
  export type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'text' | 'danger';
10
10
  export type ButtonSize = 'sm' | 'md' | 'lg';
@@ -13,7 +13,7 @@ import {
13
13
  } from 'react-native';
14
14
  import { AtomicImage } from '../image/AtomicImage';
15
15
  import { AtomicText } from '../AtomicText';
16
- import { AtomicIcon } from '../AtomicIcon';
16
+ import { AtomicIcon, useIconName } from '../icon';
17
17
  import { useAppDesignTokens } from '../../theme';
18
18
  import { getCardVariantStyles, cardStyles } from './styles/cardStyles';
19
19
  import { getCardPadding } from './configs/cardPaddingConfig';
@@ -43,6 +43,7 @@ const AtomicCardComponent: React.FC<AtomicCardProps> = ({
43
43
  testID,
44
44
  }) => {
45
45
  const tokens = useAppDesignTokens();
46
+ const checkCircleIcon = useIconName('checkCircle');
46
47
 
47
48
  const variantStyles = useMemo(() => {
48
49
  const base = getCardVariantStyles(variant, tokens);
@@ -98,7 +99,7 @@ const AtomicCardComponent: React.FC<AtomicCardProps> = ({
98
99
  {/* Selected Indicator */}
99
100
  {selected && (
100
101
  <View style={cardStyles.selectedOverlay}>
101
- <AtomicIcon name="checkmark-circle" color="primary" size="md" />
102
+ <AtomicIcon name={checkCircleIcon} color="primary" size="md" />
102
103
  </View>
103
104
  )}
104
105
 
@@ -6,7 +6,7 @@
6
6
  import React from 'react';
7
7
  import { View, ViewStyle, TouchableOpacity } from 'react-native';
8
8
  import { AtomicText } from '../AtomicText';
9
- import { AtomicIcon } from '../AtomicIcon';
9
+ import { AtomicIcon } from '../icon';
10
10
  import { useAppDesignTokens } from '../../theme';
11
11
  import { getChipSizeConfig } from './configs/chipSizeConfig';
12
12
  import { getChipColorConfig } from './configs/chipColorConfig';
@@ -3,7 +3,7 @@
3
3
  */
4
4
 
5
5
  import type { StyleProp, ViewStyle } from 'react-native';
6
- import type { IconSize } from '../../AtomicIcon';
6
+ import type { IconSize } from '../../icon';
7
7
 
8
8
  export type ChipVariant = 'filled' | 'outlined' | 'soft';
9
9
  export type ChipSize = 'sm' | 'md' | 'lg';
@@ -12,7 +12,7 @@ import {
12
12
  StyleSheet,
13
13
  } from 'react-native';
14
14
  import { useAppDesignTokens } from '../../../theme';
15
- import { AtomicIcon } from '../../AtomicIcon';
15
+ import { AtomicIcon, useIconName } from '../../icon';
16
16
  import { AtomicText } from '../../AtomicText';
17
17
 
18
18
  interface DatePickerButtonProps {
@@ -33,6 +33,7 @@ export const DatePickerButton: React.FC<DatePickerButtonProps> = ({
33
33
  testID,
34
34
  }) => {
35
35
  const tokens = useAppDesignTokens();
36
+ const calendarIcon = useIconName('calendar');
36
37
 
37
38
  const buttonStyles = StyleSheet.create({
38
39
  container: {
@@ -102,7 +103,7 @@ export const DatePickerButton: React.FC<DatePickerButtonProps> = ({
102
103
 
103
104
  <View style={buttonStyles.iconContainer}>
104
105
  <AtomicIcon
105
- name="Calendar"
106
+ name={calendarIcon}
106
107
  size="md"
107
108
  color={disabled ? 'surfaceVariant' : 'secondary'}
108
109
  />
@@ -23,8 +23,8 @@
23
23
  import React from "react";
24
24
  import { View, StyleSheet, StyleProp, ViewStyle } from "react-native";
25
25
  import Svg, { Path } from "react-native-svg";
26
- import { useAppDesignTokens } from "../theme";
27
- import { useIconRenderer, type IconRenderProps } from "./IconRegistry";
26
+ import { useAppDesignTokens } from "../../theme";
27
+ import { useIconRenderer, type IconRenderProps } from "./iconStore";
28
28
  import {
29
29
  type IconSize as BaseIconSize,
30
30
  type IconColor,
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Icon Store - Zustand-based icon configuration
3
+ *
4
+ * No defaults - all icon names come from the app.
5
+ * App sets iconNames and iconRenderer via DesignSystemProvider.
6
+ */
7
+
8
+ import { create } from 'zustand';
9
+ import type { ReactNode } from 'react';
10
+ import type { StyleProp, ViewStyle } from 'react-native';
11
+
12
+ /**
13
+ * Required icon names - app MUST provide all of these
14
+ */
15
+ export interface IconNames {
16
+ close: string;
17
+ check: string;
18
+ checkCircle: string;
19
+ chevronLeft: string;
20
+ chevronRight: string;
21
+ chevronUp: string;
22
+ chevronDown: string;
23
+ arrowLeft: string;
24
+ arrowRight: string;
25
+ search: string;
26
+ closeCircle: string;
27
+ clock: string;
28
+ refresh: string;
29
+ alertCircle: string;
30
+ star: string;
31
+ starOutline: string;
32
+ wifiOff: string;
33
+ info: string;
34
+ trash: string;
35
+ calendar: string;
36
+ swap: string;
37
+ colorFilter: string;
38
+ }
39
+
40
+ export const REQUIRED_ICON_KEYS: (keyof IconNames)[] = [
41
+ 'close', 'check', 'checkCircle', 'chevronLeft', 'chevronRight',
42
+ 'chevronUp', 'chevronDown', 'arrowLeft', 'arrowRight', 'search',
43
+ 'closeCircle', 'clock', 'refresh', 'alertCircle', 'star',
44
+ 'starOutline', 'wifiOff', 'info', 'trash', 'calendar', 'swap', 'colorFilter',
45
+ ];
46
+
47
+ /**
48
+ * Props passed to the icon renderer function
49
+ */
50
+ export interface IconRenderProps {
51
+ name: string;
52
+ size: number;
53
+ color: string;
54
+ style?: StyleProp<ViewStyle>;
55
+ testID?: string;
56
+ accessibilityLabel?: string;
57
+ }
58
+
59
+ export type IconRenderer = (props: IconRenderProps) => ReactNode;
60
+
61
+ interface IconStore {
62
+ iconNames: IconNames | null;
63
+ iconRenderer: IconRenderer | null;
64
+ isConfigured: boolean;
65
+ setConfig: (iconNames: IconNames, iconRenderer: IconRenderer) => void;
66
+ reset: () => void;
67
+ }
68
+
69
+ export const useIconStore = create<IconStore>((set) => ({
70
+ iconNames: null,
71
+ iconRenderer: null,
72
+ isConfigured: false,
73
+
74
+ setConfig: (iconNames, iconRenderer) => {
75
+ if (__DEV__) {
76
+ const missingKeys = REQUIRED_ICON_KEYS.filter(key => !iconNames[key]);
77
+ if (missingKeys.length > 0) {
78
+ console.error(
79
+ `[DesignSystem] Missing icon names: ${missingKeys.join(', ')}`
80
+ );
81
+ }
82
+ }
83
+ set({ iconNames, iconRenderer, isConfigured: true });
84
+ },
85
+
86
+ reset: () => set({ iconNames: null, iconRenderer: null, isConfigured: false }),
87
+ }));
88
+
89
+ /**
90
+ * Get icon renderer
91
+ */
92
+ export const useIconRenderer = (): IconRenderer | null => {
93
+ return useIconStore((state) => state.iconRenderer);
94
+ };
95
+
96
+ /**
97
+ * Get specific icon name from app config
98
+ */
99
+ export const useIconName = (key: keyof IconNames): string => {
100
+ const iconNames = useIconStore((state) => state.iconNames);
101
+
102
+ if (!iconNames) {
103
+ if (__DEV__) {
104
+ console.warn(
105
+ `[DesignSystem] useIconName("${key}") - iconNames not configured.`
106
+ );
107
+ }
108
+ return '';
109
+ }
110
+
111
+ return iconNames[key] || '';
112
+ };
113
+
114
+ /**
115
+ * Check if icon system is configured
116
+ */
117
+ export const useHasIconConfig = (): boolean => {
118
+ return useIconStore((state) => state.isConfigured);
119
+ };
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Icon Module
3
+ *
4
+ * Zustand-based icon system.
5
+ * App provides iconNames and iconRenderer via DesignSystemProvider.
6
+ */
7
+
8
+ // Main Component
9
+ export {
10
+ AtomicIcon,
11
+ type AtomicIconProps,
12
+ type IconSize,
13
+ type IconName,
14
+ type IconColor,
15
+ } from './AtomicIcon';
16
+
17
+ // Icon Store
18
+ export {
19
+ useIconStore,
20
+ useIconRenderer,
21
+ useIconName,
22
+ useHasIconConfig,
23
+ type IconNames,
24
+ type IconRenderer,
25
+ type IconRenderProps,
26
+ REQUIRED_ICON_KEYS,
27
+ } from './iconStore';
28
+
29
+ // Type utilities
30
+ export {
31
+ type IconSizePreset,
32
+ ICON_SIZES,
33
+ getIconSize,
34
+ isIconSizePreset,
35
+ } from './AtomicIcon.types';
@@ -33,7 +33,7 @@ export type {
33
33
  AtomicInputSize,
34
34
  } from './input/types';
35
35
 
36
- // Icon
36
+ // Icon (Zustand-based icon system)
37
37
  export {
38
38
  AtomicIcon,
39
39
  type AtomicIconProps,
@@ -41,15 +41,20 @@ export {
41
41
  type IconColor,
42
42
  type IconName,
43
43
  type IconRenderProps,
44
- } from './AtomicIcon';
45
-
46
- // Icon Registry (for custom icon renderers)
47
- export {
48
- IconProvider,
44
+ // Icon Store
45
+ useIconStore,
49
46
  useIconRenderer,
50
- useHasCustomIconRenderer,
47
+ useIconName,
48
+ useHasIconConfig,
51
49
  type IconRenderer,
52
- } from './IconRegistry';
50
+ type IconNames,
51
+ REQUIRED_ICON_KEYS,
52
+ // Type utilities
53
+ type IconSizePreset,
54
+ ICON_SIZES,
55
+ getIconSize,
56
+ isIconSizePreset,
57
+ } from './icon';
53
58
 
54
59
 
55
60
  // Avatar
@@ -96,7 +101,7 @@ export {
96
101
  type AtomicBadgeProps,
97
102
  type BadgeVariant,
98
103
  type BadgeSize,
99
- } from './AtomicBadge';
104
+ } from './badge';
100
105
 
101
106
  // Spinner
102
107
  export {
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { Pressable } from 'react-native';
3
- import { AtomicIcon } from '../../AtomicIcon';
3
+ import { AtomicIcon } from '../../icon';
4
4
 
5
5
  interface InputIconProps {
6
6
  name: string;
@@ -1,6 +1,6 @@
1
1
  import type { StyleProp, TextInputProps } from 'react-native';
2
2
  import type { TextStyle, ViewStyle } from 'react-native';
3
- import type { IconName } from '../AtomicIcon';
3
+ import type { IconName } from '../icon';
4
4
 
5
5
  export type AtomicInputVariant = 'outlined' | 'filled' | 'flat';
6
6
  export type AtomicInputState = 'default' | 'error' | 'success' | 'disabled';
@@ -9,7 +9,7 @@ import React from 'react';
9
9
  import { View, TouchableOpacity, GestureResponderEvent } from 'react-native';
10
10
  import { useAppDesignTokens } from '../../../theme';
11
11
  import { PickerOption } from '../types';
12
- import { AtomicIcon } from '../../AtomicIcon';
12
+ import { AtomicIcon, useIconName } from '../../icon';
13
13
  import { AtomicText } from '../../AtomicText';
14
14
  import {
15
15
  getChipContainerStyles,
@@ -28,6 +28,7 @@ export const PickerChips: React.FC<PickerChipsProps> = React.memo(({
28
28
  onRemoveChip,
29
29
  }) => {
30
30
  const tokens = useAppDesignTokens();
31
+ const closeIcon = useIconName('close');
31
32
 
32
33
  const chipContainerStyles = getChipContainerStyles(tokens);
33
34
  const chipStyles = getChipStyles(tokens);
@@ -47,7 +48,7 @@ export const PickerChips: React.FC<PickerChipsProps> = React.memo(({
47
48
  }}
48
49
  hitSlop={{ top: 4, bottom: 4, left: 4, right: 4 }}
49
50
  >
50
- <AtomicIcon name="X" size="sm" color="primary" />
51
+ <AtomicIcon name={closeIcon} size="sm" color="primary" />
51
52
  </TouchableOpacity>
52
53
  </View>
53
54
  ))}
@@ -6,7 +6,7 @@
6
6
  import React from 'react';
7
7
  import { TouchableOpacity, View } from 'react-native';
8
8
  import { useAppDesignTokens } from '../../../theme';
9
- import { AtomicIcon } from '../../AtomicIcon';
9
+ import { AtomicIcon, useIconName } from '../../icon';
10
10
 
11
11
 
12
12
  interface PickerIconsProps {
@@ -29,6 +29,9 @@ export const PickerIcons: React.FC<PickerIconsProps> = ({
29
29
  testID,
30
30
  }) => {
31
31
  const tokens = useAppDesignTokens();
32
+ const closeIcon = useIconName('close');
33
+ const chevronUpIcon = useIconName('chevronUp');
34
+ const chevronDownIcon = useIconName('chevronDown');
32
35
 
33
36
  return (
34
37
  <View style={{ flexDirection: 'row', alignItems: 'center', gap: tokens.spacing.xs }}>
@@ -41,13 +44,13 @@ export const PickerIcons: React.FC<PickerIconsProps> = ({
41
44
  accessibilityLabel={clearAccessibilityLabel}
42
45
  testID={`${testID}-clear`}
43
46
  >
44
- <AtomicIcon name="X" size="sm" color="secondary" />
47
+ <AtomicIcon name={closeIcon} size="sm" color="secondary" />
45
48
  </TouchableOpacity>
46
49
  )}
47
50
 
48
51
  {/* Dropdown Icon */}
49
52
  <AtomicIcon
50
- name={modalVisible ? 'ChevronUp' : 'ChevronDown'}
53
+ name={modalVisible ? chevronUpIcon : chevronDownIcon}
51
54
  size="sm"
52
55
  color={disabled ? 'surfaceVariant' : 'secondary'}
53
56
  />
@@ -14,7 +14,7 @@ import {
14
14
  import { useSafeAreaInsets } from '../../../safe-area';
15
15
  import { useAppDesignTokens } from '../../../theme';
16
16
  import { PickerOption } from '../types';
17
- import { AtomicIcon } from '../../AtomicIcon';
17
+ import { AtomicIcon, useIconName } from '../../icon';
18
18
  import { AtomicText } from '../../AtomicText';
19
19
  import {
20
20
  getModalOverlayStyles,
@@ -65,6 +65,10 @@ export const PickerModal: React.FC<PickerModalProps> = React.memo(({
65
65
  }) => {
66
66
  const tokens = useAppDesignTokens();
67
67
  const insets = useSafeAreaInsets();
68
+ const checkCircleIcon = useIconName('checkCircle');
69
+ const searchIcon = useIconName('search');
70
+ const closeIcon = useIconName('close');
71
+ const infoIcon = useIconName('info');
68
72
 
69
73
  const modalOverlayStyles = getModalOverlayStyles();
70
74
  const modalContainerStyles = getModalContainerStyles(tokens, 0);
@@ -121,7 +125,7 @@ export const PickerModal: React.FC<PickerModalProps> = React.memo(({
121
125
 
122
126
  {/* Selected Indicator */}
123
127
  {selected && (
124
- <AtomicIcon name="CircleCheck" size="md" color="primary" />
128
+ <AtomicIcon name={checkCircleIcon} size="md" color="primary" />
125
129
  )}
126
130
  </TouchableOpacity>
127
131
  );
@@ -157,14 +161,14 @@ export const PickerModal: React.FC<PickerModalProps> = React.memo(({
157
161
  accessibilityLabel={closeAccessibilityLabel}
158
162
  testID={`${testID}-close`}
159
163
  >
160
- <AtomicIcon name="X" size="md" color="primary" />
164
+ <AtomicIcon name={closeIcon} size="md" color="primary" />
161
165
  </TouchableOpacity>
162
166
  </View>
163
167
 
164
168
  {/* Search Bar */}
165
169
  {searchable && (
166
170
  <View style={searchContainerStyles}>
167
- <AtomicIcon name="Search" size="sm" color="secondary" />
171
+ <AtomicIcon name={searchIcon} size="sm" color="secondary" />
168
172
  <TextInput
169
173
  value={searchQuery}
170
174
  onChangeText={onSearchChange}
@@ -175,7 +179,7 @@ export const PickerModal: React.FC<PickerModalProps> = React.memo(({
175
179
  />
176
180
  {searchQuery.length > 0 && (
177
181
  <TouchableOpacity onPress={() => onSearchChange('')}>
178
- <AtomicIcon name="X" size="sm" color="secondary" />
182
+ <AtomicIcon name={closeIcon} size="sm" color="secondary" />
179
183
  </TouchableOpacity>
180
184
  )}
181
185
  </View>
@@ -192,7 +196,7 @@ export const PickerModal: React.FC<PickerModalProps> = React.memo(({
192
196
  />
193
197
  ) : (
194
198
  <View style={emptyStateStyles}>
195
- <AtomicIcon name="Info" size="xl" color="secondary" />
199
+ <AtomicIcon name={infoIcon} size="xl" color="secondary" />
196
200
  <AtomicText style={emptyStateTextStyles}>
197
201
  {emptyMessage}
198
202
  </AtomicText>
@@ -1,5 +1,5 @@
1
1
  import { ViewStyle, TextStyle } from 'react-native';
2
- import { IconColor } from '../../AtomicIcon';
2
+ import { IconColor } from '../../icon';
3
3
 
4
4
  /**
5
5
  * Picker option item
@@ -10,6 +10,7 @@ import { View, StyleSheet, TouchableOpacity } from "react-native";
10
10
  import {
11
11
  AtomicIcon,
12
12
  AtomicText,
13
+ useIconName,
13
14
  } from "../../../atoms";
14
15
  import {
15
16
  useAppDesignTokens,
@@ -31,7 +32,7 @@ export interface ExceptionErrorStateProps {
31
32
  }
32
33
 
33
34
  export const ExceptionErrorState: React.FC<ExceptionErrorStateProps> = ({
34
- icon = "alert-circle-outline",
35
+ icon,
35
36
  title,
36
37
  description,
37
38
  actionLabel,
@@ -39,6 +40,9 @@ export const ExceptionErrorState: React.FC<ExceptionErrorStateProps> = ({
39
40
  illustration,
40
41
  }) => {
41
42
  const tokens = useAppDesignTokens();
43
+ const alertCircleIcon = useIconName('alertCircle');
44
+ const refreshIcon = useIconName('refresh');
45
+ const displayIcon = icon || alertCircleIcon;
42
46
 
43
47
  const styles = React.useMemo(
44
48
  () =>
@@ -87,7 +91,7 @@ export const ExceptionErrorState: React.FC<ExceptionErrorStateProps> = ({
87
91
  <View
88
92
  style={[styles.iconContainer, { backgroundColor: tokens.colors.surface }]}
89
93
  >
90
- <AtomicIcon name={icon as never} size="xxl" color="secondary" />
94
+ <AtomicIcon name={displayIcon as never} size="xxl" color="secondary" />
91
95
  </View>
92
96
  )}
93
97
 
@@ -107,7 +111,7 @@ export const ExceptionErrorState: React.FC<ExceptionErrorStateProps> = ({
107
111
  onPress={onAction}
108
112
  activeOpacity={0.8}
109
113
  >
110
- <AtomicIcon name="refresh-outline" size="sm" color="onPrimary" />
114
+ <AtomicIcon name={refreshIcon} size="sm" color="onPrimary" />
111
115
  <AtomicText type="labelLarge" color="onPrimary">
112
116
  {actionLabel}
113
117
  </AtomicText>
@@ -70,10 +70,13 @@ export {
70
70
  type GlassViewProps,
71
71
  AtomicImage,
72
72
  type AtomicImageProps,
73
- // Icon Registry (for custom icon renderers)
74
- IconProvider,
73
+ // Icon Store
74
+ useIconStore,
75
75
  useIconRenderer,
76
- useHasCustomIconRenderer,
76
+ useIconName,
77
+ useHasIconConfig,
77
78
  type IconRenderProps,
78
79
  type IconRenderer,
80
+ type IconNames,
81
+ REQUIRED_ICON_KEYS,
79
82
  } from '../atoms';
@@ -7,7 +7,7 @@ import { View, TouchableOpacity, ScrollView } from 'react-native';
7
7
  import { BottomSheetModal } from '../../../../molecules/bottom-sheet/components/BottomSheetModal';
8
8
  import type { BottomSheetModalRef } from '../../../../molecules/bottom-sheet/types/BottomSheet';
9
9
  import { AtomicText } from '../../../../atoms/AtomicText';
10
- import { AtomicIcon } from '../../../../atoms/AtomicIcon';
10
+ import { AtomicIcon, useIconName } from '../../../../atoms';
11
11
  import { useAppDesignTokens } from '../../../../theme/hooks/useAppDesignTokens';
12
12
  import { FilterProcessor, type FilterPreset } from '../../../infrastructure/utils/FilterProcessor';
13
13
 
@@ -23,6 +23,7 @@ export const FilterPickerSheet = forwardRef<BottomSheetModalRef, FilterPickerShe
23
23
  ({ onSelectFilter, onDismiss, activeFilterId, snapPoints = ['50%'], title = 'Filters' }, ref) => {
24
24
  const tokens = useAppDesignTokens();
25
25
  const presets = FilterProcessor.getPresets();
26
+ const colorFilterIcon = useIconName('colorFilter');
26
27
 
27
28
  return (
28
29
  <BottomSheetModal ref={ref} snapPoints={snapPoints} onDismiss={onDismiss}>
@@ -48,10 +49,10 @@ export const FilterPickerSheet = forwardRef<BottomSheetModalRef, FilterPickerShe
48
49
  borderColor: activeFilterId === preset.id ? tokens.colors.primary : 'transparent',
49
50
  }}
50
51
  >
51
- <AtomicIcon
52
- name="color-filter"
53
- size={32}
54
- color={activeFilterId === preset.id ? 'primary' : 'secondary'}
52
+ <AtomicIcon
53
+ name={colorFilterIcon}
54
+ size={32}
55
+ color={activeFilterId === preset.id ? 'primary' : 'secondary'}
55
56
  />
56
57
  <AtomicText style={{
57
58
  ...tokens.typography.labelSmall,
@@ -7,7 +7,7 @@ import { View, TouchableOpacity, ScrollView } from 'react-native';
7
7
  import { BottomSheetModal } from '../../../../molecules/bottom-sheet/components/BottomSheetModal';
8
8
  import type { BottomSheetModalRef } from '../../../../molecules/bottom-sheet/types/BottomSheet';
9
9
  import { AtomicText } from '../../../../atoms/AtomicText';
10
- import { AtomicIcon } from '../../../../atoms/AtomicIcon';
10
+ import { AtomicIcon } from '../../../../atoms';
11
11
  import { useAppDesignTokens } from '../../../../theme/hooks/useAppDesignTokens';
12
12
  import { TextContentTab, TextStyleTab, TextTransformTab } from './TextEditorTabs';
13
13
 
@@ -10,8 +10,7 @@ import {
10
10
  TouchableOpacity,
11
11
  StyleSheet,
12
12
  } from "react-native";
13
- import { AtomicText } from "../../../../atoms/AtomicText";
14
- import { AtomicIcon } from "../../../../atoms/AtomicIcon";
13
+ import { AtomicText, AtomicIcon } from "../../../../atoms";
15
14
  import { useAppDesignTokens } from "../../../../theme/hooks/useAppDesignTokens";
16
15
 
17
16
  interface TabProps {
@@ -6,7 +6,7 @@ import {
6
6
  StyleSheet,
7
7
  } from 'react-native';
8
8
  import { useAppDesignTokens } from '../../theme';
9
- import { AtomicIcon } from '../../atoms/AtomicIcon';
9
+ import { AtomicIcon, useIconName } from '../../atoms';
10
10
  import { AtomicSpinner } from '../../atoms/AtomicSpinner';
11
11
  import type { SearchBarProps } from './types';
12
12
 
@@ -26,6 +26,8 @@ export const SearchBar: React.FC<SearchBarProps> = ({
26
26
  testID,
27
27
  }) => {
28
28
  const tokens = useAppDesignTokens();
29
+ const searchIcon = useIconName('search');
30
+ const closeCircleIcon = useIconName('closeCircle');
29
31
 
30
32
  const handleClear = () => {
31
33
  onChangeText('');
@@ -51,7 +53,7 @@ export const SearchBar: React.FC<SearchBarProps> = ({
51
53
  >
52
54
  <View style={styles.iconContainer}>
53
55
  <AtomicIcon
54
- name="search"
56
+ name={searchIcon}
55
57
  size="md"
56
58
  customColor={tokens.colors.textSecondary}
57
59
  />
@@ -99,7 +101,7 @@ export const SearchBar: React.FC<SearchBarProps> = ({
99
101
  accessibilityLabel="Clear search"
100
102
  >
101
103
  <AtomicIcon
102
- name="close-circle"
104
+ name={closeCircleIcon}
103
105
  size="md"
104
106
  customColor={tokens.colors.textSecondary}
105
107
  />