@idealyst/navigation 1.0.53 → 1.0.56

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,13 +1,14 @@
1
1
  {
2
2
  "name": "@idealyst/navigation",
3
- "version": "1.0.53",
3
+ "version": "1.0.56",
4
4
  "description": "Cross-platform navigation library for React and React Native",
5
+ "readme": "README.md",
5
6
  "main": "src/index.ts",
6
7
  "module": "src/index.ts",
7
8
  "types": "src/index.ts",
8
9
  "repository": {
9
10
  "type": "git",
10
- "url": "https://github.com/your-username/idealyst-framework.git",
11
+ "url": "https://github.com/IdealystIO/idealyst-framework.git",
11
12
  "directory": "packages/navigation"
12
13
  },
13
14
  "author": "Nicholas Mercier <nicho.mercier@gmail.com>",
@@ -37,8 +38,8 @@
37
38
  "publish:npm": "npm publish"
38
39
  },
39
40
  "peerDependencies": {
40
- "@idealyst/components": "^1.0.53",
41
- "@idealyst/theme": "^1.0.53",
41
+ "@idealyst/components": "^1.0.56",
42
+ "@idealyst/theme": "^1.0.56",
42
43
  "@react-navigation/bottom-tabs": "^7.0.0",
43
44
  "@react-navigation/drawer": "^7.0.0",
44
45
  "@react-navigation/native": "^7.0.0",
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { AvatarExamples, BadgeExamples, ButtonExamples, CardExamples, CheckboxExamples, DialogExamples, DividerExamples, IconExamples, InputExamples, PopoverExamples, TextExamples, ViewExamples, ThemeExtensionExamples } from "../../../components/src/examples";
2
+ import { AvatarExamples, BadgeExamples, ButtonExamples, CardExamples, CheckboxExamples, DialogExamples, DividerExamples, IconExamples, InputExamples, PopoverExamples, 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 { Screen, Text, View, Button } from "../../../components/src";
@@ -131,6 +131,12 @@ const IconDrawerScreen = () => (
131
131
  </Screen>
132
132
  );
133
133
 
134
+ const SVGImageDrawerScreen = () => (
135
+ <Screen>
136
+ <SVGImageExamples />
137
+ </Screen>
138
+ );
139
+
134
140
  const DialogDrawerScreen = () => (
135
141
  <Screen>
136
142
  <DialogExamples />
@@ -178,6 +184,7 @@ const DrawerRouter: RouteParam = {
178
184
  { path: "text", component: TextDrawerScreen },
179
185
  { path: "view", component: ViewDrawerScreen },
180
186
  { path: "icon", component: IconDrawerScreen },
187
+ { path: "svg-image", component: SVGImageDrawerScreen },
181
188
  { path: "dialog", component: DialogDrawerScreen },
182
189
  { path: "popover", component: PopoverDrawerScreen },
183
190
  { path: "datagrid", component: DataGridDrawerScreen },
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { AvatarExamples, BadgeExamples, ButtonExamples, CardExamples, CheckboxExamples, DialogExamples, DividerExamples, IconExamples, InputExamples, PopoverExamples, ScreenExamples, TextExamples, ViewExamples, ThemeExtensionExamples } from "../../../components/src/examples";
2
+ import { AvatarExamples, BadgeExamples, ButtonExamples, CardExamples, CheckboxExamples, DialogExamples, DividerExamples, IconExamples, InputExamples, PopoverExamples, ScreenExamples, 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";
@@ -283,6 +283,7 @@ const StackRouter: RouteParam = {
283
283
  { path: "view", component: ViewExamples},
284
284
  { path: "screen", component: ScreenExamples},
285
285
  { path: "icon", component: IconExamples},
286
+ { path: "svg-image", component: SVGImageExamples},
286
287
  { path: "dialog", component: DialogExamples},
287
288
  { path: "popover", component: PopoverExamples},
288
289
  { path: "datagrid", component: DataGridShowcase},
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { ButtonExamples, CardExamples, IconExamples, ThemeExtensionExamples } from "../../../components/src/examples";
2
+ import { ButtonExamples, CardExamples, IconExamples, SVGImageExamples, ThemeExtensionExamples } from "../../../components/src/examples";
3
3
  import { Screen, Text, View, Button, Icon } from "../../../components/src";
4
4
  import { UnistylesRuntime } from 'react-native-unistyles';
5
5
  import { RouteParam } from '../routing';
@@ -37,15 +37,26 @@ const HomeTabScreen = () => {
37
37
  TabBar Navigation Demo
38
38
  </Text>
39
39
  <Text size="medium">
40
- This demonstrates native tab navigation with screen options
40
+ This demonstrates native tab navigation with custom headers
41
41
  </Text>
42
42
 
43
+ <View spacing="sm" style={{ padding: 12, backgroundColor: 'rgba(0,150,255,0.1)', borderRadius: 8 }}>
44
+ <Text size="small" weight="semibold">📋 Header Features Demonstrated:</Text>
45
+ <Text size="small">• headerTitle: Custom title component with icon</Text>
46
+ <Text size="small">• headerLeft: Menu button (appears before title)</Text>
47
+ <Text size="small">• headerRight: Multiple action buttons</Text>
48
+ <Text size="small">• Cross-platform: Works on both mobile and web</Text>
49
+ </View>
50
+
43
51
  <View spacing="md" style={{ marginTop: 24 }}>
44
52
  <Text size="medium" weight="semibold">Navigation Tabs</Text>
45
53
  <Text size="small">
46
- The tabs below use native React Navigation with screen options for icons and labels.
47
- On mobile, tabs appear at the bottom. On web, they may adapt based on the platform.
54
+ Each tab demonstrates different header configurations:
48
55
  </Text>
56
+ <Text size="small">• Home: Custom headerTitle, headerLeft menu, headerRight actions</Text>
57
+ <Text size="small">• Components: Simple headerLeft back button, headerRight refresh</Text>
58
+ <Text size="small">• Settings: String headerTitle override, help + menu buttons</Text>
59
+ <Text size="small">• Theme: Component headerTitle with icon, save button</Text>
49
60
 
50
61
  <View spacing="sm">
51
62
  <Button size="small" variant="outlined" onPress={() => navigator.navigate({ path: '/components', vars: {} })}>
@@ -97,7 +108,14 @@ const ComponentsTabScreen = () => (
97
108
  <Screen>
98
109
  <View spacing="lg">
99
110
  <Text size="large" weight="bold">Components</Text>
100
- <Text>Explore UI components with native tab navigation</Text>
111
+ <Text>Explore UI components with custom header navigation</Text>
112
+
113
+ <View spacing="sm" style={{ padding: 12, backgroundColor: 'rgba(100,200,100,0.1)', borderRadius: 8 }}>
114
+ <Text size="small" weight="semibold">🔧 This tab demonstrates:</Text>
115
+ <Text size="small">• headerLeft: Back arrow button</Text>
116
+ <Text size="small">• headerRight: Refresh action button</Text>
117
+ <Text size="small">• Default title: Uses 'Components' from screenOptions</Text>
118
+ </View>
101
119
 
102
120
  <View spacing="md">
103
121
  <Text size="medium" weight="semibold">Button Examples</Text>
@@ -113,6 +131,11 @@ const ComponentsTabScreen = () => (
113
131
  <Text size="medium" weight="semibold">Icon Examples</Text>
114
132
  <IconExamples />
115
133
  </View>
134
+
135
+ <View spacing="md">
136
+ <Text size="medium" weight="semibold">SVG Image Examples</Text>
137
+ <SVGImageExamples />
138
+ </View>
116
139
  </View>
117
140
  </Screen>
118
141
  );
@@ -126,14 +149,24 @@ const SettingsTabScreen = () => {
126
149
  <Text size="large" weight="bold">Settings</Text>
127
150
  <Text>Configure the TabBar demo settings</Text>
128
151
 
152
+ <View spacing="sm" style={{ padding: 12, backgroundColor: 'rgba(255,150,0,0.1)', borderRadius: 8 }}>
153
+ <Text size="small" weight="semibold">⚙️ This tab demonstrates:</Text>
154
+ <Text size="small">• headerTitle: String override ('App Settings')</Text>
155
+ <Text size="small">• headerLeft: Chevron back button</Text>
156
+ <Text size="small">• headerRight: Help + menu buttons</Text>
157
+ <Text size="small">• Notice: Title in header != tab title</Text>
158
+ </View>
159
+
129
160
  <View spacing="md">
130
- <Text size="medium" weight="semibold">Navigation Info</Text>
131
- <Text size="small">
132
- This tab uses native navigation with screen options:
161
+ <Text size="medium" weight="semibold">Screen Options Used</Text>
162
+ <Text size="small" style={{ fontFamily: 'monospace', backgroundColor: 'rgba(0,0,0,0.05)', padding: 8 }}>
163
+ screenOptions: {{
164
+ title: 'Settings',{"\n"}
165
+ headerTitle: 'App Settings',{"\n"}
166
+ headerLeft: () => &lt;BackButton /&gt;,{"\n"}
167
+ headerRight: () => &lt;ActionButtons /&gt;
168
+ }}
133
169
  </Text>
134
- <Text size="small">• tabBarIcon: "cog" (Material Design Icons)</Text>
135
- <Text size="small">• tabBarLabel: "Settings"</Text>
136
- <Text size="small">• title: "Settings"</Text>
137
170
  </View>
138
171
 
139
172
  <View spacing="md">
@@ -150,7 +183,14 @@ const ThemeTabScreen = () => (
150
183
  <Screen>
151
184
  <View spacing="lg">
152
185
  <Text size="large" weight="bold">Theme System</Text>
153
- <Text>Explore the theme extension system</Text>
186
+ <Text>Explore the theme extension system with custom header</Text>
187
+
188
+ <View spacing="sm" style={{ padding: 12, backgroundColor: 'rgba(150,0,255,0.1)', borderRadius: 8 }}>
189
+ <Text size="small" weight="semibold">🎨 This tab demonstrates:</Text>
190
+ <Text size="small">• headerTitle: React component with icon + text</Text>
191
+ <Text size="small">• headerRight: Styled save button</Text>
192
+ <Text size="small">• Custom styling: Intent colors and typography</Text>
193
+ </View>
154
194
 
155
195
  <ThemeExtensionExamples />
156
196
  </View>
@@ -165,6 +205,27 @@ const TabRouter: RouteParam = {
165
205
  },
166
206
  screenOptions: {
167
207
  title: 'Home',
208
+ headerTitle: () => (
209
+ <View style={{ flexDirection: 'row', alignItems: 'center' }}>
210
+ <Icon name="home" size="md" style={{ marginRight: 8 }} />
211
+ <Text size="large" weight="bold">Tab Demo</Text>
212
+ </View>
213
+ ),
214
+ headerLeft: () => (
215
+ <Button variant="text" size="small">
216
+ <Icon name="menu" size="md" />
217
+ </Button>
218
+ ),
219
+ headerRight: () => (
220
+ <View style={{ flexDirection: 'row', alignItems: 'center' }}>
221
+ <Button variant="text" size="small" style={{ marginRight: 8 }}>
222
+ <Icon name="bell" size="md" />
223
+ </Button>
224
+ <Button variant="text" size="small">
225
+ <Icon name="account" size="md" />
226
+ </Button>
227
+ </View>
228
+ ),
168
229
  tabBarLabel: 'Home',
169
230
  tabBarIcon: ({ focused, size }) => {
170
231
  return <Icon name="home" color={focused ? 'blue' : 'black'} size={size} />
@@ -176,6 +237,16 @@ const TabRouter: RouteParam = {
176
237
  component: ComponentsTabScreen,
177
238
  screenOptions: {
178
239
  title: 'Components',
240
+ headerLeft: () => (
241
+ <Button variant="text" size="small">
242
+ <Icon name="arrow-left" size="md" />
243
+ </Button>
244
+ ),
245
+ headerRight: () => (
246
+ <Button variant="text" size="small">
247
+ <Icon name="refresh" size="md" />
248
+ </Button>
249
+ ),
179
250
  tabBarLabel: 'Components',
180
251
  tabBarIcon: (props) => {
181
252
  if (props.focused) {
@@ -190,6 +261,22 @@ const TabRouter: RouteParam = {
190
261
  component: SettingsTabScreen,
191
262
  screenOptions: {
192
263
  title: 'Settings',
264
+ headerTitle: 'App Settings',
265
+ headerLeft: () => (
266
+ <Button variant="text" size="small">
267
+ <Icon name="chevron-left" size="md" />
268
+ </Button>
269
+ ),
270
+ headerRight: () => (
271
+ <View style={{ flexDirection: 'row' }}>
272
+ <Button variant="text" size="small" style={{ marginRight: 4 }}>
273
+ <Icon name="help-circle" size="md" />
274
+ </Button>
275
+ <Button variant="text" size="small">
276
+ <Icon name="dots-vertical" size="md" />
277
+ </Button>
278
+ </View>
279
+ ),
193
280
  tabBarLabel: 'Settings',
194
281
  tabBarIcon: ({ focused, size }) => (
195
282
  <Icon
@@ -206,6 +293,17 @@ const TabRouter: RouteParam = {
206
293
  component: ThemeTabScreen,
207
294
  screenOptions: {
208
295
  title: 'Theme',
296
+ headerTitle: () => (
297
+ <View style={{ flexDirection: 'row', alignItems: 'center' }}>
298
+ <Icon name="palette" size="sm" style={{ marginRight: 6 }} />
299
+ <Text size="medium" weight="semibold">Theme System</Text>
300
+ </View>
301
+ ),
302
+ headerRight: () => (
303
+ <Button variant="contained" size="small" intent="primary">
304
+ <Text size="small" color="white">Save</Text>
305
+ </Button>
306
+ ),
209
307
  tabBarLabel: 'Theme',
210
308
  tabBarIcon: ({ focused, size }) => (
211
309
  <Icon name="palette" color={focused ? 'blue' : 'black'} size={size} />
@@ -22,7 +22,10 @@ const convertScreenOptions = (screenOptions?: ScreenOptions) => {
22
22
 
23
23
  if (screenOptions.title) {
24
24
  options.title = screenOptions.title;
25
- options.headerTitle = screenOptions.title;
25
+ // Set default headerTitle to title, but allow headerTitle to override
26
+ if (!screenOptions.headerTitle) {
27
+ options.headerTitle = screenOptions.title;
28
+ }
26
29
  }
27
30
 
28
31
  if (screenOptions.tabBarLabel) {
@@ -52,6 +55,7 @@ const convertScreenOptions = (screenOptions?: ScreenOptions) => {
52
55
  options.tabBarStyle = screenOptions.tabBarVisible ? {} : { display: 'none' };
53
56
  }
54
57
 
58
+ // headerTitle should override the default title in the header
55
59
  if (screenOptions.headerTitle) {
56
60
  options.headerTitle = screenOptions.headerTitle;
57
61
  }
@@ -60,6 +64,10 @@ const convertScreenOptions = (screenOptions?: ScreenOptions) => {
60
64
  options.headerBackVisible = screenOptions.headerBackVisible;
61
65
  }
62
66
 
67
+ if (screenOptions.headerLeft) {
68
+ options.headerLeft = screenOptions.headerLeft;
69
+ }
70
+
63
71
  if (screenOptions.headerRight) {
64
72
  options.headerRight = screenOptions.headerRight;
65
73
  }
@@ -156,14 +156,15 @@ const SimpleTabLayout: React.FC<SimpleTabLayoutProps> = ({ routeParam, webScreen
156
156
  }}>
157
157
  {/* Left side */}
158
158
  <View style={{ flexDirection: 'row', alignItems: 'center', flex: 1 }}>
159
- {webScreenOptions.headerLeft ? (
160
- renderHeaderElement(webScreenOptions.headerLeft)
161
- ) : (
162
- renderHeaderElement(
163
- webScreenOptions.headerTitle ||
164
- webScreenOptions.title ||
165
- 'Navigation'
166
- )
159
+ {webScreenOptions.headerLeft && (
160
+ <View style={{ marginRight: 12 }}>
161
+ {renderHeaderElement(webScreenOptions.headerLeft)}
162
+ </View>
163
+ )}
164
+ {renderHeaderElement(
165
+ webScreenOptions.headerTitle ||
166
+ webScreenOptions.title ||
167
+ 'Navigation'
167
168
  )}
168
169
  </View>
169
170
 
@@ -258,6 +259,10 @@ const convertScreenOptionsForWeb = (screenOptions?: ScreenOptions) => {
258
259
  webOptions.headerBackVisible = screenOptions.headerBackVisible;
259
260
  }
260
261
 
262
+ if (screenOptions.headerLeft) {
263
+ webOptions.headerLeft = screenOptions.headerLeft;
264
+ }
265
+
261
266
  if (screenOptions.headerRight) {
262
267
  webOptions.headerRight = screenOptions.headerRight;
263
268
  }