@idealyst/navigation 1.0.39 → 1.0.41
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/CLAUDE.md +417 -0
- package/LLM-ACCESS-GUIDE.md +166 -0
- package/README.md +517 -0
- package/package.json +8 -5
- package/src/context/README.md +329 -0
- package/src/examples/ExampleStackRouter.tsx +1 -1
- package/src/examples/README.md +394 -0
- package/src/layouts/GeneralLayout/README.md +498 -0
- package/src/routing/README.md +421 -0
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
# Routing System
|
|
2
|
+
|
|
3
|
+
The core routing engine that handles cross-platform navigation with a unified API built on React Navigation (Native) and React Router (Web).
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ✅ Cross-platform routing (React Navigation + React Router)
|
|
8
|
+
- ✅ Unified API across platforms
|
|
9
|
+
- ✅ Multiple layout types (stack, tab, drawer, modal)
|
|
10
|
+
- ✅ Route parameter support
|
|
11
|
+
- ✅ Nested routing capabilities
|
|
12
|
+
- ✅ Type-safe route definitions
|
|
13
|
+
|
|
14
|
+
## Core Concepts
|
|
15
|
+
|
|
16
|
+
### Route Configuration
|
|
17
|
+
|
|
18
|
+
Routes are defined using `RouteParam` objects that describe the navigation structure:
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
import { RouteParam } from '@idealyst/navigation';
|
|
22
|
+
|
|
23
|
+
const AppRouter: RouteParam = {
|
|
24
|
+
path: "/", // Route path (optional for root)
|
|
25
|
+
component: HomeScreen, // Component to render
|
|
26
|
+
layout: { // Layout configuration
|
|
27
|
+
type: "stack", // Layout type
|
|
28
|
+
component: CustomLayout, // Optional custom layout
|
|
29
|
+
},
|
|
30
|
+
routes: [ // Child routes
|
|
31
|
+
{ path: "about", component: AboutScreen },
|
|
32
|
+
{ path: "contact", component: ContactScreen },
|
|
33
|
+
],
|
|
34
|
+
};
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Layout Types
|
|
38
|
+
|
|
39
|
+
The routing system supports four layout types:
|
|
40
|
+
|
|
41
|
+
#### Stack Layout
|
|
42
|
+
Linear navigation with a navigation stack.
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
const stackRouter: RouteParam = {
|
|
46
|
+
path: "/",
|
|
47
|
+
component: HomeScreen,
|
|
48
|
+
layout: { type: "stack" },
|
|
49
|
+
routes: [
|
|
50
|
+
{ path: "profile", component: ProfileScreen },
|
|
51
|
+
{ path: "settings", component: SettingsScreen },
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Platform Behavior:**
|
|
57
|
+
- **React Native**: Native stack navigator with platform-specific animations
|
|
58
|
+
- **Web**: Browser history-based navigation with URL changes
|
|
59
|
+
|
|
60
|
+
#### Tab Layout
|
|
61
|
+
Tab-based navigation for main app sections.
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
const tabRouter: RouteParam = {
|
|
65
|
+
path: "/",
|
|
66
|
+
component: DashboardHome,
|
|
67
|
+
layout: { type: "tab" },
|
|
68
|
+
routes: [
|
|
69
|
+
{ path: "analytics", component: AnalyticsScreen },
|
|
70
|
+
{ path: "reports", component: ReportsScreen },
|
|
71
|
+
{ path: "settings", component: SettingsScreen },
|
|
72
|
+
],
|
|
73
|
+
};
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Platform Behavior:**
|
|
77
|
+
- **React Native**: Bottom tab navigator with native tab animations
|
|
78
|
+
- **Web**: Top or side tab navigation with CSS transitions
|
|
79
|
+
|
|
80
|
+
#### Drawer Layout
|
|
81
|
+
Side drawer navigation, typically for desktop/web applications.
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
const drawerRouter: RouteParam = {
|
|
85
|
+
path: "/",
|
|
86
|
+
component: MainContent,
|
|
87
|
+
layout: { type: "drawer" },
|
|
88
|
+
routes: [
|
|
89
|
+
{ path: "dashboard", component: DashboardScreen },
|
|
90
|
+
{ path: "analytics", component: AnalyticsScreen },
|
|
91
|
+
{ path: "settings", component: SettingsScreen },
|
|
92
|
+
],
|
|
93
|
+
};
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Platform Behavior:**
|
|
97
|
+
- **React Native**: Drawer navigator with gesture support
|
|
98
|
+
- **Web**: Sidebar navigation with responsive behavior
|
|
99
|
+
|
|
100
|
+
#### Modal Layout
|
|
101
|
+
Overlay modal navigation for temporary content.
|
|
102
|
+
|
|
103
|
+
```tsx
|
|
104
|
+
const modalRouter: RouteParam = {
|
|
105
|
+
path: "/",
|
|
106
|
+
component: MainApp,
|
|
107
|
+
layout: { type: "stack" },
|
|
108
|
+
routes: [
|
|
109
|
+
{
|
|
110
|
+
path: "settings",
|
|
111
|
+
component: SettingsScreen,
|
|
112
|
+
layout: { type: "modal" },
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
};
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Platform Behavior:**
|
|
119
|
+
- **React Native**: Modal navigator with native modal presentation
|
|
120
|
+
- **Web**: Overlay modal with backdrop and focus management
|
|
121
|
+
|
|
122
|
+
## Route Parameters
|
|
123
|
+
|
|
124
|
+
### Dynamic Routes
|
|
125
|
+
|
|
126
|
+
Define routes with parameters using the `:param` syntax:
|
|
127
|
+
|
|
128
|
+
```tsx
|
|
129
|
+
const router: RouteParam = {
|
|
130
|
+
path: "/",
|
|
131
|
+
component: HomeScreen,
|
|
132
|
+
routes: [
|
|
133
|
+
{ path: "user/:id", component: UserDetailScreen },
|
|
134
|
+
{ path: "product/:category/:id", component: ProductDetailScreen },
|
|
135
|
+
{ path: "search/:query?", component: SearchResultsScreen }, // Optional parameter
|
|
136
|
+
],
|
|
137
|
+
};
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Accessing Parameters
|
|
141
|
+
|
|
142
|
+
```tsx
|
|
143
|
+
import { useNavigator } from '@idealyst/navigation';
|
|
144
|
+
|
|
145
|
+
const UserDetailScreen = () => {
|
|
146
|
+
const navigator = useNavigator();
|
|
147
|
+
|
|
148
|
+
// Parameters are available through the navigation context
|
|
149
|
+
// Implementation depends on the underlying router (React Navigation/React Router)
|
|
150
|
+
|
|
151
|
+
return (
|
|
152
|
+
<Screen>
|
|
153
|
+
<Text>User Details</Text>
|
|
154
|
+
{/* Display user details based on route parameters */}
|
|
155
|
+
</Screen>
|
|
156
|
+
);
|
|
157
|
+
};
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Navigation with Parameters
|
|
161
|
+
|
|
162
|
+
```tsx
|
|
163
|
+
const UserListScreen = () => {
|
|
164
|
+
const navigator = useNavigator();
|
|
165
|
+
|
|
166
|
+
const viewUser = (userId: string) => {
|
|
167
|
+
navigator.navigate({
|
|
168
|
+
path: "/user/:id",
|
|
169
|
+
vars: { id: userId },
|
|
170
|
+
});
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
return (
|
|
174
|
+
<Screen>
|
|
175
|
+
<Button onPress={() => viewUser("123")}>
|
|
176
|
+
View User 123
|
|
177
|
+
</Button>
|
|
178
|
+
</Screen>
|
|
179
|
+
);
|
|
180
|
+
};
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Nested Routing
|
|
184
|
+
|
|
185
|
+
Create complex navigation hierarchies by nesting routes with different layout types:
|
|
186
|
+
|
|
187
|
+
```tsx
|
|
188
|
+
const AppRouter: RouteParam = {
|
|
189
|
+
path: "/",
|
|
190
|
+
component: AppShell,
|
|
191
|
+
layout: { type: "stack" },
|
|
192
|
+
routes: [
|
|
193
|
+
{
|
|
194
|
+
path: "dashboard",
|
|
195
|
+
component: DashboardLayout,
|
|
196
|
+
layout: { type: "tab" },
|
|
197
|
+
routes: [
|
|
198
|
+
{ path: "overview", component: OverviewScreen },
|
|
199
|
+
{ path: "analytics", component: AnalyticsScreen },
|
|
200
|
+
{ path: "reports", component: ReportsScreen },
|
|
201
|
+
],
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
path: "admin",
|
|
205
|
+
component: AdminLayout,
|
|
206
|
+
layout: { type: "drawer" },
|
|
207
|
+
routes: [
|
|
208
|
+
{ path: "users", component: UserManagementScreen },
|
|
209
|
+
{ path: "settings", component: AdminSettingsScreen },
|
|
210
|
+
{
|
|
211
|
+
path: "system",
|
|
212
|
+
component: SystemScreen,
|
|
213
|
+
layout: { type: "modal" },
|
|
214
|
+
routes: [
|
|
215
|
+
{ path: "logs", component: SystemLogsScreen },
|
|
216
|
+
{ path: "backup", component: BackupScreen },
|
|
217
|
+
],
|
|
218
|
+
},
|
|
219
|
+
],
|
|
220
|
+
},
|
|
221
|
+
],
|
|
222
|
+
};
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Custom Layout Components
|
|
226
|
+
|
|
227
|
+
Override default layouts with custom components:
|
|
228
|
+
|
|
229
|
+
```tsx
|
|
230
|
+
import { GeneralLayout } from '@idealyst/navigation';
|
|
231
|
+
|
|
232
|
+
const CustomStackLayout: React.FC<{ children?: React.ReactNode }> = ({ children }) => {
|
|
233
|
+
return (
|
|
234
|
+
<GeneralLayout
|
|
235
|
+
header={{
|
|
236
|
+
enabled: true,
|
|
237
|
+
content: <Text>My Custom Header</Text>,
|
|
238
|
+
}}
|
|
239
|
+
sidebar={{
|
|
240
|
+
enabled: true,
|
|
241
|
+
collapsible: true,
|
|
242
|
+
content: <CustomNavigation />,
|
|
243
|
+
}}
|
|
244
|
+
>
|
|
245
|
+
{children}
|
|
246
|
+
</GeneralLayout>
|
|
247
|
+
);
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const router: RouteParam = {
|
|
251
|
+
path: "/",
|
|
252
|
+
component: HomeScreen,
|
|
253
|
+
layout: {
|
|
254
|
+
type: "stack",
|
|
255
|
+
component: CustomStackLayout,
|
|
256
|
+
},
|
|
257
|
+
routes: [
|
|
258
|
+
{ path: "about", component: AboutScreen },
|
|
259
|
+
],
|
|
260
|
+
};
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## Platform-Specific Implementation
|
|
264
|
+
|
|
265
|
+
### React Native Implementation
|
|
266
|
+
|
|
267
|
+
The routing system uses React Navigation under the hood:
|
|
268
|
+
|
|
269
|
+
```tsx
|
|
270
|
+
// Simplified internal implementation for React Native
|
|
271
|
+
import { NavigationContainer } from '@react-navigation/native';
|
|
272
|
+
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
|
273
|
+
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
|
|
274
|
+
import { createDrawerNavigator } from '@react-navigation/drawer';
|
|
275
|
+
|
|
276
|
+
// The router automatically configures the appropriate navigator
|
|
277
|
+
// based on the layout type specified in RouteParam
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### Web Implementation
|
|
281
|
+
|
|
282
|
+
The routing system uses React Router under the hood:
|
|
283
|
+
|
|
284
|
+
```tsx
|
|
285
|
+
// Simplified internal implementation for Web
|
|
286
|
+
import { BrowserRouter, Routes, Route } from 'react-router-dom';
|
|
287
|
+
|
|
288
|
+
// The router automatically configures React Router
|
|
289
|
+
// based on the route configuration
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## Advanced Routing Patterns
|
|
293
|
+
|
|
294
|
+
### Conditional Routes
|
|
295
|
+
|
|
296
|
+
```tsx
|
|
297
|
+
const ConditionalRouter: RouteParam = {
|
|
298
|
+
path: "/",
|
|
299
|
+
component: ({ children }) => {
|
|
300
|
+
const isAuthenticated = useAuth();
|
|
301
|
+
|
|
302
|
+
if (!isAuthenticated) {
|
|
303
|
+
return <LoginScreen />;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
return children;
|
|
307
|
+
},
|
|
308
|
+
layout: { type: "stack" },
|
|
309
|
+
routes: [
|
|
310
|
+
{ path: "dashboard", component: DashboardScreen },
|
|
311
|
+
{ path: "profile", component: ProfileScreen },
|
|
312
|
+
],
|
|
313
|
+
};
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### Route Guards
|
|
317
|
+
|
|
318
|
+
```tsx
|
|
319
|
+
const ProtectedRoute: React.FC<{ children?: React.ReactNode }> = ({ children }) => {
|
|
320
|
+
const { user, loading } = useAuth();
|
|
321
|
+
|
|
322
|
+
if (loading) return <LoadingScreen />;
|
|
323
|
+
if (!user) return <LoginScreen />;
|
|
324
|
+
|
|
325
|
+
return <>{children}</>;
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
const protectedRouter: RouteParam = {
|
|
329
|
+
path: "/admin",
|
|
330
|
+
component: ProtectedRoute,
|
|
331
|
+
layout: { type: "stack" },
|
|
332
|
+
routes: [
|
|
333
|
+
{ path: "users", component: UserManagementScreen },
|
|
334
|
+
{ path: "settings", component: AdminSettingsScreen },
|
|
335
|
+
],
|
|
336
|
+
};
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### Dynamic Route Loading
|
|
340
|
+
|
|
341
|
+
```tsx
|
|
342
|
+
const LazyRoute: React.FC = () => {
|
|
343
|
+
const [Component, setComponent] = useState<React.ComponentType | null>(null);
|
|
344
|
+
|
|
345
|
+
useEffect(() => {
|
|
346
|
+
// Dynamically import component
|
|
347
|
+
import('./DynamicScreen').then(module => {
|
|
348
|
+
setComponent(() => module.default);
|
|
349
|
+
});
|
|
350
|
+
}, []);
|
|
351
|
+
|
|
352
|
+
if (!Component) return <LoadingScreen />;
|
|
353
|
+
|
|
354
|
+
return <Component />;
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
const dynamicRouter: RouteParam = {
|
|
358
|
+
path: "/dynamic",
|
|
359
|
+
component: LazyRoute,
|
|
360
|
+
};
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
## Route Configuration Best Practices
|
|
364
|
+
|
|
365
|
+
1. **Keep Routes Shallow**: Avoid deeply nested route structures
|
|
366
|
+
2. **Use Meaningful Paths**: Choose descriptive route paths
|
|
367
|
+
3. **Parameter Consistency**: Use consistent parameter naming
|
|
368
|
+
4. **Layout Appropriateness**: Choose layout types that match the user experience
|
|
369
|
+
5. **Error Boundaries**: Wrap route components in error boundaries
|
|
370
|
+
6. **Loading States**: Handle loading states for async route components
|
|
371
|
+
|
|
372
|
+
## TypeScript Support
|
|
373
|
+
|
|
374
|
+
The routing system provides full type safety:
|
|
375
|
+
|
|
376
|
+
```tsx
|
|
377
|
+
// Route parameters are type-checked
|
|
378
|
+
type UserRouteParams = {
|
|
379
|
+
id: string;
|
|
380
|
+
tab?: 'profile' | 'settings';
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
// Component props can be typed based on route parameters
|
|
384
|
+
interface UserScreenProps {
|
|
385
|
+
route: {
|
|
386
|
+
params: UserRouteParams;
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
const UserScreen: React.FC<UserScreenProps> = ({ route }) => {
|
|
391
|
+
const { id, tab } = route.params;
|
|
392
|
+
// TypeScript ensures correct parameter usage
|
|
393
|
+
};
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
## Performance Considerations
|
|
397
|
+
|
|
398
|
+
1. **Lazy Loading**: Use dynamic imports for large route components
|
|
399
|
+
2. **Route Memoization**: Memoize route configurations when possible
|
|
400
|
+
3. **Navigation Caching**: The router automatically caches navigation state
|
|
401
|
+
4. **Bundle Splitting**: Consider code splitting for large route trees
|
|
402
|
+
|
|
403
|
+
## Debugging
|
|
404
|
+
|
|
405
|
+
```tsx
|
|
406
|
+
// Enable routing debug mode (development only)
|
|
407
|
+
const router: RouteParam = {
|
|
408
|
+
path: "/",
|
|
409
|
+
component: HomeScreen,
|
|
410
|
+
// Add debug information to route configuration
|
|
411
|
+
routes: [
|
|
412
|
+
{
|
|
413
|
+
path: "debug",
|
|
414
|
+
component: () => {
|
|
415
|
+
console.log('Route rendered: /debug');
|
|
416
|
+
return <DebugScreen />;
|
|
417
|
+
}
|
|
418
|
+
},
|
|
419
|
+
],
|
|
420
|
+
};
|
|
421
|
+
```
|