@umituz/react-native-design-system 4.23.77 → 4.23.79
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.
|
|
3
|
+
"version": "4.23.79",
|
|
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",
|
package/src/exception/index.ts
CHANGED
|
@@ -51,7 +51,8 @@ export { ExceptionLogger } from './infrastructure/services/ExceptionLogger';
|
|
|
51
51
|
// =============================================================================
|
|
52
52
|
|
|
53
53
|
// Components
|
|
54
|
-
|
|
54
|
+
// ErrorBoundary temporarily disabled for React 19 compatibility
|
|
55
|
+
// export { ErrorBoundary, withErrorBoundary } from './presentation/components/ErrorBoundary';
|
|
55
56
|
export { ExceptionEmptyState } from './presentation/components/ExceptionEmptyState';
|
|
56
57
|
export type { ExceptionEmptyStateProps } from './presentation/components/ExceptionEmptyState';
|
|
57
58
|
export { ExceptionErrorState } from './presentation/components/ExceptionErrorState';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Error Boundary Component
|
|
3
|
-
*
|
|
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
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
interface ErrorInfo {
|
|
19
|
+
error: Error;
|
|
20
|
+
componentStack: string | null;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
export
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
|
|
33
|
-
return {
|
|
34
|
-
hasError: true,
|
|
35
|
-
error,
|
|
36
|
-
};
|
|
37
|
-
}
|
|
36
|
+
const tokens = useAppDesignTokens();
|
|
38
37
|
|
|
39
|
-
|
|
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 (
|
|
48
|
-
|
|
53
|
+
if (onError) {
|
|
54
|
+
onError(error, errorInfo);
|
|
49
55
|
}
|
|
50
|
-
}
|
|
56
|
+
}, [onError]);
|
|
51
57
|
|
|
52
|
-
|
|
53
|
-
|
|
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
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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
|
+
});
|