@ionic/core 8.6.3-dev.11751378808.12cc4a5c → 8.6.3-dev.11751478001.1cb7436f

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 (34) hide show
  1. package/components/focus-visible.js +27 -18
  2. package/components/ion-select.js +3 -3
  3. package/components/modal.js +8 -220
  4. package/dist/cjs/{focus-visible-CCvKiLh3.js → focus-visible-ZV7jHMPt.js} +27 -18
  5. package/dist/cjs/ion-app_8.cjs.entry.js +1 -1
  6. package/dist/cjs/ion-datetime_3.cjs.entry.js +1 -1
  7. package/dist/cjs/ion-modal.cjs.entry.js +8 -220
  8. package/dist/cjs/ion-select_3.cjs.entry.js +3 -3
  9. package/dist/collection/components/modal/animations/ios.enter.js +2 -2
  10. package/dist/collection/components/modal/animations/ios.leave.js +2 -2
  11. package/dist/collection/components/modal/modal.js +4 -87
  12. package/dist/collection/components/select/select.js +3 -3
  13. package/dist/collection/utils/focus-visible.js +27 -18
  14. package/dist/docs.json +1 -1
  15. package/dist/esm/{focus-visible-BmVRXR1y.js → focus-visible-DZ2gZBzK.js} +27 -18
  16. package/dist/esm/ion-app_8.entry.js +1 -1
  17. package/dist/esm/ion-datetime_3.entry.js +1 -1
  18. package/dist/esm/ion-modal.entry.js +8 -220
  19. package/dist/esm/ion-select_3.entry.js +3 -3
  20. package/dist/ionic/ionic.esm.js +1 -1
  21. package/dist/ionic/{p-01123ecf.entry.js → p-2d46fbe7.entry.js} +1 -1
  22. package/dist/ionic/{p-5f671887.entry.js → p-78a61b3f.entry.js} +1 -1
  23. package/dist/ionic/p-7d5cf8c1.entry.js +4 -0
  24. package/dist/ionic/p-9e32212d.entry.js +4 -0
  25. package/dist/ionic/p-DZ2gZBzK.js +4 -0
  26. package/dist/types/components/modal/modal.d.ts +0 -6
  27. package/hydrate/index.js +38 -241
  28. package/hydrate/index.mjs +38 -241
  29. package/package.json +1 -1
  30. package/dist/collection/components/modal/animations/ios.transition.js +0 -143
  31. package/dist/ionic/p-4ddc10ef.entry.js +0 -4
  32. package/dist/ionic/p-6f74a187.entry.js +0 -4
  33. package/dist/ionic/p-BmVRXR1y.js +0 -4
  34. package/dist/types/components/modal/animations/ios.transition.d.ts +0 -14
package/hydrate/index.mjs CHANGED
@@ -10412,33 +10412,44 @@ const FOCUS_KEYS = [
10412
10412
  ];
10413
10413
  const startFocusVisible = (rootEl) => {
10414
10414
  let currentFocus = [];
10415
- let keyboardMode = true;
10415
+ // Tracks if the last interaction was a pointer event (mouse, touch, pen)
10416
+ // Used to distinguish between pointer and keyboard navigation for focus styling
10417
+ let hadPointerEvent = false;
10416
10418
  const ref = rootEl ? rootEl.shadowRoot : document;
10417
10419
  const root = rootEl ? rootEl : document.body;
10420
+ // Adds or removes the focused class for styling
10418
10421
  const setFocus = (elements) => {
10419
10422
  currentFocus.forEach((el) => el.classList.remove(ION_FOCUSED));
10420
10423
  elements.forEach((el) => el.classList.add(ION_FOCUSED));
10421
10424
  currentFocus = elements;
10422
10425
  };
10423
- const pointerDown = () => {
10424
- keyboardMode = false;
10425
- setFocus([]);
10426
+ // Do not set focus on pointer interactions
10427
+ const pointerDown = (ev) => {
10428
+ if (ev instanceof PointerEvent && ev.pointerType !== '') {
10429
+ hadPointerEvent = true;
10430
+ // Reset after the event loop so only the immediate focusin is suppressed
10431
+ setTimeout(() => {
10432
+ hadPointerEvent = false;
10433
+ }, 0);
10434
+ }
10426
10435
  };
10436
+ // Clear hadPointerEvent so keyboard navigation shows focus
10437
+ // Also, clear focus if the key is not a navigation key
10427
10438
  const onKeydown = (ev) => {
10428
- keyboardMode = FOCUS_KEYS.includes(ev.key);
10429
- if (!keyboardMode) {
10439
+ hadPointerEvent = false;
10440
+ const keyboardEvent = ev;
10441
+ if (!FOCUS_KEYS.includes(keyboardEvent.key)) {
10430
10442
  setFocus([]);
10431
10443
  }
10432
10444
  };
10445
+ // Set focus if the last interaction was NOT a pointer event
10446
+ // This works around iOS/Safari bugs where keydown is not fired for Tab
10433
10447
  const onFocusin = (ev) => {
10434
- if (keyboardMode && ev.composedPath !== undefined) {
10435
- const toFocus = ev.composedPath().filter((el) => {
10436
- // TODO(FW-2832): type
10437
- if (el.classList) {
10438
- return el.classList.contains(ION_FOCUSABLE);
10439
- }
10440
- return false;
10441
- });
10448
+ const target = ev.target;
10449
+ if (target.classList.contains(ION_FOCUSABLE) && !hadPointerEvent) {
10450
+ const toFocus = ev
10451
+ .composedPath()
10452
+ .filter((el) => el instanceof HTMLElement && el.classList.contains(ION_FOCUSABLE));
10442
10453
  setFocus(toFocus);
10443
10454
  }
10444
10455
  };
@@ -10450,14 +10461,12 @@ const startFocusVisible = (rootEl) => {
10450
10461
  ref.addEventListener('keydown', onKeydown);
10451
10462
  ref.addEventListener('focusin', onFocusin);
10452
10463
  ref.addEventListener('focusout', onFocusout);
10453
- ref.addEventListener('touchstart', pointerDown, { passive: true });
10454
- ref.addEventListener('mousedown', pointerDown);
10464
+ ref.addEventListener('pointerdown', pointerDown, { passive: true });
10455
10465
  const destroy = () => {
10456
10466
  ref.removeEventListener('keydown', onKeydown);
10457
10467
  ref.removeEventListener('focusin', onFocusin);
10458
10468
  ref.removeEventListener('focusout', onFocusout);
10459
- ref.removeEventListener('touchstart', pointerDown);
10460
- ref.removeEventListener('mousedown', pointerDown);
10469
+ ref.removeEventListener('pointerdown', pointerDown);
10461
10470
  };
10462
10471
  return {
10463
10472
  destroy,
@@ -21216,7 +21225,7 @@ const iosEnterAnimation$3 = (baseEl, opts) => {
21216
21225
  baseAnimation.addAnimation(contentAnimation);
21217
21226
  }
21218
21227
  if (presentingEl) {
21219
- const isPortrait = window.innerWidth < 768;
21228
+ const isMobile = window.innerWidth < 768;
21220
21229
  const hasCardModal = presentingEl.tagName === 'ION-MODAL' && presentingEl.presentingElement !== undefined;
21221
21230
  const presentingElRoot = getElementRoot(presentingEl);
21222
21231
  const presentingAnimation = createAnimation().beforeStyles({
@@ -21225,7 +21234,7 @@ const iosEnterAnimation$3 = (baseEl, opts) => {
21225
21234
  overflow: 'hidden',
21226
21235
  });
21227
21236
  const bodyEl = document.body;
21228
- if (isPortrait) {
21237
+ if (isMobile) {
21229
21238
  /**
21230
21239
  * Fallback for browsers that does not support `max()` (ex: Firefox)
21231
21240
  * No need to worry about statusbar padding since engines like Gecko
@@ -21303,7 +21312,7 @@ const iosLeaveAnimation$3 = (baseEl, opts, duration = 500) => {
21303
21312
  .duration(duration)
21304
21313
  .addAnimation(wrapperAnimation);
21305
21314
  if (presentingEl) {
21306
- const isPortrait = window.innerWidth < 768;
21315
+ const isMobile = window.innerWidth < 768;
21307
21316
  const hasCardModal = presentingEl.tagName === 'ION-MODAL' && presentingEl.presentingElement !== undefined;
21308
21317
  const presentingElRoot = getElementRoot(presentingEl);
21309
21318
  const presentingAnimation = createAnimation()
@@ -21321,7 +21330,7 @@ const iosLeaveAnimation$3 = (baseEl, opts, duration = 500) => {
21321
21330
  }
21322
21331
  });
21323
21332
  const bodyEl = document.body;
21324
- if (isPortrait) {
21333
+ if (isMobile) {
21325
21334
  const transformOffset = !CSS.supports('width', 'max(0px, 1px)') ? '30px' : 'max(30px, var(--ion-safe-area-top))';
21326
21335
  const modalTransform = hasCardModal ? '-10px' : transformOffset;
21327
21336
  const toPresentingScale = SwipeToCloseDefaults.MIN_PRESENTING_SCALE;
@@ -21368,144 +21377,6 @@ const iosLeaveAnimation$3 = (baseEl, opts, duration = 500) => {
21368
21377
  return baseAnimation;
21369
21378
  };
21370
21379
 
21371
- /**
21372
- * Transition animation from portrait view to landscape view
21373
- * This handles the case where a card modal is open in portrait view
21374
- * and the user switches to landscape view
21375
- */
21376
- const portraitToLandscapeTransition = (baseEl, opts, duration = 300) => {
21377
- const { presentingEl } = opts;
21378
- if (!presentingEl) {
21379
- // No transition needed for non-card modals
21380
- return createAnimation('portrait-to-landscape-transition');
21381
- }
21382
- const hasCardModal = presentingEl.tagName === 'ION-MODAL' && presentingEl.presentingElement !== undefined;
21383
- const presentingElRoot = getElementRoot(presentingEl);
21384
- const bodyEl = document.body;
21385
- const baseAnimation = createAnimation('portrait-to-landscape-transition')
21386
- .addElement(baseEl)
21387
- .easing('cubic-bezier(0.32,0.72,0,1)')
21388
- .duration(duration);
21389
- const presentingAnimation = createAnimation().beforeStyles({
21390
- transform: 'translateY(0)',
21391
- 'transform-origin': 'top center',
21392
- overflow: 'hidden',
21393
- });
21394
- if (!hasCardModal) {
21395
- // Non-card modal: transition from portrait state to landscape state
21396
- // Portrait: presentingEl has transform and body has black background
21397
- // Landscape: no transform, no body background, modal wrapper opacity changes
21398
- const root = getElementRoot(baseEl);
21399
- const wrapperAnimation = createAnimation()
21400
- .addElement(root.querySelectorAll('.modal-wrapper, .modal-shadow'))
21401
- .fromTo('opacity', '1', '1'); // Keep wrapper visible in landscape
21402
- const backdropAnimation = createAnimation()
21403
- .addElement(root.querySelector('ion-backdrop'))
21404
- .fromTo('opacity', 'var(--backdrop-opacity)', 'var(--backdrop-opacity)'); // Keep backdrop visible
21405
- // Animate presentingEl from portrait state back to normal
21406
- const transformOffset = !CSS.supports('width', 'max(0px, 1px)') ? '30px' : 'max(30px, var(--ion-safe-area-top))';
21407
- const toPresentingScale = SwipeToCloseDefaults.MIN_PRESENTING_SCALE;
21408
- const fromTransform = `translateY(${transformOffset}) scale(${toPresentingScale})`;
21409
- presentingAnimation
21410
- .addElement(presentingEl)
21411
- .afterStyles({
21412
- transform: 'translateY(0px) scale(1)',
21413
- 'border-radius': '0px',
21414
- })
21415
- .beforeAddWrite(() => bodyEl.style.setProperty('background-color', ''))
21416
- .fromTo('transform', fromTransform, 'translateY(0px) scale(1)')
21417
- .fromTo('filter', 'contrast(0.85)', 'contrast(1)')
21418
- .fromTo('border-radius', '10px 10px 0 0', '0px');
21419
- baseAnimation.addAnimation([presentingAnimation, wrapperAnimation, backdropAnimation]);
21420
- }
21421
- else {
21422
- // Card modal: transition from portrait card state to landscape card state
21423
- const toPresentingScale = SwipeToCloseDefaults.MIN_PRESENTING_SCALE;
21424
- const transformOffset = !CSS.supports('width', 'max(0px, 1px)') ? '30px' : 'max(30px, var(--ion-safe-area-top))';
21425
- const fromTransform = `translateY(${transformOffset}) scale(${toPresentingScale})`;
21426
- const toTransform = `translateY(-10px) scale(${toPresentingScale})`;
21427
- presentingAnimation
21428
- .addElement(presentingElRoot.querySelector('.modal-wrapper'))
21429
- .fromTo('transform', fromTransform, toTransform)
21430
- .fromTo('filter', 'contrast(0.85)', 'contrast(0.85)'); // Keep same contrast for card
21431
- const shadowAnimation = createAnimation()
21432
- .addElement(presentingElRoot.querySelector('.modal-shadow'))
21433
- .fromTo('opacity', '0', '0') // Shadow stays hidden in landscape for card modals
21434
- .fromTo('transform', fromTransform, toTransform);
21435
- baseAnimation.addAnimation([presentingAnimation, shadowAnimation]);
21436
- }
21437
- return baseAnimation;
21438
- };
21439
- /**
21440
- * Transition animation from landscape view to portrait view
21441
- * This handles the case where a card modal is open in landscape view
21442
- * and the user switches to portrait view
21443
- */
21444
- const landscapeToPortraitTransition = (baseEl, opts, duration = 300) => {
21445
- const { presentingEl } = opts;
21446
- if (!presentingEl) {
21447
- // No transition needed for non-card modals
21448
- return createAnimation('landscape-to-portrait-transition');
21449
- }
21450
- const hasCardModal = presentingEl.tagName === 'ION-MODAL' && presentingEl.presentingElement !== undefined;
21451
- const presentingElRoot = getElementRoot(presentingEl);
21452
- const bodyEl = document.body;
21453
- const baseAnimation = createAnimation('landscape-to-portrait-transition')
21454
- .addElement(baseEl)
21455
- .easing('cubic-bezier(0.32,0.72,0,1)')
21456
- .duration(duration);
21457
- const presentingAnimation = createAnimation().beforeStyles({
21458
- transform: 'translateY(0)',
21459
- 'transform-origin': 'top center',
21460
- overflow: 'hidden',
21461
- });
21462
- if (!hasCardModal) {
21463
- // Non-card modal: transition from landscape state to portrait state
21464
- const root = getElementRoot(baseEl);
21465
- const wrapperAnimation = createAnimation()
21466
- .addElement(root.querySelectorAll('.modal-wrapper, .modal-shadow'))
21467
- .fromTo('opacity', '1', '1'); // Keep wrapper visible
21468
- const backdropAnimation = createAnimation()
21469
- .addElement(root.querySelector('ion-backdrop'))
21470
- .fromTo('opacity', 'var(--backdrop-opacity)', 'var(--backdrop-opacity)'); // Keep backdrop visible
21471
- // Animate presentingEl from normal state to portrait state
21472
- const transformOffset = !CSS.supports('width', 'max(0px, 1px)') ? '30px' : 'max(30px, var(--ion-safe-area-top))';
21473
- const toPresentingScale = SwipeToCloseDefaults.MIN_PRESENTING_SCALE;
21474
- const toTransform = `translateY(${transformOffset}) scale(${toPresentingScale})`;
21475
- presentingAnimation
21476
- .addElement(presentingEl)
21477
- .afterStyles({
21478
- transform: toTransform,
21479
- 'border-radius': '10px 10px 0 0',
21480
- filter: 'contrast(0.85)',
21481
- overflow: 'hidden',
21482
- 'transform-origin': 'top center',
21483
- })
21484
- .beforeAddWrite(() => bodyEl.style.setProperty('background-color', 'black'))
21485
- .fromTo('transform', 'translateY(0px) scale(1)', toTransform)
21486
- .fromTo('filter', 'contrast(1)', 'contrast(0.85)')
21487
- .fromTo('border-radius', '0px', '10px 10px 0 0');
21488
- baseAnimation.addAnimation([presentingAnimation, wrapperAnimation, backdropAnimation]);
21489
- }
21490
- else {
21491
- // Card modal: transition from landscape card state to portrait card state
21492
- const toPresentingScale = SwipeToCloseDefaults.MIN_PRESENTING_SCALE;
21493
- const transformOffset = !CSS.supports('width', 'max(0px, 1px)') ? '30px' : 'max(30px, var(--ion-safe-area-top))';
21494
- const fromTransform = `translateY(-10px) scale(${toPresentingScale})`;
21495
- const toTransform = `translateY(${transformOffset}) scale(${toPresentingScale})`;
21496
- presentingAnimation
21497
- .addElement(presentingElRoot.querySelector('.modal-wrapper'))
21498
- .fromTo('transform', fromTransform, toTransform)
21499
- .fromTo('filter', 'contrast(0.85)', 'contrast(0.85)'); // Keep same contrast for card
21500
- const shadowAnimation = createAnimation()
21501
- .addElement(presentingElRoot.querySelector('.modal-shadow'))
21502
- .fromTo('opacity', '0', '0') // Shadow stays hidden
21503
- .fromTo('transform', fromTransform, toTransform);
21504
- baseAnimation.addAnimation([presentingAnimation, shadowAnimation]);
21505
- }
21506
- return baseAnimation;
21507
- };
21508
-
21509
21380
  const createEnterAnimation = () => {
21510
21381
  const backdropAnimation = createAnimation()
21511
21382
  .fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
@@ -22297,7 +22168,6 @@ class Modal {
22297
22168
  }
22298
22169
  disconnectedCallback() {
22299
22170
  this.triggerController.removeClickListener();
22300
- this.cleanupViewTransitionListener();
22301
22171
  }
22302
22172
  componentWillLoad() {
22303
22173
  var _a;
@@ -22508,8 +22378,6 @@ class Modal {
22508
22378
  else if (hasCardModal) {
22509
22379
  this.initSwipeToClose();
22510
22380
  }
22511
- // Initialize view transition listener for iOS card modals
22512
- this.initViewTransitionListener();
22513
22381
  unlock();
22514
22382
  }
22515
22383
  initSwipeToClose() {
@@ -22663,7 +22531,6 @@ class Modal {
22663
22531
  if (this.gesture) {
22664
22532
  this.gesture.destroy();
22665
22533
  }
22666
- this.cleanupViewTransitionListener();
22667
22534
  }
22668
22535
  this.currentBreakpoint = undefined;
22669
22536
  this.animation = undefined;
@@ -22739,76 +22606,6 @@ class Modal {
22739
22606
  await this.setCurrentBreakpoint(nextBreakpoint);
22740
22607
  return true;
22741
22608
  }
22742
- initViewTransitionListener() {
22743
- // Only enable for iOS card modals when no custom animations are provided
22744
- if (getIonMode$1(this) !== 'ios' || !this.presentingElement || this.enterAnimation || this.leaveAnimation) {
22745
- return;
22746
- }
22747
- // Set initial view state
22748
- this.currentViewIsPortrait = window.innerWidth < 768;
22749
- // Create debounced resize handler
22750
- let resizeTimeout;
22751
- this.resizeListener = () => {
22752
- clearTimeout(resizeTimeout);
22753
- resizeTimeout = setTimeout(() => {
22754
- this.handleViewTransition();
22755
- }, 100); // Debounce for 100ms to avoid excessive calls
22756
- };
22757
- window.addEventListener('resize', this.resizeListener);
22758
- }
22759
- handleViewTransition() {
22760
- const isPortrait = window.innerWidth < 768;
22761
- // Only transition if view state actually changed
22762
- if (this.currentViewIsPortrait === isPortrait) {
22763
- return;
22764
- }
22765
- // Cancel any ongoing transition animation
22766
- if (this.viewTransitionAnimation) {
22767
- this.viewTransitionAnimation.destroy();
22768
- this.viewTransitionAnimation = undefined;
22769
- }
22770
- const { presentingElement } = this;
22771
- if (!presentingElement) {
22772
- return;
22773
- }
22774
- // Create transition animation
22775
- let transitionAnimation;
22776
- if (this.currentViewIsPortrait && !isPortrait) {
22777
- // Portrait to landscape transition
22778
- transitionAnimation = portraitToLandscapeTransition(this.el, {
22779
- presentingEl: presentingElement});
22780
- }
22781
- else {
22782
- // Landscape to portrait transition
22783
- transitionAnimation = landscapeToPortraitTransition(this.el, {
22784
- presentingEl: presentingElement});
22785
- }
22786
- // Update state and play animation
22787
- this.currentViewIsPortrait = isPortrait;
22788
- this.viewTransitionAnimation = transitionAnimation;
22789
- transitionAnimation.play().then(() => {
22790
- this.viewTransitionAnimation = undefined;
22791
- });
22792
- }
22793
- cleanupViewTransitionListener() {
22794
- const hasCardView = !!this.resizeListener;
22795
- if (this.resizeListener) {
22796
- window.removeEventListener('resize', this.resizeListener);
22797
- this.resizeListener = undefined;
22798
- }
22799
- if (this.viewTransitionAnimation) {
22800
- this.viewTransitionAnimation.destroy();
22801
- this.viewTransitionAnimation = undefined;
22802
- }
22803
- if (hasCardView) {
22804
- // If we had a card view, let's trigger the view transition
22805
- // one last time to make sure we're in the right state.
22806
- // This will prevent tricky things like resizing the modal causing
22807
- // it to dismiss programatically too quickly and preventing the view transition
22808
- // from being applied.
22809
- this.handleViewTransition();
22810
- }
22811
- }
22812
22609
  render() {
22813
22610
  const { handle, isSheetModal, presentingElement, htmlAttributes, handleBehavior, inheritedAttributes, focusTrap, expandToScroll, } = this;
22814
22611
  const showHandle = handle !== false && isSheetModal;
@@ -22816,20 +22613,20 @@ class Modal {
22816
22613
  const isCardModal = presentingElement !== undefined && mode === 'ios';
22817
22614
  const isHandleCycle = handleBehavior === 'cycle';
22818
22615
  const isSheetModalWithHandle = isSheetModal && showHandle;
22819
- return (hAsync(Host, Object.assign({ key: '857fbf50b5d0b43c1f1a335d740649cedf1d6e2b', "no-router": true,
22616
+ return (hAsync(Host, Object.assign({ key: '8add05bb43a2cdb5e3cf180147d31eb85a018fe0', "no-router": true,
22820
22617
  // Allow the modal to be navigable when the handle is focusable
22821
22618
  tabIndex: isHandleCycle && isSheetModalWithHandle ? 0 : -1 }, htmlAttributes, { style: {
22822
22619
  zIndex: `${20000 + this.overlayIndex}`,
22823
- }, 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: '07b6143d368748194e4b209b48c7d9efbeed12e0', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && hAsync("div", { key: '14eaf25ad683ca5c7369e69908ea93401dd5536b', class: "modal-shadow" }), hAsync("div", Object.assign({ key: '9b996da27066c8dfdce8fcf3abdff65948010b5e',
22620
+ }, 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: '90a6605a9564a699d6f66cf71cf6b506796a2963', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && hAsync("div", { key: 'a97d071395333bf803c0a9347bda000cf7500d8d', class: "modal-shadow" }), hAsync("div", Object.assign({ key: 'e7b7985c7414a13e3ba8dcecf497b76e92edf53e',
22824
22621
  /*
22825
22622
  role and aria-modal must be used on the
22826
22623
  same element. They must also be set inside the
22827
22624
  shadow DOM otherwise ion-button will not be highlighted
22828
22625
  when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
22829
22626
  */
22830
- role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (hAsync("button", { key: 'd3b429aa40e094548a5eeaa295f4cb1b1f921339', class: "modal-handle",
22627
+ role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (hAsync("button", { key: '8258b65570b11a8ee9c9df2537d6419cd2e34536', class: "modal-handle",
22831
22628
  // Prevents the handle from receiving keyboard focus when it does not cycle
22832
- 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: '86160fcdf92d6ca2a9afe5c801efb89c32ce2cc1' }))));
22629
+ 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: '394370d0ed03ee03152f8f8abae7ff7664ca5c13' }))));
22833
22630
  }
22834
22631
  get el() { return getElement(this); }
22835
22632
  static get watchers() { return {
@@ -32854,7 +32651,7 @@ class Select {
32854
32651
  const scrollSelectedIntoView = () => {
32855
32652
  const indexOfSelected = this.childOpts.findIndex((o) => o.value === this.value);
32856
32653
  if (indexOfSelected > -1) {
32857
- const selectedItem = overlay.querySelector(`.select-interface-option:nth-child(${indexOfSelected + 1})`);
32654
+ const selectedItem = overlay.querySelector(`.select-interface-option:nth-of-type(${indexOfSelected + 1})`);
32858
32655
  if (selectedItem) {
32859
32656
  /**
32860
32657
  * Browsers such as Firefox do not
@@ -33374,7 +33171,7 @@ class Select {
33374
33171
  * TODO(FW-5592): Remove hasStartEndSlots condition
33375
33172
  */
33376
33173
  const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || isExpanded || hasStartEndSlots));
33377
- return (hAsync(Host, { key: 'e33253af9b9daa14460c7c259fb138b4d2b875ae', onClick: this.onClick, class: createColorClasses$1(this.color, {
33174
+ return (hAsync(Host, { key: 'c03fb65e8fc9f9aab295e07b282377d57d910519', onClick: this.onClick, class: createColorClasses$1(this.color, {
33378
33175
  [mode]: true,
33379
33176
  'in-item': inItem,
33380
33177
  'in-item-color': hostContext('ion-item.ion-color', el),
@@ -33392,7 +33189,7 @@ class Select {
33392
33189
  [`select-justify-${justify}`]: justifyEnabled,
33393
33190
  [`select-shape-${shape}`]: shape !== undefined,
33394
33191
  [`select-label-placement-${labelPlacement}`]: true,
33395
- }) }, hAsync("label", { key: '03303b7131c77a78a933e8e496e7251b6b5c485b', class: "select-wrapper", id: "select-label", onClick: this.onLabelClick }, this.renderLabelContainer(), hAsync("div", { key: '9037674db6a0adc189e887c9048f817d5afdf635', class: "select-wrapper-inner" }, hAsync("slot", { key: '7c9226c838ba4bcf5bc0b234fa1613ce335cf73d', name: "start" }), hAsync("div", { key: 'a7432c3efb5c65f88a5e4b0d35c5a433fa4e949d', class: "native-wrapper", ref: (el) => (this.nativeWrapperEl = el), part: "container" }, this.renderSelectText(), this.renderListbox()), hAsync("slot", { key: '028e683df26a8f573d7670da76e0ad26d21c83e0', name: "end" }), !hasFloatingOrStackedLabel && this.renderSelectIcon()), hasFloatingOrStackedLabel && this.renderSelectIcon(), shouldRenderHighlight && hAsync("div", { key: '20341bcae3753048ce905d2aceffa5351a0db125', class: "select-highlight" })), this.renderBottomContent()));
33192
+ }) }, hAsync("label", { key: '0d0c8ec55269adcac625f2899a547f4e7f3e3741', class: "select-wrapper", id: "select-label", onClick: this.onLabelClick }, this.renderLabelContainer(), hAsync("div", { key: 'f6dfc93c0e23cbe75a2947abde67d842db2dad78', class: "select-wrapper-inner" }, hAsync("slot", { key: '957bfadf9f101f519091419a362d3abdc2be66f6', name: "start" }), hAsync("div", { key: 'ca349202a484e7f2e884533fd330f0b136754f7d', class: "native-wrapper", ref: (el) => (this.nativeWrapperEl = el), part: "container" }, this.renderSelectText(), this.renderListbox()), hAsync("slot", { key: 'f0e62a6533ff1c8f62bd2d27f60b23385c4fa9ed', name: "end" }), !hasFloatingOrStackedLabel && this.renderSelectIcon()), hasFloatingOrStackedLabel && this.renderSelectIcon(), shouldRenderHighlight && hAsync("div", { key: 'fb840d46bafafb09898ebeebbe8c181906a3d8a2', class: "select-highlight" })), this.renderBottomContent()));
33396
33193
  }
33397
33194
  get el() { return getElement(this); }
33398
33195
  static get watchers() { return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ionic/core",
3
- "version": "8.6.3-dev.11751378808.12cc4a5c",
3
+ "version": "8.6.3-dev.11751478001.1cb7436f",
4
4
  "description": "Base components for Ionic",
5
5
  "keywords": [
6
6
  "ionic",
@@ -1,143 +0,0 @@
1
- /*!
2
- * (C) Ionic http://ionicframework.com - MIT License
3
- */
4
- import { createAnimation } from "../../../utils/animation/animation";
5
- import { getElementRoot } from "../../../utils/helpers";
6
- import { SwipeToCloseDefaults } from "../gestures/swipe-to-close";
7
- /**
8
- * Transition animation from portrait view to landscape view
9
- * This handles the case where a card modal is open in portrait view
10
- * and the user switches to landscape view
11
- */
12
- export const portraitToLandscapeTransition = (baseEl, opts, duration = 300) => {
13
- const { presentingEl } = opts;
14
- if (!presentingEl) {
15
- // No transition needed for non-card modals
16
- return createAnimation('portrait-to-landscape-transition');
17
- }
18
- const hasCardModal = presentingEl.tagName === 'ION-MODAL' && presentingEl.presentingElement !== undefined;
19
- const presentingElRoot = getElementRoot(presentingEl);
20
- const bodyEl = document.body;
21
- const baseAnimation = createAnimation('portrait-to-landscape-transition')
22
- .addElement(baseEl)
23
- .easing('cubic-bezier(0.32,0.72,0,1)')
24
- .duration(duration);
25
- const presentingAnimation = createAnimation().beforeStyles({
26
- transform: 'translateY(0)',
27
- 'transform-origin': 'top center',
28
- overflow: 'hidden',
29
- });
30
- if (!hasCardModal) {
31
- // Non-card modal: transition from portrait state to landscape state
32
- // Portrait: presentingEl has transform and body has black background
33
- // Landscape: no transform, no body background, modal wrapper opacity changes
34
- const root = getElementRoot(baseEl);
35
- const wrapperAnimation = createAnimation()
36
- .addElement(root.querySelectorAll('.modal-wrapper, .modal-shadow'))
37
- .fromTo('opacity', '1', '1'); // Keep wrapper visible in landscape
38
- const backdropAnimation = createAnimation()
39
- .addElement(root.querySelector('ion-backdrop'))
40
- .fromTo('opacity', 'var(--backdrop-opacity)', 'var(--backdrop-opacity)'); // Keep backdrop visible
41
- // Animate presentingEl from portrait state back to normal
42
- const transformOffset = !CSS.supports('width', 'max(0px, 1px)') ? '30px' : 'max(30px, var(--ion-safe-area-top))';
43
- const toPresentingScale = SwipeToCloseDefaults.MIN_PRESENTING_SCALE;
44
- const fromTransform = `translateY(${transformOffset}) scale(${toPresentingScale})`;
45
- presentingAnimation
46
- .addElement(presentingEl)
47
- .afterStyles({
48
- transform: 'translateY(0px) scale(1)',
49
- 'border-radius': '0px',
50
- })
51
- .beforeAddWrite(() => bodyEl.style.setProperty('background-color', ''))
52
- .fromTo('transform', fromTransform, 'translateY(0px) scale(1)')
53
- .fromTo('filter', 'contrast(0.85)', 'contrast(1)')
54
- .fromTo('border-radius', '10px 10px 0 0', '0px');
55
- baseAnimation.addAnimation([presentingAnimation, wrapperAnimation, backdropAnimation]);
56
- }
57
- else {
58
- // Card modal: transition from portrait card state to landscape card state
59
- const toPresentingScale = SwipeToCloseDefaults.MIN_PRESENTING_SCALE;
60
- const transformOffset = !CSS.supports('width', 'max(0px, 1px)') ? '30px' : 'max(30px, var(--ion-safe-area-top))';
61
- const fromTransform = `translateY(${transformOffset}) scale(${toPresentingScale})`;
62
- const toTransform = `translateY(-10px) scale(${toPresentingScale})`;
63
- presentingAnimation
64
- .addElement(presentingElRoot.querySelector('.modal-wrapper'))
65
- .fromTo('transform', fromTransform, toTransform)
66
- .fromTo('filter', 'contrast(0.85)', 'contrast(0.85)'); // Keep same contrast for card
67
- const shadowAnimation = createAnimation()
68
- .addElement(presentingElRoot.querySelector('.modal-shadow'))
69
- .fromTo('opacity', '0', '0') // Shadow stays hidden in landscape for card modals
70
- .fromTo('transform', fromTransform, toTransform);
71
- baseAnimation.addAnimation([presentingAnimation, shadowAnimation]);
72
- }
73
- return baseAnimation;
74
- };
75
- /**
76
- * Transition animation from landscape view to portrait view
77
- * This handles the case where a card modal is open in landscape view
78
- * and the user switches to portrait view
79
- */
80
- export const landscapeToPortraitTransition = (baseEl, opts, duration = 300) => {
81
- const { presentingEl } = opts;
82
- if (!presentingEl) {
83
- // No transition needed for non-card modals
84
- return createAnimation('landscape-to-portrait-transition');
85
- }
86
- const hasCardModal = presentingEl.tagName === 'ION-MODAL' && presentingEl.presentingElement !== undefined;
87
- const presentingElRoot = getElementRoot(presentingEl);
88
- const bodyEl = document.body;
89
- const baseAnimation = createAnimation('landscape-to-portrait-transition')
90
- .addElement(baseEl)
91
- .easing('cubic-bezier(0.32,0.72,0,1)')
92
- .duration(duration);
93
- const presentingAnimation = createAnimation().beforeStyles({
94
- transform: 'translateY(0)',
95
- 'transform-origin': 'top center',
96
- overflow: 'hidden',
97
- });
98
- if (!hasCardModal) {
99
- // Non-card modal: transition from landscape state to portrait state
100
- const root = getElementRoot(baseEl);
101
- const wrapperAnimation = createAnimation()
102
- .addElement(root.querySelectorAll('.modal-wrapper, .modal-shadow'))
103
- .fromTo('opacity', '1', '1'); // Keep wrapper visible
104
- const backdropAnimation = createAnimation()
105
- .addElement(root.querySelector('ion-backdrop'))
106
- .fromTo('opacity', 'var(--backdrop-opacity)', 'var(--backdrop-opacity)'); // Keep backdrop visible
107
- // Animate presentingEl from normal state to portrait state
108
- const transformOffset = !CSS.supports('width', 'max(0px, 1px)') ? '30px' : 'max(30px, var(--ion-safe-area-top))';
109
- const toPresentingScale = SwipeToCloseDefaults.MIN_PRESENTING_SCALE;
110
- const toTransform = `translateY(${transformOffset}) scale(${toPresentingScale})`;
111
- presentingAnimation
112
- .addElement(presentingEl)
113
- .afterStyles({
114
- transform: toTransform,
115
- 'border-radius': '10px 10px 0 0',
116
- filter: 'contrast(0.85)',
117
- overflow: 'hidden',
118
- 'transform-origin': 'top center',
119
- })
120
- .beforeAddWrite(() => bodyEl.style.setProperty('background-color', 'black'))
121
- .fromTo('transform', 'translateY(0px) scale(1)', toTransform)
122
- .fromTo('filter', 'contrast(1)', 'contrast(0.85)')
123
- .fromTo('border-radius', '0px', '10px 10px 0 0');
124
- baseAnimation.addAnimation([presentingAnimation, wrapperAnimation, backdropAnimation]);
125
- }
126
- else {
127
- // Card modal: transition from landscape card state to portrait card state
128
- const toPresentingScale = SwipeToCloseDefaults.MIN_PRESENTING_SCALE;
129
- const transformOffset = !CSS.supports('width', 'max(0px, 1px)') ? '30px' : 'max(30px, var(--ion-safe-area-top))';
130
- const fromTransform = `translateY(-10px) scale(${toPresentingScale})`;
131
- const toTransform = `translateY(${transformOffset}) scale(${toPresentingScale})`;
132
- presentingAnimation
133
- .addElement(presentingElRoot.querySelector('.modal-wrapper'))
134
- .fromTo('transform', fromTransform, toTransform)
135
- .fromTo('filter', 'contrast(0.85)', 'contrast(0.85)'); // Keep same contrast for card
136
- const shadowAnimation = createAnimation()
137
- .addElement(presentingElRoot.querySelector('.modal-shadow'))
138
- .fromTo('opacity', '0', '0') // Shadow stays hidden
139
- .fromTo('transform', fromTransform, toTransform);
140
- baseAnimation.addAnimation([presentingAnimation, shadowAnimation]);
141
- }
142
- return baseAnimation;
143
- };