@idealyst/navigation 1.0.62 → 1.0.63

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": "@idealyst/navigation",
3
- "version": "1.0.62",
3
+ "version": "1.0.63",
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.62",
42
- "@idealyst/theme": "^1.0.62",
41
+ "@idealyst/components": "^1.0.63",
42
+ "@idealyst/theme": "^1.0.63",
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",
@@ -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;