Skip to content

Commit 6e500f3

Browse files
committed
docs: add Tabs examples
1 parent 41e10ae commit 6e500f3

31 files changed

+642
-23
lines changed

app/main-page.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ const navigationLinks = [
5151
new link("File System", "ns-framework-modules-category/file-system/file-system-page"),
5252
new link("Modal view", "ns-ui-category/modal-view/modal-view-examples-page"),
5353
new link("XML Parser", "ns-framework-modules-category/xml-parser/xml-parser-page"),
54-
new link("BottomNavigation", "ns-ui-widgets-category/bottom-navigation/bottom-navigation-page")
54+
new link("BottomNavigation", "ns-ui-widgets-category/bottom-navigation/bottom-navigation-page"),
55+
new link("Tabs", "ns-ui-widgets-category/tabs/tabs-page")
5556
];
5657

5758
function onNavigatingTo(args) {

app/ns-ui-widgets-category/bottom-navigation/end.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
**API Reference for the** [BottomNavigation Class](http://docs.nativescript.org/api-reference/classes/_ui_bottom_navigation_.button.html)
1+
**API Reference for the** [BottomNavigation Class](https://docs.nativescript.org/api-reference/classes/_ui_tab_navigation_bottom_navigation_.bottomnavigation)
22

33
**Native Component**
44

app/ns-ui-widgets-category/bottom-navigation/events/events-ts-page.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export function onNavigatingTo(args: EventData) {
88
const page = args.object as Page;
99
const vm = fromObject({
1010
selectedIndex: 1
11-
})
11+
});
1212

1313
page.bindingContext = vm;
1414
}
@@ -18,12 +18,12 @@ export function onBottomNavLoaded(args: EventData) {
1818
const bottomNavigation = args.object as BottomNavigation;
1919

2020
// Using selectedIndexChanged
21-
bottomNavigation.on(BottomNavigation.selectedIndexChangedEvent , (args: SelectedIndexChangedEventData) => {
22-
const oldIndex: number = args.oldIndex;
23-
const newIndex: number = args.newIndex;
21+
bottomNavigation.on(BottomNavigation.selectedIndexChangedEvent, (data: SelectedIndexChangedEventData) => {
22+
const oldIndex: number = data.oldIndex;
23+
const newIndex: number = data.newIndex;
2424
console.log(`oldIndex: ${oldIndex}; newIndex: ${newIndex}`);
2525

2626
(<any>args.object).page.bindingContext.set("selectedIndex", newIndex);
2727
});
28-
};
29-
// << bottom-navigation-events-tsc
28+
}
29+
// << bottom-navigation-events-tsc

app/ns-ui-widgets-category/bottom-navigation/overview.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
> **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.
22
3-
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).
3+
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 navigation 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).
44

55
> **Note:** NativeScript 6 introduced two new UI components called `BottomNavigation` and `Tabs`. The idea behind them is to provide more control when building tab based UI, while powering the CSS styling, the icon font support and other specific functionalities. Prior to NativeScript 6, we had the `TabView` component which had top and bottom implementations with different behavoirs for the different platofrms and some styling limitations. With `BottomNavigaiton` and `Tabs` coomponents available, the `TabView` can be considered obsolete.
66
7+
The `BottomNavigation` component roundup
8+
79
Component Primary Objectives:
810
- Used for High Level navigation.
911
- Good for UX structure with 3 to 5 different options.

app/ns-ui-widgets-category/bottom-navigation/properties/properties-ts-page.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { BottomNavigation, TabStrip, TabStripItem, TabContentItem } from "tns-co
88
export function onBottomNavLoaded(args: EventData) {
99
const bottomNav = args.object as BottomNavigation;
1010

11-
/*
11+
/*
1212
Using the items property to assign array of TabContentItem componentns
1313
Note: The number of TabContentItem components should be equal to the number of TabStripItem components
1414
*/
@@ -38,13 +38,21 @@ function createTabStrip() {
3838
for (let index = 0; index < 3; index++) {
3939
const item: TabStripItem = new TabStripItem();
4040
/*
41-
Using TabStripItem title property
41+
Using TabStripItem title property
4242
*/
43-
item.title = `Tab ${index === 0 ? "res://baseline_home_black_24pt" : (index === 1 ? "res://baseline_account_balance_black_24pt" : "res://baseline_search_black_24pt" )}`;
43+
item.title = `Tab ${index === 0
44+
? "res://baseline_home_black_24pt"
45+
: (index === 1
46+
? "res://baseline_account_balance_black_24pt"
47+
: "res://baseline_search_black_24pt")}`;
4448
/*
45-
Using TabStripItem title property
49+
Using TabStripItem title property
4650
*/
47-
item.iconSource = index === 0 ? "res://baseline_home_black_24pt" : (index === 1 ? "res://baseline_account_balance_black_24pt" : "res://baseline_search_black_24pt" );
51+
item.iconSource = index === 0
52+
? "res://baseline_home_black_24pt"
53+
: (index === 1
54+
? "res://baseline_account_balance_black_24pt"
55+
: "res://baseline_search_black_24pt");
4856
tabStripItems.push(item);
4957
}
5058
tabStrip.items = tabStripItems;
@@ -74,4 +82,4 @@ function createContent(index: number) {
7482
stack.addChild(label);
7583

7684
return stack;
77-
}
85+
}

app/ns-ui-widgets-category/bottom-navigation/properties/properties-ts-page.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
</Page.actionBar>
55
<!-- >> bottom-navigation-properties-tsc-xml -->
66
<BottomNavigation loaded="onBottomNavLoaded"></BottomNavigation>
7-
<!-- << bottom-navigation-basics-tsc-xml -->
7+
<!-- << bottom-navigation-properties-tsc-xml -->
88
</Page>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
**API Reference for the** [Tabs Class](https://docs.nativescript.org/api-reference/classes/_ui_tab_view_.tabs)
2+
3+
**Native Component**
4+
5+
| Android | iOS |
6+
|:----------------------|:---------|
7+
| [ViewPager](https://developer.android.com/reference/android/support/v4/view/ViewPager) | [UIPageViewController](https://developer.apple.com/documentation/uikit/uipageviewcontroller?language=objc) |
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
- `selectedIndexChanged` - Event used to track the tabs interaction though the change of `selectedIndex` property of `Tabs` component. The event data is of type `SelectedIndexChangedEventData` extends `EventData` with two new properties:
2+
- `oldIndex` - Provides the old selected index.
3+
- `newIndwex` - Provides the new selected index.
4+
5+
<snippet id='tabs-events-js'/>
6+
<snippet id='tabs-events-tsc'/>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const fromObject = require("tns-core-modules/data/observable").fromObject;
2+
3+
exports.onNavigatingTo = (args) => {
4+
const page = args.object;
5+
const vm = fromObject({
6+
selectedIndex: 1
7+
});
8+
9+
page.bindingContext = vm;
10+
};
11+
12+
// >> tabs-events-js
13+
exports.onTabsLoaded = (args) => {
14+
// Using the loaded event to ger a reference to the Tabs
15+
const tabs = args.object;
16+
17+
// Using selectedIndexChanged
18+
tabs.on("selectedIndexChanged", (args) => {
19+
// args is of type SelectedIndexChangedEventData
20+
const oldIndex = args.oldIndex;
21+
const newIndex = args.newIndex;
22+
console.log(`oldIndex: ${oldIndex}; newIndex: ${newIndex}`);
23+
24+
args.object.page.bindingContext.set("selectedIndex", newIndex);
25+
});
26+
};
27+
// << tabs-events-js
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<Page navigatingTo="onNavigatingTo">
2+
<Page.actionBar>
3+
<ActionBar title="Tabs - Events"/>
4+
</Page.actionBar>
5+
<!-- >> tabs-events-xml -->
6+
<Tabs selectedIndex="1" loaded="onTabsLoaded">
7+
8+
<!-- The Tabs is created via TabStrip (the containier) and TabStripItem (for each tab)-->
9+
<TabStrip>
10+
<TabStripItem title="Home" iconSource="res://baseline_home_black_24pt"></TabStripItem>
11+
<TabStripItem title="Account" iconSource="res://baseline_account_balance_black_24pt"></TabStripItem>
12+
</TabStrip>
13+
14+
<!-- The number of TabContentItem components should corespond to the number of TabStripItem components -->
15+
<TabContentItem>
16+
<GridLayout rows="*, *">
17+
<Label row="0" text="Home Page" class="h2 text-center" color="orange"></Label>
18+
<Label row="1" text="{{ 'newIndex: ' + selectedIndex }}" class="h2 text-center"></Label>
19+
</GridLayout>
20+
</TabContentItem>
21+
<TabContentItem>
22+
<GridLayout rows="*, *">
23+
<Label row="0" text="Account Page" class="h2 text-center"></Label>
24+
<Label row="1" text="{{ 'newIndex: ' + selectedIndex }}" class="h2 text-center"></Label>
25+
</GridLayout>
26+
</TabContentItem>
27+
</Tabs>
28+
<!-- << tabs-events-xml -->
29+
</Page>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// >> tabs-events-tsc
2+
import { EventData, fromObject } from "tns-core-modules/data/observable";
3+
import { Tabs, SelectedIndexChangedEventData } from "tns-core-modules/ui/tabs";
4+
// >> (hide)
5+
import { Page } from "tns-core-modules/ui/page";
6+
7+
export function onNavigatingTo(args: EventData) {
8+
const page = args.object as Page;
9+
const vm = fromObject({
10+
selectedIndex: 1
11+
});
12+
13+
page.bindingContext = vm;
14+
}
15+
// << (hide)
16+
export function onTabsLoaded(args: EventData) {
17+
// Using the loaded event to ger a reference to the Tabs
18+
const tabs = args.object as Tabs;
19+
20+
// Using selectedIndexChanged
21+
tabs.on(Tabs.selectedIndexChangedEvent, (data: SelectedIndexChangedEventData) => {
22+
const oldIndex: number = data.oldIndex;
23+
const newIndex: number = data.newIndex;
24+
console.log(`oldIndex: ${oldIndex}; newIndex: ${newIndex}`);
25+
26+
(<any>args.object).page.bindingContext.set("selectedIndex", newIndex);
27+
});
28+
}
29+
// << tabs-events-tsc
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<Page navigatingTo="onNavigatingTo">
2+
<Page.actionBar>
3+
<ActionBar title="Tabs - Events"/>
4+
</Page.actionBar>
5+
<!-- >> tabs-events-xml -->
6+
<Tabs selectedIndex="1" loaded="onTabsLoaded">
7+
8+
<!-- The Tabs tab UI is created via TabStrip (the containier) and TabStripItem (for each tab)-->
9+
<TabStrip>
10+
<TabStripItem title="Home" iconSource="res://baseline_home_black_24pt"></TabStripItem>
11+
<TabStripItem title="Account" iconSource="res://baseline_account_balance_black_24pt"></TabStripItem>
12+
</TabStrip>
13+
14+
<!-- The number of TabContentItem components should corespond to the number of TabStripItem components -->
15+
<TabContentItem>
16+
<GridLayout rows="*, *">
17+
<Label row="0" text="Home Page" class="h2 text-center" color="orangered"></Label>
18+
<Label row="1" text="{{ 'newIndex: ' + selectedIndex }}" class="h2 text-center"></Label>
19+
</GridLayout>
20+
</TabContentItem>
21+
<TabContentItem>
22+
<GridLayout rows="*, *">
23+
<Label row="0" text="Account Page" class="h2 text-center"></Label>
24+
<Label row="1" text="{{ 'selectednewIndexIndex: ' + selectedIndex }}" class="h2 text-center"></Label>
25+
</GridLayout>
26+
</TabContentItem>
27+
</Tabs>
28+
<!-- << tabs-events-xml -->
29+
</Page>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
title: Tabs
3+
description: The NativeScript's Tabs 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 mid level navigaiton with unlimited tabs and common functions.The component supports swipe gestures and preloading.
4+
position: 418
5+
slug: tabs
6+
---
7+
example-order: usage, theming, properties, events, tips-and-tricks
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
> **Disclaimer:** The `Tabs` 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.
2+
3+
The `Tabs` 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 `Tabs` is a mid level navigation. For additional information and details about bottom navigation refer to [the Material Design guidelines](https://material.io/design/components/tabs.html#usage).
4+
5+
> **Note:** NativeScript 6 introduced two new UI components called `BottomNavigation` and `Tabs`. The idea behind them is to provide more control when building tab based UI, while powering the CSS styling, the icon font support and other specific functionalities. Prior to NativeScript 6, we had the `TabView` component which had top and bottom implementations with different behavoirs for the different platofrms and some styling limitations. With `BottomNavigaiton` and `Tabs` coomponents available, the `TabView` can be considered obsolete.
6+
7+
The `Tabs` component roundup
8+
9+
- Semantic: Mid Level Navigation
10+
- Usage: Unlimited Tabs with common function
11+
- Transitions: Slide Transition indicating the relative position to each other
12+
- Gestures: Swipe Gesture
13+
- Preloading: At least 1 to the sides (because of the swipe gesture)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
2+
- `items: Array<TabContentItem>;` - Gets or sets the items of the BottomNavigation.
3+
4+
- `tabStrip: TabStrip;` - Gets or sets the tab strip of the BottomNavigation.
5+
6+
- `selectedIndex: number;` - Gets or sets the selectedIndex of the BottomNavigation.
7+
8+
- `swipeEnabled: boolean;` - Gets or sets the swipe enabled state of the Tabs.
9+
10+
- `offscreenTabLimit: number;` - Gets or sets the number of offscreen preloaded tabs of the Tabs.
11+
12+
- `tabsPosition: "top" | "bottom";` - Gets or sets the position state of the Tabs.
13+
14+
- `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.
15+
16+
- `ios: any` /* UIPageViewController */; - Gets the native iOS [UIPageViewController](https://developer.apple.com/documentation/uikit/uipageviewcontroller?language=objc) that represents the user interface for this component. Valid only when running on iOS.
17+
18+
<snippet id='tabs-properties-js'/>
19+
<snippet id='tabs-properties-tsc'/>
20+
<snippet id='tabs-properties-tsc-xml'>
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
const Label = require("tns-core-modules/ui/label").Label;
2+
const StackLayout = require("tns-core-modules/ui/layouts/stack-layout").StackLayout;
3+
const Color = require("tns-core-modules/color/color").Color;
4+
// >> tabs-properties-js
5+
const TabStrip = require("tns-core-modules/ui/tabs").TabStrip;
6+
const TabStripItem = require("tns-core-modules/ui/tabs").TabStripItem;
7+
const TabContentItem = require("tns-core-modules/ui/tabs").TabContentItem;
8+
9+
exports.onTabsLoaded = (args) => {
10+
// Tabs
11+
const tabs = args.object;
12+
/*
13+
Using the items property to assign array of TabContentItem components (with content)
14+
Note: The number of TabContentItem components should be equal to the number of TabStripItem components
15+
*/
16+
const tabContentItemsArray = createTabsContentArray();
17+
tabs.items = tabContentItemsArray;
18+
19+
/*
20+
Using the tabStrip property to createa a TabStrip with multiple TabStripItems (tabs)
21+
Note: The number of TabStripItem components should be equal to the number of TabContentItem components
22+
*/
23+
const tabStrip = createTabStrip();
24+
tabs.tabStrip = tabStrip;
25+
26+
/*
27+
Using the Tabs properties
28+
*/
29+
tabs.selectedIndex = 1;
30+
tabs.swipeEnabled = true;
31+
tabs.offscreenTabLimit = 1;
32+
tabs.tabsPosition = "top";
33+
34+
/*
35+
Using the nativeView property (correspnding to tabs.ios or tabs.android depending on the used platform)
36+
*/
37+
console.log("tabs.nativeView: ", tabs.nativeView);
38+
};
39+
// << tabs-properties-js
40+
41+
function createTabStrip() {
42+
// TabStrip
43+
const tabStrip = new TabStrip();
44+
tabStrip.iosIconRenderingMode = "automatic"; // iOS only (automatic is the default value)
45+
46+
// An array of TabStripItem
47+
const tabStripItems = [];
48+
for (let index = 0; index < 3; index++) {
49+
// Each item is of type TabStripItem
50+
const item = new TabStripItem();
51+
/*
52+
Using TabStripItem title property
53+
*/
54+
item.title = `${index === 0 ? "Home" : (index === 1 ? "Account" : "Search")}`;
55+
/*
56+
Using TabStripItem title property
57+
*/
58+
item.iconSource = index === 0 ? "res://baseline_home_black_24pt" : (index === 1 ? "res://baseline_account_balance_black_24pt" : "res://baseline_search_black_24pt");
59+
tabStripItems.push(item);
60+
}
61+
tabStrip.items = tabStripItems;
62+
63+
return tabStrip;
64+
}
65+
66+
function createTabsContentArray() {
67+
// array of TabContentItem
68+
const arr = [];
69+
for (let index = 0; index < 3; index++) {
70+
// item is of type TabContentItem
71+
const item = new TabContentItem();
72+
// The createContent is a custom method that returns a StackLayout with a Label as a chils
73+
item.view = createContent(index);
74+
arr.push(item);
75+
}
76+
77+
return arr;
78+
}
79+
80+
function createContent(index) {
81+
const label = new Label();
82+
label.text = `${index === 0 ? "Home" : (index === 1 ? "Account" : "Search")}`;
83+
label.className = "h2 text-center";
84+
label.color = new Color("red");
85+
const stack = new StackLayout();
86+
stack.verticalAlignment = "middle";
87+
stack.addChild(label);
88+
89+
return stack;
90+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<Page>
2+
<Page.actionBar>
3+
<ActionBar title="Tabs - Properties"/>
4+
</Page.actionBar>
5+
6+
<Tabs loaded="onTabsLoaded"></Tabs>
7+
</Page>

0 commit comments

Comments
 (0)