diff --git a/src/components/button/button-fab.scss b/src/components/button/button-fab.scss
deleted file mode 100644
index ccdf30e26c..0000000000
--- a/src/components/button/button-fab.scss
+++ /dev/null
@@ -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;
-}
diff --git a/src/components/button/button.ios.scss b/src/components/button/button.ios.scss
index 5b6289b3bf..1d1734c7c3 100644
--- a/src/components/button/button.ios.scss
+++ b/src/components/button/button.ios.scss
@@ -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
// --------------------------------------------------
diff --git a/src/components/button/button.md.scss b/src/components/button/button.md.scss
index d80d54131c..882d62cd28 100644
--- a/src/components/button/button.md.scss
+++ b/src/components/button/button.md.scss
@@ -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;
}
diff --git a/src/components/button/button.wp.scss b/src/components/button/button.wp.scss
index 1aaa40bf43..334ee0cc11 100644
--- a/src/components/button/button.wp.scss
+++ b/src/components/button/button.wp.scss
@@ -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;
}
diff --git a/src/components/button/test/fab/app-module.ts b/src/components/button/test/fab/app-module.ts
deleted file mode 100644
index 0bf1cc361b..0000000000
--- a/src/components/button/test/fab/app-module.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import { Component, NgModule } from '@angular/core';
-import { IonicApp, IonicModule } from '../../../..';
-
-
-@Component({
- templateUrl: 'main.html'
-})
-export class E2EPage {}
-
-@Component({
- template: ''
-})
-export class E2EApp {
- rootPage = E2EPage;
-}
-
-@NgModule({
- declarations: [
- E2EApp,
- E2EPage
- ],
- imports: [
- IonicModule.forRoot(E2EApp)
- ],
- bootstrap: [IonicApp],
- entryComponents: [
- E2EPage
- ]
-})
-export class AppModule {}
diff --git a/src/components/button/test/fab/e2e.ts b/src/components/button/test/fab/e2e.ts
deleted file mode 100644
index 8b13789179..0000000000
--- a/src/components/button/test/fab/e2e.ts
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/src/components/button/test/fab/main.html b/src/components/button/test/fab/main.html
deleted file mode 100644
index b2f30c33e9..0000000000
--- a/src/components/button/test/fab/main.html
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/components/content/content.scss b/src/components/content/content.scss
index 3cdd0cd3f9..dc7f5040d2 100644
--- a/src/components/content/content.scss
+++ b/src/components/content/content.scss
@@ -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);
-}
diff --git a/src/components/content/content.ts b/src/components/content/content.ts
index e9e023f801..77d97f3419 100644
--- a/src/components/content/content.ts
+++ b/src/components/content/content.ts
@@ -103,10 +103,12 @@ import { isTrueProperty } from '../../util/util';
@Component({
selector: 'ion-content',
template:
+ '
' +
+ '' +
+ '
' +
'' +
'' +
'
' +
- '' +
'',
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' : '');
+}
diff --git a/src/components/fab/fab.ios.scss b/src/components/fab/fab.ios.scss
new file mode 100755
index 0000000000..1fed6c3766
--- /dev/null
+++ b/src/components/fab/fab.ios.scss
@@ -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;
+ }
+}
+
diff --git a/src/components/fab/fab.md.scss b/src/components/fab/fab.md.scss
new file mode 100755
index 0000000000..beb6c3634b
--- /dev/null
+++ b/src/components/fab/fab.md.scss
@@ -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;
+ }
+}
+
diff --git a/src/components/fab/fab.scss b/src/components/fab/fab.scss
new file mode 100755
index 0000000000..df4dc5a334
--- /dev/null
+++ b/src/components/fab/fab.scss
@@ -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);
+}
diff --git a/src/components/fab/fab.ts b/src/components/fab/fab.ts
new file mode 100755
index 0000000000..b2883f11f6
--- /dev/null
+++ b/src/components/fab/fab.ts
@@ -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:
+ '' +
+ '' +
+ '' +
+ '' +
+ '',
+ 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;
+
+ /**
+ * @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: ''
+})
+export class Fab {
+ _events: UIEventManager = new UIEventManager();
+ _listsActive: boolean = false;
+
+ @ContentChild(FabButton) _mainButton: FabButton;
+ @ContentChildren(FabList) _fabLists: QueryList;
+
+ 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();
+ }
+}
diff --git a/src/components/fab/fab.wp.scss b/src/components/fab/fab.wp.scss
new file mode 100755
index 0000000000..2bff374db1
--- /dev/null
+++ b/src/components/fab/fab.wp.scss
@@ -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;
+ }
+}
diff --git a/src/components/fab/test/basic/app-module.ts b/src/components/fab/test/basic/app-module.ts
new file mode 100755
index 0000000000..a3d3921d85
--- /dev/null
+++ b/src/components/fab/test/basic/app-module.ts
@@ -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: ''
+})
+export class E2EApp {
+ root: any = E2EPage;
+}
+
+@NgModule({
+ declarations: [
+ E2EApp,
+ E2EPage
+ ],
+ imports: [
+ IonicModule.forRoot(E2EApp)
+ ],
+ bootstrap: [IonicApp],
+ entryComponents: [
+ E2EPage
+ ]
+})
+export class AppModule {}
diff --git a/src/components/fab/test/basic/main.html b/src/components/fab/test/basic/main.html
new file mode 100755
index 0000000000..4e80f717bb
--- /dev/null
+++ b/src/components/fab/test/basic/main.html
@@ -0,0 +1,73 @@
+
+
+ Floating Action Buttons
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/fab/test/fab.spec.ts b/src/components/fab/test/fab.spec.ts
new file mode 100755
index 0000000000..e69de29bb2
diff --git a/src/components/nav/test/basic/app-module.ts b/src/components/nav/test/basic/app-module.ts
index 08f1367751..75fe264b63 100644
--- a/src/components/nav/test/basic/app-module.ts
+++ b/src/components/nav/test/basic/app-module.ts
@@ -290,10 +290,9 @@ export class FullPage {
-
-
-
-
+
+
+
diff --git a/src/directives.ts b/src/directives.ts
index b047ab2085..d94d2d3ede 100644
--- a/src/directives.ts
+++ b/src/directives.ts
@@ -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,
diff --git a/src/themes/ionic.components.scss b/src/themes/ionic.components.scss
index e089b4f360..23a9ac8185 100644
--- a/src/themes/ionic.components.scss
+++ b/src/themes/ionic.components.scss
@@ -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";
diff --git a/src/themes/ionic.globals.scss b/src/themes/ionic.globals.scss
index 2d6a2a8aa5..3a2fbbcc01 100644
--- a/src/themes/ionic.globals.scss
+++ b/src/themes/ionic.globals.scss
@@ -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;
diff --git a/src/util/ui-event-manager.ts b/src/util/ui-event-manager.ts
index ac9a80914c..0b8305c856 100644
--- a/src/util/ui-event-manager.ts
+++ b/src/util/ui-event-manager.ts
@@ -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;
}