@idealyst/navigation 1.0.62 → 1.0.64
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 +3 -3
- package/src/examples/ExampleStackRouter.tsx +0 -27
- package/src/layouts/index.ts +0 -2
- package/src/routing/types.ts +5 -0
- package/src/layouts/DefaultTabLayout.web.tsx +0 -105
- package/src/layouts/GeneralLayout/GeneralLayout.styles.tsx +0 -55
- package/src/layouts/GeneralLayout/GeneralLayout.tsx +0 -143
- package/src/layouts/GeneralLayout/README.md +0 -498
- package/src/layouts/GeneralLayout/index.ts +0 -2
- package/src/layouts/GeneralLayout/types.ts +0 -99
- package/src/layouts/TabBarLayout/TabBarLayout.native.tsx +0 -283
- package/src/layouts/TabBarLayout/TabBarLayout.styles.tsx +0 -142
- package/src/layouts/TabBarLayout/TabBarLayout.web.tsx +0 -286
- package/src/layouts/TabBarLayout/index.native.ts +0 -2
- package/src/layouts/TabBarLayout/index.ts +0 -2
- package/src/layouts/TabBarLayout/index.web.ts +0 -2
- package/src/layouts/TabBarLayout/types.ts +0 -176
- package/src/routing_old/README.md +0 -421
- package/src/routing_old/index.native.tsx +0 -2
- package/src/routing_old/index.ts +0 -2
- package/src/routing_old/index.web.tsx +0 -2
- package/src/routing_old/router.native.tsx +0 -192
- package/src/routing_old/router.web.tsx +0 -366
- package/src/routing_old/types.ts +0 -74
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@idealyst/navigation",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.64",
|
|
4
4
|
"description": "Cross-platform navigation library for React and React Native",
|
|
5
5
|
"readme": "README.md",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
"publish:npm": "npm publish"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
|
-
"@idealyst/components": "^1.0.
|
|
42
|
-
"@idealyst/theme": "^1.0.
|
|
41
|
+
"@idealyst/components": "^1.0.64",
|
|
42
|
+
"@idealyst/theme": "^1.0.64",
|
|
43
43
|
"@react-navigation/bottom-tabs": "^7.0.0",
|
|
44
44
|
"@react-navigation/drawer": "^7.0.0",
|
|
45
45
|
"@react-navigation/native": "^7.0.0",
|
|
@@ -5,7 +5,6 @@ import { DatePickerExamples } from "../../../datepicker/src/examples";
|
|
|
5
5
|
import { Button, Divider, Screen, Text, View } from "../../../components/src";
|
|
6
6
|
import { useNavigator } from "../context";
|
|
7
7
|
import { UnistylesRuntime } from 'react-native-unistyles';
|
|
8
|
-
import { GeneralLayout } from '../layouts/GeneralLayout';
|
|
9
8
|
import { NavigatorParam, RouteParam } from '../routing';
|
|
10
9
|
import { getNextTheme, getThemeDisplayName, isHighContrastTheme } from './unistyles';
|
|
11
10
|
|
|
@@ -238,32 +237,6 @@ const HomeScreen = () => {
|
|
|
238
237
|
)
|
|
239
238
|
};
|
|
240
239
|
|
|
241
|
-
const WrappedGeneralLayout = (props: any) => {
|
|
242
|
-
|
|
243
|
-
const navigator = useNavigator();
|
|
244
|
-
|
|
245
|
-
return (
|
|
246
|
-
<GeneralLayout
|
|
247
|
-
header={{
|
|
248
|
-
content: <Text style={{ marginHorizontal: 'auto' }} color="inverse">Stack Router Demo App</Text>,
|
|
249
|
-
}}
|
|
250
|
-
sidebar={{
|
|
251
|
-
enabled: true,
|
|
252
|
-
collapsible: true,
|
|
253
|
-
position: 'left',
|
|
254
|
-
initiallyExpanded: false,
|
|
255
|
-
content: <Button onPress={() => {
|
|
256
|
-
navigator.navigate({
|
|
257
|
-
path: "/",
|
|
258
|
-
vars: {},
|
|
259
|
-
});
|
|
260
|
-
}}>Home</Button>,
|
|
261
|
-
}}
|
|
262
|
-
{...props}>
|
|
263
|
-
</GeneralLayout>
|
|
264
|
-
)
|
|
265
|
-
}
|
|
266
|
-
|
|
267
240
|
const StackRouter: NavigatorParam = {
|
|
268
241
|
path: "/",
|
|
269
242
|
type: 'navigator',
|
package/src/layouts/index.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
export * from './GeneralLayout';
|
|
2
|
-
export * from './TabBarLayout';
|
|
3
1
|
export { DefaultTabLayout } from './DefaultTabLayout'
|
|
4
2
|
export { DefaultStackLayout } from './DefaultStackLayout'
|
|
5
3
|
export type { TabLayoutProps, StackLayoutProps, TabLayoutComponent, StackLayoutComponent } from '../routing/types'
|
package/src/routing/types.ts
CHANGED
|
@@ -58,6 +58,11 @@ export type NavigatorOptions = {
|
|
|
58
58
|
* Custom header right component
|
|
59
59
|
*/
|
|
60
60
|
headerRight?: React.ComponentType | React.ReactElement;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Whether to hide the native React Navigation header (mobile only)
|
|
64
|
+
*/
|
|
65
|
+
hideNativeHeader?: boolean;
|
|
61
66
|
}
|
|
62
67
|
|
|
63
68
|
export type BaseNavigatorParam = {
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import { View, Text, Button, Icon } from '@idealyst/components'
|
|
3
|
-
import { TabLayoutProps } from '../routing/types'
|
|
4
|
-
|
|
5
|
-
export interface DefaultTabLayoutProps extends TabLayoutProps {
|
|
6
|
-
currentRoute: React.ComponentType
|
|
7
|
-
onNavigate: (path: string) => void
|
|
8
|
-
currentPath: string
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Default Tab Layout Component for Web
|
|
13
|
-
* Provides a simple tab navigation interface using @idealyst/components
|
|
14
|
-
*/
|
|
15
|
-
export const DefaultTabLayout: React.FC<DefaultTabLayoutProps> = ({
|
|
16
|
-
options,
|
|
17
|
-
routes,
|
|
18
|
-
currentRoute: CurrentRoute,
|
|
19
|
-
onNavigate,
|
|
20
|
-
currentPath
|
|
21
|
-
}) => {
|
|
22
|
-
return (
|
|
23
|
-
<View style={{ height: '100vh', flexDirection: 'column' }}>
|
|
24
|
-
{/* Header */}
|
|
25
|
-
{options?.headerTitle && (
|
|
26
|
-
<View style={{
|
|
27
|
-
padding: 16,
|
|
28
|
-
borderBottomWidth: 1,
|
|
29
|
-
borderBottomColor: '#e0e0e0',
|
|
30
|
-
backgroundColor: '#f8f9fa'
|
|
31
|
-
}}>
|
|
32
|
-
<View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between' }}>
|
|
33
|
-
<View style={{ flexDirection: 'row', alignItems: 'center', flex: 1 }}>
|
|
34
|
-
{options.headerLeft && React.createElement(options.headerLeft as any)}
|
|
35
|
-
|
|
36
|
-
{typeof options.headerTitle === 'string' ? (
|
|
37
|
-
<Text size="large" weight="bold" style={{ marginLeft: options.headerLeft ? 12 : 0 }}>
|
|
38
|
-
{options.headerTitle}
|
|
39
|
-
</Text>
|
|
40
|
-
) : (
|
|
41
|
-
React.createElement(options.headerTitle as any)
|
|
42
|
-
)}
|
|
43
|
-
</View>
|
|
44
|
-
|
|
45
|
-
{options.headerRight && React.createElement(options.headerRight as any)}
|
|
46
|
-
</View>
|
|
47
|
-
</View>
|
|
48
|
-
)}
|
|
49
|
-
|
|
50
|
-
{/* Tab Navigation */}
|
|
51
|
-
<View style={{
|
|
52
|
-
padding: 12,
|
|
53
|
-
borderBottomWidth: 1,
|
|
54
|
-
borderBottomColor: '#e0e0e0',
|
|
55
|
-
backgroundColor: '#ffffff'
|
|
56
|
-
}}>
|
|
57
|
-
<View style={{ flexDirection: 'row', gap: 8 }}>
|
|
58
|
-
{routes.map((route) => {
|
|
59
|
-
if (route.type !== 'screen') return null
|
|
60
|
-
|
|
61
|
-
const isActive = currentPath === (route.path === '/' ? '/' : `/${route.path.replace(/^\//, '')}`)
|
|
62
|
-
const screenRoute = route as any
|
|
63
|
-
const label = screenRoute.options?.tabBarLabel || screenRoute.options?.title || (route.path === '/' ? 'Home' : route.path)
|
|
64
|
-
const icon = screenRoute.options?.tabBarIcon
|
|
65
|
-
|
|
66
|
-
return (
|
|
67
|
-
<Button
|
|
68
|
-
key={route.path}
|
|
69
|
-
variant={isActive ? 'contained' : 'outlined'}
|
|
70
|
-
intent={isActive ? 'primary' : undefined}
|
|
71
|
-
size="small"
|
|
72
|
-
onPress={() => onNavigate(route.path)}
|
|
73
|
-
style={{
|
|
74
|
-
flexDirection: 'row',
|
|
75
|
-
alignItems: 'center',
|
|
76
|
-
gap: 6
|
|
77
|
-
}}
|
|
78
|
-
>
|
|
79
|
-
{icon && typeof icon === 'string' && (
|
|
80
|
-
<Icon
|
|
81
|
-
name={icon as any}
|
|
82
|
-
size="sm"
|
|
83
|
-
color={isActive ? 'white' : 'primary'}
|
|
84
|
-
/>
|
|
85
|
-
)}
|
|
86
|
-
<Text
|
|
87
|
-
size="small"
|
|
88
|
-
color={isActive ? 'white' : 'primary'}
|
|
89
|
-
weight={isActive ? 'semibold' : 'medium'}
|
|
90
|
-
>
|
|
91
|
-
{label}
|
|
92
|
-
</Text>
|
|
93
|
-
</Button>
|
|
94
|
-
)
|
|
95
|
-
})}
|
|
96
|
-
</View>
|
|
97
|
-
</View>
|
|
98
|
-
|
|
99
|
-
{/* Content Area */}
|
|
100
|
-
<View style={{ flex: 1, padding: 20 }}>
|
|
101
|
-
<CurrentRoute />
|
|
102
|
-
</View>
|
|
103
|
-
</View>
|
|
104
|
-
)
|
|
105
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
// Simple style objects for the GeneralLayout
|
|
2
|
-
export const generalLayoutStyles = {
|
|
3
|
-
container: {
|
|
4
|
-
display: 'flex',
|
|
5
|
-
width: '100%',
|
|
6
|
-
height: '100vh',
|
|
7
|
-
overflow: 'hidden',
|
|
8
|
-
} as const,
|
|
9
|
-
|
|
10
|
-
headerContainer: {
|
|
11
|
-
display: 'flex',
|
|
12
|
-
flexDirection: 'row',
|
|
13
|
-
width: '100%',
|
|
14
|
-
zIndex: 100,
|
|
15
|
-
} as const,
|
|
16
|
-
|
|
17
|
-
bodyContainer: {
|
|
18
|
-
display: 'flex',
|
|
19
|
-
flexDirection: 'row',
|
|
20
|
-
flex: 1,
|
|
21
|
-
overflow: 'hidden',
|
|
22
|
-
} as const,
|
|
23
|
-
|
|
24
|
-
sidebar: {
|
|
25
|
-
display: 'flex',
|
|
26
|
-
flexDirection: 'column',
|
|
27
|
-
transition: 'width 0.3s ease-in-out',
|
|
28
|
-
overflow: 'hidden',
|
|
29
|
-
zIndex: 50,
|
|
30
|
-
} as const,
|
|
31
|
-
|
|
32
|
-
sidebarContent: {
|
|
33
|
-
flex: 1,
|
|
34
|
-
overflow: 'auto',
|
|
35
|
-
} as const,
|
|
36
|
-
|
|
37
|
-
sidebarToggle: {
|
|
38
|
-
alignSelf: 'flex-end',
|
|
39
|
-
margin: '8px',
|
|
40
|
-
marginBottom: '16px',
|
|
41
|
-
} as const,
|
|
42
|
-
|
|
43
|
-
mainContent: {
|
|
44
|
-
flex: 1,
|
|
45
|
-
display: 'flex',
|
|
46
|
-
flexDirection: 'column',
|
|
47
|
-
overflow: 'auto',
|
|
48
|
-
order: 2,
|
|
49
|
-
} as const,
|
|
50
|
-
|
|
51
|
-
contentArea: {
|
|
52
|
-
flex: 1,
|
|
53
|
-
overflow: 'auto',
|
|
54
|
-
} as const,
|
|
55
|
-
};
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import React, { useState, useCallback } from 'react';
|
|
2
|
-
import { View, Button, Text } from '@idealyst/components';
|
|
3
|
-
import { GeneralLayoutProps, SidebarConfig, HeaderConfig } from './types';
|
|
4
|
-
import { generalLayoutStyles } from './GeneralLayout.styles';
|
|
5
|
-
|
|
6
|
-
const GeneralLayout: React.FC<GeneralLayoutProps> = ({
|
|
7
|
-
children,
|
|
8
|
-
sidebar = {},
|
|
9
|
-
header = {},
|
|
10
|
-
style,
|
|
11
|
-
testID,
|
|
12
|
-
}) => {
|
|
13
|
-
// Default sidebar configuration
|
|
14
|
-
const sidebarConfig: Required<SidebarConfig> = {
|
|
15
|
-
enabled: true,
|
|
16
|
-
initiallyExpanded: true,
|
|
17
|
-
expandedWidth: 280,
|
|
18
|
-
collapsedWidth: 60,
|
|
19
|
-
collapsible: true,
|
|
20
|
-
position: 'left',
|
|
21
|
-
content: null,
|
|
22
|
-
style: undefined,
|
|
23
|
-
...sidebar,
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
// Default header configuration
|
|
27
|
-
const headerConfig: Required<HeaderConfig> = {
|
|
28
|
-
enabled: true,
|
|
29
|
-
height: 64,
|
|
30
|
-
content: null,
|
|
31
|
-
style: undefined,
|
|
32
|
-
...header,
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
// State for sidebar expansion
|
|
36
|
-
const [isSidebarExpanded, setIsSidebarExpanded] = useState(
|
|
37
|
-
sidebarConfig.initiallyExpanded
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
// Toggle sidebar expansion
|
|
41
|
-
const toggleSidebar = useCallback(() => {
|
|
42
|
-
if (sidebarConfig.collapsible) {
|
|
43
|
-
setIsSidebarExpanded((prev) => !prev);
|
|
44
|
-
}
|
|
45
|
-
}, [sidebarConfig.collapsible]);
|
|
46
|
-
|
|
47
|
-
// Calculate sidebar width based on expanded state
|
|
48
|
-
const sidebarWidth = isSidebarExpanded
|
|
49
|
-
? sidebarConfig.expandedWidth
|
|
50
|
-
: sidebarConfig.collapsedWidth;
|
|
51
|
-
|
|
52
|
-
// Create dynamic styles for sidebar width
|
|
53
|
-
const sidebarDynamicStyles = {
|
|
54
|
-
width: sidebarWidth,
|
|
55
|
-
minWidth: sidebarWidth,
|
|
56
|
-
maxWidth: sidebarWidth,
|
|
57
|
-
order: sidebarConfig.position === 'right' ? 3 : 1,
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
// Create dynamic styles for header height
|
|
61
|
-
const headerDynamicStyles = {
|
|
62
|
-
height: headerConfig.height,
|
|
63
|
-
minHeight: headerConfig.height,
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
return (
|
|
67
|
-
<View
|
|
68
|
-
background="transparent"
|
|
69
|
-
style={[
|
|
70
|
-
generalLayoutStyles.container,
|
|
71
|
-
style,
|
|
72
|
-
]}
|
|
73
|
-
testID={testID}
|
|
74
|
-
>
|
|
75
|
-
{/* Header */}
|
|
76
|
-
{headerConfig.enabled && (
|
|
77
|
-
<View
|
|
78
|
-
border="thin"
|
|
79
|
-
spacing="md"
|
|
80
|
-
style={[
|
|
81
|
-
generalLayoutStyles.headerContainer,
|
|
82
|
-
headerDynamicStyles,
|
|
83
|
-
headerConfig.style,
|
|
84
|
-
]}
|
|
85
|
-
>
|
|
86
|
-
{headerConfig.content}
|
|
87
|
-
</View>
|
|
88
|
-
)}
|
|
89
|
-
|
|
90
|
-
{/* Body Container */}
|
|
91
|
-
<View style={generalLayoutStyles.bodyContainer}>
|
|
92
|
-
{/* Sidebar */}
|
|
93
|
-
{sidebarConfig.enabled && (
|
|
94
|
-
<View
|
|
95
|
-
background="surface"
|
|
96
|
-
border="thin"
|
|
97
|
-
spacing="md"
|
|
98
|
-
style={[
|
|
99
|
-
generalLayoutStyles.sidebar,
|
|
100
|
-
sidebarDynamicStyles,
|
|
101
|
-
sidebarConfig.style,
|
|
102
|
-
]}
|
|
103
|
-
>
|
|
104
|
-
{/* Sidebar Toggle Button - Positioned within sidebar using flexbox */}
|
|
105
|
-
{sidebarConfig.collapsible && (
|
|
106
|
-
<Button
|
|
107
|
-
onPress={toggleSidebar}
|
|
108
|
-
variant="outlined"
|
|
109
|
-
size="small"
|
|
110
|
-
style={[
|
|
111
|
-
generalLayoutStyles.sidebarToggle,
|
|
112
|
-
// Align toggle button based on sidebar position
|
|
113
|
-
{ alignSelf: sidebarConfig.position === 'right' ? 'flex-start' : 'flex-end' }
|
|
114
|
-
]}
|
|
115
|
-
>
|
|
116
|
-
{sidebarConfig.position === 'right'
|
|
117
|
-
? (isSidebarExpanded ? '→' : '←')
|
|
118
|
-
: (isSidebarExpanded ? '←' : '→')
|
|
119
|
-
}
|
|
120
|
-
</Button>
|
|
121
|
-
)}
|
|
122
|
-
|
|
123
|
-
{/* Sidebar Content */}
|
|
124
|
-
<View style={generalLayoutStyles.sidebarContent}>
|
|
125
|
-
{sidebarConfig.content}
|
|
126
|
-
</View>
|
|
127
|
-
</View>
|
|
128
|
-
)}
|
|
129
|
-
|
|
130
|
-
{/* Main Content Area */}
|
|
131
|
-
<View style={generalLayoutStyles.mainContent}>
|
|
132
|
-
<View
|
|
133
|
-
style={generalLayoutStyles.contentArea}
|
|
134
|
-
>
|
|
135
|
-
{children}
|
|
136
|
-
</View>
|
|
137
|
-
</View>
|
|
138
|
-
</View>
|
|
139
|
-
</View>
|
|
140
|
-
);
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
export default GeneralLayout;
|