@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/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: '79cd09dd43183008f470b31abb7b3606f653a98b', class: {
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,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ionic/core",
3
- "version": "8.8.4-dev.11775576543.172b7b99",
3
+ "version": "8.8.4-dev.11775666666.132201b7",
4
4
  "description": "Base components for Ionic",
5
5
  "engines": {
6
6
  "node": ">= 16"