This commit is contained in:
Adam Bradley
2015-12-30 15:03:05 -06:00
parent c136d2143a
commit 2c169ff508
11 changed files with 372 additions and 379 deletions

View File

@@ -1,33 +1,79 @@
import {Component, Injectable, Renderer} from 'angular2/core';
import {Component, Renderer} from 'angular2/core';
import {NgFor, NgIf} from 'angular2/common';
import {NavParams} from '../nav/nav-controller';
import {ViewController} from '../nav/view-controller';
import {Config} from '../../config/config';
import {Icon} from '../icon/icon';
import {Animation} from '../../animations/animation';
import {NavParams} from '../nav/nav-controller';
import {extend} from '../../util/util';
/**
* @name ActionSheet
* @description
* The Action Sheet is a slide-up dialog that lets the user choose from a set
* of options. Dangerous options are made obvious. There are easy ways to
* cancel out of the action sheet, such as tapping the backdrop or even hitting
* escape key on desktop.
*
* @usage
* ```ts
* ```
*
* @demo /docs/v2/demos/action-sheet/
* @see {@link /docs/v2/components#action-sheets ActionSheet Component Docs}
*/
export class ActionSheet extends ViewController {
constructor(data={}) {
data.buttons = data.buttons || [];
super(ActionSheetCmp, data);
this.viewType = 'action-sheet';
}
getTransitionName(direction) {
let key = 'actionSheet' + (direction === 'back' ? 'Leave' : 'Enter');
return this._nav && this._nav.config.get(key);
}
setTitle(title) {
this._data.title = title;
}
setSubTitle(subTitle) {
this._data.subTitle = subTitle;
}
addButton(button) {
this._data.buttons.push(button);
}
static create(data={}) {
return new ActionSheet(data);
}
}
@Component({
selector: 'ion-action-sheet',
template:
'<div (click)="cancel()" tappable disable-activated class="backdrop"></div>' +
'<div (click)="dismiss()" tappable disable-activated class="backdrop" role="presentation"></div>' +
'<div class="action-sheet-wrapper">' +
'<div class="action-sheet-container">' +
'<div class="action-sheet-group action-sheet-options">' +
'<div class="action-sheet-title" *ngIf="d.titleText">{{d.titleText}}</div>' +
'<button (click)="buttonClicked(i)" *ngFor="#b of d.buttons; #i=index" class="action-sheet-button action-sheet-option disable-hover">' +
'<div class="action-sheet-title" *ngIf="d.title">{{d.title}}</div>' +
'<div class="action-sheet-sub-title" *ngIf="d.subTitle">{{d.subTitle}}</div>' +
'<button (click)="click(b)" *ngFor="#b of d.buttons" class="action-sheet-button action-sheet-option disable-hover" [ngClass]="b.cssClass">' +
'<icon [name]="b.icon" *ngIf="b.icon" class="action-sheet-icon"></icon> ' +
'{{b.text}}' +
'</button>' +
'<button *ngIf="d.destructiveText" (click)="destructive()" class="action-sheet-button action-sheet-destructive disable-hover">' +
'<icon [name]="d.destructiveIcon" *ngIf="d.destructiveIcon" class="action-sheet-icon"></icon> ' +
'{{d.destructiveText}}' +
'</button>' +
'</div>' +
'<div class="action-sheet-group" *ngIf="d.cancelText">' +
'<button (click)="cancel()" class="action-sheet-button action-sheet-cancel disable-hover">' +
'<icon [name]="d.cancelIcon" *ngIf="d.cancelIcon" class="action-sheet-icon"></icon> ' +
'{{d.cancelText}}' +
'<div class="action-sheet-group" *ngIf="d.cancelButton">' +
'<button (click)="click(d.cancelButton)" class="action-sheet-button action-sheet-cancel disable-hover" [ngClass]="d.cancelButton.cssClass">' +
'<icon [name]="d.cancelButton.icon" *ngIf="d.cancelButton.icon" class="action-sheet-icon"></icon> ' +
'{{d.cancelButton.text}}' +
'</button>' +
'</div>' +
'</div>' +
@@ -39,7 +85,10 @@ import {extend} from '../../util/util';
})
class ActionSheetCmp {
constructor(params: NavParams, renderer: Renderer) {
constructor(
private _viewCtrl: ViewController,
params: NavParams, renderer: Renderer
) {
this.d = params.data;
if (this.d.cssClass) {
@@ -47,121 +96,64 @@ class ActionSheetCmp {
}
}
cancel() {
this.d.cancel && this.d.cancel();
return this.close();
}
click(button) {
let shouldDismiss = true;
destructive() {
if (this.d.destructiveButtonClicked()) {
return this.close();
if (button.handler) {
// a handler has been provided, execute it
if (button.handler() === false) {
// if the return value of the handler is false then do not dismiss
shouldDismiss = false;
}
}
if (shouldDismiss) {
this.dismiss();
}
}
buttonClicked(index) {
if (this.d.buttonClicked(index)) {
return this.close();
}
dismiss() {
this._viewCtrl.dismiss(this);
}
onPageLoaded() {
// normalize the data
let buttons = [];
this.d.buttons.forEach(button => {
if (typeof button === 'string') {
button = { text: button };
}
if (button.style === 'cancel') {
this.d.cancelButton = button;
} else {
if (button.style === 'destructive') {
button.cssClass = (button.cssClass + ' ' || '') + 'action-sheet-destructive';
}
buttons.push(button);
}
});
this.d.buttons = buttons;
let self = this;
self.keyUp = function(ev) {
if (ev.keyCode === 27) {
console.debug('actionsheet escape');
self.dismiss();
}
};
document.addEventListener('keyup', this.keyUp);
}
onPageDidLeave() {
document.removeEventListener('keyup', this.keyUp);
}
}
/**
* @name ActionSheet
* @description
* The Action Sheet is a slide-up pane that lets the user choose from a set of options. Dangerous options are made obvious.
* There are easy ways to cancel out of the action sheet, such as tapping the backdrop or even hitting escape on the keyboard for desktop testing.
*
* @usage
* ```ts
* openMenu() {
*
* this.actionSheet.open({
* buttons: [
* { text: 'Share This' },
* { text: 'Move' }
* ],
* destructiveText: 'Delete',
* titleText: 'Modify your album',
* cancelText: 'Cancel',
* cancel: function() {
* console.log('Canceled');
* },
* destructiveButtonClicked: () => {
* console.log('Destructive clicked');
* },
* buttonClicked: function(index) {
* console.log('Button clicked', index);
* if(index == 1) { return false; }
* return true;
* }
*
* }).then(actionSheetRef => {
* this.actionSheetRef = actionSheetRef;
* });
*
* }
* ```
*
* @demo /docs/v2/demos/action-sheet/
* @see {@link /docs/v2/components#action-sheets ActionSheet Component Docs}
*/
@Injectable()
export class ActionSheet {
constructor(config: Config) {
//this.ctrl = ctrl;
this.config = config;
}
/**
* Create and open a new Action Sheet. This is the
* public API, and most often you will only use ActionSheet.open()
*
* @param {Object} [opts={}] An object containing optional settings.
* - `[Object]` `buttons` Which buttons to show. Each button is an object with a `text` field.
* - `{string}` `titleText` The title to show on the action sheet.
* - `{string=}` `cancelText` the text for a 'cancel' button on the action sheet.
* - `{string=}` `destructiveText` The text for a 'danger' on the action sheet.
* - `{function=}` `cancel` Called if the cancel button is pressed, the backdrop is tapped or
* the hardware back button is pressed.
* - `{function=}` `buttonClicked` Called when one of the non-destructive buttons is clicked,
* with the index of the button that was clicked and the button object. Return true to close
* the action sheet, or false to keep it opened.
* - `{function=}` `destructiveButtonClicked` Called when the destructive button is clicked.
* Return true to close the action sheet, or false to keep it opened.
* - `{String}` `enterAnimation` The class used to animate an actionSheet that is entering.
* - `{String}` `leaveAnimation` The class used to animate an actionSheet that is leaving.
* @return {Promise} Promise that resolves when the action sheet is open.
*/
open(opts={}) {
opts = extend({
pageType: OVERLAY_TYPE,
enterAnimation: this.config.get('actionSheetEnter'),
leaveAnimation: this.config.get('actionSheetLeave'),
cancelIcon: this.config.get('actionSheetCancelIcon'),
destructiveIcon: this.config.get('actionSheetDestructiveIcon')
}, opts);
return this.ctrl.open(ActionSheetCmp, opts, opts);
}
/**
* Retrieves an actionSheet instance.
*
* @param {String} [handle] The handle used to open the instance to be retrieved.
* @returns {ActionSheet} An actionSheet instance.
*/
get(handle) {
if (handle) {
return this.ctrl.getByHandle(handle);
}
return this.ctrl.getByType(OVERLAY_TYPE);
}
}
const OVERLAY_TYPE = 'action-sheet';
class ActionSheetSlideIn extends Animation {

View File

@@ -1,41 +1,66 @@
import {App, ActionSheet} from 'ionic/ionic';
import {App, Page, ActionSheet, NavController} from 'ionic/ionic';
@App({
@Page({
templateUrl: 'main.html'
})
class E2EApp {
class E2EPage {
constructor(actionSheet: ActionSheet) {
this.actionSheet = actionSheet;
constructor(nav: NavController) {
this.nav = nav;
}
openActionSheet() {
openActionSheet(ev) {
this.result = '';
this.actionSheet.open({
let actionSheet = ActionSheet.create({
buttons: [
{ text: 'Share This' },
{ text: 'Move' }
],
destructiveText: 'Delete',
titleText: 'Modify your album',
cancelText: 'Cancel',
cancel: function() {
console.log('Canceled');
},
destructiveButtonClicked: () => {
console.log('Destructive clicked');
},
buttonClicked: function(index) {
console.log('Button clicked', index);
if(index == 1) { return false; }
return true;
}
{
text: 'Cancel',
style: 'cancel', // will always sort to be on the bottom
handler: () => {
console.log('cancel this clicked');
this.result = 'Canceled';
}
},
{
text: 'Archive',
handler: () => {
console.log('Archive clicked');
this.result = 'Archived';
}
},
{
text: 'No close',
handler: () => {
console.log('do not close clicked');
}).then(actionSheetRef => {
this.actionSheetRef = actionSheetRef;
// returning false does not allow the actionsheet to be closed
return false;
}
},
{
text: 'Destructive',
style: 'destructive',
handler: () => {
console.log('Destructive clicked');
this.result = 'Destructive';
}
}
]
});
this.nav.present(actionSheet);
}
}
@App({
template: '<ion-nav [root]="root"></ion-nav>'
})
class E2EApp {
constructor() {
this.root = E2EPage;
}
}

View File

@@ -1,4 +1,12 @@
<ion-navbar *navbar>
<ion-title>Action Sheet</ion-title>
</ion-navbar>
<ion-content padding>
<button class="e2eOpenActionSheet" (click)="openActionSheet()">Open Action Sheet</button>
<pre>
Result: {{result}}
</pre>
</ion-content>