@idealyst/navigation 1.0.81 → 1.0.83
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 +16 -10
- package/src/context/NavigatorContext.native.tsx +15 -9
- package/src/context/NavigatorContext.web.tsx +2 -5
- package/src/examples/ExampleStackRouter.tsx +11 -1
- package/src/hooks/useParams.web.ts +1 -1
- package/src/index.web.ts +2 -2
- package/src/layouts/DefaultStackLayout.tsx +1 -2
- package/src/layouts/DefaultTabLayout.tsx +1 -1
- package/src/router/index.native.ts +17 -0
- package/src/router/index.ts +3 -0
- package/src/router/index.web.ts +6 -0
- package/src/routing/index.native.tsx +0 -4
- package/src/routing/index.web.tsx +1 -3
- package/src/routing/router.web.tsx +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@idealyst/navigation",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.83",
|
|
4
4
|
"description": "Cross-platform navigation library for React and React Native",
|
|
5
5
|
"readme": "README.md",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -31,6 +31,11 @@
|
|
|
31
31
|
"import": "./src/examples/unistyles.ts",
|
|
32
32
|
"require": "./src/examples/unistyles.ts",
|
|
33
33
|
"types": "./src/examples/unistyles.ts"
|
|
34
|
+
},
|
|
35
|
+
"./router": {
|
|
36
|
+
"import": "./src/router/index.ts",
|
|
37
|
+
"require": "./src/router/index.ts",
|
|
38
|
+
"types": "./src/router/index.ts"
|
|
34
39
|
}
|
|
35
40
|
},
|
|
36
41
|
"scripts": {
|
|
@@ -38,25 +43,26 @@
|
|
|
38
43
|
"publish:npm": "npm publish"
|
|
39
44
|
},
|
|
40
45
|
"peerDependencies": {
|
|
41
|
-
"@idealyst/components": "^1.0.
|
|
42
|
-
"@idealyst/theme": "^1.0.
|
|
43
|
-
"@react-navigation/bottom-tabs": "
|
|
44
|
-
"@react-navigation/drawer": "
|
|
45
|
-
"@react-navigation/native": "
|
|
46
|
-
"@react-navigation/native-stack": "
|
|
46
|
+
"@idealyst/components": "^1.0.83",
|
|
47
|
+
"@idealyst/theme": "^1.0.83",
|
|
48
|
+
"@react-navigation/bottom-tabs": ">=7.0.0",
|
|
49
|
+
"@react-navigation/drawer": ">=7.0.0",
|
|
50
|
+
"@react-navigation/native": ">=7.0.0",
|
|
51
|
+
"@react-navigation/native-stack": ">=7.0.0",
|
|
47
52
|
"react": ">=16.8.0",
|
|
48
53
|
"react-native": ">=0.60.0",
|
|
49
54
|
"react-native-gesture-handler": "*",
|
|
50
55
|
"react-native-reanimated": "*",
|
|
51
56
|
"react-native-safe-area-context": "*",
|
|
52
57
|
"react-native-screens": "*",
|
|
53
|
-
"react-native-unistyles": "
|
|
54
|
-
"react-router": "
|
|
55
|
-
"react-router-dom": "
|
|
58
|
+
"react-native-unistyles": ">=3.0.0",
|
|
59
|
+
"react-router": ">=6.0.0",
|
|
60
|
+
"react-router-dom": ">=6.0.0"
|
|
56
61
|
},
|
|
57
62
|
"devDependencies": {
|
|
58
63
|
"@types/react": "^19.1.8",
|
|
59
64
|
"@types/react-dom": "^19.1.6",
|
|
65
|
+
"react-router": "7.9.1",
|
|
60
66
|
"typescript": "^5.0.0"
|
|
61
67
|
},
|
|
62
68
|
"files": [
|
|
@@ -9,15 +9,18 @@ const NavigatorContext = createContext<NavigatorContextValue>({
|
|
|
9
9
|
});
|
|
10
10
|
|
|
11
11
|
// Utility function to parse path with parameters and find matching route
|
|
12
|
-
const parseParameterizedPath = (path: string,
|
|
12
|
+
const parseParameterizedPath = (path: string, rootRoute: any): { routeName: string, params: Record<string, string> } | null => {
|
|
13
13
|
// Handle absolute paths like /event/123
|
|
14
14
|
if (path.startsWith('/')) {
|
|
15
15
|
const pathSegments = path.split('/').filter(Boolean);
|
|
16
16
|
|
|
17
17
|
// Find matching route by checking patterns like /event/:id
|
|
18
|
-
const findMatchingRoute = (routeList: any[], segments: string[], startIndex = 0): any => {
|
|
18
|
+
const findMatchingRoute = (routeList: any[], segments: string[], startIndex = 0, pathPrefix = ''): any => {
|
|
19
19
|
for (const route of routeList) {
|
|
20
20
|
const routeSegments = route.path.split('/').filter(Boolean);
|
|
21
|
+
// Clean up path joining to avoid double slashes
|
|
22
|
+
const cleanPath = route.path.startsWith('/') ? route.path.slice(1) : route.path;
|
|
23
|
+
const fullRoutePath = pathPrefix ? `${pathPrefix}/${cleanPath}` : route.path;
|
|
21
24
|
|
|
22
25
|
if (routeSegments.length === segments.length - startIndex) {
|
|
23
26
|
let isMatch = true;
|
|
@@ -39,13 +42,18 @@ const parseParameterizedPath = (path: string, routes: any[]): { routeName: strin
|
|
|
39
42
|
}
|
|
40
43
|
|
|
41
44
|
if (isMatch) {
|
|
42
|
-
return { route, params: extractedParams };
|
|
45
|
+
return { route, params: extractedParams, fullPath: fullRoutePath };
|
|
43
46
|
}
|
|
44
47
|
}
|
|
45
48
|
|
|
46
49
|
// Check nested routes
|
|
47
50
|
if (route.routes) {
|
|
48
|
-
const nestedMatch = findMatchingRoute(
|
|
51
|
+
const nestedMatch = findMatchingRoute(
|
|
52
|
+
route.routes,
|
|
53
|
+
segments,
|
|
54
|
+
startIndex + routeSegments.length,
|
|
55
|
+
fullRoutePath
|
|
56
|
+
);
|
|
49
57
|
if (nestedMatch) {
|
|
50
58
|
return nestedMatch;
|
|
51
59
|
}
|
|
@@ -54,10 +62,10 @@ const parseParameterizedPath = (path: string, routes: any[]): { routeName: strin
|
|
|
54
62
|
return null;
|
|
55
63
|
};
|
|
56
64
|
|
|
57
|
-
const match = findMatchingRoute([
|
|
65
|
+
const match = findMatchingRoute(rootRoute.routes || [], pathSegments);
|
|
58
66
|
if (match) {
|
|
59
67
|
return {
|
|
60
|
-
routeName: match.
|
|
68
|
+
routeName: match.fullPath,
|
|
61
69
|
params: match.params
|
|
62
70
|
};
|
|
63
71
|
}
|
|
@@ -71,10 +79,8 @@ const UnwrappedNavigatorProvider = ({ route }: NavigatorProviderProps) => {
|
|
|
71
79
|
const navigation = useNavigation();
|
|
72
80
|
|
|
73
81
|
const navigate = (params: NavigateParams) => {
|
|
74
|
-
|
|
75
82
|
// Parse parameterized path for mobile
|
|
76
|
-
const parsed = parseParameterizedPath(params.path,
|
|
77
|
-
|
|
83
|
+
const parsed = parseParameterizedPath(params.path, route);
|
|
78
84
|
if (parsed) {
|
|
79
85
|
// Navigate to the pattern route with extracted parameters
|
|
80
86
|
navigation.navigate(parsed.routeName as never, parsed.params as never);
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import React, { createContext, memo, useContext, useMemo } from 'react';
|
|
2
|
-
import { useNavigate, useParams } from '
|
|
2
|
+
import { useNavigate, useParams } from '../router';
|
|
3
3
|
import { NavigateParams, NavigatorProviderProps, NavigatorContextValue } from './types';
|
|
4
4
|
import { buildNavigator } from '../routing';
|
|
5
5
|
|
|
6
6
|
const NavigatorContext = createContext<NavigatorContextValue>({
|
|
7
7
|
navigate: () => {},
|
|
8
|
-
params: {},
|
|
9
8
|
});
|
|
10
9
|
|
|
11
|
-
export const NavigatorProvider = ({
|
|
10
|
+
export const NavigatorProvider = ({
|
|
12
11
|
route,
|
|
13
12
|
}: NavigatorProviderProps) => {
|
|
14
13
|
const reactRouterNavigate = useNavigate()
|
|
15
|
-
const params = useParams()
|
|
16
14
|
|
|
17
15
|
const navigateFunction = (params: NavigateParams) => {
|
|
18
16
|
if (params.path) {
|
|
@@ -44,7 +42,6 @@ export const NavigatorProvider = ({
|
|
|
44
42
|
return (
|
|
45
43
|
<NavigatorContext.Provider value={{
|
|
46
44
|
navigate: navigateFunction,
|
|
47
|
-
params: params || {}
|
|
48
45
|
}}>
|
|
49
46
|
<RouteComponent />
|
|
50
47
|
</NavigatorContext.Provider>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { AvatarExamples, BadgeExamples, ButtonExamples, CardExamples, CheckboxExamples, DialogExamples, DividerExamples, IconExamples, InputExamples, PopoverExamples, ScreenExamples, SVGImageExamples, TextExamples, ViewExamples, ThemeExtensionExamples } from "../../../components/src/examples";
|
|
2
|
+
import { AvatarExamples, BadgeExamples, ButtonExamples, CardExamples, CheckboxExamples, DialogExamples, DividerExamples, IconExamples, InputExamples, PopoverExamples, ScreenExamples, SelectExamples, SVGImageExamples, TextExamples, ViewExamples, ThemeExtensionExamples } from "../../../components/src/examples";
|
|
3
3
|
import { DataGridShowcase } from "../../../datagrid/src/examples";
|
|
4
4
|
import { DatePickerExamples } from "../../../datepicker/src/examples";
|
|
5
5
|
import { Button, Divider, Screen, Text, View } from "../../../components/src";
|
|
@@ -192,6 +192,15 @@ const HomeScreen = () => {
|
|
|
192
192
|
}}>
|
|
193
193
|
Popover
|
|
194
194
|
</Button>
|
|
195
|
+
<Button
|
|
196
|
+
onPress={() => {
|
|
197
|
+
navigator.navigate({
|
|
198
|
+
path: "/select",
|
|
199
|
+
vars: {},
|
|
200
|
+
});
|
|
201
|
+
}}>
|
|
202
|
+
Select
|
|
203
|
+
</Button>
|
|
195
204
|
|
|
196
205
|
<Divider spacing="medium" />
|
|
197
206
|
<Text size="small" weight="semibold" color="secondary">Data Components</Text>
|
|
@@ -257,6 +266,7 @@ const StackRouter: NavigatorParam = {
|
|
|
257
266
|
{ path: "svg-image", type: 'screen', component: SVGImageExamples},
|
|
258
267
|
{ path: "dialog", type: 'screen', component: DialogExamples},
|
|
259
268
|
{ path: "popover", type: 'screen', component: PopoverExamples},
|
|
269
|
+
{ path: "select", type: 'screen', component: SelectExamples},
|
|
260
270
|
{ path: "datagrid", type: 'screen', component: DataGridShowcase},
|
|
261
271
|
{ path: "datepicker", type: 'screen', component: DatePickerExamples},
|
|
262
272
|
{ path: "theme-extension", type: 'screen', component: ThemeExtensionExamples},
|
package/src/index.web.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Web-specific exports
|
|
2
2
|
export * from './index';
|
|
3
3
|
|
|
4
|
-
//
|
|
5
|
-
export {
|
|
4
|
+
// Direct export to fix module resolution
|
|
5
|
+
export { NavigatorProvider, useNavigator } from './context/NavigatorContext.web';
|
|
@@ -1,8 +1,7 @@
|
|
|
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'
|
|
6
5
|
export interface DefaultStackLayoutProps extends StackLayoutProps {
|
|
7
6
|
onNavigate: (path: string) => void
|
|
8
7
|
currentPath: string
|
|
@@ -1,7 +1,7 @@
|
|
|
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
5
|
|
|
6
6
|
export interface DefaultTabLayoutProps extends TabLayoutProps {}
|
|
7
7
|
|
|
@@ -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,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';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import { Routes, Route } from '
|
|
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'
|