@umituz/react-native-design-system 1.1.3 → 1.3.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/README.md +16 -11
- package/package.json +1 -2
- package/src/domains/icons/domain/config/IconLibraryConfig.ts +93 -0
- package/src/domains/icons/domain/entities/Icon.ts +143 -0
- package/src/domains/icons/domain/interfaces/IIconAdapter.ts +144 -0
- package/src/domains/icons/index.ts +109 -0
- package/src/domains/icons/infrastructure/adapters/LucideAdapter.ts +100 -0
- package/src/domains/icons/infrastructure/registries/ExpoIconRegistry.ts +191 -0
- package/src/domains/icons/presentation/components/Icon.tsx +132 -0
- package/src/domains/icons/presentation/hooks/useIconLibrary.ts +141 -0
- package/src/index.ts +12 -0
- package/src/presentation/atoms/AtomicButton.tsx +188 -40
- package/src/presentation/atoms/AtomicCard.tsx +52 -29
- package/src/presentation/atoms/AtomicIcon.tsx +26 -117
- package/src/presentation/atoms/AtomicInput.tsx +217 -99
- package/src/presentation/atoms/AtomicText.tsx +38 -6
- package/src/presentation/atoms/AtomicTextArea.tsx +173 -58
- package/src/presentation/organisms/FormContainer.tsx +16 -16
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Icons Domain - Expo Vector Icons Registry
|
|
3
|
+
*
|
|
4
|
+
* Registry for @expo/vector-icons (Material, FontAwesome, Ionicons).
|
|
5
|
+
* Provides metadata and search capabilities for 1000+ icons.
|
|
6
|
+
*
|
|
7
|
+
* @domain icons
|
|
8
|
+
* @layer infrastructure
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { IIconRegistry, IconMetadata } from '@domains/icons/domain/entities/Icon';
|
|
12
|
+
import { IconLibrary, IconCategory } from '@domains/icons/domain/entities/Icon';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Expo vector icons registry
|
|
16
|
+
* Maps common Material Design, FontAwesome, and Ionicons
|
|
17
|
+
*/
|
|
18
|
+
export class ExpoIconRegistry implements IIconRegistry {
|
|
19
|
+
private icons: IconMetadata[] = [
|
|
20
|
+
// Navigation icons (Material Design)
|
|
21
|
+
{
|
|
22
|
+
name: 'home',
|
|
23
|
+
library: IconLibrary.MATERIAL,
|
|
24
|
+
category: IconCategory.NAVIGATION,
|
|
25
|
+
tags: ['house', 'main', 'start'],
|
|
26
|
+
searchTerms: ['home', 'house', 'main', 'dashboard'],
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: 'arrow-back',
|
|
30
|
+
library: IconLibrary.MATERIAL,
|
|
31
|
+
category: IconCategory.NAVIGATION,
|
|
32
|
+
tags: ['back', 'previous', 'return'],
|
|
33
|
+
searchTerms: ['arrow', 'back', 'previous', 'navigate'],
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'menu',
|
|
37
|
+
library: IconLibrary.MATERIAL,
|
|
38
|
+
category: IconCategory.NAVIGATION,
|
|
39
|
+
tags: ['hamburger', 'drawer', 'navigation'],
|
|
40
|
+
searchTerms: ['menu', 'hamburger', 'navigation', 'drawer'],
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: 'search',
|
|
44
|
+
library: IconLibrary.MATERIAL,
|
|
45
|
+
category: IconCategory.ACTION,
|
|
46
|
+
tags: ['find', 'lookup', 'query'],
|
|
47
|
+
searchTerms: ['search', 'find', 'lookup', 'magnify'],
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
// Action icons (Material Design)
|
|
51
|
+
{
|
|
52
|
+
name: 'add',
|
|
53
|
+
library: IconLibrary.MATERIAL,
|
|
54
|
+
category: IconCategory.ACTION,
|
|
55
|
+
tags: ['plus', 'create', 'new'],
|
|
56
|
+
searchTerms: ['add', 'plus', 'create', 'new'],
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: 'delete',
|
|
60
|
+
library: IconLibrary.MATERIAL,
|
|
61
|
+
category: IconCategory.ACTION,
|
|
62
|
+
tags: ['remove', 'trash', 'bin'],
|
|
63
|
+
searchTerms: ['delete', 'remove', 'trash', 'garbage'],
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: 'edit',
|
|
67
|
+
library: IconLibrary.MATERIAL,
|
|
68
|
+
category: IconCategory.ACTION,
|
|
69
|
+
tags: ['pencil', 'modify', 'update'],
|
|
70
|
+
searchTerms: ['edit', 'pencil', 'modify', 'write'],
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: 'settings',
|
|
74
|
+
library: IconLibrary.MATERIAL,
|
|
75
|
+
category: IconCategory.ACTION,
|
|
76
|
+
tags: ['gear', 'preferences', 'config'],
|
|
77
|
+
searchTerms: ['settings', 'gear', 'preferences', 'options'],
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name: 'favorite',
|
|
81
|
+
library: IconLibrary.MATERIAL,
|
|
82
|
+
category: IconCategory.ACTION,
|
|
83
|
+
tags: ['heart', 'like', 'love'],
|
|
84
|
+
searchTerms: ['favorite', 'heart', 'like', 'love'],
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
// Social icons (FontAwesome)
|
|
88
|
+
{
|
|
89
|
+
name: 'facebook',
|
|
90
|
+
library: IconLibrary.FONTAWESOME,
|
|
91
|
+
category: IconCategory.SOCIAL,
|
|
92
|
+
tags: ['fb', 'social', 'network'],
|
|
93
|
+
searchTerms: ['facebook', 'fb', 'social', 'meta'],
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
name: 'twitter',
|
|
97
|
+
library: IconLibrary.FONTAWESOME,
|
|
98
|
+
category: IconCategory.SOCIAL,
|
|
99
|
+
tags: ['x', 'social', 'tweet'],
|
|
100
|
+
searchTerms: ['twitter', 'x', 'social', 'tweet'],
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: 'instagram',
|
|
104
|
+
library: IconLibrary.FONTAWESOME,
|
|
105
|
+
category: IconCategory.SOCIAL,
|
|
106
|
+
tags: ['ig', 'social', 'photo'],
|
|
107
|
+
searchTerms: ['instagram', 'ig', 'social', 'photo'],
|
|
108
|
+
},
|
|
109
|
+
|
|
110
|
+
// Communication icons (Ionicons)
|
|
111
|
+
{
|
|
112
|
+
name: 'mail',
|
|
113
|
+
library: IconLibrary.IONICONS,
|
|
114
|
+
category: IconCategory.COMMUNICATION,
|
|
115
|
+
tags: ['email', 'message', 'envelope'],
|
|
116
|
+
searchTerms: ['mail', 'email', 'message', 'contact'],
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: 'call',
|
|
120
|
+
library: IconLibrary.IONICONS,
|
|
121
|
+
category: IconCategory.COMMUNICATION,
|
|
122
|
+
tags: ['phone', 'telephone', 'dial'],
|
|
123
|
+
searchTerms: ['call', 'phone', 'telephone', 'dial'],
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
name: 'notifications',
|
|
127
|
+
library: IconLibrary.IONICONS,
|
|
128
|
+
category: IconCategory.COMMUNICATION,
|
|
129
|
+
tags: ['bell', 'alert', 'reminder'],
|
|
130
|
+
searchTerms: ['notifications', 'bell', 'alert', 'reminder'],
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
// Media icons (Material Design)
|
|
134
|
+
{
|
|
135
|
+
name: 'camera',
|
|
136
|
+
library: IconLibrary.MATERIAL,
|
|
137
|
+
category: IconCategory.MEDIA,
|
|
138
|
+
tags: ['photo', 'picture', 'snapshot'],
|
|
139
|
+
searchTerms: ['camera', 'photo', 'picture', 'image'],
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: 'image',
|
|
143
|
+
library: IconLibrary.MATERIAL,
|
|
144
|
+
category: IconCategory.MEDIA,
|
|
145
|
+
tags: ['photo', 'picture', 'gallery'],
|
|
146
|
+
searchTerms: ['image', 'photo', 'picture', 'gallery'],
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
name: 'videocam',
|
|
150
|
+
library: IconLibrary.MATERIAL,
|
|
151
|
+
category: IconCategory.MEDIA,
|
|
152
|
+
tags: ['video', 'camera', 'record'],
|
|
153
|
+
searchTerms: ['video', 'camera', 'record', 'film'],
|
|
154
|
+
},
|
|
155
|
+
];
|
|
156
|
+
|
|
157
|
+
getAllIcons(): IconMetadata[] {
|
|
158
|
+
return this.icons;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
getIconsByCategory(category: IconCategory): IconMetadata[] {
|
|
162
|
+
if (category === IconCategory.ALL) {
|
|
163
|
+
return this.icons;
|
|
164
|
+
}
|
|
165
|
+
return this.icons.filter(icon => icon.category === category);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
searchIcons(query: string): IconMetadata[] {
|
|
169
|
+
if (!query.trim()) {
|
|
170
|
+
return this.icons;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const normalizedQuery = query.toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
174
|
+
|
|
175
|
+
return this.icons.filter(icon => {
|
|
176
|
+
const normalizedName = icon.name.toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
177
|
+
const normalizedTags = icon.tags.map(tag => tag.toLowerCase().replace(/[^a-z0-9]/g, ''));
|
|
178
|
+
const normalizedTerms = icon.searchTerms.map(term => term.toLowerCase().replace(/[^a-z0-9]/g, ''));
|
|
179
|
+
|
|
180
|
+
return (
|
|
181
|
+
normalizedName.includes(normalizedQuery) ||
|
|
182
|
+
normalizedTags.some(tag => tag.includes(normalizedQuery)) ||
|
|
183
|
+
normalizedTerms.some(term => term.includes(normalizedQuery))
|
|
184
|
+
);
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
getIconMetadata(name: string): IconMetadata | null {
|
|
189
|
+
return this.icons.find(icon => icon.name === name) || null;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Universal Icon Component
|
|
3
|
+
*
|
|
4
|
+
* 🎯 SINGLE ICON COMPONENT FOR ALL APPS
|
|
5
|
+
*
|
|
6
|
+
* Automatically uses the icon library configured in IconLibraryConfig.
|
|
7
|
+
* Change library = change config, no code changes needed!
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* import { Icon } from '@domains/icons';
|
|
12
|
+
*
|
|
13
|
+
* // Basic usage
|
|
14
|
+
* <Icon name="Settings" size="md" color="primary" />
|
|
15
|
+
*
|
|
16
|
+
* // Custom size and color
|
|
17
|
+
* <Icon name="Heart" customSize={32} customColor="#FF0000" />
|
|
18
|
+
*
|
|
19
|
+
* // With background
|
|
20
|
+
* <Icon name="Info" size="lg" withBackground backgroundColor="#667eea" />
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* 🔧 To change icon library:
|
|
24
|
+
* 1. Update CURRENT_LIBRARY in domain/config/IconLibraryConfig.ts
|
|
25
|
+
* 2. Done! All apps use new library automatically
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import React from 'react';
|
|
29
|
+
import { View, StyleSheet, StyleProp, ViewStyle } from 'react-native';
|
|
30
|
+
import { useAppDesignTokens } from '../../../../presentation/hooks/useAppDesignTokens';
|
|
31
|
+
import { CURRENT_LIBRARY } from '../../domain/config/IconLibraryConfig';
|
|
32
|
+
import { LucideAdapter } from '../../infrastructure/adapters/LucideAdapter';
|
|
33
|
+
import type { IconProps } from '../../domain/interfaces/IIconAdapter';
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Get adapter based on current library configuration
|
|
37
|
+
*/
|
|
38
|
+
const getAdapter = () => {
|
|
39
|
+
switch (CURRENT_LIBRARY) {
|
|
40
|
+
case 'lucide':
|
|
41
|
+
return LucideAdapter;
|
|
42
|
+
// Future: Add more adapters here
|
|
43
|
+
// case 'material':
|
|
44
|
+
// return MaterialAdapter;
|
|
45
|
+
// case 'fontawesome':
|
|
46
|
+
// return FontAwesomeAdapter;
|
|
47
|
+
default:
|
|
48
|
+
return LucideAdapter;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Universal Icon Component
|
|
54
|
+
*/
|
|
55
|
+
export const Icon: React.FC<IconProps> = ({
|
|
56
|
+
name,
|
|
57
|
+
size = 'md',
|
|
58
|
+
customSize,
|
|
59
|
+
color = 'onSurface',
|
|
60
|
+
customColor,
|
|
61
|
+
strokeWidth,
|
|
62
|
+
withBackground = false,
|
|
63
|
+
backgroundColor,
|
|
64
|
+
accessibilityLabel,
|
|
65
|
+
testID,
|
|
66
|
+
style,
|
|
67
|
+
}) => {
|
|
68
|
+
const tokens = useAppDesignTokens();
|
|
69
|
+
const adapter = getAdapter();
|
|
70
|
+
|
|
71
|
+
// Get icon component from adapter
|
|
72
|
+
const IconComponent = adapter.getIconComponent(name);
|
|
73
|
+
|
|
74
|
+
if (!IconComponent) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Calculate icon size
|
|
79
|
+
const iconSize = adapter.getIconSize(size, customSize);
|
|
80
|
+
|
|
81
|
+
// Get icon color from theme
|
|
82
|
+
const iconColor = adapter.getIconColor(color, tokens, customColor);
|
|
83
|
+
|
|
84
|
+
// Get stroke width (for outline icons)
|
|
85
|
+
const iconStrokeWidth = strokeWidth || adapter.getStrokeWidth?.() || 2;
|
|
86
|
+
|
|
87
|
+
// Container size (slightly larger than icon)
|
|
88
|
+
const containerSize = iconSize + 8;
|
|
89
|
+
|
|
90
|
+
const containerStyles: StyleProp<ViewStyle> = [
|
|
91
|
+
withBackground && {
|
|
92
|
+
width: containerSize,
|
|
93
|
+
height: containerSize,
|
|
94
|
+
borderRadius: containerSize / 2,
|
|
95
|
+
backgroundColor: backgroundColor || tokens.colors.surfaceVariant,
|
|
96
|
+
justifyContent: 'center',
|
|
97
|
+
alignItems: 'center',
|
|
98
|
+
},
|
|
99
|
+
style,
|
|
100
|
+
];
|
|
101
|
+
|
|
102
|
+
const IconElement = (
|
|
103
|
+
<IconComponent
|
|
104
|
+
size={iconSize}
|
|
105
|
+
color={iconColor}
|
|
106
|
+
strokeWidth={iconStrokeWidth}
|
|
107
|
+
accessibilityLabel={accessibilityLabel || `${name} icon`}
|
|
108
|
+
testID={testID}
|
|
109
|
+
/>
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
if (withBackground) {
|
|
113
|
+
return (
|
|
114
|
+
<View style={containerStyles} testID={`${testID}-container`}>
|
|
115
|
+
{IconElement}
|
|
116
|
+
</View>
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return IconElement;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Export icon types for convenience
|
|
125
|
+
*/
|
|
126
|
+
export type { IconProps } from '../../domain/interfaces/IIconAdapter';
|
|
127
|
+
export { type IconSize, type IconColor } from '../../domain/interfaces/IIconAdapter';
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Export current library's icon names for TypeScript autocomplete
|
|
131
|
+
*/
|
|
132
|
+
export type { LucideIconName as IconName } from '../../infrastructure/adapters/LucideAdapter';
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Icons Domain - useIconLibrary Hook
|
|
3
|
+
*
|
|
4
|
+
* React hook for accessing icon libraries (Lucide + Expo vector icons).
|
|
5
|
+
* Provides search, filter, and metadata access for all available icons.
|
|
6
|
+
*
|
|
7
|
+
* @domain icons
|
|
8
|
+
* @layer presentation
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { useMemo, useState, useCallback } from 'react';
|
|
12
|
+
import type { IconMetadata } from '@domains/icons/domain/entities/Icon';
|
|
13
|
+
import { IconLibrary, IconCategory, IconUtils, ICON_CONSTANTS } from '@domains/icons/domain/entities/Icon';
|
|
14
|
+
import { ExpoIconRegistry } from '@domains/icons/infrastructure/registries/ExpoIconRegistry';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Hook for icon library access and search
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* const { icons, searchIcons, filterByCategory } = useIconLibrary();
|
|
21
|
+
*
|
|
22
|
+
* // Search icons
|
|
23
|
+
* const results = searchIcons('home');
|
|
24
|
+
*
|
|
25
|
+
* // Filter by category
|
|
26
|
+
* const navIcons = filterByCategory(IconCategory.NAVIGATION);
|
|
27
|
+
*/
|
|
28
|
+
export const useIconLibrary = (defaultLibrary: IconLibrary = ICON_CONSTANTS.DEFAULT_LIBRARY) => {
|
|
29
|
+
const [selectedLibrary, setSelectedLibrary] = useState<IconLibrary>(defaultLibrary);
|
|
30
|
+
const [selectedCategory, setSelectedCategory] = useState<IconCategory>(IconCategory.ALL);
|
|
31
|
+
|
|
32
|
+
// Initialize registry
|
|
33
|
+
const registry = useMemo(() => new ExpoIconRegistry(), []);
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Get all icons from the selected library
|
|
37
|
+
*/
|
|
38
|
+
const icons = useMemo(() => {
|
|
39
|
+
const allIcons = registry.getAllIcons();
|
|
40
|
+
return selectedLibrary === IconLibrary.LUCIDE
|
|
41
|
+
? [] // Lucide icons are in design-system/AtomicIcon
|
|
42
|
+
: allIcons.filter(icon => icon.library === selectedLibrary);
|
|
43
|
+
}, [registry, selectedLibrary]);
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Get icons filtered by category
|
|
47
|
+
*/
|
|
48
|
+
const iconsByCategory = useMemo(() => {
|
|
49
|
+
return IconUtils.filterByCategory(icons, selectedCategory);
|
|
50
|
+
}, [icons, selectedCategory]);
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Search icons by query
|
|
54
|
+
*/
|
|
55
|
+
const searchIcons = useCallback(
|
|
56
|
+
(query: string): IconMetadata[] => {
|
|
57
|
+
if (!query.trim()) {
|
|
58
|
+
return iconsByCategory;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const results = registry.searchIcons(query);
|
|
62
|
+
const filteredResults = selectedLibrary === IconLibrary.LUCIDE
|
|
63
|
+
? results
|
|
64
|
+
: results.filter(icon => icon.library === selectedLibrary);
|
|
65
|
+
|
|
66
|
+
return IconUtils.filterByCategory(filteredResults, selectedCategory)
|
|
67
|
+
.slice(0, ICON_CONSTANTS.MAX_SEARCH_RESULTS);
|
|
68
|
+
},
|
|
69
|
+
[registry, selectedLibrary, selectedCategory, iconsByCategory]
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Filter icons by category
|
|
74
|
+
*/
|
|
75
|
+
const filterByCategory = useCallback(
|
|
76
|
+
(category: IconCategory): IconMetadata[] => {
|
|
77
|
+
return IconUtils.filterByCategory(icons, category);
|
|
78
|
+
},
|
|
79
|
+
[icons]
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Get icon metadata by name
|
|
84
|
+
*/
|
|
85
|
+
const getIconMetadata = useCallback(
|
|
86
|
+
(name: string): IconMetadata | null => {
|
|
87
|
+
return registry.getIconMetadata(name);
|
|
88
|
+
},
|
|
89
|
+
[registry]
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Get all available categories
|
|
94
|
+
*/
|
|
95
|
+
const availableCategories = useMemo(() => {
|
|
96
|
+
return Object.values(IconCategory);
|
|
97
|
+
}, []);
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Get all available libraries
|
|
101
|
+
*/
|
|
102
|
+
const availableLibraries = useMemo(() => {
|
|
103
|
+
return Object.values(IconLibrary);
|
|
104
|
+
}, []);
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Switch library
|
|
108
|
+
*/
|
|
109
|
+
const switchLibrary = useCallback((library: IconLibrary) => {
|
|
110
|
+
setSelectedLibrary(library);
|
|
111
|
+
}, []);
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Switch category
|
|
115
|
+
*/
|
|
116
|
+
const switchCategory = useCallback((category: IconCategory) => {
|
|
117
|
+
setSelectedCategory(category);
|
|
118
|
+
}, []);
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
// Current state
|
|
122
|
+
selectedLibrary,
|
|
123
|
+
selectedCategory,
|
|
124
|
+
icons: iconsByCategory,
|
|
125
|
+
|
|
126
|
+
// Search & filter
|
|
127
|
+
searchIcons,
|
|
128
|
+
filterByCategory,
|
|
129
|
+
getIconMetadata,
|
|
130
|
+
|
|
131
|
+
// Library & category management
|
|
132
|
+
switchLibrary,
|
|
133
|
+
switchCategory,
|
|
134
|
+
availableCategories,
|
|
135
|
+
availableLibraries,
|
|
136
|
+
|
|
137
|
+
// Constants
|
|
138
|
+
IconLibrary,
|
|
139
|
+
IconCategory,
|
|
140
|
+
};
|
|
141
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -351,3 +351,15 @@ export {
|
|
|
351
351
|
export {
|
|
352
352
|
useDesignSystemTheme,
|
|
353
353
|
} from './infrastructure/theme/globalThemeStore';
|
|
354
|
+
|
|
355
|
+
// =============================================================================
|
|
356
|
+
// ICONS DOMAIN - Universal Icon System
|
|
357
|
+
// =============================================================================
|
|
358
|
+
|
|
359
|
+
export {
|
|
360
|
+
Icon,
|
|
361
|
+
type IconProps,
|
|
362
|
+
type IconSize,
|
|
363
|
+
type IconColor,
|
|
364
|
+
type IconName,
|
|
365
|
+
} from './domains/icons/presentation/components/Icon';
|