@umituz/react-native-design-system 2.6.82 → 2.6.84

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": "2.6.82",
3
+ "version": "2.6.84",
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",
@@ -60,9 +60,11 @@
60
60
  "@umituz/react-native-storage": "*",
61
61
  "@umituz/react-native-uuid": "*",
62
62
  "expo-application": ">=5.0.0",
63
+ "expo-blur": ">=13.0.0",
63
64
  "expo-clipboard": ">=8.0.0",
64
65
  "expo-crypto": ">=13.0.0",
65
66
  "expo-device": ">=5.0.0",
67
+ "expo-font": ">=12.0.0",
66
68
  "expo-linear-gradient": ">=15.0.0",
67
69
  "expo-sharing": ">=12.0.0",
68
70
  "react": ">=19.0.0",
@@ -110,10 +112,12 @@
110
112
  "eslint-plugin-react-hooks": "^7.0.1",
111
113
  "eslint-plugin-react-native": "^5.0.0",
112
114
  "expo-application": "~5.9.1",
115
+ "expo-blur": "~14.0.0",
113
116
  "expo-clipboard": "~8.0.7",
114
117
  "expo-crypto": "~14.0.0",
115
118
  "expo-device": "~7.0.2",
116
119
  "expo-file-system": "^19.0.21",
120
+ "expo-font": "~13.0.0",
117
121
  "expo-haptics": "~14.0.0",
118
122
  "expo-linear-gradient": "~15.0.7",
119
123
  "expo-localization": "~16.0.1",
@@ -0,0 +1,52 @@
1
+ import React from 'react';
2
+ import { StyleSheet, ViewStyle, StyleProp } from 'react-native';
3
+ import { BlurView, BlurTint } from 'expo-blur';
4
+ import { useDesignSystemTheme } from '../../theme';
5
+
6
+ export interface GlassViewProps {
7
+ children?: React.ReactNode;
8
+ style?: StyleProp<ViewStyle>;
9
+ intensity?: number;
10
+ tint?: BlurTint;
11
+ experimentalBlurMethod?: 'dimezisBlurView' | 'none';
12
+ }
13
+
14
+ /**
15
+ * GlassView
16
+ *
17
+ * A wrapper around Expo BlurView to create glassmorphism effects.
18
+ * Automatically adapts to current theme unless overridden.
19
+ */
20
+ export const GlassView: React.FC<GlassViewProps> = ({
21
+ children,
22
+ style,
23
+ intensity = 50,
24
+ tint,
25
+ experimentalBlurMethod,
26
+
27
+ }) => {
28
+ const { themeMode } = useDesignSystemTheme();
29
+ const isDark = themeMode === 'dark';
30
+
31
+ // Default tint based on theme if not provided
32
+ // We explicitly cast the default strings to BlurTint to satisfy TS
33
+ const defaultTint = (isDark ? 'dark' : 'light') as BlurTint;
34
+ const resolvedTint = tint || defaultTint;
35
+
36
+ return (
37
+ <BlurView
38
+ intensity={intensity}
39
+ tint={resolvedTint}
40
+ style={[styles.container, style]}
41
+ experimentalBlurMethod={experimentalBlurMethod}
42
+ >
43
+ {children}
44
+ </BlurView>
45
+ );
46
+ };
47
+
48
+ const styles = StyleSheet.create({
49
+ container: {
50
+ overflow: 'hidden',
51
+ },
52
+ });
@@ -0,0 +1 @@
1
+ export * from './GlassView';
@@ -116,3 +116,6 @@ export { AtomicStatusBar, type AtomicStatusBarProps } from './status-bar';
116
116
 
117
117
  // Keyboard Avoiding
118
118
  export { AtomicKeyboardAvoidingView, type AtomicKeyboardAvoidingViewProps } from './AtomicKeyboardAvoidingView';
119
+
120
+ // GlassView
121
+ export { GlassView, type GlassViewProps } from './GlassView';
@@ -66,4 +66,6 @@ export {
66
66
  type AtomicStatusBarProps,
67
67
  AtomicKeyboardAvoidingView,
68
68
  type AtomicKeyboardAvoidingViewProps,
69
+ GlassView,
70
+ type GlassViewProps,
69
71
  } from '../atoms';
@@ -163,4 +163,7 @@ export {
163
163
  type SplashColors,
164
164
  type UseSplashFlowOptions,
165
165
  type UseSplashFlowResult,
166
+ // GlowingCard
167
+ GlowingCard,
168
+ type GlowingCardProps,
166
169
  } from '../molecules';
@@ -0,0 +1,74 @@
1
+ import React from 'react';
2
+ import { View, StyleSheet, StyleProp, ViewStyle, Pressable, GestureResponderEvent } from 'react-native';
3
+ import { useAppDesignTokens } from '../../theme';
4
+
5
+ export interface GlowingCardProps {
6
+ children: React.ReactNode;
7
+ glowColor?: string;
8
+ intensity?: number; // 0 to 1, default 1
9
+ style?: StyleProp<ViewStyle>;
10
+ onPress?: (event: GestureResponderEvent) => void;
11
+ testID?: string;
12
+ }
13
+
14
+ /**
15
+ * GlowingCard
16
+ *
17
+ * A card component with a neon-like glow effect using shadows.
18
+ */
19
+ export const GlowingCard: React.FC<GlowingCardProps> = ({
20
+ children,
21
+ glowColor,
22
+ intensity = 1,
23
+ style,
24
+ onPress,
25
+ testID,
26
+ }) => {
27
+ const tokens = useAppDesignTokens();
28
+ const resolvedColor = glowColor || tokens.colors.primary;
29
+
30
+ const shadowStyle: ViewStyle = {
31
+ shadowColor: resolvedColor,
32
+ shadowOffset: { width: 0, height: 0 },
33
+ shadowOpacity: 0.6 * intensity,
34
+ shadowRadius: 10 * intensity,
35
+ elevation: 8 * intensity, // Android elevation
36
+ backgroundColor: tokens.colors.surface, // Ensure bg is solid or it looks weird
37
+ borderRadius: tokens.borders.radius.md,
38
+ borderColor: resolvedColor,
39
+ borderWidth: 1,
40
+ };
41
+
42
+ const containerStyle = [
43
+ styles.container,
44
+ shadowStyle,
45
+ style,
46
+ ];
47
+
48
+ if (onPress) {
49
+ return (
50
+ <Pressable
51
+ style={({ pressed }) => [
52
+ containerStyle,
53
+ pressed && { opacity: 0.9, transform: [{ scale: 0.98 }] }
54
+ ]}
55
+ onPress={onPress}
56
+ testID={testID}
57
+ >
58
+ {children}
59
+ </Pressable>
60
+ );
61
+ }
62
+
63
+ return (
64
+ <View style={containerStyle} testID={testID}>
65
+ {children}
66
+ </View>
67
+ );
68
+ };
69
+
70
+ const styles = StyleSheet.create({
71
+ container: {
72
+ overflow: 'visible', // Needed for shadow
73
+ },
74
+ });
@@ -0,0 +1 @@
1
+ export * from './GlowingCard';
@@ -61,3 +61,6 @@ export * from './countdown';
61
61
 
62
62
  // Splash
63
63
  export * from './splash';
64
+
65
+ // GlowingCard
66
+ export { GlowingCard, type GlowingCardProps } from './GlowingCard';
@@ -22,6 +22,17 @@ export interface CustomThemeColors {
22
22
  accentDark?: string;
23
23
  buttonPrimary?: string;
24
24
  buttonSecondary?: string;
25
+
26
+ // Background overrides
27
+ backgroundPrimary?: string;
28
+ backgroundSecondary?: string;
29
+ surface?: string;
30
+ surfaceVariant?: string;
31
+
32
+ // Text overrides
33
+ textPrimary?: string;
34
+ textSecondary?: string;
35
+ textTertiary?: string;
25
36
  }
26
37
 
27
38
  /**
@@ -111,6 +122,37 @@ export const applyCustomColors = (
111
122
  result.buttonSecondary = customColors.buttonSecondary;
112
123
  }
113
124
 
125
+ // Apply background override
126
+ if (customColors.backgroundPrimary) {
127
+ result.backgroundPrimary = customColors.backgroundPrimary;
128
+ result.background = customColors.backgroundPrimary; // Alias
129
+ }
130
+ if (customColors.backgroundSecondary) {
131
+ result.backgroundSecondary = customColors.backgroundSecondary;
132
+ }
133
+
134
+ // Apply surface overrides
135
+ if (customColors.surface) {
136
+ result.surface = customColors.surface;
137
+ result.card = customColors.surface; // Alias
138
+ result.cardBackground = customColors.surface; // Alias
139
+ }
140
+ if (customColors.surfaceVariant) {
141
+ result.surfaceVariant = customColors.surfaceVariant;
142
+ result.surfaceSecondary = customColors.surfaceVariant; // Alias
143
+ }
144
+
145
+ // Apply text overrides
146
+ if (customColors.textPrimary) {
147
+ result.textPrimary = customColors.textPrimary;
148
+ result.text = customColors.textPrimary; // Alias
149
+ }
150
+ if (customColors.textSecondary) {
151
+ result.textSecondary = customColors.textSecondary;
152
+ }
153
+ if (customColors.textTertiary) {
154
+ result.textTertiary = customColors.textTertiary;
155
+ }
156
+
114
157
  return result as ColorPalette;
115
158
  };
116
-
@@ -1,6 +1,7 @@
1
1
  import React, { useEffect, useState, ReactNode } from 'react';
2
2
  import { ActivityIndicator, View, StyleSheet } from 'react-native';
3
3
  import { GestureHandlerRootView } from 'react-native-gesture-handler';
4
+ import { useFonts } from 'expo-font';
4
5
  import { SafeAreaProvider, initialWindowMetrics } from '../../../safe-area';
5
6
  import { useThemeStore } from '../stores/themeStore';
6
7
  import { useDesignSystemTheme } from '../globalThemeStore';
@@ -16,6 +17,8 @@ interface DesignSystemProviderProps {
16
17
  children: ReactNode;
17
18
  /** Custom theme colors to override defaults */
18
19
  customColors?: CustomThemeColors;
20
+ /** Custom fonts to load (name -> source map) */
21
+ fonts?: Record<string, any>;
19
22
  /** Show loading indicator while initializing (default: true) */
20
23
  showLoadingIndicator?: boolean;
21
24
  /** Splash screen configuration (used when showLoadingIndicator is true) */
@@ -35,6 +38,7 @@ interface DesignSystemProviderProps {
35
38
  export const DesignSystemProvider: React.FC<DesignSystemProviderProps> = ({
36
39
  children,
37
40
  customColors,
41
+ fonts,
38
42
  showLoadingIndicator = true,
39
43
  splashConfig,
40
44
  loadingComponent,
@@ -44,6 +48,10 @@ export const DesignSystemProvider: React.FC<DesignSystemProviderProps> = ({
44
48
  // ALL HOOKS MUST BE AT THE TOP (Rules of Hooks)
45
49
  const [isInitialized, setIsInitialized] = useState(false);
46
50
  const [minDisplayTimeMet, setMinDisplayTimeMet] = useState(false);
51
+
52
+ // Load fonts if provided
53
+ const [fontsLoaded, fontError] = fonts ? useFonts(fonts) : [true, null];
54
+
47
55
  const initialize = useThemeStore((state) => state.initialize);
48
56
  const setCustomColors = useDesignSystemTheme((state) => state.setCustomColors);
49
57
 
@@ -66,44 +74,58 @@ export const DesignSystemProvider: React.FC<DesignSystemProviderProps> = ({
66
74
  // Initialize theme store
67
75
  initialize()
68
76
  .then(() => {
69
- if (__DEV__) console.log('[DesignSystemProvider] Initialized successfully - setting isInitialized to true');
77
+ if (__DEV__) console.log('[DesignSystemProvider] Theme initialized successfully');
70
78
  setIsInitialized(true);
71
- if (__DEV__) console.log('[DesignSystemProvider] State updated - calling onInitialized callback');
72
- onInitialized?.();
73
79
  })
74
80
  .catch((error) => {
75
81
  if (__DEV__) console.error('[DesignSystemProvider] Initialization failed:', error);
76
- if (__DEV__) console.log('[DesignSystemProvider] Error occurred - setting isInitialized to true anyway');
77
82
  setIsInitialized(true); // Still render app even on error
78
83
  onError?.(error);
79
84
  });
80
85
 
81
86
  return () => clearTimeout(displayTimer);
82
- }, [initialize, customColors, setCustomColors, onInitialized, onError]);
87
+ }, [initialize, customColors, setCustomColors, onError]);
88
+
89
+ // Handle initialization completion when both theme and fonts are ready
90
+ useEffect(() => {
91
+ if (isInitialized && fontsLoaded && minDisplayTimeMet) {
92
+ if (__DEV__) console.log('[DesignSystemProvider] All systems ready - calling onInitialized');
93
+ onInitialized?.();
94
+ }
95
+ }, [isInitialized, fontsLoaded, minDisplayTimeMet, onInitialized]);
96
+
97
+ // Handle font errors
98
+ useEffect(() => {
99
+ if (fontError) {
100
+ if (__DEV__) console.error('[DesignSystemProvider] Font loading failed:', fontError);
101
+ onError?.(fontError);
102
+ }
103
+ }, [fontError, onError]);
83
104
 
84
105
  // ALL HOOKS ABOVE - NOW SAFE TO USE OTHER LOGIC
85
106
 
86
107
  if (__DEV__) {
87
108
  console.log('[DesignSystemProvider] Component render:', {
88
109
  isInitialized,
110
+ fontsLoaded,
89
111
  minDisplayTimeMet,
90
112
  showLoadingIndicator,
91
113
  hasSplashConfig: !!splashConfig,
92
- splashConfigKeys: splashConfig ? Object.keys(splashConfig) : [],
93
114
  });
94
115
  }
95
116
 
96
117
  const renderContent = () => {
97
- const shouldShowSplash = showLoadingIndicator && (!isInitialized || !minDisplayTimeMet);
118
+ // Show splash if:
119
+ // 1. Loading indicator is enabled AND
120
+ // 2. Either theme not init OR fonts not loaded OR min time not met
121
+ const shouldShowSplash = showLoadingIndicator && (!isInitialized || !fontsLoaded || !minDisplayTimeMet);
98
122
 
99
123
  if (__DEV__) {
100
124
  console.log('[DesignSystemProvider] renderContent:', {
101
- showLoadingIndicator,
102
- isInitialized,
103
- minDisplayTimeMet,
104
125
  shouldShowSplash,
105
- hasSplashConfig: !!splashConfig,
106
- hasLoadingComponent: !!loadingComponent,
126
+ isInitialized,
127
+ fontsLoaded,
128
+ minDisplayTimeMet
107
129
  });
108
130
  }
109
131