@ionic/core 8.7.17-dev.11771865171.14f4c2cf → 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 (52) hide show
  1. package/components/ion-range.js +39 -152
  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-modal.cjs.entry.js +206 -43
  7. package/dist/cjs/ion-range.cjs.entry.js +39 -149
  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/modal/gestures/sheet.js +108 -11
  14. package/dist/collection/components/modal/gestures/swipe-to-close.js +54 -1
  15. package/dist/collection/components/modal/modal.js +98 -31
  16. package/dist/collection/components/range/range.js +42 -172
  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 +120 -144
  23. package/dist/esm/ion-modal.entry.js +206 -43
  24. package/dist/esm/ion-range.entry.js +39 -149
  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-012212e4.entry.js +4 -0
  33. package/dist/ionic/p-0f418a37.entry.js +4 -0
  34. package/dist/ionic/p-1838bed5.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/modal/gestures/sheet.d.ts +2 -2
  38. package/dist/types/components/modal/gestures/swipe-to-close.d.ts +2 -2
  39. package/dist/types/components/modal/modal-interface.d.ts +7 -0
  40. package/dist/types/components/modal/modal.d.ts +17 -1
  41. package/dist/types/components/range/range-interface.d.ts +0 -1
  42. package/dist/types/components/range/range.d.ts +4 -33
  43. package/dist/types/components/segment-view/segment-view.d.ts +4 -0
  44. package/dist/types/components/select/select.d.ts +3 -0
  45. package/dist/types/components.d.ts +27 -2
  46. package/hydrate/index.js +270 -228
  47. package/hydrate/index.mjs +270 -228
  48. package/package.json +1 -1
  49. package/dist/ionic/p-020af078.entry.js +0 -4
  50. package/dist/ionic/p-88367362.entry.js +0 -4
  51. package/dist/ionic/p-91840a80.entry.js +0 -4
  52. package/dist/ionic/p-991a3dd9.entry.js +0 -4
package/hydrate/index.js CHANGED
@@ -21536,7 +21536,7 @@ const calculateSpringStep = (t) => {
21536
21536
  const SwipeToCloseDefaults = {
21537
21537
  MIN_PRESENTING_SCALE: 0.915,
21538
21538
  };
21539
- const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss) => {
21539
+ const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss, onDragStart, onDragMove, onDragEnd) => {
21540
21540
  /**
21541
21541
  * The step value at which a card modal
21542
21542
  * is eligible for dismissing via gesture.
@@ -21646,6 +21646,7 @@ const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss) =>
21646
21646
  disableContentScrollY(contentEl);
21647
21647
  }
21648
21648
  animation.progressStart(true, isOpen ? 1 : 0);
21649
+ onDragStart();
21649
21650
  };
21650
21651
  const onMove = (detail) => {
21651
21652
  const { deltaY } = detail;
@@ -21713,6 +21714,13 @@ const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss) =>
21713
21714
  setCardStatusBarDark();
21714
21715
  }
21715
21716
  lastStep = clampedStep;
21717
+ const eventDetail = {
21718
+ currentY: detail.currentY,
21719
+ deltaY: detail.deltaY,
21720
+ velocityY: detail.velocityY,
21721
+ progress: calculateProgress(el, detail.deltaY),
21722
+ };
21723
+ onDragMove(eventDetail);
21716
21724
  };
21717
21725
  const onEnd = (detail) => {
21718
21726
  const velocity = detail.velocityY;
@@ -21771,6 +21779,13 @@ const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss) =>
21771
21779
  else if (shouldComplete) {
21772
21780
  onDismiss();
21773
21781
  }
21782
+ const eventDetail = {
21783
+ currentY: detail.currentY,
21784
+ deltaY: detail.deltaY,
21785
+ velocityY: detail.velocityY,
21786
+ progress: calculateProgress(el, detail.deltaY),
21787
+ };
21788
+ onDragEnd(eventDetail);
21774
21789
  };
21775
21790
  const gesture = createGesture({
21776
21791
  el,
@@ -21788,6 +21803,44 @@ const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss) =>
21788
21803
  const computeDuration = (remaining, velocity) => {
21789
21804
  return clamp(400, remaining / Math.abs(velocity * 1.1), 500);
21790
21805
  };
21806
+ /**
21807
+ * Calculates the progress of the swipe gesture.
21808
+ *
21809
+ * The progress is a value between 0 and 1 that represents how far
21810
+ * the swipe has progressed towards closing the modal.
21811
+ *
21812
+ * A value closer to 1 means the modal is closer to being opened,
21813
+ * while a value closer to 0 means the modal is closer to being closed.
21814
+ *
21815
+ * @param el The modal
21816
+ * @param deltaY The change in Y position (positive when dragging down, negative when dragging up)
21817
+ * @returns The progress of the swipe gesture
21818
+ */
21819
+ const calculateProgress = (el, deltaY) => {
21820
+ const windowHeight = window.innerHeight;
21821
+ // Position when fully open
21822
+ const modalTop = el.getBoundingClientRect().top;
21823
+ /**
21824
+ * The distance between the top of the modal and the bottom of the screen
21825
+ * is the total distance the modal needs to travel to be fully closed.
21826
+ */
21827
+ const totalDistance = windowHeight - modalTop;
21828
+ /**
21829
+ * The pull percentage is how far the user has swiped compared to the total
21830
+ * distance needed to close the modal.
21831
+ */
21832
+ const pullPercentage = deltaY / totalDistance;
21833
+ /**
21834
+ * The progress is the inverse of the pull percentage because
21835
+ * when the user starts swiping up, the progress should be close to 1,
21836
+ * and when the user has swiped all the way down, the progress should be
21837
+ * close to 0.
21838
+ */
21839
+ const progress = 1 - pullPercentage;
21840
+ // Round to the nearest thousandth to avoid returning very small decimal
21841
+ const roundedProgress = Math.round(progress * 1000) / 1000;
21842
+ return Math.max(0, Math.min(1, roundedProgress));
21843
+ };
21791
21844
 
21792
21845
  const createSheetEnterAnimation = (opts) => {
21793
21846
  const { currentBreakpoint, backdropBreakpoint, expandToScroll } = opts;
@@ -22236,7 +22289,7 @@ const mdLeaveAnimation$2 = (baseEl, opts) => {
22236
22289
  return baseAnimation;
22237
22290
  };
22238
22291
 
22239
- const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, backdropBreakpoint, animation, breakpoints = [], expandToScroll, getCurrentBreakpoint, onDismiss, onBreakpointChange) => {
22292
+ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, backdropBreakpoint, animation, breakpoints = [], expandToScroll, getCurrentBreakpoint, onDismiss, onBreakpointChange, onDragStart, onDragMove, onDragEnd) => {
22240
22293
  // Defaults for the sheet swipe animation
22241
22294
  const defaultBackdrop = [
22242
22295
  { offset: 0, opacity: 'var(--backdrop-opacity)' },
@@ -22499,6 +22552,7 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
22499
22552
  baseEl.focus();
22500
22553
  });
22501
22554
  animation.progressStart(true, 1 - currentBreakpoint);
22555
+ onDragStart();
22502
22556
  };
22503
22557
  const onMove = (detail) => {
22504
22558
  /**
@@ -22567,6 +22621,15 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
22567
22621
  : step;
22568
22622
  offset = clamp(0.0001, processedStep, maxStep);
22569
22623
  animation.progressStep(offset);
22624
+ const closest = calculateClosestBreakpoint(detail.velocityY, detail.deltaY);
22625
+ const eventDetail = {
22626
+ currentY: detail.currentY,
22627
+ deltaY: detail.deltaY,
22628
+ velocityY: detail.velocityY,
22629
+ progress: calculateProgress(detail.currentY),
22630
+ currentBreakpoint: closest,
22631
+ };
22632
+ onDragMove(eventDetail);
22570
22633
  };
22571
22634
  const onEnd = (detail) => {
22572
22635
  /**
@@ -22585,16 +22648,7 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
22585
22648
  swapFooterPosition('stationary');
22586
22649
  return;
22587
22650
  }
22588
- /**
22589
- * When the gesture releases, we need to determine
22590
- * the closest breakpoint to snap to.
22591
- */
22592
- const velocity = detail.velocityY;
22593
- const threshold = (detail.deltaY + velocity * 350) / height;
22594
- const diff = currentBreakpoint - threshold;
22595
- const closest = breakpoints.reduce((a, b) => {
22596
- return Math.abs(b - diff) < Math.abs(a - diff) ? b : a;
22597
- });
22651
+ const closest = calculateClosestBreakpoint(detail.velocityY, detail.deltaY);
22598
22652
  moveSheetToBreakpoint({
22599
22653
  breakpoint: closest,
22600
22654
  breakpointOffset: offset,
@@ -22605,6 +22659,14 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
22605
22659
  */
22606
22660
  animated: true,
22607
22661
  });
22662
+ const eventDetail = {
22663
+ currentY: detail.currentY,
22664
+ deltaY: detail.deltaY,
22665
+ velocityY: detail.velocityY,
22666
+ progress: calculateProgress(detail.currentY),
22667
+ currentBreakpoint: closest,
22668
+ };
22669
+ onDragEnd(eventDetail);
22608
22670
  };
22609
22671
  const moveSheetToBreakpoint = (options) => {
22610
22672
  const { breakpoint, canDismiss, breakpointOffset, animated } = options;
@@ -22744,6 +22806,94 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
22744
22806
  .progressEnd(1, 0, animated ? 500 : 0);
22745
22807
  });
22746
22808
  };
22809
+ /**
22810
+ * Calculates the closest breakpoint based on the current velocity and deltaY.
22811
+ * This determines where the sheet should snap to when the user releases the
22812
+ * gesture.
22813
+ *
22814
+ * @param velocityY The current velocity of the gesture in the Y direction.
22815
+ * @param deltaY The change in Y position since the gesture started.
22816
+ * @returns The closest breakpoint value.
22817
+ */
22818
+ const calculateClosestBreakpoint = (velocityY, deltaY) => {
22819
+ const threshold = (deltaY + velocityY * 350) / height;
22820
+ const diff = currentBreakpoint - threshold;
22821
+ const closest = breakpoints.reduce((a, b) => {
22822
+ return Math.abs(b - diff) < Math.abs(a - diff) ? b : a;
22823
+ });
22824
+ return closest;
22825
+ };
22826
+ /**
22827
+ * Calculates the progress of the swipe gesture.
22828
+ *
22829
+ * The progress is a value between 0 and 1 that represents how far
22830
+ * the swipe has progressed towards closing the modal.
22831
+ *
22832
+ * A value closer to 1 means the modal is closer to being opened,
22833
+ * while a value closer to 0 means the modal is closer to being closed.
22834
+ *
22835
+ * @param currentY The current Y position of the gesture
22836
+ * @returns The progress of the sheet gesture
22837
+ */
22838
+ const calculateProgress = (currentY) => {
22839
+ const minBreakpoint = breakpoints[0];
22840
+ const maxBreakpoint = breakpoints[breakpoints.length - 1];
22841
+ // Convert breakpoints to pixel Y coordinates
22842
+ /**
22843
+ * The lowest point the sheet can be dragged to aka the point at which
22844
+ * the sheet is fully closed.
22845
+ */
22846
+ const maxY = convertBreakpointToY(minBreakpoint);
22847
+ /**
22848
+ * The highest point the sheet can be dragged to aka the point at which
22849
+ * the sheet is fully open.
22850
+ */
22851
+ const minY = convertBreakpointToY(maxBreakpoint);
22852
+ // The total distance between the fully open and fully closed positions.
22853
+ const totalDistance = maxY - minY;
22854
+ // The distance from the current position to the fully closed position.
22855
+ const distanceFromBottom = maxY - currentY;
22856
+ /**
22857
+ * The progress represents how far the sheet is from the bottom relative
22858
+ * to the total distance. When the user starts swiping up, the progress
22859
+ * should be close to 1, and when the user has swiped all the way down,
22860
+ * the progress should be close to 0.
22861
+ */
22862
+ const progress = distanceFromBottom / totalDistance;
22863
+ // Round to the nearest thousandth to avoid returning very small decimal
22864
+ const roundedProgress = Math.round(progress * 1000) / 1000;
22865
+ return Math.max(0, Math.min(1, roundedProgress));
22866
+ };
22867
+ /**
22868
+ * Converts a breakpoint value (0 to 1) into a pixel Y coordinate
22869
+ * on the screen.
22870
+ *
22871
+ * @param breakpoint The breakpoint value (e.g., 0.5 for half-open)
22872
+ * @returns The pixel Y coordinate on the screen
22873
+ */
22874
+ const convertBreakpointToY = (breakpoint) => {
22875
+ const rect = baseEl.getBoundingClientRect();
22876
+ const modalHeight = rect.height;
22877
+ // The bottom of the screen.
22878
+ const viewportBottom = window.innerHeight;
22879
+ /**
22880
+ * The active height is how much of the modal is actually showing
22881
+ * on the screen for this specific breakpoint.
22882
+ */
22883
+ const activeHeight = modalHeight * breakpoint;
22884
+ /**
22885
+ * To find the Y coordinate, start at the bottom of the screen
22886
+ * and move up by the active height of the modal.
22887
+ *
22888
+ * A breakpoint of 1.0 means the active height is the full modal height
22889
+ * (fully open). A breakpoint of 0.0 means the active height is 0
22890
+ * (fully closed).
22891
+ *
22892
+ * Since screen Y coordinates get smaller as you go up, we subtract the
22893
+ * active height from the viewport bottom.
22894
+ */
22895
+ return viewportBottom - activeHeight;
22896
+ };
22747
22897
  const gesture = createGesture({
22748
22898
  el: wrapperEl,
22749
22899
  gestureName: 'modalSheet',
@@ -22788,6 +22938,9 @@ class Modal {
22788
22938
  this.willDismissShorthand = createEvent(this, "willDismiss", 7);
22789
22939
  this.didDismissShorthand = createEvent(this, "didDismiss", 7);
22790
22940
  this.ionMount = createEvent(this, "ionMount", 7);
22941
+ this.ionDragStart = createEvent(this, "ionDragStart", 7);
22942
+ this.ionDragMove = createEvent(this, "ionDragMove", 7);
22943
+ this.ionDragEnd = createEvent(this, "ionDragEnd", 7);
22791
22944
  this.lockController = createLockController();
22792
22945
  this.triggerController = createTriggerController();
22793
22946
  this.coreDelegate = CoreDelegate();
@@ -23255,32 +23408,7 @@ class Modal {
23255
23408
  return;
23256
23409
  }
23257
23410
  const statusBarStyle = (_a = this.statusBarStyle) !== null && _a !== void 0 ? _a : Style.Default;
23258
- this.gesture = createSwipeToCloseGesture(el, ani, statusBarStyle, () => {
23259
- /**
23260
- * While the gesture animation is finishing
23261
- * it is possible for a user to tap the backdrop.
23262
- * This would result in the dismiss animation
23263
- * being played again. Typically this is avoided
23264
- * by setting `presented = false` on the overlay
23265
- * component; however, we cannot do that here as
23266
- * that would prevent the element from being
23267
- * removed from the DOM.
23268
- */
23269
- this.gestureAnimationDismissing = true;
23270
- /**
23271
- * Reset the status bar style as the dismiss animation
23272
- * starts otherwise the status bar will be the wrong
23273
- * color for the duration of the dismiss animation.
23274
- * The dismiss method does this as well, but
23275
- * in this case it's only called once the animation
23276
- * has finished.
23277
- */
23278
- setCardStatusBarDefault(this.statusBarStyle);
23279
- this.animation.onFinish(async () => {
23280
- await this.dismiss(undefined, GESTURE);
23281
- this.gestureAnimationDismissing = false;
23282
- });
23283
- });
23411
+ this.gesture = createSwipeToCloseGesture(el, ani, statusBarStyle, () => this.cardOnDismiss(), () => this.onDragStart(), (detail) => this.onDragMove(detail), (detail) => this.onDragEnd(detail));
23284
23412
  this.gesture.enable(true);
23285
23413
  }
23286
23414
  initSheetGesture() {
@@ -23301,7 +23429,7 @@ class Modal {
23301
23429
  this.currentBreakpoint = breakpoint;
23302
23430
  this.ionBreakpointDidChange.emit({ breakpoint });
23303
23431
  }
23304
- });
23432
+ }, () => this.onDragStart(), (detail) => this.onDragMove(detail), (detail) => this.onDragEnd(detail));
23305
23433
  this.gesture = gesture;
23306
23434
  this.moveSheetToBreakpoint = moveSheetToBreakpoint;
23307
23435
  this.gesture.enable(true);
@@ -23398,6 +23526,32 @@ class Modal {
23398
23526
  this.gestureAnimationDismissing = false;
23399
23527
  });
23400
23528
  }
23529
+ cardOnDismiss() {
23530
+ /**
23531
+ * While the gesture animation is finishing
23532
+ * it is possible for a user to tap the backdrop.
23533
+ * This would result in the dismiss animation
23534
+ * being played again. Typically this is avoided
23535
+ * by setting `presented = false` on the overlay
23536
+ * component; however, we cannot do that here as
23537
+ * that would prevent the element from being
23538
+ * removed from the DOM.
23539
+ */
23540
+ this.gestureAnimationDismissing = true;
23541
+ /**
23542
+ * Reset the status bar style as the dismiss animation
23543
+ * starts otherwise the status bar will be the wrong
23544
+ * color for the duration of the dismiss animation.
23545
+ * The dismiss method does this as well, but
23546
+ * in this case it's only called once the animation
23547
+ * has finished.
23548
+ */
23549
+ setCardStatusBarDefault(this.statusBarStyle);
23550
+ this.animation.onFinish(async () => {
23551
+ await this.dismiss(undefined, GESTURE);
23552
+ this.gestureAnimationDismissing = false;
23553
+ });
23554
+ }
23401
23555
  /**
23402
23556
  * Dismiss the modal overlay after it has been presented.
23403
23557
  * This is a no-op if the overlay has not been presented yet. If you want
@@ -23713,6 +23867,15 @@ class Modal {
23713
23867
  (_a = this.parentRemovalObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
23714
23868
  this.parentRemovalObserver = undefined;
23715
23869
  }
23870
+ onDragStart() {
23871
+ this.ionDragStart.emit();
23872
+ }
23873
+ onDragMove(detail) {
23874
+ this.ionDragMove.emit(detail);
23875
+ }
23876
+ onDragEnd(detail) {
23877
+ this.ionDragEnd.emit(detail);
23878
+ }
23716
23879
  render() {
23717
23880
  const { handle, isSheetModal, presentingElement, htmlAttributes, handleBehavior, inheritedAttributes, focusTrap, expandToScroll, } = this;
23718
23881
  const showHandle = handle !== false && isSheetModal;
@@ -23720,20 +23883,20 @@ class Modal {
23720
23883
  const isCardModal = presentingElement !== undefined && mode === 'ios';
23721
23884
  const isHandleCycle = handleBehavior === 'cycle';
23722
23885
  const isSheetModalWithHandle = isSheetModal && showHandle;
23723
- return (hAsync(Host, Object.assign({ key: '87328006ea6c75ebc518ace300438492a567223e', "no-router": true,
23886
+ return (hAsync(Host, Object.assign({ key: 'bca3cbdb2ce8e5127d27eae7494c434aaeddaf88', "no-router": true,
23724
23887
  // Allow the modal to be navigable when the handle is focusable
23725
23888
  tabIndex: isHandleCycle && isSheetModalWithHandle ? 0 : -1 }, htmlAttributes, { style: {
23726
23889
  zIndex: `${20000 + this.overlayIndex}`,
23727
- }, 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 }), hAsync("ion-backdrop", { key: 'ee94ff8e09b691dd4ad4e4db1720f06bc3c5a469', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && hAsync("div", { key: 'bffd69b4635c22d9f249725bd952c1e93d5615c7', class: "modal-shadow" }), hAsync("div", Object.assign({ key: '1d394d3c68916e464ff1fbf5242419f4a3d3cca1',
23890
+ }, 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 }), hAsync("ion-backdrop", { key: 'b1c4112123d84d8a9b9d455bcc17d884f99d9f28', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && hAsync("div", { key: '080c8e6d37b311a1b5ad2655d99f18668abae211', class: "modal-shadow" }), hAsync("div", Object.assign({ key: '8ba05e9520b1b5529bf0caeb766da5bf612d4d14',
23728
23891
  /*
23729
23892
  role and aria-modal must be used on the
23730
23893
  same element. They must also be set inside the
23731
23894
  shadow DOM otherwise ion-button will not be highlighted
23732
23895
  when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
23733
23896
  */
23734
- role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (hAsync("button", { key: '2dcf58792018e557e0c323baad2d672bc99c0bb1', class: "modal-handle",
23897
+ role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (hAsync("button", { key: '2d2d5d731f55755f32ebcbf557f97486dc6202a6', class: "modal-handle",
23735
23898
  // Prevents the handle from receiving keyboard focus when it does not cycle
23736
- 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) })), hAsync("slot", { key: '44164b1e8710c3895400ad9f44ecd99873874ad5', onSlotchange: this.onSlotChange }))));
23899
+ 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) })), hAsync("slot", { key: 'c717d19865dafba02e15db79bc0662c5d89e96fd', onSlotchange: this.onSlotChange }))));
23737
23900
  }
23738
23901
  get el() { return getElement(this); }
23739
23902
  static get watchers() { return {
@@ -28717,30 +28880,13 @@ const rangeMdCss = ":host{--knob-handle-size:calc(var(--knob-size) * 2);display:
28717
28880
  * @slot start - Content is placed to the left of the range slider in LTR, and to the right in RTL.
28718
28881
  * @slot end - Content is placed to the right of the range slider in LTR, and to the left in RTL.
28719
28882
  *
28720
- * @part label - The label text describing the range.
28721
28883
  * @part tick - An inactive tick mark.
28722
28884
  * @part tick-active - An active tick mark.
28885
+ * @part pin - The counter that appears above a knob.
28886
+ * @part knob - The handle that is used to drag the range.
28723
28887
  * @part bar - The inactive part of the bar.
28724
28888
  * @part bar-active - The active part of the bar.
28725
- * @part knob-handle - The container element that wraps the knob and handles drag interactions.
28726
- * @part knob-handle-a - The container element for the first knob. Only available when `dualKnobs` is `true`.
28727
- * @part knob-handle-b - The container element for the second knob. Only available when `dualKnobs` is `true`.
28728
- * @part knob-handle-lower - The container element for the lower knob. Only available when `dualKnobs` is `true`.
28729
- * @part knob-handle-upper - The container element for the upper knob. Only available when `dualKnobs` is `true`.
28730
- * @part pin - The counter that appears above a knob.
28731
- * @part pin-a - The counter that appears above the first knob. Only available when `dualKnobs` is `true`.
28732
- * @part pin-b - The counter that appears above the second knob. Only available when `dualKnobs` is `true`.
28733
- * @part pin-lower - The counter that appears above the lower knob. Only available when `dualKnobs` is `true`.
28734
- * @part pin-upper - The counter that appears above the upper knob. Only available when `dualKnobs` is `true`.
28735
- * @part knob - The visual knob element that appears on the range track.
28736
- * @part knob-a - The visual knob element for the first knob. Only available when `dualKnobs` is `true`.
28737
- * @part knob-b - The visual knob element for the second knob. Only available when `dualKnobs` is `true`.
28738
- * @part knob-lower - The visual knob element for the lower knob. Only available when `dualKnobs` is `true`.
28739
- * @part knob-upper - The visual knob element for the upper knob. Only available when `dualKnobs` is `true`.
28740
- * @part activated - Added to the knob-handle, knob, and pin when the knob is activated (has the `ion-activated` class). Only one set has this part at a time when `dualKnobs` is `true`.
28741
- * @part focused - Added to the knob-handle, knob, and pin that currently has focus. Only one set has this part at a time when `dualKnobs` is `true`.
28742
- * @part hover - Added to the knob-handle, knob, and pin when the knob has hover. Only one set has this part at a time when `dualKnobs` is `true`.
28743
- * @part pressed - Added to the knob-handle, knob, and pin that is currently being pressed to drag. Only one set has this part at a time when `dualKnobs` is `true`.
28889
+ * @part label - The label text describing the range.
28744
28890
  */
28745
28891
  class Range {
28746
28892
  constructor(hostRef) {
@@ -28758,7 +28904,6 @@ class Range {
28758
28904
  this.inheritedAttributes = {};
28759
28905
  this.contentEl = null;
28760
28906
  this.initialContentScrollY = true;
28761
- this.focusFromPointer = false;
28762
28907
  this.ratioA = 0;
28763
28908
  this.ratioB = 0;
28764
28909
  /**
@@ -28868,29 +29013,6 @@ class Range {
28868
29013
  this.gesture.enable(!this.disabled);
28869
29014
  }
28870
29015
  };
28871
- /**
28872
- * Observes the knob handles for the ion-activated class and syncs
28873
- * activatedKnob so the activated part is correctly set on the handle,
28874
- * knob, and pin.
28875
- */
28876
- this.setupActivatedObserver = () => {
28877
- const knobHandleA = this.el.shadowRoot.querySelector('.range-knob-handle-a');
28878
- const knobHandleB = this.el.shadowRoot.querySelector('.range-knob-handle-b');
28879
- const syncActivated = () => {
28880
- this.activatedKnob = (knobHandleA === null || knobHandleA === void 0 ? void 0 : knobHandleA.classList.contains('ion-activated'))
28881
- ? 'A'
28882
- : (knobHandleB === null || knobHandleB === void 0 ? void 0 : knobHandleB.classList.contains('ion-activated'))
28883
- ? 'B'
28884
- : undefined;
28885
- };
28886
- this.activatedObserver = new MutationObserver(syncActivated);
28887
- this.activatedObserver.observe(this.el.shadowRoot, {
28888
- attributes: true,
28889
- attributeFilter: ['class'],
28890
- subtree: true,
28891
- });
28892
- syncActivated();
28893
- };
28894
29016
  this.handleKeyboard = (knob, isIncrease) => {
28895
29017
  const { ensureValueInBounds } = this;
28896
29018
  let step = this.step;
@@ -28913,7 +29035,6 @@ class Range {
28913
29035
  this.onBlur = () => {
28914
29036
  if (this.hasFocus) {
28915
29037
  this.hasFocus = false;
28916
- this.focusedKnob = undefined;
28917
29038
  this.ionBlur.emit();
28918
29039
  }
28919
29040
  };
@@ -28924,20 +29045,21 @@ class Range {
28924
29045
  }
28925
29046
  };
28926
29047
  this.onKnobFocus = (knob) => {
28927
- // Clicking focuses the range which is needed for the keyboard,
28928
- // but we only want to add the ion-focused class when focused via Tab.
28929
- if (!this.focusFromPointer) {
28930
- this.focusedKnob = knob;
28931
- }
28932
- else {
28933
- this.focusFromPointer = false;
28934
- this.focusedKnob = undefined;
28935
- }
28936
- // If the knob was not already focused, emit the focus event
28937
29048
  if (!this.hasFocus) {
28938
29049
  this.hasFocus = true;
28939
29050
  this.ionFocus.emit();
28940
29051
  }
29052
+ // Manually manage ion-focused class for dual knobs
29053
+ if (this.dualKnobs && this.el.shadowRoot) {
29054
+ const knobA = this.el.shadowRoot.querySelector('.range-knob-a');
29055
+ const knobB = this.el.shadowRoot.querySelector('.range-knob-b');
29056
+ // Remove ion-focused from both knobs first
29057
+ knobA === null || knobA === void 0 ? void 0 : knobA.classList.remove('ion-focused');
29058
+ knobB === null || knobB === void 0 ? void 0 : knobB.classList.remove('ion-focused');
29059
+ // Add ion-focused only to the focused knob
29060
+ const focusedKnobEl = knob === 'A' ? knobA : knobB;
29061
+ focusedKnobEl === null || focusedKnobEl === void 0 ? void 0 : focusedKnobEl.classList.add('ion-focused');
29062
+ }
28941
29063
  };
28942
29064
  this.onKnobBlur = () => {
28943
29065
  // Check if focus is moving to another knob within the same range
@@ -28949,18 +29071,18 @@ class Range {
28949
29071
  if (!isStillFocusedOnKnob) {
28950
29072
  if (this.hasFocus) {
28951
29073
  this.hasFocus = false;
28952
- this.focusedKnob = undefined;
28953
29074
  this.ionBlur.emit();
28954
29075
  }
29076
+ // Remove ion-focused from both knobs when focus leaves the range
29077
+ if (this.dualKnobs && this.el.shadowRoot) {
29078
+ const knobA = this.el.shadowRoot.querySelector('.range-knob-a');
29079
+ const knobB = this.el.shadowRoot.querySelector('.range-knob-b');
29080
+ knobA === null || knobA === void 0 ? void 0 : knobA.classList.remove('ion-focused');
29081
+ knobB === null || knobB === void 0 ? void 0 : knobB.classList.remove('ion-focused');
29082
+ }
28955
29083
  }
28956
29084
  }, 0);
28957
29085
  };
28958
- this.onKnobMouseEnter = (knob) => {
28959
- this.hoveredKnob = knob;
28960
- };
28961
- this.onKnobMouseLeave = () => {
28962
- this.hoveredKnob = undefined;
28963
- };
28964
29086
  }
28965
29087
  debounceChanged() {
28966
29088
  const { ionInput, debounce, originalIonInput } = this;
@@ -29037,7 +29159,6 @@ class Range {
29037
29159
  this.originalIonInput = this.ionInput;
29038
29160
  this.setupGesture();
29039
29161
  this.updateRatio();
29040
- this.setupActivatedObserver();
29041
29162
  this.didLoad = true;
29042
29163
  }
29043
29164
  connectedCallback() {
@@ -29063,10 +29184,6 @@ class Range {
29063
29184
  this.gesture.destroy();
29064
29185
  this.gesture = undefined;
29065
29186
  }
29066
- if (this.activatedObserver) {
29067
- this.activatedObserver.disconnect();
29068
- this.activatedObserver = undefined;
29069
- }
29070
29187
  }
29071
29188
  getValue() {
29072
29189
  var _a;
@@ -29219,6 +29336,7 @@ class Range {
29219
29336
  ratio = 1 - ratio;
29220
29337
  }
29221
29338
  this.pressedKnob = !this.dualKnobs || Math.abs(this.ratioA - ratio) < Math.abs(this.ratioB - ratio) ? 'A' : 'B';
29339
+ this.setFocus(this.pressedKnob);
29222
29340
  }
29223
29341
  get valA() {
29224
29342
  return ratioToValue(this.ratioA, this.min, this.max, this.step);
@@ -29245,23 +29363,9 @@ class Range {
29245
29363
  updateRatio() {
29246
29364
  const value = this.getValue();
29247
29365
  const { min, max } = this;
29248
- /**
29249
- * For dual knobs, value gives lower/upper but not which is A vs B.
29250
- * Assign (lowerRatio, upperRatio) to (ratioA, ratioB) in the way that
29251
- * minimizes change from the current ratios so the knobs don't swap.
29252
- */
29253
29366
  if (this.dualKnobs) {
29254
- const lowerRatio = valueToRatio(value.lower, min, max);
29255
- const upperRatio = valueToRatio(value.upper, min, max);
29256
- if (Math.abs(this.ratioA - lowerRatio) + Math.abs(this.ratioB - upperRatio) <=
29257
- Math.abs(this.ratioA - upperRatio) + Math.abs(this.ratioB - lowerRatio)) {
29258
- this.ratioA = lowerRatio;
29259
- this.ratioB = upperRatio;
29260
- }
29261
- else {
29262
- this.ratioA = upperRatio;
29263
- this.ratioB = lowerRatio;
29264
- }
29367
+ this.ratioA = valueToRatio(value.lower, min, max);
29368
+ this.ratioB = valueToRatio(value.upper, min, max);
29265
29369
  }
29266
29370
  else {
29267
29371
  this.ratioA = valueToRatio(value, min, max);
@@ -29278,6 +29382,14 @@ class Range {
29278
29382
  };
29279
29383
  this.noUpdate = false;
29280
29384
  }
29385
+ setFocus(knob) {
29386
+ if (this.el.shadowRoot) {
29387
+ const knobEl = this.el.shadowRoot.querySelector(knob === 'A' ? '.range-knob-a' : '.range-knob-b');
29388
+ if (knobEl) {
29389
+ knobEl.focus();
29390
+ }
29391
+ }
29392
+ }
29281
29393
  /**
29282
29394
  * Returns true if content was passed to the "start" slot
29283
29395
  */
@@ -29295,7 +29407,7 @@ class Range {
29295
29407
  }
29296
29408
  renderRangeSlider() {
29297
29409
  var _a;
29298
- const { min, max, step, handleKeyboard, activatedKnob, focusedKnob, hoveredKnob, pressedKnob, disabled, pin, ratioLower, ratioUpper, pinFormatter, inheritedAttributes, } = this;
29410
+ const { min, max, step, handleKeyboard, pressedKnob, disabled, pin, ratioLower, ratioUpper, pinFormatter, inheritedAttributes, } = this;
29299
29411
  let barStart = `${ratioLower * 100}%`;
29300
29412
  let barEnd = `${100 - ratioUpper * 100}%`;
29301
29413
  const rtl = isRTL$1(this.el);
@@ -29355,9 +29467,7 @@ class Range {
29355
29467
  ticks.push(tick);
29356
29468
  }
29357
29469
  }
29358
- return (hAsync("div", { class: "range-slider", ref: (rangeEl) => (this.rangeSlider = rangeEl), onPointerDown: () => {
29359
- this.focusFromPointer = true;
29360
- },
29470
+ return (hAsync("div", { class: "range-slider", ref: (rangeEl) => (this.rangeSlider = rangeEl),
29361
29471
  /**
29362
29472
  * Since the gesture has a threshold, the value
29363
29473
  * won't change until the user has dragged past
@@ -29370,7 +29480,6 @@ class Range {
29370
29480
  * we need to listen for the "pointerUp" event.
29371
29481
  */
29372
29482
  onPointerUp: (ev) => {
29373
- this.focusFromPointer = false;
29374
29483
  /**
29375
29484
  * If the user drags the knob on the web
29376
29485
  * version (does not occur on mobile),
@@ -29396,11 +29505,6 @@ class Range {
29396
29505
  'has-ticks': ticks.length > 0,
29397
29506
  }, role: "presentation", style: barStyle, part: "bar-active" })), renderKnob(rtl, {
29398
29507
  knob: 'A',
29399
- position: getKnobPosition('A', this.ratioA, this.ratioB, this.dualKnobs),
29400
- dualKnobs: this.dualKnobs,
29401
- activated: activatedKnob === 'A',
29402
- focused: focusedKnob === 'A',
29403
- hovered: hoveredKnob === 'A',
29404
29508
  pressed: pressedKnob === 'A',
29405
29509
  value: this.valA,
29406
29510
  ratio: this.ratioA,
@@ -29413,16 +29517,9 @@ class Range {
29413
29517
  inheritedAttributes,
29414
29518
  onKnobFocus: this.onKnobFocus,
29415
29519
  onKnobBlur: this.onKnobBlur,
29416
- onKnobMouseEnter: this.onKnobMouseEnter,
29417
- onKnobMouseLeave: this.onKnobMouseLeave,
29418
29520
  }), this.dualKnobs &&
29419
29521
  renderKnob(rtl, {
29420
29522
  knob: 'B',
29421
- position: getKnobPosition('B', this.ratioA, this.ratioB, this.dualKnobs),
29422
- dualKnobs: this.dualKnobs,
29423
- activated: activatedKnob === 'B',
29424
- focused: focusedKnob === 'B',
29425
- hovered: hoveredKnob === 'B',
29426
29523
  pressed: pressedKnob === 'B',
29427
29524
  value: this.valB,
29428
29525
  ratio: this.ratioB,
@@ -29435,8 +29532,6 @@ class Range {
29435
29532
  inheritedAttributes,
29436
29533
  onKnobFocus: this.onKnobFocus,
29437
29534
  onKnobBlur: this.onKnobBlur,
29438
- onKnobMouseEnter: this.onKnobMouseEnter,
29439
- onKnobMouseLeave: this.onKnobMouseLeave,
29440
29535
  })));
29441
29536
  }
29442
29537
  render() {
@@ -29455,12 +29550,6 @@ class Range {
29455
29550
  const hasEndContent = (hasLabel && labelPlacement === 'end') || this.hasEndSlotContent;
29456
29551
  const needsEndAdjustment = inItem && !hasEndContent;
29457
29552
  const mode = getIonMode$1(this);
29458
- /**
29459
- * Determine the name and position of the pressed knob to apply
29460
- * Host classes for styling.
29461
- */
29462
- const pressedKnobName = dualKnobs ? pressedKnob === null || pressedKnob === void 0 ? void 0 : pressedKnob.toLowerCase() : undefined;
29463
- const pressedKnobPosition = dualKnobs && pressedKnob ? getKnobPosition(pressedKnob, this.ratioA, this.ratioB, dualKnobs) : undefined;
29464
29553
  /**
29465
29554
  * Determine if any knob is at the min or max value to
29466
29555
  * apply Host classes for styling.
@@ -29468,24 +29557,21 @@ class Range {
29468
29557
  const valueAtMin = dualKnobs ? this.valA === min || this.valB === min : this.valA === min;
29469
29558
  const valueAtMax = dualKnobs ? this.valA === max || this.valB === max : this.valA === max;
29470
29559
  renderHiddenInput(true, el, this.name, JSON.stringify(this.getValue()), disabled);
29471
- return (hAsync(Host, { key: '8e439db9836fdefdc779573082c788e3ddb3ef73', onFocusin: this.onFocus, onFocusout: this.onBlur, id: rangeId, class: createColorClasses$1(this.color, {
29560
+ return (hAsync(Host, { key: 'ed646a42d51b8fe22012198c354cbcf5a389c108', onFocusin: this.onFocus, onFocusout: this.onBlur, id: rangeId, class: createColorClasses$1(this.color, {
29472
29561
  [mode]: true,
29473
29562
  'in-item': inItem,
29474
29563
  'range-disabled': disabled,
29475
- 'range-dual-knobs': dualKnobs,
29476
29564
  'range-pressed': pressedKnob !== undefined,
29477
- [`range-pressed-${pressedKnobName}`]: pressedKnob !== undefined && pressedKnobName !== undefined,
29478
- [`range-pressed-${pressedKnobPosition}`]: pressedKnob !== undefined && pressedKnobPosition !== undefined,
29479
29565
  'range-has-pin': pin,
29480
29566
  [`range-label-placement-${labelPlacement}`]: true,
29481
29567
  'range-item-start-adjustment': needsStartAdjustment,
29482
29568
  'range-item-end-adjustment': needsEndAdjustment,
29483
29569
  'range-value-min': valueAtMin,
29484
29570
  'range-value-max': valueAtMax,
29485
- }) }, hAsync("label", { key: 'e14c56db4d1eef11a3a0639c4bbed368041fc3eb', class: "range-wrapper", id: "range-label" }, hAsync("div", { key: '16d125b0af19fdfa3663731657a7cca51a7ed442', class: {
29571
+ }) }, hAsync("label", { key: '3083e4f2a624e3b268396acb4415f7c6ac44d851', class: "range-wrapper", id: "range-label" }, hAsync("div", { key: '47b92f94d2a0381dd7c5cd3dda54ed2942096715', class: {
29486
29572
  'label-text-wrapper': true,
29487
29573
  'label-text-wrapper-hidden': !hasLabel,
29488
- }, part: "label" }, label !== undefined ? hAsync("div", { class: "label-text" }, label) : hAsync("slot", { name: "label" })), hAsync("div", { key: '545cc52a3e675e9df328dab537a4e44b7f3c59f8', class: "native-wrapper" }, hAsync("slot", { key: 'ac54b45a21c9db231ebe11498d508d05864b56fb', name: "start" }), this.renderRangeSlider(), hAsync("slot", { key: '7182dba53df2ff878d572b30afda64b37082c82e', name: "end" })))));
29574
+ }, part: "label" }, label !== undefined ? hAsync("div", { class: "label-text" }, label) : hAsync("slot", { name: "label" })), hAsync("div", { key: '5341da8d19eb29091df680978a0e20cc8f2eec65', class: "native-wrapper" }, hAsync("slot", { key: '09f1437078032676695442d8c827a16faa7dffe2', name: "start" }), this.renderRangeSlider(), hAsync("slot", { key: '02b7781970ea4d44f10b5f4627a2ca36eca45f85', name: "end" })))));
29489
29575
  }
29490
29576
  get el() { return getElement(this); }
29491
29577
  static get watchers() { return {
@@ -29523,9 +29609,6 @@ class Range {
29523
29609
  "labelPlacement": [1, "label-placement"],
29524
29610
  "ratioA": [32],
29525
29611
  "ratioB": [32],
29526
- "activatedKnob": [32],
29527
- "focusedKnob": [32],
29528
- "hoveredKnob": [32],
29529
29612
  "pressedKnob": [32]
29530
29613
  },
29531
29614
  "$listeners$": undefined,
@@ -29533,7 +29616,7 @@ class Range {
29533
29616
  "$attrsToReflect$": [["color", "color"]]
29534
29617
  }; }
29535
29618
  }
29536
- const renderKnob = (rtl, { knob, position, dualKnobs, value, ratio, min, max, disabled, activated, focused, hovered, pressed, pin, handleKeyboard, pinFormatter, inheritedAttributes, onKnobFocus, onKnobBlur, onKnobMouseEnter, onKnobMouseLeave, }) => {
29619
+ const renderKnob = (rtl, { knob, value, ratio, min, max, disabled, pressed, pin, handleKeyboard, pinFormatter, inheritedAttributes, onKnobFocus, onKnobBlur, }) => {
29537
29620
  const start = rtl ? 'right' : 'left';
29538
29621
  const knobStyle = () => {
29539
29622
  const style = {};
@@ -29554,66 +29637,16 @@ const renderKnob = (rtl, { knob, position, dualKnobs, value, ratio, min, max, di
29554
29637
  ev.preventDefault();
29555
29638
  ev.stopPropagation();
29556
29639
  }
29557
- }, onFocus: () => onKnobFocus(knob), onBlur: onKnobBlur, onMouseEnter: () => onKnobMouseEnter(knob), onMouseLeave: onKnobMouseLeave, class: {
29640
+ }, onFocus: () => onKnobFocus(knob), onBlur: onKnobBlur, class: {
29558
29641
  'range-knob-handle': true,
29559
- 'range-knob-handle-a': knob === 'A',
29560
- 'range-knob-handle-b': knob === 'B',
29642
+ 'range-knob-a': knob === 'A',
29643
+ 'range-knob-b': knob === 'B',
29561
29644
  'range-knob-pressed': pressed,
29562
29645
  'range-knob-min': value === min,
29563
29646
  'range-knob-max': value === max,
29564
29647
  'ion-activatable': true,
29565
29648
  'ion-focusable': true,
29566
- 'ion-focused': focused,
29567
- }, part: [
29568
- 'knob-handle',
29569
- dualKnobs && knob === 'A' && 'knob-handle-a',
29570
- dualKnobs && knob === 'B' && 'knob-handle-b',
29571
- dualKnobs && position === 'lower' && 'knob-handle-lower',
29572
- dualKnobs && position === 'upper' && 'knob-handle-upper',
29573
- pressed && 'pressed',
29574
- focused && 'focused',
29575
- hovered && 'hover',
29576
- activated && 'activated',
29577
- ]
29578
- .filter(Boolean)
29579
- .join(' '), style: knobStyle(), role: "slider", tabindex: disabled ? -1 : 0, "aria-label": ariaLabel !== undefined ? ariaLabel : null, "aria-labelledby": ariaLabel === undefined ? 'range-label' : null, "aria-valuemin": min, "aria-valuemax": max, "aria-disabled": disabled ? 'true' : null, "aria-valuenow": value }, pin && (hAsync("div", { class: "range-pin", role: "presentation", part: [
29580
- 'pin',
29581
- dualKnobs && knob === 'A' && 'pin-a',
29582
- dualKnobs && knob === 'B' && 'pin-b',
29583
- dualKnobs && position === 'lower' && 'pin-lower',
29584
- dualKnobs && position === 'upper' && 'pin-upper',
29585
- pressed && 'pressed',
29586
- focused && 'focused',
29587
- hovered && 'hover',
29588
- activated && 'activated',
29589
- ]
29590
- .filter(Boolean)
29591
- .join(' ') }, pinFormatter(value))), hAsync("div", { class: "range-knob", role: "presentation", part: [
29592
- 'knob',
29593
- dualKnobs && knob === 'A' && 'knob-a',
29594
- dualKnobs && knob === 'B' && 'knob-b',
29595
- dualKnobs && position === 'lower' && 'knob-lower',
29596
- dualKnobs && position === 'upper' && 'knob-upper',
29597
- pressed && 'pressed',
29598
- focused && 'focused',
29599
- hovered && 'hover',
29600
- activated && 'activated',
29601
- ]
29602
- .filter(Boolean)
29603
- .join(' ') })));
29604
- };
29605
- /**
29606
- * Returns whether the given knob is at the lower or upper position based
29607
- * on current ratios for the given knob.
29608
- */
29609
- const getKnobPosition = (knob, ratioA, ratioB, dualKnobs) => {
29610
- if (dualKnobs) {
29611
- if (knob === 'A') {
29612
- return ratioA <= ratioB ? 'lower' : 'upper';
29613
- }
29614
- return ratioB <= ratioA ? 'lower' : 'upper';
29615
- }
29616
- return 'lower';
29649
+ }, style: knobStyle(), role: "slider", tabindex: disabled ? -1 : 0, "aria-label": ariaLabel !== undefined ? ariaLabel : null, "aria-labelledby": ariaLabel === undefined ? 'range-label' : null, "aria-valuemin": min, "aria-valuemax": max, "aria-disabled": disabled ? 'true' : null, "aria-valuenow": value }, pin && (hAsync("div", { class: "range-pin", role: "presentation", part: "pin" }, pinFormatter(value))), hAsync("div", { class: "range-knob", role: "presentation", part: "knob" })));
29617
29650
  };
29618
29651
  const ratioToValue = (ratio, min, max, step) => {
29619
29652
  let value = (max - min) * ratio;
@@ -33614,9 +33647,9 @@ class SegmentContent {
33614
33647
  }; }
33615
33648
  }
33616
33649
 
33617
- const segmentViewIosCss = ":host{display:-ms-flexbox;display:flex;height:100%;overflow-x:scroll;-webkit-scroll-snap-type:x mandatory;-ms-scroll-snap-type:x mandatory;scroll-snap-type:x mandatory;scrollbar-width:none;-ms-overflow-style:none}:host::-webkit-scrollbar{display:none}:host(.segment-view-disabled){-ms-touch-action:none;touch-action:none;overflow-x:hidden}:host(.segment-view-scroll-disabled){pointer-events:none}:host(.segment-view-disabled){opacity:0.3}";
33650
+ const segmentViewIosCss = ":host{display:-ms-flexbox;display:flex;height:100%;overflow-x:scroll;-webkit-scroll-snap-type:x mandatory;-ms-scroll-snap-type:x mandatory;scroll-snap-type:x mandatory;scrollbar-width:none;-ms-overflow-style:none}:host::-webkit-scrollbar{display:none}:host(.segment-view-disabled),:host(.segment-view-swipe-disabled){-ms-touch-action:none;touch-action:none;overflow-x:hidden}:host(.segment-view-scroll-disabled){pointer-events:none}:host(.segment-view-disabled){opacity:0.3}";
33618
33651
 
33619
- const segmentViewMdCss = ":host{display:-ms-flexbox;display:flex;height:100%;overflow-x:scroll;-webkit-scroll-snap-type:x mandatory;-ms-scroll-snap-type:x mandatory;scroll-snap-type:x mandatory;scrollbar-width:none;-ms-overflow-style:none}:host::-webkit-scrollbar{display:none}:host(.segment-view-disabled){-ms-touch-action:none;touch-action:none;overflow-x:hidden}:host(.segment-view-scroll-disabled){pointer-events:none}:host(.segment-view-disabled){opacity:0.3}";
33652
+ const segmentViewMdCss = ":host{display:-ms-flexbox;display:flex;height:100%;overflow-x:scroll;-webkit-scroll-snap-type:x mandatory;-ms-scroll-snap-type:x mandatory;scroll-snap-type:x mandatory;scrollbar-width:none;-ms-overflow-style:none}:host::-webkit-scrollbar{display:none}:host(.segment-view-disabled),:host(.segment-view-swipe-disabled){-ms-touch-action:none;touch-action:none;overflow-x:hidden}:host(.segment-view-scroll-disabled){pointer-events:none}:host(.segment-view-disabled){opacity:0.3}";
33620
33653
 
33621
33654
  class SegmentView {
33622
33655
  constructor(hostRef) {
@@ -33628,6 +33661,10 @@ class SegmentView {
33628
33661
  * If `true`, the segment view cannot be interacted with.
33629
33662
  */
33630
33663
  this.disabled = false;
33664
+ /**
33665
+ * If `true`, users will be able to swipe the segment view to navigate between segment contents.
33666
+ */
33667
+ this.swipeGesture = true;
33631
33668
  }
33632
33669
  handleScroll(ev) {
33633
33670
  var _a;
@@ -33715,11 +33752,12 @@ class SegmentView {
33715
33752
  return Array.from(this.el.querySelectorAll('ion-segment-content'));
33716
33753
  }
33717
33754
  render() {
33718
- const { disabled, isManualScroll } = this;
33719
- return (hAsync(Host, { key: 'e180b67bb3143a5f4611fb358c037be6fc782a8f', class: {
33755
+ const { disabled, isManualScroll, swipeGesture } = this;
33756
+ return (hAsync(Host, { key: '565cccce7f0cfc4c71508777cc60292d6f24334f', class: {
33720
33757
  'segment-view-disabled': disabled,
33721
33758
  'segment-view-scroll-disabled': isManualScroll === false,
33722
- } }, hAsync("slot", { key: '41c11d6a7406a10f5c64a2e73abfc072afd8fc73' })));
33759
+ 'segment-view-swipe-disabled': swipeGesture === false,
33760
+ } }, hAsync("slot", { key: '4118c240364467302b8f593e33c37837ea5d06f0' })));
33723
33761
  }
33724
33762
  get el() { return getElement(this); }
33725
33763
  static get style() { return {
@@ -33731,6 +33769,7 @@ class SegmentView {
33731
33769
  "$tagName$": "ion-segment-view",
33732
33770
  "$members$": {
33733
33771
  "disabled": [4],
33772
+ "swipeGesture": [4, "swipe-gesture"],
33734
33773
  "isManualScroll": [32],
33735
33774
  "setContent": [64]
33736
33775
  },
@@ -33760,6 +33799,9 @@ const selectMdCss = ":host{--padding-top:0px;--padding-end:0px;--padding-bottom:
33760
33799
  * @part supporting-text - Supporting text displayed beneath the select.
33761
33800
  * @part helper-text - Supporting text displayed beneath the select when the select is valid.
33762
33801
  * @part error-text - Supporting text displayed beneath the select when the select is invalid and touched.
33802
+ * @part bottom - The container element for helper text, error text, and counter.
33803
+ * @part wrapper - The clickable label element that wraps the entire form field (label text, slots, selected values or placeholder, and toggle icons).
33804
+ * @part inner - The inner element of the wrapper that manages the slots, selected values or placeholder, and toggle icons.
33763
33805
  */
33764
33806
  class Select {
33765
33807
  constructor(hostRef) {
@@ -34456,7 +34498,7 @@ class Select {
34456
34498
  if (!hasHintText) {
34457
34499
  return;
34458
34500
  }
34459
- return hAsync("div", { class: "select-bottom" }, this.renderHintText());
34501
+ return (hAsync("div", { class: "select-bottom", part: "bottom" }, this.renderHintText()));
34460
34502
  }
34461
34503
  render() {
34462
34504
  const { disabled, el, isExpanded, expandedIcon, labelPlacement, justify, placeholder, fill, shape, name, value, hasFocus, } = this;
@@ -34487,7 +34529,7 @@ class Select {
34487
34529
  * TODO(FW-5592): Remove hasStartEndSlots condition
34488
34530
  */
34489
34531
  const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || isExpanded || hasStartEndSlots));
34490
- return (hAsync(Host, { key: 'b7fa907f8fbc54fd63e2d07a9bb5156d94fd5057', onClick: this.onClick, class: createColorClasses$1(this.color, {
34532
+ return (hAsync(Host, { key: 'ada627c442ebcdd4a4ee96e5f5f3ec0e2181d689', onClick: this.onClick, class: createColorClasses$1(this.color, {
34491
34533
  [mode]: true,
34492
34534
  'in-item': inItem,
34493
34535
  'in-item-color': hostContext('ion-item.ion-color', el),
@@ -34505,7 +34547,7 @@ class Select {
34505
34547
  [`select-justify-${justify}`]: justifyEnabled,
34506
34548
  [`select-shape-${shape}`]: shape !== undefined,
34507
34549
  [`select-label-placement-${labelPlacement}`]: true,
34508
- }) }, hAsync("label", { key: '11137e6a8b0374e93923ddb5a4629972ded5f43c', class: "select-wrapper", id: "select-label", onClick: this.onLabelClick }, this.renderLabelContainer(), hAsync("div", { key: '99e3c09b5e6c2e7be493ed5834f991fffe45cfff', class: "select-wrapper-inner" }, hAsync("slot", { key: '740f0e5a913cb0209d5acae31c33a6ed8f672dfc', name: "start" }), hAsync("div", { key: 'b20e33c8b60915a5194948fcf8e22d7789f0b050', class: "native-wrapper", ref: (el) => (this.nativeWrapperEl = el), part: "container" }, this.renderSelectText(), this.renderListbox()), hAsync("slot", { key: '0199f338185d5fa2cdd977bb20516746bd9ddad5', name: "end" }), !hasFloatingOrStackedLabel && this.renderSelectIcon()), hasFloatingOrStackedLabel && this.renderSelectIcon(), shouldRenderHighlight && hAsync("div", { key: '3b54de893cc8fc66df8588cee22e30d6f10850b3', class: "select-highlight" })), this.renderBottomContent()));
34550
+ }) }, hAsync("label", { key: 'd1c4663e740cfdcd28f90a5e0297d05cf42cc4df', class: "select-wrapper", id: "select-label", onClick: this.onLabelClick, part: "wrapper" }, this.renderLabelContainer(), hAsync("div", { key: 'cd671e0b543378e7b822ce649a7b4006094b111f', class: "select-wrapper-inner", part: "inner" }, hAsync("slot", { key: '48e7df0c517a382195736273019b855e422a82ed', name: "start" }), hAsync("div", { key: '822747ffb9101cb1d3ff947da55bc2e8e1f2c8e2', class: "native-wrapper", ref: (el) => (this.nativeWrapperEl = el), part: "container" }, this.renderSelectText(), this.renderListbox()), hAsync("slot", { key: '349200d9f9ebf25e0b8708ac8683a76e7c6ed33c', name: "end" }), !hasFloatingOrStackedLabel && this.renderSelectIcon()), hasFloatingOrStackedLabel && this.renderSelectIcon(), shouldRenderHighlight && hAsync("div", { key: '7eefb70d431cb9c01cc408d35349f7a3d0f2af35', class: "select-highlight" })), this.renderBottomContent()));
34509
34551
  }
34510
34552
  get el() { return getElement(this); }
34511
34553
  static get watchers() { return {
@@ -35999,7 +36041,7 @@ class Textarea {
35999
36041
  * TODO(FW-5592): Remove hasStartEndSlots condition
36000
36042
  */
36001
36043
  const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
36002
- return (hAsync(Host, { key: 'a70a62d7aae3831a50acd74f60b930925ada1326', class: createColorClasses$1(this.color, {
36044
+ return (hAsync(Host, { key: '543076e7ed730451b490a9008cabe8f4a5d1f347', class: createColorClasses$1(this.color, {
36003
36045
  [mode]: true,
36004
36046
  'has-value': hasValue,
36005
36047
  'has-focus': hasFocus,
@@ -36008,7 +36050,7 @@ class Textarea {
36008
36050
  [`textarea-shape-${shape}`]: shape !== undefined,
36009
36051
  [`textarea-label-placement-${labelPlacement}`]: true,
36010
36052
  'textarea-disabled': disabled,
36011
- }) }, hAsync("label", { key: '8a2dd59a60f7469df84018eb0ede3a9ec3862703', class: "textarea-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), hAsync("div", { key: '1bfc368236e3da7a225a45118c27fbfc1fe5fa46', class: "textarea-wrapper-inner" }, hAsync("div", { key: '215cbb2635ff52e31a8973376989b85e7245d40f', class: "start-slot-wrapper" }, hAsync("slot", { key: '9f6b461cdee9d629deb695d2bea054ece2f32305', name: "start" })), hAsync("div", { key: 'c1af35a2d5bc452bebe0b22a26d15ff52b4e9fc8', class: "native-wrapper", ref: (el) => (this.textareaWrapper = el) }, hAsync("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)), hAsync("div", { key: 'c053ea8b865d0e29763aed2e4939cc9c9e374c15', class: "end-slot-wrapper" }, hAsync("slot", { key: '930aa641833b0df54b9ea10368fc2f46d5f491f6', name: "end" }))), shouldRenderHighlight && hAsync("div", { key: '8d12597d15f5f429d80e8272ea99e64ed924e482', class: "textarea-highlight" })), this.renderBottomContent()));
36053
+ }) }, hAsync("label", { key: '3aebaa02edde10e19b2bbe2fbcc10f70b4faccff', class: "textarea-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), hAsync("div", { key: '73c1c7fee0ffffe65296060dd4110003d3975c44', class: "textarea-wrapper-inner" }, hAsync("div", { key: '5a245b822afae0b9858ef0d176a2fe06983954e2', class: "start-slot-wrapper" }, hAsync("slot", { key: '684305a1b558f93af6eb99825981ced1c09c7a8c', name: "start" })), hAsync("div", { key: 'f2f723b674cff48cf76656450ff6c1362514ea90', class: "native-wrapper", ref: (el) => (this.textareaWrapper = el) }, hAsync("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)), hAsync("div", { key: '018cbf061fb53aa1d1caf6173fd08348cbe3413a', class: "end-slot-wrapper" }, hAsync("slot", { key: 'c383636f2d8a548e48848d0967f71ee1969b1411', name: "end" }))), shouldRenderHighlight && hAsync("div", { key: '6522d2058f9842abad9e7223b542cb7e1af40477', class: "textarea-highlight" })), this.renderBottomContent()));
36012
36054
  }
36013
36055
  get el() { return getElement(this); }
36014
36056
  static get watchers() { return {
@@ -36029,7 +36071,7 @@ class Textarea {
36029
36071
  "autofocus": [4],
36030
36072
  "clearOnEdit": [4, "clear-on-edit"],
36031
36073
  "debounce": [2],
36032
- "disabled": [4],
36074
+ "disabled": [516],
36033
36075
  "fill": [1],
36034
36076
  "inputmode": [1],
36035
36077
  "enterkeyhint": [1],
@@ -36037,7 +36079,7 @@ class Textarea {
36037
36079
  "minlength": [2],
36038
36080
  "name": [1],
36039
36081
  "placeholder": [1],
36040
- "readonly": [4],
36082
+ "readonly": [516],
36041
36083
  "required": [4],
36042
36084
  "spellcheck": [4],
36043
36085
  "cols": [514],
@@ -36059,7 +36101,7 @@ class Textarea {
36059
36101
  },
36060
36102
  "$listeners$": [[2, "click", "onClickCapture"]],
36061
36103
  "$lazyBundleId$": "-",
36062
- "$attrsToReflect$": [["color", "color"], ["cols", "cols"], ["autoGrow", "auto-grow"]]
36104
+ "$attrsToReflect$": [["color", "color"], ["disabled", "disabled"], ["readonly", "readonly"], ["cols", "cols"], ["autoGrow", "auto-grow"]]
36063
36105
  }; }
36064
36106
  }
36065
36107
  let textareaIds = 0;