@ionic/core 8.7.17-dev.11771359170.1fda0949 → 8.7.17-dev.11771870864.19b2cde1

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.
Files changed (51) hide show
  1. package/components/ion-datetime.js +5 -5
  2. package/components/ion-segment-view.js +11 -5
  3. package/components/ion-select.js +3 -3
  4. package/components/ion-textarea.js +4 -4
  5. package/components/modal.js +206 -43
  6. package/dist/cjs/ion-datetime_3.cjs.entry.js +5 -5
  7. package/dist/cjs/ion-modal.cjs.entry.js +206 -43
  8. package/dist/cjs/ion-segment-view.cjs.entry.js +10 -5
  9. package/dist/cjs/ion-select_3.cjs.entry.js +3 -3
  10. package/dist/cjs/ion-textarea.cjs.entry.js +2 -2
  11. package/dist/cjs/ionic.cjs.js +1 -1
  12. package/dist/cjs/loader.cjs.js +1 -1
  13. package/dist/collection/components/datetime/datetime.js +5 -12
  14. package/dist/collection/components/modal/gestures/sheet.js +108 -11
  15. package/dist/collection/components/modal/gestures/swipe-to-close.js +54 -1
  16. package/dist/collection/components/modal/modal.js +98 -31
  17. package/dist/collection/components/segment-view/segment-view.ios.css +2 -1
  18. package/dist/collection/components/segment-view/segment-view.js +28 -3
  19. package/dist/collection/components/segment-view/segment-view.md.css +2 -1
  20. package/dist/collection/components/select/select.js +6 -3
  21. package/dist/collection/components/textarea/textarea.js +4 -4
  22. package/dist/docs.json +115 -51
  23. package/dist/esm/ion-datetime_3.entry.js +5 -5
  24. package/dist/esm/ion-modal.entry.js +206 -43
  25. package/dist/esm/ion-segment-view.entry.js +10 -5
  26. package/dist/esm/ion-select_3.entry.js +3 -3
  27. package/dist/esm/ion-textarea.entry.js +2 -2
  28. package/dist/esm/ionic.js +1 -1
  29. package/dist/esm/loader.js +1 -1
  30. package/dist/html.html-data.json +4 -0
  31. package/dist/ionic/ionic.esm.js +1 -1
  32. package/dist/ionic/p-0f418a37.entry.js +4 -0
  33. package/dist/ionic/p-1838bed5.entry.js +4 -0
  34. package/dist/ionic/p-29721c43.entry.js +4 -0
  35. package/dist/ionic/p-9a2d390d.entry.js +4 -0
  36. package/dist/ionic/{p-c19f63d0.entry.js → p-e1d1f3cc.entry.js} +1 -1
  37. package/dist/types/components/datetime/datetime.d.ts +0 -7
  38. package/dist/types/components/modal/gestures/sheet.d.ts +2 -2
  39. package/dist/types/components/modal/gestures/swipe-to-close.d.ts +2 -2
  40. package/dist/types/components/modal/modal-interface.d.ts +7 -0
  41. package/dist/types/components/modal/modal.d.ts +17 -1
  42. package/dist/types/components/segment-view/segment-view.d.ts +4 -0
  43. package/dist/types/components/select/select.d.ts +3 -0
  44. package/dist/types/components.d.ts +27 -2
  45. package/hydrate/index.js +233 -68
  46. package/hydrate/index.mjs +233 -68
  47. package/package.json +1 -1
  48. package/dist/ionic/p-020af078.entry.js +0 -4
  49. package/dist/ionic/p-88367362.entry.js +0 -4
  50. package/dist/ionic/p-91840a80.entry.js +0 -4
  51. package/dist/ionic/p-9dcc3ae4.entry.js +0 -4
@@ -7,7 +7,7 @@ import { clamp, getElementRoot, raf } from "../../../utils/helpers";
7
7
  import { FOCUS_TRAP_DISABLE_CLASS } from "../../../utils/overlays";
8
8
  import { getBackdropValueForSheet } from "../utils";
9
9
  import { calculateSpringStep, handleCanDismiss } from "./utils";
10
- export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, backdropBreakpoint, animation, breakpoints = [], expandToScroll, getCurrentBreakpoint, onDismiss, onBreakpointChange) => {
10
+ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, backdropBreakpoint, animation, breakpoints = [], expandToScroll, getCurrentBreakpoint, onDismiss, onBreakpointChange, onDragStart, onDragMove, onDragEnd) => {
11
11
  // Defaults for the sheet swipe animation
12
12
  const defaultBackdrop = [
13
13
  { offset: 0, opacity: 'var(--backdrop-opacity)' },
@@ -270,6 +270,7 @@ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpo
270
270
  baseEl.focus();
271
271
  });
272
272
  animation.progressStart(true, 1 - currentBreakpoint);
273
+ onDragStart();
273
274
  };
274
275
  const onMove = (detail) => {
275
276
  /**
@@ -338,6 +339,15 @@ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpo
338
339
  : step;
339
340
  offset = clamp(0.0001, processedStep, maxStep);
340
341
  animation.progressStep(offset);
342
+ const closest = calculateClosestBreakpoint(detail.velocityY, detail.deltaY);
343
+ const eventDetail = {
344
+ currentY: detail.currentY,
345
+ deltaY: detail.deltaY,
346
+ velocityY: detail.velocityY,
347
+ progress: calculateProgress(detail.currentY),
348
+ currentBreakpoint: closest,
349
+ };
350
+ onDragMove(eventDetail);
341
351
  };
342
352
  const onEnd = (detail) => {
343
353
  /**
@@ -356,16 +366,7 @@ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpo
356
366
  swapFooterPosition('stationary');
357
367
  return;
358
368
  }
359
- /**
360
- * When the gesture releases, we need to determine
361
- * the closest breakpoint to snap to.
362
- */
363
- const velocity = detail.velocityY;
364
- const threshold = (detail.deltaY + velocity * 350) / height;
365
- const diff = currentBreakpoint - threshold;
366
- const closest = breakpoints.reduce((a, b) => {
367
- return Math.abs(b - diff) < Math.abs(a - diff) ? b : a;
368
- });
369
+ const closest = calculateClosestBreakpoint(detail.velocityY, detail.deltaY);
369
370
  moveSheetToBreakpoint({
370
371
  breakpoint: closest,
371
372
  breakpointOffset: offset,
@@ -376,6 +377,14 @@ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpo
376
377
  */
377
378
  animated: true,
378
379
  });
380
+ const eventDetail = {
381
+ currentY: detail.currentY,
382
+ deltaY: detail.deltaY,
383
+ velocityY: detail.velocityY,
384
+ progress: calculateProgress(detail.currentY),
385
+ currentBreakpoint: closest,
386
+ };
387
+ onDragEnd(eventDetail);
379
388
  };
380
389
  const moveSheetToBreakpoint = (options) => {
381
390
  const { breakpoint, canDismiss, breakpointOffset, animated } = options;
@@ -515,6 +524,94 @@ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpo
515
524
  .progressEnd(1, 0, animated ? 500 : 0);
516
525
  });
517
526
  };
527
+ /**
528
+ * Calculates the closest breakpoint based on the current velocity and deltaY.
529
+ * This determines where the sheet should snap to when the user releases the
530
+ * gesture.
531
+ *
532
+ * @param velocityY The current velocity of the gesture in the Y direction.
533
+ * @param deltaY The change in Y position since the gesture started.
534
+ * @returns The closest breakpoint value.
535
+ */
536
+ const calculateClosestBreakpoint = (velocityY, deltaY) => {
537
+ const threshold = (deltaY + velocityY * 350) / height;
538
+ const diff = currentBreakpoint - threshold;
539
+ const closest = breakpoints.reduce((a, b) => {
540
+ return Math.abs(b - diff) < Math.abs(a - diff) ? b : a;
541
+ });
542
+ return closest;
543
+ };
544
+ /**
545
+ * Calculates the progress of the swipe gesture.
546
+ *
547
+ * The progress is a value between 0 and 1 that represents how far
548
+ * the swipe has progressed towards closing the modal.
549
+ *
550
+ * A value closer to 1 means the modal is closer to being opened,
551
+ * while a value closer to 0 means the modal is closer to being closed.
552
+ *
553
+ * @param currentY The current Y position of the gesture
554
+ * @returns The progress of the sheet gesture
555
+ */
556
+ const calculateProgress = (currentY) => {
557
+ const minBreakpoint = breakpoints[0];
558
+ const maxBreakpoint = breakpoints[breakpoints.length - 1];
559
+ // Convert breakpoints to pixel Y coordinates
560
+ /**
561
+ * The lowest point the sheet can be dragged to aka the point at which
562
+ * the sheet is fully closed.
563
+ */
564
+ const maxY = convertBreakpointToY(minBreakpoint);
565
+ /**
566
+ * The highest point the sheet can be dragged to aka the point at which
567
+ * the sheet is fully open.
568
+ */
569
+ const minY = convertBreakpointToY(maxBreakpoint);
570
+ // The total distance between the fully open and fully closed positions.
571
+ const totalDistance = maxY - minY;
572
+ // The distance from the current position to the fully closed position.
573
+ const distanceFromBottom = maxY - currentY;
574
+ /**
575
+ * The progress represents how far the sheet is from the bottom relative
576
+ * to the total distance. When the user starts swiping up, the progress
577
+ * should be close to 1, and when the user has swiped all the way down,
578
+ * the progress should be close to 0.
579
+ */
580
+ const progress = distanceFromBottom / totalDistance;
581
+ // Round to the nearest thousandth to avoid returning very small decimal
582
+ const roundedProgress = Math.round(progress * 1000) / 1000;
583
+ return Math.max(0, Math.min(1, roundedProgress));
584
+ };
585
+ /**
586
+ * Converts a breakpoint value (0 to 1) into a pixel Y coordinate
587
+ * on the screen.
588
+ *
589
+ * @param breakpoint The breakpoint value (e.g., 0.5 for half-open)
590
+ * @returns The pixel Y coordinate on the screen
591
+ */
592
+ const convertBreakpointToY = (breakpoint) => {
593
+ const rect = baseEl.getBoundingClientRect();
594
+ const modalHeight = rect.height;
595
+ // The bottom of the screen.
596
+ const viewportBottom = window.innerHeight;
597
+ /**
598
+ * The active height is how much of the modal is actually showing
599
+ * on the screen for this specific breakpoint.
600
+ */
601
+ const activeHeight = modalHeight * breakpoint;
602
+ /**
603
+ * To find the Y coordinate, start at the bottom of the screen
604
+ * and move up by the active height of the modal.
605
+ *
606
+ * A breakpoint of 1.0 means the active height is the full modal height
607
+ * (fully open). A breakpoint of 0.0 means the active height is 0
608
+ * (fully closed).
609
+ *
610
+ * Since screen Y coordinates get smaller as you go up, we subtract the
611
+ * active height from the viewport bottom.
612
+ */
613
+ return viewportBottom - activeHeight;
614
+ };
518
615
  const gesture = createGesture({
519
616
  el: wrapperEl,
520
617
  gestureName: 'modalSheet',
@@ -12,7 +12,7 @@ import { calculateSpringStep, handleCanDismiss } from "./utils";
12
12
  export const SwipeToCloseDefaults = {
13
13
  MIN_PRESENTING_SCALE: 0.915,
14
14
  };
15
- export const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss) => {
15
+ export const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss, onDragStart, onDragMove, onDragEnd) => {
16
16
  /**
17
17
  * The step value at which a card modal
18
18
  * is eligible for dismissing via gesture.
@@ -122,6 +122,7 @@ export const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismi
122
122
  disableContentScrollY(contentEl);
123
123
  }
124
124
  animation.progressStart(true, isOpen ? 1 : 0);
125
+ onDragStart();
125
126
  };
126
127
  const onMove = (detail) => {
127
128
  const { deltaY } = detail;
@@ -189,6 +190,13 @@ export const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismi
189
190
  setCardStatusBarDark();
190
191
  }
191
192
  lastStep = clampedStep;
193
+ const eventDetail = {
194
+ currentY: detail.currentY,
195
+ deltaY: detail.deltaY,
196
+ velocityY: detail.velocityY,
197
+ progress: calculateProgress(el, detail.deltaY),
198
+ };
199
+ onDragMove(eventDetail);
192
200
  };
193
201
  const onEnd = (detail) => {
194
202
  const velocity = detail.velocityY;
@@ -247,6 +255,13 @@ export const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismi
247
255
  else if (shouldComplete) {
248
256
  onDismiss();
249
257
  }
258
+ const eventDetail = {
259
+ currentY: detail.currentY,
260
+ deltaY: detail.deltaY,
261
+ velocityY: detail.velocityY,
262
+ progress: calculateProgress(el, detail.deltaY),
263
+ };
264
+ onDragEnd(eventDetail);
250
265
  };
251
266
  const gesture = createGesture({
252
267
  el,
@@ -264,3 +279,41 @@ export const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismi
264
279
  const computeDuration = (remaining, velocity) => {
265
280
  return clamp(400, remaining / Math.abs(velocity * 1.1), 500);
266
281
  };
282
+ /**
283
+ * Calculates the progress of the swipe gesture.
284
+ *
285
+ * The progress is a value between 0 and 1 that represents how far
286
+ * the swipe has progressed towards closing the modal.
287
+ *
288
+ * A value closer to 1 means the modal is closer to being opened,
289
+ * while a value closer to 0 means the modal is closer to being closed.
290
+ *
291
+ * @param el The modal
292
+ * @param deltaY The change in Y position (positive when dragging down, negative when dragging up)
293
+ * @returns The progress of the swipe gesture
294
+ */
295
+ const calculateProgress = (el, deltaY) => {
296
+ const windowHeight = window.innerHeight;
297
+ // Position when fully open
298
+ const modalTop = el.getBoundingClientRect().top;
299
+ /**
300
+ * The distance between the top of the modal and the bottom of the screen
301
+ * is the total distance the modal needs to travel to be fully closed.
302
+ */
303
+ const totalDistance = windowHeight - modalTop;
304
+ /**
305
+ * The pull percentage is how far the user has swiped compared to the total
306
+ * distance needed to close the modal.
307
+ */
308
+ const pullPercentage = deltaY / totalDistance;
309
+ /**
310
+ * The progress is the inverse of the pull percentage because
311
+ * when the user starts swiping up, the progress should be close to 1,
312
+ * and when the user has swiped all the way down, the progress should be
313
+ * close to 0.
314
+ */
315
+ const progress = 1 - pullPercentage;
316
+ // Round to the nearest thousandth to avoid returning very small decimal
317
+ const roundedProgress = Math.round(progress * 1000) / 1000;
318
+ return Math.max(0, Math.min(1, roundedProgress));
319
+ };
@@ -501,32 +501,7 @@ export class Modal {
501
501
  return;
502
502
  }
503
503
  const statusBarStyle = (_a = this.statusBarStyle) !== null && _a !== void 0 ? _a : StatusBarStyle.Default;
504
- this.gesture = createSwipeToCloseGesture(el, ani, statusBarStyle, () => {
505
- /**
506
- * While the gesture animation is finishing
507
- * it is possible for a user to tap the backdrop.
508
- * This would result in the dismiss animation
509
- * being played again. Typically this is avoided
510
- * by setting `presented = false` on the overlay
511
- * component; however, we cannot do that here as
512
- * that would prevent the element from being
513
- * removed from the DOM.
514
- */
515
- this.gestureAnimationDismissing = true;
516
- /**
517
- * Reset the status bar style as the dismiss animation
518
- * starts otherwise the status bar will be the wrong
519
- * color for the duration of the dismiss animation.
520
- * The dismiss method does this as well, but
521
- * in this case it's only called once the animation
522
- * has finished.
523
- */
524
- setCardStatusBarDefault(this.statusBarStyle);
525
- this.animation.onFinish(async () => {
526
- await this.dismiss(undefined, GESTURE);
527
- this.gestureAnimationDismissing = false;
528
- });
529
- });
504
+ this.gesture = createSwipeToCloseGesture(el, ani, statusBarStyle, () => this.cardOnDismiss(), () => this.onDragStart(), (detail) => this.onDragMove(detail), (detail) => this.onDragEnd(detail));
530
505
  this.gesture.enable(true);
531
506
  }
532
507
  initSheetGesture() {
@@ -547,7 +522,7 @@ export class Modal {
547
522
  this.currentBreakpoint = breakpoint;
548
523
  this.ionBreakpointDidChange.emit({ breakpoint });
549
524
  }
550
- });
525
+ }, () => this.onDragStart(), (detail) => this.onDragMove(detail), (detail) => this.onDragEnd(detail));
551
526
  this.gesture = gesture;
552
527
  this.moveSheetToBreakpoint = moveSheetToBreakpoint;
553
528
  this.gesture.enable(true);
@@ -644,6 +619,32 @@ export class Modal {
644
619
  this.gestureAnimationDismissing = false;
645
620
  });
646
621
  }
622
+ cardOnDismiss() {
623
+ /**
624
+ * While the gesture animation is finishing
625
+ * it is possible for a user to tap the backdrop.
626
+ * This would result in the dismiss animation
627
+ * being played again. Typically this is avoided
628
+ * by setting `presented = false` on the overlay
629
+ * component; however, we cannot do that here as
630
+ * that would prevent the element from being
631
+ * removed from the DOM.
632
+ */
633
+ this.gestureAnimationDismissing = true;
634
+ /**
635
+ * Reset the status bar style as the dismiss animation
636
+ * starts otherwise the status bar will be the wrong
637
+ * color for the duration of the dismiss animation.
638
+ * The dismiss method does this as well, but
639
+ * in this case it's only called once the animation
640
+ * has finished.
641
+ */
642
+ setCardStatusBarDefault(this.statusBarStyle);
643
+ this.animation.onFinish(async () => {
644
+ await this.dismiss(undefined, GESTURE);
645
+ this.gestureAnimationDismissing = false;
646
+ });
647
+ }
647
648
  /**
648
649
  * Dismiss the modal overlay after it has been presented.
649
650
  * This is a no-op if the overlay has not been presented yet. If you want
@@ -967,6 +968,15 @@ export class Modal {
967
968
  (_a = this.parentRemovalObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
968
969
  this.parentRemovalObserver = undefined;
969
970
  }
971
+ onDragStart() {
972
+ this.ionDragStart.emit();
973
+ }
974
+ onDragMove(detail) {
975
+ this.ionDragMove.emit(detail);
976
+ }
977
+ onDragEnd(detail) {
978
+ this.ionDragEnd.emit(detail);
979
+ }
970
980
  render() {
971
981
  const { handle, isSheetModal, presentingElement, htmlAttributes, handleBehavior, inheritedAttributes, focusTrap, expandToScroll, } = this;
972
982
  const showHandle = handle !== false && isSheetModal;
@@ -974,20 +984,20 @@ export class Modal {
974
984
  const isCardModal = presentingElement !== undefined && mode === 'ios';
975
985
  const isHandleCycle = handleBehavior === 'cycle';
976
986
  const isSheetModalWithHandle = isSheetModal && showHandle;
977
- return (h(Host, Object.assign({ key: '87328006ea6c75ebc518ace300438492a567223e', "no-router": true,
987
+ return (h(Host, Object.assign({ key: 'bca3cbdb2ce8e5127d27eae7494c434aaeddaf88', "no-router": true,
978
988
  // Allow the modal to be navigable when the handle is focusable
979
989
  tabIndex: isHandleCycle && isSheetModalWithHandle ? 0 : -1 }, htmlAttributes, { style: {
980
990
  zIndex: `${20000 + this.overlayIndex}`,
981
- }, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, [`modal-no-expand-scroll`]: isSheetModal && !expandToScroll, 'overlay-hidden': true, [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle, onFocus: this.onModalFocus }), h("ion-backdrop", { key: 'ee94ff8e09b691dd4ad4e4db1720f06bc3c5a469', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { key: 'bffd69b4635c22d9f249725bd952c1e93d5615c7', class: "modal-shadow" }), h("div", Object.assign({ key: '1d394d3c68916e464ff1fbf5242419f4a3d3cca1',
991
+ }, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, [`modal-no-expand-scroll`]: isSheetModal && !expandToScroll, 'overlay-hidden': true, [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle, onFocus: this.onModalFocus }), h("ion-backdrop", { key: 'b1c4112123d84d8a9b9d455bcc17d884f99d9f28', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { key: '080c8e6d37b311a1b5ad2655d99f18668abae211', class: "modal-shadow" }), h("div", Object.assign({ key: '8ba05e9520b1b5529bf0caeb766da5bf612d4d14',
982
992
  /*
983
993
  role and aria-modal must be used on the
984
994
  same element. They must also be set inside the
985
995
  shadow DOM otherwise ion-button will not be highlighted
986
996
  when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
987
997
  */
988
- role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: '2dcf58792018e557e0c323baad2d672bc99c0bb1', class: "modal-handle",
998
+ role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: '2d2d5d731f55755f32ebcbf557f97486dc6202a6', class: "modal-handle",
989
999
  // Prevents the handle from receiving keyboard focus when it does not cycle
990
- tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle", ref: (el) => (this.dragHandleEl = el) })), h("slot", { key: '44164b1e8710c3895400ad9f44ecd99873874ad5', onSlotchange: this.onSlotChange }))));
1000
+ tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle", ref: (el) => (this.dragHandleEl = el) })), h("slot", { key: 'c717d19865dafba02e15db79bc0662c5d89e96fd', onSlotchange: this.onSlotChange }))));
991
1001
  }
992
1002
  static get is() { return "ion-modal"; }
993
1003
  static get encapsulation() { return "shadow"; }
@@ -1734,6 +1744,63 @@ export class Modal {
1734
1744
  "resolved": "void",
1735
1745
  "references": {}
1736
1746
  }
1747
+ }, {
1748
+ "method": "ionDragStart",
1749
+ "name": "ionDragStart",
1750
+ "bubbles": true,
1751
+ "cancelable": true,
1752
+ "composed": true,
1753
+ "docs": {
1754
+ "tags": [],
1755
+ "text": "Event that is emitted when the sheet modal or card modal gesture starts."
1756
+ },
1757
+ "complexType": {
1758
+ "original": "void",
1759
+ "resolved": "void",
1760
+ "references": {}
1761
+ }
1762
+ }, {
1763
+ "method": "ionDragMove",
1764
+ "name": "ionDragMove",
1765
+ "bubbles": true,
1766
+ "cancelable": true,
1767
+ "composed": true,
1768
+ "docs": {
1769
+ "tags": [],
1770
+ "text": "Event that is emitted when the sheet modal or card modal gesture moves."
1771
+ },
1772
+ "complexType": {
1773
+ "original": "ModalDragEventDetail",
1774
+ "resolved": "ModalDragEventDetail",
1775
+ "references": {
1776
+ "ModalDragEventDetail": {
1777
+ "location": "import",
1778
+ "path": "./modal-interface",
1779
+ "id": "src/components/modal/modal-interface.ts::ModalDragEventDetail"
1780
+ }
1781
+ }
1782
+ }
1783
+ }, {
1784
+ "method": "ionDragEnd",
1785
+ "name": "ionDragEnd",
1786
+ "bubbles": true,
1787
+ "cancelable": true,
1788
+ "composed": true,
1789
+ "docs": {
1790
+ "tags": [],
1791
+ "text": "Event that is emitted when the sheet modal or card modal gesture ends."
1792
+ },
1793
+ "complexType": {
1794
+ "original": "ModalDragEventDetail",
1795
+ "resolved": "ModalDragEventDetail",
1796
+ "references": {
1797
+ "ModalDragEventDetail": {
1798
+ "location": "import",
1799
+ "path": "./modal-interface",
1800
+ "id": "src/components/modal/modal-interface.ts::ModalDragEventDetail"
1801
+ }
1802
+ }
1803
+ }
1737
1804
  }];
1738
1805
  }
1739
1806
  static get methods() {
@@ -14,7 +14,8 @@
14
14
  display: none;
15
15
  }
16
16
 
17
- :host(.segment-view-disabled) {
17
+ :host(.segment-view-disabled),
18
+ :host(.segment-view-swipe-disabled) {
18
19
  touch-action: none;
19
20
  overflow-x: hidden;
20
21
  }
@@ -11,6 +11,10 @@ export class SegmentView {
11
11
  * If `true`, the segment view cannot be interacted with.
12
12
  */
13
13
  this.disabled = false;
14
+ /**
15
+ * If `true`, users will be able to swipe the segment view to navigate between segment contents.
16
+ */
17
+ this.swipeGesture = true;
14
18
  }
15
19
  handleScroll(ev) {
16
20
  var _a;
@@ -98,11 +102,12 @@ export class SegmentView {
98
102
  return Array.from(this.el.querySelectorAll('ion-segment-content'));
99
103
  }
100
104
  render() {
101
- const { disabled, isManualScroll } = this;
102
- return (h(Host, { key: 'e180b67bb3143a5f4611fb358c037be6fc782a8f', class: {
105
+ const { disabled, isManualScroll, swipeGesture } = this;
106
+ return (h(Host, { key: '565cccce7f0cfc4c71508777cc60292d6f24334f', class: {
103
107
  'segment-view-disabled': disabled,
104
108
  'segment-view-scroll-disabled': isManualScroll === false,
105
- } }, h("slot", { key: '41c11d6a7406a10f5c64a2e73abfc072afd8fc73' })));
109
+ 'segment-view-swipe-disabled': swipeGesture === false,
110
+ } }, h("slot", { key: '4118c240364467302b8f593e33c37837ea5d06f0' })));
106
111
  }
107
112
  static get is() { return "ion-segment-view"; }
108
113
  static get encapsulation() { return "shadow"; }
@@ -139,6 +144,26 @@ export class SegmentView {
139
144
  "reflect": false,
140
145
  "attribute": "disabled",
141
146
  "defaultValue": "false"
147
+ },
148
+ "swipeGesture": {
149
+ "type": "boolean",
150
+ "mutable": false,
151
+ "complexType": {
152
+ "original": "boolean",
153
+ "resolved": "boolean",
154
+ "references": {}
155
+ },
156
+ "required": false,
157
+ "optional": false,
158
+ "docs": {
159
+ "tags": [],
160
+ "text": "If `true`, users will be able to swipe the segment view to navigate between segment contents."
161
+ },
162
+ "getter": false,
163
+ "setter": false,
164
+ "reflect": false,
165
+ "attribute": "swipe-gesture",
166
+ "defaultValue": "true"
142
167
  }
143
168
  };
144
169
  }
@@ -14,7 +14,8 @@
14
14
  display: none;
15
15
  }
16
16
 
17
- :host(.segment-view-disabled) {
17
+ :host(.segment-view-disabled),
18
+ :host(.segment-view-swipe-disabled) {
18
19
  touch-action: none;
19
20
  overflow-x: hidden;
20
21
  }
@@ -27,6 +27,9 @@ import { getIonMode } from "../../global/ionic-global";
27
27
  * @part supporting-text - Supporting text displayed beneath the select.
28
28
  * @part helper-text - Supporting text displayed beneath the select when the select is valid.
29
29
  * @part error-text - Supporting text displayed beneath the select when the select is invalid and touched.
30
+ * @part bottom - The container element for helper text, error text, and counter.
31
+ * @part wrapper - The clickable label element that wraps the entire form field (label text, slots, selected values or placeholder, and toggle icons).
32
+ * @part inner - The inner element of the wrapper that manages the slots, selected values or placeholder, and toggle icons.
30
33
  */
31
34
  export class Select {
32
35
  constructor() {
@@ -803,7 +806,7 @@ export class Select {
803
806
  if (!hasHintText) {
804
807
  return;
805
808
  }
806
- return h("div", { class: "select-bottom" }, this.renderHintText());
809
+ return (h("div", { class: "select-bottom", part: "bottom" }, this.renderHintText()));
807
810
  }
808
811
  render() {
809
812
  const { disabled, el, isExpanded, expandedIcon, labelPlacement, justify, placeholder, fill, shape, name, value, hasFocus, } = this;
@@ -834,7 +837,7 @@ export class Select {
834
837
  * TODO(FW-5592): Remove hasStartEndSlots condition
835
838
  */
836
839
  const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || isExpanded || hasStartEndSlots));
837
- return (h(Host, { key: 'b7fa907f8fbc54fd63e2d07a9bb5156d94fd5057', onClick: this.onClick, class: createColorClasses(this.color, {
840
+ return (h(Host, { key: 'ada627c442ebcdd4a4ee96e5f5f3ec0e2181d689', onClick: this.onClick, class: createColorClasses(this.color, {
838
841
  [mode]: true,
839
842
  'in-item': inItem,
840
843
  'in-item-color': hostContext('ion-item.ion-color', el),
@@ -852,7 +855,7 @@ export class Select {
852
855
  [`select-justify-${justify}`]: justifyEnabled,
853
856
  [`select-shape-${shape}`]: shape !== undefined,
854
857
  [`select-label-placement-${labelPlacement}`]: true,
855
- }) }, h("label", { key: '11137e6a8b0374e93923ddb5a4629972ded5f43c', class: "select-wrapper", id: "select-label", onClick: this.onLabelClick }, this.renderLabelContainer(), h("div", { key: '99e3c09b5e6c2e7be493ed5834f991fffe45cfff', class: "select-wrapper-inner" }, h("slot", { key: '740f0e5a913cb0209d5acae31c33a6ed8f672dfc', name: "start" }), h("div", { key: 'b20e33c8b60915a5194948fcf8e22d7789f0b050', class: "native-wrapper", ref: (el) => (this.nativeWrapperEl = el), part: "container" }, this.renderSelectText(), this.renderListbox()), h("slot", { key: '0199f338185d5fa2cdd977bb20516746bd9ddad5', name: "end" }), !hasFloatingOrStackedLabel && this.renderSelectIcon()), hasFloatingOrStackedLabel && this.renderSelectIcon(), shouldRenderHighlight && h("div", { key: '3b54de893cc8fc66df8588cee22e30d6f10850b3', class: "select-highlight" })), this.renderBottomContent()));
858
+ }) }, h("label", { key: 'd1c4663e740cfdcd28f90a5e0297d05cf42cc4df', class: "select-wrapper", id: "select-label", onClick: this.onLabelClick, part: "wrapper" }, this.renderLabelContainer(), h("div", { key: 'cd671e0b543378e7b822ce649a7b4006094b111f', class: "select-wrapper-inner", part: "inner" }, h("slot", { key: '48e7df0c517a382195736273019b855e422a82ed', name: "start" }), h("div", { key: '822747ffb9101cb1d3ff947da55bc2e8e1f2c8e2', class: "native-wrapper", ref: (el) => (this.nativeWrapperEl = el), part: "container" }, this.renderSelectText(), this.renderListbox()), h("slot", { key: '349200d9f9ebf25e0b8708ac8683a76e7c6ed33c', name: "end" }), !hasFloatingOrStackedLabel && this.renderSelectIcon()), hasFloatingOrStackedLabel && this.renderSelectIcon(), shouldRenderHighlight && h("div", { key: '7eefb70d431cb9c01cc408d35349f7a3d0f2af35', class: "select-highlight" })), this.renderBottomContent()));
856
859
  }
857
860
  static get is() { return "ion-select"; }
858
861
  static get encapsulation() { return "shadow"; }
@@ -471,7 +471,7 @@ export class Textarea {
471
471
  * TODO(FW-5592): Remove hasStartEndSlots condition
472
472
  */
473
473
  const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
474
- return (h(Host, { key: 'a70a62d7aae3831a50acd74f60b930925ada1326', class: createColorClasses(this.color, {
474
+ return (h(Host, { key: '543076e7ed730451b490a9008cabe8f4a5d1f347', class: createColorClasses(this.color, {
475
475
  [mode]: true,
476
476
  'has-value': hasValue,
477
477
  'has-focus': hasFocus,
@@ -480,7 +480,7 @@ export class Textarea {
480
480
  [`textarea-shape-${shape}`]: shape !== undefined,
481
481
  [`textarea-label-placement-${labelPlacement}`]: true,
482
482
  'textarea-disabled': disabled,
483
- }) }, h("label", { key: '8a2dd59a60f7469df84018eb0ede3a9ec3862703', class: "textarea-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), h("div", { key: '1bfc368236e3da7a225a45118c27fbfc1fe5fa46', class: "textarea-wrapper-inner" }, h("div", { key: '215cbb2635ff52e31a8973376989b85e7245d40f', class: "start-slot-wrapper" }, h("slot", { key: '9f6b461cdee9d629deb695d2bea054ece2f32305', name: "start" })), h("div", { key: 'c1af35a2d5bc452bebe0b22a26d15ff52b4e9fc8', class: "native-wrapper", ref: (el) => (this.textareaWrapper = el) }, h("textarea", Object.assign({ key: '69a69b3cf0932baafbe37e6e846f1a571608d3f2', class: "native-textarea", ref: (el) => (this.nativeInput = el), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, minLength: this.minlength, maxLength: this.maxlength, name: this.name, placeholder: this.placeholder || '', readOnly: this.readonly, required: this.required, spellcheck: this.spellcheck, cols: this.cols, rows: this.rows, wrap: this.wrap, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeyDown, "aria-describedby": this.getHintTextID(), "aria-invalid": this.isInvalid ? 'true' : undefined }, this.inheritedAttributes), value)), h("div", { key: 'c053ea8b865d0e29763aed2e4939cc9c9e374c15', class: "end-slot-wrapper" }, h("slot", { key: '930aa641833b0df54b9ea10368fc2f46d5f491f6', name: "end" }))), shouldRenderHighlight && h("div", { key: '8d12597d15f5f429d80e8272ea99e64ed924e482', class: "textarea-highlight" })), this.renderBottomContent()));
483
+ }) }, h("label", { key: '3aebaa02edde10e19b2bbe2fbcc10f70b4faccff', class: "textarea-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), h("div", { key: '73c1c7fee0ffffe65296060dd4110003d3975c44', class: "textarea-wrapper-inner" }, h("div", { key: '5a245b822afae0b9858ef0d176a2fe06983954e2', class: "start-slot-wrapper" }, h("slot", { key: '684305a1b558f93af6eb99825981ced1c09c7a8c', name: "start" })), h("div", { key: 'f2f723b674cff48cf76656450ff6c1362514ea90', class: "native-wrapper", ref: (el) => (this.textareaWrapper = el) }, h("textarea", Object.assign({ key: 'ae826e876a4b476502498b9c64ea020010c55db3', class: "native-textarea", ref: (el) => (this.nativeInput = el), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, minLength: this.minlength, maxLength: this.maxlength, name: this.name, placeholder: this.placeholder || '', readOnly: this.readonly, required: this.required, spellcheck: this.spellcheck, cols: this.cols, rows: this.rows, wrap: this.wrap, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeyDown, "aria-describedby": this.getHintTextID(), "aria-invalid": this.isInvalid ? 'true' : undefined }, this.inheritedAttributes), value)), h("div", { key: '018cbf061fb53aa1d1caf6173fd08348cbe3413a', class: "end-slot-wrapper" }, h("slot", { key: 'c383636f2d8a548e48848d0967f71ee1969b1411', name: "end" }))), shouldRenderHighlight && h("div", { key: '6522d2058f9842abad9e7223b542cb7e1af40477', class: "textarea-highlight" })), this.renderBottomContent()));
484
484
  }
485
485
  static get is() { return "ion-textarea"; }
486
486
  static get encapsulation() { return "scoped"; }
@@ -618,7 +618,7 @@ export class Textarea {
618
618
  },
619
619
  "getter": false,
620
620
  "setter": false,
621
- "reflect": false,
621
+ "reflect": true,
622
622
  "attribute": "disabled",
623
623
  "defaultValue": "false"
624
624
  },
@@ -772,7 +772,7 @@ export class Textarea {
772
772
  },
773
773
  "getter": false,
774
774
  "setter": false,
775
- "reflect": false,
775
+ "reflect": true,
776
776
  "attribute": "readonly",
777
777
  "defaultValue": "false"
778
778
  },