@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.
- package/package.json +1 -1
- package/src/atoms/AtomicFab.tsx +1 -1
- package/src/atoms/EmptyState.tsx +1 -1
- package/src/atoms/{AtomicBadge.tsx → badge/AtomicBadge.tsx} +3 -3
- package/src/atoms/badge/index.ts +6 -0
- package/src/atoms/button/AtomicButton.tsx +1 -1
- package/src/atoms/button/types/index.ts +1 -1
- package/src/atoms/card/AtomicCard.tsx +3 -2
- package/src/atoms/chip/AtomicChip.tsx +1 -1
- package/src/atoms/chip/types/index.ts +1 -1
- package/src/atoms/datepicker/components/DatePickerButton.tsx +3 -2
- package/src/atoms/{AtomicIcon.tsx → icon/AtomicIcon.tsx} +2 -2
- package/src/atoms/icon/iconStore.ts +119 -0
- package/src/atoms/icon/index.ts +35 -0
- package/src/atoms/index.ts +14 -9
- package/src/atoms/input/components/InputIcon.tsx +1 -1
- package/src/atoms/input/types.ts +1 -1
- package/src/atoms/picker/components/PickerChips.tsx +3 -2
- package/src/atoms/picker/components/PickerIcons.tsx +6 -3
- package/src/atoms/picker/components/PickerModal.tsx +10 -6
- package/src/atoms/picker/types/index.ts +1 -1
- package/src/exception/presentation/components/ExceptionErrorState.tsx +7 -3
- package/src/exports/atoms.ts +6 -3
- package/src/image/presentation/components/editor/FilterPickerSheet.tsx +6 -5
- package/src/image/presentation/components/editor/TextEditorSheet.tsx +1 -1
- package/src/image/presentation/components/editor/TextEditorTabs.tsx +1 -2
- package/src/molecules/SearchBar/SearchBar.tsx +5 -3
- package/src/molecules/SearchBar/SearchHistory.tsx +5 -3
- package/src/molecules/action-footer/ActionFooter.tsx +1 -1
- package/src/molecules/alerts/AlertBanner.tsx +3 -2
- package/src/molecules/alerts/AlertToast.tsx +3 -2
- package/src/molecules/bottom-sheet/components/filter/FilterBottomSheet.tsx +5 -3
- package/src/molecules/bottom-sheet/components/filter/FilterSheetComponents/FilterSheetHeader.tsx +13 -9
- package/src/molecules/bottom-sheet/components/filter/FilterSheetComponents/FilterSheetOption.tsx +8 -4
- package/src/molecules/circular-menu/CircularMenuCloseButton.tsx +3 -2
- package/src/molecules/countdown/components/Countdown.tsx +1 -1
- package/src/molecules/countdown/components/CountdownHeader.tsx +4 -3
- package/src/molecules/info-grid/InfoGrid.tsx +1 -1
- package/src/molecules/navigation/components/NavigationHeader.tsx +3 -2
- package/src/molecules/navigation/hooks/useTabConfig.ts +1 -1
- package/src/molecules/navigation/types.ts +1 -1
- package/src/molecules/navigation/utils/IconRenderer.ts +1 -2
- package/src/onboarding/presentation/components/OnboardingHeader.tsx +3 -2
- package/src/onboarding/presentation/components/OnboardingResetSetting.tsx +1 -2
- package/src/onboarding/presentation/components/OnboardingSlide.tsx +3 -2
- package/src/onboarding/presentation/components/QuestionSlideHeader.tsx +1 -2
- package/src/onboarding/presentation/components/questions/QuestionOptionItem.tsx +1 -2
- package/src/onboarding/presentation/components/questions/RatingQuestion.tsx +1 -2
- package/src/onboarding/presentation/components/questions/SingleChoiceQuestion.tsx +1 -2
- package/src/theme/core/TokenFactory.ts +1 -1
- package/src/theme/index.ts +1 -1
- package/src/theme/infrastructure/providers/DesignSystemProvider.tsx +15 -85
- package/src/atoms/IconRegistry.tsx +0 -102
- /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
|
|
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=
|
|
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=
|
|
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
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
172
|
+
<AtomicIcon name={closeIcon} size="md" color="textPrimary" />
|
|
171
173
|
</TouchableOpacity>
|
|
172
174
|
</View>
|
|
173
175
|
|
package/src/molecules/bottom-sheet/components/filter/FilterSheetComponents/FilterSheetHeader.tsx
CHANGED
|
@@ -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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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: {
|
package/src/molecules/bottom-sheet/components/filter/FilterSheetComponents/FilterSheetOption.tsx
CHANGED
|
@@ -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=
|
|
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=
|
|
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
|
|
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
|
|
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=
|
|
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
|
|
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=
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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=
|
|
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
|
|
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
|
|
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=
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
package/src/theme/index.ts
CHANGED
|
@@ -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/
|
|
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 {
|
|
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
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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',
|
|
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
|
-
|
|
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
|
-
//
|
|
96
|
-
if (
|
|
97
|
-
|
|
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);
|
|
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
|
-
{
|
|
110
|
+
{content}
|
|
181
111
|
</SafeAreaProvider>
|
|
182
112
|
</GestureHandlerRootView>
|
|
183
113
|
);
|