fix(tabs): use slot instead of placement

This commit is contained in:
Manu Mtz.-Almeida
2018-11-01 19:26:05 +01:00
parent 1532bd2f48
commit 72f0a76a1f
17 changed files with 29 additions and 47 deletions

View File

@ -865,14 +865,14 @@ export class Tab {
} }
export declare interface TabBar extends StencilComponents<'IonTabBar'> {} export declare interface TabBar extends StencilComponents<'IonTabBar'> {}
@Component({ selector: 'ion-tab-bar', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['mode', 'color', 'layout', 'placement', 'selectedTab', 'translucent'] }) @Component({ selector: 'ion-tab-bar', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['mode', 'color', 'layout', 'selectedTab', 'translucent'] })
export class TabBar { export class TabBar {
ionTabBarChanged: EventEmitter<CustomEvent>; ionTabBarChanged: EventEmitter<CustomEvent>;
constructor(c: ChangeDetectorRef, r: ElementRef) { constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach(); c.detach();
const el = r.nativeElement; const el = r.nativeElement;
proxyInputs(this, el, ['mode', 'color', 'layout', 'placement', 'selectedTab', 'translucent']); proxyInputs(this, el, ['mode', 'color', 'layout', 'selectedTab', 'translucent']);
proxyOutputs(this, el, ['ionTabBarChanged']); proxyOutputs(this, el, ['ionTabBarChanged']);
} }
} }

View File

@ -30,7 +30,7 @@
"ionicons": "4.4.6" "ionicons": "4.4.6"
}, },
"devDependencies": { "devDependencies": {
"@stencil/core": "0.15.2-2", "@stencil/core": "0.15.2",
"@stencil/sass": "0.1.1", "@stencil/sass": "0.1.1",
"@stencil/utils": "latest", "@stencil/utils": "latest",
"@types/jest": "^23.3.1", "@types/jest": "^23.3.1",

View File

@ -59,7 +59,6 @@ import {
TabbarChangedDetail, TabbarChangedDetail,
TabbarClickDetail, TabbarClickDetail,
TabbarLayout, TabbarLayout,
TabbarPlacement,
TextFieldTypes, TextFieldTypes,
TextInputChangeEvent, TextInputChangeEvent,
ToastOptions, ToastOptions,
@ -4441,7 +4440,7 @@ export namespace Components {
*/ */
'color'?: Color; 'color'?: Color;
/** /**
* Set the layout of the text and icon in the tabbar. * Set the layout of the text and icon in the tab bar.
*/ */
'layout': TabbarLayout; 'layout': TabbarLayout;
/** /**
@ -4449,10 +4448,6 @@ export namespace Components {
*/ */
'mode': Mode; 'mode': Mode;
/** /**
* Set the position of the tabbar, relative to the content.
*/
'placement': TabbarPlacement;
/**
* The selected tab component * The selected tab component
*/ */
'selectedTab'?: string; 'selectedTab'?: string;
@ -4467,7 +4462,7 @@ export namespace Components {
*/ */
'color'?: Color; 'color'?: Color;
/** /**
* Set the layout of the text and icon in the tabbar. * Set the layout of the text and icon in the tab bar.
*/ */
'layout'?: TabbarLayout; 'layout'?: TabbarLayout;
/** /**
@ -4476,10 +4471,6 @@ export namespace Components {
'mode'?: Mode; 'mode'?: Mode;
'onIonTabBarChanged'?: (event: CustomEvent<TabbarChangedDetail>) => void; 'onIonTabBarChanged'?: (event: CustomEvent<TabbarChangedDetail>) => void;
/** /**
* Set the position of the tabbar, relative to the content.
*/
'placement'?: TabbarPlacement;
/**
* The selected tab component * The selected tab component
*/ */
'selectedTab'?: string; 'selectedTab'?: string;

View File

@ -114,7 +114,7 @@
inline tab 4 inline tab 4
</ion-tab> </ion-tab>
<ion-tab-bar> <ion-tab-bar slot="bottom">
<ion-tab-button tab="tab-one"> <ion-tab-button tab="tab-one">
<ion-label>Plain List</ion-label> <ion-label>Plain List</ion-label>

View File

@ -2,7 +2,7 @@
Tab bar is the UI component that implements the array of button of `ion-tabs`. It's provided by default when `ion-tabs` is used, though, this "implicit" tab bar can not be customized. Tab bar is the UI component that implements the array of button of `ion-tabs`. It's provided by default when `ion-tabs` is used, though, this "implicit" tab bar can not be customized.
In order to have a custom tabbar, it should be provided in user's markup as direct children of `ion-tabs`: In order to have a custom tab bar, it should be provided in user's markup as direct children of `ion-tabs`:
```html ```html
<style> <style>
@ -17,7 +17,7 @@ In order to have a custom tabbar, it should be provided in user's markup as dire
<ion-tab></ion-tab> <ion-tab></ion-tab>
<!-- User provided ion-tab-bar that can be customized --> <!-- User provided ion-tab-bar that can be customized -->
<ion-tab-bar color="dark" layout="icon-only"> <ion-tab-bar slot="bottom" color="dark" layout="icon-only">
</ion-tabs> </ion-tabs>
``` ```
@ -30,9 +30,8 @@ In order to have a custom tabbar, it should be provided in user's markup as dire
| Property | Attribute | Description | Type | | Property | Attribute | Description | Type |
| ------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | | ------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| `color` | `color` | The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics). | `string \| undefined` | | `color` | `color` | The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics). | `string \| undefined` |
| `layout` | `layout` | Set the layout of the text and icon in the tabbar. | `"icon-bottom" \| "icon-end" \| "icon-hide" \| "icon-start" \| "icon-top" \| "label-hide"` | | `layout` | `layout` | Set the layout of the text and icon in the tab bar. | `"icon-bottom" \| "icon-end" \| "icon-hide" \| "icon-start" \| "icon-top" \| "label-hide"` |
| `mode` | `mode` | The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. | `"ios" \| "md"` | | `mode` | `mode` | The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. | `"ios" \| "md"` |
| `placement` | `placement` | Set the position of the tabbar, relative to the content. | `"bottom" \| "top"` |
| `selectedTab` | `selected-tab` | The selected tab component | `string \| undefined` | | `selectedTab` | `selected-tab` | The selected tab component | `string \| undefined` |
| `translucent` | `translucent` | If `true`, the tab bar will be translucent. Defaults to `false`. | `boolean` | | `translucent` | `translucent` | If `true`, the tab bar will be translucent. Defaults to `false`. | `boolean` |

View File

@ -1,5 +1,4 @@
export type TabbarLayout = 'icon-top' | 'icon-start' | 'icon-end' | 'icon-bottom' | 'icon-hide' | 'label-hide'; export type TabbarLayout = 'icon-top' | 'icon-start' | 'icon-end' | 'icon-bottom' | 'icon-hide' | 'label-hide';
export type TabbarPlacement = 'top' | 'bottom';
export interface TabbarChangedDetail { export interface TabbarChangedDetail {
tab?: string; tab?: string;

View File

@ -10,7 +10,6 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
order: 1;
width: auto; width: auto;
@ -37,13 +36,11 @@
--background-focused: #{current-color(shade)}; --background-focused: #{current-color(shade)};
} }
:host(.placement-top) { :host([slot="top"]) {
order: -1;
border-bottom: var(--border); border-bottom: var(--border);
} }
:host(.placement-bottom) { :host([slot="bottom"]) {
padding-bottom: var(--ion-safe-area-bottom, 0); padding-bottom: var(--ion-safe-area-bottom, 0);
border-top: var(--border); border-top: var(--border);

View File

@ -1,6 +1,6 @@
import { Component, ComponentInterface, Element, Event, EventEmitter, Listen, Prop, QueueApi, State, Watch } from '@stencil/core'; import { Component, ComponentInterface, Element, Event, EventEmitter, Listen, Prop, QueueApi, State, Watch } from '@stencil/core';
import { Color, Mode, TabbarChangedDetail, TabbarLayout, TabbarPlacement } from '../../interface'; import { Color, Mode, TabbarChangedDetail, TabbarLayout } from '../../interface';
import { createColorClasses } from '../../utils/theme'; import { createColorClasses } from '../../utils/theme';
@Component({ @Component({
@ -34,15 +34,10 @@ export class TabBar implements ComponentInterface {
@Prop() color?: Color; @Prop() color?: Color;
/** /**
* Set the layout of the text and icon in the tabbar. * Set the layout of the text and icon in the tab bar.
*/ */
@Prop() layout: TabbarLayout = 'icon-top'; @Prop() layout: TabbarLayout = 'icon-top';
/**
* Set the position of the tabbar, relative to the content.
*/
@Prop() placement: TabbarPlacement = 'bottom';
/** /**
* The selected tab component * The selected tab component
*/ */
@ -69,7 +64,7 @@ export class TabBar implements ComponentInterface {
@Listen('body:keyboardWillShow') @Listen('body:keyboardWillShow')
protected onKeyboardWillShow() { protected onKeyboardWillShow() {
if (this.placement === 'bottom') { if (this.el.getAttribute('slot') === 'bottom') {
this.keyboardVisible = true; this.keyboardVisible = true;
} }
} }
@ -79,15 +74,13 @@ export class TabBar implements ComponentInterface {
} }
hostData() { hostData() {
const { color, translucent, placement, keyboardVisible } = this; const { color, translucent, keyboardVisible } = this;
return { return {
role: 'tablist', 'role': 'tablist',
'aria-hidden': keyboardVisible ? 'true' : null, 'aria-hidden': keyboardVisible ? 'true' : null,
'slot': 'tabbar',
class: { class: {
...createColorClasses(color), ...createColorClasses(color),
'tabbar-translucent': translucent, 'tabbar-translucent': translucent,
[`placement-${placement}`]: true,
'tabbar-hidden': keyboardVisible, 'tabbar-hidden': keyboardVisible,
} }
}; };

View File

@ -1,7 +1,7 @@
```html ```html
<ion-tabs> <ion-tabs>
<ion-tab-bar> <ion-tab-bar slot="bottom">
<ion-tab-button tab="schedule" href="/app/tabs/(schedule:schedule)"> <ion-tab-button tab="schedule" href="/app/tabs/(schedule:schedule)">
<ion-icon name="calendar"></ion-icon> <ion-icon name="calendar"></ion-icon>
<ion-label>Schedule</ion-label> <ion-label>Schedule</ion-label>

View File

@ -12,7 +12,7 @@ In order to do so, an `ion-tab-bar` should be provided as a direct child of `ion
<ion-tab tab="home">Home Content</ion-tab> <ion-tab tab="home">Home Content</ion-tab>
<ion-tab tab="settings">Settings Content</ion-tab> <ion-tab tab="settings">Settings Content</ion-tab>
<ion-tab-bar> <ion-tab-bar slot="bottom">
<ion-tab-button tab="home"> <ion-tab-button tab="home">
<ion-label>Home</ion-label> <ion-label>Home</ion-label>
@ -30,6 +30,8 @@ In order to do so, an `ion-tab-bar` should be provided as a direct child of `ion
Note that both `ion-tabs` and `ion-tab-bar` can be used as standalone elements. They dont depend on each other to work, but they are usually used together in order to implement a tab-based navigation that feels like a native app. Note that both `ion-tabs` and `ion-tab-bar` can be used as standalone elements. They dont depend on each other to work, but they are usually used together in order to implement a tab-based navigation that feels like a native app.
`ion-tab-bar` always needs `slot="bottom"` in order to be projected into `ion-tabs` at the right place.
## The "tab" property ## The "tab" property
Each `ion-tab-button` will activate one of the tabs when tapped. Each `ion-tab-button` will activate one of the tabs when tapped.
@ -68,7 +70,7 @@ Using tabs with Angular's router is fairly straight forward. The only additional
```html ```html
<ion-tabs> <ion-tabs>
<ion-tab-bar> <ion-tab-bar slot="bottom">
<ion-tab-button tab="schedule" href="/app/tabs/(schedule:schedule)"> <ion-tab-button tab="schedule" href="/app/tabs/(schedule:schedule)">
<ion-icon name="calendar"></ion-icon> <ion-icon name="calendar"></ion-icon>
<ion-label>Schedule</ion-label> <ion-label>Schedule</ion-label>

View File

@ -196,10 +196,11 @@ export class Tabs implements NavOutlet {
render() { render() {
return [ return [
<slot name="top"></slot>,
<div class="tabs-inner"> <div class="tabs-inner">
<slot></slot> <slot></slot>
</div>, </div>,
<slot name="tabbar"></slot> <slot name="bottom"></slot>
]; ];
} }
} }

View File

@ -69,7 +69,7 @@
<ion-tab tab="tab-four" component="page-one"></ion-tab> <ion-tab tab="tab-four" component="page-one"></ion-tab>
<ion-tab-bar> <ion-tab-bar slot="bottom">
<ion-tab-button href="" tab="tab-one" class="e2eTabOneButton"> <ion-tab-button href="" tab="tab-one" class="e2eTabOneButton">
<ion-label>Tab One</ion-label> <ion-label>Tab One</ion-label>
<ion-icon name="star"></ion-icon> <ion-icon name="star"></ion-icon>

View File

@ -55,7 +55,7 @@
<ion-tab tab="page-one" disabled icon="chatboxes" component="page-one"></ion-tab> <ion-tab tab="page-one" disabled icon="chatboxes" component="page-one"></ion-tab>
<ion-tab-bar placement="top"> <ion-tab-bar slot="top">
<ion-tab-button tab="star-tab"> <ion-tab-button tab="star-tab">
<ion-icon name="star"></ion-icon> <ion-icon name="star"></ion-icon>
</ion-tab-button> </ion-tab-button>

View File

@ -54,7 +54,7 @@
<ion-tab tab="tab-four" component="page-one"></ion-tab> <ion-tab tab="tab-four" component="page-one"></ion-tab>
<ion-tab-bar> <ion-tab-bar slot="bottom">
<ion-tab-button tab="tab-one"> <ion-tab-button tab="tab-one">
<ion-label>Plain List</ion-label> <ion-label>Plain List</ion-label>
<ion-icon name="star"></ion-icon> <ion-icon name="star"></ion-icon>

View File

@ -23,7 +23,7 @@
<div class="div-two" slot="not-initialized">Div Two</div> <div class="div-two" slot="not-initialized">Div Two</div>
</ion-tab> </ion-tab>
<ion-tab-bar> <ion-tab-bar slot="bottom">
<ion-tab-button tab="tab-one"> <ion-tab-button tab="tab-one">
<ion-label>Tab One</ion-label> <ion-label>Tab One</ion-label>
<ion-icon name="star"></ion-icon> <ion-icon name="star"></ion-icon>

View File

@ -1,7 +1,7 @@
```html ```html
<ion-tabs> <ion-tabs>
<ion-tab-bar> <ion-tab-bar slot="bottom">
<ion-tab-button tab="schedule" href="/app/tabs/(schedule:schedule)"> <ion-tab-button tab="schedule" href="/app/tabs/(schedule:schedule)">
<ion-icon name="calendar"></ion-icon> <ion-icon name="calendar"></ion-icon>
<ion-label>Schedule</ion-label> <ion-label>Schedule</ion-label>

View File

@ -9,7 +9,7 @@
<ion-tab tab="tab-map" component="page-map"></ion-tab> <ion-tab tab="tab-map" component="page-map"></ion-tab>
<ion-tab tab="tab-about" component="page-about"></ion-tab> <ion-tab tab="tab-about" component="page-about"></ion-tab>
<ion-tab-bar> <ion-tab-bar slot="bottom">
<ion-tab-button tab="tab-schedule"> <ion-tab-button tab="tab-schedule">
<ion-icon name="calendar"></ion-icon> <ion-icon name="calendar"></ion-icon>
<ion-label>Schedule</ion-label> <ion-label>Schedule</ion-label>