Components
Ionic apps are made of high-level building blocks called components. Components allow you to quickly construct an interface for your app. Ionic comes with a number of components, including modals, popups, and cards. Although components are primarily HTML and CSS, some components also include JavaScript functionality. Check out the examples below to see what each component looks like and to learn how to use each one. Once you’re familiar with the basics, head over to the API docs for ideas on how to customize each component.
Action Sheets
Action Sheets slide up from the bottom edge of the device screen, and display a set of options with the ability to confirm or cancel an action. Action Sheets can sometimes be used as an alternative to menus, however, they should not be used for navigation.
The Action Sheet always appears above any other components on the page, and must be dismissed in order to interact with the underlying content. When it is triggered, the rest of the page darkens to give more focus to the Action Sheet options.
Basic Usage
presentActionSheet() {
let actionSheet = ActionSheet.create({
title: 'Modify your album',
buttons: [
{
text: 'Destructive',
role: 'destructive',
handler: () => {
console.log('Destructive clicked');
}
},{
text: 'Archive',
handler: () => {
console.log('Archive clicked');
}
},{
text: 'Cancel',
role: 'cancel',
handler: () => {
console.log('Cancel clicked');
}
}
]
});
this.nav.present(actionSheet);
}
Alerts
Alerts are a great way to offer the user the ability to choose a specific action or list of actions. They also can provide the user with important information, or require them to make a decision (or multiple decisions).
From a UI perspective, you can think of Alerts as a type of “floating” modal, that covers only a portion of the screen. This means Alerts should only be used for quick actions like password verification, small app notifications, or quick options. More in depth user flows should be reserved for full screen Modals.
Alerts are quite flexible, and can easily be customized. Check out the API docs for more information.
Basic Usage:
Basic Alerts are generally used to notify the user about new information (a change in the app, a new feature), an urgent situation that requires acknowledgement, or as a confirmation to the user that an action was successful or not.
doAlert() {
let alert = Alert.create({
title: 'New Friend!',
subTitle: 'Your friend, Obi wan Kenobi, just accepted your friend request!',
buttons: ['OK']
});
this.nav.present(alert);
}
Prompt Alerts
Prompts offer the user a way to input data or information. For example, often times Prompt Alerts will be used to ask the user for password confirmation as a means of security before moving forward in an app’s ux flow.
let prompt = Alert.create({
title: 'Login',
message: "Enter a name for this new album you're so keen on adding",
inputs: [
{
name: 'title',
placeholder: 'Title'
},
],
buttons: [
{
text: 'Cancel',
handler: data => {
console.log('Cancel clicked');
}
},
{
text: 'Save',
handler: data => {
console.log('Saved clicked');
}
}
]
});
Confirmation Alerts
Confirmation Alerts are used when it is required that the user explicitly confirms a particular choice before progressing forward in the app. A common example of the Confirmation Alert is checking to make sure a user wants to delete or remove a contact from their address book.
let confirm = Alert.create({
title: 'Use this lightsaber?',
message: 'Do you agree to use this lightsaber to do good across the intergalactic galaxy?',
buttons: [
{
text: 'Disagree',
handler: () => {
console.log('Disagree clicked');
}
},
{
text: 'Agree',
handler: () => {
console.log('Agree clicked');
}
}
]
});
Radio
Radio Alerts are simply another type of Confirmation Alert, but use the Radio component to offer several choices. They offer the user a set of options to choose from, but are allowed to only make one final selection before continuing forward.
doRadio() {
let alert = Alert.create();
alert.setTitle('Lightsaber color');
alert.addInput({
type: 'radio',
label: 'Blue',
value: 'blue',
checked: true
});
alert.addButton('Cancel');
alert.addButton({
text: 'OK',
handler: data => {
this.testRadioOpen = false;
this.testRadioResult = data;
}
});
Checkbox
Checkbox Alerts are simply another type of Confirmation Alert, but use the Checkbox component to offer several choices. They offer the user a set of options to choose from.
doCheckbox() {
let alert = Alert.create();
alert.setTitle('Which planets have you visited?');
alert.addInput({
type: 'checkbox',
label: 'Alderaan',
value: 'value1',
checked: true
});
alert.addInput({
type: 'checkbox',
label: 'Bespin',
value: 'value2'
});
alert.addButton('Cancel');
alert.addButton({
text: 'Okay',
handler: data => {
console.log('Checkbox data:', data);
this.testCheckboxOpen = false;
this.testCheckboxResult = data;
}
});
}
Badges
Badges are small components that typically communicate a numerical value to the user. They are typically used within an item.
Basic Usage
<ion-item>
<ion-icon name="logo-twitter" item-left></ion-icon>
Followers
<ion-badge item-right>260k</ion-badge>
</ion-item>
Badges can also be given any color attribute:
<ion-badge secondary></ion-badge>
Buttons
Buttons are an essential way to interact with and navigate through an app, and should clearly communicate what action will occur after the user taps them. Buttons are simple components in Ionic, can consist of text, an icon, or both, and can be enhanced with a wide range of attributes.
- Contents
- Default Style
- Outline Style
- Clear Style
- Round Buttons
- Block Buttons
- Full Buttons
- Button Sizes
- Icon Buttons
- Floating Action Buttons
- Buttons In Components
Basic Usage
<button>Button</button>
The primary
property sets the color of the button. Ionic includes a number of default colors which can be easily overridden:
<button light>Light</button>
<button>Primary</button>
<button secondary>Secondary</button>
<button danger>Danger</button>
<button dark>Dark</button>
Outline Style
To use the outline style for a button, just add the outline
property:
<button light outline>Light Outline</button>
<button outline>Primary Outline</button>
<button secondary outline>Secondary Outline</button>
<button danger outline>Danger Outline</button>
<button dark outline>Dark Outline</button>
Clear Style
To use the clear style for a button, just add the clear
property:
<button light clear>Light Clear</button>
<button clear>Primary Clear</button>
<button secondary clear>Secondary Clear</button>
<button danger clear>Danger Clear</button>
<button dark clear>Dark Clear</button>
Round Buttons
To create a button with rounded corners, just add the round
property:
<button light round>Light Round</button>
<button round>Primary Round</button>
<button secondary round>Secondary Round</button>
<button danger round>Danger Round</button>
<button dark round>Dark Round</button>
Block Buttons
Adding block
to a button will make the button take 100% of its parent’s width. It will also add display: block
to the button:
<button block>Block Button</button>
Full Buttons
Adding full
to a button will also make the button take 100% of its parent’s width. However, it will also remove the button’s left and right borders. This style is useful when the button should stretch across the entire width of the display.
<button full>Full Button</button>
Button Sizes
Add the large
attribute to make a button larger, or small
to make it smaller:
<button small>Small</button>
<button>Default</button>
<button large>Large</button>
Icon Buttons
To add icons to a button, add an icon component inside of it:
<!-- Float the icon left -->
<button>
<ion-icon name="home"></ion-icon>
Left Icon
</button>
<!-- Float the icon right -->
<button>
Right Icon
<ion-icon name="home"></ion-icon>
</button>
<!-- Only icon (no text) -->
<button>
<ion-icon name="home"></ion-icon>
</button>
Floating Action Buttons
Adding fab
to a button will turn it into a floating action button. This is a material design styled button that is meant to draw the user to take a specific action. Fab buttons are positioned absolutely, and their placement can be controlled by adding attributes like fab-top
and fab-left
. See the button API spec for a full list of attributes.
<button fab>FAB</button>
Buttons In Components
Although buttons can be used on their own, they can easily be used within other components. For example, buttons can be added to a list item or a navbar.
<ion-navbar>
<ion-buttons start>
<button>
<ion-icon name="contact"></ion-icon>
</button>
</ion-buttons>
<ion-buttons end>
<button>
<ion-icon name="search"></ion-icon>
</button>
</ion-buttons>
</ion-navbar>
<ion-list>
<ion-item>
Left Icon Button
<button outline item-right>
<ion-icon name="star"></ion-icon>
Left Icon
</button>
</ion-item>
</ion-list>
Cards
Cards are a great way to display important pieces of content, and are quickly emerging as a core design pattern for apps. They're are a great way to contain and organize information, while also setting up predictable expectations for the user. With so much content to display at once, and often so little screen realestate, cards have fast become the design pattern of choice for many companies, including the likes of Google, Twitter, and Spotify.
For mobile experiences, Cards make it easy to display the same information visually across many different screen sizes. They allow for more control, are flexible, and can even be animated. Cards are usually placed on top of one another, but they can also be used like a "page" and swiped between, left and right.
Basic Usage:
Cards are primarily a CSS component. To use add a basic card, follow this structure:
<ion-card>
<ion-card-header>
Card Header
</ion-card-header>
<ion-card-content>
<!-- Add card content here! -->
</ion-card-content>
</ion-card>
Card Headers
Just like a normal page, cards can be customized to include headers. To add use add a card header, add the <ion-card-header>
component inside of your card:
<ion-card>
<ion-card-header>
Header
</ion-card-header>
<ion-card-content>
The British use the term "header", but the American term "head-shot" the English simply refuse to adopt.
</ion-card-content>
</ion-card>
Lists In Cards
A card can contain a list of items. To create a card list, add elements with the ion-item
attribute inside of an ion-list
in your card:
<ion-card>
<ion-card-header>
Explore Nearby
</ion-card-header>
<ion-list>
<button ion-item>
<ion-icon name="cart" item-left></ion-icon>
Shopping
</button>
<button ion-item>
<ion-icon name="medical" item-left></ion-icon>
Hospital
</button>
<button ion-item>
<ion-icon name="cafe" item-left></ion-icon>
Cafe
</button>
<button ion-item>
<ion-icon name="paw" item-left></ion-icon>
Dog Park
</button>
<button ion-item>
<ion-icon name="beer" item-left></ion-icon>
Pub
</button>
<button ion-item>
<ion-icon name="planet" item-left></ion-icon>
Space
</button>
</ion-list>
</ion-card>
Images In Cards
Images often vary in size, so it is important that they adopt a consistent style throughout your app. Images can easily be added to cards. Adding an image to a card will give the image a constant width, and a variable height. Lists, headers, and other card components can easily be combined with image cards. To add an image to a card, use the following markup:
<ion-card>
<img src="img/nin-live.png"/>
<ion-card-content>
<ion-card-title>
Nine Inch Nails Live
</ion-card-title>
<p>
The most popular industrial group ever, and largely
responsible for bringing the music to a mass audience.
</p>
</ion-card-content>
</ion-card>
Background Images
Coming soon.
Advanced Cards
The styles from different types of cards can be combined to create advanced cards. Cards can also receive custom CSS. Below are a few advanced cards that have been built by combining various card attributes with a small amount of custom CSS.
- Contents
- Social Cards
- Map Cards
Social Cards
It’s often necessary to create social cards within an application. Using a combination of different items in a card you can achieve this.
<ion-card>
<ion-item>
<ion-avatar item-left>
<img src="img/marty-avatar.png">
</ion-avatar>
<h2>Marty McFly</h2>
<p>November 5, 1955</p>
</ion-item>
<img src="img/advance-card-bttf.png">
<ion-card-content>
<p>Wait a minute. Wait a minute, Doc. Uhhh... Are you telling me that you built a time machine... out of a DeLorean?! Whoa. This is heavy.</p>
</ion-card-content>
<ion-item>
<button primary clear item-left>
<ion-icon name="thumbs-up"></ion-icon>
<div>12 Likes</div>
</button>
<button primary clear item-left>
<ion-icon name="text"></ion-icon>
<div>4 Comments</div>
</button>
<ion-note item-right>
11h ago
</ion-note>
</ion-item>
</ion-card>
Map Cards
A combination of Ionic components can be used to create a card that appears as a map.
<ion-card>
<img src="img/advance-card-map-madison.png">
<button fab fab-right fab-top>
<ion-icon name="pin"></ion-icon>
</button>
<ion-item>
<ion-icon name="football" item-left large></ion-icon>
<h2>Museum of Football</h2>
<p>11 N. Way St, Madison, WI 53703</p>
</ion-item>
<ion-item>
<ion-icon name="wine" item-left large ></ion-icon>
<h2>Institute of Fine Cocktails</h2>
<p>14 S. Hop Avenue, Madison, WI 53703</p>
</ion-item>
<ion-item>
<span item-left>18 min</span>
<span item-left>(2.6 mi)</span>
<button primary clear item-right>
<ion-icon name="navigate"></ion-icon>
Start
</button>
</ion-item>
</ion-card>
Checkbox
A checkbox is an input component that holds a boolean value. Checkboxes are no different than HTML checkbox inputs. However, like other Ionic components, checkboxes are styled differently on each platform. Use the checked
attribute to set the default value, and the disabled
attribute to disable the user from changing the value.
Basic Usage
<ion-item>
<ion-label>Daenerys Targaryen</ion-label>
<ion-checkbox dark checked="true"></ion-checkbox>
</ion-item>
<ion-item>
<ion-label>Arya Stark</ion-label>
<ion-checkbox disabled="true"></ion-checkbox>
</ion-item>
Events
You can target specific events to trigger specific functionality. Built on top of Hammer.js, you can bind to tap
, press
, pan
, swipe
, rotate
, and pinch
.
These events are listened for the same way as DOM events such as click.
Basic Usage
<ion-card (tap)="tapEvent($event)">
<ion-item>
Tapped: times
</ion-item>
</ion-card>
Grid
Ionic’s grid system is based on flexbox, a CSS feature supported by all devices that Ionic supports. The grid is composed of two units — rows and columns. Columns will expand to fill their row, and will resize to fit additional columns.
In order to set width use width
attribute on ion-col tag.
<ion-row>
<ion-col width-10>This column will take 10% of space</ion-col>
</ion-row>
Explicit Column Percentage Attributes | |
---|---|
width-10 | 10% |
width-20 | 20% |
width-25 | 25% |
width-33 | 33.3333% |
width-50 | 50% |
width-67 | 66.6666% |
width-75 | 75% |
width-80 | 80% |
width-90 | 90% |
Use the offset
attribute on a column to set its percent offset from the left (eg: offset-25
). To change how columns in a row align vertically, add the center
or baseline
attribute to an <ion-row>
.
Use the wrap
attribute on an <ion-row>
element to allow items in that row to wrap. This applies the flex-wrap: wrap;
style to the <ion-row>
element.
Icons
Ionic comes with the same 700+ Ionicons icons we’ve all come to know and love.
Basic Usage:
To use an icon, just add the Icon’s CSS class to your element:
<ion-icon name="heart"></ion-icon>
Active / Inactive Icons:
All icons have both active
and inactive
states. Active icons are typically full and thick, where as inactive icons are outlined and thin. Set the is-active
attribute to true
or false to change the state of the icon. Icons will default to active if a value is not specified.
<ion-icon name="heart"></ion-icon> <!-- active -->
<ion-icon name="heart" isActive="false"></ion-icon> <!-- inactive -->
Platform Specific Icons:
Many icons have both Material Design and iOS versions. Ionic will automatically use the correct version based on the platform.
However, if you want more control, you can explicitly set the icon to use for each platform. Use the md
(material design) and ios
attributes to specify a platform specific icon:
<ion-icon ios="logo-apple" md="logo-android"></ion-icon>
Variable Icons:
To set an icon using a variable:
<ion-icon [name]="myIcon"></ion-icon>
export class MyFirstPage {
constructor(nav: NavController) {
// use the home icon
this.myIcon = "home";
}
}
Inputs
Inputs are essential for collecting and handling user input in a secure way. They should follow styling and interaction guidelines for each platform, so that they are intuitive for users to interact with. Ionic uses Angular 2’s form library, which can be thought of as two dependent pieces, Controls, and Control Groups.
Each input field in a form has a Control, a function that binds to the value in the field, and performs validation. A Control Group is a collection of Controls. Control Groups handle form submission, and provide a high level API that can be used to determine whether the entire form is valid.
A number of attributes that can be used to style forms and their various input fields are listed below. For more info on form logic, check out the Inputs API docs.
- Contents
- Fixed Inline Labels
- Floating Labels
- Inline Labels
- Inset Labels
- Placeholder Labels
- Stacked Labels
Fixed Labels
Use fixed
to place a label to the left of the input element. When the user enters text, the label does not hide. The user’s input will align on the same position, regardless of the length of the label. Note that there’s nothing stopping you from also using a placeholder label too.
<ion-list>
<ion-item>
<ion-label fixed>Username</ion-label>
<ion-input type="text" value=""></ion-input>
</ion-item>
<ion-item>
<ion-label fixed>Password</ion-label>
<ion-input type="password"></ion-input>
</ion-item>
</ion-list>
Floating Labels
Floating labels are just like Stacked Labels, except that their labels animate, or “float” up when text is entered in the input. Each <ion-label>
should have the floating
attribute assigned.
Enter text in the example to the right to see the floating labels in action.
<ion-list>
<ion-item>
<ion-label floating>Username</ion-label>
<ion-input type="text"></ion-input>
</ion-item>
<ion-item>
<ion-label floating>Password</ion-label>
<ion-input type="password"></ion-input>
</ion-item>
</ion-list>
Inline Labels
If a label attribute is not provided, an <ion-label>
component will default to using an inline label. When the user enters text, the label does not hide. Note that there’s nothing stopping you from also using a placeholder as well.
<ion-list>
<ion-item>
<ion-label>Username</ion-label>
<ion-input type="text"></ion-input>
</ion-item>
<ion-item>
<ion-label>Password</ion-label>
<ion-input type="password"></ion-input>
</ion-item>
</ion-list>
<div padding>
<button block>Sign In</button>
</div>
Inset Labels
By default each input item will fill 100% of the width of its parent element (the list). However, you can inset the list by adding the inset
attribute.
<ion-list inset>
<ion-item>
<ion-label>Username</ion-label>
<ion-input type="text"></ion-input>
</ion-item>
<ion-item>
<ion-label>Password</ion-label>
<ion-input type="password"></ion-input>
</ion-item>
</ion-list>
Placeholder Labels
Add the placeholder
attribute to an <input>
element to simulate the input’s label. When the user begins to enter text into the input, the placeholder label will be hidden.
<ion-list>
<ion-item>
<ion-input type="text" placeholder="Username"></ion-input>
</ion-item>
<ion-item>
<ion-input type="password" placeholder="Password"></ion-input>
</ion-item>
</ion-list>
Stacked Labels
A stacked label will always appear on top of the input. Each <ion-label>
should have the stacked
attribute.
You can also add a placeholder so that users have a hint of what type of text the input is looking for.
<ion-list>
<ion-item>
<ion-label stacked>Username</ion-label>
<ion-input type="text"></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>Password</ion-label>
<ion-input type="password"></ion-input>
</ion-item>
</ion-list>
Lists
Lists are used to display rows of information, such as a contact list, playlist, or menu. Or maybe something crazy we don’t even know exists yet!
- Contents
- Basic Lists
- Inset List
- List Dividers
- List Headers
- Icon List
- Avatar List
- Multiline List
- Sliding List
- Thumbnail List
Basic Usage (Default)
By default, all lists will be styled with divider lines:
<ion-list>
<ion-item *ngFor="#item of items" (click)="itemSelected(item)">
{{item.title}}
</ion-item>
</ion-list>
Basic Usage (No Lines)
Adding the no-lines
attribute will hide the dividers between list items:
<ion-list no-lines>
<ion-item *ngFor="#item of items" (click)="itemSelected(item)">
{{item.title}}
</ion-item>
</ion-list>
Inset List
By default, lists have no outside margin, to add one, add the inset
property to the list component.
<ion-list inset>
<ion-item *ngFor="#item of items" (click)="itemSelected(item)">
{{item.title}}
</ion-item>
</ion-list>
List Dividers
To divide groups of items, use <ion-item-group>
instead of <ion-list>
. Use <ion-item-divider>
components to divide the group in to multiple sections:
<ion-content>
<ion-item-group>
<ion-item-divider light>A</ion-item-divider>
<ion-item>Angola</ion-item>
<ion-item>Argentina</ion-item>
<ion-item-divider light>B</ion-item-divider>
</ion-item-group>
</ion-content>
List Headers
Each list can include a header at the top of the list:
<ion-list>
<ion-list-header>
Action
</ion-list-header>
<ion-item>Terminator II</ion-item>
<ion-item>The Empire Strikes Back</ion-item>
<ion-item>Blade Runner</ion-item>
</ion-list>
Icon List
Adding icons to list items is a great way to hint about the contents of each item. The position of the icon can be set using the item-left
and item-right
attributes:
<ion-list>
<ion-item>
<ion-icon name="leaf" item-left></ion-icon>
Herbology
<ion-icon name="rose" item-right></ion-icon>
</ion-item>
</ion-list>
Avatar List
Item avatars showcase an image larger than an icon, but smaller than a thumbnail. To use an avatar, add an <ion-avatar>
component inside of an item. The position of the avatar can be set using the item-left
and item-right
attributes:
<ion-list>
<ion-item>
<ion-avatar item-left>
<img src="img/avatar-cher.png">
</ion-avatar>
<h2>Cher</h2>
<p>Ugh. As if.</p>
</ion-item>
</ion-list>
Multiline List
Multiline lists are identical to regular lists, except they can multiple lines of text. When multiple header or paragraph tags are added to an <ion-item>
, the item will automatically adjust its height to fit the new lines. Below is an example with three lines of text:
<ion-list>
<ion-item>
<ion-avatar item-left>
<img src="img/avatar-finn.png">
</ion-avatar>
<h2>Finn</h2>
<h3>Don't Know What To Do!</h3>
<p>I've had a pretty messed up day. If we just...</p>
</ion-item>
</ion-list>
Sliding List
Sliding items can be swiped to the left to reveal a set of buttons. To use a sliding item, add a <ion-item-sliding>
component inside of a list. Next, add a <ion-item-options>
component inside of the sliding item to contain the buttons:
<ion-list>
<ion-item-sliding>
<ion-item>
<ion-avatar item-left>
<img src="img/slimer.png">
</ion-avatar>
<h2>Slimer</h2>
</ion-item>
<ion-item-options>
<button primary>
<ion-icon name="text"></ion-icon>
Text
</button>
<button secondary>
<ion-icon name="call"></ion-icon>
Call
</button>
</ion-item-options>
</ion-item-sliding>
</ion-list>
Thumbnail List
Item thumbnails showcase an image that takes up the entire height of an item. To use a thumbnail, add an <ion-thumbnail>
component inside of an item. The position of the thumbnail can be set using the item-left
and item-right
attributes:
<ion-list>
<ion-item>
<ion-thumbnail item-left>
<img src="img/thumbnail-totoro.png">
</ion-thumbnail>
<h2>My Neighbor Totoro</h2>
<p>Hayao Miyazaki • 1988</p>
<button clear item-right>View</button>
</ion-item>
</ion-list>
Loading
The Loading component is an overlay that prevents user interaction while indicating activity. By default, it shows a spinner based on the mode. It can also be passed any HTML content to display with the spinner. You can hide or change the spinner to any of our predefined spinners. The loading indicator is styled to display on top of other content even during navigation.
Check out the API docs for more information.
Basic Usage
presentLoading() {
let loading = Loading.create({
content: "Please wait...",
duration: 3000
});
this.nav.present(loading);
}
Menus
For more in depth information on Menus, see the Menu API reference.
Menu is a side-menu navigation that can be dragged out or toggled to show. Menu supports two display styles currently: overlay, and reveal. Overlay is the tradtional Android drawer style, and Reveal is the traditional iOS style. By default, Menu will adjust to the correct style for the platform.
Along with Tabs, Menus are a common way to navigate through an app if you have several “root” or “top-level” pages. For the basics of navigating through an Ionic app, see the Navigation section.
For UX reasons, we first recommend using Tabs. However, for situations where using Tabs might not be desirable, for example if you have a large number of root pages (making a TabBar impractical), a menu might be a better solution.
Menus also allow you to return to root pages at any point. This can be helpful if you have particularly deep navigation by allowing you to return to the top level of your app quickly.
However, because Menus are not always and immediately visible on screen, they require more work for the user than Tabs. Make sure to weigh your priorities when designing the navigational structure of your app.
To use a Menu add an <ion-menu>
to your markup next to your root <ion-nav>
.
Basic Usage
@App({
template: `
<ion-menu [content]="content">
<ion-toolbar>
<ion-title>Pages</ion-title>
</ion-toolbar>
<ion-content>
<ion-list>
<button ion-item (click)="openPage(loginPage)">
Login
</button>
<button ion-item (click)="openPage(signupPage)">
Signup
</button>
</ion-list>
</ion-content>
</ion-menu>
<ion-nav id="nav" #content [root]="rootPage"></ion-nav>`
})
class MyApp {}
The <ion-menu>
s bound [content]
property gets a reference to the <ion-nav>
in order to listen for drag events on the main content so it knows when to open/close.
Then in our @App component we have two buttons with click handlers that navigate to a new root page:
import {MenuController, IonicApp} from 'ionic/ionic';
import {LoginPage} from 'login';
import {SignupPage} from 'signup';
@App({
...
})
class MyApp {
constructor(app: IonicApp, menu: MenuController) {
this.app = app;
this.menu = menu;
this.rootPage = LoginPage;
this.loginPage = LoginPage;
this.signupPage = SignupPage;
}
openPage(page) {
// Reset the nav controller to have just this page
// we wouldn't want the back button to show in this scenario
this.rootPage = page;
// close the menu when clicking a link from the menu
this.menu.close();
}
}
We inject the MenuController
provider so we can close the opened menu. We then use the NavController’s setRoot
function to clear the navigation stack and set the selected page as the new navigation root.
Menus can be a little more complicated, but they allow for many different configuration options. For example, the Google Maps app uses a drawer style Menu that exposes a list of items that open Modals over the main map content area and toggle settings on and off.
For more information on Menus, check out the Menu API reference.
Modals
Modals slide in off screen to display a temporary UI, often used for login or signup pages, message composition, and option selection.
Basic Usage
Next, we need to create the class that will control our modal. Let’s import Modal
, NavController
and ViewController
:
import {Modal, NavController, ViewController} from 'ionic-angular';
Next, let’s create our modal and define add its template:
@Page({
template: `
<ion-content padding>
<h2>I'm a modal!</h2>
<button (click)="close()">Close</button>
</ion-content>`
})
class MyModal {
constructor(viewCtrl: ViewController) {
this.viewCtrl = viewCtrl;
}
close() {
this.viewCtrl.dismiss();
}
}
Finally, let’s add the code that will open our Modal:
import {Modal, NavController} from 'ionic/ionic'
class MyPage {
constructor(nav: NavController){
this.nav = nav;
}
showModal() {
let modal = Modal.create(MyModal);
this.nav.present(modal)
}
}
The Modal.create()
function can also receive an object as the second argument that will be passed to the modal. See the Modal API docs for more information.
Navigation
For more in depth information on navigation, see the Nav API reference.
Navigation is how users move between different pages in your app. Ionic’s navigation follows standard native animation concepts, like those in iOS.
Like native apps, URLs are not required for navigation. Instead, pages are pushed and popped on and off a navigation controller’s page stack. URLs can be used to link back to unique, important parts of your app (“deeplinking”) but don’t define navigation as your app runs.
There are several ways to navigate throughout an Ionic app:
Basic Navigation
The simplest way to navigate throughout your app is to create and initialize a new navigation controller, using <ion-nav>
:
import {StartPage} from 'start'
@App({
template: '<ion-nav [root]="rootPage"></ion-nav>'
})
class MyApp {
constructor(){
// First page to push onto the stack
this.rootPage = StartPage;
}
}
You can access the navigation controller you create by injecting it into any of your Pages:
@Page({
template: `
<ion-navbar *navbar>
<ion-title>Login</ion-title>
</ion-navbar>
<ion-content>Hello World</ion-content>`
})
export class StartPage {
constructor(nav: NavController){
this.nav = nav;
}
}
To navigate from one page to another simply push or pop a new page onto the stack:
@Page({
template: `
<ion-navbar *navbar>
<ion-title>Login</ion-title>
</ion-navbar>
<ion-content>
<button (click)="goToOtherPage()">
Go to OtherPage
</button>
</ion-content>`
})
export class StartPage {
constructor(nav: NavController) {
this.nav = nav;
}
goToOtherPage(){
//push another page onto the history stack
//causing the nav controller to animate the new page in
this.nav.push(OtherPage);
}
}
@Page({
template: `
<ion-navbar *navbar>
<ion-title>Other Page</ion-title>
</ion-navbar>
<ion-content>I'm the other page!</ion-content>`
})
class OtherPage {}
If your page has an <ion-navbar>
, a back button will automatically be added to it if it is not a root page.
Alternatively, if you want to go back, but don’t have a NavBar, you can pop the current page off the stack:
@Page({
template: `
<ion-content>
<button (click)="goBack()">
There's no place like home
</button>
</ion-content>`
})
class OtherPage {
constructor(nav: NavController) {
this.nav = nav;
}
goBack() {
this.nav.pop();
}
}
For more information on basic navigation, check out the Nav API reference.
Navigating from the Root Component
What if you want to control navigation from your root app component (the one decorated with @App
, not @Page
)? You can’t inject NavController
because any components that are navigation controllers are children of the root component so they aren’t available to be injected.
By adding an id
to ion-nav
, you can use the IonicApp
service to get a reference to the Nav
component, which is a navigation controller (it extends NavController
):
@App({
template: '<ion-nav id="my-nav" [root]="rootPage"></ion-nav>'
})
export class MyApp {
constructor(app: IonicApp) {
this.rootPage = TabsPage;
this.app = app;
}
// Wait for the components in MyApp's template to be initialized
// In this case, we are waiting for the Nav with id="my-nav"
ngAfterViewInit() {
var nav = this.app.getComponent('my-nav');
// Let's navigate from TabsPage to Page1
nav.push(Page1);
}
}
Advanced Navigation
What if you have several “root” or “top-level” pages that don’t have a parent-child relationship, but rather are siblings? You have two options: Tabs and Menu.
Radio
Like the checkbox, a radio is an input component that holds a boolean value. Under the hood, radios are no different than HTML radio inputs. However, like other Ionic components, radios are styled differently on each platform. Unlike checkboxes, radio components form a group, where only one radio can be selected at a time. Use the checked
attribute to set the default value, and the disabled
attribute to disable the user from changing to that value.
Basic Usage
<ion-list radio-group>
<ion-list-header>
Language
</ion-list-header>
<ion-item>
<ion-label>Go</ion-label>
<ion-radio checked="true" value="go"></ion-radio>
</ion-item>
<ion-item>
<ion-label>Rust</ion-label>
<ion-radio value="rust"></ion-radio>
</ion-item>
<ion-item>
<ion-label>Python</ion-label>
<ion-radio value="python" disabled="true"></ion-radio>
</ion-item>
</ion-list>
Searchbar
A Searchbar binds to a model, and emits an input event when the model is changed.
Basic Usage
<ion-searchbar [(ngModel)]="searchQuery" (input)="getItems($event)"></ion-searchbar>
<ion-list>
<ion-item *ngFor="#item of items">
{{ item }}
</ion-item>
</ion-list>
Note that in this example, the Searchbar binds to the searchQuery
variable. The getItems()
function is called when the input changes, which updates the cities that are displayed. Although this example filters the list based on the search input, Searchbar can be used in many different scenarios:
@Page({
templateUrl: 'search/template.html',
})
class SearchPage {
constructor() {
this.searchQuery = '';
this.initializeItems();
}
initializeItems() {
this.items = [
'Amsterdam',
'Bogota',
...
];
}
getItems(searchbar) {
// Reset items back to all of the items
this.initializeItems();
// set q to the value of the searchbar
var q = searchbar.value;
// if the value is an empty string don't filter the items
if (q.trim() == '') {
return;
}
this.items = this.items.filter((v) => {
if (v.toLowerCase().indexOf(q.toLowerCase()) > -1) {
return true;
}
return false;
})
}
}
The Searchbar takes a number of configuration options on the <ion-searchbar>
element, such as cancelButtonText
and hideCancelButton
. Check out the Searchbar API reference for more information on configuring a Searchbar.
Segment
Use the segment to control radio selections.
Basic Usage
<div padding>
<ion-segment [(ngModel)]="pet">
<ion-segment-button value="kittens">
Kittens
</ion-segment-button>
<ion-segment-button value="puppies">
Puppies
</ion-segment-button>
</ion-segment>
</div>
<div [ngSwitch]="pet">
<ion-list *ngSwitchWhen="'puppies'">
<ion-item>
<ion-thumbnail item-left>
<img src="img/thumbnail-puppy-1.jpg">
</ion-thumbnail>
<h2>Ruby</h2>
</ion-item>
...
</ion-list>
<ion-list *ngSwitchWhen="'kittens'">
<ion-item>
<ion-thumbnail item-left>
<img src="img/thumbnail-kitten-1.jpg">
</ion-thumbnail>
<h2>Luna</h2>
</ion-item>
...
</ion-list>
</div>
Select
Basic Usage
The ion-select
component is similar to an HTML <select>
element, however, Ionic’s select component makes it easier for users to sort through and select the preferred option or options. When users tap the select component, a dialog will appear with all of the options in a large, easy to select list for users.
<ion-list>
<ion-item>
<ion-label>Gaming</ion-label>
<ion-select [(ngModel)]="gaming">
<ion-option value="nes">NES</ion-option>
<ion-option value="n64">Nintendo64</ion-option>
<ion-option value="ps">PlayStation</ion-option>
<ion-option value="genesis">Sega Genesis</ion-option>
<ion-option value="saturn">Sega Saturn</ion-option>
<ion-option value="snes">SNES</ion-option>
</ion-select>
</ion-item>
</ion-list>
You can make multiple selection with <ion-select>
by adding multiple="true"
to the element
<ion-list>
<ion-item>
<ion-label>Toppings</ion-label>
<ion-select [(ngModel)]="toppings" multiple="true" cancelText="Nah" okText="Okay!">
<ion-option value="bacon" checked="true">Bacon</ion-option>
<ion-option value="olives">Black Olives</ion-option>
<ion-option value="xcheese" checked="true">Extra Cheese</ion-option>
<ion-option value="peppers">Green Peppers</ion-option>
<ion-option value="mushrooms">Mushrooms</ion-option>
<ion-option value="onions">Onions</ion-option>
<ion-option value="pepperoni">Pepperoni</ion-option>
<ion-option value="pineapple">Pineapple</ion-option>
<ion-option value="sausage">Sausage</ion-option>
<ion-option value="Spinach">Spinach</ion-option>
</ion-select>
</ion-item>
</ion-list>
Slides
Slides make it easy to create galleries, tutorials, and page-based layouts.
Basic Usage
<ion-slides pager>
<ion-slide style="background-color: green">
<h2>Slide 1</h2>
</ion-slide>
<ion-slide style="background-color: blue">
<h2>Slide 2</h2>
</ion-slide>
<ion-slide style="background-color: red">
<h2>Slide 3</h2>
</ion-slide>
</ion-slides>
Slides take a number of configuration options on the <ion-slides>
element. Check out the Slides API reference for more information on configuring slides.
Tabs
For more details on the Tabs component, see the Tabs API reference, and the Tab API reference for information on configuring the individual Tab components it contains.
Tabs powers a multi-tabbed interface with a Tab Bar and a set of “pages” that can be tabbed through.
For iOS, tabs will appear at the bottom of the screen. For Android, tabs will be at the top of the screen, below the nav-bar. This follows each platform’s design specification, but can be configured with Config.
Tabs are useful if you have a few “root” or “top-level” pages. They are obvious to the user and quickly accessed, since they are always on the screen. However if screen space is limited, or you have a large number of root pages, a Menu may be a better option.
- Contents
- Text Tabs
- Icon Tabs
- Text and Icon Tabs
- Badge Tabs
Basic Usage
To initialize Tabs, use <ion-tabs>
, with a child <ion-tab>
for each tab:
@App({
template: `
<ion-tabs>
<ion-tab tabIcon="heart" [root]="tab1"></ion-tab>
<ion-tab tabIcon="star" [root]="tab2"></ion-tab>
</ion-tabs>`
})
class MyApp {
constructor() {
this.tab1 = Tab1;
this.tab2 = Tab2;
}
}
Individual tabs are just @Pages
:
@Page({
template: `
<ion-navbar *navbar>
<ion-title>Heart</ion-title>
</ion-navbar>
<ion-content>Tab 1</ion-content>`
})
class Tab1 {}
@Page({
template: `
<ion-navbar *navbar>
<ion-title>Star</ion-title>
</ion-navbar>
<ion-content>Tab 2</ion-content>`
})
class Tab2 {}
Notice that each <ion-tab>
binds to a [root]
property, just like <ion-nav>
in the Navigation section above. That is because each <ion-tab>
is really just a navigation controller. This means that each tab has its own history stack, and NavController instances injected
into children @Pages
of each tab will be unique to each tab:
@Page({
...
})
class Tab1 {
constructor(nav: NavController) {
// Id is 1, nav refers to Tab1
console.log(nav.id)
}
}
@Page({
...
})
class Tab2 {
constructor(nav: NavController) {
// Id is 2, nav refers to Tab2
console.log(nav.id)
}
}
Icon Tabs
To add an icon inside of a tab, use the tab-icon
attribute. This attribute can be passed the name of any icon:
@Page({
template: `
<ion-navbar *navbar>
<ion-title>Tabs</ion-title>
</ion-navbar>
<ion-content>
</ion-content>`,
})
class TabContentPage {
constructor() {
}
}
@Page({
template: `
<ion-tabs>
<ion-tab tabIcon="contact" [root]="tab1"></ion-tab>
<ion-tab tabIcon="compass" [root]="tab2"></ion-tab>
<ion-tab tabIcon="analytics" [root]="tab3"></ion-tab>
<ion-tab tabIcon="settings" [root]="tab4"></ion-tab>
</ion-tabs>`
})
export class TabsIconPage {
constructor() {
this.tab1 = TabContentPage;
this.tab2 = TabContentPage;
...
}
}
Icon and Text
To add text and an icon inside of a tab, use the tab-icon
and tab-title
attributes:
@Page({
template: `
<ion-navbar *navbar>
<ion-title>Tabs</ion-title>
</ion-navbar>
<ion-content>
</ion-content>`
})
class TabsTextContentPage {
constructor() {
}
}
@Page({
template: `
<ion-tabs>
<ion-tab tabIcon="water" tabTitle="Water" [root]="tab1"></ion-tab>
<ion-tab tabIcon="leaf" tabTitle="Life" [root]="tab2"></ion-tab>
<ion-tab tabIcon="flame" tabTitle="Fire" [root]="tab3"></ion-tab>
<ion-tab tabIcon="magnet" tabTitle="Force" [root]="tab4"></ion-tab>
</ion-tabs>`
})
export class TabsTextPage {
constructor() {
this.tab1 = TabsTextContentPage;
this.tab2 = TabsTextContentPage;
...
}
}
Badges
To add a badge to a tab, use the tabBadge
and tabBadgeStyle
attributes. The tabBadgeStyle
attribute can be passed the name of any color:
@Page({
template: `
<ion-navbar *navbar>
<ion-title>Tabs</ion-title>
</ion-navbar>
<ion-content>
</ion-content>`,
})
class TabBadgePage {
constructor() {
}
}
@Page({
template:
'<ion-tabs>' +
'<ion-tab tabIcon="call" [root]="tabOne" tabBadge="3" tabBadgeStyle="danger"></ion-tab>' +
'<ion-tab tabIcon="chatbubbles" [root]="tabTwo" tabBadge="14" tabBadgeStyle="danger"></ion-tab>' +
'<ion-tab tabIcon="musical-notes" [root]="tabThree"></ion-tab>' +
'</ion-tabs>',
})
export class BadgesPage {
constructor() {
this.tabOne = TabBadgePage;
this.tabTwo = TabBadgePage;
}
}
For more information on tabs, check out the Tabs API reference.
Toggle
A toggle is an input component that holds a boolean value. Like the checkbox, toggles are often used to allow the user to switch a setting on or off. Attributes like value
, disabled
, and checked
can be applied to the toggle to control its behavior. Check out the Toggle API Reference for more information.
Basic Usage
<ion-item>
<ion-label> Sam</ion-label>
<ion-toggle disabled checked="false"></ion-toggle>
</ion-item>
Toolbar
A toolbar is a generic bar that can be used in an app as a header, sub-header, footer, or even sub-footer. Since ion-toolbar
is based on flexbox, no matter how many toolbars you have in your page, they will be displayed correctly and ion-content
will adjust accordingly.
- Contents
- Basic Usage
- Buttons in Toolbars
- Segment in Toolbars
- Searchbar in Toolbars
- Changing the Color
Basic Usage
Add the property position="bottom"
to place the tool bar below the content:
<ion-toolbar>
<ion-title>Toolbar</ion-title>
</ion-toolbar>
<ion-content></ion-content>
<ion-toolbar position="bottom">
<ion-title>Footer</ion-title>
</ion-toolbar>
Header
One of the best uses of the toolbar is as a header.
<ion-toolbar primary>
<ion-buttons start>
<icon name="content"></icon>
</ion-buttons>
<ion-title>Header</ion-title>
<ion-buttons end>
<icon name="search"></icon>
</ion-buttons>
</ion-toolbar>
<ion-content>
<p>There is a header above me!</p>
</ion-content>
Buttons in Toolbars
Buttons can be added to both header and footer toolbars. To add a button to a toolbar, we need to first add an ion-buttons
component. This component wraps one or more buttons, and can be given the start
or end
attributes to control the placement of the buttons it contains:
<ion-toolbar>
<ion-buttons start>
<button royal>
<ion-icon name="search"></ion-icon>
</button>
</ion-buttons>
<ion-title>Send To...</ion-title>
<ion-buttons end>
<button royal>
<ion-icon name="person-add"></ion-icon>
</button>
</ion-buttons>
</ion-toolbar>
<ion-content></ion-content>
<ion-toolbar position="bottom">
<p>Ash, Misty, Brock</p>
<ion-buttons end>
<button royal>
Send
<ion-icon name="send"></ion-icon>
</button>
</ion-buttons>
</ion-toolbar>
Segment in Toolbars
Segments are a great way to allow users to switch between different sets of data. Use the following markup to add a segment to a toolbar:
<ion-toolbar>
<ion-buttons start>
<button>
<ion-icon name="create"></ion-icon>
</button>
</ion-buttons>
<ion-segment>
<ion-segment-button value="new">
New
</ion-segment-button>
<ion-segment-button value="hot">
Hot
</ion-segment-button>
</ion-segment>
<ion-buttons end>
<button>
<ion-icon name="more"></ion-icon>
</button>
</ion-buttons>
</ion-toolbar>
Searchbar in Toolbars
Another common design paradigm is to include a searchbar inside your toolbar.
<ion-toolbar primary>
<ion-searchbar [(ngModel)]="searchQuery" (input)="getItems($event)"></ion-searchbar>
</ion-toolbar>
<ion-content>
<ion-list>
<ion-item *ngFor="#item of items">
{{ item }}
</ion-item>
</ion-list>
</ion-content>
@Page({
templateUrl: 'search/template.html',
})
class SearchPage {
constructor() {
this.searchQuery = '';
this.initializeItems();
}
initializeItems() {
this.items = [
'Angular 1.x',
'Angular 2',
'ReactJS',
'EmberJS',
'Meteor',
'Typescript',
'Dart',
'CoffeeScript'
];
}
getItems(searchbar) {
// Reset items back to all of the items
this.initializeItems();
// set q to the value of the searchbar
var q = searchbar.value;
// if the value is an empty string don't filter the items
if (q.trim() == '') {
return;
}
this.items = this.items.filter((v) => {
if (v.toLowerCase().indexOf(q.toLowerCase()) > -1) {
return true;
}
return false;
})
}
}
Changing the Color
You can change the toolbars color by changing the property on the element.
@Page({
template: `
<ion-toolbar primary>
<ion-title>Toolbar</ion-title>
</ion-toolbar>
<ion-toolbar secondary>
<ion-title>Toolbar</ion-title>
</ion-toolbar>
<ion-toolbar danger>
<ion-title>Toolbar</ion-title>
</ion-toolbar>
<ion-toolbar dark>
<ion-title>Toolbar</ion-title>
</ion-toolbar>
`
})
You can also change the navbar’s color the same way. This will allow you to have a different color navbar per page in your app.
<ion-navbar *navbar dark>
<ion-title>Dark</ion-title>
</ion-navbar>
<ion-navbar *navbar danger>
<ion-title>Danger</ion-title>
</ion-navbar>
<ion-navbar *navbar secondary>
<ion-title>Secondary</ion-title>
</ion-navbar>