mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
refactor(tabs): apply design-doc (#16048)
This commit is contained in:
@@ -4,23 +4,29 @@ Tabs are a top level navigation component for created multiple stacked navs.
|
||||
The component is a container of individual [Tab](../Tab/) components.
|
||||
|
||||
`ion-tabs` is a styleless component that works as a router outlet in
|
||||
order to handle navigation. When the user does not provide a `ion-tabbar` in their markup, `ion-tabs`, by default provides one. Notice that `ion-tabbar` is the UI component that can be used to switch between tabs.
|
||||
order to handle navigation. When the user does not provide a `ion-tab-bar` in their markup, `ion-tabs`, by default provides one. Notice that `ion-tab-bar` is the UI component that can be used to switch between tabs.
|
||||
|
||||
In order to customize the style of the `ion-tabbar`, it should be included in the user's markup as
|
||||
In order to customize the style of the `ion-tab-bar`, it should be included in the user's markup as
|
||||
direct children of `ion-tabs`, like this:
|
||||
|
||||
```html
|
||||
<style>
|
||||
.my-custom-tabs {
|
||||
font-size: 20px;
|
||||
}
|
||||
</style>
|
||||
<ion-tabs>
|
||||
<ion-tab label="Indiana Jones"></ion-tab>
|
||||
<ion-tab label="Star Wars"></ion-tab>
|
||||
<ion-tab label="Jurassic Park"></ion-tab>
|
||||
<ion-tab tab="home">Home Content</ion-tab>
|
||||
<ion-tab tab="settings">Settings Content</ion-tab>
|
||||
|
||||
<ion-tabbar color="danger" layout="icon-start" placement="top"></ion-tabbar>
|
||||
<ion-tab-bar>
|
||||
|
||||
<ion-tab-button tab="home">
|
||||
<ion-label>Home</ion-label>
|
||||
<ion-icon name="home"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="settings">
|
||||
<ion-label>Settings</ion-label>
|
||||
<ion-icon name="gear"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
</ion-tab-bar>
|
||||
</ion-tabs>
|
||||
```
|
||||
|
||||
@@ -29,11 +35,9 @@ direct children of `ion-tabs`, like this:
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type |
|
||||
| -------------- | --------------- | ------------------------------------------------------------------------------- | --------------------- |
|
||||
| `name` | `name` | A unique name for the tabs. | `string \| undefined` |
|
||||
| `tabbarHidden` | `tabbar-hidden` | If `true`, the tabbar will be hidden. Defaults to `false`. | `boolean` |
|
||||
| `useRouter` | `use-router` | If `true`, the tabs will use the router and `selectedTab` will not do anything. | `boolean` |
|
||||
| Property | Attribute | Description | Type |
|
||||
| -------- | --------- | --------------------------- | --------------------- |
|
||||
| `name` | `name` | A unique name for the tabs. | `string \| undefined` |
|
||||
|
||||
|
||||
## Events
|
||||
@@ -68,15 +72,15 @@ Type: `Promise<HTMLIonTabElement | undefined>`
|
||||
|
||||
|
||||
|
||||
### `getTab(tabOrIndex: string | number | HTMLIonTabElement) => Promise<HTMLIonTabElement | undefined>`
|
||||
### `getTab(tab: string | HTMLIonTabElement) => Promise<HTMLIonTabElement | undefined>`
|
||||
|
||||
Get the tab at the given index
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| ------------ | --------------------------------------- | ----------- |
|
||||
| `tabOrIndex` | `HTMLIonTabElement \| number \| string` | |
|
||||
| Name | Type | Description |
|
||||
| ----- | ----------------------------- | ----------- |
|
||||
| `tab` | `HTMLIonTabElement \| string` | |
|
||||
|
||||
#### Returns
|
||||
|
||||
@@ -84,15 +88,15 @@ Type: `Promise<HTMLIonTabElement | undefined>`
|
||||
|
||||
|
||||
|
||||
### `select(tabOrIndex: number | HTMLIonTabElement) => Promise<boolean>`
|
||||
### `select(tab: string | HTMLIonTabElement) => Promise<boolean>`
|
||||
|
||||
Index or the Tab instance, of the tab to select.
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| ------------ | ----------------------------- | ----------- |
|
||||
| `tabOrIndex` | `HTMLIonTabElement \| number` | |
|
||||
| Name | Type | Description |
|
||||
| ----- | ----------------------------- | ----------- |
|
||||
| `tab` | `HTMLIonTabElement \| string` | |
|
||||
|
||||
#### Returns
|
||||
|
||||
|
||||
@@ -22,8 +22,3 @@
|
||||
|
||||
contain: layout size style;
|
||||
}
|
||||
|
||||
:host(.tabbar-hidden) ion-tabbar,
|
||||
:host(.tabbar-hidden)::slotted(ion-tabbar) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Build, Component, Element, Event, EventEmitter, Listen, Method, Prop, State } from '@stencil/core';
|
||||
import { Component, Element, Event, EventEmitter, Listen, Method, Prop, State } from '@stencil/core';
|
||||
|
||||
import { Config, NavOutlet, RouteID, RouteWrite } from '../../interface';
|
||||
import { Config, NavOutlet, RouteID, RouteWrite, TabbarClickDetail } from '../../interface';
|
||||
|
||||
@Component({
|
||||
tag: 'ion-tabs',
|
||||
@@ -9,11 +9,9 @@ import { Config, NavOutlet, RouteID, RouteWrite } from '../../interface';
|
||||
})
|
||||
export class Tabs implements NavOutlet {
|
||||
|
||||
private ids = -1;
|
||||
private transitioning = false;
|
||||
private tabsId = (++tabIds);
|
||||
private leavingTab?: HTMLIonTabElement;
|
||||
private userTabbarEl?: HTMLIonTabbarElement;
|
||||
private useRouter = false;
|
||||
|
||||
@Element() el!: HTMLStencilElement;
|
||||
|
||||
@@ -28,16 +26,6 @@ export class Tabs implements NavOutlet {
|
||||
*/
|
||||
@Prop() name?: string;
|
||||
|
||||
/**
|
||||
* If `true`, the tabbar will be hidden. Defaults to `false`.
|
||||
*/
|
||||
@Prop() tabbarHidden = false;
|
||||
|
||||
/**
|
||||
* If `true`, the tabs will use the router and `selectedTab` will not do anything.
|
||||
*/
|
||||
@Prop({ mutable: true }) useRouter = false;
|
||||
|
||||
/**
|
||||
* Emitted when the tab changes.
|
||||
*/
|
||||
@@ -59,13 +47,8 @@ export class Tabs implements NavOutlet {
|
||||
@Event() ionNavDidChange!: EventEmitter<void>;
|
||||
|
||||
async componentWillLoad() {
|
||||
if (!this.useRouter) {
|
||||
this.useRouter = !!this.doc.querySelector('ion-router') && !this.el.closest('[no-router]');
|
||||
}
|
||||
this.userTabbarEl = this.el.querySelector('ion-tabbar') || undefined;
|
||||
|
||||
this.initTabs();
|
||||
|
||||
this.useRouter = !!this.doc.querySelector('ion-router') && !this.el.closest('[no-router]');
|
||||
this.tabs = Array.from(this.el.querySelectorAll('ion-tab'));
|
||||
this.ionNavWillLoad.emit();
|
||||
this.componentWillUpdate();
|
||||
}
|
||||
@@ -80,28 +63,23 @@ export class Tabs implements NavOutlet {
|
||||
}
|
||||
|
||||
componentWillUpdate() {
|
||||
const tabbarEl = this.userTabbarEl;
|
||||
if (tabbarEl) {
|
||||
tabbarEl.tabs = this.tabs.slice();
|
||||
tabbarEl.selectedTab = this.selectedTab;
|
||||
const tabbar = this.el.querySelector('ion-tab-bar');
|
||||
if (tabbar) {
|
||||
const tab = this.selectedTab ? this.selectedTab.tab : undefined;
|
||||
tabbar.selectedTab = tab;
|
||||
}
|
||||
}
|
||||
|
||||
@Listen('ionTabMutated')
|
||||
protected onTabMutated() {
|
||||
this.el.forceUpdate();
|
||||
}
|
||||
|
||||
@Listen('ionTabbarClick')
|
||||
protected onTabClicked(ev: CustomEvent<HTMLIonTabElement>) {
|
||||
const selectedTab = ev.detail;
|
||||
const href = selectedTab.href as string | undefined;
|
||||
@Listen('ionTabButtonClick')
|
||||
protected onTabClicked(ev: CustomEvent<TabbarClickDetail>) {
|
||||
const { href, tab } = ev.detail;
|
||||
const selectedTab = this.tabs.find(t => t.tab === tab);
|
||||
if (this.useRouter && href !== undefined) {
|
||||
const router = this.doc.querySelector('ion-router');
|
||||
if (router) {
|
||||
router.push(href);
|
||||
}
|
||||
} else {
|
||||
} else if (selectedTab) {
|
||||
this.select(selectedTab);
|
||||
}
|
||||
}
|
||||
@@ -110,8 +88,8 @@ export class Tabs implements NavOutlet {
|
||||
* Index or the Tab instance, of the tab to select.
|
||||
*/
|
||||
@Method()
|
||||
async select(tabOrIndex: number | HTMLIonTabElement): Promise<boolean> {
|
||||
const selectedTab = await this.getTab(tabOrIndex);
|
||||
async select(tab: string | HTMLIonTabElement): Promise<boolean> {
|
||||
const selectedTab = await this.getTab(tab);
|
||||
if (!this.shouldSwitch(selectedTab)) {
|
||||
return false;
|
||||
}
|
||||
@@ -141,20 +119,21 @@ export class Tabs implements NavOutlet {
|
||||
/** @internal */
|
||||
@Method()
|
||||
async getRouteId(): Promise<RouteID | undefined> {
|
||||
const id = this.selectedTab && this.selectedTab.name;
|
||||
return id !== undefined ? { id, element: this.selectedTab } : undefined;
|
||||
const tabId = this.selectedTab && this.selectedTab.tab;
|
||||
return tabId !== undefined ? { id: tabId, element: this.selectedTab } : undefined;
|
||||
}
|
||||
|
||||
/** Get the tab at the given index */
|
||||
@Method()
|
||||
async getTab(tabOrIndex: string | number | HTMLIonTabElement): Promise<HTMLIonTabElement | undefined> {
|
||||
if (typeof tabOrIndex === 'string') {
|
||||
return this.tabs.find(tab => tab.name === tabOrIndex);
|
||||
async getTab(tab: string | HTMLIonTabElement): Promise<HTMLIonTabElement | undefined> {
|
||||
const tabEl = (typeof tab === 'string')
|
||||
? this.tabs.find(t => t.tab === tab)
|
||||
: tab;
|
||||
|
||||
if (!tabEl) {
|
||||
console.error(`tab with id: "${tabEl}" does not exist`);
|
||||
}
|
||||
if (typeof tabOrIndex === 'number') {
|
||||
return this.tabs[tabOrIndex];
|
||||
}
|
||||
return tabOrIndex;
|
||||
return tabEl;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,47 +144,13 @@ export class Tabs implements NavOutlet {
|
||||
return Promise.resolve(this.selectedTab);
|
||||
}
|
||||
|
||||
private initTabs() {
|
||||
const tabs = this.tabs = Array.from(this.el.querySelectorAll('ion-tab'));
|
||||
tabs.forEach(tab => {
|
||||
const id = `t-${this.tabsId}-${++this.ids}`;
|
||||
tab.btnId = 'tab-' + id;
|
||||
tab.id = 'tabpanel-' + id;
|
||||
});
|
||||
}
|
||||
|
||||
private async initSelect(): Promise<void> {
|
||||
const tabs = this.tabs;
|
||||
// wait for all tabs to be ready
|
||||
await Promise.all(tabs.map(tab => tab.componentOnReady()));
|
||||
if (this.useRouter) {
|
||||
if (Build.isDev) {
|
||||
const tab = tabs.find(t => t.selected);
|
||||
if (tab) {
|
||||
console.warn('When using a router (ion-router) <ion-tab selected="true"> makes no difference' +
|
||||
'Define routes properly the define which tab is selected');
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
// find pre-selected tabs
|
||||
const selectedTab = tabs.find(t => t.selected) ||
|
||||
tabs.find(t => t.show && !t.disabled);
|
||||
|
||||
// reset all tabs none is selected
|
||||
for (const tab of tabs) {
|
||||
if (tab !== selectedTab) {
|
||||
tab.selected = false;
|
||||
}
|
||||
}
|
||||
if (selectedTab) {
|
||||
await selectedTab.setActive();
|
||||
}
|
||||
this.selectedTab = selectedTab;
|
||||
if (selectedTab) {
|
||||
selectedTab.selected = true;
|
||||
selectedTab.active = true;
|
||||
}
|
||||
// wait for all tabs to be ready
|
||||
await Promise.all(this.tabs.map(tab => tab.componentOnReady()));
|
||||
await this.select(this.tabs[0]);
|
||||
}
|
||||
|
||||
private setActive(selectedTab: HTMLIonTabElement): Promise<void> {
|
||||
@@ -213,13 +158,6 @@ export class Tabs implements NavOutlet {
|
||||
return Promise.reject('transitioning already happening');
|
||||
}
|
||||
|
||||
// Reset rest of tabs
|
||||
for (const tab of this.tabs) {
|
||||
if (selectedTab !== tab) {
|
||||
tab.selected = false;
|
||||
}
|
||||
}
|
||||
|
||||
this.transitioning = true;
|
||||
this.leavingTab = this.selectedTab;
|
||||
this.selectedTab = selectedTab;
|
||||
@@ -237,7 +175,6 @@ export class Tabs implements NavOutlet {
|
||||
return;
|
||||
}
|
||||
|
||||
selectedTab.selected = true;
|
||||
if (leavingTab !== selectedTab) {
|
||||
if (leavingTab) {
|
||||
leavingTab.active = false;
|
||||
@@ -262,28 +199,12 @@ export class Tabs implements NavOutlet {
|
||||
return selectedTab !== undefined && selectedTab !== leavingTab && !this.transitioning;
|
||||
}
|
||||
|
||||
hostData() {
|
||||
return {
|
||||
class: {
|
||||
'tabbar-hidden': this.tabbarHidden
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
return [
|
||||
<div class="tabs-inner">
|
||||
<slot></slot>
|
||||
</div>,
|
||||
<slot name="tabbar">
|
||||
<ion-tabbar
|
||||
tabs={this.tabs.slice()}
|
||||
selectedTab={this.selectedTab}
|
||||
>
|
||||
</ion-tabbar>
|
||||
</slot>
|
||||
<slot name="tabbar"></slot>
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
let tabIds = -1;
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const { register, Page, platforms } = require('../../../../../scripts/e2e');
|
||||
const { getElement, waitAndGetElementById, waitForTransition } = require('../../../../../scripts/e2e/utils');
|
||||
|
||||
class E2ETestPage extends Page {
|
||||
constructor(driver, platform) {
|
||||
super(driver, `http://localhost:3333/src/components/tabs/test/basic?ionic:mode=${platform}`);
|
||||
}
|
||||
}
|
||||
|
||||
platforms.forEach(platform => {
|
||||
describe('tabs/basic', () => {
|
||||
register('should init', driver => {
|
||||
const page = new E2ETestPage(driver, platform);
|
||||
return page.navigate();
|
||||
});
|
||||
|
||||
// register('should check each tab', async (driver, testContext) => {
|
||||
// testContext.timeout(60000);
|
||||
// const page = new E2ETestPage(driver, platform);
|
||||
|
||||
// await waitForTransition(300);
|
||||
|
||||
// const tabTwoButton = await waitAndGetElementById(driver, 'tab-t-0-1');
|
||||
// tabTwoButton.click();
|
||||
// await waitForTransition(600);
|
||||
|
||||
// const tabThreeButton = await waitAndGetElementById(driver, 'tab-t-0-2');
|
||||
// tabThreeButton.click();
|
||||
// await waitForTransition(600);
|
||||
// });
|
||||
});
|
||||
});
|
||||
25
core/src/components/tabs/test/basic/e2e.ts
Normal file
25
core/src/components/tabs/test/basic/e2e.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
|
||||
it('tab-group: basic', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/tab-group/test/basic?ionic:_testing=true'
|
||||
});
|
||||
|
||||
let compare = await page.compareScreenshot();
|
||||
expect(compare).toMatchScreenshot();
|
||||
|
||||
const button2 = await page.find('.e2eTabTwoButton');
|
||||
await button2.click();
|
||||
compare = await page.compareScreenshot();
|
||||
expect(compare).toMatchScreenshot();
|
||||
|
||||
const button3 = await page.find('.e2eTabThreeButton');
|
||||
await button3.click();
|
||||
compare = await page.compareScreenshot();
|
||||
expect(compare).toMatchScreenshot();
|
||||
|
||||
const button4 = await page.find('.e2eTabFourButton');
|
||||
await button4.click();
|
||||
compare = await page.compareScreenshot();
|
||||
expect(compare).toMatchScreenshot();
|
||||
});
|
||||
@@ -14,7 +14,8 @@
|
||||
|
||||
<ion-app>
|
||||
<ion-tabs>
|
||||
<ion-tab label="Plain List" icon="star">
|
||||
|
||||
<ion-tab tab="tab-one">
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Tab One</ion-title>
|
||||
@@ -22,13 +23,12 @@
|
||||
</ion-header>
|
||||
<ion-content padding>
|
||||
<h1>Tab One</h1>
|
||||
|
||||
<ion-button expand="block" onclick="updateBadgeCount()">Update Badge Count</ion-button>
|
||||
<ion-button color="secondary" expand="block" onclick="updateBadgeColor()">Update Badge Color</ion-button>
|
||||
</ion-content>
|
||||
</ion-tab>
|
||||
|
||||
<ion-tab label="Schedule" icon="globe" badge="6" badge-color="danger">
|
||||
<ion-tab tab="schedule">
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Tab Two</ion-title>
|
||||
@@ -39,7 +39,7 @@
|
||||
</ion-content>
|
||||
</ion-tab>
|
||||
|
||||
<ion-tab id="tabWithBadge" badge="6" badge-color="primary" label="Stopwatch" icon="logo-facebook">
|
||||
<ion-tab tab="tab-three">
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Tab Three</ion-title>
|
||||
@@ -50,7 +50,7 @@
|
||||
</ion-content>
|
||||
</ion-tab>
|
||||
|
||||
<ion-tab id="hiddenTab" label="Hidden" icon="alert" show="false">
|
||||
<ion-tab tab="hidden-tab">
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Hidden Tab</ion-title>
|
||||
@@ -61,25 +61,58 @@
|
||||
</ion-content>
|
||||
</ion-tab>
|
||||
|
||||
<ion-tab disabled label="Messages" icon="chatboxes" component="page-one">
|
||||
</ion-tab>
|
||||
<ion-tab tab="tab-four" component="page-one"></ion-tab>
|
||||
|
||||
<ion-tabbar></ion-tabbar>
|
||||
<ion-tab-bar>
|
||||
<ion-tab-button href="" tab="tab-one" class="e2eTabOneButton">
|
||||
<ion-label>Plain List</ion-label>
|
||||
<ion-icon name="star"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="schedule" class="e2eTabTwoButton">
|
||||
<ion-label>Schedule</ion-label>
|
||||
<ion-icon name="globe"></ion-icon>
|
||||
<ion-badge color="danger">6</ion-badge>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="tab-three" class="e2eTabThreeButton" disabled>
|
||||
<ion-label>Stopwatch</ion-label>
|
||||
<ion-icon name="logo-facebook"></ion-icon>
|
||||
<ion-badge color="primary">6</ion-badge>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="hidden-tab" hidden>
|
||||
<ion-label>Hidden</ion-label>
|
||||
<ion-icon name="alert"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="tab-four" class="e2eTabFourButton">
|
||||
<ion-label>Messages</ion-label>
|
||||
<ion-icon name="chatboxes"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
</ion-tab-bar>
|
||||
</ion-tabs>
|
||||
</ion-app>
|
||||
|
||||
<script>
|
||||
var tab = document.getElementById('tabWithBadge');
|
||||
|
||||
function updateBadgeCount() {
|
||||
var current = parseInt(tab.badge);
|
||||
tab.badge = ++current;
|
||||
class PageOne extends HTMLElement {
|
||||
connectedCallback() {
|
||||
this.innerHTML = `
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Page Four</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content padding>
|
||||
Page Four
|
||||
</ion-content>
|
||||
`;
|
||||
}
|
||||
}
|
||||
customElements.define('page-one', PageOne);
|
||||
|
||||
function updateBadgeColor() {
|
||||
var current = tab.badgeColor;
|
||||
tab.badgeColor = current === 'primary' ? 'danger' : 'primary';
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const { register, Page, platforms } = require('../../../../../scripts/e2e');
|
||||
const { getElement, waitAndGetElementById, waitForTransition } = require('../../../../../scripts/e2e/utils');
|
||||
|
||||
class E2ETestPage extends Page {
|
||||
constructor(driver, platform) {
|
||||
super(driver, `http://localhost:3333/src/components/tabs/test/colors?ionic:mode=${platform}`);
|
||||
}
|
||||
}
|
||||
|
||||
platforms.forEach(platform => {
|
||||
describe('tabs/colors', () => {
|
||||
register('should init', driver => {
|
||||
const page = new E2ETestPage(driver, platform);
|
||||
return page.navigate();
|
||||
});
|
||||
|
||||
// register('should check each tab', async (driver, testContext) => {
|
||||
// testContext.timeout(60000);
|
||||
// const page = new E2ETestPage(driver, platform);
|
||||
|
||||
// await waitForTransition(300);
|
||||
|
||||
// const tabTwoButton = await waitAndGetElementById(driver, 'tab-t-0-1');
|
||||
// tabTwoButton.click();
|
||||
// await waitForTransition(600);
|
||||
|
||||
// const tabThreeButton = await waitAndGetElementById(driver, 'tab-t-0-2');
|
||||
// tabThreeButton.click();
|
||||
// await waitForTransition(600);
|
||||
// });
|
||||
});
|
||||
});
|
||||
@@ -1,114 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html dir="ltr">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Tab - Colors</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
|
||||
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet">
|
||||
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet">
|
||||
<script src="../../../../../dist/ionic.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
|
||||
<!-- Default -->
|
||||
<ion-tabs>
|
||||
<ion-tab label="Recents"></ion-tab>
|
||||
<ion-tab label="Favorites" badge="6"></ion-tab>
|
||||
<ion-tab label="Settings"></ion-tab>
|
||||
</ion-tabs>
|
||||
|
||||
|
||||
<!-- Icons -->
|
||||
<ion-tabs selected-index="1">
|
||||
<ion-tab icon="call"></ion-tab>
|
||||
<ion-tab icon="heart"></ion-tab>
|
||||
<ion-tab icon="settings"></ion-tab>
|
||||
<ion-tabbar color="primary"></ion-tabbar>
|
||||
</ion-tabs>
|
||||
|
||||
|
||||
<!-- Icons on top of text -->
|
||||
<ion-tabs selected-index="2">
|
||||
<ion-tab label="Location" icon="navigate"></ion-tab>
|
||||
<ion-tab label="Favorites" badge="6" icon="heart"></ion-tab>
|
||||
<ion-tab label="Radio" icon="musical-notes"></ion-tab>
|
||||
|
||||
<ion-tabbar color="secondary"></ion-tabbar>
|
||||
</ion-tabs>
|
||||
|
||||
|
||||
<!-- Icons below text -->
|
||||
<ion-tabs selected-index="1">
|
||||
<ion-tab label="Recents" icon="call"></ion-tab>
|
||||
<ion-tab label="Favorites" badge="6" icon="heart"></ion-tab>
|
||||
<ion-tab label="Settings" icon="settings"></ion-tab>
|
||||
|
||||
<ion-tabbar layout="icon-bottom" color="dark"></ion-tabbar>
|
||||
</ion-tabs>
|
||||
|
||||
|
||||
<!-- Icons right of text -->
|
||||
<ion-tabs selected-index="0">
|
||||
<ion-tab label="Recents" icon="call"></ion-tab>
|
||||
<ion-tab label="Favorites" badge="6" icon="heart"></ion-tab>
|
||||
<ion-tab label="Settings" icon="settings"></ion-tab>
|
||||
|
||||
<ion-tabbar layout="icon-end" color="danger"></ion-tabbar>
|
||||
</ion-tabs>
|
||||
|
||||
|
||||
<!-- Icons left of text -->
|
||||
<ion-tabs>
|
||||
<ion-tab label="Recents" icon="call"></ion-tab>
|
||||
<ion-tab label="Favorites" badge="6" badge-color="danger" icon="heart"></ion-tab>
|
||||
<ion-tab label="Settings" icon="settings"></ion-tab>
|
||||
|
||||
<ion-tabbar layout="icon-start" color="light"></ion-tabbar>
|
||||
</ion-tabs>
|
||||
|
||||
|
||||
<!-- No icons -->
|
||||
<ion-tabs>
|
||||
<ion-tab label="Recents" icon="call"></ion-tab>
|
||||
<ion-tab label="Favorites" badge="6" badge-color="danger" icon="heart"></ion-tab>
|
||||
<ion-tab label="Settings" icon="settings"></ion-tab>
|
||||
|
||||
<ion-tabbar layout="icon-hide" color="primary"></ion-tabbar>
|
||||
</ion-tabs>
|
||||
|
||||
|
||||
<!-- No label -->
|
||||
<ion-tabs>
|
||||
<ion-tab label="Recents" icon="call"></ion-tab>
|
||||
<ion-tab label="Favorites" badge="6" badge-color="danger" icon="heart"></ion-tab>
|
||||
<ion-tab label="Settings" icon="settings"></ion-tab>
|
||||
|
||||
<ion-tabbar layout="label-hide" color="secondary"></ion-tabbar>
|
||||
</ion-tabs>
|
||||
|
||||
|
||||
<!-- No overflow text -->
|
||||
<ion-tabs>
|
||||
<ion-tab label="Indiana Jones and the Raiders of the Lost Ark"></ion-tab>
|
||||
<ion-tab label="Indiana Jones and the Temple of Doom"></ion-tab>
|
||||
<ion-tab label="Indiana Jones and the Last Crusade"></ion-tab>
|
||||
|
||||
<ion-tabbar color="danger"></ion-tabbar>
|
||||
|
||||
</ion-tabs>
|
||||
|
||||
</ion-app>
|
||||
|
||||
<style>
|
||||
ion-tabs {
|
||||
position: relative;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
</style>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -252,19 +252,36 @@
|
||||
|
||||
<body>
|
||||
|
||||
<ion-app useRouter='false'>
|
||||
<ion-app>
|
||||
<ion-tabs>
|
||||
<ion-tab label="Plain List" icon="star" path="">
|
||||
<ion-tab tab="plain-list">
|
||||
<ion-nav root="page-one"></ion-nav>
|
||||
</ion-tab>
|
||||
|
||||
<ion-tab label="Schedule" icon="globe" path="tab2">
|
||||
<ion-tab tab="schedule">
|
||||
<ion-nav root="page-four"></ion-nav>
|
||||
</ion-tab>
|
||||
|
||||
<ion-tab label="Stopwatch" icon="logo-facebook" path="tab3">
|
||||
<ion-tab tab="stopwatch">
|
||||
<ion-nav root="page-seven"></ion-nav>
|
||||
</ion-tab>
|
||||
|
||||
<ion-tab-bar>
|
||||
<ion-tab-button tab="plain-list">
|
||||
<ion-label>Plain List</ion-label>
|
||||
<ion-icon name="star"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="schedule">
|
||||
<ion-label>Schedule</ion-label>
|
||||
<ion-icon name="globe"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="stopwatch">
|
||||
<ion-label>Stopwatch</ion-label>
|
||||
<ion-icon name="logo-facebook"></ion-icon>
|
||||
</ion-tab-button>
|
||||
</ion-tab-bar>
|
||||
</ion-tabs>
|
||||
</ion-app>
|
||||
</body>
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const { register, Page, platforms } = require('../../../../../scripts/e2e');
|
||||
const { getElement, waitAndGetElementById, waitForTransition } = require('../../../../../scripts/e2e/utils');
|
||||
|
||||
class E2ETestPage extends Page {
|
||||
constructor(driver, platform) {
|
||||
super(driver, `http://localhost:3333/src/components/tabs/test/placements?ionic:mode=${platform}`);
|
||||
}
|
||||
}
|
||||
|
||||
platforms.forEach(platform => {
|
||||
describe('tabs/placements', () => {
|
||||
register('should init', driver => {
|
||||
const page = new E2ETestPage(driver, platform);
|
||||
return page.navigate();
|
||||
});
|
||||
|
||||
// register('should check each tab', async (driver, testContext) => {
|
||||
// testContext.timeout(60000);
|
||||
// const page = new E2ETestPage(driver, platform);
|
||||
|
||||
// await waitForTransition(300);
|
||||
|
||||
// const tabTwoButton = await waitAndGetElementById(driver, 'tab-t-0-1');
|
||||
// tabTwoButton.click();
|
||||
// await waitForTransition(600);
|
||||
|
||||
// const tabThreeButton = await waitAndGetElementById(driver, 'tab-t-0-2');
|
||||
// tabThreeButton.click();
|
||||
// await waitForTransition(600);
|
||||
// });
|
||||
});
|
||||
});
|
||||
10
core/src/components/tabs/test/placements/e2e.ts
Normal file
10
core/src/components/tabs/test/placements/e2e.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
|
||||
it('tab-group: placements', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/tab-group/test/placements?ionic:_testing=true'
|
||||
});
|
||||
|
||||
const compare = await page.compareScreenshot();
|
||||
expect(compare).toMatchScreenshot();
|
||||
});
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
<ion-app>
|
||||
<ion-tabs>
|
||||
<ion-tab icon="star">
|
||||
<ion-tab tab="star-tab">
|
||||
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
</ion-tab>
|
||||
|
||||
<ion-tab icon="globe">
|
||||
<ion-tab tab="globe-tab">
|
||||
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
</ion-tab>
|
||||
|
||||
<ion-tab icon="logo-facebook">
|
||||
<ion-tab tab="facebook-tab">
|
||||
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
@@ -53,10 +53,23 @@
|
||||
|
||||
</ion-tab>
|
||||
|
||||
<ion-tab disabled icon="chatboxes" component="page-one"></ion-tab>
|
||||
<ion-tab tab="page-one" disabled icon="chatboxes" component="page-one"></ion-tab>
|
||||
|
||||
<ion-tabbar placement="top"></ion-tabbar>
|
||||
<ion-tab-bar placement="top">
|
||||
<ion-tab-button tab="star-tab">
|
||||
<ion-icon name="star"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="globe-tab">
|
||||
<ion-icon name="globe"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="facebook-tab">
|
||||
<ion-icon name="logo-facebook"></ion-icon>
|
||||
</ion-tab-button>
|
||||
</ion-tab-bar>
|
||||
</ion-tabs>
|
||||
|
||||
</ion-app>
|
||||
</body>
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
|
||||
<ion-app>
|
||||
<ion-tabs>
|
||||
<ion-tab label="Plain List" icon="star" path="">
|
||||
|
||||
<ion-tab tab="tab-one">
|
||||
<ion-header translucent>
|
||||
<ion-toolbar>
|
||||
<ion-title>Tab One</ion-title>
|
||||
@@ -24,10 +24,9 @@
|
||||
<ion-content padding fullscreen>
|
||||
Tab One
|
||||
</ion-content>
|
||||
|
||||
</ion-tab>
|
||||
|
||||
<ion-tab label="Schedule" icon="globe" path="tab2">
|
||||
<ion-tab tab="tab-two">
|
||||
|
||||
<ion-header translucent>
|
||||
<ion-toolbar>
|
||||
@@ -40,7 +39,7 @@
|
||||
|
||||
</ion-tab>
|
||||
|
||||
<ion-tab label="Stopwatch" icon="logo-facebook" path="tab3">
|
||||
<ion-tab tab="tab-three">
|
||||
|
||||
<ion-header translucent>
|
||||
<ion-toolbar>
|
||||
@@ -53,8 +52,29 @@
|
||||
|
||||
</ion-tab>
|
||||
|
||||
<ion-tab disabled label="Messages" icon="chatboxes" component="page-one" path="tab4">
|
||||
</ion-tab>
|
||||
<ion-tab tab="tab-four" component="page-one"></ion-tab>
|
||||
|
||||
<ion-tab-bar>
|
||||
<ion-tab-button tab="tab-one">
|
||||
<ion-label>Plain List</ion-label>
|
||||
<ion-icon name="star"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="tab-two">
|
||||
<ion-label>Schedule</ion-label>
|
||||
<ion-icon name="globe"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="tab-three">
|
||||
<ion-label>Stopwatch</ion-label>
|
||||
<ion-icon name="logo-facebook"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="tab-four">
|
||||
<ion-label>Messages</ion-label>
|
||||
<ion-icon name="chatboxes"></ion-icon>
|
||||
</ion-tab-button>
|
||||
</ion-tab-bar>
|
||||
</ion-tabs>
|
||||
|
||||
<style>
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html dir="ltr">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Tab - Translucent</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet">
|
||||
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet">
|
||||
<script src="../../../../../dist/ionic.js"></script>
|
||||
<script type="text/javascript">
|
||||
window.Ionic.config = { useRouter: true };
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<ion-app>
|
||||
<ion-tabs>
|
||||
<ion-tab label="Today" icon="calendar" path="" root="translucent-page-tab">
|
||||
<ion-route path="" component="translucent-page-tab"></ion-route>
|
||||
</ion-tab>
|
||||
|
||||
<ion-tab label="Games" icon="planet" root="page-two">
|
||||
<ion-route path="" component="page-two"></ion-route>
|
||||
<ion-route path="path/to/page/three" component="page-three"></ion-route>
|
||||
</ion-tab>
|
||||
|
||||
<ion-tab label="Apps" icon="logo-buffer" root="page-three">
|
||||
<ion-route path="/" component="page-three"></ion-route>
|
||||
</ion-tab>
|
||||
|
||||
<ion-tab label="Updates" icon="download" badge="7" badge-style="danger" root="translucent-page-tab">
|
||||
<ion-route component="page-one"></ion-route>
|
||||
<ion-route path="paginaaaa-two" component="page-two"></ion-route>
|
||||
</ion-tab>
|
||||
|
||||
<ion-tab label="Search" icon="search">
|
||||
<ion-route path="" component="translucent-page-tab"></ion-route>
|
||||
</ion-tab>
|
||||
|
||||
<ion-tabbar color="primary" translucent></ion-tabbar>
|
||||
</ion-tabs>
|
||||
|
||||
<ion-nav-controller></ion-nav-controller>
|
||||
</ion-app>
|
||||
|
||||
<style>
|
||||
f {
|
||||
display: block;
|
||||
background: blue;
|
||||
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
.red {
|
||||
background-color: #ea445a;
|
||||
}
|
||||
|
||||
.green {
|
||||
background-color: #76d672;
|
||||
}
|
||||
|
||||
.blue {
|
||||
background-color: #3478f6;
|
||||
}
|
||||
|
||||
.yellow {
|
||||
background-color: #ffff80;
|
||||
}
|
||||
|
||||
.pink {
|
||||
background-color: #ff6b86;
|
||||
}
|
||||
|
||||
.purple {
|
||||
background-color: #7e34f6;
|
||||
}
|
||||
|
||||
.black {
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.orange {
|
||||
background-color: #f69234;
|
||||
}
|
||||
|
||||
</style>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -15,13 +15,25 @@
|
||||
|
||||
<body>
|
||||
<ion-tabs>
|
||||
<ion-tab label="Tab One" icon="star" path="">
|
||||
<ion-tab tab="tab-one">
|
||||
<div class="div-one" slot="not-initialized">Div One</div>
|
||||
</ion-tab>
|
||||
|
||||
<ion-tab label="Tab Two" icon="globe" path="tab2">
|
||||
<ion-tab tab="tab-two">
|
||||
<div class="div-two" slot="not-initialized">Div Two</div>
|
||||
</ion-tab>
|
||||
|
||||
<ion-tab-bar>
|
||||
<ion-tab-button tab="tab-one">
|
||||
<ion-label>Tab One</ion-label>
|
||||
<ion-icon name="star"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="tab-two">
|
||||
<ion-label>Tab Two</ion-label>
|
||||
<ion-icon name="globe"></ion-icon>
|
||||
</ion-tab-button>
|
||||
</ion-tab-bar>
|
||||
</ion-tabs>
|
||||
|
||||
<style>
|
||||
|
||||
Reference in New Issue
Block a user