mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-19 11:41:20 +08:00
Action Menu Improvements
This commit is contained in:
@ -1,4 +1,4 @@
|
|||||||
import {DynamicComponentLoader, ComponentLaoder, ElementRef, ComponentRef, onDestroy, DomRenderer} from 'angular2/angular2';
|
import {NgIf, NgFor, DynamicComponentLoader, ComponentLaoder, ElementRef, ComponentRef, onDestroy, DomRenderer} from 'angular2/angular2';
|
||||||
import {bind, Injector} from 'angular2/di';
|
import {bind, Injector} from 'angular2/di';
|
||||||
import {Promise} from 'angular2/src/facade/async';
|
import {Promise} from 'angular2/src/facade/async';
|
||||||
import {isPresent, Type} from 'angular2/src/facade/lang';
|
import {isPresent, Type} from 'angular2/src/facade/lang';
|
||||||
@ -11,6 +11,7 @@ import {Item, Icon} from 'ionic/ionic'
|
|||||||
import {Ionic} from 'ionic/components/app/app'
|
import {Ionic} from 'ionic/components/app/app'
|
||||||
import {IonicComponent} from 'ionic/config/component'
|
import {IonicComponent} from 'ionic/config/component'
|
||||||
import {raf, ready} from 'ionic/util/dom'
|
import {raf, ready} from 'ionic/util/dom'
|
||||||
|
import * as util from 'ionic/util'
|
||||||
|
|
||||||
import {Animation} from 'ionic/animations/animation';
|
import {Animation} from 'ionic/animations/animation';
|
||||||
|
|
||||||
@ -20,51 +21,71 @@ import {Animation} from 'ionic/animations/animation';
|
|||||||
})
|
})
|
||||||
@View({
|
@View({
|
||||||
template: `
|
template: `
|
||||||
<div class="overlay-backdrop"></div>
|
<div class="action-menu-backdrop">
|
||||||
<div class="overlay-container">
|
<div class="action-menu-wrapper">
|
||||||
<div class="action-menu-container">
|
<div class="action-menu">
|
||||||
|
<div class="action-menu-group action-menu-options">
|
||||||
<div class="list-header">Action Menu List Header</div>
|
<div class="action-menu-title" *ng-if="titleText">{{titleText}}</div>
|
||||||
<div class="list">
|
<button (click)="buttonClicked(index)" *ng-for="#b of buttons; #index = index" class="button action-menu-option">{{b.text}}</button>
|
||||||
<button ion-item class="item">
|
<button *ng-if="destructiveText" (click)="destructiveButtonClicked()" class="button destructive action-menu-destructive">{{destructiveText}}</button>
|
||||||
Button 1
|
</div>
|
||||||
</button>
|
<div class="action-menu-group action-menu-cancel" *ng-if="cancelText">
|
||||||
<button ion-item class="item">
|
<button class="button" (click)="cancel()">{{cancelText}}</button>
|
||||||
Button 2
|
</div>
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="list-header">Action Menu Label</div>
|
|
||||||
<div class="list">
|
|
||||||
<button ion-item class="item">Button 1</button>
|
|
||||||
<button ion-item class="item">Button 2</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="list">
|
|
||||||
<button ion-item class="item">Button 1</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>`,
|
</div>`,
|
||||||
directives: [Item,Icon]
|
directives: [Item,Icon, NgIf, NgFor]
|
||||||
})
|
})
|
||||||
export class ActionMenu {
|
export class ActionMenu {
|
||||||
constructor(elementRef: ElementRef) {
|
constructor(elementRef: ElementRef) {
|
||||||
this.domElement = elementRef.domElement
|
this.domElement = elementRef.domElement
|
||||||
this.config = ActionMenu.config.invoke(this)
|
this.config = ActionMenu.config.invoke(this)
|
||||||
|
|
||||||
|
this.wrapperEl = this.domElement.querySelector('.action-menu-wrapper');
|
||||||
|
|
||||||
console.log('ActionMenu: Component Created', this.domElement);
|
console.log('ActionMenu: Component Created', this.domElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
var backdrop = this.domElement.children[0].classList.remove('active');
|
||||||
|
var slideOut = Animation.create(this.wrapperEl, 'slide-out');
|
||||||
|
return slideOut.play();
|
||||||
|
}
|
||||||
|
|
||||||
|
open() {
|
||||||
|
var backdrop = this.domElement.children[0].classList.add('active');
|
||||||
|
var slideIn = Animation.create(this.wrapperEl, 'slide-in');
|
||||||
|
return slideIn.play();
|
||||||
|
}
|
||||||
|
|
||||||
|
setOptions(opts) {
|
||||||
|
util.extend(this, opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overridden by options
|
||||||
|
destructiveButtonClicked() {}
|
||||||
|
buttonClicked(index) {}
|
||||||
|
cancel() {}
|
||||||
|
|
||||||
static open(opts) {
|
static open(opts) {
|
||||||
console.log('Opening menu', opts, Ionic);
|
console.log('Opening menu', opts, Ionic);
|
||||||
|
|
||||||
ActionMenu._inject();
|
var promise = new Promise(resolve => {
|
||||||
|
ActionMenu._inject().then((actionMenu) => {
|
||||||
|
actionMenu.setOptions(opts);
|
||||||
|
setTimeout(() => {
|
||||||
|
actionMenu.open();
|
||||||
|
})
|
||||||
|
resolve(actionMenu);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _inject() {
|
static _inject() {
|
||||||
Ionic.appendToRoot(ActionMenu).then(() => {
|
return Ionic.appendToRoot(ActionMenu);
|
||||||
console.log('Action Menu appended');
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,16 @@ $action-menu-max-width: 520px !default;
|
|||||||
$action-menu-background-color: rgba(243,243,243,.95) !default;
|
$action-menu-background-color: rgba(243,243,243,.95) !default;
|
||||||
$action-menu-button-text-color: #007aff !default;
|
$action-menu-button-text-color: #007aff !default;
|
||||||
|
|
||||||
|
$sheet-margin: 8px !default;
|
||||||
|
$sheet-border-radius: 4px !default;
|
||||||
|
|
||||||
|
$sheet-options-bg-color: #f1f2f3 !default;
|
||||||
|
$sheet-options-bg-active-color: #e4e5e7 !default;
|
||||||
|
$sheet-options-text-color: #007aff !default;
|
||||||
|
$sheet-options-border-color: #d1d3d6 !default;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
.action-menu-container {
|
.action-menu-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: $z-index-action-menu;
|
z-index: $z-index-action-menu;
|
||||||
@ -24,4 +33,171 @@ $action-menu-button-text-color: #007aff !default;
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
.action-menu-backdrop {
|
||||||
|
transition: background-color 150ms ease-in-out;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: $z-index-action-menu;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(0,0,0,0);
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background-color: rgba(0,0,0,0.4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-menu-wrapper {
|
||||||
|
//transform: translate3d(0, 100%, 0);
|
||||||
|
//transition: all cubic-bezier(.36, .66, .04, 1) 500ms;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 500px;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-menu-up {
|
||||||
|
transform: translate3d(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-menu {
|
||||||
|
margin-left: $sheet-margin;
|
||||||
|
margin-right: $sheet-margin;
|
||||||
|
width: auto;
|
||||||
|
z-index: $z-index-action-menu;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.button {
|
||||||
|
display: block;
|
||||||
|
padding: 1px;
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 0;
|
||||||
|
border-color: $sheet-options-border-color;
|
||||||
|
background-color: transparent;
|
||||||
|
|
||||||
|
color: $sheet-options-text-color;
|
||||||
|
font-size: 21px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: $sheet-options-text-color;
|
||||||
|
}
|
||||||
|
&.destructive {
|
||||||
|
color: #ff3b30;
|
||||||
|
&:hover {
|
||||||
|
color: #ff3b30;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.active, .button.activated {
|
||||||
|
box-shadow: none;
|
||||||
|
border-color: $sheet-options-border-color;
|
||||||
|
color: $sheet-options-text-color;
|
||||||
|
background: $sheet-options-bg-active-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-menu-has-icons .icon {
|
||||||
|
position: absolute;
|
||||||
|
left: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-menu-title {
|
||||||
|
padding: $sheet-margin * 2;
|
||||||
|
color: #8f8f8f;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-menu-group {
|
||||||
|
margin-bottom: $sheet-margin;
|
||||||
|
border-radius: $sheet-border-radius;
|
||||||
|
background-color: #fff;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.button {
|
||||||
|
border-width: 1px 0px 0px 0px;
|
||||||
|
}
|
||||||
|
.button:first-child:last-child {
|
||||||
|
border-width: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-menu-options {
|
||||||
|
background: $sheet-options-bg-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-menu-cancel {
|
||||||
|
.button {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-menu-open {
|
||||||
|
pointer-events: none;
|
||||||
|
|
||||||
|
&.modal-open .modal {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-menu-backdrop {
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.platform-android {
|
||||||
|
|
||||||
|
.action-menu-backdrop.active {
|
||||||
|
background-color: rgba(0,0,0,0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-menu {
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
.action-menu-title,
|
||||||
|
.button {
|
||||||
|
text-align: left;
|
||||||
|
border-color: transparent;
|
||||||
|
font-size: 16px;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-menu-title {
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 16px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.active,
|
||||||
|
.button.activated {
|
||||||
|
background: #e8e8e8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-menu-group {
|
||||||
|
margin: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
background-color: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-menu-cancel {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-menu-has-icons {
|
||||||
|
|
||||||
|
.button {
|
||||||
|
padding-left: 56px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -19,8 +19,25 @@ class IonicApp {
|
|||||||
|
|
||||||
openMenu() {
|
openMenu() {
|
||||||
console.log('Opening ActionMenu')
|
console.log('Opening ActionMenu')
|
||||||
|
|
||||||
ActionMenu.open({
|
ActionMenu.open({
|
||||||
title: 'Do you really want to?'
|
buttons: [
|
||||||
|
{ text: '<b>Share</b> This' },
|
||||||
|
{ text: 'Move' }
|
||||||
|
],
|
||||||
|
destructiveText: 'Delete',
|
||||||
|
titleText: 'Modify your album',
|
||||||
|
cancelText: 'Cancel',
|
||||||
|
cancel: function() {
|
||||||
|
// add cancel code..
|
||||||
|
console.log('Canceled');
|
||||||
|
},
|
||||||
|
buttonClicked: function(index) {
|
||||||
|
console.log('Button clicked', index);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}).then(actionMenu => {
|
||||||
|
this.actionMenu = actionMenu;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,9 @@ class IonicAppRoot {
|
|||||||
|
|
||||||
document.body.querySelector('ion-app').appendChild(newEl);
|
document.body.querySelector('ion-app').appendChild(newEl);
|
||||||
|
|
||||||
resolve(newEl);
|
console.log('Injected and created', containerRef);
|
||||||
|
|
||||||
|
resolve(containerRef.instance, containerRef.location);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user