feat(overlay): fire the cancel handler when dismissing from backdrop

Renamed action sheet’s button.style to button.role, and added
button.role to alerts. Pass the button’s role in the dismiss method.
Related #5251
This commit is contained in:
Adam Bradley
2016-01-29 16:11:25 -06:00
parent b472c6cd43
commit 1c618b51eb
6 changed files with 93 additions and 53 deletions

View File

@ -19,16 +19,18 @@ import {ViewController} from '../nav/view-controller';
* hitting the escape key on desktop.
*
* An action sheet is created from an array of `buttons`, with each button
* including properties for its `text`, and optionally a `style` and `handler`.
* including properties for its `text`, and optionally a `handler` and `role`.
* If a handler returns `false` then the action sheet will not be dismissed. An
* action sheet can also optionally have a `title` and a `subTitle`.
*
* A button's `style` property can either be `destructive` or `cancel`. Buttons
* without a style property will have a default style for its platform. Buttons
* with the `cancel` style will always load as the bottom button, no matter where
* A button's `role` property can either be `destructive` or `cancel`. Buttons
* without a role property will have a default look for its platform. Buttons
* with the `cancel` role will always load as the bottom button, no matter where
* it shows up in the array. All other buttons will show up in the order they
* have been added to the `buttons` array. Note: We recommend that `destructive`
* buttons show be the first button in the array, making it the button on top.
* Additionally, if the action sheet is dismissed by tapping the backdrop, then
* it will fire the handler from the button with the cancel role.
*
* Its shorthand is to add all the action sheet's options from within the
* `ActionSheet.create(opts)` first argument. Otherwise the action sheet's
@ -46,7 +48,7 @@ import {ViewController} from '../nav/view-controller';
* buttons: [
* {
* text: 'Destructive',
* style: 'destructive',
* role: 'destructive',
* handler: () => {
* console.log('Destructive clicked');
* }
@ -59,7 +61,7 @@ import {ViewController} from '../nav/view-controller';
* },
* {
* text: 'Cancel',
* style: 'cancel',
* role: 'cancel',
* handler: () => {
* console.log('Cancel clicked');
* }
@ -137,7 +139,7 @@ import {ViewController} from '../nav/view-controller';
@Component({
selector: 'ion-action-sheet',
template:
'<div (click)="dismiss()" tappable disable-activated class="backdrop" role="presentation"></div>' +
'<div (click)="bdClick()" tappable disable-activated class="backdrop" role="presentation"></div>' +
'<div class="action-sheet-wrapper">' +
'<div class="action-sheet-container">' +
'<div class="action-sheet-group">' +
@ -179,28 +181,6 @@ class ActionSheetCmp {
}
}
click(button) {
let shouldDismiss = true;
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) {
setTimeout(() => {
this.dismiss();
}, this._config.get('pageTransitionDelay'));
}
}
dismiss(): Promise<any> {
return this._viewCtrl.dismiss(null);
}
onPageLoaded() {
// normalize the data
let buttons = [];
@ -213,11 +193,24 @@ class ActionSheetCmp {
button.cssClass = '';
}
// deprecated warning
if (button.style === 'cancel') {
console.warn('Alert "style" property has been renamed to "role"');
button.role = 'cancel';
this.d.cancelButton = button;
}
if (button.role === 'cancel') {
this.d.cancelButton = button;
} else {
// deprecated warning
if (button.style === 'destructive') {
button.role = 'destructive';
button.cssClass = (button.cssClass + ' ' || '') + 'action-sheet-destructive';
}
if (button.role === 'destructive') {
button.cssClass = (button.cssClass + ' ' || '') + 'action-sheet-destructive';
}
buttons.push(button);
@ -230,13 +223,44 @@ class ActionSheetCmp {
self.keyUp = function(ev: KeyboardEvent) {
if (ev.keyCode === 27) {
console.debug('actionsheet escape');
self.dismiss();
self.bdClick();
}
};
document.addEventListener('keyup', this.keyUp);
}
click(button, dismissDelay?) {
let shouldDismiss = true;
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) {
setTimeout(() => {
this.dismiss(button.role);
}, dismissDelay || this._config.get('pageTransitionDelay'));
}
}
bdClick() {
if (this.d.cancelButton) {
this.click(this.d.cancelButton, 1);
} else {
this.dismiss('backdrop');
}
}
dismiss(role): Promise<any> {
return this._viewCtrl.dismiss(null, role);
}
onPageDidLeave() {
document.removeEventListener('keyup', this.keyUp);
}

View File

@ -5,10 +5,9 @@ import {App, Page, ActionSheet, NavController} from 'ionic/ionic';
templateUrl: 'main.html'
})
class E2EPage {
result: string = '';
constructor(nav: NavController) {
this.nav = nav;
}
constructor(private nav: NavController) {}
presentActionSheet1() {
this.result = '';
@ -18,7 +17,7 @@ class E2EPage {
buttons: [
{
text: 'Destructive',
style: 'destructive',
role: 'destructive',
handler: () => {
console.log('Destructive clicked');
this.result = 'Destructive';
@ -42,7 +41,7 @@ class E2EPage {
},
{
text: 'Cancel',
style: 'cancel', // will always sort to be on the bottom
role: 'cancel', // will always sort to be on the bottom
handler: () => {
console.log('Cancel clicked');
this.result = 'Canceled';
@ -68,7 +67,7 @@ class E2EPage {
},
{
text: 'Cancel',
style: 'cancel',
role: 'cancel',
handler: () => {
console.log('cancel this clicked');
this.result = 'Canceled';
@ -76,7 +75,7 @@ class E2EPage {
},
{
text: 'Destructive',
style: 'destructive',
role: 'destructive',
handler: () => {
console.log('Destructive clicked');
this.result = 'Destructive';

View File

@ -25,12 +25,17 @@ import {ViewController} from '../nav/view-controller';
* array, from left to right. Note: The right most button (the last one in the
* array) is the main button.
*
* Optionally, a `role` property can be added to a button, such as `cancel`.
* If a `cancel` role is on one of the buttons, then if the alert is dismissed
* by tapping the backdrop, then it will fire the handler from the button
* with a cancel role.
*
* Alerts can also include inputs whos data can be passed back to the app.
* Inputs can be used to prompt users for information.
*
* Its shorthand is to add all the alert's options from within the
* `Alert.create(opts)` first argument. Otherwise the alert's
* instance has methods to add options, such as `setTitle()` or `addButton()`.
* `Alert.create(opts)` first argument. Otherwise the alert's instance
* has methods to add options, such as `setTitle()` or `addButton()`.
*
* @usage
* ```ts
@ -54,6 +59,7 @@ import {ViewController} from '../nav/view-controller';
* buttons: [
* {
* text: 'Cancel',
* role: 'cancel',
* handler: () => {
* console.log('Cancel clicked');
* }
@ -86,6 +92,7 @@ import {ViewController} from '../nav/view-controller';
* buttons: [
* {
* text: 'Cancel',
* role: 'cancel',
* handler: data => {
* console.log('Cancel clicked');
* }
@ -230,7 +237,7 @@ export class Alert extends ViewController {
@Component({
selector: 'ion-alert',
template:
'<div (click)="dismiss()" tappable disable-activated class="backdrop" role="presentation"></div>' +
'<div (click)="bdClick()" tappable disable-activated class="backdrop" role="presentation"></div>' +
'<div class="alert-wrapper">' +
'<div class="alert-head">' +
'<h2 id="{{hdrId}}" class="alert-title" *ngIf="d.title" [innerHTML]="d.title"></h2>' +
@ -370,7 +377,7 @@ class AlertCmp {
} else if (ev.keyCode === 27) {
console.debug('alert escape');
self.dismiss();
self.bdClick();
}
};
@ -391,7 +398,7 @@ class AlertCmp {
}
}
btnClick(button) {
btnClick(button, dismissDelay?) {
let shouldDismiss = true;
if (button.handler) {
@ -405,8 +412,8 @@ class AlertCmp {
if (shouldDismiss) {
setTimeout(() => {
this.dismiss();
}, this._config.get('pageTransitionDelay'));
this.dismiss(button.role);
}, dismissDelay || this._config.get('pageTransitionDelay'));
}
}
@ -421,8 +428,18 @@ class AlertCmp {
checkedInput.checked = !checkedInput.checked;
}
dismiss(): Promise<any> {
return this._viewCtrl.dismiss(this.getValues());
bdClick() {
let cancelBtn = this.d.buttons.find(b => b.role === 'cancel');
if (cancelBtn) {
this.btnClick(cancelBtn, 1);
} else {
this.dismiss('backdrop');
}
}
dismiss(role): Promise<any> {
return this._viewCtrl.dismiss(this.getValues(), role);
}
getValues() {

View File

@ -6,8 +6,7 @@ import {App, Page, Alert, NavController} from 'ionic/ionic';
})
class E2EPage {
constructor(nav: NavController) {
this.nav = nav;
constructor(private nav: NavController) {
this.testConfirmOpen = false;
this.testPromptOpen = false;
this.testConfirmResult = '';
@ -31,6 +30,7 @@ class E2EPage {
alert.setMessage('Message <strong>text</strong>!!!');
alert.addButton({
text: 'Cancel',
role: 'cancel',
handler: () => {
console.log('Confirm Cancel');
this.testConfirmResult = 'Cancel';
@ -88,8 +88,8 @@ class E2EPage {
this.testPromptOpen = true;
});
alert.onDismiss(data => {
console.log('onDismiss data', data);
alert.onDismiss((data, role) => {
console.log('onDismiss, data:', data, 'role:', role);
});
}

View File

@ -114,7 +114,7 @@ export class NavRouter extends RouterOutlet {
class ResolvedInstruction extends Instruction {
constructor(public component: ComponentInstruction, public child: Instruction,
public auxInstruction: {[key: string]: Instruction}) {
super();
super(component, child, auxInstruction);
}
resolveComponent(): Promise<ComponentInstruction> {

View File

@ -83,8 +83,8 @@ export class ViewController {
this._onDismiss = callback;
}
dismiss(data) {
this._onDismiss && this._onDismiss(data);
dismiss(data, role?) {
this._onDismiss && this._onDismiss(data, role);
return this._nav.remove(this._nav.indexOf(this), 1, this._leavingOpts);
}