Compare commits

...

5 Commits

Author SHA1 Message Date
Maria Hutt
ea77945b1e feat(reorder-group): if else timeout 2023-11-17 16:59:40 -08:00
Maria Hutt
8d11b3eb3f feat(reorder-group): more cleanup 2023-11-14 13:17:12 -08:00
Maria Hutt
263e8ddcf5 feat(reorder-group): clean timeout 2023-11-14 11:50:51 -08:00
Maria Hutt
8d81101d6d feat(reorder-group): use createGesture 2023-11-14 11:11:42 -08:00
Maria Hutt
7ceacc3820 feat(reorder-group): long press 2023-11-10 14:02:21 -08:00
3 changed files with 178 additions and 37 deletions

View File

@@ -2407,6 +2407,7 @@ export namespace Components {
interface IonReorder {
}
interface IonReorderGroup {
"activate": 'tap' | 'press';
/**
* Completes the reorder operation. Must be called by the `ionItemReorder` event. If a list of items is passed, the list will be reordered and returned in the proper order. If no parameters are passed or if `true` is passed in, the reorder will complete and the item will remain in the position it was dragged to. If `false` is passed, the reorder will complete and the item will bounce back to its original position.
* @param listOrReorder A list of items to be sorted and returned in the new order or a boolean of whether or not the reorder should reposition the item.
@@ -7104,6 +7105,7 @@ declare namespace LocalJSX {
interface IonReorder {
}
interface IonReorderGroup {
"activate"?: 'tap' | 'press';
/**
* If `true`, the reorder will be hidden.
*/

View File

@@ -36,6 +36,11 @@ export class ReorderGroup implements ComponentInterface {
private containerTop = 0;
private containerBottom = 0;
private longPressTimeout: any;
private pressed = false;
// the amount of time in milliseconds that the user must press and hold before the reorder is initiated
private longPressDuration = 500;
@State() state = ReorderGroupState.Idle;
@Element() el!: HTMLElement;
@@ -51,6 +56,11 @@ export class ReorderGroup implements ComponentInterface {
}
}
// default is `tap` to maintain backwards compatibility
// `tap` will initiate the reorder immediately
// `press` will initiate the reorder after the `longPressDuration`
@Prop() activate: 'tap' | 'press' = 'tap'
/**
* Event that needs to be listened to in order to complete the reorder action.
* Once the event has been emitted, the `complete()` method then needs
@@ -125,52 +135,78 @@ export class ReorderGroup implements ComponentInterface {
private onStart(ev: GestureDetail) {
ev.event.preventDefault();
const item = (this.selectedItemEl = ev.data);
const heights = this.cachedHeights;
heights.length = 0;
const el = this.el;
const children: any = el.children;
if (!children || children.length === 0) {
return;
}
let sum = 0;
for (let i = 0; i < children.length; i++) {
const child = children[i];
sum += child.offsetHeight;
heights.push(sum);
child.$ionIndex = i;
}
const box = el.getBoundingClientRect();
this.containerTop = box.top;
this.containerBottom = box.bottom;
if (this.scrollEl) {
const scrollBox = this.scrollEl.getBoundingClientRect();
this.scrollElInitial = this.scrollEl.scrollTop;
this.scrollElTop = scrollBox.top + AUTO_SCROLL_MARGIN;
this.scrollElBottom = scrollBox.bottom - AUTO_SCROLL_MARGIN;
if (this.activate === 'press') {
this.longPressTimeout = setTimeout(() => {
this.pressed = true;
this.clearGestureTimeout();
console.log('hits')
this.selectingItem(ev);
}, this.longPressDuration);
} else {
this.scrollElInitial = 0;
this.scrollElTop = 0;
this.scrollElBottom = 0;
console.log('nope')
this.selectingItem(ev);
}
this.lastToIndex = indexForItem(item);
this.selectedItemHeight = item.offsetHeight;
this.state = ReorderGroupState.Active;
item.classList.add(ITEM_REORDER_SELECTED);
hapticSelectionStart();
}
private selectingItem(ev: GestureDetail) {
const item = (this.selectedItemEl = ev.data);
const heights = this.cachedHeights;
heights.length = 0;
const el = this.el;
const children: any = el.children;
if (!children || children.length === 0) {
return;
}
let sum = 0;
for (let i = 0; i < children.length; i++) {
const child = children[i];
sum += child.offsetHeight;
heights.push(sum);
child.$ionIndex = i;
}
const box = el.getBoundingClientRect();
this.containerTop = box.top;
this.containerBottom = box.bottom;
if (this.scrollEl) {
const scrollBox = this.scrollEl.getBoundingClientRect();
this.scrollElInitial = this.scrollEl.scrollTop;
this.scrollElTop = scrollBox.top + AUTO_SCROLL_MARGIN;
this.scrollElBottom = scrollBox.bottom - AUTO_SCROLL_MARGIN;
} else {
this.scrollElInitial = 0;
this.scrollElTop = 0;
this.scrollElBottom = 0;
}
this.lastToIndex = indexForItem(item);
this.selectedItemHeight = item.offsetHeight;
this.state = ReorderGroupState.Active;
item.classList.add(ITEM_REORDER_SELECTED);
hapticSelectionStart();
}
private clearGestureTimeout = () => {
if (this.longPressTimeout) {
clearTimeout(this.longPressTimeout);
this.longPressTimeout = undefined;
}
};
private onMove(ev: GestureDetail) {
const selectedItem = this.selectedItemEl;
if (!selectedItem) {
return;
}
if (this.activate === 'press' && !this.pressed) {
return;
}
// Scroll if we reach the scroll margins
const scroll = this.autoscroll(ev.currentY);
@@ -191,6 +227,8 @@ export class ReorderGroup implements ComponentInterface {
// Update selected item position
selectedItem.style.transform = `translateY(${deltaY}px)`;
this.clearGestureTimeout();
}
private onEnd() {
@@ -215,10 +253,18 @@ export class ReorderGroup implements ComponentInterface {
}
hapticSelectionEnd();
if (this.activate === 'press' && !this.pressed) {
return;
}
this.pressed = false;
this.clearGestureTimeout();
}
private completeReorder(listOrReorder?: boolean | any[]): any {
const selectedItemEl = this.selectedItemEl;
console.log('end')
if (selectedItemEl && this.state === ReorderGroupState.Complete) {
const children = this.el.children as any;
const len = children.length;

View File

@@ -0,0 +1,93 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8" />
<title>Reorder - Basic</title>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
<script src="../../../../../scripts/testing/scripts.js"></script>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
</head>
<body>
<ion-app>
<ion-header>
<ion-toolbar>
<ion-title>Reorder - Long Press</ion-title>
</ion-toolbar>
</ion-header>
<ion-content id="content">
<p>Reorder with icons</p>
<ion-list>
<ion-reorder-group id="reorder-icons" activate="press" disabled="false">
<ion-item button>
<ion-label> Item 1 (default ion-reorder) </ion-label>
<ion-reorder slot="end"></ion-reorder>
</ion-item>
<ion-item-sliding>
<ion-item button>
<ion-label> Item 2 (default ion-reorder with ion-item-sliding) </ion-label>
<ion-reorder slot="end"></ion-reorder>
</ion-item>
<ion-item-options side="start">
<ion-item-option>Favorite</ion-item-option>
<ion-item-option color="danger">Share</ion-item-option>
</ion-item-options>
<ion-item-options side="end">
<ion-item-option>Unread</ion-item-option>
</ion-item-options>
</ion-item-sliding>
</ion-reorder-group>
</ion-list>
<p>Reorder with wrapper</p>
<ion-list>
<ion-reorder-group id="reorder-wrappers" disabled="false" activate="press" long-press-duration="5000">
<ion-reorder>
<ion-item>
<ion-label> Item 1 </ion-label>
</ion-item>
</ion-reorder>
<ion-reorder>
<ion-item-sliding>
<ion-item button>
<ion-label> Item 2 (default ion-reorder with ion-item-sliding) </ion-label>
</ion-item>
<ion-item-options side="start">
<ion-item-option>Favorite</ion-item-option>
<ion-item-option color="danger">Share</ion-item-option>
</ion-item-options>
<ion-item-options side="end">
<ion-item-option>Unread</ion-item-option>
</ion-item-options>
</ion-item-sliding>
</ion-reorder>
</ion-list>
</ion-content>
</ion-app>
<script>
const reorderGroup = document.getElementById('reorder-icons');
reorderGroup.addEventListener('ionItemReorder', ({ detail }) => {
console.log('Dragged from index', detail.from, 'to', detail.to);
detail.complete();
});
const reorderGroup2 = document.getElementById('reorder-wrappers');
reorderGroup2.addEventListener('ionItemReorder', ({ detail }) => {
console.log('Dragged from index', detail.from, 'to', detail.to);
detail.complete();
});
</script>
</body>
</html>