@umituz/react-native-design-system 2.5.9 → 2.5.11
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 +1 -1
- package/package.json +3 -1
- package/src/atoms/AtomicButton.tsx +2 -5
- package/src/atoms/AtomicChip.tsx +13 -13
- package/src/atoms/AtomicIcon.tsx +1 -8
- package/src/atoms/AtomicPicker.tsx +6 -5
- package/src/atoms/__tests__/AtomicIcon.test.tsx +0 -6
- package/src/atoms/input/hooks/useInputState.ts +0 -6
- package/src/atoms/picker/components/PickerModal.tsx +15 -6
- package/src/atoms/picker/types/index.ts +17 -4
- package/src/device/detection/deviceDetection.ts +7 -20
- package/src/layouts/ScreenHeader/ScreenHeader.tsx +1 -2
- package/src/molecules/alerts/AlertToast.tsx +1 -1
- package/src/molecules/animation/presentation/hooks/useFireworks.ts +1 -3
- package/src/molecules/animation/presentation/providers/AnimationThemeProvider.tsx +1 -3
- package/src/molecules/avatar/Avatar.tsx +2 -2
- package/src/molecules/bottom-sheet/components/BottomSheetModal.tsx +0 -6
- package/src/molecules/calendar/infrastructure/storage/CalendarStore.ts +243 -245
- package/src/molecules/navigation/StackNavigator.tsx +6 -9
- package/src/molecules/navigation/TabsNavigator.tsx +9 -13
- package/src/molecules/navigation/utils/AppNavigation.ts +0 -2
- package/src/molecules/navigation/utils/LabelProcessor.ts +1 -10
- package/src/molecules/navigation/utils/NavigationCleanup.ts +4 -8
- package/src/molecules/navigation/utils/NavigationValidator.ts +2 -11
- package/src/presentation/utils/variants/compound.ts +0 -4
- package/src/presentation/utils/variants/core.ts +0 -4
- package/src/presentation/utils/variants/helpers.ts +0 -6
- package/src/safe-area/components/SafeAreaProvider.tsx +0 -10
- package/src/safe-area/utils/validation.ts +3 -27
- package/src/theme/core/CustomColors.ts +2 -8
- package/src/theme/core/colors/ColorUtils.ts +0 -6
- package/src/theme/infrastructure/storage/ThemeStorage.ts +2 -16
- package/src/typography/presentation/utils/textColorUtils.ts +0 -3
- package/src/utilities/clipboard/ClipboardUtils.ts +1 -5
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ npm install @umituz/react-native-design-system
|
|
|
23
23
|
### Peer Dependencies
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
|
-
npm install react@18.3.1 react-native@0.76.3 react-native-reanimated@~3.10.1 react-native-svg@^15.0.0
|
|
26
|
+
npm install react@18.3.1 react-native@0.76.3 react-native-reanimated@~3.10.1 react-native-svg@^15.0.0
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
> **v1.3.0 Breaking Change**: React Native Paper dependency removed! All components now use pure React Native implementation for lighter bundle size and full control over styling.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-design-system",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.11",
|
|
4
4
|
"description": "Universal design system for React Native apps - Consolidated package with atoms, molecules, organisms, theme, typography, responsive and safe area utilities",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
"@umituz/react-native-filesystem": "*",
|
|
60
60
|
"@umituz/react-native-haptics": "*",
|
|
61
61
|
"@umituz/react-native-localization": "*",
|
|
62
|
+
"@umituz/react-native-storage": "*",
|
|
62
63
|
"@umituz/react-native-uuid": "*",
|
|
63
64
|
"expo-application": ">=5.0.0",
|
|
64
65
|
"expo-clipboard": ">=8.0.0",
|
|
@@ -112,6 +113,7 @@
|
|
|
112
113
|
"@umituz/react-native-filesystem": "^2.1.7",
|
|
113
114
|
"@umituz/react-native-haptics": "^1.0.2",
|
|
114
115
|
"@umituz/react-native-localization": "^3.5.34",
|
|
116
|
+
"@umituz/react-native-storage": "latest",
|
|
115
117
|
"@umituz/react-native-uuid": "*",
|
|
116
118
|
"eslint": "^9.39.2",
|
|
117
119
|
"eslint-plugin-react": "^7.37.5",
|
|
@@ -41,9 +41,6 @@ export const AtomicButton: React.FC<AtomicButtonProps> = React.memo(({
|
|
|
41
41
|
|
|
42
42
|
const handlePress = () => {
|
|
43
43
|
if (!disabled) {
|
|
44
|
-
if (__DEV__) {
|
|
45
|
-
console.log('[AtomicButton] Button pressed:', { title, variant, disabled });
|
|
46
|
-
}
|
|
47
44
|
onPress();
|
|
48
45
|
}
|
|
49
46
|
};
|
|
@@ -115,7 +112,7 @@ export const AtomicButton: React.FC<AtomicButtonProps> = React.memo(({
|
|
|
115
112
|
return {
|
|
116
113
|
container: {
|
|
117
114
|
...baseStyle,
|
|
118
|
-
backgroundColor:
|
|
115
|
+
backgroundColor: undefined,
|
|
119
116
|
borderWidth: 1,
|
|
120
117
|
borderColor: tokens.colors.border,
|
|
121
118
|
},
|
|
@@ -129,7 +126,7 @@ export const AtomicButton: React.FC<AtomicButtonProps> = React.memo(({
|
|
|
129
126
|
return {
|
|
130
127
|
container: {
|
|
131
128
|
...baseStyle,
|
|
132
|
-
backgroundColor:
|
|
129
|
+
backgroundColor: undefined,
|
|
133
130
|
},
|
|
134
131
|
text: {
|
|
135
132
|
...baseTextStyle,
|
package/src/atoms/AtomicChip.tsx
CHANGED
|
@@ -108,37 +108,37 @@ export const AtomicChip: React.FC<AtomicChipProps> = React.memo(({
|
|
|
108
108
|
|
|
109
109
|
const sizeConfig = sizeMap[size];
|
|
110
110
|
|
|
111
|
-
// Color mapping
|
|
111
|
+
// Color mapping - using undefined for transparent backgrounds
|
|
112
112
|
const colorMap = {
|
|
113
113
|
primary: {
|
|
114
114
|
filled: { bg: tokens.colors.primary, text: tokens.colors.onPrimary, border: tokens.colors.primary },
|
|
115
|
-
outlined: { bg:
|
|
116
|
-
soft: { bg: tokens.colors.primaryContainer, text: tokens.colors.onPrimaryContainer, border:
|
|
115
|
+
outlined: { bg: undefined, text: tokens.colors.primary, border: tokens.colors.primary },
|
|
116
|
+
soft: { bg: tokens.colors.primaryContainer, text: tokens.colors.onPrimaryContainer, border: undefined },
|
|
117
117
|
},
|
|
118
118
|
secondary: {
|
|
119
119
|
filled: { bg: tokens.colors.secondary, text: tokens.colors.onSecondary, border: tokens.colors.secondary },
|
|
120
|
-
outlined: { bg:
|
|
121
|
-
soft: { bg: tokens.colors.secondaryContainer, text: tokens.colors.onSecondaryContainer, border:
|
|
120
|
+
outlined: { bg: undefined, text: tokens.colors.secondary, border: tokens.colors.secondary },
|
|
121
|
+
soft: { bg: tokens.colors.secondaryContainer, text: tokens.colors.onSecondaryContainer, border: undefined },
|
|
122
122
|
},
|
|
123
123
|
success: {
|
|
124
124
|
filled: { bg: tokens.colors.success, text: tokens.colors.onSuccess, border: tokens.colors.success },
|
|
125
|
-
outlined: { bg:
|
|
126
|
-
soft: { bg: tokens.colors.successContainer, text: tokens.colors.onSuccessContainer, border:
|
|
125
|
+
outlined: { bg: undefined, text: tokens.colors.success, border: tokens.colors.success },
|
|
126
|
+
soft: { bg: tokens.colors.successContainer, text: tokens.colors.onSuccessContainer, border: undefined },
|
|
127
127
|
},
|
|
128
128
|
warning: {
|
|
129
129
|
filled: { bg: tokens.colors.warning, text: tokens.colors.onWarning, border: tokens.colors.warning },
|
|
130
|
-
outlined: { bg:
|
|
131
|
-
soft: { bg: tokens.colors.warningContainer, text: tokens.colors.onWarningContainer, border:
|
|
130
|
+
outlined: { bg: undefined, text: tokens.colors.warning, border: tokens.colors.warning },
|
|
131
|
+
soft: { bg: tokens.colors.warningContainer, text: tokens.colors.onWarningContainer, border: undefined },
|
|
132
132
|
},
|
|
133
133
|
error: {
|
|
134
134
|
filled: { bg: tokens.colors.error, text: tokens.colors.onError, border: tokens.colors.error },
|
|
135
|
-
outlined: { bg:
|
|
136
|
-
soft: { bg: tokens.colors.errorContainer, text: tokens.colors.onErrorContainer, border:
|
|
135
|
+
outlined: { bg: undefined, text: tokens.colors.error, border: tokens.colors.error },
|
|
136
|
+
soft: { bg: tokens.colors.errorContainer, text: tokens.colors.onErrorContainer, border: undefined },
|
|
137
137
|
},
|
|
138
138
|
info: {
|
|
139
139
|
filled: { bg: tokens.colors.info, text: tokens.colors.onInfo, border: tokens.colors.info },
|
|
140
|
-
outlined: { bg:
|
|
141
|
-
soft: { bg: tokens.colors.infoContainer, text: tokens.colors.onInfoContainer, border:
|
|
140
|
+
outlined: { bg: undefined, text: tokens.colors.info, border: tokens.colors.info },
|
|
141
|
+
soft: { bg: tokens.colors.infoContainer, text: tokens.colors.onInfoContainer, border: undefined },
|
|
142
142
|
},
|
|
143
143
|
};
|
|
144
144
|
|
package/src/atoms/AtomicIcon.tsx
CHANGED
|
@@ -122,17 +122,10 @@ export const AtomicIcon: React.FC<AtomicIconProps> = React.memo(({
|
|
|
122
122
|
? getSemanticColor(color, tokens)
|
|
123
123
|
: tokens.colors.textPrimary;
|
|
124
124
|
|
|
125
|
-
// Validate icon
|
|
125
|
+
// Validate icon - use fallback silently if invalid
|
|
126
126
|
const isValidIcon = name in Ionicons.glyphMap;
|
|
127
127
|
const iconName = isValidIcon ? name : FALLBACK_ICON;
|
|
128
128
|
|
|
129
|
-
if (__DEV__ && !isValidIcon) {
|
|
130
|
-
console.warn(
|
|
131
|
-
`[AtomicIcon] Invalid icon name: "${name}". Using fallback icon "${FALLBACK_ICON}". ` +
|
|
132
|
-
`Available icons: https://icons.expo.fyi/`
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
129
|
const iconElement = (
|
|
137
130
|
<Ionicons
|
|
138
131
|
name={iconName as keyof typeof Ionicons.glyphMap}
|
|
@@ -73,7 +73,7 @@ export const AtomicPicker: React.FC<AtomicPickerProps> = ({
|
|
|
73
73
|
onChange,
|
|
74
74
|
options,
|
|
75
75
|
label,
|
|
76
|
-
placeholder
|
|
76
|
+
placeholder,
|
|
77
77
|
error,
|
|
78
78
|
disabled = false,
|
|
79
79
|
multiple = false,
|
|
@@ -82,9 +82,10 @@ export const AtomicPicker: React.FC<AtomicPickerProps> = ({
|
|
|
82
82
|
autoClose = true,
|
|
83
83
|
size = 'md',
|
|
84
84
|
modalTitle,
|
|
85
|
-
emptyMessage
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
emptyMessage,
|
|
86
|
+
searchPlaceholder,
|
|
87
|
+
clearAccessibilityLabel,
|
|
88
|
+
closeAccessibilityLabel,
|
|
88
89
|
style,
|
|
89
90
|
labelStyle,
|
|
90
91
|
testID,
|
|
@@ -294,7 +295,7 @@ export const AtomicPicker: React.FC<AtomicPickerProps> = ({
|
|
|
294
295
|
filteredOptions={filteredOptions}
|
|
295
296
|
multiple={multiple}
|
|
296
297
|
emptyMessage={emptyMessage}
|
|
297
|
-
searchPlaceholder=
|
|
298
|
+
searchPlaceholder={searchPlaceholder}
|
|
298
299
|
closeAccessibilityLabel={closeAccessibilityLabel}
|
|
299
300
|
testID={testID}
|
|
300
301
|
/>
|
|
@@ -18,12 +18,6 @@ jest.mock('@umituz/react-native-design-system-theme', () => ({
|
|
|
18
18
|
}),
|
|
19
19
|
}));
|
|
20
20
|
|
|
21
|
-
// Mock Lucide icons
|
|
22
|
-
jest.mock('lucide-react-native', () => ({
|
|
23
|
-
Settings: () => 'Settings-Icon',
|
|
24
|
-
Heart: () => 'Heart-Icon',
|
|
25
|
-
}));
|
|
26
|
-
|
|
27
21
|
describe('AtomicIcon', () => {
|
|
28
22
|
it('renders with default props', () => {
|
|
29
23
|
const { getByTestId } = render(
|
|
@@ -35,17 +35,11 @@ export const useInputState = ({
|
|
|
35
35
|
const [isPasswordVisible, setIsPasswordVisible] = useState(!secureTextEntry);
|
|
36
36
|
|
|
37
37
|
const handleTextChange = useCallback((text: string) => {
|
|
38
|
-
if (__DEV__) {
|
|
39
|
-
console.log('[useInputState] Text changed:', { text, length: text.length });
|
|
40
|
-
}
|
|
41
38
|
setLocalValue(text);
|
|
42
39
|
onChangeText?.(text);
|
|
43
40
|
}, [onChangeText]);
|
|
44
41
|
|
|
45
42
|
const togglePasswordVisibility = useCallback(() => {
|
|
46
|
-
if (__DEV__) {
|
|
47
|
-
console.log('[useInputState] Password visibility toggled');
|
|
48
|
-
}
|
|
49
43
|
setIsPasswordVisible((prev) => !prev);
|
|
50
44
|
}, []);
|
|
51
45
|
|
|
@@ -38,6 +38,12 @@ import {
|
|
|
38
38
|
getEmptyStateTextStyles,
|
|
39
39
|
} from '../styles/pickerStyles';
|
|
40
40
|
|
|
41
|
+
/**
|
|
42
|
+
* PickerModalProps
|
|
43
|
+
*
|
|
44
|
+
* IMPORTANT: String props are REQUIRED for proper i18n support.
|
|
45
|
+
* Pass translated strings from your app's i18n system.
|
|
46
|
+
*/
|
|
41
47
|
interface PickerModalProps {
|
|
42
48
|
visible: boolean;
|
|
43
49
|
onClose: () => void;
|
|
@@ -50,9 +56,12 @@ interface PickerModalProps {
|
|
|
50
56
|
onSearchChange: (query: string) => void;
|
|
51
57
|
filteredOptions: PickerOption[];
|
|
52
58
|
multiple?: boolean;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
59
|
+
/** Empty state message - REQUIRED for i18n */
|
|
60
|
+
emptyMessage: string;
|
|
61
|
+
/** Search placeholder - REQUIRED for i18n */
|
|
62
|
+
searchPlaceholder: string;
|
|
63
|
+
/** Close accessibility label - REQUIRED for i18n */
|
|
64
|
+
closeAccessibilityLabel: string;
|
|
56
65
|
testID?: string;
|
|
57
66
|
}
|
|
58
67
|
|
|
@@ -66,9 +75,9 @@ export const PickerModal: React.FC<PickerModalProps> = React.memo(({
|
|
|
66
75
|
searchQuery,
|
|
67
76
|
onSearchChange,
|
|
68
77
|
filteredOptions,
|
|
69
|
-
emptyMessage
|
|
70
|
-
searchPlaceholder
|
|
71
|
-
closeAccessibilityLabel
|
|
78
|
+
emptyMessage,
|
|
79
|
+
searchPlaceholder,
|
|
80
|
+
closeAccessibilityLabel,
|
|
72
81
|
testID,
|
|
73
82
|
}) => {
|
|
74
83
|
const tokens = useAppDesignTokens();
|
|
@@ -18,12 +18,20 @@ export interface PickerOption {
|
|
|
18
18
|
|
|
19
19
|
export type PickerSize = 'sm' | 'md' | 'lg';
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* AtomicPickerProps
|
|
23
|
+
*
|
|
24
|
+
* IMPORTANT: String props (placeholder, emptyMessage, etc.) are REQUIRED
|
|
25
|
+
* for proper i18n support. Pass translated strings from your app's i18n system.
|
|
26
|
+
* Do NOT rely on default English values.
|
|
27
|
+
*/
|
|
21
28
|
export interface AtomicPickerProps {
|
|
22
29
|
value: string | string[];
|
|
23
30
|
onChange: (value: string | string[]) => void;
|
|
24
31
|
options: PickerOption[];
|
|
25
32
|
label?: string;
|
|
26
|
-
|
|
33
|
+
/** Placeholder text - REQUIRED for i18n, pass translated string */
|
|
34
|
+
placeholder: string;
|
|
27
35
|
error?: string;
|
|
28
36
|
disabled?: boolean;
|
|
29
37
|
multiple?: boolean;
|
|
@@ -33,9 +41,14 @@ export interface AtomicPickerProps {
|
|
|
33
41
|
color?: IconColor;
|
|
34
42
|
size?: PickerSize;
|
|
35
43
|
modalTitle?: string;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
44
|
+
/** Empty state message - REQUIRED for i18n, pass translated string */
|
|
45
|
+
emptyMessage: string;
|
|
46
|
+
/** Search placeholder text - REQUIRED for i18n, pass translated string */
|
|
47
|
+
searchPlaceholder: string;
|
|
48
|
+
/** Clear button accessibility label - REQUIRED for i18n, pass translated string */
|
|
49
|
+
clearAccessibilityLabel: string;
|
|
50
|
+
/** Close button accessibility label - REQUIRED for i18n, pass translated string */
|
|
51
|
+
closeAccessibilityLabel: string;
|
|
39
52
|
style?: ViewStyle | ViewStyle[];
|
|
40
53
|
labelStyle?: TextStyle | TextStyle[];
|
|
41
54
|
testID?: string;
|
|
@@ -13,20 +13,15 @@ import { validateScreenDimensions } from '../../responsive/validation';
|
|
|
13
13
|
* Helper function for device detection with fallback
|
|
14
14
|
* @param operation - Operation to perform
|
|
15
15
|
* @param fallback - Fallback value if operation fails
|
|
16
|
-
* @param warningMessage - Warning message for __DEV__
|
|
17
16
|
* @returns Operation result or fallback
|
|
18
17
|
*/
|
|
19
18
|
const withDeviceDetectionFallback = <T>(
|
|
20
19
|
operation: () => T,
|
|
21
|
-
fallback: T
|
|
22
|
-
warningMessage: string
|
|
20
|
+
fallback: T
|
|
23
21
|
): T => {
|
|
24
22
|
try {
|
|
25
23
|
return operation();
|
|
26
24
|
} catch {
|
|
27
|
-
if (__DEV__) {
|
|
28
|
-
console.warn(`[DeviceDetection] ${warningMessage}`);
|
|
29
|
-
}
|
|
30
25
|
return fallback;
|
|
31
26
|
}
|
|
32
27
|
};
|
|
@@ -53,9 +48,6 @@ export const getScreenDimensions = () => {
|
|
|
53
48
|
validateScreenDimensions(width, height);
|
|
54
49
|
return { width, height };
|
|
55
50
|
} catch {
|
|
56
|
-
if (__DEV__) {
|
|
57
|
-
console.warn('[getScreenDimensions] Invalid screen dimensions detected, using fallback values');
|
|
58
|
-
}
|
|
59
51
|
// Fallback to safe default dimensions
|
|
60
52
|
return { width: 414, height: 896 };
|
|
61
53
|
}
|
|
@@ -71,8 +63,7 @@ export const isSmallPhone = (): boolean => {
|
|
|
71
63
|
const { width } = getScreenDimensions();
|
|
72
64
|
return width <= DEVICE_BREAKPOINTS.SMALL_PHONE;
|
|
73
65
|
},
|
|
74
|
-
false
|
|
75
|
-
'Error detecting device type, assuming standard phone'
|
|
66
|
+
false
|
|
76
67
|
);
|
|
77
68
|
};
|
|
78
69
|
|
|
@@ -86,8 +77,7 @@ export const isTablet = (): boolean => {
|
|
|
86
77
|
const { width } = getScreenDimensions();
|
|
87
78
|
return width >= DEVICE_BREAKPOINTS.SMALL_TABLET;
|
|
88
79
|
},
|
|
89
|
-
false
|
|
90
|
-
'Error detecting device type, assuming phone'
|
|
80
|
+
false
|
|
91
81
|
);
|
|
92
82
|
};
|
|
93
83
|
|
|
@@ -101,8 +91,7 @@ export const isLandscape = (): boolean => {
|
|
|
101
91
|
const { width, height } = getScreenDimensions();
|
|
102
92
|
return width > height;
|
|
103
93
|
},
|
|
104
|
-
false
|
|
105
|
-
'Error detecting orientation, assuming portrait'
|
|
94
|
+
false
|
|
106
95
|
);
|
|
107
96
|
};
|
|
108
97
|
|
|
@@ -125,15 +114,14 @@ export const getDeviceType = (): DeviceType => {
|
|
|
125
114
|
|
|
126
115
|
return DeviceType.TABLET;
|
|
127
116
|
},
|
|
128
|
-
DeviceType.MEDIUM_PHONE
|
|
129
|
-
'Error detecting device type, assuming medium phone'
|
|
117
|
+
DeviceType.MEDIUM_PHONE
|
|
130
118
|
);
|
|
131
119
|
};
|
|
132
120
|
|
|
133
121
|
/**
|
|
134
122
|
* Responsive spacing multiplier
|
|
135
123
|
* Returns a multiplier for spacing based on device size
|
|
136
|
-
*
|
|
124
|
+
*
|
|
137
125
|
* @returns Spacing multiplier (0.9-1.2)
|
|
138
126
|
*/
|
|
139
127
|
export const getSpacingMultiplier = (): number => {
|
|
@@ -149,7 +137,6 @@ export const getSpacingMultiplier = (): number => {
|
|
|
149
137
|
|
|
150
138
|
return LAYOUT_CONSTANTS.SPACING_MULTIPLIER_STANDARD;
|
|
151
139
|
},
|
|
152
|
-
LAYOUT_CONSTANTS.SPACING_MULTIPLIER_STANDARD
|
|
153
|
-
'Error calculating spacing multiplier, using fallback'
|
|
140
|
+
LAYOUT_CONSTANTS.SPACING_MULTIPLIER_STANDARD
|
|
154
141
|
);
|
|
155
142
|
};
|
|
@@ -74,9 +74,8 @@ const ScreenHeaderBackButton: React.FC<{
|
|
|
74
74
|
const handleBackPress = React.useCallback(() => {
|
|
75
75
|
if (onBackPress) {
|
|
76
76
|
onBackPress();
|
|
77
|
-
} else if (__DEV__) {
|
|
78
|
-
console.warn('ScreenHeader: onBackPress is required when back button is visible');
|
|
79
77
|
}
|
|
78
|
+
// If no onBackPress provided, do nothing silently
|
|
80
79
|
}, [onBackPress]);
|
|
81
80
|
|
|
82
81
|
if (hideBackButton) return null;
|
|
@@ -48,7 +48,7 @@ export function AlertToast({ alert }: AlertToastProps) {
|
|
|
48
48
|
return { backgroundColor: tokens.colors.backgroundPrimary };
|
|
49
49
|
case 'secondary':
|
|
50
50
|
return {
|
|
51
|
-
backgroundColor:
|
|
51
|
+
backgroundColor: undefined,
|
|
52
52
|
borderWidth: 1,
|
|
53
53
|
borderColor: tokens.colors.textInverse,
|
|
54
54
|
};
|
|
@@ -38,9 +38,7 @@ export const useFireworks = (config: FireworksConfig) => {
|
|
|
38
38
|
} = config;
|
|
39
39
|
|
|
40
40
|
if (!colors || colors.length === 0) {
|
|
41
|
-
|
|
42
|
-
console.warn('useFireworks: colors array is required and cannot be empty');
|
|
43
|
-
}
|
|
41
|
+
// Return no-op when colors not provided
|
|
44
42
|
return { particles: [], trigger: () => { }, isActive: false };
|
|
45
43
|
}
|
|
46
44
|
|
|
@@ -50,9 +50,7 @@ export const AnimationThemeProvider: React.FC<AnimationThemeProviderProps> = ({
|
|
|
50
50
|
export const useAnimationTheme = (): ThemeContext => {
|
|
51
51
|
const context = useContext(ThemeContext);
|
|
52
52
|
if (!context) {
|
|
53
|
-
if
|
|
54
|
-
console.warn('useAnimationTheme must be used within AnimationThemeProvider');
|
|
55
|
-
}
|
|
53
|
+
// Return default theme if used outside provider
|
|
56
54
|
return {
|
|
57
55
|
theme: DEFAULT_ANIMATION_THEME,
|
|
58
56
|
setTheme: () => {},
|
|
@@ -129,7 +129,7 @@ export const Avatar: React.FC<AvatarProps> = ({
|
|
|
129
129
|
styles.initials,
|
|
130
130
|
{
|
|
131
131
|
fontSize: config.fontSize,
|
|
132
|
-
color:
|
|
132
|
+
color: tokens.colors.textInverse,
|
|
133
133
|
},
|
|
134
134
|
]}
|
|
135
135
|
>
|
|
@@ -143,7 +143,7 @@ export const Avatar: React.FC<AvatarProps> = ({
|
|
|
143
143
|
<AtomicIcon
|
|
144
144
|
name={icon}
|
|
145
145
|
customSize={config.iconSize}
|
|
146
|
-
customColor=
|
|
146
|
+
customColor={tokens.colors.textInverse}
|
|
147
147
|
/>
|
|
148
148
|
);
|
|
149
149
|
};
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
declare const __DEV__: boolean;
|
|
2
|
-
|
|
3
1
|
import React, { forwardRef, useCallback, useMemo, useImperativeHandle, useRef } from 'react';
|
|
4
2
|
import { StyleSheet } from 'react-native';
|
|
5
3
|
import {
|
|
@@ -78,10 +76,6 @@ export const BottomSheetModal = forwardRef<BottomSheetModalRef, BottomSheetModal
|
|
|
78
76
|
|
|
79
77
|
useImperativeHandle(ref, () => ({
|
|
80
78
|
present: () => {
|
|
81
|
-
if (__DEV__) {
|
|
82
|
-
console.log('[BottomSheetModal] present() called');
|
|
83
|
-
console.log('[BottomSheetModal] modalRef.current:', modalRef.current);
|
|
84
|
-
}
|
|
85
79
|
modalRef.current?.present();
|
|
86
80
|
},
|
|
87
81
|
dismiss: () => modalRef.current?.dismiss(),
|