mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-20 20:33:32 +08:00
feat(fab): update floating action buttons
This commit is contained in:

committed by
Adam Bradley

parent
83d973b1a8
commit
490a06dd3e
@ -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;
|
|
||||||
}
|
|
@ -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
|
// Generate iOS Button Colors
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
@ -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;
|
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] {
|
.button-md [icon-only] {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
@ -309,14 +309,6 @@ $button-wp-fab-border-radius: 50% !default;
|
|||||||
border-radius: $button-wp-round-border-radius;
|
border-radius: $button-wp-round-border-radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Windows FAB Button
|
|
||||||
// --------------------------------------------------
|
|
||||||
|
|
||||||
.button-fab-wp {
|
|
||||||
border-radius: $button-wp-fab-border-radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-wp [icon-only] {
|
.button-wp [icon-only] {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
@ -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 {}
|
|
@ -1 +0,0 @@
|
|||||||
|
|
@ -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>
|
|
@ -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
|
// Content Padding
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
||||||
@ -151,15 +172,3 @@ ion-content.js-scroll > .scroll-content {
|
|||||||
margin-left: $content-margin;
|
margin-left: $content-margin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Content Fixed
|
|
||||||
// --------------------------------------------------
|
|
||||||
|
|
||||||
ion-fixed {
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
z-index: $z-index-fixed-content;
|
|
||||||
|
|
||||||
transform: translateZ(0);
|
|
||||||
}
|
|
||||||
|
@ -103,10 +103,12 @@ import { isTrueProperty } from '../../util/util';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'ion-content',
|
selector: 'ion-content',
|
||||||
template:
|
template:
|
||||||
|
'<div class="fixed-content">' +
|
||||||
|
'<ng-content select="[ion-fixed],ion-fab"></ng-content>' +
|
||||||
|
'</div>' +
|
||||||
'<div class="scroll-content">' +
|
'<div class="scroll-content">' +
|
||||||
'<ng-content></ng-content>' +
|
'<ng-content></ng-content>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<ng-content select="ion-fixed"></ng-content>' +
|
|
||||||
'<ng-content select="ion-refresher"></ng-content>',
|
'<ng-content select="ion-refresher"></ng-content>',
|
||||||
host: {
|
host: {
|
||||||
'[class.statusbar-padding]': '_sbPadding'
|
'[class.statusbar-padding]': '_sbPadding'
|
||||||
@ -136,6 +138,11 @@ export class Content extends Ion {
|
|||||||
*/
|
*/
|
||||||
_scrollEle: HTMLElement;
|
_scrollEle: HTMLElement;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_fixedEle: HTMLElement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A number representing how many pixels the top of the content has been
|
* A number representing how many pixels the top of the content has been
|
||||||
* adjusted, which could be by either padding or margin.
|
* adjusted, which could be by either padding or margin.
|
||||||
@ -175,7 +182,8 @@ export class Content extends Ion {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ngOnInit() {
|
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._zone.runOutsideAngular(() => {
|
||||||
this._scroll = new ScrollView(this._scrollEle);
|
this._scroll = new ScrollView(this._scrollEle);
|
||||||
@ -530,63 +538,61 @@ export class Content extends Ion {
|
|||||||
* DOM WRITE
|
* DOM WRITE
|
||||||
*/
|
*/
|
||||||
writeDimensions() {
|
writeDimensions() {
|
||||||
let newVal: number;
|
let scrollEle = this._scrollEle as any;
|
||||||
let scrollEle = this._scrollEle;
|
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) {
|
if (this._fullscreen) {
|
||||||
// adjust the content with padding, allowing content to scroll under headers/footers
|
// 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)
|
// 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
|
// 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
|
// 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;
|
// Only update top margin if value changed
|
||||||
if (this._tabsPlacement === 'top') {
|
if (contentTop !== this.contentTop) {
|
||||||
newVal += this._tabbarHeight;
|
scrollEle.style[topProperty] = cssFormat(contentTop);
|
||||||
}
|
fixedEle.style.marginTop = cssFormat(fixedTop);
|
||||||
if (newVal !== this.contentTop) {
|
this.contentTop = contentTop;
|
||||||
scrollEle.style.paddingTop = (newVal > 0 ? newVal + 'px' : '');
|
}
|
||||||
this.contentTop = newVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
newVal = this._footerHeight + this._paddingBottom;
|
// Only update bottom margin if value changed
|
||||||
if (this._tabsPlacement === 'bottom') {
|
if (contentBottom !== this.contentBottom) {
|
||||||
newVal += this._tabbarHeight;
|
scrollEle.style[bottomProperty] = cssFormat(contentBottom);
|
||||||
|
fixedEle.style.marginBottom = cssFormat(fixedBottom);
|
||||||
if (newVal > 0 && this._footerEle) {
|
this.contentBottom = contentBottom;
|
||||||
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';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -606,3 +612,7 @@ export class Content extends Ion {
|
|||||||
function parsePxUnit(val: string): number {
|
function parsePxUnit(val: string): number {
|
||||||
return (val.indexOf('px') > 0) ? parseInt(val, 10) : 0;
|
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
32
src/components/fab/fab.ios.scss
Executable 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
48
src/components/fab/fab.md.scss
Executable 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
202
src/components/fab/fab.scss
Executable 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
168
src/components/fab/fab.ts
Executable 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
32
src/components/fab/fab.wp.scss
Executable 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;
|
||||||
|
}
|
||||||
|
}
|
45
src/components/fab/test/basic/app-module.ts
Executable file
45
src/components/fab/test/basic/app-module.ts
Executable 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 {}
|
73
src/components/fab/test/basic/main.html
Executable file
73
src/components/fab/test/basic/main.html
Executable 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>
|
0
src/components/fab/test/fab.spec.ts
Executable file
0
src/components/fab/test/fab.spec.ts
Executable 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="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>
|
<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>
|
<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>
|
<button ion-button ion-fixed (click)="presentAlert()">fixed button (alert)</button>
|
||||||
</ion-fixed>
|
<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-fixed style="pointer-events: none; top:0; bottom:0; right:0; width:50%; background: rgba(0,0,0,0.5);"></ion-fixed>
|
|
||||||
</ion-content>
|
</ion-content>
|
||||||
<ion-footer>
|
<ion-footer>
|
||||||
<ion-toolbar no-border-bottom>
|
<ion-toolbar no-border-bottom>
|
||||||
|
@ -11,6 +11,7 @@ import { Checkbox } from './components/checkbox/checkbox';
|
|||||||
import { Chip } from './components/chip/chip';
|
import { Chip } from './components/chip/chip';
|
||||||
import { Content } from './components/content/content';
|
import { Content } from './components/content/content';
|
||||||
import { DateTime } from './components/datetime/datetime';
|
import { DateTime } from './components/datetime/datetime';
|
||||||
|
import { Fab, FabButton, FabList } from './components/fab/fab';
|
||||||
import { Fixed } from './components/fixed/fixed';
|
import { Fixed } from './components/fixed/fixed';
|
||||||
import { Grid, Row, Col } from './components/grid/grid';
|
import { Grid, Row, Col } from './components/grid/grid';
|
||||||
import { Icon } from './components/icon/icon';
|
import { Icon } from './components/icon/icon';
|
||||||
@ -79,6 +80,7 @@ export { Checkbox } from './components/checkbox/checkbox';
|
|||||||
export { Chip } from './components/chip/chip';
|
export { Chip } from './components/chip/chip';
|
||||||
export { Content } from './components/content/content';
|
export { Content } from './components/content/content';
|
||||||
export { DateTime } from './components/datetime/datetime';
|
export { DateTime } from './components/datetime/datetime';
|
||||||
|
export { Fab, FabButton, FabList } from './components/fab/fab';
|
||||||
export { Fixed } from './components/fixed/fixed';
|
export { Fixed } from './components/fixed/fixed';
|
||||||
export { Grid, Row, Col } from './components/grid/grid';
|
export { Grid, Row, Col } from './components/grid/grid';
|
||||||
export { Icon } from './components/icon/icon';
|
export { Icon } from './components/icon/icon';
|
||||||
@ -171,6 +173,9 @@ export const IONIC_DIRECTIVES: any[] = [
|
|||||||
Col,
|
Col,
|
||||||
Content,
|
Content,
|
||||||
DateTime,
|
DateTime,
|
||||||
|
Fab,
|
||||||
|
FabButton,
|
||||||
|
FabList,
|
||||||
Fixed,
|
Fixed,
|
||||||
Footer,
|
Footer,
|
||||||
Grid,
|
Grid,
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
|
|
||||||
@import
|
@import
|
||||||
"../components/button/button",
|
"../components/button/button",
|
||||||
"../components/button/button-fab",
|
|
||||||
"../components/button/button-icon",
|
"../components/button/button-icon",
|
||||||
"../components/button/button.ios",
|
"../components/button/button.ios",
|
||||||
"../components/button/button.md",
|
"../components/button/button.md",
|
||||||
@ -66,6 +65,12 @@
|
|||||||
"../components/datetime/datetime.md",
|
"../components/datetime/datetime.md",
|
||||||
"../components/datetime/datetime.wp";
|
"../components/datetime/datetime.wp";
|
||||||
|
|
||||||
|
@import
|
||||||
|
"../components/fab/fab",
|
||||||
|
"../components/fab/fab.ios",
|
||||||
|
"../components/fab/fab.md",
|
||||||
|
"../components/fab/fab.wp";
|
||||||
|
|
||||||
@import
|
@import
|
||||||
"../components/grid/grid";
|
"../components/grid/grid";
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ $z-index-menu-backdrop: 79;
|
|||||||
$z-index-overlay: 1000;
|
$z-index-overlay: 1000;
|
||||||
$z-index-click-block: 9999;
|
$z-index-click-block: 9999;
|
||||||
|
|
||||||
$z-index-fixed-content: 2;
|
$z-index-fixed-content: 100;
|
||||||
$z-index-scroll-content: 1;
|
$z-index-scroll-content: 1;
|
||||||
$z-index-refresher: 0;
|
$z-index-refresher: 0;
|
||||||
|
|
||||||
|
@ -4,8 +4,8 @@ export interface PointerEventsConfig {
|
|||||||
element?: HTMLElement;
|
element?: HTMLElement;
|
||||||
elementRef?: ElementRef;
|
elementRef?: ElementRef;
|
||||||
pointerDown: (ev: any) => boolean;
|
pointerDown: (ev: any) => boolean;
|
||||||
pointerMove: (ev: any) => void;
|
pointerMove?: (ev: any) => void;
|
||||||
pointerUp: (ev: any) => void;
|
pointerUp?: (ev: any) => void;
|
||||||
nativeOptions?: any;
|
nativeOptions?: any;
|
||||||
zone?: boolean;
|
zone?: boolean;
|
||||||
}
|
}
|
||||||
@ -37,7 +37,6 @@ export class PointerEvents {
|
|||||||
private zone: boolean,
|
private zone: boolean,
|
||||||
private option: any
|
private option: any
|
||||||
) {
|
) {
|
||||||
|
|
||||||
this.bindTouchEnd = this.handleTouchEnd.bind(this);
|
this.bindTouchEnd = this.handleTouchEnd.bind(this);
|
||||||
this.bindMouseUp = this.handleMouseUp.bind(this);
|
this.bindMouseUp = this.handleMouseUp.bind(this);
|
||||||
|
|
||||||
@ -50,7 +49,7 @@ export class PointerEvents {
|
|||||||
if (!this.pointerDown(ev)) {
|
if (!this.pointerDown(ev)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!this.rmTouchMove) {
|
if (!this.rmTouchMove && this.pointerMove) {
|
||||||
this.rmTouchMove = listenEvent(this.ele, 'touchmove', this.zone, this.option, this.pointerMove);
|
this.rmTouchMove = listenEvent(this.ele, 'touchmove', this.zone, this.option, this.pointerMove);
|
||||||
}
|
}
|
||||||
if (!this.rmTouchEnd) {
|
if (!this.rmTouchEnd) {
|
||||||
@ -69,7 +68,7 @@ export class PointerEvents {
|
|||||||
if (!this.pointerDown(ev)) {
|
if (!this.pointerDown(ev)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!this.rmMouseMove) {
|
if (!this.rmMouseMove && this.pointerMove) {
|
||||||
this.rmMouseMove = listenEvent(document, 'mousemove', this.zone, this.option, this.pointerMove);
|
this.rmMouseMove = listenEvent(document, 'mousemove', this.zone, this.option, this.pointerMove);
|
||||||
}
|
}
|
||||||
if (!this.rmMouseUp) {
|
if (!this.rmMouseUp) {
|
||||||
@ -79,12 +78,12 @@ export class PointerEvents {
|
|||||||
|
|
||||||
private handleTouchEnd(ev: any) {
|
private handleTouchEnd(ev: any) {
|
||||||
this.stopTouch();
|
this.stopTouch();
|
||||||
this.pointerUp(ev);
|
this.pointerUp && this.pointerUp(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleMouseUp(ev: any) {
|
private handleMouseUp(ev: any) {
|
||||||
this.stopMouse();
|
this.stopMouse();
|
||||||
this.pointerUp(ev);
|
this.pointerUp && this.pointerUp(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
private stopTouch() {
|
private stopTouch() {
|
||||||
@ -147,7 +146,7 @@ export class UIEventManager {
|
|||||||
element = config.elementRef.nativeElement;
|
element = config.elementRef.nativeElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!element || !config.pointerDown || !config.pointerMove || !config.pointerUp) {
|
if (!element || !config.pointerDown) {
|
||||||
console.error('PointerEvents config is invalid');
|
console.error('PointerEvents config is invalid');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user