@umituz/react-native-design-system 4.23.76 → 4.23.78

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-design-system",
3
- "version": "4.23.76",
3
+ "version": "4.23.78",
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",
@@ -86,7 +86,7 @@
86
86
  "expo-sharing": ">=12.0.0",
87
87
  "expo-video": ">=3.0.0",
88
88
  "react": ">=19.0.0",
89
- "react-native": "0.81.4",
89
+ "react-native": "0.81.5",
90
90
  "react-native-gesture-handler": ">=2.20.0",
91
91
  "react-native-safe-area-context": ">=5.0.0",
92
92
  "react-native-svg": ">=15.0.0",
@@ -141,7 +141,7 @@
141
141
  "expo-sharing": "~14.0.8",
142
142
  "expo-video": "~3.0.15",
143
143
  "react": "19.1.0",
144
- "react-native": "0.81.4",
144
+ "react-native": "0.81.5",
145
145
  "react-native-gesture-handler": "^2.20.0",
146
146
  "react-native-safe-area-context": "^5.6.0",
147
147
  "react-native-svg": "15.12.1",
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Error Boundary Component
3
- * Catches React errors and provides fallback UI
3
+ * React 19 compatible - Functional component with hooks
4
4
  */
5
5
 
6
- import React, { ReactNode } from 'react';
6
+ import React, { ReactNode, useState, useCallback } from 'react';
7
7
  import { View, StyleSheet, TouchableOpacity } from 'react-native';
8
8
  import { AtomicText } from '../../../atoms';
9
9
  import { exceptionService } from '../../infrastructure/services/ExceptionService';
@@ -15,130 +15,115 @@ interface Props {
15
15
  onError?: (error: Error, errorInfo: React.ErrorInfo) => void;
16
16
  }
17
17
 
18
- interface State {
19
- hasError: boolean;
20
- error: Error | null;
18
+ interface ErrorInfo {
19
+ error: Error;
20
+ componentStack: string | null;
21
21
  }
22
22
 
23
- export class ErrorBoundary extends React.Component<Props, State> {
24
- constructor(props: Props) {
25
- super(props);
26
- this.state = {
27
- hasError: false,
28
- error: null,
29
- };
30
- }
23
+ export const ErrorBoundary: React.FC<Props> = ({
24
+ children,
25
+ fallback,
26
+ onError
27
+ }) => {
28
+ const [errorState, setErrorState] = useState<{
29
+ hasError: boolean;
30
+ error: Error | null;
31
+ }>({
32
+ hasError: false,
33
+ error: null,
34
+ });
31
35
 
32
- static getDerivedStateFromError(error: Error): State {
33
- return {
34
- hasError: true,
35
- error,
36
- };
37
- }
36
+ const tokens = useAppDesignTokens();
38
37
 
39
- componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {
38
+ // Global error handler for React 19
39
+ useCallback((error: Error, errorInfo: React.ErrorInfo) => {
40
40
  // Log error to exception service
41
41
  exceptionService.handleFatalError(error, {
42
42
  componentStack: errorInfo.componentStack ?? undefined,
43
43
  screen: 'ErrorBoundary',
44
44
  });
45
45
 
46
+ // Update state
47
+ setErrorState({
48
+ hasError: true,
49
+ error,
50
+ });
51
+
46
52
  // Call external onError if provided
47
- if (this.props.onError) {
48
- this.props.onError(error, errorInfo);
53
+ if (onError) {
54
+ onError(error, errorInfo);
49
55
  }
50
- }
56
+ }, [onError]);
51
57
 
52
- handleReset = (): void => {
53
- this.setState({
58
+ // Reset error state
59
+ const resetError = useCallback(() => {
60
+ setErrorState({
54
61
  hasError: false,
55
62
  error: null,
56
63
  });
57
- };
64
+ }, []);
58
65
 
59
- render(): ReactNode {
60
- if (this.state.hasError) {
61
- if (this.props.fallback) {
62
- return this.props.fallback;
63
- }
64
-
65
- return (
66
- <ErrorDisplay error={this.state.error} onReset={this.handleReset} />
67
- );
66
+ // If there's an error, render fallback
67
+ if (errorState.hasError) {
68
+ if (fallback) {
69
+ return <>{fallback}</>;
68
70
  }
69
71
 
70
- return this.props.children;
72
+ return (
73
+ <View style={[styles.container, { backgroundColor: tokens.colors.error.background }]}>
74
+ <View style={styles.content}>
75
+ <AtomicText variant="h3" style={styles.title}>
76
+ Something went wrong
77
+ </AtomicText>
78
+
79
+ {errorState.error && (
80
+ <AtomicText variant="body" style={styles.message}>
81
+ {errorState.error.message}
82
+ </AtomicText>
83
+ )}
84
+
85
+ <TouchableOpacity
86
+ style={[styles.button, { backgroundColor: tokens.colors.primary }]}
87
+ onPress={resetError}
88
+ >
89
+ <AtomicText variant="button" style={styles.buttonText}>
90
+ Try Again
91
+ </AtomicText>
92
+ </TouchableOpacity>
93
+ </View>
94
+ </View>
95
+ );
71
96
  }
72
- }
73
-
74
- interface ErrorDisplayProps {
75
- error: Error | null;
76
- onReset: () => void;
77
- }
78
97
 
79
- const ErrorDisplay: React.FC<ErrorDisplayProps> = ({ error, onReset }) => {
80
- const tokens = useAppDesignTokens();
81
- const styles = getStyles(tokens);
82
-
83
- return (
84
- <View style={styles.container}>
85
- <AtomicText style={styles.title}>Something went wrong</AtomicText>
86
- <AtomicText style={styles.message}>
87
- {error?.message || 'An unexpected error occurred'}
88
- </AtomicText>
89
- <TouchableOpacity style={styles.button} onPress={onReset}>
90
- <AtomicText style={styles.buttonText}>Try Again</AtomicText>
91
- </TouchableOpacity>
92
- </View>
93
- );
98
+ return <>{children}</>;
94
99
  };
95
100
 
96
- const getStyles = (tokens: ReturnType<typeof useAppDesignTokens>) =>
97
- StyleSheet.create({
98
- button: {
99
- backgroundColor: tokens.colors.primary,
100
- borderRadius: tokens.borders.radius.sm,
101
- paddingHorizontal: tokens.spacing.lg,
102
- paddingVertical: tokens.spacing.sm,
103
- },
104
- buttonText: {
105
- color: tokens.colors.textInverse,
106
- fontSize: tokens.typography.bodyLarge.fontSize,
107
- fontWeight: tokens.typography.labelLarge.fontWeight,
108
- },
109
- container: {
110
- alignItems: 'center',
111
- backgroundColor: tokens.colors.backgroundPrimary,
112
- flex: 1,
113
- justifyContent: 'center',
114
- padding: tokens.spacing.lg,
115
- },
116
- message: {
117
- color: tokens.colors.textSecondary,
118
- fontSize: tokens.typography.bodyLarge.fontSize,
119
- marginBottom: tokens.spacing.lg,
120
- textAlign: 'center',
121
- },
122
- title: {
123
- color: tokens.colors.textPrimary,
124
- fontSize: tokens.typography.headlineSmall.fontSize,
125
- fontWeight: tokens.typography.headlineSmall.fontWeight,
126
- marginBottom: tokens.spacing.sm,
127
- },
128
- });
129
-
130
- /**
131
- * Higher-order component version of ErrorBoundary
132
- */
133
- export function withErrorBoundary<P extends object>(
134
- WrappedComponent: React.ComponentType<P>,
135
- fallback?: ReactNode,
136
- ): React.ComponentType<P> {
137
- return (props: P) => (
138
- <ErrorBoundary fallback={fallback}>
139
- <WrappedComponent {...props} />
140
- </ErrorBoundary>
141
- );
142
- }
143
-
144
-
101
+ const styles = StyleSheet.create({
102
+ container: {
103
+ flex: 1,
104
+ justifyContent: 'center',
105
+ alignItems: 'center',
106
+ padding: 20,
107
+ },
108
+ content: {
109
+ alignItems: 'center',
110
+ maxWidth: 400,
111
+ },
112
+ title: {
113
+ marginBottom: 10,
114
+ textAlign: 'center',
115
+ },
116
+ message: {
117
+ marginBottom: 20,
118
+ textAlign: 'center',
119
+ opacity: 0.7,
120
+ },
121
+ button: {
122
+ paddingHorizontal: 20,
123
+ paddingVertical: 12,
124
+ borderRadius: 8,
125
+ },
126
+ buttonText: {
127
+ color: '#fff',
128
+ },
129
+ });