mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70b5b6b5e5 | ||
|
|
5094feec89 | ||
|
|
1ca7df75ed | ||
|
|
877d8211d5 | ||
|
|
a8731dfc98 | ||
|
|
7803998542 | ||
|
|
8bd2f24d06 | ||
|
|
63f728f517 | ||
|
|
61935602a1 | ||
|
|
1a4aacf8be | ||
|
|
5a5da39a1e | ||
|
|
c7645ee59d | ||
|
|
2743c63537 | ||
|
|
7a1342caa1 | ||
|
|
3564bcfe1b | ||
|
|
f149c5ee95 | ||
|
|
2791c40c29 |
2
.github/ISSUE_TEMPLATE.md
vendored
2
.github/ISSUE_TEMPLATE.md
vendored
@@ -19,7 +19,7 @@
|
||||
|
||||
For Ionic V1 issues - http://plnkr.co/edit/Xo1QyAUx35ny1Xf9ODHx?p=preview
|
||||
|
||||
For Ionic issues - http://plnkr.co/edit/z0DzVL?p=preview
|
||||
For Ionic issues - http://plnkr.co/edit/cpeRJs?p=preview
|
||||
-->
|
||||
|
||||
**Related code:**
|
||||
|
||||
88
CHANGELOG.md
88
CHANGELOG.md
@@ -1,3 +1,91 @@
|
||||
<a name="3.4.1"></a>
|
||||
## [3.4.1](https://github.com/ionic-team/ionic/compare/v3.4.0...v3.4.1) (2017-06-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **themes:** change default app-direction ([ce92be0](https://github.com/ionic-team/ionic/commit/ce92be0))
|
||||
|
||||
|
||||
|
||||
<a name="3.4.0"></a>
|
||||
# [3.4.0](https://github.com/ionic-team/ionic/compare/v3.3.0...v3.4.0) (2017-06-15)
|
||||
|
||||
### Steps to Upgrade
|
||||
|
||||
`ionic-angular` should be set to version `3.4.0` in the package.json dependency list. The latest `@angular` release `4.1.3` is also supported. Feel free to update apps by updating the `package.json` dependencies to match below.
|
||||
|
||||
```
|
||||
"dependencies": {
|
||||
"@angular/common": "4.1.3",
|
||||
"@angular/compiler": "4.1.3",
|
||||
"@angular/compiler-cli": "4.1.3",
|
||||
"@angular/core": "4.1.3",
|
||||
"@angular/forms": "4.1.3",
|
||||
"@angular/http": "4.1.3",
|
||||
"@angular/platform-browser": "4.1.3",
|
||||
"@angular/platform-browser-dynamic": "4.1.3",
|
||||
"@ionic-native/core": "3.12.1",
|
||||
"@ionic-native/splash-screen": "3.12.1",
|
||||
"@ionic-native/status-bar": "3.12.1",
|
||||
"@ionic/storage": "2.0.1",
|
||||
"ionic-angular": "3.4.1",
|
||||
"ionicons": "3.0.0",
|
||||
"rxjs": "5.4.0",
|
||||
"sw-toolbox": "3.6.0",
|
||||
"zone.js": "0.8.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ionic/app-scripts": "1.3.7",
|
||||
"typescript": "2.3.4"
|
||||
}
|
||||
```
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **button:** rtl fix for md ripple effect ([#11842](https://github.com/ionic-team/ionic/issues/11842)) ([bb966e5](https://github.com/ionic-team/ionic/commit/bb966e5))
|
||||
* **content:** scroll content should inherit background ([#11467](https://github.com/ionic-team/ionic/issues/11467)) ([6256b0f](https://github.com/ionic-team/ionic/commit/6256b0f))
|
||||
* **datetime:** set datetime direction the same on ltr and rtl ([#11992](https://github.com/ionic-team/ionic/issues/11992)) ([20c9dd7](https://github.com/ionic-team/ionic/commit/20c9dd7))
|
||||
* **gesture:** RTL fix for slide-gesture ([#11822](https://github.com/ionic-team/ionic/issues/11822)) ([59a1e3d](https://github.com/ionic-team/ionic/commit/59a1e3d))
|
||||
* **input:** add correct translate3d for rtl ([ef85ba6](https://github.com/ionic-team/ionic/commit/ef85ba6)), closes [#11745](https://github.com/ionic-team/ionic/issues/11745) [#11211](https://github.com/ionic-team/ionic/issues/11211)
|
||||
* **input:** better handling of attributes ([9f86e10](https://github.com/ionic-team/ionic/commit/9f86e10))
|
||||
* **input:** slightly longer delay for autofocus ([#12037](https://github.com/ionic-team/ionic/issues/12037)) ([54ac2e3](https://github.com/ionic-team/ionic/commit/54ac2e3))
|
||||
* **input:** use all supported attributes on both textareas and inputs ([#12028](https://github.com/ionic-team/ionic/issues/12028)) ([8041eed](https://github.com/ionic-team/ionic/commit/8041eed))
|
||||
* **item-sliding:** RTL fix for item sliding ([#11825](https://github.com/ionic-team/ionic/issues/11825)) ([10f4df4](https://github.com/ionic-team/ionic/commit/10f4df4))
|
||||
* **keyboard:** big keyboard/input refactor ([c10f72b](https://github.com/ionic-team/ionic/commit/c10f72b)), closes [#9699](https://github.com/ionic-team/ionic/issues/9699) [#11484](https://github.com/ionic-team/ionic/issues/11484) [#11389](https://github.com/ionic-team/ionic/issues/11389) [#11325](https://github.com/ionic-team/ionic/issues/11325) [#11291](https://github.com/ionic-team/ionic/issues/11291) [#10828](https://github.com/ionic-team/ionic/issues/10828) [#11291](https://github.com/ionic-team/ionic/issues/11291) [#10393](https://github.com/ionic-team/ionic/issues/10393) [#10257](https://github.com/ionic-team/ionic/issues/10257) [#9434](https://github.com/ionic-team/ionic/issues/9434) [#8933](https://github.com/ionic-team/ionic/issues/8933) [#7178](https://github.com/ionic-team/ionic/issues/7178) [#7047](https://github.com/ionic-team/ionic/issues/7047) [#10552](https://github.com/ionic-team/ionic/issues/10552) [#10393](https://github.com/ionic-team/ionic/issues/10393) [#10183](https://github.com/ionic-team/ionic/issues/10183) [#10187](https://github.com/ionic-team/ionic/issues/10187) [#10852](https://github.com/ionic-team/ionic/issues/10852) [#11578](https://github.com/ionic-team/ionic/issues/11578)
|
||||
* **menu:** rtl gesture for menu ([#11830](https://github.com/ionic-team/ionic/issues/11830)) ([30047f0](https://github.com/ionic-team/ionic/commit/30047f0))
|
||||
* **refresher:** border should only show when pulled ([#12015](https://github.com/ionic-team/ionic/issues/12015)) ([47e3c70](https://github.com/ionic-team/ionic/commit/47e3c70)), closes [#10994](https://github.com/ionic-team/ionic/issues/10994)
|
||||
* **rtl:** add icon-start and icon-end attributes ([#11737](https://github.com/ionic-team/ionic/issues/11737)) ([a40b872](https://github.com/ionic-team/ionic/commit/a40b872))
|
||||
* **sass:** add default flag to variables ([#11779](https://github.com/ionic-team/ionic/issues/11779)) ([f14d7d6](https://github.com/ionic-team/ionic/commit/f14d7d6))
|
||||
* **searchbar:** caret moving to the end when typing ([261bc4d](https://github.com/ionic-team/ionic/commit/261bc4d))
|
||||
* **segment:** fix border-radius logic for RTL ([#11981](https://github.com/ionic-team/ionic/issues/11981)) ([6db8c14](https://github.com/ionic-team/ionic/commit/6db8c14))
|
||||
* **select:** add cssClass for popover interface ([#11769](https://github.com/ionic-team/ionic/issues/11769)) ([1c25acb](https://github.com/ionic-team/ionic/commit/1c25acb))
|
||||
* **select:** return undefined when there are no options ([#11968](https://github.com/ionic-team/ionic/issues/11968)) ([dc6c586](https://github.com/ionic-team/ionic/commit/dc6c586)), closes [#10435](https://github.com/ionic-team/ionic/issues/10435)
|
||||
* **split-pane:** correct split-pane menu side order ([30dc247](https://github.com/ionic-team/ionic/commit/30dc247))
|
||||
* **textarea:** apply classes properly ([dc958c3](https://github.com/ionic-team/ionic/commit/dc958c3))
|
||||
* **toggle:** RTL fix for toggle ([2afb936](https://github.com/ionic-team/ionic/commit/2afb936))
|
||||
* **toolbar:** get the correct contrast color for md mode ([0f4ed1c](https://github.com/ionic-team/ionic/commit/0f4ed1c)), closes [#11848](https://github.com/ionic-team/ionic/issues/11848)
|
||||
* **toolbar:** use the correct contrast color for MD toolbar ([041689b](https://github.com/ionic-team/ionic/commit/041689b)), closes [#11848](https://github.com/ionic-team/ionic/issues/11848)
|
||||
* **transition:** RTL fix for transition on ios ([#11820](https://github.com/ionic-team/ionic/issues/11820)) ([6322134](https://github.com/ionic-team/ionic/commit/6322134))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **background-position:** add background position support for rtl ([#11946](https://github.com/ionic-team/ionic/issues/11946)) ([305c306](https://github.com/ionic-team/ionic/commit/305c306))
|
||||
* **loading:** add enableBackdropDismiss to Loading ([#11937](https://github.com/ionic-team/ionic/issues/11937)) ([d0ae810](https://github.com/ionic-team/ionic/commit/d0ae810)), closes [#7975](https://github.com/ionic-team/ionic/issues/7975)
|
||||
* **loading:** add margin start variable ([#11980](https://github.com/ionic-team/ionic/issues/11980)) ([3e0d43e](https://github.com/ionic-team/ionic/commit/3e0d43e))
|
||||
* **rtl:** add transform and transform-origin support for rtl ([#11649](https://github.com/ionic-team/ionic/issues/11649)) ([2273fb5](https://github.com/ionic-team/ionic/commit/2273fb5))
|
||||
* **rtl:** optimize the new mixins for smaller bundle, ltr separation ([#11635](https://github.com/ionic-team/ionic/issues/11635)) ([f0c6948](https://github.com/ionic-team/ionic/commit/f0c6948))
|
||||
* **rtl:** support flipped svg background images on rtl ([#11945](https://github.com/ionic-team/ionic/issues/11945)) ([f4452b5](https://github.com/ionic-team/ionic/commit/f4452b5))
|
||||
* **slides:** support centering slides and using decimal numbers ([e3c60c5](https://github.com/ionic-team/ionic/commit/e3c60c5)), closes [#10361](https://github.com/ionic-team/ionic/issues/10361)
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **item-sliding:** remove duplicate class ([#11829](https://github.com/ionic-team/ionic/issues/11829)) ([c9cb9ae](https://github.com/ionic-team/ionic/commit/c9cb9ae))
|
||||
|
||||
|
||||
|
||||
<a name="3.3.0"></a>
|
||||
# [3.3.0](https://github.com/ionic-team/ionic/compare/v3.2.1...v3.3.0) (2017-05-24)
|
||||
|
||||
|
||||
@@ -20,6 +20,13 @@
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Hair Color</ion-label>
|
||||
<ion-select [(ngModel)]="hairColor" okText="Okay" cancelText="Dismiss" [compareWith]="compareFn">
|
||||
<ion-option *ngFor="let o of hairColorData" [value]="o">{{o.text}}</ion-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Gaming</ion-label>
|
||||
<ion-select [(ngModel)]="gaming" okText="Okay" cancelText="Dismiss">
|
||||
@@ -147,6 +154,13 @@
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Skittles</ion-label>
|
||||
<ion-select [(ngModel)]="skittles" multiple="true" okText="Okay" cancelText="Dismiss" [compareWith]="compareFn">
|
||||
<ion-option *ngFor="let o of skittlesData" [value]="o">{{o.text}}</ion-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Disabled</ion-label>
|
||||
<ion-select multiple disabled="true">
|
||||
|
||||
@@ -10,6 +10,10 @@ export class PageOne {
|
||||
petAlertOpts: any;
|
||||
petData: any;
|
||||
pets: Array<string>;
|
||||
hairColorData: any;
|
||||
hairColor: any;
|
||||
skittlesData: any;
|
||||
skittles: Array<any>;
|
||||
notifications: string = 'mute_1';
|
||||
rating: number = 2;
|
||||
|
||||
@@ -31,9 +35,37 @@ export class PageOne {
|
||||
{ text: 'Honey Badger', value: 'honeybadger' },
|
||||
];
|
||||
|
||||
this.hairColorData = [
|
||||
{ text: 'Brown', value: 'brown' },
|
||||
{ text: 'Blonde', value: 'blonde' },
|
||||
{ text: 'Black', value: 'black' },
|
||||
{ text: 'Red', value: 'red' }
|
||||
];
|
||||
|
||||
// Pre-selected object with different object reference
|
||||
this.hairColor = { text: 'Brown', value: 'brown' };
|
||||
|
||||
this.skittlesData = [
|
||||
{ text: 'Red', value: 'red' },
|
||||
{ text: 'Orange', value: 'orange' },
|
||||
{ text: 'Yellow', value: 'yellow' },
|
||||
{ text: 'Green', value: 'green' },
|
||||
{ text: 'Purple', value: 'purple' }
|
||||
];
|
||||
|
||||
// Pre-selected object with different object reference
|
||||
this.skittles = [
|
||||
{ text: 'Red', value: 'red' },
|
||||
{ text: 'Purple', value: 'purple' }
|
||||
];
|
||||
|
||||
this.pets = ['cat', 'dog'];
|
||||
}
|
||||
|
||||
compareFn(option1: any, option2: any) {
|
||||
return option1.value === option2.value;
|
||||
}
|
||||
|
||||
monthChange(val: any) {
|
||||
console.log('Month Change:', val);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "ionic2",
|
||||
"version": "3.3.0",
|
||||
"version": "3.4.1",
|
||||
"description": "A powerful framework for building mobile and progressive web apps with JavaScript and Angular",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@@ -146,4 +146,4 @@
|
||||
"pre-push#master": [
|
||||
"test"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -117,8 +117,6 @@ export class ActionSheetCmp {
|
||||
}
|
||||
|
||||
ionViewDidEnter() {
|
||||
this._plt.focusOutActiveElement();
|
||||
|
||||
const focusableEle = this._elementRef.nativeElement.querySelector('button');
|
||||
if (focusableEle) {
|
||||
focusableEle.focus();
|
||||
|
||||
@@ -194,18 +194,10 @@ export class AlertCmp {
|
||||
}
|
||||
|
||||
ionViewDidLeave() {
|
||||
this._plt.focusOutActiveElement();
|
||||
this.gestureBlocker.unblock();
|
||||
}
|
||||
|
||||
ionViewWillLeave() {
|
||||
this._plt.focusOutActiveElement();
|
||||
}
|
||||
|
||||
ionViewDidEnter() {
|
||||
// focus out of the active element
|
||||
this._plt.focusOutActiveElement();
|
||||
|
||||
// set focus on the first input or button in the alert
|
||||
// note that this does not always work and bring up the keyboard on
|
||||
// devices since the focus command must come from the user's touch event
|
||||
|
||||
@@ -241,7 +241,6 @@ export class App {
|
||||
// TODO: move _setNav() to the earlier stages of NavController. _queueTrns()
|
||||
enteringView._setNav(portal);
|
||||
|
||||
opts.keyboardClose = false;
|
||||
opts.direction = DIRECTION_FORWARD;
|
||||
|
||||
if (!opts.animation) {
|
||||
@@ -249,7 +248,7 @@ export class App {
|
||||
}
|
||||
|
||||
enteringView.setLeavingOpts({
|
||||
keyboardClose: false,
|
||||
keyboardClose: opts.keyboardClose,
|
||||
direction: DIRECTION_BACK,
|
||||
animation: enteringView.getTransitionName(DIRECTION_BACK),
|
||||
ev: opts.ev
|
||||
|
||||
@@ -5,7 +5,6 @@ import { Config } from '../../config/config';
|
||||
import { DeepLinker } from '../../navigation/deep-linker';
|
||||
import { DomController } from '../../platform/dom-controller';
|
||||
import { GestureController } from '../../gestures/gesture-controller';
|
||||
import { Keyboard } from '../../platform/keyboard';
|
||||
import { NavControllerBase } from '../../navigation/nav-controller-base';
|
||||
import { Platform } from '../../platform/platform';
|
||||
import { TransitionController } from '../../transitions/transition-controller';
|
||||
@@ -22,7 +21,6 @@ export class OverlayPortal extends NavControllerBase {
|
||||
@Inject(forwardRef(() => App)) app: App,
|
||||
config: Config,
|
||||
plt: Platform,
|
||||
keyboard: Keyboard,
|
||||
elementRef: ElementRef,
|
||||
zone: NgZone,
|
||||
renderer: Renderer,
|
||||
@@ -34,7 +32,7 @@ export class OverlayPortal extends NavControllerBase {
|
||||
domCtrl: DomController,
|
||||
errHandler: ErrorHandler
|
||||
) {
|
||||
super(null, app, config, plt, keyboard, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, domCtrl, errHandler);
|
||||
super(null, app, config, plt, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, domCtrl, errHandler);
|
||||
this._isPortal = true;
|
||||
this._init = true;
|
||||
this.setViewport(viewPort);
|
||||
|
||||
@@ -492,7 +492,7 @@ $button-md-strong-font-weight: bold !default;
|
||||
}
|
||||
}
|
||||
|
||||
.md .button-effect {
|
||||
.md button .button-effect {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
@@ -312,8 +312,13 @@ export class TextInput extends BaseInput<string> implements IonicFormInput {
|
||||
// Copy remaining attributes, not handled by ionic/angular
|
||||
copyInputAttributes(ionInputEle, nativeInputEle);
|
||||
|
||||
// prevent having tabIndex duplicated
|
||||
if (ionInputEle.hasAttribute('tabIndex')) {
|
||||
ionInputEle.removeAttribute('tabIndex');
|
||||
}
|
||||
|
||||
// handle the autofocus attribute
|
||||
if (ionInputEle.hasAttribute('autofocus')) {
|
||||
// the ion-input element has the autofocus attributes
|
||||
ionInputEle.removeAttribute('autofocus');
|
||||
switch (this._autoFocusAssist) {
|
||||
case 'immediate':
|
||||
|
||||
@@ -46,7 +46,7 @@ export class ItemReorderGesture {
|
||||
}
|
||||
this.reorderList._reorderPrepare();
|
||||
|
||||
let item = reorderMark.getReorderNode();
|
||||
const item = reorderMark.getReorderNode();
|
||||
if (!item) {
|
||||
console.error('reorder node not found');
|
||||
return false;
|
||||
@@ -71,26 +71,26 @@ export class ItemReorderGesture {
|
||||
}
|
||||
|
||||
private onDragMove(ev: any) {
|
||||
let selectedItem = this.selectedItemEle;
|
||||
const selectedItem = this.selectedItemEle;
|
||||
if (!selectedItem) {
|
||||
return;
|
||||
}
|
||||
ev.preventDefault();
|
||||
|
||||
// Get coordinate
|
||||
let coord = pointerCoord(ev);
|
||||
let posY = coord.y;
|
||||
const coord = pointerCoord(ev);
|
||||
const posY = coord.y;
|
||||
|
||||
// Scroll if we reach the scroll margins
|
||||
let scrollPosition = this.scroll(posY);
|
||||
const scrollPosition = this.scroll(posY);
|
||||
|
||||
// Only perform hit test if we moved at least 30px from previous position
|
||||
if (Math.abs(posY - this.lastYcoord) > 30) {
|
||||
let overItem = this.itemForCoord(coord);
|
||||
var overItem = this.itemForCoord(coord);
|
||||
if (overItem) {
|
||||
let toIndex = indexForItem(overItem);
|
||||
var toIndex = indexForItem(overItem);
|
||||
if (toIndex !== undefined && (toIndex !== this.lastToIndex || this.emptyZone)) {
|
||||
let fromIndex = indexForItem(selectedItem);
|
||||
var fromIndex = indexForItem(selectedItem);
|
||||
this.lastToIndex = toIndex;
|
||||
this.lastYcoord = posY;
|
||||
this.emptyZone = false;
|
||||
@@ -102,12 +102,12 @@ export class ItemReorderGesture {
|
||||
}
|
||||
|
||||
// Update selected item position
|
||||
let ydiff = Math.round(posY - this.offset.y + scrollPosition);
|
||||
const ydiff = Math.round(posY - this.offset.y + scrollPosition);
|
||||
(<any>selectedItem.style)[this.plt.Css.transform] = `translateY(${ydiff}px)`;
|
||||
}
|
||||
|
||||
private onDragEnd(ev: any) {
|
||||
let selectedItem = this.selectedItemEle;
|
||||
const selectedItem = this.selectedItemEle;
|
||||
if (!selectedItem) {
|
||||
return;
|
||||
}
|
||||
@@ -116,9 +116,9 @@ export class ItemReorderGesture {
|
||||
ev.stopPropagation();
|
||||
}
|
||||
|
||||
let toIndex = this.lastToIndex;
|
||||
let fromIndex = indexForItem(selectedItem);
|
||||
let reorderInactive = () => {
|
||||
const toIndex = this.lastToIndex;
|
||||
const fromIndex = indexForItem(selectedItem);
|
||||
const reorderInactive = () => {
|
||||
this.selectedItemEle.style.transition = '';
|
||||
this.selectedItemEle.classList.remove(ITEM_REORDER_ACTIVE);
|
||||
this.selectedItemEle = null;
|
||||
@@ -134,7 +134,7 @@ export class ItemReorderGesture {
|
||||
}
|
||||
|
||||
private itemForCoord(coord: PointerCoordinates): HTMLElement {
|
||||
const sideOffset = this.plt.isRTL ? 100 : -100;
|
||||
const sideOffset = this.reorderList._isStart === this.plt.isRTL ? -100 : 100;
|
||||
const x = this.offset.x + sideOffset;
|
||||
const y = coord.y;
|
||||
const element = this.plt.getElementFromPoint(x, y);
|
||||
@@ -167,6 +167,7 @@ const SCROLL_JUMP = 10;
|
||||
const ITEM_REORDER_ACTIVE = 'reorder-active';
|
||||
|
||||
export interface ItemReorderGestureDelegate {
|
||||
_isStart: boolean;
|
||||
getNativeElement: () => any;
|
||||
_reorderPrepare: () => void;
|
||||
_scrollContent: (scrollPosition: number) => number;
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
@import "../../themes/ionic.globals";
|
||||
|
||||
$reorder-initial-transform: 160% !default;
|
||||
|
||||
// Item reorder
|
||||
// --------------------------------------------------
|
||||
|
||||
ion-reorder {
|
||||
@include transform(translate3d(160%, 0, 0));
|
||||
@include transform(translate3d($reorder-initial-transform, 0, 0));
|
||||
|
||||
display: none;
|
||||
|
||||
@@ -18,13 +20,18 @@ ion-reorder {
|
||||
font-size: 1.7em;
|
||||
opacity: .25;
|
||||
|
||||
|
||||
transition: transform 140ms ease-in;
|
||||
|
||||
pointer-events: all;
|
||||
touch-action: manipulation;
|
||||
}
|
||||
|
||||
.reorder-side-start ion-reorder {
|
||||
@include transform(translate3d(-$reorder-initial-transform, 0, 0));
|
||||
|
||||
order: -1;
|
||||
}
|
||||
|
||||
ion-reorder ion-icon {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@@ -142,12 +142,14 @@ export class ReorderIndexes {
|
||||
host: {
|
||||
'[class.reorder-enabled]': '_enableReorder',
|
||||
'[class.reorder-visible]': '_visibleReorder',
|
||||
'[class.reorder-side-start]': '_isStart'
|
||||
}
|
||||
})
|
||||
export class ItemReorder implements ItemReorderGestureDelegate {
|
||||
|
||||
_enableReorder: boolean = false;
|
||||
_visibleReorder: boolean = false;
|
||||
_isStart: boolean = false;
|
||||
_reorderGesture: ItemReorderGesture;
|
||||
_lastToIndex: number = -1;
|
||||
_element: HTMLElement;
|
||||
@@ -158,6 +160,14 @@ export class ItemReorder implements ItemReorderGestureDelegate {
|
||||
*/
|
||||
@Output() ionItemReorder: EventEmitter<ReorderIndexes> = new EventEmitter<ReorderIndexes>();
|
||||
|
||||
/**
|
||||
* @input {string} Which side of the view the ion-reorder should be placed. Default `"end"`.
|
||||
*/
|
||||
@Input('side')
|
||||
set side(side: 'start' | 'end') {
|
||||
this._isStart = side === 'start';
|
||||
}
|
||||
|
||||
constructor(
|
||||
private _plt: Platform,
|
||||
private _dom: DomController,
|
||||
|
||||
@@ -344,24 +344,24 @@ export class ItemSliding {
|
||||
|
||||
if (isFinal) {
|
||||
this.item.setElementStyle(platform.Css.transition, '');
|
||||
}
|
||||
|
||||
if (openAmount > 0) {
|
||||
var state = (openAmount >= (this._optsWidthRightSide + SWIPE_MARGIN))
|
||||
? SlidingState.Right | SlidingState.SwipeRight
|
||||
: SlidingState.Right;
|
||||
|
||||
this._setState(state);
|
||||
|
||||
} else if (openAmount < 0) {
|
||||
var state = (openAmount <= (-this._optsWidthLeftSide - SWIPE_MARGIN))
|
||||
? SlidingState.Left | SlidingState.SwipeLeft
|
||||
: SlidingState.Left;
|
||||
|
||||
this._setState(state);
|
||||
|
||||
} else {
|
||||
if (openAmount > 0) {
|
||||
var state = (openAmount >= (this._optsWidthRightSide + SWIPE_MARGIN))
|
||||
? SlidingState.Right | SlidingState.SwipeRight
|
||||
: SlidingState.Right;
|
||||
|
||||
this._setState(state);
|
||||
|
||||
} else if (openAmount < 0) {
|
||||
var state = (openAmount <= (-this._optsWidthLeftSide - SWIPE_MARGIN))
|
||||
? SlidingState.Left | SlidingState.SwipeLeft
|
||||
: SlidingState.Left;
|
||||
|
||||
this._setState(state);
|
||||
}
|
||||
}
|
||||
if (openAmount === 0) {
|
||||
assert(openAmount === 0, 'bad internal state');
|
||||
this._tmr = platform.timeout(() => {
|
||||
this._setState(SlidingState.Disabled);
|
||||
this._tmr = null;
|
||||
@@ -371,7 +371,7 @@ export class ItemSliding {
|
||||
}
|
||||
|
||||
this.item.setElementStyle(platform.Css.transform, `translate3d(${-openAmount}px,0,0)`);
|
||||
let ionDrag = this.ionDrag;
|
||||
const ionDrag = this.ionDrag;
|
||||
if (ionDrag.observers.length > 0) {
|
||||
ionDrag.emit(this);
|
||||
}
|
||||
|
||||
@@ -13,24 +13,30 @@
|
||||
|
||||
<ion-list [reorder]="isReordering" (ionItemReorder)="reorder($event)">
|
||||
<button ion-item *ngFor="let item of items" (click)="clickedButton(item)"
|
||||
[style.background]="'rgb('+(255-item*4)+','+(255-item*4)+','+(255-item*4)+')'"
|
||||
[style.min-height]="item*2+35+'px'">
|
||||
[style.background]="'rgb('+(255-item*4)+','+(255-item*4)+','+(255-item*4)+')'"
|
||||
[style.min-height]="item*2+35+'px'">
|
||||
{{item}}
|
||||
</button>
|
||||
</ion-list>
|
||||
|
||||
<ion-list [reorder]="isReordering" (ionItemReorder)="$event.applyTo(items)">
|
||||
<ion-item-sliding *ngFor="let item of items">
|
||||
<button ion-item (click)="clickedButton(item)">
|
||||
<h2>Sliding item {{item}}</h2>
|
||||
</button>
|
||||
<ion-item-options side="right" icon-start>
|
||||
<button ion-button color='danger'>
|
||||
<ion-icon name="trash"></ion-icon>
|
||||
Remove
|
||||
</button>
|
||||
</ion-item-options>
|
||||
</ion-item-sliding>
|
||||
</ion-list>
|
||||
<div *ngFor="let side of ['start', 'end']">
|
||||
<ion-list>
|
||||
<ion-list-header>{{side}}</ion-list-header>
|
||||
<ion-item-group [reorder]="isReordering" (ionItemReorder)="$event.applyTo(items)" [side]="side">
|
||||
<ion-item-sliding *ngFor="let item of items">
|
||||
<button ion-item (click)="clickedButton(item)">
|
||||
<h2>Sliding item {{item}}</h2>
|
||||
<div item-end>right</div>
|
||||
</button>
|
||||
<ion-item-options side="right" icon-start>
|
||||
<button ion-button color='danger'>
|
||||
<ion-icon name="trash"></ion-icon>
|
||||
Remove
|
||||
</button>
|
||||
</ion-item-options>
|
||||
</ion-item-sliding>
|
||||
</ion-item-group>
|
||||
</ion-list>
|
||||
</div>
|
||||
|
||||
</ion-content>
|
||||
|
||||
@@ -9,7 +9,7 @@ export class RootPage {
|
||||
isReordering: boolean = false;
|
||||
|
||||
constructor() {
|
||||
let nu = 9;
|
||||
let nu = 5;
|
||||
for (let i = 0; i < nu; i++) {
|
||||
this.items.push(i);
|
||||
}
|
||||
|
||||
@@ -79,8 +79,6 @@ export class LoadingCmp {
|
||||
}
|
||||
|
||||
ionViewDidEnter() {
|
||||
this._plt.focusOutActiveElement();
|
||||
|
||||
// If there is a duration, dismiss after that amount of time
|
||||
if ( this.d && this.d.duration ) {
|
||||
this.durationTimeout = setTimeout(() => this.dismiss('backdrop'), this.d.duration);
|
||||
|
||||
@@ -5,7 +5,6 @@ import { Config } from '../../config/config';
|
||||
import { DeepLinker } from '../../navigation/deep-linker';
|
||||
import { DomController } from '../../platform/dom-controller';
|
||||
import { GestureController } from '../../gestures/gesture-controller';
|
||||
import { Keyboard } from '../../platform/keyboard';
|
||||
import { Nav as INav } from '../../navigation/nav-interfaces';
|
||||
import { NavController } from '../../navigation/nav-controller';
|
||||
import { NavControllerBase } from '../../navigation/nav-controller-base';
|
||||
@@ -66,7 +65,6 @@ export class Nav extends NavControllerBase implements AfterViewInit, RootNode, I
|
||||
app: App,
|
||||
config: Config,
|
||||
plt: Platform,
|
||||
keyboard: Keyboard,
|
||||
elementRef: ElementRef,
|
||||
zone: NgZone,
|
||||
renderer: Renderer,
|
||||
@@ -77,7 +75,7 @@ export class Nav extends NavControllerBase implements AfterViewInit, RootNode, I
|
||||
domCtrl: DomController,
|
||||
errHandler: ErrorHandler
|
||||
) {
|
||||
super(parent, app, config, plt, keyboard, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, domCtrl, errHandler);
|
||||
super(parent, app, config, plt, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, domCtrl, errHandler);
|
||||
|
||||
if (viewCtrl) {
|
||||
// an ion-nav can also act as an ion-page within a parent ion-nav
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Nav } from '../nav';
|
||||
|
||||
import { GestureController } from '../../../gestures/gesture-controller';
|
||||
import { Keyboard } from '../../../platform/keyboard';
|
||||
import {
|
||||
mockApp,
|
||||
mockConfig,
|
||||
@@ -88,7 +87,6 @@ function getNav() {
|
||||
const app = mockApp(config, platform);
|
||||
const zone = mockZone();
|
||||
const dom = mockDomController(platform);
|
||||
const keyboard = new Keyboard(config, platform, zone, dom);
|
||||
const elementRef = mockElementRef();
|
||||
const renderer = mockRenderer();
|
||||
const componentFactoryResolver: any = null;
|
||||
@@ -101,7 +99,6 @@ function getNav() {
|
||||
app,
|
||||
config,
|
||||
platform,
|
||||
keyboard,
|
||||
elementRef,
|
||||
zone,
|
||||
renderer,
|
||||
|
||||
@@ -161,8 +161,6 @@ export class PickerCmp {
|
||||
}
|
||||
|
||||
ionViewDidEnter() {
|
||||
this._plt.focusOutActiveElement();
|
||||
|
||||
let focusableEle = this._elementRef.nativeElement.querySelector('button');
|
||||
if (focusableEle) {
|
||||
focusableEle.focus();
|
||||
|
||||
@@ -67,7 +67,6 @@ export class PopoverCmp {
|
||||
}
|
||||
|
||||
ionViewPreLoad() {
|
||||
this._plt.focusOutActiveElement();
|
||||
this._load(this._navParams.data.component);
|
||||
}
|
||||
|
||||
|
||||
@@ -123,6 +123,31 @@ import { SelectPopover, SelectPopoverOption } from './select-popover-component';
|
||||
* };
|
||||
* ```
|
||||
*
|
||||
* ### Object Value References
|
||||
*
|
||||
* When using objects for select values, it is possible for the identities of these objects to
|
||||
* change if they are coming from a server or database, while the selected value's identity
|
||||
* remains the same. For example, this can occur when an existing record with the desired object value
|
||||
* is loaded into the select, but the newly retrieved select options now have different identities. This will
|
||||
* result in the select appearing to have no value at all, even though the original selection in still intact.
|
||||
*
|
||||
* Using the `compareWith` `Input` is the solution to this problem
|
||||
*
|
||||
* ```html
|
||||
* <ion-item>
|
||||
* <ion-label>Employee</ion-label>
|
||||
* <ion-select [(ngModel)]="employee" [compareWith]="compareFn">
|
||||
* <ion-option *ngFor="let employee of employees" [value]="employee">{{employee.name}}</ion-option>
|
||||
* </ion-select>
|
||||
* </ion-item>
|
||||
* ```
|
||||
*
|
||||
* ```ts
|
||||
* compareFn(e1: Employee, e2: Employee): boolean {
|
||||
* return e1 && e2 ? e1.id === e2.id : e1 === e2;
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @demo /docs/demos/src/select/
|
||||
*/
|
||||
@Component({
|
||||
@@ -153,6 +178,7 @@ export class Select extends BaseInput<any> implements OnDestroy {
|
||||
_overlay: ActionSheet | Alert | Popover;
|
||||
_texts: string[] = [];
|
||||
_text: string = '';
|
||||
_compareWith: (o1: any, o2: any) => boolean = isCheckedProperty;
|
||||
|
||||
/**
|
||||
* @input {string} The text to display on the cancel button. Default: `Cancel`.
|
||||
@@ -187,6 +213,18 @@ export class Select extends BaseInput<any> implements OnDestroy {
|
||||
*/
|
||||
@Input() selectedText: string = '';
|
||||
|
||||
/**
|
||||
* @input {Function} The function that will be called to compare object values
|
||||
*/
|
||||
@Input()
|
||||
set compareWith(fn: (o1: any, o2: any) => boolean) {
|
||||
if (typeof fn !== 'function') {
|
||||
throw new Error(`compareWith must be a function, but received ${JSON.stringify(fn)}`);
|
||||
}
|
||||
this._compareWith = fn;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @output {any} Emitted when the selection was cancelled.
|
||||
*/
|
||||
@@ -448,7 +486,7 @@ export class Select extends BaseInput<any> implements OnDestroy {
|
||||
this._options.forEach(option => {
|
||||
// check this option if the option's value is in the values array
|
||||
option.selected = this.getValues().some(selectValue => {
|
||||
return isCheckedProperty(selectValue, option.value);
|
||||
return this._compareWith(selectValue, option.value);
|
||||
});
|
||||
|
||||
if (option.selected) {
|
||||
|
||||
@@ -15,10 +15,13 @@ export class TabHighlight {
|
||||
constructor(private _elementRef: ElementRef, private _dom: DomController) {}
|
||||
|
||||
select(tab: Tab) {
|
||||
if (!tab) {
|
||||
return;
|
||||
}
|
||||
const dom = this._dom;
|
||||
|
||||
dom.read(() => {
|
||||
const btnEle: HTMLElement = tab.btn.getElementRef().nativeElement;
|
||||
const btnEle: HTMLElement = tab.btn.getNativeElement();
|
||||
const transform = `translate3d(${btnEle.offsetLeft}px,0,0) scaleX(${btnEle.offsetWidth})`;
|
||||
|
||||
dom.write(() => {
|
||||
|
||||
@@ -6,7 +6,6 @@ import { DeepLinker } from '../../navigation/deep-linker';
|
||||
import { DomController } from '../../platform/dom-controller';
|
||||
import { GestureController } from '../../gestures/gesture-controller';
|
||||
import { isTrueProperty } from '../../util/util';
|
||||
import { Keyboard } from '../../platform/keyboard';
|
||||
import { Tab as ITab } from '../../navigation/nav-interfaces';
|
||||
import { NavControllerBase } from '../../navigation/nav-controller-base';
|
||||
import { NavOptions } from '../../navigation/nav-util';
|
||||
@@ -255,7 +254,6 @@ export class Tab extends NavControllerBase implements ITab {
|
||||
app: App,
|
||||
config: Config,
|
||||
plt: Platform,
|
||||
keyboard: Keyboard,
|
||||
elementRef: ElementRef,
|
||||
zone: NgZone,
|
||||
renderer: Renderer,
|
||||
@@ -268,7 +266,7 @@ export class Tab extends NavControllerBase implements ITab {
|
||||
errHandler: ErrorHandler
|
||||
) {
|
||||
// A Tab is a NavController for its child pages
|
||||
super(parent, app, config, plt, keyboard, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, _dom, errHandler);
|
||||
super(parent, app, config, plt, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, _dom, errHandler);
|
||||
|
||||
this.id = parent.add(this);
|
||||
this._tabsHideOnSubPages = config.getBoolean('tabsHideOnSubPages');
|
||||
|
||||
@@ -302,7 +302,7 @@ $tabs-md-tab-icon-size: 2.4rem !default;
|
||||
transition-duration: 300ms;
|
||||
}
|
||||
|
||||
.tabs-md[tabsHighlight=true][tabsPlacement=bottom] .tab-highlight {
|
||||
.tabs-md[tabsHighlight=true][tabsPlacement=bottom] > .tabbar > .tab-highlight {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -98,6 +98,7 @@ export class Toast extends ViewController {
|
||||
*/
|
||||
present(navOptions: NavOptions = {}): Promise<any> {
|
||||
navOptions.disableApp = false;
|
||||
navOptions.keyboardClose = false;
|
||||
return this._app.present(this, navOptions, PORTAL_TOAST);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ import { GestureController } from '../gestures/gesture-controller';
|
||||
import { isBlank, isNumber, isPresent, isTrueProperty, assert, removeArrayItem } from '../util/util';
|
||||
import { isViewController, ViewController } from './view-controller';
|
||||
import { Ion } from '../components/ion';
|
||||
import { Keyboard } from '../platform/keyboard';
|
||||
import { NavController } from './nav-controller';
|
||||
import { NavParams } from './nav-params';
|
||||
import { Platform } from '../platform/platform';
|
||||
@@ -63,7 +62,6 @@ export class NavControllerBase extends Ion implements NavController {
|
||||
public _app: App,
|
||||
public config: Config,
|
||||
public plt: Platform,
|
||||
public _keyboard: Keyboard,
|
||||
elementRef: ElementRef,
|
||||
public _zone: NgZone,
|
||||
renderer: Renderer,
|
||||
@@ -760,7 +758,7 @@ export class NavControllerBase extends Ion implements NavController {
|
||||
if (opts.keyboardClose !== false) {
|
||||
// the keyboard is still open!
|
||||
// no problem, let's just close for them
|
||||
this._keyboard.close();
|
||||
this.plt.focusOutActiveElement();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
|
||||
// Global app direction
|
||||
$app-direction: null !default;
|
||||
$app-direction: ltr !default;
|
||||
|
||||
|
||||
// Global font path
|
||||
|
||||
@@ -142,7 +142,7 @@
|
||||
}
|
||||
|
||||
@mixin multi-dir() {
|
||||
@if $app-direction == null {
|
||||
@if $app-direction == multi {
|
||||
$root: #{&};
|
||||
@at-root [dir="ltr"], [dir="rtl"] {
|
||||
#{$root} {
|
||||
@@ -155,7 +155,7 @@
|
||||
}
|
||||
|
||||
@mixin rtl() {
|
||||
@if $app-direction == null {
|
||||
@if $app-direction == multi {
|
||||
$root: #{&};
|
||||
@at-root [dir="rtl"] {
|
||||
#{$root} {
|
||||
@@ -168,7 +168,7 @@
|
||||
}
|
||||
|
||||
@mixin ltr() {
|
||||
@if $app-direction == null {
|
||||
@if $app-direction == multi {
|
||||
$root: #{&};
|
||||
@at-root [dir="ltr"] {
|
||||
#{$root} {
|
||||
|
||||
@@ -10,7 +10,6 @@ import { DomController } from '../platform/dom-controller';
|
||||
import { GestureController } from '../gestures/gesture-controller';
|
||||
import { Haptic } from '../tap-click/haptic';
|
||||
import { IonicApp } from '../components/app/app-root';
|
||||
import { Keyboard } from '../platform/keyboard';
|
||||
import { Menu } from '../components/menu/menu';
|
||||
import { NavOptions } from '../navigation/nav-util';
|
||||
import { NavControllerBase } from '../navigation/nav-controller-base';
|
||||
@@ -403,7 +402,6 @@ export function mockNavController(): NavControllerBase {
|
||||
let app = mockApp(config, platform);
|
||||
let zone = mockZone();
|
||||
let dom = mockDomController(platform);
|
||||
let keyboard = new Keyboard(config, platform, zone, dom);
|
||||
let elementRef = mockElementRef();
|
||||
let renderer = mockRenderer();
|
||||
let componentFactoryResolver: any = null;
|
||||
@@ -415,7 +413,6 @@ export function mockNavController(): NavControllerBase {
|
||||
app,
|
||||
config,
|
||||
platform,
|
||||
keyboard,
|
||||
elementRef,
|
||||
zone,
|
||||
renderer,
|
||||
@@ -447,7 +444,6 @@ export function mockNavController(): NavControllerBase {
|
||||
export function mockOverlayPortal(app: App, config: Config, plt: MockPlatform): OverlayPortal {
|
||||
let zone = mockZone();
|
||||
let dom = mockDomController(plt);
|
||||
let keyboard = new Keyboard(config, plt, zone, dom);
|
||||
let elementRef = mockElementRef();
|
||||
let renderer = mockRenderer();
|
||||
let componentFactoryResolver: any = null;
|
||||
@@ -460,7 +456,6 @@ export function mockOverlayPortal(app: App, config: Config, plt: MockPlatform):
|
||||
app,
|
||||
config,
|
||||
plt,
|
||||
keyboard,
|
||||
elementRef,
|
||||
zone,
|
||||
renderer,
|
||||
@@ -480,7 +475,6 @@ export function mockTab(parentTabs: Tabs): Tab {
|
||||
let app = (<any>parentTabs)._app || mockApp(config, platform);
|
||||
let zone = mockZone();
|
||||
let dom = mockDomController(platform);
|
||||
let keyboard = new Keyboard(config, platform, zone, dom);
|
||||
let elementRef = mockElementRef();
|
||||
let renderer = mockRenderer();
|
||||
let changeDetectorRef = mockChangeDetectorRef();
|
||||
@@ -493,7 +487,6 @@ export function mockTab(parentTabs: Tabs): Tab {
|
||||
app,
|
||||
config,
|
||||
platform,
|
||||
keyboard,
|
||||
elementRef,
|
||||
zone,
|
||||
renderer,
|
||||
|
||||
Reference in New Issue
Block a user