mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
chore(build): rename ionic directory to src and update all references in the build process.
This commit is contained in:
111
src/components/action-sheet/action-sheet.ios.scss
Normal file
111
src/components/action-sheet/action-sheet.ios.scss
Normal file
@@ -0,0 +1,111 @@
|
||||
@import "../../globals.ios";
|
||||
@import "./action-sheet";
|
||||
|
||||
// iOS Action Sheet
|
||||
// --------------------------------------------------
|
||||
|
||||
$action-sheet-ios-text-align: center !default;
|
||||
$action-sheet-ios-padding: 0 10px !default;
|
||||
$action-sheet-ios-group-margin-bottom: 10px !default;
|
||||
$action-sheet-ios-background: #f9f9f9 !default;
|
||||
|
||||
$action-sheet-ios-border-color: #d6d6da !default;
|
||||
$action-sheet-ios-border-radius: 13px !default;
|
||||
|
||||
$action-sheet-ios-title-padding: 1.5rem !default;
|
||||
$action-sheet-ios-title-color: #8f8f8f !default;
|
||||
$action-sheet-ios-title-font-size: 1.3rem !default;
|
||||
$action-sheet-ios-title-font-weight: 400 !default;
|
||||
$action-sheet-ios-title-border-radius: 0 !default;
|
||||
|
||||
$action-sheet-ios-button-min-height: 5.6rem !default;
|
||||
$action-sheet-ios-button-padding: 18px !default;
|
||||
$action-sheet-ios-button-text-color: #007aff !default;
|
||||
$action-sheet-ios-button-font-size: 2rem !default;
|
||||
$action-sheet-ios-button-border-width: 1px !default;
|
||||
$action-sheet-ios-button-border-style: solid !default;
|
||||
$action-sheet-ios-button-border-color: #d1d3d6 !default;
|
||||
$action-sheet-ios-button-background: transparent !default;
|
||||
$action-sheet-ios-button-background-activated: #ebebeb !default;
|
||||
|
||||
$action-sheet-ios-button-destructive-text-color: #f53d3d !default;
|
||||
$action-sheet-ios-button-cancel-background: #fff !default;
|
||||
$action-sheet-ios-button-cancel-font-weight: 600 !default;
|
||||
|
||||
|
||||
ion-action-sheet {
|
||||
text-align: $action-sheet-ios-text-align;
|
||||
}
|
||||
|
||||
.action-sheet-container {
|
||||
padding: $action-sheet-ios-padding;
|
||||
}
|
||||
|
||||
.action-sheet-group {
|
||||
overflow: hidden;
|
||||
|
||||
margin-bottom: $action-sheet-ios-group-margin-bottom - 2;
|
||||
|
||||
border-radius: $action-sheet-ios-border-radius;
|
||||
background: $action-sheet-ios-background;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: $action-sheet-ios-group-margin-bottom;
|
||||
}
|
||||
}
|
||||
|
||||
.action-sheet-title {
|
||||
padding: $action-sheet-ios-title-padding;
|
||||
|
||||
border-bottom: $action-sheet-ios-button-border-width $action-sheet-ios-button-border-style $action-sheet-ios-border-color;
|
||||
border-radius: $action-sheet-ios-title-border-radius;
|
||||
font-size: $action-sheet-ios-title-font-size;
|
||||
font-weight: $action-sheet-ios-title-font-weight;
|
||||
text-align: $action-sheet-ios-text-align;
|
||||
color: $action-sheet-ios-title-color;
|
||||
}
|
||||
|
||||
.action-sheet-button {
|
||||
margin: 0;
|
||||
padding: $action-sheet-ios-button-padding;
|
||||
|
||||
min-height: $action-sheet-ios-button-min-height;
|
||||
|
||||
border-bottom: $action-sheet-ios-button-border-width $action-sheet-ios-button-border-style $action-sheet-ios-border-color;
|
||||
font-size: $action-sheet-ios-button-font-size;
|
||||
color: $action-sheet-ios-button-text-color;
|
||||
background: $action-sheet-ios-button-background;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
&.activated {
|
||||
margin-top: -$action-sheet-ios-button-border-width;
|
||||
|
||||
border-top: $action-sheet-ios-button-border-width $action-sheet-ios-button-border-style $action-sheet-ios-button-background-activated;
|
||||
border-bottom-color: $action-sheet-ios-button-background-activated;
|
||||
background: $action-sheet-ios-button-background-activated;
|
||||
}
|
||||
}
|
||||
|
||||
.action-sheet-selected {
|
||||
font-weight: bold;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.action-sheet-destructive {
|
||||
color: $action-sheet-ios-button-destructive-text-color;
|
||||
}
|
||||
|
||||
.action-sheet-cancel {
|
||||
font-weight: $action-sheet-ios-button-cancel-font-weight;
|
||||
background: $action-sheet-ios-button-cancel-background;
|
||||
}
|
||||
|
||||
&.hairlines {
|
||||
.action-sheet-title,
|
||||
.action-sheet-button {
|
||||
border-bottom-width: $hairlines-width;
|
||||
}
|
||||
}
|
||||
81
src/components/action-sheet/action-sheet.md.scss
Normal file
81
src/components/action-sheet/action-sheet.md.scss
Normal file
@@ -0,0 +1,81 @@
|
||||
@import "../../globals.md";
|
||||
@import "./action-sheet";
|
||||
|
||||
// Material Design Action Sheet
|
||||
// --------------------------------------------------
|
||||
|
||||
$action-sheet-md-text-align: left !default;
|
||||
$action-sheet-md-background: #fafafa !default;
|
||||
$action-sheet-md-group-margin-bottom: 8px !default;
|
||||
|
||||
$action-sheet-md-title-color: #757575 !default;
|
||||
$action-sheet-md-title-font-size: 1.6rem !default;
|
||||
$action-sheet-md-title-padding: 19px 16px 17px !default;
|
||||
|
||||
$action-sheet-md-button-min-height: 4.8rem !default;
|
||||
$action-sheet-md-button-text-color: #222 !default;
|
||||
$action-sheet-md-button-font-size: 1.6rem !default;
|
||||
$action-sheet-md-button-padding: 0 16px !default;
|
||||
$action-sheet-md-button-background: transparent !default;
|
||||
$action-sheet-md-button-background-activated: #f1f1f1 !default;
|
||||
|
||||
$action-sheet-md-icon-font-size: 2.4rem !default;
|
||||
$action-sheet-md-icon-min-width: 24px !default;
|
||||
$action-sheet-md-icon-text-align: center !default;
|
||||
$action-sheet-md-icon-vertical-align: middle !default;
|
||||
$action-sheet-md-icon-margin: 0 28px 0 0 !default;
|
||||
|
||||
|
||||
.action-sheet-title {
|
||||
padding: $action-sheet-md-title-padding;
|
||||
|
||||
font-size: $action-sheet-md-title-font-size;
|
||||
text-align: $action-sheet-md-text-align;
|
||||
color: $action-sheet-md-title-color;
|
||||
}
|
||||
|
||||
.action-sheet-button {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
padding: $action-sheet-md-button-padding;
|
||||
|
||||
min-height: $action-sheet-md-button-min-height;
|
||||
|
||||
font-size: $action-sheet-md-button-font-size;
|
||||
text-align: $action-sheet-md-text-align;
|
||||
color: $action-sheet-md-button-text-color;
|
||||
background: $action-sheet-md-button-background;
|
||||
|
||||
&.activated {
|
||||
background: $action-sheet-md-button-background-activated;
|
||||
}
|
||||
}
|
||||
|
||||
.action-sheet-icon {
|
||||
margin: $action-sheet-md-icon-margin;
|
||||
|
||||
min-width: $action-sheet-md-icon-min-width;
|
||||
|
||||
font-size: $action-sheet-md-icon-font-size;
|
||||
text-align: $action-sheet-md-icon-text-align;
|
||||
vertical-align: $action-sheet-md-icon-vertical-align;
|
||||
}
|
||||
|
||||
.action-sheet-group {
|
||||
overflow: hidden;
|
||||
|
||||
background: $action-sheet-md-background;
|
||||
|
||||
&:last-child .action-sheet-button {
|
||||
margin-bottom: $action-sheet-md-group-margin-bottom;
|
||||
}
|
||||
|
||||
.button-inner {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
.action-sheet-selected {
|
||||
font-weight: bold;
|
||||
}
|
||||
39
src/components/action-sheet/action-sheet.scss
Normal file
39
src/components/action-sheet/action-sheet.scss
Normal file
@@ -0,0 +1,39 @@
|
||||
@import "../../globals.core";
|
||||
|
||||
// Action Sheet
|
||||
// --------------------------------------------------
|
||||
|
||||
$action-sheet-width: 100% !default;
|
||||
$action-sheet-max-width: 500px !default;
|
||||
|
||||
|
||||
ion-action-sheet {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: $z-index-overlay;
|
||||
display: block;
|
||||
|
||||
width: $action-sheet-width;
|
||||
height: $action-sheet-width;
|
||||
}
|
||||
|
||||
.action-sheet-wrapper {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: $z-index-overlay-wrapper;
|
||||
display: block;
|
||||
|
||||
margin: auto;
|
||||
|
||||
width: $action-sheet-width;
|
||||
max-width: $action-sheet-max-width;
|
||||
|
||||
transform: translate3d(0, 100%, 0);
|
||||
}
|
||||
|
||||
.action-sheet-button {
|
||||
width: $action-sheet-width;
|
||||
}
|
||||
482
src/components/action-sheet/action-sheet.ts
Normal file
482
src/components/action-sheet/action-sheet.ts
Normal file
@@ -0,0 +1,482 @@
|
||||
import {Component, Renderer, ElementRef, HostListener, ViewEncapsulation} from '@angular/core';
|
||||
|
||||
import {Animation} from '../../animations/animation';
|
||||
import {Transition, TransitionOptions} from '../../transitions/transition';
|
||||
import {Config} from '../../config/config';
|
||||
import {Icon} from '../icon/icon';
|
||||
import {isPresent} from '../../util/util';
|
||||
import {NavParams} from '../nav/nav-params';
|
||||
import {ViewController} from '../nav/view-controller';
|
||||
|
||||
|
||||
/**
|
||||
* @name ActionSheet
|
||||
* @description
|
||||
* An Action Sheet is a dialog that lets the user choose from a set of
|
||||
* options. It appears on top of the app's content, and must be manually
|
||||
* dismissed by the user before they can resume interaction with the app.
|
||||
* Dangerous (destructive) options are made obvious in `ios` mode. There are easy
|
||||
* ways to cancel out of the action sheet, such as tapping the backdrop or
|
||||
* 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 `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 `role` property can either be `destructive` or `cancel`. Buttons
|
||||
* without a role property will have the default look for the platform. Buttons
|
||||
* with the `cancel` role will always load as the bottom button, no matter where
|
||||
* they are in the array. All other buttons will be displayed in the order they
|
||||
* have been added to the `buttons` array. Note: We recommend that `destructive`
|
||||
* buttons are always the first button in the array, making them the top button.
|
||||
* Additionally, if the action sheet is dismissed by tapping the backdrop, then
|
||||
* it will fire the handler from the button with the cancel role.
|
||||
*
|
||||
* You can pass all of the action sheet's options in the first argument of
|
||||
* the create method: `ActionSheet.create(opts)`. Otherwise the action sheet's
|
||||
* instance has methods to add options, like `setTitle()` or `addButton()`.
|
||||
*
|
||||
* @usage
|
||||
* ```ts
|
||||
* constructor(nav: NavController) {
|
||||
* this.nav = nav;
|
||||
* }
|
||||
*
|
||||
* presentActionSheet() {
|
||||
* let actionSheet = ActionSheet.create({
|
||||
* title: 'Modify your album',
|
||||
* buttons: [
|
||||
* {
|
||||
* text: 'Destructive',
|
||||
* role: 'destructive',
|
||||
* handler: () => {
|
||||
* console.log('Destructive clicked');
|
||||
* }
|
||||
* },
|
||||
* {
|
||||
* text: 'Archive',
|
||||
* handler: () => {
|
||||
* console.log('Archive clicked');
|
||||
* }
|
||||
* },
|
||||
* {
|
||||
* text: 'Cancel',
|
||||
* role: 'cancel',
|
||||
* handler: () => {
|
||||
* console.log('Cancel clicked');
|
||||
* }
|
||||
* }
|
||||
* ]
|
||||
* });
|
||||
*
|
||||
* this.nav.present(actionSheet);
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* ### Dismissing And Async Navigation
|
||||
*
|
||||
* After an action sheet has been dismissed, the app may need to also transition
|
||||
* to another page depending on the handler's logic. However, because multiple
|
||||
* transitions were fired at roughly the same time, it's difficult for the
|
||||
* nav controller to cleanly animate multiple transitions that may
|
||||
* have been kicked off asynchronously. This is further described in the
|
||||
* [`Nav Transition Promises`](../../nav/NavController) section. For action sheets,
|
||||
* this means it's best to wait for the action sheet to finish its transition
|
||||
* out before starting a new transition on the same nav controller.
|
||||
*
|
||||
* In the example below, after the button has been clicked, its handler
|
||||
* waits on async operation to complete, *then* it uses `pop` to navigate
|
||||
* back a page in the same stack. The potential problem is that the async operation
|
||||
* may have been completed before the action sheet has even finished its transition
|
||||
* out. In this case, it's best to ensure the action sheet has finished its transition
|
||||
* out first, *then* start the next transition.
|
||||
*
|
||||
* ```ts
|
||||
* let actionSheet = ActionSheet.create({
|
||||
* title: 'Hello',
|
||||
* buttons: [{
|
||||
* text: 'Ok',
|
||||
* handler: () => {
|
||||
* // user has clicked the action sheet button
|
||||
* // begin the action sheet's dimiss transition
|
||||
* let navTransition = actionSheet.dismiss();
|
||||
*
|
||||
* // start some async method
|
||||
* someAsyncOperation().then(() => {
|
||||
* // once the async operation has completed
|
||||
* // then run the next nav transition after the
|
||||
* // first transition has finished animating out
|
||||
*
|
||||
* navTransition.then(() => {
|
||||
* this.nav.pop();
|
||||
* });
|
||||
* });
|
||||
* return false;
|
||||
* }
|
||||
* }]
|
||||
* });
|
||||
*
|
||||
* this.nav.present(actionSheet);
|
||||
* ```
|
||||
*
|
||||
* It's important to note that the handler returns `false`. A feature of
|
||||
* button handlers is that they automatically dismiss the action sheet when their button
|
||||
* was clicked, however, we'll need more control regarding the transition. Because
|
||||
* the handler returns `false`, then the action sheet does not automatically dismiss
|
||||
* itself. Instead, you now have complete control of when the action sheet has finished
|
||||
* transitioning, and the ability to wait for the action sheet to finish transitioning
|
||||
* out before starting a new transition.
|
||||
*
|
||||
*
|
||||
* @demo /docs/v2/demos/action-sheet/
|
||||
* @see {@link /docs/v2/components#action-sheets ActionSheet Component Docs}
|
||||
*/
|
||||
export class ActionSheet extends ViewController {
|
||||
|
||||
constructor(opts: ActionSheetOptions = {}) {
|
||||
opts.buttons = opts.buttons || [];
|
||||
opts.enableBackdropDismiss = isPresent(opts.enableBackdropDismiss) ? !!opts.enableBackdropDismiss : true;
|
||||
|
||||
super(ActionSheetCmp, opts);
|
||||
this.viewType = 'action-sheet';
|
||||
this.isOverlay = true;
|
||||
|
||||
// by default, actionsheets should not fire lifecycle events of other views
|
||||
// for example, when an actionsheets enters, the current active view should
|
||||
// not fire its lifecycle events because it's not conceptually leaving
|
||||
this.fireOtherLifecycles = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
getTransitionName(direction: string) {
|
||||
let key = 'actionSheet' + (direction === 'back' ? 'Leave' : 'Enter');
|
||||
return this._nav && this._nav.config.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} title Action sheet title
|
||||
*/
|
||||
setTitle(title: string) {
|
||||
this.data.title = title;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} subTitle Action sheet subtitle
|
||||
*/
|
||||
setSubTitle(subTitle: string) {
|
||||
this.data.subTitle = subTitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {object} button Action sheet button
|
||||
*/
|
||||
addButton(button: any) {
|
||||
this.data.buttons.push(button);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open an action sheet with the following options
|
||||
*
|
||||
* | Option | Type | Description |
|
||||
* |-----------------------|------------|-----------------------------------------------------------------|
|
||||
* | title |`string` | The title for the actionsheet |
|
||||
* | subTitle |`string` | The sub-title for the actionsheet |
|
||||
* | cssClass |`string` | An additional class for custom styles |
|
||||
* | enableBackdropDismiss |`boolean` | If the actionsheet should close when the user taps the backdrop |
|
||||
* | buttons |`array<any>`| An array of buttons to display |
|
||||
*
|
||||
* For the buttons:
|
||||
*
|
||||
* | Option | Type | Description |
|
||||
* |----------|----------|--------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
* | text | `string` | The buttons text |
|
||||
* | icon | `icon` | The buttons icons |
|
||||
* | handler | `any` | An express the button should evaluate |
|
||||
* | cssClass | `string` | An additional class for custom styles |
|
||||
* | role | `string` | How the button should be displayed, `destructive` or `cancel`. If not role is provided, it will display the button without any additional styles |
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param {object} opts Action sheet options
|
||||
*/
|
||||
static create(opts: ActionSheetOptions = {}) {
|
||||
return new ActionSheet(opts);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
@Component({
|
||||
selector: 'ion-action-sheet',
|
||||
template:
|
||||
'<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">' +
|
||||
'<div class="action-sheet-title" id="{{hdrId}}" *ngIf="d.title">{{d.title}}</div>' +
|
||||
'<div class="action-sheet-sub-title" id="{{descId}}" *ngIf="d.subTitle">{{d.subTitle}}</div>' +
|
||||
'<button category="action-sheet-button" (click)="click(b)" *ngFor="let b of d.buttons" class="disable-hover" [ngClass]="b.cssClass">' +
|
||||
'<ion-icon [name]="b.icon" *ngIf="b.icon" class="action-sheet-icon"></ion-icon> ' +
|
||||
'{{b.text}}' +
|
||||
'</button>' +
|
||||
'</div>' +
|
||||
'<div class="action-sheet-group" *ngIf="d.cancelButton">' +
|
||||
'<button category="action-sheet-button" (click)="click(d.cancelButton)" class="action-sheet-cancel disable-hover" [ngClass]="d.cancelButton.cssClass">' +
|
||||
'<ion-icon [name]="d.cancelButton.icon" *ngIf="d.cancelButton.icon" class="action-sheet-icon"></ion-icon> ' +
|
||||
'{{d.cancelButton.text}}' +
|
||||
'</button>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</div>',
|
||||
host: {
|
||||
'role': 'dialog',
|
||||
'[attr.aria-labelledby]': 'hdrId',
|
||||
'[attr.aria-describedby]': 'descId'
|
||||
},
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
})
|
||||
class ActionSheetCmp {
|
||||
private d: any;
|
||||
private descId: string;
|
||||
private hdrId: string;
|
||||
private id: number;
|
||||
private created: number;
|
||||
|
||||
constructor(
|
||||
private _viewCtrl: ViewController,
|
||||
private _config: Config,
|
||||
private _elementRef: ElementRef,
|
||||
params: NavParams,
|
||||
renderer: Renderer
|
||||
) {
|
||||
this.d = params.data;
|
||||
this.created = Date.now();
|
||||
|
||||
if (this.d.cssClass) {
|
||||
renderer.setElementClass(_elementRef.nativeElement, this.d.cssClass, true);
|
||||
}
|
||||
|
||||
this.id = (++actionSheetIds);
|
||||
if (this.d.title) {
|
||||
this.hdrId = 'acst-hdr-' + this.id;
|
||||
}
|
||||
if (this.d.subTitle) {
|
||||
this.descId = 'acst-subhdr-' + this.id;
|
||||
}
|
||||
}
|
||||
|
||||
onPageLoaded() {
|
||||
// normalize the data
|
||||
let buttons = [];
|
||||
|
||||
this.d.buttons.forEach(button => {
|
||||
if (typeof button === 'string') {
|
||||
button = { text: button };
|
||||
}
|
||||
if (!button.cssClass) {
|
||||
button.cssClass = '';
|
||||
}
|
||||
|
||||
// deprecated warning
|
||||
if (button.style) {
|
||||
console.warn('Action sheet "style" property has been renamed to "role"');
|
||||
button.role = button.style;
|
||||
}
|
||||
|
||||
if (button.role === 'cancel') {
|
||||
this.d.cancelButton = button;
|
||||
|
||||
} else {
|
||||
if (button.role === 'destructive') {
|
||||
button.cssClass = (button.cssClass + ' ' || '') + 'action-sheet-destructive';
|
||||
} else if (button.role === 'selected') {
|
||||
button.cssClass = (button.cssClass + ' ' || '') + 'action-sheet-selected';
|
||||
}
|
||||
buttons.push(button);
|
||||
}
|
||||
});
|
||||
|
||||
this.d.buttons = buttons;
|
||||
}
|
||||
|
||||
onPageDidEnter() {
|
||||
let activeElement: any = document.activeElement;
|
||||
if (document.activeElement) {
|
||||
activeElement.blur();
|
||||
}
|
||||
|
||||
let focusableEle = this._elementRef.nativeElement.querySelector('button');
|
||||
if (focusableEle) {
|
||||
focusableEle.focus();
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('body:keyup', ['$event'])
|
||||
private _keyUp(ev: KeyboardEvent) {
|
||||
if (this.isEnabled() && this._viewCtrl.isLast()) {
|
||||
if (ev.keyCode === 27) {
|
||||
console.debug('actionsheet, escape button');
|
||||
this.bdClick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
click(button, dismissDelay?) {
|
||||
if (!this.isEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
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.isEnabled() && this.d.enableBackdropDismiss) {
|
||||
if (this.d.cancelButton) {
|
||||
this.click(this.d.cancelButton, 1);
|
||||
|
||||
} else {
|
||||
this.dismiss('backdrop');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dismiss(role): Promise<any> {
|
||||
return this._viewCtrl.dismiss(null, role);
|
||||
}
|
||||
|
||||
isEnabled() {
|
||||
let tm = this._config.getNumber('overlayCreatedDiff', 750);
|
||||
return (this.created + tm < Date.now());
|
||||
}
|
||||
}
|
||||
|
||||
export interface ActionSheetOptions {
|
||||
title?: string;
|
||||
subTitle?: string;
|
||||
cssClass?: string;
|
||||
buttons?: Array<any>;
|
||||
enableBackdropDismiss?: boolean;
|
||||
}
|
||||
|
||||
|
||||
class ActionSheetSlideIn extends Transition {
|
||||
constructor(enteringView, leavingView, opts: TransitionOptions) {
|
||||
super(opts);
|
||||
|
||||
let ele = enteringView.pageRef().nativeElement;
|
||||
let backdrop = new Animation(ele.querySelector('.backdrop'));
|
||||
let wrapper = new Animation(ele.querySelector('.action-sheet-wrapper'));
|
||||
|
||||
backdrop.fromTo('opacity', 0.01, 0.4);
|
||||
wrapper.fromTo('translateY', '100%', '0%');
|
||||
|
||||
this.easing('cubic-bezier(.36,.66,.04,1)').duration(400).add(backdrop).add(wrapper);
|
||||
}
|
||||
}
|
||||
Transition.register('action-sheet-slide-in', ActionSheetSlideIn);
|
||||
|
||||
|
||||
class ActionSheetSlideOut extends Transition {
|
||||
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
|
||||
super(opts);
|
||||
|
||||
let ele = leavingView.pageRef().nativeElement;
|
||||
let backdrop = new Animation(ele.querySelector('.backdrop'));
|
||||
let wrapper = new Animation(ele.querySelector('.action-sheet-wrapper'));
|
||||
|
||||
backdrop.fromTo('opacity', 0.4, 0);
|
||||
wrapper.fromTo('translateY', '0%', '100%');
|
||||
|
||||
this.easing('cubic-bezier(.36,.66,.04,1)').duration(300).add(backdrop).add(wrapper);
|
||||
}
|
||||
}
|
||||
Transition.register('action-sheet-slide-out', ActionSheetSlideOut);
|
||||
|
||||
|
||||
class ActionSheetMdSlideIn extends Transition {
|
||||
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
|
||||
super(opts);
|
||||
|
||||
let ele = enteringView.pageRef().nativeElement;
|
||||
let backdrop = new Animation(ele.querySelector('.backdrop'));
|
||||
let wrapper = new Animation(ele.querySelector('.action-sheet-wrapper'));
|
||||
|
||||
backdrop.fromTo('opacity', 0.01, 0.26);
|
||||
wrapper.fromTo('translateY', '100%', '0%');
|
||||
|
||||
this.easing('cubic-bezier(.36,.66,.04,1)').duration(400).add(backdrop).add(wrapper);
|
||||
}
|
||||
}
|
||||
Transition.register('action-sheet-md-slide-in', ActionSheetMdSlideIn);
|
||||
|
||||
|
||||
class ActionSheetMdSlideOut extends Transition {
|
||||
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
|
||||
super(opts);
|
||||
|
||||
let ele = leavingView.pageRef().nativeElement;
|
||||
let backdrop = new Animation(ele.querySelector('.backdrop'));
|
||||
let wrapper = new Animation(ele.querySelector('.action-sheet-wrapper'));
|
||||
|
||||
backdrop.fromTo('opacity', 0.26, 0);
|
||||
wrapper.fromTo('translateY', '0%', '100%');
|
||||
|
||||
this.easing('cubic-bezier(.36,.66,.04,1)').duration(450).add(backdrop).add(wrapper);
|
||||
}
|
||||
}
|
||||
Transition.register('action-sheet-md-slide-out', ActionSheetMdSlideOut);
|
||||
|
||||
class ActionSheetWpSlideIn extends Transition {
|
||||
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
|
||||
super(opts);
|
||||
|
||||
let ele = enteringView.pageRef().nativeElement;
|
||||
let backdrop = new Animation(ele.querySelector('.backdrop'));
|
||||
let wrapper = new Animation(ele.querySelector('.action-sheet-wrapper'));
|
||||
|
||||
backdrop.fromTo('opacity', 0.01, 0.16);
|
||||
wrapper.fromTo('translateY', '100%', '0%');
|
||||
|
||||
this.easing('cubic-bezier(.36,.66,.04,1)').duration(400).add(backdrop).add(wrapper);
|
||||
}
|
||||
}
|
||||
Transition.register('action-sheet-wp-slide-in', ActionSheetWpSlideIn);
|
||||
|
||||
|
||||
class ActionSheetWpSlideOut extends Transition {
|
||||
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
|
||||
super(opts);
|
||||
|
||||
let ele = leavingView.pageRef().nativeElement;
|
||||
let backdrop = new Animation(ele.querySelector('.backdrop'));
|
||||
let wrapper = new Animation(ele.querySelector('.action-sheet-wrapper'));
|
||||
|
||||
backdrop.fromTo('opacity', 0.1, 0);
|
||||
wrapper.fromTo('translateY', '0%', '100%');
|
||||
|
||||
this.easing('cubic-bezier(.36,.66,.04,1)').duration(450).add(backdrop).add(wrapper);
|
||||
}
|
||||
}
|
||||
Transition.register('action-sheet-wp-slide-out', ActionSheetWpSlideOut);
|
||||
|
||||
let actionSheetIds = -1;
|
||||
88
src/components/action-sheet/action-sheet.wp.scss
Normal file
88
src/components/action-sheet/action-sheet.wp.scss
Normal file
@@ -0,0 +1,88 @@
|
||||
@import "../../globals.wp";
|
||||
@import "./action-sheet";
|
||||
|
||||
// Windows Action Sheet
|
||||
// --------------------------------------------------
|
||||
|
||||
$action-sheet-wp-text-align: left !default;
|
||||
$action-sheet-wp-background: #fff !default;
|
||||
$action-sheet-wp-box-shadow-color: rgba(0, 0, 0, .2) !default;
|
||||
$action-sheet-wp-box-shadow: 0 -1px 0 $action-sheet-wp-box-shadow-color !default;
|
||||
$action-sheet-wp-group-margin-bottom: 8px !default;
|
||||
|
||||
$action-sheet-wp-title-padding: 19px 16px 17px !default;
|
||||
$action-sheet-wp-title-font-size: 2rem !default;
|
||||
$action-sheet-wp-title-color: #4d4d4d !default;
|
||||
$action-sheet-wp-title-text-align: $action-sheet-wp-text-align !default;
|
||||
|
||||
$action-sheet-wp-button-height: 4.8rem !default;
|
||||
$action-sheet-wp-button-text-color: #4d4d4d !default;
|
||||
$action-sheet-wp-button-font-size: 1.5rem !default;
|
||||
$action-sheet-wp-button-padding: 0 16px !default;
|
||||
$action-sheet-wp-button-text-align: $action-sheet-wp-text-align !default;
|
||||
$action-sheet-wp-button-background: transparent !default;
|
||||
$action-sheet-wp-button-background-activated: $list-wp-activated-background-color !default;
|
||||
|
||||
$action-sheet-wp-icon-min-width: 24px !default;
|
||||
$action-sheet-wp-icon-text-align: center !default;
|
||||
$action-sheet-wp-icon-vertical-align: middle !default;
|
||||
$action-sheet-wp-icon-font-size: 2.4rem !default;
|
||||
$action-sheet-wp-icon-margin: 0 16px 0 0 !default;
|
||||
|
||||
|
||||
.action-sheet-wrapper {
|
||||
box-shadow: $action-sheet-wp-box-shadow;
|
||||
}
|
||||
|
||||
.action-sheet-title {
|
||||
padding: $action-sheet-wp-title-padding;
|
||||
|
||||
font-size: $action-sheet-wp-title-font-size;
|
||||
text-align: $action-sheet-wp-title-text-align;
|
||||
color: $action-sheet-wp-title-color;
|
||||
}
|
||||
|
||||
.action-sheet-button {
|
||||
padding: $action-sheet-wp-button-padding;
|
||||
|
||||
min-height: $action-sheet-wp-button-height;
|
||||
|
||||
font-size: $action-sheet-wp-button-font-size;
|
||||
text-align: $action-sheet-wp-button-text-align;
|
||||
color: $action-sheet-wp-button-text-color;
|
||||
background: $action-sheet-wp-button-background;
|
||||
|
||||
&.activated {
|
||||
background: $action-sheet-wp-button-background-activated;
|
||||
}
|
||||
}
|
||||
|
||||
.action-sheet-icon {
|
||||
margin: $action-sheet-wp-icon-margin;
|
||||
|
||||
min-width: $action-sheet-wp-icon-min-width;
|
||||
|
||||
font-size: $action-sheet-wp-icon-font-size;
|
||||
text-align: $action-sheet-wp-icon-text-align;
|
||||
vertical-align: $action-sheet-wp-icon-vertical-align;
|
||||
}
|
||||
|
||||
.action-sheet-group {
|
||||
background: $action-sheet-wp-background;
|
||||
|
||||
&:last-child .action-sheet-button {
|
||||
margin-bottom: $action-sheet-wp-group-margin-bottom;
|
||||
}
|
||||
|
||||
.button-inner {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
.action-sheet-selected {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.action-sheet-cancel {
|
||||
background: $action-sheet-wp-button-background;
|
||||
}
|
||||
8
src/components/action-sheet/test/basic/e2e.ts
Normal file
8
src/components/action-sheet/test/basic/e2e.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
it('should open action sheet', function() {
|
||||
element(by.css('.e2eOpenActionSheet')).click();
|
||||
});
|
||||
|
||||
it('should close with backdrop click', function() {
|
||||
element(by.css('.backdrop')).click();
|
||||
});
|
||||
183
src/components/action-sheet/test/basic/index.ts
Normal file
183
src/components/action-sheet/test/basic/index.ts
Normal file
@@ -0,0 +1,183 @@
|
||||
import {App, Page, ActionSheet, Alert, Modal, NavController, ViewController, Platform} from '../../../../../ionic';
|
||||
|
||||
|
||||
@Page({
|
||||
templateUrl: 'main.html'
|
||||
})
|
||||
class E2EPage {
|
||||
result: string = '';
|
||||
|
||||
constructor(private nav: NavController, private platform: Platform) {}
|
||||
|
||||
presentActionSheet1() {
|
||||
this.result = '';
|
||||
|
||||
let actionSheet = ActionSheet.create({
|
||||
title: 'Albums',
|
||||
buttons: [
|
||||
{
|
||||
text: 'Delete',
|
||||
role: 'destructive',
|
||||
icon: !this.platform.is('ios') ? 'trash' : null,
|
||||
handler: () => {
|
||||
console.log('Delete clicked');
|
||||
this.result = 'Deleted';
|
||||
}
|
||||
},
|
||||
{
|
||||
text: 'Share',
|
||||
icon: !this.platform.is('ios') ? 'share' : null,
|
||||
handler: () => {
|
||||
console.log('Share clicked');
|
||||
this.result = 'Shared';
|
||||
}
|
||||
},
|
||||
{
|
||||
text: 'Play',
|
||||
icon: !this.platform.is('ios') ? 'arrow-dropright-circle' : null,
|
||||
handler: () => {
|
||||
let modal = Modal.create(ModalPage);
|
||||
this.nav.present(modal);
|
||||
|
||||
// returning false does not allow the actionsheet to be closed
|
||||
return false;
|
||||
}
|
||||
},
|
||||
{
|
||||
text: 'Favorite',
|
||||
icon: !this.platform.is('ios') ? 'heart' : null,
|
||||
handler: () => {
|
||||
console.log('Favorite clicked');
|
||||
this.result = 'Favorited';
|
||||
}
|
||||
},
|
||||
{
|
||||
text: 'Cancel',
|
||||
role: 'cancel', // will always sort to be on the bottom
|
||||
icon: !this.platform.is('ios') ? 'close' : null,
|
||||
handler: () => {
|
||||
console.log('Cancel clicked');
|
||||
this.result = 'Canceled';
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
this.nav.present(actionSheet);
|
||||
}
|
||||
|
||||
presentActionSheet2(ev) {
|
||||
this.result = '';
|
||||
|
||||
let actionSheet = ActionSheet.create({
|
||||
enableBackdropDismiss: false,
|
||||
buttons: [
|
||||
{
|
||||
text: 'Archive',
|
||||
handler: () => {
|
||||
console.log('Archive clicked');
|
||||
this.result = 'Archived';
|
||||
}
|
||||
},
|
||||
{
|
||||
text: 'Cancel',
|
||||
role: 'cancel',
|
||||
handler: () => {
|
||||
console.log('cancel this clicked');
|
||||
this.result = 'Canceled';
|
||||
}
|
||||
},
|
||||
{
|
||||
text: 'Destructive',
|
||||
role: 'destructive',
|
||||
handler: () => {
|
||||
console.log('Destructive clicked');
|
||||
this.result = 'Destructive';
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
this.nav.present(actionSheet);
|
||||
}
|
||||
|
||||
presentActionSheet3(ev) {
|
||||
this.result = '';
|
||||
|
||||
let actionSheet = ActionSheet.create({
|
||||
buttons: [
|
||||
{
|
||||
text: 'Open Alert',
|
||||
handler: () => {
|
||||
this.result = 'Opened alert';
|
||||
|
||||
let alert = Alert.create();
|
||||
alert.setTitle('Alert!');
|
||||
alert.setMessage('Alert opened from an action sheet');
|
||||
alert.addButton({
|
||||
text: 'Cancel',
|
||||
role: 'cancel',
|
||||
handler: () => {
|
||||
this.result = 'pressed Cancel button in alert from action sheet';
|
||||
}
|
||||
});
|
||||
alert.addButton({
|
||||
text: 'Okay',
|
||||
handler: () => {
|
||||
this.result = 'pressed Okay button in alert from action sheet';
|
||||
}
|
||||
});
|
||||
|
||||
this.nav.present(alert).then(() => {
|
||||
this.result = 'Alert from action sheet opened';
|
||||
});
|
||||
|
||||
// do not close the action sheet yet
|
||||
return false;
|
||||
}
|
||||
},
|
||||
{
|
||||
text: 'Cancel',
|
||||
role: 'cancel',
|
||||
handler: () => {
|
||||
this.result = 'Canceled';
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
this.nav.present(actionSheet);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Page({
|
||||
template: `
|
||||
<ion-toolbar>
|
||||
<ion-buttons start>
|
||||
<button (click)="dismiss()">Close</button>
|
||||
</ion-buttons>
|
||||
<ion-title>Modal</ion-title>
|
||||
</ion-toolbar>
|
||||
<ion-content padding>
|
||||
Hi, I'm Bob, and I'm a modal.
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
class ModalPage {
|
||||
constructor(private viewCtrl: ViewController) {}
|
||||
|
||||
dismiss() {
|
||||
this.viewCtrl.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@App({
|
||||
template: '<ion-nav [root]="root"></ion-nav>'
|
||||
})
|
||||
class E2EApp {
|
||||
constructor() {
|
||||
this.root = E2EPage;
|
||||
}
|
||||
}
|
||||
14
src/components/action-sheet/test/basic/main.html
Normal file
14
src/components/action-sheet/test/basic/main.html
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
<ion-navbar *navbar>
|
||||
<ion-title>Action Sheet</ion-title>
|
||||
</ion-navbar>
|
||||
|
||||
<ion-content padding>
|
||||
<button block class="e2eOpenActionSheet" (click)="presentActionSheet1()">Present Action Sheet 1</button>
|
||||
<button block (click)="presentActionSheet2()">Present Action Sheet 2</button>
|
||||
<button block (click)="presentActionSheet3()">Present Action Sheet 3</button>
|
||||
|
||||
<pre>
|
||||
Result: {{result}}
|
||||
</pre>
|
||||
</ion-content>
|
||||
Reference in New Issue
Block a user