@ionic/core 8.8.4-dev.11775576543.172b7b99 → 8.8.4-dev.11775666666.132201b7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/ion-item-sliding.js +1 -1
- package/dist/cjs/ion-item-option_3.cjs.entry.js +137 -1
- package/dist/collection/components/item-sliding/item-sliding.js +137 -1
- package/dist/collection/utils/test/playwright/drag-element.js +3 -4
- package/dist/docs.json +1 -1
- package/dist/esm/ion-item-option_3.entry.js +137 -1
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/{p-727bb80c.entry.js → p-b0c54b4c.entry.js} +1 -1
- package/dist/types/components/item-sliding/item-sliding.d.ts +28 -1
- package/dist/types/utils/test/playwright/drag-element.d.ts +1 -1
- package/hydrate/index.js +137 -1
- package/hydrate/index.mjs +137 -1
- package/package.json +1 -1
package/hydrate/index.mjs
CHANGED
|
@@ -22148,10 +22148,18 @@ class ItemSliding {
|
|
|
22148
22148
|
this.disabledChanged();
|
|
22149
22149
|
}
|
|
22150
22150
|
disconnectedCallback() {
|
|
22151
|
+
var _a;
|
|
22151
22152
|
if (this.gesture) {
|
|
22152
22153
|
this.gesture.destroy();
|
|
22153
22154
|
this.gesture = undefined;
|
|
22154
22155
|
}
|
|
22156
|
+
if (this.tmr !== undefined) {
|
|
22157
|
+
clearTimeout(this.tmr);
|
|
22158
|
+
this.tmr = undefined;
|
|
22159
|
+
}
|
|
22160
|
+
// Abort any in-progress animation. The abort handler rejects the pending
|
|
22161
|
+
// promise, causing animateFullSwipe's finally block to run cleanup.
|
|
22162
|
+
(_a = this.animationAbortController) === null || _a === void 0 ? void 0 : _a.abort();
|
|
22155
22163
|
this.item = null;
|
|
22156
22164
|
this.leftOptions = this.rightOptions = undefined;
|
|
22157
22165
|
if (openSlidingItem === this.el) {
|
|
@@ -22185,6 +22193,9 @@ class ItemSliding {
|
|
|
22185
22193
|
*/
|
|
22186
22194
|
async open(side) {
|
|
22187
22195
|
var _a;
|
|
22196
|
+
if ((this.state & 128 /* SlidingState.AnimatingFullSwipe */) !== 0) {
|
|
22197
|
+
return;
|
|
22198
|
+
}
|
|
22188
22199
|
/**
|
|
22189
22200
|
* It is possible for the item to be added to the DOM
|
|
22190
22201
|
* after the item-sliding component was created. As a result,
|
|
@@ -22236,6 +22247,9 @@ class ItemSliding {
|
|
|
22236
22247
|
* Close the sliding item. Items can also be closed from the [List](./list).
|
|
22237
22248
|
*/
|
|
22238
22249
|
async close() {
|
|
22250
|
+
if ((this.state & 128 /* SlidingState.AnimatingFullSwipe */) !== 0) {
|
|
22251
|
+
return;
|
|
22252
|
+
}
|
|
22239
22253
|
this.setOpenAmount(0, true);
|
|
22240
22254
|
}
|
|
22241
22255
|
/**
|
|
@@ -22266,6 +22280,111 @@ class ItemSliding {
|
|
|
22266
22280
|
return this.rightOptions;
|
|
22267
22281
|
}
|
|
22268
22282
|
}
|
|
22283
|
+
/**
|
|
22284
|
+
* Check if the given item options element contains at least one expandable, non-disabled option.
|
|
22285
|
+
*/
|
|
22286
|
+
hasExpandableOptions(options) {
|
|
22287
|
+
if (!options)
|
|
22288
|
+
return false;
|
|
22289
|
+
const optionElements = options.querySelectorAll('ion-item-option');
|
|
22290
|
+
return Array.from(optionElements).some((option) => {
|
|
22291
|
+
return option.expandable === true && !option.disabled;
|
|
22292
|
+
});
|
|
22293
|
+
}
|
|
22294
|
+
/**
|
|
22295
|
+
* Returns a Promise that resolves after `ms` milliseconds, or rejects if the
|
|
22296
|
+
* given AbortSignal is fired before the timer expires.
|
|
22297
|
+
*/
|
|
22298
|
+
delay(ms, signal) {
|
|
22299
|
+
return new Promise((resolve, reject) => {
|
|
22300
|
+
const id = setTimeout(resolve, ms);
|
|
22301
|
+
signal.addEventListener('abort', () => {
|
|
22302
|
+
clearTimeout(id);
|
|
22303
|
+
reject(new DOMException('Animation cancelled', 'AbortError'));
|
|
22304
|
+
}, { once: true });
|
|
22305
|
+
});
|
|
22306
|
+
}
|
|
22307
|
+
/**
|
|
22308
|
+
* Animate the item to a specific position using CSS transitions.
|
|
22309
|
+
* Returns a Promise that resolves when the animation completes, or rejects if
|
|
22310
|
+
* the given AbortSignal is fired.
|
|
22311
|
+
*/
|
|
22312
|
+
animateToPosition(position, duration, signal) {
|
|
22313
|
+
return new Promise((resolve, reject) => {
|
|
22314
|
+
if (!this.item) {
|
|
22315
|
+
return resolve();
|
|
22316
|
+
}
|
|
22317
|
+
this.item.style.transition = `transform ${duration}ms ease-out`;
|
|
22318
|
+
this.item.style.transform = `translate3d(${-position}px, 0, 0)`;
|
|
22319
|
+
const id = setTimeout(resolve, duration);
|
|
22320
|
+
signal.addEventListener('abort', () => {
|
|
22321
|
+
clearTimeout(id);
|
|
22322
|
+
reject(new DOMException('Animation cancelled', 'AbortError'));
|
|
22323
|
+
}, { once: true });
|
|
22324
|
+
});
|
|
22325
|
+
}
|
|
22326
|
+
/**
|
|
22327
|
+
* Calculate the swipe threshold distance required to trigger a full swipe animation.
|
|
22328
|
+
* Returns the maximum options width plus a margin to ensure it's achievable.
|
|
22329
|
+
*/
|
|
22330
|
+
getSwipeThreshold(direction) {
|
|
22331
|
+
const maxWidth = direction === 'end' ? this.optsWidthRightSide : this.optsWidthLeftSide;
|
|
22332
|
+
return maxWidth + SWIPE_MARGIN;
|
|
22333
|
+
}
|
|
22334
|
+
/**
|
|
22335
|
+
* Animate the item through a full swipe sequence: off-screen → trigger action → return.
|
|
22336
|
+
* This is used when an expandable option is swiped beyond the threshold.
|
|
22337
|
+
*/
|
|
22338
|
+
async animateFullSwipe(direction) {
|
|
22339
|
+
const abortController = new AbortController();
|
|
22340
|
+
this.animationAbortController = abortController;
|
|
22341
|
+
const { signal } = abortController;
|
|
22342
|
+
// Prevent interruption during animation
|
|
22343
|
+
if (this.gesture) {
|
|
22344
|
+
this.gesture.enable(false);
|
|
22345
|
+
}
|
|
22346
|
+
try {
|
|
22347
|
+
const options = direction === 'end' ? this.rightOptions : this.leftOptions;
|
|
22348
|
+
// Trigger expandable state without moving the item
|
|
22349
|
+
// Set state directly so expandable option fills its container, starting from
|
|
22350
|
+
// the exact position where the user released, without any visual snap.
|
|
22351
|
+
this.state =
|
|
22352
|
+
direction === 'end'
|
|
22353
|
+
? 8 /* SlidingState.End */ | 32 /* SlidingState.SwipeEnd */ | 128 /* SlidingState.AnimatingFullSwipe */
|
|
22354
|
+
: 16 /* SlidingState.Start */ | 64 /* SlidingState.SwipeStart */ | 128 /* SlidingState.AnimatingFullSwipe */;
|
|
22355
|
+
await this.delay(100, signal);
|
|
22356
|
+
// Animate off-screen while maintaining the expanded state
|
|
22357
|
+
const offScreenDistance = direction === 'end' ? window.innerWidth : -window.innerWidth;
|
|
22358
|
+
await this.animateToPosition(offScreenDistance, 250, signal);
|
|
22359
|
+
// Trigger action
|
|
22360
|
+
if (options) {
|
|
22361
|
+
options.fireSwipeEvent();
|
|
22362
|
+
}
|
|
22363
|
+
// Small delay before returning
|
|
22364
|
+
await this.delay(300, signal);
|
|
22365
|
+
// Return to closed state
|
|
22366
|
+
await this.animateToPosition(0, 250, signal);
|
|
22367
|
+
}
|
|
22368
|
+
catch (_a) {
|
|
22369
|
+
// Animation was aborted (e.g. component disconnected). finally handles cleanup.
|
|
22370
|
+
}
|
|
22371
|
+
finally {
|
|
22372
|
+
this.animationAbortController = undefined;
|
|
22373
|
+
// Reset state
|
|
22374
|
+
if (this.item) {
|
|
22375
|
+
this.item.style.transition = '';
|
|
22376
|
+
this.item.style.transform = '';
|
|
22377
|
+
}
|
|
22378
|
+
this.openAmount = 0;
|
|
22379
|
+
this.state = 2 /* SlidingState.Disabled */;
|
|
22380
|
+
if (openSlidingItem === this.el) {
|
|
22381
|
+
openSlidingItem = undefined;
|
|
22382
|
+
}
|
|
22383
|
+
if (this.gesture) {
|
|
22384
|
+
this.gesture.enable(!this.disabled);
|
|
22385
|
+
}
|
|
22386
|
+
}
|
|
22387
|
+
}
|
|
22269
22388
|
async updateOptions() {
|
|
22270
22389
|
var _a;
|
|
22271
22390
|
const options = this.el.querySelectorAll('ion-item-options');
|
|
@@ -22372,6 +22491,23 @@ class ItemSliding {
|
|
|
22372
22491
|
if (contentEl) {
|
|
22373
22492
|
resetContentScrollY(contentEl, initialContentScrollY);
|
|
22374
22493
|
}
|
|
22494
|
+
// Check for full swipe conditions with expandable options
|
|
22495
|
+
const rawSwipeDistance = Math.abs(gesture.deltaX);
|
|
22496
|
+
const direction = gesture.deltaX < 0 ? 'end' : 'start';
|
|
22497
|
+
const options = direction === 'end' ? this.rightOptions : this.leftOptions;
|
|
22498
|
+
const hasExpandable = this.hasExpandableOptions(options);
|
|
22499
|
+
const shouldTriggerFullSwipe = hasExpandable &&
|
|
22500
|
+
(rawSwipeDistance > this.getSwipeThreshold(direction) ||
|
|
22501
|
+
(Math.abs(gesture.velocityX) > 0.5 &&
|
|
22502
|
+
rawSwipeDistance > (direction === 'end' ? this.optsWidthRightSide : this.optsWidthLeftSide) * 0.5));
|
|
22503
|
+
if (shouldTriggerFullSwipe) {
|
|
22504
|
+
this.animateFullSwipe(direction).catch(() => {
|
|
22505
|
+
if (this.gesture) {
|
|
22506
|
+
this.gesture.enable(!this.disabled);
|
|
22507
|
+
}
|
|
22508
|
+
});
|
|
22509
|
+
return;
|
|
22510
|
+
}
|
|
22375
22511
|
const velocity = gesture.velocityX;
|
|
22376
22512
|
let restingPoint = this.openAmount > 0 ? this.optsWidthRightSide : -this.optsWidthLeftSide;
|
|
22377
22513
|
// Check if the drag didn't clear the buttons mid-point
|
|
@@ -22479,7 +22615,7 @@ class ItemSliding {
|
|
|
22479
22615
|
}
|
|
22480
22616
|
render() {
|
|
22481
22617
|
const theme = getIonTheme(this);
|
|
22482
|
-
return (hAsync(Host, { key: '
|
|
22618
|
+
return (hAsync(Host, { key: 'c945f30d9f7deb90d22064d4059e2b08f35614be', class: {
|
|
22483
22619
|
[theme]: true,
|
|
22484
22620
|
'item-sliding-active-slide': this.state !== 2 /* SlidingState.Disabled */,
|
|
22485
22621
|
'item-sliding-active-options-end': (this.state & 8 /* SlidingState.End */) !== 0,
|