Skip to content

Commit

Permalink
docs: BottomNavigation examples
Browse files Browse the repository at this point in the history
  • Loading branch information
NickIliev committed Jul 4, 2019
1 parent 97f3a2e commit 758bf62
Show file tree
Hide file tree
Showing 36 changed files with 578 additions and 215 deletions.
2 changes: 1 addition & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
"no-multi-str": "error",
"no-multiple-empty-lines": "error",
"no-negated-condition": "off",
"no-nested-ternary": "error",
"no-nested-ternary": "off",
"no-new": "error",
"no-new-func": "error",
"no-new-object": "error",
Expand Down
Binary file added app/App_Resources/iOS/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/App_Resources/iOS/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/App_Resources/iOS/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/App_Resources/iOS/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/App_Resources/iOS/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/App_Resources/iOS/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/App_Resources/iOS/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/App_Resources/iOS/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/App_Resources/iOS/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
const ListViewLinksModel = require("../../links-view-model");
const link = require("../../link");
const navigationLinks = [
new link("Basics", "ns-ui-widgets-category/bottom-navigation/basics/basics-page")
// new link("Styling", "ns-ui-widgets-category/tab-view/styling/styling-page"),
// new link("Title Icon Fonts", "ns-ui-widgets-category/tab-view/title-icon-fonts/title-icon-fonts-page"),
// new link("Code Behind", "ns-ui-widgets-category/tab-view/code-behind/code-behind-page"),
// new link("Navigation", "ns-ui-widgets-category/tab-view/navigation/navigation")
new link("Usage", "ns-ui-widgets-category/bottom-navigation/usage/usage-page"),
new link("Usage", "ns-ui-widgets-category/bottom-navigation/styling/styling-page"),
new link("Events", "ns-ui-widgets-category/bottom-navigation/events/events-page"),
new link("Properties", "ns-ui-widgets-category/bottom-navigation/properties/properties-page")
];
const navigationLinksTsc = [
new link("Basics", "ns-ui-widgets-category/bottom-navigation/basics/basics-ts-page")
// new link("Navigation", "ns-ui-widgets-category/tab-view/navigation/navigation-ts-page")
new link("Usage", "ns-ui-widgets-category/bottom-navigation/usage/usage-ts-page"),
new link("Usage", "ns-ui-widgets-category/bottom-navigation/styling/styling-ts-page"),
new link("Events", "ns-ui-widgets-category/bottom-navigation/events/events-ts-page"),
new link("Properties", "ns-ui-widgets-category/bottom-navigation/properties/properties-page")
];

function onNavigatingTo(args) {
const page = args.object;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- `selectedIndexChanged` - Event used to track the tabs interaction though the change of `selectedIndex` property of `BottomNavigation` component. The event data is of type `SelectedIndexChangedEventData` extends `EventData` with two new properties:
- `oldIndex` - Provides the old selected index.
- `newIndwex` - Provides the new selected index.

<snippet id='bottom-navigation-events-js'/>
<snippet id='bottom-navigation-events-tsc'/>
27 changes: 27 additions & 0 deletions app/ns-ui-widgets-category/bottom-navigation/events/events-page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const fromObject = require("tns-core-modules/data/observable").fromObject;

exports.onNavigatingTo = (args) => {
const page = args.object;
const vm = fromObject({
selectedIndex: 1
});

page.bindingContext = vm;
};

// >> bottom-navigation-events-js
exports.onBottomNavLoaded = (args) => {
// Using the loaded event to ger a reference to the BottomNavigation
const bottomNavigation = args.object;

// Using selectedIndexChanged
bottomNavigation.on("selectedIndexChanged", (args) => {
// args is of type SelectedIndexChangedEventData
const oldIndex = args.oldIndex;
const newIndex = args.newIndex;
console.log(`oldIndex: ${oldIndex}; newIndex: ${newIndex}`);

args.object.page.bindingContext.set("selectedIndex", newIndex);
});
};
// << bottom-navigation-events-js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<Page navigatingTo="onNavigatingTo">
<Page.actionBar>
<ActionBar title="BottomNavigation - Events"/>
</Page.actionBar>
<!-- >> bottom-navigation-events-xml -->
<BottomNavigation selectedIndex="1" loaded="onBottomNavLoaded">

<!-- The bottom tab UI is created via TabStrip (the containier) and TabStripItem (for each tab)-->
<TabStrip>
<TabStripItem title="Home" iconSource="res://baseline_home_black_24pt"></TabStripItem>
<TabStripItem title="Account" iconSource="res://baseline_account_balance_black_24pt"></TabStripItem>
</TabStrip>

<!-- The number of TabContentItem components should corespond to the number of TabStripItem components -->
<TabContentItem>
<GridLayout rows="*, *">
<Label row="0" text="Home Page" class="h2 text-center" color="orange"></Label>
<Label row="1" text="{{ 'newIndex: ' + selectedIndex }}" class="h2 text-center"></Label>
</GridLayout>
</TabContentItem>
<TabContentItem>
<GridLayout rows="*, *">
<Label row="0" text="Account Page" class="h2 text-center"></Label>
<Label row="1" text="{{ 'newIndex: ' + selectedIndex }}" class="h2 text-center"></Label>
</GridLayout>
</TabContentItem>
</BottomNavigation>
<!-- << bottom-navigation-events-xml -->
</Page>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// >> bottom-navigation-events-tsc
import { EventData, fromObject } from "tns-core-modules/data/observable";
import { BottomNavigation, SelectedIndexChangedEventData } from "tns-core-modules/ui/bottom-navigation";
// >> (hide)
import { Page } from "tns-core-modules/ui/page";

export function onNavigatingTo(args: EventData) {
const page = args.object as Page;
const vm = fromObject({
selectedIndex: 1
})

page.bindingContext = vm;
}
// << (hide)
export function onBottomNavLoaded(args: EventData) {
// Using the loaded event to ger a reference to the BottomNavigation
const bottomNavigation = args.object as BottomNavigation;

// Using selectedIndexChanged
bottomNavigation.on(BottomNavigation.selectedIndexChangedEvent , (args: SelectedIndexChangedEventData) => {
const oldIndex: number = args.oldIndex;
const newIndex: number = args.newIndex;
console.log(`oldIndex: ${oldIndex}; newIndex: ${newIndex}`);

(<any>args.object).page.bindingContext.set("selectedIndex", newIndex);
});
};
// << bottom-navigation-events-tsc
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<Page navigatingTo="onNavigatingTo">
<Page.actionBar>
<ActionBar title="BottomNavigation - Events"/>
</Page.actionBar>
<!-- >> bottom-navigation-events-xml -->
<BottomNavigation selectedIndex="1" loaded="onBottomNavLoaded">

<!-- The bottom tab UI is created via TabStrip (the containier) and TabStripItem (for each tab)-->
<TabStrip>
<TabStripItem title="Home" iconSource="res://baseline_home_black_24pt"></TabStripItem>
<TabStripItem title="Account" iconSource="res://baseline_account_balance_black_24pt"></TabStripItem>
</TabStrip>

<!-- The number of TabContentItem components should corespond to the number of TabStripItem components -->
<TabContentItem>
<GridLayout rows="*, *">
<Label row="0" text="Home Page" class="h2 text-center" color="orangered"></Label>
<Label row="1" text="{{ 'newIndex: ' + selectedIndex }}" class="h2 text-center"></Label>
</GridLayout>
</TabContentItem>
<TabContentItem>
<GridLayout rows="*, *">
<Label row="0" text="Account Page" class="h2 text-center"></Label>
<Label row="1" text="{{ 'selectednewIndexIndex: ' + selectedIndex }}" class="h2 text-center"></Label>
</GridLayout>
</TabContentItem>
</BottomNavigation>
<!-- << bottom-navigation-events-xml -->
</Page>
1 change: 1 addition & 0 deletions app/ns-ui-widgets-category/bottom-navigation/metadata.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ description: The NativeScript's BottomNavigation component provides a simple way
position: 416
slug: bottom-navigation
---
example-order: usage, styling, properties, events, tips-and-tricks
26 changes: 1 addition & 25 deletions app/ns-ui-widgets-category/bottom-navigation/overview.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

> **Disclaimer:** The `BottomNavigation` component is currently in **Beta** version. The component is being actively developed - use [the tracking issue](https://github.com/NativeScript/NativeScript/issues/6967) for details about the ongoing implementation.
The `BottomNavigation` component provides a simple way to navigate between different views while providing common UI for both iOS and Android platforms. The recommended scenario suitable for `BottomNavigation` is a high level navigaiton with 3 to 5 tabs each with separate function. For additional information and details about bottom navigation refer to [the Material Design guidelines](https://material.io/design/components/bottom-navigation.html#usage).

Expand All @@ -12,27 +12,3 @@ Limitations
- No navigation transitions.
- No navigation gestures (e.g., swipe to navigate).
- No content preloading.



<!--
The `TabView` component provides a simple way to navigate between different views by tapping on some of the tabs or by swiping between the views.
By default the `TabView` will load the view of the first tab, however it's possible to load alternative tabs when the app starts by setting the component’s `selectedIndex` property.
<----snippet id='tab-view-require'/>
<----snippet id='tab-view-import'/>
The general behavior of the `TabView` component is to load its items on demand. This means that every `TabViewItem` view will be loaded when it is shown and will be unloaded when it disappears. Respectively, the `loaded` and `unloaded` events will be fired when navigating between views. However, there are some specifics for each platform (iOS and Android), which are described in the notes below.
> Note (iOS specific): The iOS implementation uses `UITabBarController`. This means that only one `TabViewItem` can be shown at a given time and only one needs to be loaded. When the user selects a new `TabViewItem`, we load the new item and unload the previous one.
> Note (Android specific): The Android implementation uses a `ViewPager` control, which allows using the `swipe` gesture to navigate to the next or previous tab. This means that only one `TabViewItem` can be shown, but multiple `TabViewItems` need to be loaded to the side. If this is not done, you will not be able to see the next `TabViewItem` contents during the swipe. By default, the `ViewPager` control will pre-load one `TabViewItem` on the left and on on the right. Regarding that, if one of the items is already pre-loaded, it will not be loaded again. In NativeScript, we have exposed a property called `androidOffscreenTabLimit`, which allows specifying how many components should be pre-loaded to the sides (if you are setting up `androidOffscreenTabLimit` to 0, and using a nativescript version lower than 5, the Android behavior will match to the iOS behavior).
The iOS and Android UX guidelines regarding the Tab controls differ greatly. The difference is described in the below points:
* The iOS tabs have their tab bar, which will be displayed always on the bottom and does not allow swipe gesture for changing tabs.
* The Android tabs are on top and will enable the swipe navigation between the tabs.
* For Android we have `androidTabsPosition` property which has two options `top`(default value) and `bottom`. Setting up this property to `bottom` allows mimicking Bottom Tab Navigation control(provided by android support library v25 release). Setting the Tabs at the bottom will disable the swipe navigation and the items preloading functionality.
-->
14 changes: 14 additions & 0 deletions app/ns-ui-widgets-category/bottom-navigation/properties/article.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

- `items: Array<TabContentItem>;` - Gets or sets the items of the BottomNavigation.

- `tabStrip: TabStrip;` - Gets or sets the tab strip of the BottomNavigation.

- `selectedIndex: number;` - Gets or sets the selectedIndex of the BottomNavigation.

- `android: any` /* android.view.View */; - Gets the native [android widget](http://developer.android.com/reference/android/support/v4/view/ViewPager.html) that represents the user interface for this component. Valid only when running on Android OS.

- `ios: any` /* UITabBarController */; - Gets the native iOS [UITabBarController](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITabBarController_Class/) that represents the user interface for this component. Valid only when running on iOS.

<snippet id='bottom-navigation-properties-js'/>
<snippet id='bottom-navigation-properties-tsc'/>
<snippet id='bottom-navigation-properties-tsc-xml'>
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
const Label = require("tns-core-modules/ui/label").Label;
const StackLayout = require("tns-core-modules/ui/layouts/stack-layout").StackLayout;
const Color = require("tns-core-modules/color/color").Color;
// >> bottom-navigation-events-js
const TabStrip = require("tns-core-modules/ui/bottom-navigation").TabStrip;
const TabStripItem = require("tns-core-modules/ui/bottom-navigation").TabStripItem;
const TabContentItem = require("tns-core-modules/ui/bottom-navigation").TabContentItem;

exports.onBottomNavLoaded = (args) => {
// BottomNavigation
const bottomNav = args.object;
/*
Using the items property to assign array of TabContentItem components (with content)
Note: The number of TabContentItem components should be equal to the number of TabStripItem components
*/
const tabContentItemsArray = createTabsContentArray();
bottomNav.items = tabContentItemsArray;

/*
Using the tabStrip property to createa a TabStrip with multiple TabStripItems (tabs)
Note: The number of TabStripItem components should be equal to the number of TabContentItem components
*/
const tabStrip = createTabStrip();
bottomNav.tabStrip = tabStrip;

/*
Using the selectedIndex property
*/
bottomNav.selectedIndex = 1;

/*
Using the nativeView property (correspnding to bottomNav.ios or bottomNav.android depending on the used platform)
*/
console.log("bottomNav.nativeView: ", bottomNav.nativeView);
};
// << bottom-navigation-events-js

function createTabStrip() {
// TabStrip
const tabStrip = new TabStrip();
tabStrip.iosIconRenderingMode = "automatic"; // iOS only (automatic is the default value)

// An array of TabStripItem
const tabStripItems = [];
for (let index = 0; index < 3; index++) {
// Each item is of type TabStripItem
const item = new TabStripItem();
/*
Using TabStripItem title property
*/
item.title = `${index === 0 ? "Home" : (index === 1 ? "Account" : "Search")}`;
/*
Using TabStripItem title property
*/
item.iconSource = index === 0 ? "res://baseline_home_black_24pt" : (index === 1 ? "res://baseline_account_balance_black_24pt" : "res://baseline_search_black_24pt");
tabStripItems.push(item);
}
tabStrip.items = tabStripItems;

return tabStrip;
}

function createTabsContentArray() {
// array of TabContentItem
const arr = [];
for (let index = 0; index < 3; index++) {
// item is of type TabContentItem
const item = new TabContentItem();
// The createContent is a custom method that returns a StackLayout with a Label as a chils
item.view = createContent(index);
arr.push(item);
}

return arr;
}

function createContent(index) {
const label = new Label();
label.text = `${index === 0 ? "Home" : (index === 1 ? "Account" : "Search")}`;
label.className = "h2 text-center";
label.color = new Color("red");
const stack = new StackLayout();
stack.verticalAlignment = "middle";
stack.addChild(label);

return stack;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Page>
<Page.actionBar>
<ActionBar title="BottomNavigation - Usage"/>
</Page.actionBar>

<BottomNavigation loaded="onBottomNavLoaded"></BottomNavigation>
</Page>
Loading

0 comments on commit 758bf62

Please sign in to comment.