@idealyst/navigation 1.0.82 → 1.0.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.
Files changed (36) hide show
  1. package/package.json +23 -10
  2. package/src/context/NavigatorContext.native.tsx +37 -6
  3. package/src/context/NavigatorContext.web.tsx +5 -3
  4. package/src/context/types.ts +2 -0
  5. package/src/examples/CustomStackLayout.tsx +1 -3
  6. package/src/examples/CustomTabLayout.tsx +6 -5
  7. package/src/examples/ExampleNavigationRouter.tsx +111 -0
  8. package/src/examples/ExampleSearchDialog.tsx +134 -0
  9. package/src/examples/ExampleSidebar.tsx +134 -0
  10. package/src/examples/ExampleWebLayout.tsx +107 -0
  11. package/src/examples/HeaderRight.tsx +27 -0
  12. package/src/examples/index.ts +3 -5
  13. package/src/examples/unistyles.ts +6 -12
  14. package/src/hooks/useParams.web.ts +1 -1
  15. package/src/index.native.ts +4 -1
  16. package/src/index.web.ts +2 -2
  17. package/src/layouts/DefaultStackLayout.tsx +6 -5
  18. package/src/layouts/DefaultTabLayout.tsx +11 -6
  19. package/src/router/index.native.ts +17 -0
  20. package/src/router/index.ts +3 -0
  21. package/src/router/index.web.ts +6 -0
  22. package/src/routing/DrawerContentWrapper.native.tsx +25 -0
  23. package/src/routing/HeaderWrapper.native.tsx +19 -0
  24. package/src/routing/index.native.tsx +0 -4
  25. package/src/routing/index.web.tsx +1 -3
  26. package/src/routing/router.native.tsx +133 -23
  27. package/src/routing/router.web.tsx +2 -3
  28. package/src/routing/types.ts +40 -12
  29. package/CLAUDE.md +0 -417
  30. package/LLM-ACCESS-GUIDE.md +0 -166
  31. package/src/examples/ExampleDrawerRouter.tsx +0 -196
  32. package/src/examples/ExampleHybridRouter.tsx +0 -62
  33. package/src/examples/ExampleStackRouter.tsx +0 -266
  34. package/src/examples/ExampleTabRouter.tsx +0 -318
  35. package/src/examples/README.md +0 -394
  36. package/src/examples/highContrastThemes.ts +0 -583
@@ -0,0 +1,107 @@
1
+ import React, { useState } from 'react';
2
+ import { View, Text, Button, Divider, ListItem, Icon, Badge } from '@idealyst/components';
3
+ import { useNavigator } from '../context';
4
+ import { Outlet } from '../router';
5
+ import { UnistylesRuntime, useUnistyles } from 'react-native-unistyles';
6
+ import { getNextTheme, getThemeDisplayName, isHighContrastTheme } from './unistyles';
7
+ import ExampleSidebar from './ExampleSidebar';
8
+ import ExampleSearchDialog from './ExampleSearchDialog';
9
+
10
+
11
+ export const ExampleWebLayout: React.FC = () => {
12
+ const navigator = useNavigator();
13
+ const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
14
+ const [showSearch, setShowSearch] = useState(false);
15
+ const currentTheme = UnistylesRuntime.themeName || 'light';
16
+ const { theme } = useUnistyles();
17
+
18
+ const cycleTheme = () => {
19
+ const nextTheme = getNextTheme(currentTheme);
20
+ UnistylesRuntime.setTheme(nextTheme as any);
21
+ };
22
+
23
+ const sidebarWidth = sidebarCollapsed ? 0 : 280;
24
+
25
+ return (
26
+ <View background='primary' style={{ height: '100vh', flexDirection: 'column', overflow: 'hidden' }}>
27
+ {/* Header */}
28
+ <View style={{
29
+ paddingRight: 32,
30
+ borderBottomWidth: 1,
31
+ borderBottomStyle: 'solid',
32
+ borderBottomColor: theme.colors.border.primary,
33
+ flexDirection: 'row',
34
+ alignItems: 'center',
35
+ justifyContent: 'space-between',
36
+ }}>
37
+ <View style={{ flexDirection: 'row', alignItems: 'center' }}>
38
+ <Button
39
+ type="text"
40
+ leftIcon="menu"
41
+ size="lg"
42
+ onPress={() => setSidebarCollapsed(!sidebarCollapsed)}
43
+ style={{ padding: 8 }}
44
+ />
45
+ <Button type='text' size="lg">
46
+ <Text weight="bold" size="lg">
47
+ Idealyst Components
48
+ </Text>
49
+ </Button>
50
+ <Badge color='green'>
51
+ {getThemeDisplayName(currentTheme)}
52
+ </Badge>
53
+ </View>
54
+
55
+ <View style={{ flexDirection: 'row', gap: 8, alignItems: 'center' }}>
56
+ <Button
57
+ leftIcon="magnify"
58
+ size='lg'
59
+ intent='neutral'
60
+ type='text'
61
+ onPress={() => setShowSearch(true)}
62
+ />
63
+ <Button
64
+ type="outlined"
65
+ intent="primary"
66
+ size="sm"
67
+ onPress={cycleTheme}
68
+ >
69
+ Cycle Theme
70
+ </Button>
71
+ </View>
72
+ </View>
73
+
74
+ {/* Search Dialog */}
75
+ <ExampleSearchDialog open={showSearch} onOpenChange={setShowSearch} />
76
+
77
+ {/* Main Content Area with Sidebar */}
78
+ <View style={{ flex: 1, flexDirection: 'row', overflow: 'hidden' }}>
79
+ {/* Sidebar */}
80
+ <View style={{
81
+ width: sidebarWidth,
82
+ height: '100%',
83
+ borderRightWidth: sidebarCollapsed ? 0 : 1,
84
+ borderRightStyle: 'solid',
85
+ borderRightColor: theme.colors.border.primary,
86
+ transition: 'width 0.3s ease, border-right-width 0.3s ease',
87
+ overflow: 'hidden',
88
+ flexShrink: 0,
89
+ }}>
90
+ {!sidebarCollapsed && (
91
+ <ExampleSidebar />
92
+ )}
93
+ </View>
94
+
95
+ {/* Content Area */}
96
+ <View style={{
97
+ flex: 1,
98
+ overflowY: 'auto',
99
+ }}>
100
+ <View style={{ padding: 24, maxWidth: 1200, margin: '0 auto', width: '100%' }}>
101
+ <Outlet key={currentTheme} />
102
+ </View>
103
+ </View>
104
+ </View>
105
+ </View>
106
+ );
107
+ };
@@ -0,0 +1,27 @@
1
+ import React, { useState } from 'react';
2
+ import { Button, Icon, View } from '@idealyst/components';
3
+ import { UnistylesRuntime } from 'react-native-unistyles';
4
+ import ExampleSearchDialog from './ExampleSearchDialog';
5
+
6
+ export default function HeaderRight() {
7
+ const [isDark, setIsDark] = useState(false);
8
+ const [showDialog, setShowDialog] = useState(false);
9
+
10
+ const toggleTheme = () => {
11
+ const newTheme = isDark ? 'light' : 'dark';
12
+ UnistylesRuntime.setTheme(newTheme);
13
+ setIsDark(!isDark);
14
+ };
15
+
16
+ return (
17
+ <View style={{ flexDirection: 'row', alignItems: 'center', paddingHorizontal: 12, }}>
18
+ <Button style={{ padding: 0, margin: 0, }} type='text' onPress={() => setShowDialog(true)} >
19
+ <Icon name='magnify' intent='neutral' size={'md'} />
20
+ </Button>
21
+ <Button type='text' size='sm' onPress={toggleTheme}>
22
+ <Icon color={isDark ? 'yellow' : 'blue.800'} name={isDark ? 'weather-sunny' : 'moon-waning-crescent'} size='md' />
23
+ </Button>
24
+ <ExampleSearchDialog open={showDialog} onOpenChange={setShowDialog} />
25
+ </View>
26
+ );
27
+ }
@@ -1,6 +1,4 @@
1
- export { default as ExampleStackRouter } from './ExampleStackRouter';
2
- export { default as ExampleTabRouter } from './ExampleTabRouter';
3
- export { default as ExampleDrawerRouter } from './ExampleDrawerRouter';
4
- export { default as ExampleHybridRouter } from './ExampleHybridRouter';
1
+ export { default as ExampleNavigationRouter } from './ExampleNavigationRouter';
5
2
  export { default as CustomStackLayout } from './CustomStackLayout';
6
- export { default as CustomTabLayout } from './CustomTabLayout';
3
+ export { default as CustomTabLayout } from './CustomTabLayout';
4
+ export { ExampleWebLayout } from './ExampleWebLayout';
@@ -1,31 +1,25 @@
1
- import { breakpoints, defaultLightTheme, defaultDarkTheme } from '@idealyst/theme';
2
- import { highContrastThemes } from './highContrastThemes';
1
+ import { lightTheme, darkTheme } from '@idealyst/theme';
3
2
  import { StyleSheet } from 'react-native-unistyles';
4
3
 
5
4
  // Extend UnistylesThemes to include high contrast themes
6
5
  // This overrides the more limited declaration from the components package
7
6
  declare module 'react-native-unistyles' {
8
7
  export interface UnistylesThemes {
9
- light: typeof defaultLightTheme;
10
- dark: typeof defaultDarkTheme;
11
- lightHighContrast: typeof highContrastThemes.lightHighContrast;
12
- darkHighContrast: typeof highContrastThemes.darkHighContrast;
8
+ light: typeof lightTheme,
9
+ dark: typeof darkTheme,
13
10
  }
14
11
  }
15
-
12
+
16
13
  // Configure with all themes, including high contrast variants
17
14
  // This will override any previous configuration
18
15
  StyleSheet.configure({
19
16
  themes: {
20
- light: defaultLightTheme,
21
- dark: defaultDarkTheme,
22
- lightHighContrast: highContrastThemes.lightHighContrast,
23
- darkHighContrast: highContrastThemes.darkHighContrast,
17
+ light: lightTheme,
18
+ dark: darkTheme,
24
19
  },
25
20
  settings: {
26
21
  initialTheme: 'light',
27
22
  },
28
- breakpoints,
29
23
  });
30
24
 
31
25
  // Export theme names for easy reference
@@ -1,4 +1,4 @@
1
- import { useParams as useReactRouterParams } from 'react-router';
1
+ import { useParams as useReactRouterParams } from '../router';
2
2
 
3
3
  /**
4
4
  * Custom useParams hook that wraps React Router's useParams
@@ -1,4 +1,7 @@
1
1
  // Native-specific exports
2
- export * from './index';
2
+ export * from './context';
3
+ export * from './layouts';
4
+ export * from './routing';
5
+ export * from './hooks';
3
6
 
4
7
  // No React Router exports needed for native
package/src/index.web.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  // Web-specific exports
2
2
  export * from './index';
3
3
 
4
- // Re-export React Router components to ensure single instance
5
- export { Outlet } from 'react-router';
4
+ // Direct export to fix module resolution
5
+ export { NavigatorProvider, useNavigator } from './context/NavigatorContext.web';
@@ -1,10 +1,9 @@
1
1
  import React from 'react'
2
2
  import { View, Text } from '@idealyst/components'
3
3
  import { StackLayoutProps } from '../routing/types'
4
- import { Outlet } from '..'
5
-
4
+ import { Outlet } from '../router'
5
+ import { useNavigator } from '../context'
6
6
  export interface DefaultStackLayoutProps extends StackLayoutProps {
7
- onNavigate: (path: string) => void
8
7
  currentPath: string
9
8
  }
10
9
 
@@ -15,9 +14,11 @@ export interface DefaultStackLayoutProps extends StackLayoutProps {
15
14
  export const DefaultStackLayout: React.FC<DefaultStackLayoutProps> = ({
16
15
  options,
17
16
  routes,
18
- onNavigate,
19
17
  currentPath
20
18
  }) => {
19
+
20
+ const navigator = useNavigator()
21
+
21
22
  return (
22
23
  <View style={{ height: '100vh', flexDirection: 'column' }}>
23
24
  {/* Header */}
@@ -34,7 +35,7 @@ export const DefaultStackLayout: React.FC<DefaultStackLayoutProps> = ({
34
35
 
35
36
  {options.headerTitle && (
36
37
  typeof options.headerTitle === 'string' ? (
37
- <Text size="large" weight="bold" style={{ marginLeft: options.headerLeft ? 12 : 0 }}>
38
+ <Text size="lg" weight="bold" style={{ marginLeft: options.headerLeft ? 12 : 0 }}>
38
39
  {options.headerTitle}
39
40
  </Text>
40
41
  ) : (
@@ -1,7 +1,8 @@
1
1
  import React from 'react'
2
2
  import { View, Text, Button, Icon } from '@idealyst/components'
3
3
  import { TabLayoutProps } from '../routing/types'
4
- import { Outlet } from '..'
4
+ import { Outlet } from '../router'
5
+ import { useNavigator } from '../context'
5
6
 
6
7
  export interface DefaultTabLayoutProps extends TabLayoutProps {}
7
8
 
@@ -12,9 +13,11 @@ export interface DefaultTabLayoutProps extends TabLayoutProps {}
12
13
  export const DefaultTabLayout: React.FC<DefaultTabLayoutProps> = ({
13
14
  options,
14
15
  routes,
15
- onNavigate,
16
16
  currentPath
17
17
  }) => {
18
+
19
+ const navigator = useNavigator()
20
+
18
21
  return (
19
22
  <View style={{ height: '100vh', flexDirection: 'column' }}>
20
23
  {/* Header */}
@@ -30,7 +33,7 @@ export const DefaultTabLayout: React.FC<DefaultTabLayoutProps> = ({
30
33
  {options.headerLeft && React.createElement(options.headerLeft as any)}
31
34
 
32
35
  {typeof options.headerTitle === 'string' ? (
33
- <Text size="large" weight="bold" style={{ marginLeft: options.headerLeft ? 12 : 0 }}>
36
+ <Text size="lg" weight="bold" style={{ marginLeft: options.headerLeft ? 12 : 0 }}>
34
37
  {options.headerTitle}
35
38
  </Text>
36
39
  ) : (
@@ -64,8 +67,10 @@ export const DefaultTabLayout: React.FC<DefaultTabLayoutProps> = ({
64
67
  key={route.path}
65
68
  variant={isActive ? 'contained' : 'outlined'}
66
69
  intent={isActive ? 'primary' : undefined}
67
- size="small"
68
- onPress={() => onNavigate(route.path)}
70
+ size="sm"
71
+ onPress={() => navigator.navigate({
72
+ path: route.fullPath
73
+ })}
69
74
  style={{
70
75
  flexDirection: 'row',
71
76
  alignItems: 'center',
@@ -80,7 +85,7 @@ export const DefaultTabLayout: React.FC<DefaultTabLayoutProps> = ({
80
85
  />
81
86
  )}
82
87
  <Text
83
- size="small"
88
+ size="sm"
84
89
  color={isActive ? 'white' : 'primary'}
85
90
  weight={isActive ? 'semibold' : 'medium'}
86
91
  >
@@ -0,0 +1,17 @@
1
+ // Native platforms don't use React Router
2
+ // This is a stub to maintain cross-platform compatibility
3
+
4
+ export const BrowserRouter = null;
5
+ export const HashRouter = null;
6
+ export const MemoryRouter = null;
7
+ export const Router = null;
8
+ export const useNavigate = () => null;
9
+ export const useLocation = () => null;
10
+ export const useParams = () => null;
11
+ export const useSearchParams = () => null;
12
+ export const Navigate = null;
13
+ export const Outlet = null;
14
+ export const Route = null;
15
+ export const Routes = null;
16
+ export const Link = null;
17
+ export const NavLink = null;
@@ -0,0 +1,3 @@
1
+ // Platform-specific exports will be used
2
+ // This file exists for TypeScript resolution
3
+ // The actual exports come from platform-specific files
@@ -0,0 +1,6 @@
1
+ // Export all React Router modules from a centralized location
2
+ // This prevents duplication issues when multiple packages need React Router
3
+
4
+ // Re-export everything from react-router-dom
5
+ // This includes all react-router exports plus the DOM-specific ones
6
+ export * from 'react-router-dom';
@@ -0,0 +1,25 @@
1
+ import React from 'react';
2
+ import { DrawerContentComponentProps } from '@react-navigation/drawer';
3
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
4
+ import { DrawerNavigatorProvider } from '../context/index.native';
5
+ import { NavigatorParam, DrawerSidebarProps } from './types';
6
+
7
+ /**
8
+ * Wrapper that renders the sidebar component and passes safe area insets
9
+ * The NavigatorContext is already provided by NavigatorProvider higher up in the tree,
10
+ * so the sidebar can use useNavigator hook directly
11
+ */
12
+ export const DrawerContentWrapper: React.FC<{
13
+ content: React.ComponentType<DrawerSidebarProps>;
14
+ route: NavigatorParam;
15
+ drawerProps: DrawerContentComponentProps;
16
+ }> = ({ content: Content, route, drawerProps }) => {
17
+ // Get safe area insets from React Native Safe Area Context
18
+ const insets = useSafeAreaInsets();
19
+
20
+ return (
21
+ <DrawerNavigatorProvider navigation={drawerProps.navigation} route={route}>
22
+ <Content insets={insets} />
23
+ </DrawerNavigatorProvider>
24
+ );
25
+ };
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import { DrawerNavigatorProvider } from '../context/index.native';
3
+ import { NavigatorParam } from './types';
4
+
5
+ /**
6
+ * Wrapper that renders the header component with navigation context
7
+ * This allows header components to use useNavigator and access route info
8
+ */
9
+ export const HeaderWrapper: React.FC<{
10
+ content: React.ComponentType<any>;
11
+ route: NavigatorParam;
12
+ navigation: any;
13
+ }> = ({ content: Content, route, navigation }) => {
14
+ return (
15
+ <DrawerNavigatorProvider navigation={navigation} route={route}>
16
+ <Content />
17
+ </DrawerNavigatorProvider>
18
+ );
19
+ };
@@ -1,6 +1,2 @@
1
1
  export * from './router.native';
2
2
  export * from './types';
3
-
4
- // Added for consistency
5
- const Outlet = null
6
- export { Outlet };
@@ -1,4 +1,2 @@
1
1
  export * from './router.web';
2
- export * from './types';
3
-
4
- export { Outlet } from 'react-router';
2
+ export * from './types';
@@ -1,21 +1,129 @@
1
- import { NavigatorParam, RouteParam } from './types'
1
+ import { NavigatorParam, RouteParam, ScreenOptions } from './types'
2
2
 
3
3
  import { TypedNavigator } from "@react-navigation/native";
4
4
  import { createNativeStackNavigator } from "@react-navigation/native-stack";
5
5
  import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
6
+ import { createDrawerNavigator } from "@react-navigation/drawer";
7
+ import { DrawerContentWrapper } from './DrawerContentWrapper.native';
8
+ import { HeaderWrapper } from './HeaderWrapper.native';
9
+ import React from 'react';
10
+ import { useUnistyles } from 'react-native-unistyles';
11
+ import { useIsFocused } from '@react-navigation/native';
12
+
13
+ /**
14
+ * Wrapper that makes screen components reactive to theme changes
15
+ * Only updates when the screen is focused
16
+ */
17
+ const ThemeAwareScreenWrapper: React.FC<{
18
+ Component: React.ComponentType<any>;
19
+ [key: string]: any;
20
+ }> = ({ Component, ...props }) => {
21
+ const isFocused = useIsFocused();
22
+
23
+ // Force update mechanism
24
+ const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
25
+
26
+ // Subscribe to theme changes
27
+ const { rt } = useUnistyles();
28
+
29
+ // Force re-render when theme changes (only when focused)
30
+ React.useEffect(() => {
31
+ if (isFocused) {
32
+ console.log('[ThemeAwareScreenWrapper] Theme changed, forcing update. New theme:', rt.themeName);
33
+ forceUpdate();
34
+ }
35
+ }, [rt.themeName, isFocused]);
36
+
37
+ // Log when component renders
38
+ React.useEffect(() => {
39
+ if (isFocused) {
40
+ console.log('[ThemeAwareScreenWrapper] Screen rendered with theme:', rt.themeName);
41
+ }
42
+ });
43
+
44
+ // Only render when focused to optimize performance
45
+ if (!isFocused) {
46
+ return null;
47
+ }
48
+
49
+ return <Component {...props} />;
50
+ };
51
+
52
+ /**
53
+ * Cache for wrapped components to maintain stable references across renders
54
+ */
55
+ const wrappedComponentCache = new WeakMap<React.ComponentType<any>, React.ComponentType<any>>();
56
+
57
+ /**
58
+ * Creates a theme-aware component wrapper with a stable reference
59
+ * This prevents React Navigation warnings about inline components
60
+ */
61
+ const createThemeAwareComponent = (OriginalComponent: React.ComponentType<any>) => {
62
+ // Check cache first to return the same wrapped component reference
63
+ if (wrappedComponentCache.has(OriginalComponent)) {
64
+ return wrappedComponentCache.get(OriginalComponent)!;
65
+ }
66
+
67
+ const Wrapped = React.memo((props: any) => (
68
+ <ThemeAwareScreenWrapper Component={OriginalComponent} {...props} />
69
+ ));
70
+ Wrapped.displayName = `ThemeAware(${OriginalComponent.displayName || OriginalComponent.name || 'Component'})`;
71
+
72
+ // Store in cache for future lookups
73
+ wrappedComponentCache.set(OriginalComponent, Wrapped);
74
+
75
+ return Wrapped;
76
+ };
6
77
 
7
78
  /**
8
79
  * Build the Mobile navigator using React Navigation
9
- * @param params
10
- * @param parentPath
11
- * @returns
80
+ * @param params
81
+ * @param parentPath
82
+ * @returns
12
83
  */
13
84
  export const buildNavigator = (params: NavigatorParam, parentPath = '') => {
14
85
  const NavigatorType = getNavigatorType(params);
86
+
87
+ // Wrap screenOptions to provide navigation context to headerRight
88
+ const screenOptions = params.options?.headerRight
89
+ ? (navProps: any) => {
90
+ const baseOptions = typeof params.options === 'function'
91
+ ? params.options(navProps)
92
+ : params.options;
93
+
94
+ return {
95
+ ...baseOptions,
96
+ headerRight: () => (
97
+ <HeaderWrapper
98
+ content={baseOptions.headerRight}
99
+ route={params}
100
+ navigation={navProps.navigation}
101
+ />
102
+ ),
103
+ };
104
+ }
105
+ : params.options;
106
+
107
+ // Special handling for drawer navigator with custom sidebar
108
+ if (params.layout === 'drawer' && params.sidebarComponent) {
109
+ return () => (
110
+ <NavigatorType.Navigator
111
+ screenOptions={screenOptions}
112
+ drawerContent={(drawerProps: any) => (
113
+ <DrawerContentWrapper
114
+ route={params}
115
+ content={params.sidebarComponent!}
116
+ drawerProps={drawerProps}
117
+ />
118
+ )}
119
+ >
120
+ {params.routes.map((child, index) => buildScreen(child, NavigatorType, parentPath, index))}
121
+ </NavigatorType.Navigator>
122
+ );
123
+ }
124
+
15
125
  return () => (
16
- <NavigatorType.Navigator screenOptions={{
17
- headerShown: params.options?.headerShown
18
- }}>
126
+ <NavigatorType.Navigator screenOptions={screenOptions}>
19
127
  {params.routes.map((child, index) => buildScreen(child, NavigatorType, parentPath, index))}
20
128
  </NavigatorType.Navigator>
21
129
  )
@@ -23,8 +131,8 @@ export const buildNavigator = (params: NavigatorParam, parentPath = '') => {
23
131
 
24
132
  /**
25
133
  * Get Navigator Type
26
- * @param params
27
- * @returns
134
+ * @param params
135
+ * @returns
28
136
  */
29
137
  const getNavigatorType = (params: NavigatorParam) => {
30
138
  switch (params.layout) {
@@ -32,16 +140,18 @@ const getNavigatorType = (params: NavigatorParam) => {
32
140
  return createNativeStackNavigator();
33
141
  case 'tab':
34
142
  return createBottomTabNavigator();
143
+ case 'drawer':
144
+ return createDrawerNavigator();
35
145
  }
36
146
  throw new Error(`Unsupported navigator type: ${params.layout}`);
37
147
  }
38
148
 
39
149
  /**
40
150
  * Build Screen
41
- * @param params
42
- * @param Navigator
43
- * @param parentPath
44
- * @returns
151
+ * @param params
152
+ * @param Navigator
153
+ * @param parentPath
154
+ * @returns
45
155
  */
46
156
  const buildScreen = (params: RouteParam, Navigator: TypedNavigator, parentPath = '', index: number) => {
47
157
  // Build the full path by combining parent path with current route path
@@ -56,20 +166,20 @@ const buildScreen = (params: RouteParam, Navigator: TypedNavigator, parentPath =
56
166
  const routePath = params.path.startsWith('/') ? params.path.slice(1) : params.path;
57
167
  fullPath = `${parentPath}/${routePath}`;
58
168
  }
59
-
60
- console.log('📱 Registering screen:', {
61
- originalPath: params.path,
62
- parentPath,
63
- fullPath,
64
- type: params.type,
65
- screenName: fullPath
66
- });
67
-
169
+
170
+ // Determine the component - wrap screens with ThemeAwareScreenWrapper
171
+ let component: React.ComponentType<any>;
172
+ if (params.type === 'screen') {
173
+ component = createThemeAwareComponent(params.component);
174
+ } else {
175
+ component = buildNavigator(params, fullPath);
176
+ }
177
+
68
178
  return (
69
179
  <Navigator.Screen
70
180
  key={`${fullPath}-${index}`}
71
181
  name={fullPath}
72
- component={params.type === 'screen' ? params.component : buildNavigator(params, fullPath)}
182
+ component={component}
73
183
  options={params.options}
74
184
  />
75
185
  )
@@ -1,5 +1,5 @@
1
1
  import React from 'react'
2
- import { Routes, Route } from 'react-router'
2
+ import { Routes, Route } from '../router'
3
3
  import { DefaultStackLayout } from '../layouts/DefaultStackLayout'
4
4
  import { DefaultTabLayout } from '../layouts/DefaultTabLayout'
5
5
  import { NavigatorParam, RouteParam } from './types'
@@ -13,7 +13,7 @@ import { NavigatorParam, RouteParam } from './types'
13
13
  export const buildNavigator = (params: NavigatorParam, parentPath = '') => {
14
14
  return () => (
15
15
  <Routes>
16
- {params.routes.map((child, index) => buildRoute(child, index))}
16
+ {buildRoute(params, 0, false)}
17
17
  </Routes>
18
18
  )
19
19
  }
@@ -63,7 +63,6 @@ const buildRoute = (params: RouteParam, index: number, isNested = false) => {
63
63
  <LayoutComponent
64
64
  options={params.options}
65
65
  routes={routesWithFullPaths}
66
- onNavigate={() => {}} // Layout components can use their own navigation logic
67
66
  currentPath=""
68
67
  />
69
68
  }