feat(fab): update floating action buttons

This commit is contained in:
Manu Mtz.-Almeida
2016-09-21 16:42:07 +02:00
committed by Adam Bradley
parent 83d973b1a8
commit 490a06dd3e
22 changed files with 703 additions and 223 deletions

View File

@ -1,58 +0,0 @@
@import "../../themes/ionic.globals";
// Floating Action Buttons
// --------------------------------------------------
/// @prop - Width and height of the FAB button
$button-fab-size: 56px !default;
.button-fab {
position: absolute;
overflow: hidden;
line-height: $button-fab-size;
vertical-align: middle;
background-clip: padding-box;
}
.button-fab.button {
width: $button-fab-size;
min-width: 0;
height: $button-fab-size;
font-size: 14px;
}
.button-fab ion-icon {
flex: 1;
font-size: 2.8rem;
}
.button-fab[fab-center] {
left: 50%;
margin-left: -$button-fab-size / 2;
}
.button-fab[fab-top] {
top: 16px;
}
.button-fab[fab-right] {
right: 16px;
}
.button-fab[fab-bottom] {
bottom: 16px;
}
.button-fab[fab-left] {
left: 16px;
}
.button-fab[fab-fixed] {
position: fixed;
}

View File

@ -311,14 +311,6 @@ $button-ios-fab-border-radius: 50% !default;
}
// iOS FAB Button
// --------------------------------------------------
.button-fab-ios {
border-radius: $button-ios-fab-border-radius;
}
// Generate iOS Button Colors
// --------------------------------------------------

View File

@ -394,23 +394,6 @@ $button-md-fab-box-shadow-activated: 0 5px 15px 0 rgba(0, 0, 0, .4),
border-radius: $button-md-round-border-radius;
}
// Material Design FAB Button
// --------------------------------------------------
.button-fab-md {
border-radius: $button-md-fab-border-radius;
box-shadow: $button-md-fab-box-shadow;
transition: box-shadow $button-md-transition-duration $button-md-transition-timing-function,
background-color $button-md-transition-duration $button-md-transition-timing-function,
color $button-md-transition-duration $button-md-transition-timing-function;
}
.button-fab-md.activated {
box-shadow: $button-md-fab-box-shadow-activated;
}
.button-md [icon-only] {
padding: 0;
}

View File

@ -309,14 +309,6 @@ $button-wp-fab-border-radius: 50% !default;
border-radius: $button-wp-round-border-radius;
}
// Windows FAB Button
// --------------------------------------------------
.button-fab-wp {
border-radius: $button-wp-fab-border-radius;
}
.button-wp [icon-only] {
padding: 0;
}

View File

@ -1,30 +0,0 @@
import { Component, NgModule } from '@angular/core';
import { IonicApp, IonicModule } from '../../../..';
@Component({
templateUrl: 'main.html'
})
export class E2EPage {}
@Component({
template: '<ion-nav [root]="rootPage"></ion-nav>'
})
export class E2EApp {
rootPage = E2EPage;
}
@NgModule({
declarations: [
E2EApp,
E2EPage
],
imports: [
IonicModule.forRoot(E2EApp)
],
bootstrap: [IonicApp],
entryComponents: [
E2EPage
]
})
export class AppModule {}

View File

@ -1 +0,0 @@

View File

@ -1,25 +0,0 @@
<ion-content>
<button ion-button fab fab-left fab-top>
<ion-icon name="add"></ion-icon>
</button>
<button ion-button fab fab-center fab-top color="secondary">
<ion-icon name="add"></ion-icon>
</button>
<button ion-button fab fab-right fab-top color="danger">
<ion-icon name="add"></ion-icon>
</button>
<button ion-button fab fab-left fab-bottom color="light">
<ion-icon name="add"></ion-icon>
</button>
<button ion-button fab fab-center fab-bottom color="primary">
<ion-icon name="add"></ion-icon>
</button>
<button ion-button fab fab-right fab-bottom color="dark">
<ion-icon name="add"></ion-icon>
</button>
</ion-content>

View File

@ -57,6 +57,27 @@ ion-content.js-scroll > .scroll-content {
}
// Fixed Content (ion-fixed and ion-fab)
// --------------------------------------------------
.fixed-content {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: block;
}
[ion-fixed] {
position: absolute;
z-index: $z-index-fixed-content;
transform: translateZ(0);
}
// Content Padding
// --------------------------------------------------
@ -151,15 +172,3 @@ ion-content.js-scroll > .scroll-content {
margin-left: $content-margin;
}
}
// Content Fixed
// --------------------------------------------------
ion-fixed {
position: absolute;
z-index: $z-index-fixed-content;
transform: translateZ(0);
}

View File

@ -103,10 +103,12 @@ import { isTrueProperty } from '../../util/util';
@Component({
selector: 'ion-content',
template:
'<div class="fixed-content">' +
'<ng-content select="[ion-fixed],ion-fab"></ng-content>' +
'</div>' +
'<div class="scroll-content">' +
'<ng-content></ng-content>' +
'</div>' +
'<ng-content select="ion-fixed"></ng-content>' +
'<ng-content select="ion-refresher"></ng-content>',
host: {
'[class.statusbar-padding]': '_sbPadding'
@ -136,6 +138,11 @@ export class Content extends Ion {
*/
_scrollEle: HTMLElement;
/*
* @private
*/
_fixedEle: HTMLElement;
/**
* A number representing how many pixels the top of the content has been
* adjusted, which could be by either padding or margin.
@ -175,7 +182,8 @@ export class Content extends Ion {
* @private
*/
ngOnInit() {
this._scrollEle = this._elementRef.nativeElement.children[0];
this._fixedEle = this._elementRef.nativeElement.children[0];
this._scrollEle = this._elementRef.nativeElement.children[1];
this._zone.runOutsideAngular(() => {
this._scroll = new ScrollView(this._scrollEle);
@ -530,63 +538,61 @@ export class Content extends Ion {
* DOM WRITE
*/
writeDimensions() {
let newVal: number;
let scrollEle = this._scrollEle;
let scrollEle = this._scrollEle as any;
if (!scrollEle) {
return;
}
if (!scrollEle) return;
let fixedEle = this._fixedEle;
if (!fixedEle) {
return;
}
// only write when it has changed
// Toolbar height
let contentTop = this._headerHeight;
let contentBottom = this._footerHeight;
// Tabs height
if (this._tabsPlacement === 'top') {
contentTop += this._tabbarHeight;
} else if (this._tabsPlacement === 'bottom') {
contentBottom += this._tabbarHeight;
// Update footer position
if (contentBottom > 0 && this._footerEle) {
this._footerEle.style.bottom = cssFormat(contentBottom - this._footerHeight);
}
}
// Handle fullscreen viewport (padding vs margin)
let topProperty = 'marginTop';
let bottomProperty = 'marginBottom';
let fixedTop: number = contentTop;
let fixedBottom: number = contentBottom;
if (this._fullscreen) {
// adjust the content with padding, allowing content to scroll under headers/footers
// however, on iOS you cannot control the margins of the scrollbar (last tested iOS9.2)
// only add inline padding styles if the computed padding value, which would
// have come from the app's css, is different than the new padding value
contentTop += this._paddingTop;
contentBottom += this._paddingBottom;
topProperty = 'paddingTop';
bottomProperty = 'paddingBottom';
}
newVal = this._headerHeight + this._paddingTop;
if (this._tabsPlacement === 'top') {
newVal += this._tabbarHeight;
}
if (newVal !== this.contentTop) {
scrollEle.style.paddingTop = (newVal > 0 ? newVal + 'px' : '');
this.contentTop = newVal;
}
// Only update top margin if value changed
if (contentTop !== this.contentTop) {
scrollEle.style[topProperty] = cssFormat(contentTop);
fixedEle.style.marginTop = cssFormat(fixedTop);
this.contentTop = contentTop;
}
newVal = this._footerHeight + this._paddingBottom;
if (this._tabsPlacement === 'bottom') {
newVal += this._tabbarHeight;
if (newVal > 0 && this._footerEle) {
this._footerEle.style.bottom = (newVal - this._footerHeight - this._paddingBottom) + 'px';
}
}
if (newVal !== this.contentBottom) {
scrollEle.style.paddingBottom = (newVal > 0 ? newVal + 'px' : '');
this.contentBottom = newVal;
}
} else {
// adjust the content with margins
newVal = this._headerHeight;
if (this._tabsPlacement === 'top') {
newVal += this._tabbarHeight;
}
if (newVal !== this.contentTop) {
scrollEle.style.marginTop = (newVal > 0 ? newVal + 'px' : '');
this.contentTop = newVal;
}
newVal = this._footerHeight;
if (this._tabsPlacement === 'bottom') {
newVal += this._tabbarHeight;
}
if (newVal !== this.contentBottom) {
scrollEle.style.marginBottom = (newVal > 0 ? newVal + 'px' : '');
this.contentBottom = newVal;
if (newVal > 0 && this._footerEle) {
this._footerEle.style.bottom = (newVal - this._footerHeight) + 'px';
}
}
// Only update bottom margin if value changed
if (contentBottom !== this.contentBottom) {
scrollEle.style[bottomProperty] = cssFormat(contentBottom);
fixedEle.style.marginBottom = cssFormat(fixedBottom);
this.contentBottom = contentBottom;
}
@ -606,3 +612,7 @@ export class Content extends Ion {
function parsePxUnit(val: string): number {
return (val.indexOf('px') > 0) ? parseInt(val, 10) : 0;
}
function cssFormat(val: number): string {
return (val > 0 ? val + 'px' : '');
}

32
src/components/fab/fab.ios.scss Executable file
View File

@ -0,0 +1,32 @@
@import "../../themes/ionic.globals.ios";
// iOS FAB Button
// --------------------------------------------------
/// @prop - Border radius of the FAB button
$button-ios-fab-border-radius: 50% !default;
.fab-button {
border-radius: $button-ios-fab-border-radius;
}
// Generate iOS FAB colors
// --------------------------------------------------
@each $color-name, $color-base, $color-contrast in get-colors($colors-ios) {
$background-color: $color-base;
$background-color-activated: color-shade($background-color);
$fg-color: $color-contrast;
.fab-ios-#{$color-name} {
color: $fg-color;
background-color: $background-color;
}
.fab-ios-#{$color-name}.activated {
background-color: $background-color-activated;
}
}

48
src/components/fab/fab.md.scss Executable file
View File

@ -0,0 +1,48 @@
@import "../../themes/ionic.globals.md";
// Material Design FAB Button
// --------------------------------------------------
/// @prop - Border radius of the FAB button
$button-md-fab-border-radius: 50% !default;
/// @prop - Box shadow of the FAB button
$button-md-fab-box-shadow: 0 4px 6px 0 rgba(0, 0, 0, .14), 0 4px 5px rgba(0, 0, 0, .1) !default;
/// @prop - Box shadow of the activated FAB button
$button-md-fab-box-shadow-activated: 0 5px 15px 0 rgba(0, 0, 0, .4), 0 4px 7px 0 rgba(0, 0, 0, .1) !default;
.fab-button {
border-radius: $button-md-fab-border-radius;
box-shadow: $button-md-fab-box-shadow;
transition: box-shadow $button-md-transition-duration $button-md-transition-timing-function,
background-color $button-md-transition-duration $button-md-transition-timing-function,
color $button-md-transition-duration $button-md-transition-timing-function;
&.activated {
box-shadow: $button-md-fab-box-shadow-activated;
}
}
// Generate iOS FAB colors
// --------------------------------------------------
@each $color-name, $color-base, $color-contrast in get-colors($colors-md) {
$background-color: $color-base;
$background-color-activated: color-shade($background-color);
$fg-color: $color-contrast;
.fab-md-#{$color-name} {
color: $fg-color;
background-color: $background-color;
}
.fab-md-#{$color-name}.activated {
background-color: $background-color-activated;
}
}

202
src/components/fab/fab.scss Executable file
View File

@ -0,0 +1,202 @@
@import "../../themes/ionic.globals";
// Floating Action Buttons
// --------------------------------------------------
/// @prop - Width and height of the FAB button
$button-fab-size: 56px !default;
$button-fab-mini-size: 40px !default;
$button-fab-content-margin: 10px !default;
$button-fab-list-margin: 10px !default;
.fab-button {
position: relative;
z-index: 0;
display: block;
overflow: hidden;
width: $button-fab-size;
height: $button-fab-size;
font-size: 14px;
line-height: $button-fab-size;
text-align: center;
text-overflow: ellipsis;
text-transform: none;
white-space: nowrap;
color: #fff;
background-color: #327eff;
cursor: pointer;
transition: background-color, opacity 100ms linear;
-moz-appearance: none;
-webkit-appearance: none;
background-clip: padding-box;
font-kerning: none;
user-select: none;
ion-icon {
flex: 1;
font-size: 2.4rem;
}
}
// FAB mini
// --------------------------------------------------
.fab-button[mini] {
margin: ($button-fab-size - $button-fab-mini-size) / 2;
width: $button-fab-mini-size;
height: $button-fab-mini-size;
line-height: $button-fab-mini-size;
.fab-close-icon {
line-height: $button-fab-mini-size;
}
}
// FAB container
// --------------------------------------------------
ion-fab {
position: absolute;
z-index: $z-index-fixed-content;
&[center] {
left: 50%;
margin-left: -$button-fab-size / 2;
}
&[middle] {
top: 50%;
margin-top: -$button-fab-size / 2;
}
&[top] {
top: $button-fab-content-margin;
}
&[right] {
right: $button-fab-content-margin;
}
&[bottom] {
bottom: $button-fab-content-margin;
}
&[left] {
left: $button-fab-content-margin;
}
&[top][edge] {
top: -$button-fab-size / 2;
}
&[bottom][edge] {
bottom: -$button-fab-size / 2;
}
}
// FAB list (speed dial)
// --------------------------------------------------
ion-fab-list {
position: absolute;
top: 0;
display: none;
flex-direction: column;
align-items: center;
margin: $button-fab-size + $button-fab-list-margin 0;
min-width: $button-fab-size;
min-height: $button-fab-size;
.fab-button {
margin: 8px;
width: $button-fab-mini-size;
height: $button-fab-mini-size;
color: #797979;
background: #fff;
opacity: 0;
visibility: hidden;
transform: scale(0);
transition: all 200ms ease;
transition-delay: 10ms;
transition-property: transform, opacity;
&.fab-dial-button-visible {
opacity: 1;
visibility: visible;
transform: scale(1);
}
}
}
ion-fab-list[side=top] {
top: initial;
bottom: 0;
flex-direction: column-reverse;
}
ion-fab-list[side=left] {
right: 0;
flex-direction: row-reverse;
margin: 0 $button-fab-size + $button-fab-list-margin;
}
ion-fab-list[side=right] {
left: 0;
flex-direction: row;
margin: 0 $button-fab-size + $button-fab-list-margin;
}
// FAB animation
// --------------------------------------------------
.fab-list-active {
display: flex;
}
.fab-close-icon {
position: absolute;
top: 0;
right: 0;
left: 0;
line-height: $button-fab-size;
opacity: 0;
transform: scale(.4) rotateZ(-45deg);
transition: all ease-in-out 300ms;
}
.fab-button .button-inner {
transition: all ease-in-out 300ms;
}
.fab-close-active .fab-close-icon {
opacity: 1;
transform: scale(1) rotateZ(0deg);
}
.fab-close-active .button-inner {
opacity: 0;
transform: scale(.4) rotateZ(45deg);
}

168
src/components/fab/fab.ts Executable file
View File

@ -0,0 +1,168 @@
import { Component, ContentChild, Input, ContentChildren, QueryList, ChangeDetectionStrategy, Directive, ElementRef, Renderer, ViewEncapsulation } from '@angular/core';
import { Config } from '../../config/config';
import { Ion } from '../ion';
import { UIEventManager } from '../../util/ui-event-manager';
import { isTrueProperty } from '../../util/util';
@Component({
selector: '[ion-fab]',
template:
'<ion-icon name="close" class="fab-close-icon"></ion-icon>' +
'<span class="button-inner">' +
'<ng-content></ng-content>' +
'</span>' +
'<div class="button-effect"></div>',
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
})
export class FabButton extends Ion {
ngAfterContentInit() {
this.setElementClass('fab-button', true); // set role
}
/**
* @input {string} The predefined color to use. For example: `"primary"`, `"secondary"`, `"danger"`.
*/
@Input()
set color(val: string) {
this._setColor('fab', val);
}
/**
* @input {string} The mode to apply to this component.
*/
@Input()
set mode(val: string) {
this._setMode('fab', val);
}
constructor(
config: Config,
elementRef: ElementRef,
renderer: Renderer,
) {
super(config, elementRef, renderer);
this.mode = config.get('mode');
}
setActiveClose(closeVisible: boolean) {
this.setElementClass('fab-close-active', closeVisible);
}
}
/**
* @name Fab
* @module ionic
*
* @demo /docs/v2/demos/fab/
* @see {@link /docs/v2/components#fab Fab Component Docs}
*/
@Directive({
selector: 'ion-fab-list',
host: {
'[class.fab-list-active]': '_visible'
}
})
export class FabList {
_visible: boolean = false;
@ContentChildren(FabButton) _buttons: QueryList<FabButton>;
/**
* @private
*/
setVisible(val: boolean) {
let visible = isTrueProperty(val);
if (visible === this._visible) {
return;
}
let buttons = this._buttons.toArray();
let i = 1;
if (visible) {
buttons.forEach(fab => {
setTimeout(() => fab.setElementClass('fab-dial-button-visible', true), i * 30);
i++;
});
} else {
buttons.forEach(fab => fab.setElementClass('fab-dial-button-visible', false));
}
this._visible = visible;
}
}
@Component({
selector: 'ion-fab',
template: '<ng-content></ng-content>'
})
export class Fab {
_events: UIEventManager = new UIEventManager();
_listsActive: boolean = false;
@ContentChild(FabButton) _mainButton: FabButton;
@ContentChildren(FabList) _fabLists: QueryList<FabList>;
constructor(private _elementRef: ElementRef) { }
/**
* @private
*/
ngAfterContentInit() {
this._events.listen(this._mainButton.getNativeElement(), 'click', this.pointerUp.bind(this));
}
/**
* @private
*/
pointerUp(ev: any) {
if (this.canActivateList(ev)) {
this.toggleList();
}
}
/**
* @private
*/
canActivateList(ev: any): boolean {
if (this._fabLists.length > 0 && this._mainButton && ev.target) {
let ele = ev.target.closest('ion-fab>button');
return (ele && ele === this._mainButton.getNativeElement());
}
return false;
}
/**
* @private
*/
toggleList() {
this.setActiveLists(!this._listsActive);
}
setActiveLists(isActive: boolean) {
if (isActive === this._listsActive) {
return;
}
let lists = this._fabLists.toArray();
for (let list of lists) {
list.setVisible(isActive);
}
this._mainButton.setActiveClose(isActive);
this._listsActive = isActive;
}
close() {
this.setActiveLists(false);
}
/**
* @private
*/
ngOnDestroy() {
this._events.unlistenAll();
}
}

32
src/components/fab/fab.wp.scss Executable file
View File

@ -0,0 +1,32 @@
@import "../../themes/ionic.globals.wp";
// Windows FAB Button
// --------------------------------------------------
/// @prop - Border radius of the FAB button
$button-wp-fab-border-radius: 50% !default;
.fab-button {
border-radius: $button-wp-fab-border-radius;
}
// Generate iOS FAB colors
// --------------------------------------------------
@each $color-name, $color-base, $color-contrast in get-colors($colors-wp) {
$background-color: $color-base;
$background-color-activated: color-shade($background-color);
$fg-color: $color-contrast;
.fab-wp-#{$color-name} {
color: $fg-color;
background-color: $background-color;
}
.fab-wp-#{$color-name}.activated {
background-color: $background-color-activated;
}
}

View File

@ -0,0 +1,45 @@
import { Component, NgModule } from '@angular/core';
import { IonicApp, IonicModule, Fab } from '../../../..';
@Component({
templateUrl: 'main.html'
})
export class E2EPage {
array: number[] = [];
add() {
this.array.push(1);
}
clickMainFAB() {
console.log('Clicked open social menu');
}
openSocial(network: string, fab: Fab) {
console.log('Share in ' + network);
fab.close();
}
}
@Component({
template: '<ion-nav [root]="root"></ion-nav>'
})
export class E2EApp {
root: any = E2EPage;
}
@NgModule({
declarations: [
E2EApp,
E2EPage
],
imports: [
IonicModule.forRoot(E2EApp)
],
bootstrap: [IonicApp],
entryComponents: [
E2EPage
]
})
export class AppModule {}

View File

@ -0,0 +1,73 @@
<ion-header>
<ion-toolbar>
<ion-title>Floating Action Buttons</ion-title>
</ion-toolbar>
</ion-header>
<ion-content fullscreen>
<div f></div>
<div f></div>
<button ion-button>Test</button>
<div f *ngFor="let a of array"></div>
<ion-fab top right edge #fab1>
<button ion-fab mini (click)="clickMainFAB()"><ion-icon name="add"></ion-icon></button>
<ion-fab-list>
<button ion-fab (click)="openSocial('facebook', fab1)"><ion-icon name="logo-facebook"></ion-icon></button>
<button ion-fab (click)="openSocial('twitter', fab1)"><ion-icon name="logo-twitter"></ion-icon></button>
<button ion-fab (click)="openSocial('vimeo', fab1)"><ion-icon name="logo-vimeo"></ion-icon></button>
<button ion-fab (click)="openSocial('googleplus', fab1)"><ion-icon name="logo-googleplus"></ion-icon></button>
</ion-fab-list>
</ion-fab>
<ion-fab right bottom #fab2>
<button ion-fab color="light"><ion-icon name="arrow-dropleft"></ion-icon></button>
<ion-fab-list side="left">
<button ion-fab (click)="openSocial('facebook', fab2)"><ion-icon name="logo-facebook"></ion-icon></button>
<button ion-fab (click)="openSocial('twitter', fab2)"><ion-icon name="logo-twitter"></ion-icon></button>
<button ion-fab (click)="openSocial('vimeo', fab2)"><ion-icon name="logo-vimeo"></ion-icon></button>
<button ion-fab (click)="openSocial('googleplus', fab2)"><ion-icon name="logo-googleplus"></ion-icon></button>
</ion-fab-list>
</ion-fab>
<ion-fab left top #fab3>
<button ion-fab color="secondary"><ion-icon name="arrow-dropright"></ion-icon></button>
<ion-fab-list side="right">
<button ion-fab (click)="openSocial('facebook', fab3)"><ion-icon name="logo-facebook"></ion-icon></button>
<button ion-fab (click)="openSocial('twitter', fab3)"><ion-icon name="logo-twitter"></ion-icon></button>
<button ion-fab (click)="openSocial('vimeo', fab3)"><ion-icon name="logo-vimeo"></ion-icon></button>
<button ion-fab (click)="openSocial('googleplus', fab3)"><ion-icon name="logo-googleplus"></ion-icon></button>
</ion-fab-list>
</ion-fab>
<ion-fab left bottom #fab4>
<button ion-fab color="dark"><ion-icon name="arrow-dropup"></ion-icon></button>
<ion-fab-list side="top">
<button ion-fab (click)="openSocial('facebook', fab4)"><ion-icon name="logo-facebook"></ion-icon></button>
<button ion-fab (click)="openSocial('twitter', fab4)"><ion-icon name="logo-twitter"></ion-icon></button>
<button ion-fab (click)="openSocial('vimeo', fab4)"><ion-icon name="logo-vimeo"></ion-icon></button>
<button ion-fab (click)="openSocial('googleplus', fab4)"><ion-icon name="logo-googleplus"></ion-icon></button>
</ion-fab-list>
</ion-fab>
<ion-fab center middle #fab5>
<button ion-fab color="danger" (click)="clickMainFAB()"><ion-icon name="md-share"></ion-icon></button>
<ion-fab-list side="top">
<button ion-fab (click)="openSocial('vimeo', fab5)"><ion-icon name="logo-vimeo"></ion-icon></button>
</ion-fab-list>
<ion-fab-list side="bottom">
<button ion-fab (click)="openSocial('facebook', fab5)"><ion-icon name="logo-facebook"></ion-icon></button>
</ion-fab-list>
<ion-fab-list side="left">
<button ion-fab (click)="openSocial('googleplus', fab5)"><ion-icon name="logo-googleplus"></ion-icon></button>
</ion-fab-list>
<ion-fab-list side="right">
<button ion-fab (click)="openSocial('twitter', fab5)"><ion-icon name="logo-twitter"></ion-icon></button>
</ion-fab-list>
</ion-fab>
<ion-fab right middle>
<button ion-fab color="danger" (click)="add()"><ion-icon name="add"></ion-icon></button>
</ion-fab>
</ion-content>

View File

View File

@ -290,10 +290,9 @@ export class FullPage {
<p><button ion-button id="insert" (click)="insert()">Insert first page into history before this</button></p>
<p><button ion-button id="remove" (click)="removeSecond()">Remove second page in history</button></p>
<div class="yellow"><div f></div><div f></div><div f></div><div f></div><div f></div><div f></div><div f></div><div f></div><div f></div><div f></div><div f></div><div f></div><div f></div><div f></div><div f></div><div f></div><div f></div><div f></div><div f></div><div f></div></div>
<ion-fixed style="bottom:0">
<button ion-button (click)="presentAlert()">fixed button (alert)</button>
</ion-fixed>
<ion-fixed style="pointer-events: none; top:0; bottom:0; right:0; width:50%; background: rgba(0,0,0,0.5);"></ion-fixed>
<button ion-button ion-fixed (click)="presentAlert()">fixed button (alert)</button>
<div ion-fixed style="position: absolute; pointer-events: none; top:10px; bottom:10px; right:10px; width:50%; background: rgba(0,0,0,0.5);"></div>
</ion-content>
<ion-footer>
<ion-toolbar no-border-bottom>

View File

@ -11,6 +11,7 @@ import { Checkbox } from './components/checkbox/checkbox';
import { Chip } from './components/chip/chip';
import { Content } from './components/content/content';
import { DateTime } from './components/datetime/datetime';
import { Fab, FabButton, FabList } from './components/fab/fab';
import { Fixed } from './components/fixed/fixed';
import { Grid, Row, Col } from './components/grid/grid';
import { Icon } from './components/icon/icon';
@ -79,6 +80,7 @@ export { Checkbox } from './components/checkbox/checkbox';
export { Chip } from './components/chip/chip';
export { Content } from './components/content/content';
export { DateTime } from './components/datetime/datetime';
export { Fab, FabButton, FabList } from './components/fab/fab';
export { Fixed } from './components/fixed/fixed';
export { Grid, Row, Col } from './components/grid/grid';
export { Icon } from './components/icon/icon';
@ -171,6 +173,9 @@ export const IONIC_DIRECTIVES: any[] = [
Col,
Content,
DateTime,
Fab,
FabButton,
FabList,
Fixed,
Footer,
Grid,

View File

@ -31,7 +31,6 @@
@import
"../components/button/button",
"../components/button/button-fab",
"../components/button/button-icon",
"../components/button/button.ios",
"../components/button/button.md",
@ -66,6 +65,12 @@
"../components/datetime/datetime.md",
"../components/datetime/datetime.wp";
@import
"../components/fab/fab",
"../components/fab/fab.ios",
"../components/fab/fab.md",
"../components/fab/fab.wp";
@import
"../components/grid/grid";

View File

@ -32,7 +32,7 @@ $z-index-menu-backdrop: 79;
$z-index-overlay: 1000;
$z-index-click-block: 9999;
$z-index-fixed-content: 2;
$z-index-fixed-content: 100;
$z-index-scroll-content: 1;
$z-index-refresher: 0;

View File

@ -4,8 +4,8 @@ export interface PointerEventsConfig {
element?: HTMLElement;
elementRef?: ElementRef;
pointerDown: (ev: any) => boolean;
pointerMove: (ev: any) => void;
pointerUp: (ev: any) => void;
pointerMove?: (ev: any) => void;
pointerUp?: (ev: any) => void;
nativeOptions?: any;
zone?: boolean;
}
@ -37,7 +37,6 @@ export class PointerEvents {
private zone: boolean,
private option: any
) {
this.bindTouchEnd = this.handleTouchEnd.bind(this);
this.bindMouseUp = this.handleMouseUp.bind(this);
@ -50,7 +49,7 @@ export class PointerEvents {
if (!this.pointerDown(ev)) {
return;
}
if (!this.rmTouchMove) {
if (!this.rmTouchMove && this.pointerMove) {
this.rmTouchMove = listenEvent(this.ele, 'touchmove', this.zone, this.option, this.pointerMove);
}
if (!this.rmTouchEnd) {
@ -69,7 +68,7 @@ export class PointerEvents {
if (!this.pointerDown(ev)) {
return;
}
if (!this.rmMouseMove) {
if (!this.rmMouseMove && this.pointerMove) {
this.rmMouseMove = listenEvent(document, 'mousemove', this.zone, this.option, this.pointerMove);
}
if (!this.rmMouseUp) {
@ -79,12 +78,12 @@ export class PointerEvents {
private handleTouchEnd(ev: any) {
this.stopTouch();
this.pointerUp(ev);
this.pointerUp && this.pointerUp(ev);
}
private handleMouseUp(ev: any) {
this.stopMouse();
this.pointerUp(ev);
this.pointerUp && this.pointerUp(ev);
}
private stopTouch() {
@ -147,7 +146,7 @@ export class UIEventManager {
element = config.elementRef.nativeElement;
}
if (!element || !config.pointerDown || !config.pointerMove || !config.pointerUp) {
if (!element || !config.pointerDown) {
console.error('PointerEvents config is invalid');
return;
}