Skip to content

Commit bfdc898

Browse files
committed
feat(item): sliding items work with list reorder
1 parent b7826ba commit bfdc898

File tree

15 files changed

+494
-349
lines changed

15 files changed

+494
-349
lines changed

demos/item-sliding/index.ts

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,52 @@
1-
import { Component } from '@angular/core';
1+
import { Component, ViewEncapsulation } from '@angular/core';
22

33
import { ionicBootstrap, ItemSliding, NavController, Toast } from 'ionic-angular';
44

55

66
@Component({
7-
templateUrl: 'main.html'
7+
templateUrl: 'main.html',
8+
encapsulation: ViewEncapsulation.None
89
})
910
class ApiDemoPage {
1011
chats: any[];
1112
logins: any[];
13+
editButton: string = 'Edit';
14+
editing: boolean = false;
1215

1316
constructor(private nav: NavController) {
1417
this.chats = [
18+
{
19+
img: './avatar-cher.png',
20+
name: 'Cher',
21+
message: 'Ugh. As if.',
22+
time: '9:38 pm'
23+
}, {
24+
img: './avatar-dionne.png',
25+
name: 'Dionne',
26+
message: 'Mr. Hall was way harsh.',
27+
time: '8:59 pm'
28+
}, {
29+
img: './avatar-murray.png',
30+
name: 'Murray',
31+
message: 'Excuse me, "Ms. Dione."',
32+
time: 'Wed'
33+
},
34+
{
35+
img: './avatar-cher.png',
36+
name: 'Cher',
37+
message: 'Ugh. As if.',
38+
time: '9:38 pm'
39+
}, {
40+
img: './avatar-dionne.png',
41+
name: 'Dionne',
42+
message: 'Mr. Hall was way harsh.',
43+
time: '8:59 pm'
44+
}, {
45+
img: './avatar-murray.png',
46+
name: 'Murray',
47+
message: 'Excuse me, "Ms. Dione."',
48+
time: 'Wed'
49+
},
1550
{
1651
img: './avatar-cher.png',
1752
name: 'Cher',
@@ -49,6 +84,15 @@ class ApiDemoPage {
4984
}];
5085
}
5186

87+
toggleEdit() {
88+
this.editing = !this.editing;
89+
if (this.editing) {
90+
this.editButton = 'Done';
91+
} else {
92+
this.editButton = 'Edit';
93+
}
94+
}
95+
5296
more(item: ItemSliding) {
5397
console.log('More');
5498
item.close();

demos/item-sliding/main.html

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,24 @@
22

33
<ion-navbar>
44
<ion-title>Item Sliding</ion-title>
5+
<ion-buttons end>
6+
<button (click)="toggleEdit()">{{editButton}}</button>
7+
</ion-buttons>
58
</ion-navbar>
69

710
</ion-header>
811

912

10-
<ion-content class="outer-content">
13+
<ion-content class="outer-content" fullscreen>
1114

12-
<ion-list class="chat-sliding-demo">
15+
<ion-list class="chat-sliding-demo" [sliding]="!editing">
1316
<ion-list-header>
1417
Chats
1518
</ion-list-header>
1619

17-
<ion-item-sliding *ngFor="let chat of chats; let ref = index" [ref]="ref" #item>
20+
<ion-item-group [reorder]="editing">
21+
22+
<ion-item-sliding *ngFor="let chat of chats" #item>
1823
<ion-item>
1924
<ion-avatar item-left>
2025
<img [src]="chat.img">
@@ -41,13 +46,14 @@ <h2>{{chat.name}}</h2>
4146
</button>
4247
</ion-item-options>
4348

44-
<ion-item-options side="left">
49+
<ion-item-options side="left" (ionSwipe)="archive(item)">
4550
<button primary expandable (click)="archive(item)">
4651
<ion-icon name="archive"></ion-icon>
4752
Archive
4853
</button>
4954
</ion-item-options>
5055
</ion-item-sliding>
56+
</ion-item-group>
5157
</ion-list>
5258

5359
<ion-list class="login-sliding-demo">
@@ -87,6 +93,12 @@ <h2>{{login.name}}</h2>
8793
#download-spinner {
8894
display: none;
8995
}
96+
97+
div.toolbar-background {
98+
background-color: rgba(255, 255, 255, 0.65);
99+
-webkit-backdrop-filter: saturate(180%) blur(20px);
100+
backdrop-filter: saturate(180%) blur(20px);
101+
}
90102

91103
svg circle {
92104
stroke: white;
Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {Item} from './item';
2-
import {List} from '../list/list';
2+
import {Reorder} from '../item/item-reorder';
33
import {UIEventManager} from '../../util/ui-event-manager';
44
import {closest, Coordinates, pointerCoord, CSS, nativeRaf} from '../../util/dom';
55

@@ -12,7 +12,6 @@ const ITEM_REORDER_ACTIVE = 'reorder-active';
1212
* @private
1313
*/
1414
export class ItemReorderGesture {
15-
private selectedItem: Item = null;
1615
private selectedItemEle: HTMLElement = null;
1716
private selectedItemHeight: number;
1817

@@ -26,7 +25,7 @@ export class ItemReorderGesture {
2625

2726
private events: UIEventManager = new UIEventManager(false);
2827

29-
constructor(public list: List) {
28+
constructor(public list: Reorder) {
3029
let element = this.list.getNativeElement();
3130
this.events.pointerEvents(element,
3231
this.onDragStart.bind(this),
@@ -35,32 +34,30 @@ export class ItemReorderGesture {
3534
}
3635

3736
private onDragStart(ev: any): boolean {
38-
let itemEle = ev.target;
39-
if (itemEle.nodeName !== 'ION-REORDER') {
37+
let reorderElement = ev.target;
38+
if (reorderElement.nodeName !== 'ION-REORDER') {
4039
return false;
4140
}
4241

43-
let item = <Item> itemEle['$ionComponent'];
42+
let item = reorderElement['$ionReorderNode'];
4443
if (!item) {
45-
console.error('item does not contain ion component');
44+
console.error('item does not contain ion ionReorderNode');
4645
return false;
4746
}
4847
ev.preventDefault();
4948

5049
// Preparing state
51-
this.selectedItem = item;
52-
this.selectedItemEle = item.getNativeElement();
53-
this.selectedItemHeight = item.height();
54-
this.lastToIndex = item.index;
55-
this.lastYcoord = -100;
50+
this.selectedItemEle = item;
51+
this.selectedItemHeight = item.offsetHeight;
52+
this.lastYcoord = this.lastToIndex = -100;
5653

5754
this.windowHeight = window.innerHeight - AUTO_SCROLL_MARGIN;
5855
this.lastScrollPosition = this.list.scrollContent(0);
5956

6057
this.offset = pointerCoord(ev);
6158
this.offset.y += this.lastScrollPosition;
6259

63-
item.setCssClass(ITEM_REORDER_ACTIVE, true);
60+
item.classList.add(ITEM_REORDER_ACTIVE);
6461
this.list.reorderStart();
6562
return true;
6663
}
@@ -83,9 +80,9 @@ export class ItemReorderGesture {
8380
if (Math.abs(posY - this.lastYcoord) > 30) {
8481
let overItem = this.itemForCoord(coord);
8582
if (overItem) {
86-
let toIndex = overItem.index;
87-
if (toIndex !== this.lastToIndex || this.emptyZone) {
88-
let fromIndex = this.selectedItem.index;
83+
let toIndex = indexForItem(overItem);
84+
if (toIndex && (toIndex !== this.lastToIndex || this.emptyZone)) {
85+
let fromIndex = indexForItem(this.selectedItemEle);
8986
this.lastToIndex = toIndex;
9087
this.lastYcoord = posY;
9188
this.emptyZone = false;
@@ -96,40 +93,25 @@ export class ItemReorderGesture {
9693
}
9794
}
9895

99-
// Update selected item position
96+
// Update selected item position
10097
let ydiff = Math.round(posY - this.offset.y + scrollPosition);
10198
selectedItem.style[CSS.transform] = `translateY(${ydiff}px)`;
10299
}
103-
100+
104101
private onDragEnd() {
105102
if (!this.selectedItemEle) {
106103
return;
107104
}
108105

109-
nativeRaf(() => {
110-
let toIndex = this.lastToIndex;
111-
let fromIndex = this.selectedItem.index;
112-
this.selectedItem.setCssClass(ITEM_REORDER_ACTIVE, false);
113-
this.selectedItem = null;
114-
this.selectedItemEle = null;
115-
this.list.reorderEmit(fromIndex, toIndex);
116-
});
106+
let toIndex = this.lastToIndex;
107+
let fromIndex = indexForItem(this.selectedItemEle);
108+
this.selectedItemEle.classList.remove(ITEM_REORDER_ACTIVE);
109+
this.selectedItemEle = null;
110+
this.list.reorderEmit(fromIndex, toIndex);
117111
}
118112

119-
private itemForCoord(coord: Coordinates): Item {
120-
let element = <HTMLElement>document.elementFromPoint(this.offset.x - 100, coord.y);
121-
if (!element) {
122-
return null;
123-
}
124-
if (element.nodeName !== 'ION-ITEM') {
125-
return null;
126-
}
127-
let item = <Item>(<any>element)['$ionComponent'];
128-
if (!item) {
129-
console.error('item does not have $ionComponent');
130-
return null;
131-
}
132-
return item;
113+
private itemForCoord(coord: Coordinates): HTMLElement {
114+
return itemForPosition(this.offset.x - 100, coord.y);
133115
}
134116

135117
private scroll(posY: number): number {
@@ -141,8 +123,6 @@ export class ItemReorderGesture {
141123
return this.lastScrollPosition;
142124
}
143125

144-
145-
146126
/**
147127
* @private
148128
*/
@@ -153,3 +133,25 @@ export class ItemReorderGesture {
153133
this.list = null;
154134
}
155135
}
136+
137+
function itemForPosition(x: number, y: number): HTMLElement {
138+
let element = <HTMLElement>document.elementFromPoint(x, y);
139+
if (!element) {
140+
return null;
141+
}
142+
if (element.nodeName !== 'ION-ITEM' && !element.hasAttribute('ion-item')) {
143+
return null;
144+
}
145+
if (indexForItem(element)) {
146+
return element;
147+
}
148+
let parent = element.parentNode;
149+
if (indexForItem(parent)) {
150+
return <HTMLElement>parent;
151+
}
152+
return null;
153+
}
154+
155+
function indexForItem(element: any): number {
156+
return element['$ionIndex'];
157+
}

src/components/item/item-reorder.scss

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ ion-reorder {
2424

2525
.reorder-enabled {
2626

27-
.item {
27+
.item, .item-wrapper {
28+
transition: transform 300ms;
29+
2830
will-change: transform;
2931
}
3032

@@ -40,6 +42,7 @@ ion-reorder {
4042
}
4143

4244

45+
.item-wrapper.reorder-active,
4346
.item.reorder-active {
4447
z-index: 4;
4548

0 commit comments

Comments
 (0)