@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.mjs CHANGED
@@ -21534,7 +21534,7 @@ const calculateSpringStep = (t) => {
21534
21534
  const SwipeToCloseDefaults = {
21535
21535
  MIN_PRESENTING_SCALE: 0.915,
21536
21536
  };
21537
- const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss) => {
21537
+ const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss, onDragStart, onDragMove, onDragEnd) => {
21538
21538
  /**
21539
21539
  * The step value at which a card modal
21540
21540
  * is eligible for dismissing via gesture.
@@ -21644,6 +21644,7 @@ const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss) =>
21644
21644
  disableContentScrollY(contentEl);
21645
21645
  }
21646
21646
  animation.progressStart(true, isOpen ? 1 : 0);
21647
+ onDragStart();
21647
21648
  };
21648
21649
  const onMove = (detail) => {
21649
21650
  const { deltaY } = detail;
@@ -21711,6 +21712,13 @@ const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss) =>
21711
21712
  setCardStatusBarDark();
21712
21713
  }
21713
21714
  lastStep = clampedStep;
21715
+ const eventDetail = {
21716
+ currentY: detail.currentY,
21717
+ deltaY: detail.deltaY,
21718
+ velocityY: detail.velocityY,
21719
+ progress: calculateProgress(el, detail.deltaY),
21720
+ };
21721
+ onDragMove(eventDetail);
21714
21722
  };
21715
21723
  const onEnd = (detail) => {
21716
21724
  const velocity = detail.velocityY;
@@ -21769,6 +21777,13 @@ const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss) =>
21769
21777
  else if (shouldComplete) {
21770
21778
  onDismiss();
21771
21779
  }
21780
+ const eventDetail = {
21781
+ currentY: detail.currentY,
21782
+ deltaY: detail.deltaY,
21783
+ velocityY: detail.velocityY,
21784
+ progress: calculateProgress(el, detail.deltaY),
21785
+ };
21786
+ onDragEnd(eventDetail);
21772
21787
  };
21773
21788
  const gesture = createGesture({
21774
21789
  el,
@@ -21786,6 +21801,44 @@ const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss) =>
21786
21801
  const computeDuration = (remaining, velocity) => {
21787
21802
  return clamp(400, remaining / Math.abs(velocity * 1.1), 500);
21788
21803
  };
21804
+ /**
21805
+ * Calculates the progress of the swipe gesture.
21806
+ *
21807
+ * The progress is a value between 0 and 1 that represents how far
21808
+ * the swipe has progressed towards closing the modal.
21809
+ *
21810
+ * A value closer to 1 means the modal is closer to being opened,
21811
+ * while a value closer to 0 means the modal is closer to being closed.
21812
+ *
21813
+ * @param el The modal
21814
+ * @param deltaY The change in Y position (positive when dragging down, negative when dragging up)
21815
+ * @returns The progress of the swipe gesture
21816
+ */
21817
+ const calculateProgress = (el, deltaY) => {
21818
+ const windowHeight = window.innerHeight;
21819
+ // Position when fully open
21820
+ const modalTop = el.getBoundingClientRect().top;
21821
+ /**
21822
+ * The distance between the top of the modal and the bottom of the screen
21823
+ * is the total distance the modal needs to travel to be fully closed.
21824
+ */
21825
+ const totalDistance = windowHeight - modalTop;
21826
+ /**
21827
+ * The pull percentage is how far the user has swiped compared to the total
21828
+ * distance needed to close the modal.
21829
+ */
21830
+ const pullPercentage = deltaY / totalDistance;
21831
+ /**
21832
+ * The progress is the inverse of the pull percentage because
21833
+ * when the user starts swiping up, the progress should be close to 1,
21834
+ * and when the user has swiped all the way down, the progress should be
21835
+ * close to 0.
21836
+ */
21837
+ const progress = 1 - pullPercentage;
21838
+ // Round to the nearest thousandth to avoid returning very small decimal
21839
+ const roundedProgress = Math.round(progress * 1000) / 1000;
21840
+ return Math.max(0, Math.min(1, roundedProgress));
21841
+ };
21789
21842
 
21790
21843
  const createSheetEnterAnimation = (opts) => {
21791
21844
  const { currentBreakpoint, backdropBreakpoint, expandToScroll } = opts;
@@ -22234,7 +22287,7 @@ const mdLeaveAnimation$2 = (baseEl, opts) => {
22234
22287
  return baseAnimation;
22235
22288
  };
22236
22289
 
22237
- const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, backdropBreakpoint, animation, breakpoints = [], expandToScroll, getCurrentBreakpoint, onDismiss, onBreakpointChange) => {
22290
+ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, backdropBreakpoint, animation, breakpoints = [], expandToScroll, getCurrentBreakpoint, onDismiss, onBreakpointChange, onDragStart, onDragMove, onDragEnd) => {
22238
22291
  // Defaults for the sheet swipe animation
22239
22292
  const defaultBackdrop = [
22240
22293
  { offset: 0, opacity: 'var(--backdrop-opacity)' },
@@ -22497,6 +22550,7 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
22497
22550
  baseEl.focus();
22498
22551
  });
22499
22552
  animation.progressStart(true, 1 - currentBreakpoint);
22553
+ onDragStart();
22500
22554
  };
22501
22555
  const onMove = (detail) => {
22502
22556
  /**
@@ -22565,6 +22619,15 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
22565
22619
  : step;
22566
22620
  offset = clamp(0.0001, processedStep, maxStep);
22567
22621
  animation.progressStep(offset);
22622
+ const closest = calculateClosestBreakpoint(detail.velocityY, detail.deltaY);
22623
+ const eventDetail = {
22624
+ currentY: detail.currentY,
22625
+ deltaY: detail.deltaY,
22626
+ velocityY: detail.velocityY,
22627
+ progress: calculateProgress(detail.currentY),
22628
+ currentBreakpoint: closest,
22629
+ };
22630
+ onDragMove(eventDetail);
22568
22631
  };
22569
22632
  const onEnd = (detail) => {
22570
22633
  /**
@@ -22583,16 +22646,7 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
22583
22646
  swapFooterPosition('stationary');
22584
22647
  return;
22585
22648
  }
22586
- /**
22587
- * When the gesture releases, we need to determine
22588
- * the closest breakpoint to snap to.
22589
- */
22590
- const velocity = detail.velocityY;
22591
- const threshold = (detail.deltaY + velocity * 350) / height;
22592
- const diff = currentBreakpoint - threshold;
22593
- const closest = breakpoints.reduce((a, b) => {
22594
- return Math.abs(b - diff) < Math.abs(a - diff) ? b : a;
22595
- });
22649
+ const closest = calculateClosestBreakpoint(detail.velocityY, detail.deltaY);
22596
22650
  moveSheetToBreakpoint({
22597
22651
  breakpoint: closest,
22598
22652
  breakpointOffset: offset,
@@ -22603,6 +22657,14 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
22603
22657
  */
22604
22658
  animated: true,
22605
22659
  });
22660
+ const eventDetail = {
22661
+ currentY: detail.currentY,
22662
+ deltaY: detail.deltaY,
22663
+ velocityY: detail.velocityY,
22664
+ progress: calculateProgress(detail.currentY),
22665
+ currentBreakpoint: closest,
22666
+ };
22667
+ onDragEnd(eventDetail);
22606
22668
  };
22607
22669
  const moveSheetToBreakpoint = (options) => {
22608
22670
  const { breakpoint, canDismiss, breakpointOffset, animated } = options;
@@ -22742,6 +22804,94 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
22742
22804
  .progressEnd(1, 0, animated ? 500 : 0);
22743
22805
  });
22744
22806
  };
22807
+ /**
22808
+ * Calculates the closest breakpoint based on the current velocity and deltaY.
22809
+ * This determines where the sheet should snap to when the user releases the
22810
+ * gesture.
22811
+ *
22812
+ * @param velocityY The current velocity of the gesture in the Y direction.
22813
+ * @param deltaY The change in Y position since the gesture started.
22814
+ * @returns The closest breakpoint value.
22815
+ */
22816
+ const calculateClosestBreakpoint = (velocityY, deltaY) => {
22817
+ const threshold = (deltaY + velocityY * 350) / height;
22818
+ const diff = currentBreakpoint - threshold;
22819
+ const closest = breakpoints.reduce((a, b) => {
22820
+ return Math.abs(b - diff) < Math.abs(a - diff) ? b : a;
22821
+ });
22822
+ return closest;
22823
+ };
22824
+ /**
22825
+ * Calculates the progress of the swipe gesture.
22826
+ *
22827
+ * The progress is a value between 0 and 1 that represents how far
22828
+ * the swipe has progressed towards closing the modal.
22829
+ *
22830
+ * A value closer to 1 means the modal is closer to being opened,
22831
+ * while a value closer to 0 means the modal is closer to being closed.
22832
+ *
22833
+ * @param currentY The current Y position of the gesture
22834
+ * @returns The progress of the sheet gesture
22835
+ */
22836
+ const calculateProgress = (currentY) => {
22837
+ const minBreakpoint = breakpoints[0];
22838
+ const maxBreakpoint = breakpoints[breakpoints.length - 1];
22839
+ // Convert breakpoints to pixel Y coordinates
22840
+ /**
22841
+ * The lowest point the sheet can be dragged to aka the point at which
22842
+ * the sheet is fully closed.
22843
+ */
22844
+ const maxY = convertBreakpointToY(minBreakpoint);
22845
+ /**
22846
+ * The highest point the sheet can be dragged to aka the point at which
22847
+ * the sheet is fully open.
22848
+ */
22849
+ const minY = convertBreakpointToY(maxBreakpoint);
22850
+ // The total distance between the fully open and fully closed positions.
22851
+ const totalDistance = maxY - minY;
22852
+ // The distance from the current position to the fully closed position.
22853
+ const distanceFromBottom = maxY - currentY;
22854
+ /**
22855
+ * The progress represents how far the sheet is from the bottom relative
22856
+ * to the total distance. When the user starts swiping up, the progress
22857
+ * should be close to 1, and when the user has swiped all the way down,
22858
+ * the progress should be close to 0.
22859
+ */
22860
+ const progress = distanceFromBottom / totalDistance;
22861
+ // Round to the nearest thousandth to avoid returning very small decimal
22862
+ const roundedProgress = Math.round(progress * 1000) / 1000;
22863
+ return Math.max(0, Math.min(1, roundedProgress));
22864
+ };
22865
+ /**
22866
+ * Converts a breakpoint value (0 to 1) into a pixel Y coordinate
22867
+ * on the screen.
22868
+ *
22869
+ * @param breakpoint The breakpoint value (e.g., 0.5 for half-open)
22870
+ * @returns The pixel Y coordinate on the screen
22871
+ */
22872
+ const convertBreakpointToY = (breakpoint) => {
22873
+ const rect = baseEl.getBoundingClientRect();
22874
+ const modalHeight = rect.height;
22875
+ // The bottom of the screen.
22876
+ const viewportBottom = window.innerHeight;
22877
+ /**
22878
+ * The active height is how much of the modal is actually showing
22879
+ * on the screen for this specific breakpoint.
22880
+ */
22881
+ const activeHeight = modalHeight * breakpoint;
22882
+ /**
22883
+ * To find the Y coordinate, start at the bottom of the screen
22884
+ * and move up by the active height of the modal.
22885
+ *
22886
+ * A breakpoint of 1.0 means the active height is the full modal height
22887
+ * (fully open). A breakpoint of 0.0 means the active height is 0
22888
+ * (fully closed).
22889
+ *
22890
+ * Since screen Y coordinates get smaller as you go up, we subtract the
22891
+ * active height from the viewport bottom.
22892
+ */
22893
+ return viewportBottom - activeHeight;
22894
+ };
22745
22895
  const gesture = createGesture({
22746
22896
  el: wrapperEl,
22747
22897
  gestureName: 'modalSheet',
@@ -22786,6 +22936,9 @@ class Modal {
22786
22936
  this.willDismissShorthand = createEvent(this, "willDismiss", 7);
22787
22937
  this.didDismissShorthand = createEvent(this, "didDismiss", 7);
22788
22938
  this.ionMount = createEvent(this, "ionMount", 7);
22939
+ this.ionDragStart = createEvent(this, "ionDragStart", 7);
22940
+ this.ionDragMove = createEvent(this, "ionDragMove", 7);
22941
+ this.ionDragEnd = createEvent(this, "ionDragEnd", 7);
22789
22942
  this.lockController = createLockController();
22790
22943
  this.triggerController = createTriggerController();
22791
22944
  this.coreDelegate = CoreDelegate();
@@ -23253,32 +23406,7 @@ class Modal {
23253
23406
  return;
23254
23407
  }
23255
23408
  const statusBarStyle = (_a = this.statusBarStyle) !== null && _a !== void 0 ? _a : Style.Default;
23256
- this.gesture = createSwipeToCloseGesture(el, ani, statusBarStyle, () => {
23257
- /**
23258
- * While the gesture animation is finishing
23259
- * it is possible for a user to tap the backdrop.
23260
- * This would result in the dismiss animation
23261
- * being played again. Typically this is avoided
23262
- * by setting `presented = false` on the overlay
23263
- * component; however, we cannot do that here as
23264
- * that would prevent the element from being
23265
- * removed from the DOM.
23266
- */
23267
- this.gestureAnimationDismissing = true;
23268
- /**
23269
- * Reset the status bar style as the dismiss animation
23270
- * starts otherwise the status bar will be the wrong
23271
- * color for the duration of the dismiss animation.
23272
- * The dismiss method does this as well, but
23273
- * in this case it's only called once the animation
23274
- * has finished.
23275
- */
23276
- setCardStatusBarDefault(this.statusBarStyle);
23277
- this.animation.onFinish(async () => {
23278
- await this.dismiss(undefined, GESTURE);
23279
- this.gestureAnimationDismissing = false;
23280
- });
23281
- });
23409
+ this.gesture = createSwipeToCloseGesture(el, ani, statusBarStyle, () => this.cardOnDismiss(), () => this.onDragStart(), (detail) => this.onDragMove(detail), (detail) => this.onDragEnd(detail));
23282
23410
  this.gesture.enable(true);
23283
23411
  }
23284
23412
  initSheetGesture() {
@@ -23299,7 +23427,7 @@ class Modal {
23299
23427
  this.currentBreakpoint = breakpoint;
23300
23428
  this.ionBreakpointDidChange.emit({ breakpoint });
23301
23429
  }
23302
- });
23430
+ }, () => this.onDragStart(), (detail) => this.onDragMove(detail), (detail) => this.onDragEnd(detail));
23303
23431
  this.gesture = gesture;
23304
23432
  this.moveSheetToBreakpoint = moveSheetToBreakpoint;
23305
23433
  this.gesture.enable(true);
@@ -23396,6 +23524,32 @@ class Modal {
23396
23524
  this.gestureAnimationDismissing = false;
23397
23525
  });
23398
23526
  }
23527
+ cardOnDismiss() {
23528
+ /**
23529
+ * While the gesture animation is finishing
23530
+ * it is possible for a user to tap the backdrop.
23531
+ * This would result in the dismiss animation
23532
+ * being played again. Typically this is avoided
23533
+ * by setting `presented = false` on the overlay
23534
+ * component; however, we cannot do that here as
23535
+ * that would prevent the element from being
23536
+ * removed from the DOM.
23537
+ */
23538
+ this.gestureAnimationDismissing = true;
23539
+ /**
23540
+ * Reset the status bar style as the dismiss animation
23541
+ * starts otherwise the status bar will be the wrong
23542
+ * color for the duration of the dismiss animation.
23543
+ * The dismiss method does this as well, but
23544
+ * in this case it's only called once the animation
23545
+ * has finished.
23546
+ */
23547
+ setCardStatusBarDefault(this.statusBarStyle);
23548
+ this.animation.onFinish(async () => {
23549
+ await this.dismiss(undefined, GESTURE);
23550
+ this.gestureAnimationDismissing = false;
23551
+ });
23552
+ }
23399
23553
  /**
23400
23554
  * Dismiss the modal overlay after it has been presented.
23401
23555
  * This is a no-op if the overlay has not been presented yet. If you want
@@ -23711,6 +23865,15 @@ class Modal {
23711
23865
  (_a = this.parentRemovalObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
23712
23866
  this.parentRemovalObserver = undefined;
23713
23867
  }
23868
+ onDragStart() {
23869
+ this.ionDragStart.emit();
23870
+ }
23871
+ onDragMove(detail) {
23872
+ this.ionDragMove.emit(detail);
23873
+ }
23874
+ onDragEnd(detail) {
23875
+ this.ionDragEnd.emit(detail);
23876
+ }
23714
23877
  render() {
23715
23878
  const { handle, isSheetModal, presentingElement, htmlAttributes, handleBehavior, inheritedAttributes, focusTrap, expandToScroll, } = this;
23716
23879
  const showHandle = handle !== false && isSheetModal;
@@ -23718,20 +23881,20 @@ class Modal {
23718
23881
  const isCardModal = presentingElement !== undefined && mode === 'ios';
23719
23882
  const isHandleCycle = handleBehavior === 'cycle';
23720
23883
  const isSheetModalWithHandle = isSheetModal && showHandle;
23721
- return (hAsync(Host, Object.assign({ key: '87328006ea6c75ebc518ace300438492a567223e', "no-router": true,
23884
+ return (hAsync(Host, Object.assign({ key: 'bca3cbdb2ce8e5127d27eae7494c434aaeddaf88', "no-router": true,
23722
23885
  // Allow the modal to be navigable when the handle is focusable
23723
23886
  tabIndex: isHandleCycle && isSheetModalWithHandle ? 0 : -1 }, htmlAttributes, { style: {
23724
23887
  zIndex: `${20000 + this.overlayIndex}`,
23725
- }, 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',
23888
+ }, 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',
23726
23889
  /*
23727
23890
  role and aria-modal must be used on the
23728
23891
  same element. They must also be set inside the
23729
23892
  shadow DOM otherwise ion-button will not be highlighted
23730
23893
  when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
23731
23894
  */
23732
- 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",
23895
+ 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",
23733
23896
  // Prevents the handle from receiving keyboard focus when it does not cycle
23734
- 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 }))));
23897
+ 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 }))));
23735
23898
  }
23736
23899
  get el() { return getElement(this); }
23737
23900
  static get watchers() { return {
@@ -28715,30 +28878,13 @@ const rangeMdCss = ":host{--knob-handle-size:calc(var(--knob-size) * 2);display:
28715
28878
  * @slot start - Content is placed to the left of the range slider in LTR, and to the right in RTL.
28716
28879
  * @slot end - Content is placed to the right of the range slider in LTR, and to the left in RTL.
28717
28880
  *
28718
- * @part label - The label text describing the range.
28719
28881
  * @part tick - An inactive tick mark.
28720
28882
  * @part tick-active - An active tick mark.
28883
+ * @part pin - The counter that appears above a knob.
28884
+ * @part knob - The handle that is used to drag the range.
28721
28885
  * @part bar - The inactive part of the bar.
28722
28886
  * @part bar-active - The active part of the bar.
28723
- * @part knob-handle - The container element that wraps the knob and handles drag interactions.
28724
- * @part knob-handle-a - The container element for the first knob. Only available when `dualKnobs` is `true`.
28725
- * @part knob-handle-b - The container element for the second knob. Only available when `dualKnobs` is `true`.
28726
- * @part knob-handle-lower - The container element for the lower knob. Only available when `dualKnobs` is `true`.
28727
- * @part knob-handle-upper - The container element for the upper knob. Only available when `dualKnobs` is `true`.
28728
- * @part pin - The counter that appears above a knob.
28729
- * @part pin-a - The counter that appears above the first knob. Only available when `dualKnobs` is `true`.
28730
- * @part pin-b - The counter that appears above the second knob. Only available when `dualKnobs` is `true`.
28731
- * @part pin-lower - The counter that appears above the lower knob. Only available when `dualKnobs` is `true`.
28732
- * @part pin-upper - The counter that appears above the upper knob. Only available when `dualKnobs` is `true`.
28733
- * @part knob - The visual knob element that appears on the range track.
28734
- * @part knob-a - The visual knob element for the first knob. Only available when `dualKnobs` is `true`.
28735
- * @part knob-b - The visual knob element for the second knob. Only available when `dualKnobs` is `true`.
28736
- * @part knob-lower - The visual knob element for the lower knob. Only available when `dualKnobs` is `true`.
28737
- * @part knob-upper - The visual knob element for the upper knob. Only available when `dualKnobs` is `true`.
28738
- * @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`.
28739
- * @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`.
28740
- * @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`.
28741
- * @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`.
28887
+ * @part label - The label text describing the range.
28742
28888
  */
28743
28889
  class Range {
28744
28890
  constructor(hostRef) {
@@ -28756,7 +28902,6 @@ class Range {
28756
28902
  this.inheritedAttributes = {};
28757
28903
  this.contentEl = null;
28758
28904
  this.initialContentScrollY = true;
28759
- this.focusFromPointer = false;
28760
28905
  this.ratioA = 0;
28761
28906
  this.ratioB = 0;
28762
28907
  /**
@@ -28866,29 +29011,6 @@ class Range {
28866
29011
  this.gesture.enable(!this.disabled);
28867
29012
  }
28868
29013
  };
28869
- /**
28870
- * Observes the knob handles for the ion-activated class and syncs
28871
- * activatedKnob so the activated part is correctly set on the handle,
28872
- * knob, and pin.
28873
- */
28874
- this.setupActivatedObserver = () => {
28875
- const knobHandleA = this.el.shadowRoot.querySelector('.range-knob-handle-a');
28876
- const knobHandleB = this.el.shadowRoot.querySelector('.range-knob-handle-b');
28877
- const syncActivated = () => {
28878
- this.activatedKnob = (knobHandleA === null || knobHandleA === void 0 ? void 0 : knobHandleA.classList.contains('ion-activated'))
28879
- ? 'A'
28880
- : (knobHandleB === null || knobHandleB === void 0 ? void 0 : knobHandleB.classList.contains('ion-activated'))
28881
- ? 'B'
28882
- : undefined;
28883
- };
28884
- this.activatedObserver = new MutationObserver(syncActivated);
28885
- this.activatedObserver.observe(this.el.shadowRoot, {
28886
- attributes: true,
28887
- attributeFilter: ['class'],
28888
- subtree: true,
28889
- });
28890
- syncActivated();
28891
- };
28892
29014
  this.handleKeyboard = (knob, isIncrease) => {
28893
29015
  const { ensureValueInBounds } = this;
28894
29016
  let step = this.step;
@@ -28911,7 +29033,6 @@ class Range {
28911
29033
  this.onBlur = () => {
28912
29034
  if (this.hasFocus) {
28913
29035
  this.hasFocus = false;
28914
- this.focusedKnob = undefined;
28915
29036
  this.ionBlur.emit();
28916
29037
  }
28917
29038
  };
@@ -28922,20 +29043,21 @@ class Range {
28922
29043
  }
28923
29044
  };
28924
29045
  this.onKnobFocus = (knob) => {
28925
- // Clicking focuses the range which is needed for the keyboard,
28926
- // but we only want to add the ion-focused class when focused via Tab.
28927
- if (!this.focusFromPointer) {
28928
- this.focusedKnob = knob;
28929
- }
28930
- else {
28931
- this.focusFromPointer = false;
28932
- this.focusedKnob = undefined;
28933
- }
28934
- // If the knob was not already focused, emit the focus event
28935
29046
  if (!this.hasFocus) {
28936
29047
  this.hasFocus = true;
28937
29048
  this.ionFocus.emit();
28938
29049
  }
29050
+ // Manually manage ion-focused class for dual knobs
29051
+ if (this.dualKnobs && this.el.shadowRoot) {
29052
+ const knobA = this.el.shadowRoot.querySelector('.range-knob-a');
29053
+ const knobB = this.el.shadowRoot.querySelector('.range-knob-b');
29054
+ // Remove ion-focused from both knobs first
29055
+ knobA === null || knobA === void 0 ? void 0 : knobA.classList.remove('ion-focused');
29056
+ knobB === null || knobB === void 0 ? void 0 : knobB.classList.remove('ion-focused');
29057
+ // Add ion-focused only to the focused knob
29058
+ const focusedKnobEl = knob === 'A' ? knobA : knobB;
29059
+ focusedKnobEl === null || focusedKnobEl === void 0 ? void 0 : focusedKnobEl.classList.add('ion-focused');
29060
+ }
28939
29061
  };
28940
29062
  this.onKnobBlur = () => {
28941
29063
  // Check if focus is moving to another knob within the same range
@@ -28947,18 +29069,18 @@ class Range {
28947
29069
  if (!isStillFocusedOnKnob) {
28948
29070
  if (this.hasFocus) {
28949
29071
  this.hasFocus = false;
28950
- this.focusedKnob = undefined;
28951
29072
  this.ionBlur.emit();
28952
29073
  }
29074
+ // Remove ion-focused from both knobs when focus leaves the range
29075
+ if (this.dualKnobs && this.el.shadowRoot) {
29076
+ const knobA = this.el.shadowRoot.querySelector('.range-knob-a');
29077
+ const knobB = this.el.shadowRoot.querySelector('.range-knob-b');
29078
+ knobA === null || knobA === void 0 ? void 0 : knobA.classList.remove('ion-focused');
29079
+ knobB === null || knobB === void 0 ? void 0 : knobB.classList.remove('ion-focused');
29080
+ }
28953
29081
  }
28954
29082
  }, 0);
28955
29083
  };
28956
- this.onKnobMouseEnter = (knob) => {
28957
- this.hoveredKnob = knob;
28958
- };
28959
- this.onKnobMouseLeave = () => {
28960
- this.hoveredKnob = undefined;
28961
- };
28962
29084
  }
28963
29085
  debounceChanged() {
28964
29086
  const { ionInput, debounce, originalIonInput } = this;
@@ -29035,7 +29157,6 @@ class Range {
29035
29157
  this.originalIonInput = this.ionInput;
29036
29158
  this.setupGesture();
29037
29159
  this.updateRatio();
29038
- this.setupActivatedObserver();
29039
29160
  this.didLoad = true;
29040
29161
  }
29041
29162
  connectedCallback() {
@@ -29061,10 +29182,6 @@ class Range {
29061
29182
  this.gesture.destroy();
29062
29183
  this.gesture = undefined;
29063
29184
  }
29064
- if (this.activatedObserver) {
29065
- this.activatedObserver.disconnect();
29066
- this.activatedObserver = undefined;
29067
- }
29068
29185
  }
29069
29186
  getValue() {
29070
29187
  var _a;
@@ -29217,6 +29334,7 @@ class Range {
29217
29334
  ratio = 1 - ratio;
29218
29335
  }
29219
29336
  this.pressedKnob = !this.dualKnobs || Math.abs(this.ratioA - ratio) < Math.abs(this.ratioB - ratio) ? 'A' : 'B';
29337
+ this.setFocus(this.pressedKnob);
29220
29338
  }
29221
29339
  get valA() {
29222
29340
  return ratioToValue(this.ratioA, this.min, this.max, this.step);
@@ -29243,23 +29361,9 @@ class Range {
29243
29361
  updateRatio() {
29244
29362
  const value = this.getValue();
29245
29363
  const { min, max } = this;
29246
- /**
29247
- * For dual knobs, value gives lower/upper but not which is A vs B.
29248
- * Assign (lowerRatio, upperRatio) to (ratioA, ratioB) in the way that
29249
- * minimizes change from the current ratios so the knobs don't swap.
29250
- */
29251
29364
  if (this.dualKnobs) {
29252
- const lowerRatio = valueToRatio(value.lower, min, max);
29253
- const upperRatio = valueToRatio(value.upper, min, max);
29254
- if (Math.abs(this.ratioA - lowerRatio) + Math.abs(this.ratioB - upperRatio) <=
29255
- Math.abs(this.ratioA - upperRatio) + Math.abs(this.ratioB - lowerRatio)) {
29256
- this.ratioA = lowerRatio;
29257
- this.ratioB = upperRatio;
29258
- }
29259
- else {
29260
- this.ratioA = upperRatio;
29261
- this.ratioB = lowerRatio;
29262
- }
29365
+ this.ratioA = valueToRatio(value.lower, min, max);
29366
+ this.ratioB = valueToRatio(value.upper, min, max);
29263
29367
  }
29264
29368
  else {
29265
29369
  this.ratioA = valueToRatio(value, min, max);
@@ -29276,6 +29380,14 @@ class Range {
29276
29380
  };
29277
29381
  this.noUpdate = false;
29278
29382
  }
29383
+ setFocus(knob) {
29384
+ if (this.el.shadowRoot) {
29385
+ const knobEl = this.el.shadowRoot.querySelector(knob === 'A' ? '.range-knob-a' : '.range-knob-b');
29386
+ if (knobEl) {
29387
+ knobEl.focus();
29388
+ }
29389
+ }
29390
+ }
29279
29391
  /**
29280
29392
  * Returns true if content was passed to the "start" slot
29281
29393
  */
@@ -29293,7 +29405,7 @@ class Range {
29293
29405
  }
29294
29406
  renderRangeSlider() {
29295
29407
  var _a;
29296
- const { min, max, step, handleKeyboard, activatedKnob, focusedKnob, hoveredKnob, pressedKnob, disabled, pin, ratioLower, ratioUpper, pinFormatter, inheritedAttributes, } = this;
29408
+ const { min, max, step, handleKeyboard, pressedKnob, disabled, pin, ratioLower, ratioUpper, pinFormatter, inheritedAttributes, } = this;
29297
29409
  let barStart = `${ratioLower * 100}%`;
29298
29410
  let barEnd = `${100 - ratioUpper * 100}%`;
29299
29411
  const rtl = isRTL$1(this.el);
@@ -29353,9 +29465,7 @@ class Range {
29353
29465
  ticks.push(tick);
29354
29466
  }
29355
29467
  }
29356
- return (hAsync("div", { class: "range-slider", ref: (rangeEl) => (this.rangeSlider = rangeEl), onPointerDown: () => {
29357
- this.focusFromPointer = true;
29358
- },
29468
+ return (hAsync("div", { class: "range-slider", ref: (rangeEl) => (this.rangeSlider = rangeEl),
29359
29469
  /**
29360
29470
  * Since the gesture has a threshold, the value
29361
29471
  * won't change until the user has dragged past
@@ -29368,7 +29478,6 @@ class Range {
29368
29478
  * we need to listen for the "pointerUp" event.
29369
29479
  */
29370
29480
  onPointerUp: (ev) => {
29371
- this.focusFromPointer = false;
29372
29481
  /**
29373
29482
  * If the user drags the knob on the web
29374
29483
  * version (does not occur on mobile),
@@ -29394,11 +29503,6 @@ class Range {
29394
29503
  'has-ticks': ticks.length > 0,
29395
29504
  }, role: "presentation", style: barStyle, part: "bar-active" })), renderKnob(rtl, {
29396
29505
  knob: 'A',
29397
- position: getKnobPosition('A', this.ratioA, this.ratioB, this.dualKnobs),
29398
- dualKnobs: this.dualKnobs,
29399
- activated: activatedKnob === 'A',
29400
- focused: focusedKnob === 'A',
29401
- hovered: hoveredKnob === 'A',
29402
29506
  pressed: pressedKnob === 'A',
29403
29507
  value: this.valA,
29404
29508
  ratio: this.ratioA,
@@ -29411,16 +29515,9 @@ class Range {
29411
29515
  inheritedAttributes,
29412
29516
  onKnobFocus: this.onKnobFocus,
29413
29517
  onKnobBlur: this.onKnobBlur,
29414
- onKnobMouseEnter: this.onKnobMouseEnter,
29415
- onKnobMouseLeave: this.onKnobMouseLeave,
29416
29518
  }), this.dualKnobs &&
29417
29519
  renderKnob(rtl, {
29418
29520
  knob: 'B',
29419
- position: getKnobPosition('B', this.ratioA, this.ratioB, this.dualKnobs),
29420
- dualKnobs: this.dualKnobs,
29421
- activated: activatedKnob === 'B',
29422
- focused: focusedKnob === 'B',
29423
- hovered: hoveredKnob === 'B',
29424
29521
  pressed: pressedKnob === 'B',
29425
29522
  value: this.valB,
29426
29523
  ratio: this.ratioB,
@@ -29433,8 +29530,6 @@ class Range {
29433
29530
  inheritedAttributes,
29434
29531
  onKnobFocus: this.onKnobFocus,
29435
29532
  onKnobBlur: this.onKnobBlur,
29436
- onKnobMouseEnter: this.onKnobMouseEnter,
29437
- onKnobMouseLeave: this.onKnobMouseLeave,
29438
29533
  })));
29439
29534
  }
29440
29535
  render() {
@@ -29453,12 +29548,6 @@ class Range {
29453
29548
  const hasEndContent = (hasLabel && labelPlacement === 'end') || this.hasEndSlotContent;
29454
29549
  const needsEndAdjustment = inItem && !hasEndContent;
29455
29550
  const mode = getIonMode$1(this);
29456
- /**
29457
- * Determine the name and position of the pressed knob to apply
29458
- * Host classes for styling.
29459
- */
29460
- const pressedKnobName = dualKnobs ? pressedKnob === null || pressedKnob === void 0 ? void 0 : pressedKnob.toLowerCase() : undefined;
29461
- const pressedKnobPosition = dualKnobs && pressedKnob ? getKnobPosition(pressedKnob, this.ratioA, this.ratioB, dualKnobs) : undefined;
29462
29551
  /**
29463
29552
  * Determine if any knob is at the min or max value to
29464
29553
  * apply Host classes for styling.
@@ -29466,24 +29555,21 @@ class Range {
29466
29555
  const valueAtMin = dualKnobs ? this.valA === min || this.valB === min : this.valA === min;
29467
29556
  const valueAtMax = dualKnobs ? this.valA === max || this.valB === max : this.valA === max;
29468
29557
  renderHiddenInput(true, el, this.name, JSON.stringify(this.getValue()), disabled);
29469
- return (hAsync(Host, { key: '8e439db9836fdefdc779573082c788e3ddb3ef73', onFocusin: this.onFocus, onFocusout: this.onBlur, id: rangeId, class: createColorClasses$1(this.color, {
29558
+ return (hAsync(Host, { key: 'ed646a42d51b8fe22012198c354cbcf5a389c108', onFocusin: this.onFocus, onFocusout: this.onBlur, id: rangeId, class: createColorClasses$1(this.color, {
29470
29559
  [mode]: true,
29471
29560
  'in-item': inItem,
29472
29561
  'range-disabled': disabled,
29473
- 'range-dual-knobs': dualKnobs,
29474
29562
  'range-pressed': pressedKnob !== undefined,
29475
- [`range-pressed-${pressedKnobName}`]: pressedKnob !== undefined && pressedKnobName !== undefined,
29476
- [`range-pressed-${pressedKnobPosition}`]: pressedKnob !== undefined && pressedKnobPosition !== undefined,
29477
29563
  'range-has-pin': pin,
29478
29564
  [`range-label-placement-${labelPlacement}`]: true,
29479
29565
  'range-item-start-adjustment': needsStartAdjustment,
29480
29566
  'range-item-end-adjustment': needsEndAdjustment,
29481
29567
  'range-value-min': valueAtMin,
29482
29568
  'range-value-max': valueAtMax,
29483
- }) }, hAsync("label", { key: 'e14c56db4d1eef11a3a0639c4bbed368041fc3eb', class: "range-wrapper", id: "range-label" }, hAsync("div", { key: '16d125b0af19fdfa3663731657a7cca51a7ed442', class: {
29569
+ }) }, hAsync("label", { key: '3083e4f2a624e3b268396acb4415f7c6ac44d851', class: "range-wrapper", id: "range-label" }, hAsync("div", { key: '47b92f94d2a0381dd7c5cd3dda54ed2942096715', class: {
29484
29570
  'label-text-wrapper': true,
29485
29571
  'label-text-wrapper-hidden': !hasLabel,
29486
- }, 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" })))));
29572
+ }, 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" })))));
29487
29573
  }
29488
29574
  get el() { return getElement(this); }
29489
29575
  static get watchers() { return {
@@ -29521,9 +29607,6 @@ class Range {
29521
29607
  "labelPlacement": [1, "label-placement"],
29522
29608
  "ratioA": [32],
29523
29609
  "ratioB": [32],
29524
- "activatedKnob": [32],
29525
- "focusedKnob": [32],
29526
- "hoveredKnob": [32],
29527
29610
  "pressedKnob": [32]
29528
29611
  },
29529
29612
  "$listeners$": undefined,
@@ -29531,7 +29614,7 @@ class Range {
29531
29614
  "$attrsToReflect$": [["color", "color"]]
29532
29615
  }; }
29533
29616
  }
29534
- const renderKnob = (rtl, { knob, position, dualKnobs, value, ratio, min, max, disabled, activated, focused, hovered, pressed, pin, handleKeyboard, pinFormatter, inheritedAttributes, onKnobFocus, onKnobBlur, onKnobMouseEnter, onKnobMouseLeave, }) => {
29617
+ const renderKnob = (rtl, { knob, value, ratio, min, max, disabled, pressed, pin, handleKeyboard, pinFormatter, inheritedAttributes, onKnobFocus, onKnobBlur, }) => {
29535
29618
  const start = rtl ? 'right' : 'left';
29536
29619
  const knobStyle = () => {
29537
29620
  const style = {};
@@ -29552,66 +29635,16 @@ const renderKnob = (rtl, { knob, position, dualKnobs, value, ratio, min, max, di
29552
29635
  ev.preventDefault();
29553
29636
  ev.stopPropagation();
29554
29637
  }
29555
- }, onFocus: () => onKnobFocus(knob), onBlur: onKnobBlur, onMouseEnter: () => onKnobMouseEnter(knob), onMouseLeave: onKnobMouseLeave, class: {
29638
+ }, onFocus: () => onKnobFocus(knob), onBlur: onKnobBlur, class: {
29556
29639
  'range-knob-handle': true,
29557
- 'range-knob-handle-a': knob === 'A',
29558
- 'range-knob-handle-b': knob === 'B',
29640
+ 'range-knob-a': knob === 'A',
29641
+ 'range-knob-b': knob === 'B',
29559
29642
  'range-knob-pressed': pressed,
29560
29643
  'range-knob-min': value === min,
29561
29644
  'range-knob-max': value === max,
29562
29645
  'ion-activatable': true,
29563
29646
  'ion-focusable': true,
29564
- 'ion-focused': focused,
29565
- }, part: [
29566
- 'knob-handle',
29567
- dualKnobs && knob === 'A' && 'knob-handle-a',
29568
- dualKnobs && knob === 'B' && 'knob-handle-b',
29569
- dualKnobs && position === 'lower' && 'knob-handle-lower',
29570
- dualKnobs && position === 'upper' && 'knob-handle-upper',
29571
- pressed && 'pressed',
29572
- focused && 'focused',
29573
- hovered && 'hover',
29574
- activated && 'activated',
29575
- ]
29576
- .filter(Boolean)
29577
- .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: [
29578
- 'pin',
29579
- dualKnobs && knob === 'A' && 'pin-a',
29580
- dualKnobs && knob === 'B' && 'pin-b',
29581
- dualKnobs && position === 'lower' && 'pin-lower',
29582
- dualKnobs && position === 'upper' && 'pin-upper',
29583
- pressed && 'pressed',
29584
- focused && 'focused',
29585
- hovered && 'hover',
29586
- activated && 'activated',
29587
- ]
29588
- .filter(Boolean)
29589
- .join(' ') }, pinFormatter(value))), hAsync("div", { class: "range-knob", role: "presentation", part: [
29590
- 'knob',
29591
- dualKnobs && knob === 'A' && 'knob-a',
29592
- dualKnobs && knob === 'B' && 'knob-b',
29593
- dualKnobs && position === 'lower' && 'knob-lower',
29594
- dualKnobs && position === 'upper' && 'knob-upper',
29595
- pressed && 'pressed',
29596
- focused && 'focused',
29597
- hovered && 'hover',
29598
- activated && 'activated',
29599
- ]
29600
- .filter(Boolean)
29601
- .join(' ') })));
29602
- };
29603
- /**
29604
- * Returns whether the given knob is at the lower or upper position based
29605
- * on current ratios for the given knob.
29606
- */
29607
- const getKnobPosition = (knob, ratioA, ratioB, dualKnobs) => {
29608
- if (dualKnobs) {
29609
- if (knob === 'A') {
29610
- return ratioA <= ratioB ? 'lower' : 'upper';
29611
- }
29612
- return ratioB <= ratioA ? 'lower' : 'upper';
29613
- }
29614
- return 'lower';
29647
+ }, 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" })));
29615
29648
  };
29616
29649
  const ratioToValue = (ratio, min, max, step) => {
29617
29650
  let value = (max - min) * ratio;
@@ -33612,9 +33645,9 @@ class SegmentContent {
33612
33645
  }; }
33613
33646
  }
33614
33647
 
33615
- 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}";
33648
+ 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}";
33616
33649
 
33617
- 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}";
33650
+ 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}";
33618
33651
 
33619
33652
  class SegmentView {
33620
33653
  constructor(hostRef) {
@@ -33626,6 +33659,10 @@ class SegmentView {
33626
33659
  * If `true`, the segment view cannot be interacted with.
33627
33660
  */
33628
33661
  this.disabled = false;
33662
+ /**
33663
+ * If `true`, users will be able to swipe the segment view to navigate between segment contents.
33664
+ */
33665
+ this.swipeGesture = true;
33629
33666
  }
33630
33667
  handleScroll(ev) {
33631
33668
  var _a;
@@ -33713,11 +33750,12 @@ class SegmentView {
33713
33750
  return Array.from(this.el.querySelectorAll('ion-segment-content'));
33714
33751
  }
33715
33752
  render() {
33716
- const { disabled, isManualScroll } = this;
33717
- return (hAsync(Host, { key: 'e180b67bb3143a5f4611fb358c037be6fc782a8f', class: {
33753
+ const { disabled, isManualScroll, swipeGesture } = this;
33754
+ return (hAsync(Host, { key: '565cccce7f0cfc4c71508777cc60292d6f24334f', class: {
33718
33755
  'segment-view-disabled': disabled,
33719
33756
  'segment-view-scroll-disabled': isManualScroll === false,
33720
- } }, hAsync("slot", { key: '41c11d6a7406a10f5c64a2e73abfc072afd8fc73' })));
33757
+ 'segment-view-swipe-disabled': swipeGesture === false,
33758
+ } }, hAsync("slot", { key: '4118c240364467302b8f593e33c37837ea5d06f0' })));
33721
33759
  }
33722
33760
  get el() { return getElement(this); }
33723
33761
  static get style() { return {
@@ -33729,6 +33767,7 @@ class SegmentView {
33729
33767
  "$tagName$": "ion-segment-view",
33730
33768
  "$members$": {
33731
33769
  "disabled": [4],
33770
+ "swipeGesture": [4, "swipe-gesture"],
33732
33771
  "isManualScroll": [32],
33733
33772
  "setContent": [64]
33734
33773
  },
@@ -33758,6 +33797,9 @@ const selectMdCss = ":host{--padding-top:0px;--padding-end:0px;--padding-bottom:
33758
33797
  * @part supporting-text - Supporting text displayed beneath the select.
33759
33798
  * @part helper-text - Supporting text displayed beneath the select when the select is valid.
33760
33799
  * @part error-text - Supporting text displayed beneath the select when the select is invalid and touched.
33800
+ * @part bottom - The container element for helper text, error text, and counter.
33801
+ * @part wrapper - The clickable label element that wraps the entire form field (label text, slots, selected values or placeholder, and toggle icons).
33802
+ * @part inner - The inner element of the wrapper that manages the slots, selected values or placeholder, and toggle icons.
33761
33803
  */
33762
33804
  class Select {
33763
33805
  constructor(hostRef) {
@@ -34454,7 +34496,7 @@ class Select {
34454
34496
  if (!hasHintText) {
34455
34497
  return;
34456
34498
  }
34457
- return hAsync("div", { class: "select-bottom" }, this.renderHintText());
34499
+ return (hAsync("div", { class: "select-bottom", part: "bottom" }, this.renderHintText()));
34458
34500
  }
34459
34501
  render() {
34460
34502
  const { disabled, el, isExpanded, expandedIcon, labelPlacement, justify, placeholder, fill, shape, name, value, hasFocus, } = this;
@@ -34485,7 +34527,7 @@ class Select {
34485
34527
  * TODO(FW-5592): Remove hasStartEndSlots condition
34486
34528
  */
34487
34529
  const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || isExpanded || hasStartEndSlots));
34488
- return (hAsync(Host, { key: 'b7fa907f8fbc54fd63e2d07a9bb5156d94fd5057', onClick: this.onClick, class: createColorClasses$1(this.color, {
34530
+ return (hAsync(Host, { key: 'ada627c442ebcdd4a4ee96e5f5f3ec0e2181d689', onClick: this.onClick, class: createColorClasses$1(this.color, {
34489
34531
  [mode]: true,
34490
34532
  'in-item': inItem,
34491
34533
  'in-item-color': hostContext('ion-item.ion-color', el),
@@ -34503,7 +34545,7 @@ class Select {
34503
34545
  [`select-justify-${justify}`]: justifyEnabled,
34504
34546
  [`select-shape-${shape}`]: shape !== undefined,
34505
34547
  [`select-label-placement-${labelPlacement}`]: true,
34506
- }) }, 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()));
34548
+ }) }, 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()));
34507
34549
  }
34508
34550
  get el() { return getElement(this); }
34509
34551
  static get watchers() { return {
@@ -35997,7 +36039,7 @@ class Textarea {
35997
36039
  * TODO(FW-5592): Remove hasStartEndSlots condition
35998
36040
  */
35999
36041
  const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
36000
- return (hAsync(Host, { key: 'a70a62d7aae3831a50acd74f60b930925ada1326', class: createColorClasses$1(this.color, {
36042
+ return (hAsync(Host, { key: '543076e7ed730451b490a9008cabe8f4a5d1f347', class: createColorClasses$1(this.color, {
36001
36043
  [mode]: true,
36002
36044
  'has-value': hasValue,
36003
36045
  'has-focus': hasFocus,
@@ -36006,7 +36048,7 @@ class Textarea {
36006
36048
  [`textarea-shape-${shape}`]: shape !== undefined,
36007
36049
  [`textarea-label-placement-${labelPlacement}`]: true,
36008
36050
  'textarea-disabled': disabled,
36009
- }) }, 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()));
36051
+ }) }, 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()));
36010
36052
  }
36011
36053
  get el() { return getElement(this); }
36012
36054
  static get watchers() { return {
@@ -36027,7 +36069,7 @@ class Textarea {
36027
36069
  "autofocus": [4],
36028
36070
  "clearOnEdit": [4, "clear-on-edit"],
36029
36071
  "debounce": [2],
36030
- "disabled": [4],
36072
+ "disabled": [516],
36031
36073
  "fill": [1],
36032
36074
  "inputmode": [1],
36033
36075
  "enterkeyhint": [1],
@@ -36035,7 +36077,7 @@ class Textarea {
36035
36077
  "minlength": [2],
36036
36078
  "name": [1],
36037
36079
  "placeholder": [1],
36038
- "readonly": [4],
36080
+ "readonly": [516],
36039
36081
  "required": [4],
36040
36082
  "spellcheck": [4],
36041
36083
  "cols": [514],
@@ -36057,7 +36099,7 @@ class Textarea {
36057
36099
  },
36058
36100
  "$listeners$": [[2, "click", "onClickCapture"]],
36059
36101
  "$lazyBundleId$": "-",
36060
- "$attrsToReflect$": [["color", "color"], ["cols", "cols"], ["autoGrow", "auto-grow"]]
36102
+ "$attrsToReflect$": [["color", "color"], ["disabled", "disabled"], ["readonly", "readonly"], ["cols", "cols"], ["autoGrow", "auto-grow"]]
36061
36103
  }; }
36062
36104
  }
36063
36105
  let textareaIds = 0;