Skip to content

Commit a665931

Browse files
committed
add new navigation example
1 parent cdfb592 commit a665931

13 files changed

+341
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Page ux:Class="AccountPage" Title="Your Account">
2+
<JavaScript>
3+
exports.userName = "Hannah"
4+
</JavaScript>
5+
<TitleAreaContent>
6+
<ResourceString Key="Title" Value="{userName}'s Account"/>
7+
</TitleAreaContent>
8+
9+
<Text Alignment="Center" Value="Account information"/>
10+
</Page>
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<DockPanel Color="#DDD" ux:Class="AppMenu">
2+
<!-- TODO: Remove this, depends on removing that JavaScript part -->
3+
<Router ux:Dependency="router"/>
4+
5+
<!-- TODO: Remove need for this JavaScript, do routing with a UX action -->
6+
<JavaScript>
7+
exports.gotoOne = function() {
8+
router.goto( "home", {}, "flights", {}, "arrivals" )
9+
}
10+
exports.gotoTwo = function() {
11+
router.goto( "home", {}, "flights", {}, "departures" )
12+
}
13+
exports.gotoThree = function() {
14+
router.goto( "home", {}, "bookings" )
15+
}
16+
exports.gotoAccount = function() {
17+
router.push( "account" )
18+
}
19+
</JavaScript>
20+
21+
<!-- logo / app name -->
22+
<Panel Dock="Top">
23+
<Text Value="✈️" Alignment="Center" Margin="0,0,0,10" FontSize="100"/>
24+
<Text Value="AppName" Alignment="BottomCenter" FontSize="20"/>
25+
</Panel>
26+
27+
<Panel ux:Class="AppMenuItem" HitTestMode="LocalBounds">
28+
<string ux:Property="Icon"/>
29+
<string ux:Property="Label"/>
30+
<!-- TODO: Remove use of `object` here, introduce an appropriate type -->
31+
<object ux:Property="Handler"/>
32+
33+
<Text Alignment="CenterLeft" Width="32" Margin="4,0" Value="{Property this.Icon}"
34+
Font="MaterialIcons" FontSize="32"/>
35+
<Text Alignment="CenterLeft" Margin="40,0,10,0" Value="{Property this.Label}"/>
36+
<Clicked Handler="{Property this.Handler}">
37+
<RaiseUserEvent EventName="dismissMenu"/>
38+
</Clicked>
39+
</Panel>
40+
41+
<StackPanel ItemSpacing="5" Margin="0,30,0,0">
42+
<AppMenuItem Icon="&#xE904;" Label="Arrivals" Handler="{gotoOne}"/>
43+
<AppMenuItem Icon="&#xE905;" Label="Departures" Handler="{gotoTwo}"/>
44+
<AppMenuItem Icon="&#xE896;" Label="Bookings" Handler="{gotoThree}"/>
45+
<AppMenuItem Icon="&#xE7FD;" Label="Account" Handler="{gotoAccount}"/>
46+
</StackPanel>
47+
</DockPanel>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<DockPanel ux:Class="ApplicationTop">
2+
<Router ux:Dependency="router"/>
3+
4+
<!--
5+
The title is partially static and dynamic:
6+
7+
- The Menu or Back button is on all pages and in the code here
8+
- Each page will use `TitleAreaContent` to add a title, or other controls into this panel.
9+
-->
10+
<Panel Dock="Top" ux:Name="titleArea" Height="40" Color="#DDD">
11+
<!-- Include Back or Menu navigation -->
12+
<Panel Alignment="Left" Padding="5,0" HitTestMode="LocalBounds" Navigation="router">
13+
<WhileCanGoBack>
14+
<Text Value="&#xE5C4;" Alignment="Center" Font="MaterialIcons" FontSize="28"/>
15+
<Clicked>
16+
<GoBack/>
17+
</Clicked>
18+
</WhileCanGoBack>
19+
<WhileCanGoBack Invert="true">
20+
<Text Value="&#xE5D2;" Alignment="Center" Font="MaterialIcons" FontSize="28"/>
21+
<Clicked>
22+
<RaiseUserEvent EventName="requestMenu"/>
23+
</Clicked>
24+
</WhileCanGoBack>
25+
</Panel>
26+
</Panel>
27+
<!-- The `TitleAreaContent` finds the panel via a resource binding -->
28+
<ResourceObject Key="titleArea" Value="titleArea"/>
29+
30+
<!--
31+
Two levels of navigation are used.
32+
33+
The "home" path contains the bottom action bar to quickly navigate between top-level sections. Any page that wishes to have this action bar should reside inside "home".
34+
35+
The other pages will not have this action bar, but will still have the common titleArea.
36+
-->
37+
<Navigator DefaultPath="home">
38+
<CreateBookingPage ux:Template="createBooking"/>
39+
<AccountPage ux:Template="account"/>
40+
<BookingPage ux:Template="booking"/>
41+
42+
<DockPanel ux:Name="home">
43+
<PageControl Interaction="None" ux:Name="homeNav">
44+
<FlightsPage ux:Name="flights" router="router">
45+
<!-- use resources to adjust icon in the bottom action bar -->
46+
<string ux:Key="Icon" ux:Value="&#xE539;"/>
47+
<string ux:Key="ShortTitle" ux:Value="Flights"/>
48+
</FlightsPage>
49+
<BookingsPage ux:Name="bookings" router="router">
50+
<string ux:Key="Icon" ux:Value="&#xE896;"/>
51+
<string ux:Key="ShortTitle" ux:Value="Bookings"/>
52+
</BookingsPage>
53+
</PageControl>
54+
55+
<!-- The icon/page listing at the bottom. Here we're using a PageIndicator to make the creation dynamic. Though you could also hard-code the display here and use a `Navigator` above instead of a `PageControl` -->
56+
<PageIndicator Navigation="homeNav" Dock="Bottom" Color="#DDD">
57+
<GridLayout RowCount="1" ChildOrder="ColumnMajor"/>
58+
59+
<StackPanel ux:Template="Dot" Alignment="Center" ItemSpacing="5" Margin="5">
60+
<Text Value="{Page Icon}" Font="MaterialIcons" FontSize="40"
61+
Color="#888" TextAlignment="Center" ux:Name="icon"/>
62+
<Text Value="{Page ShortTitle}" FontSize="14"
63+
Color="#888" TextAlignment="Center" ux:Name="label"/>
64+
<ActivatingAnimation>
65+
<Change icon.Color="#468"/>
66+
<Change label.Color="#468"/>
67+
</ActivatingAnimation>
68+
<Clicked>
69+
<NavigateTo Target="{Page Visual}"/>
70+
</Clicked>
71+
</StackPanel>
72+
</PageIndicator>
73+
</DockPanel>
74+
</Navigator>
75+
</DockPanel>
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<Page ux:Class="BookingPage" Title="View Booking">
2+
<JavaScript>
3+
var Observable = require( "FuseJS/Observable" )
4+
exports.info = Observable()
5+
6+
this.Parameter.onValueChanged( module, function(v) {
7+
//load the info from a module (with fetch)
8+
exports.info.value = {
9+
id: v.id,
10+
}
11+
})
12+
</JavaScript>
13+
<TitleAreaContent>
14+
<ResourceString Key="Title" Value="View {info.id}"/>
15+
</TitleAreaContent>
16+
17+
<Text Alignment="Center" Value="View Booking Page"/>
18+
</Page>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<Page Color="#CCC" Title="Bookings" ux:Class="BookingsPage">
2+
<Router ux:Dependency="router"/>
3+
4+
<JavaScript>
5+
var Observable = require( "FuseJS/Observable" )
6+
exports.order = function() {
7+
router.push( "createBooking" )
8+
}
9+
10+
exports.bookings = Observable()
11+
for (var i=0; i < 10; ++i ) {
12+
exports.bookings.add( {
13+
id: Math.floor( Math.random() * 100000 ),
14+
title: "Booking @" + i,
15+
})
16+
}
17+
18+
exports.view = function(args) {
19+
router.push( "booking", { id: args.data.id } )
20+
}
21+
</JavaScript>
22+
<TitleAreaContent>
23+
<Panel Alignment="Right" Padding="5,0" HitTestMode="LocalBounds" Clicked="{order}">
24+
<Text Value="&#xE854;" Alignment="Center" Font="MaterialIcons" FontSize="28"/>
25+
</Panel>
26+
</TitleAreaContent>
27+
28+
<ScrollView>
29+
<StackPanel ItemSpacing="5" Margin="0,5">
30+
<Each Items="{bookings}">
31+
<DockPanel HitTestMode="LocalBounds" Clicked="{view}" Color="#FFF">
32+
<Text Value="#{id}" FontSize="32" Dock="Left" Alignment="Center"/>
33+
<Text Value="{title}" Alignment="Center" Margin="10"/>
34+
35+
<Text Dock="Right" Margin="5" Value="&#xE5CC;" Font="MaterialIcons" FontSize="40" Alignment="Center"/>
36+
</DockPanel>
37+
</Each>
38+
</StackPanel>
39+
</ScrollView>
40+
</Page>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<Page ux:Class="CreateBookingPage" Title="Create Booking">
2+
<TitleAreaContent/>
3+
4+
<Text Alignment="Center" Value="Create Booking Page"/>
5+
</Page>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<Page Color="#EEE" ux:Class="FlightsPage">
2+
<Router ux:Dependency="router"/>
3+
4+
<TitleAreaContent>
5+
<!-- create tabs to show active sub-page -->
6+
<PageIndicator Navigation="flightNav" Alignment="Center">
7+
<Panel ux:Template="Dot" Padding="10,2" HitTestMode="LocalBounds">
8+
<Rectangle Layer="Background" Color="#0000" ux:Name="back"
9+
StrokeWidth="1.5" StrokeColor="#888"/>
10+
<Text Value="{Page Title}" FontSize="16" TextColor="#000" ux:Name="text"/>
11+
<ActivatingAnimation>
12+
<Change back.Color="#888"/>
13+
<Change text.Color="#FFF"/>
14+
</ActivatingAnimation>
15+
<Clicked>
16+
<NavigateTo Target="{Page Node}"/>
17+
</Clicked>
18+
</Panel>
19+
</PageIndicator>
20+
</TitleAreaContent>
21+
22+
<!-- TODO: Navigator wasn't working here with the NavigateTo above -->
23+
<!-- <Navigator ux:Name="flightNav" DefaultPath="arrivals"> -->
24+
<PageControl Interaction="None" ux:Name="flightNav">
25+
<Page Color="#EEF" Title="Arrivals" ux:Name="arrivals">
26+
<Text Alignment="Center" Value="Listing of arrivals"/>
27+
</Page>
28+
29+
<Page Color="#EEC" Title="Departures" ux:Name="departures">
30+
<Text Alignment="Center" Value="Listing of departures"/>
31+
</Page>
32+
</PageControl>
33+
</Page>
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<App>
2+
<Font File="../../Assets/fonts/MaterialIcons-Regular.ttf" ux:Global="MaterialIcons"/>
3+
4+
<Router ux:Name="router"/>
5+
<ResourceObject Key="router" Value="router"/>
6+
7+
<ClientPanel>
8+
<!-- TODO: Provide dismiss in UX, or way to set a value (`Active`) to `null` -->
9+
<JavaScript>
10+
exports.dismissMenu = function() {
11+
edge.dismiss()
12+
}
13+
</JavaScript>
14+
15+
<!-- An event that opens the left edge menu -->
16+
<UserEvent ux:Name="requestMenu"/>
17+
<OnUserEvent EventName="requestMenu">
18+
<Set edge.Active="menu"/>
19+
</OnUserEvent>
20+
21+
<UserEvent ux:Name="dismissMenu"/>
22+
<OnUserEvent EventName="dismissMenu" Handler="{dismissMenu}"/>
23+
24+
<EdgeNavigator ux:Name="edge">
25+
<AppMenu Edge="Left" ux:Name="menu" router="router"/>
26+
27+
<ApplicationTop router="router"/>
28+
</EdgeNavigator>
29+
</ClientPanel>
30+
</App>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"Packages": [
3+
"Fuse",
4+
"FuseJS"
5+
],
6+
"Includes": [
7+
"*"
8+
]
9+
}
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Navigation
2+
3+
Multi-level application navigation using an edge menu, a title area, an action bar.
4+
5+
6+
## Structure
7+
8+
The first navigation level is created by a `EdgeNavigator` in `MainView.ux` to control the side menu. This doesn't participate in the `Router` navigation but instead uses signals.
9+
10+
`ApplicationTop.ux` creates the next levels of animation, it is the root level for the `Router`. All pages have a title bar; those in `home` have an additional action bar at the bottom.
11+
12+
The application uses `goto` to get to any page within `home` and `push` to get to all others. This limits the overall application depth to avoid confusing the user.
13+
14+
15+
## Flights Page sub-navigation
16+
17+
The `FlightsPage.ux` has another level of navigation for "arrivals" and "departures". This is controlled via the router but exposed as more of a filter to the user at the top of the page. By making this proper router paths the side menu is able to navigate directly to either sub-page.
18+
19+
20+
## Bookings sub-pages
21+
22+
The `BookingsPage.ux` displays a list of bookings (in a real app you'd obviously want to load this list). A top-right corner icon uses the router to `push` the `createBooking` page. Clicking on individual items will `push` the `booking` page for that item.
23+
24+
Note that only the `id` is passed to the `booking` page. That page is responsible for looking up information based on that id, usually via a common JavaScript module.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!--
2+
This class will be used to place things in the title area,
3+
There must be a resource called `titleArea` that defines where this content is placed.
4+
-->
5+
<Container ux:Class="TitleAreaContent" Subtree="titleRegion">
6+
<WhileActive Threshold="0.5" ux:Binding="Children">
7+
<Change titleRegionRoot.IsEnabled="true"/>
8+
</WhileActive>
9+
10+
<AlternateRoot ParentNode="{Resource titleArea}" IsEnabled="false" ux:Name="titleRegionRoot"
11+
ux:Binding="Children">
12+
<Panel ux:Name="titleRegion">
13+
<!-- show page title -->
14+
<Text Value="{Resource Title}" Alignment="Center" FontSize="20"/>
15+
</Panel>
16+
</AlternateRoot>
17+
</Container>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: Application navigation
2+
desc: Multi-level application navigation with
3+
api:
4+
-
5+
class: Fuse.AlternateRoot
6+
desc: Pages place content in a common title area
7+
-
8+
class: Fuse.Resources.ResourceObject
9+
desc: Assigns a node to a resource for use later in an `AlternateRoot`.
10+
-
11+
class: Fuse.Triggers.Actions.RaiseUserEvent
12+
desc: Coordinates display and dismissal of side menu
13+
-
14+
class: Fuse.Triggers.OnUserEvent
15+
desc: Coordinates display and dismissal of side menu
16+
-
17+
class: Fuse.UserEvent
18+
desc: Coordinates display and dismissal of side menu
19+
-
20+
class: Fuse.Navigation.Router
21+
desc: Navigation control for a multi-level application
22+
-
23+
class: Fuse.Controls.Navigator
24+
desc: Navigation between application pages
25+
-
26+
class: Fuse.Controls.PageControl
27+
desc: Navigation between application pages
28+
-
29+
class: Fuse.Controls.PageIndicator
30+
desc: Dynamic action bar for navigation in application
31+
-
32+
class: Fuse.Controls.Container
33+
desc: Combined with AlternateRoot to display page specific elements in the title bar

0 commit comments

Comments
 (0)