@ionic/core 9.0.1-dev.11787248963.10a00c73 → 9.0.1-dev.11787589191.1e183b55

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 (94) hide show
  1. package/components/index.js +1 -1
  2. package/components/ion-action-sheet.js +1 -1
  3. package/components/ion-alert.js +1 -1
  4. package/components/ion-datetime.js +1 -1
  5. package/components/ion-item-sliding.js +1 -1
  6. package/components/ion-loading.js +1 -1
  7. package/components/ion-menu.js +1 -1
  8. package/components/ion-modal.js +1 -1
  9. package/components/ion-popover.js +1 -1
  10. package/components/ion-segment-button.js +1 -1
  11. package/components/ion-select-modal.js +1 -1
  12. package/components/ion-select-popover.js +1 -1
  13. package/components/ion-select.js +1 -1
  14. package/components/ion-toast.js +1 -1
  15. package/components/p-BPnXVGaS.js +4 -0
  16. package/components/p-BQAiulS1.js +4 -0
  17. package/components/p-Bh2ta0iG.js +4 -0
  18. package/components/{p-CaiZOhfC.js → p-BnUOVmKh.js} +1 -1
  19. package/components/{p-Bnc0m4SW.js → p-D1OCo42s.js} +1 -1
  20. package/components/p-DD57rSP_.js +4 -0
  21. package/components/p-DnXLaaf7.js +4 -0
  22. package/dist/cjs/index.cjs.js +1 -1
  23. package/dist/cjs/ion-action-sheet.cjs.entry.js +35 -20
  24. package/dist/cjs/ion-alert.cjs.entry.js +20 -12
  25. package/dist/cjs/ion-datetime.cjs.entry.js +1 -1
  26. package/dist/cjs/ion-item-option_3.cjs.entry.js +11 -9
  27. package/dist/cjs/ion-loading.cjs.entry.js +7 -3
  28. package/dist/cjs/ion-menu_3.cjs.entry.js +1 -1
  29. package/dist/cjs/ion-modal.cjs.entry.js +75 -22
  30. package/dist/cjs/ion-popover.cjs.entry.js +13 -3
  31. package/dist/cjs/ion-segment_2.cjs.entry.js +7 -11
  32. package/dist/cjs/ion-select-modal.cjs.entry.js +1 -1
  33. package/dist/cjs/ion-select_3.cjs.entry.js +1 -1
  34. package/dist/cjs/ion-toast.cjs.entry.js +1 -1
  35. package/dist/cjs/{overlays-Bg0auTQa.js → overlays-B5JeC8OQ.js} +52 -29
  36. package/dist/collection/components/action-sheet/action-sheet.js +35 -20
  37. package/dist/collection/components/alert/alert.js +20 -12
  38. package/dist/collection/components/item-sliding/item-sliding.js +12 -10
  39. package/dist/collection/components/loading/loading.js +7 -3
  40. package/dist/collection/components/modal/modal.js +75 -22
  41. package/dist/collection/components/popover/popover.js +13 -3
  42. package/dist/collection/components/segment-button/segment-button.js +7 -11
  43. package/dist/collection/utils/overlays.js +51 -29
  44. package/dist/docs.json +1 -1
  45. package/dist/esm/index.js +1 -1
  46. package/dist/esm/ion-action-sheet.entry.js +35 -20
  47. package/dist/esm/ion-alert.entry.js +20 -12
  48. package/dist/esm/ion-datetime.entry.js +1 -1
  49. package/dist/esm/ion-item-option_3.entry.js +12 -10
  50. package/dist/esm/ion-loading.entry.js +7 -3
  51. package/dist/esm/ion-menu_3.entry.js +1 -1
  52. package/dist/esm/ion-modal.entry.js +75 -22
  53. package/dist/esm/ion-popover.entry.js +13 -3
  54. package/dist/esm/ion-segment_2.entry.js +7 -11
  55. package/dist/esm/ion-select-modal.entry.js +1 -1
  56. package/dist/esm/ion-select_3.entry.js +1 -1
  57. package/dist/esm/ion-toast.entry.js +1 -1
  58. package/dist/esm/{overlays-BpnIFlXI.js → overlays-CefdMZgF.js} +52 -30
  59. package/dist/ionic/index.esm.js +1 -1
  60. package/dist/ionic/ionic.esm.js +1 -1
  61. package/dist/ionic/p-36abc1ee.entry.js +4 -0
  62. package/dist/ionic/{p-873a315a.entry.js → p-408973f4.entry.js} +1 -1
  63. package/dist/ionic/{p-4437015c.entry.js → p-46a938a9.entry.js} +1 -1
  64. package/dist/ionic/p-47626333.entry.js +4 -0
  65. package/dist/ionic/p-8f464a8f.entry.js +4 -0
  66. package/dist/ionic/p-9455207b.entry.js +4 -0
  67. package/dist/ionic/p-DLLCmV-y.js +4 -0
  68. package/dist/ionic/{p-05800a02.entry.js → p-a2fa2de2.entry.js} +1 -1
  69. package/dist/ionic/p-a53b0908.entry.js +4 -0
  70. package/dist/ionic/{p-75887ee0.entry.js → p-b875a59e.entry.js} +1 -1
  71. package/dist/ionic/p-f3b671aa.entry.js +4 -0
  72. package/dist/ionic/p-f521b13c.entry.js +4 -0
  73. package/dist/ionic/{p-49b9d405.entry.js → p-f8713b2c.entry.js} +1 -1
  74. package/dist/types/components/action-sheet/action-sheet.d.ts +10 -0
  75. package/dist/types/components/alert/alert.d.ts +7 -0
  76. package/dist/types/components/modal/modal.d.ts +8 -0
  77. package/dist/types/utils/overlays.d.ts +9 -0
  78. package/hydrate/index.js +214 -104
  79. package/hydrate/index.mjs +214 -104
  80. package/package.json +1 -1
  81. package/components/p-Bg4OwDwb.js +0 -4
  82. package/components/p-CQAjyETU.js +0 -4
  83. package/components/p-DqAI6tg7.js +0 -4
  84. package/components/p-DrehWDfv.js +0 -4
  85. package/components/p-eFI3mtEX.js +0 -4
  86. package/dist/collection/utils/test/late-props/late-props.js +0 -69
  87. package/dist/ionic/p-34b9379b.entry.js +0 -4
  88. package/dist/ionic/p-48c859fe.entry.js +0 -4
  89. package/dist/ionic/p-5b906fd6.entry.js +0 -4
  90. package/dist/ionic/p-68507e70.entry.js +0 -4
  91. package/dist/ionic/p-886d9e66.entry.js +0 -4
  92. package/dist/ionic/p-DdhHqKj-.js +0 -4
  93. package/dist/ionic/p-b7a11b58.entry.js +0 -4
  94. package/dist/ionic/p-f7dd1ed9.entry.js +0 -4
package/hydrate/index.mjs CHANGED
@@ -7959,6 +7959,15 @@ const activeAnimations = new WeakMap();
7959
7959
  const isBackdropAlwaysBlocking = (el) => {
7960
7960
  return el.showBackdrop !== false && !((el.backdropBreakpoint ?? 0) > 0);
7961
7961
  };
7962
+ /**
7963
+ * Whether the overlay takes the app root out of the accessibility tree and
7964
+ * blocks body scroll while presented. Toasts never do, modal and popover can
7965
+ * opt out with `focusTrap={false}`, and a backdrop that does not block
7966
+ * (`showBackdrop={false}`, or a `backdropBreakpoint` above 0) is excluded.
7967
+ */
7968
+ const locksAppRoot = (el) => {
7969
+ return el.tagName !== 'ION-TOAST' && el.focusTrap !== false && isBackdropAlwaysBlocking(el);
7970
+ };
7962
7971
  const createController = (tagName) => {
7963
7972
  return {
7964
7973
  create(options) {
@@ -8327,6 +8336,13 @@ const getPresentedOverlay = (doc, overlayTag, id) => {
8327
8336
  // Otherwise, return the last overlay with the given id
8328
8337
  return (id === undefined ? overlays : overlays.filter((o) => o.id === id)).slice(-1)[0];
8329
8338
  };
8339
+ /**
8340
+ * The element an app nests its views under. Overlays hide this rather than the
8341
+ * whole root, so the overlay itself (a sibling) stays reachable.
8342
+ */
8343
+ const getViewContainer = () => {
8344
+ return getAppRoot(document).querySelector('ion-router-outlet, #ion-view-container-root');
8345
+ };
8330
8346
  /**
8331
8347
  * When an overlay is presented, the main
8332
8348
  * focus is the overlay not the page content.
@@ -8350,8 +8366,7 @@ const getPresentedOverlay = (doc, overlayTag, id) => {
8350
8366
  * for main content.
8351
8367
  */
8352
8368
  const setRootAriaHidden = (hidden = false) => {
8353
- const root = getAppRoot(document);
8354
- const viewContainer = root.querySelector('ion-router-outlet, #ion-view-container-root');
8369
+ const viewContainer = getViewContainer();
8355
8370
  if (!viewContainer) {
8356
8371
  return;
8357
8372
  }
@@ -8376,15 +8391,40 @@ const cleanupRootFocusTrapAccessibility = () => {
8376
8391
  return;
8377
8392
  }
8378
8393
  const remainingOverlays = getPresentedOverlays(document);
8379
- const hasRemainingLocking = remainingOverlays.some((o) => {
8380
- const el = o;
8381
- return el.tagName !== 'ION-TOAST' && el.focusTrap !== false && isBackdropAlwaysBlocking(el);
8382
- });
8394
+ const hasRemainingLocking = remainingOverlays.some((o) => locksAppRoot(o));
8383
8395
  if (!hasRemainingLocking) {
8384
8396
  setRootAriaHidden(false);
8385
8397
  document.body.classList.remove(BACKDROP_NO_SCROLL);
8386
8398
  }
8387
8399
  };
8400
+ /**
8401
+ * Shared by `present()` and the restore below, which have to stay in lockstep.
8402
+ */
8403
+ const applyRootLock = (el) => {
8404
+ // Hiding the container the overlay now sits in would hide the overlay too.
8405
+ if (!getViewContainer()?.contains(el)) {
8406
+ setRootAriaHidden(true);
8407
+ }
8408
+ document.body.classList.add(BACKDROP_NO_SCROLL);
8409
+ };
8410
+ /**
8411
+ * Re-applies the root lock that `cleanupRootFocusTrapAccessibility()` released.
8412
+ * Call from `connectedCallback` when the overlay is still presented.
8413
+ *
8414
+ * A synchronous move keeps the overlay connected, so the lock survives. A
8415
+ * detach with a re-insert in a later task releases it, which is the shape a
8416
+ * framework produces when it takes a subtree out and puts it back.
8417
+ */
8418
+ const restoreRootFocusTrapAccessibility = (overlayEl) => {
8419
+ if (typeof document === 'undefined') {
8420
+ return;
8421
+ }
8422
+ const el = overlayEl;
8423
+ if (!locksAppRoot(el)) {
8424
+ return;
8425
+ }
8426
+ applyRootLock(el);
8427
+ };
8388
8428
  const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts) => {
8389
8429
  if (overlay.presented) {
8390
8430
  return;
@@ -8401,15 +8441,7 @@ const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts)
8401
8441
  restoreElementFocus(overlay.el);
8402
8442
  }
8403
8443
  /**
8404
- * Due to accessibility guidelines, toasts do not have
8405
- * focus traps.
8406
- *
8407
- * All other overlays should have focus traps to prevent
8408
- * the keyboard focus from leaving the overlay unless
8409
- * developers explicitly opt out (for example, sheet
8410
- * modals that should permit background interaction).
8411
- *
8412
- * Note: Some apps move inline overlays to a specific container
8444
+ * Some apps move inline overlays to a specific container
8413
8445
  * during the willPresent lifecycle (e.g., React portals via
8414
8446
  * onWillPresent). Defer applying aria-hidden/inert to the app
8415
8447
  * root until after willPresent so we can detect where the
@@ -8418,18 +8450,11 @@ const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts)
8418
8450
  * to avoid disabling the overlay.
8419
8451
  */
8420
8452
  const overlayEl = overlay.el;
8421
- const shouldTrapFocus = overlayEl.tagName !== 'ION-TOAST' && overlayEl.focusTrap !== false;
8422
- const shouldLockRoot = shouldTrapFocus && isBackdropAlwaysBlocking(overlayEl);
8453
+ const shouldLockRoot = locksAppRoot(overlayEl);
8423
8454
  overlay.presented = true;
8424
8455
  overlay.willPresent.emit();
8425
8456
  if (shouldLockRoot) {
8426
- const root = getAppRoot(document);
8427
- const viewContainer = root.querySelector('ion-router-outlet, #ion-view-container-root');
8428
- const overlayInsideViewContainer = viewContainer ? viewContainer.contains(overlayEl) : false;
8429
- if (!overlayInsideViewContainer) {
8430
- setRootAriaHidden(true);
8431
- }
8432
- document.body.classList.add(BACKDROP_NO_SCROLL);
8457
+ applyRootLock(overlayEl);
8433
8458
  }
8434
8459
  overlay.willPresentShorthand?.emit();
8435
8460
  const mode = getIonMode$1(overlay);
@@ -8555,12 +8580,9 @@ const dismiss = async (overlay, data, role, name, iosLeaveAnimation, mdLeaveAnim
8555
8580
  * from the root element when the last focus-trapping overlay
8556
8581
  * is dismissed.
8557
8582
  */
8558
- const overlaysLockingRoot = presentedOverlays.filter((o) => {
8559
- const el = o;
8560
- return el.tagName !== 'ION-TOAST' && el.focusTrap !== false && isBackdropAlwaysBlocking(el);
8561
- });
8583
+ const overlaysLockingRoot = presentedOverlays.filter((o) => locksAppRoot(o));
8562
8584
  const overlayEl = overlay.el;
8563
- const locksRoot = overlayEl.tagName !== 'ION-TOAST' && overlayEl.focusTrap !== false && isBackdropAlwaysBlocking(overlayEl);
8585
+ const locksRoot = locksAppRoot(overlayEl);
8564
8586
  /**
8565
8587
  * If this is the last visible overlay that is trapping focus
8566
8588
  * then we want to re-add the root to the accessibility tree.
@@ -10556,6 +10578,13 @@ class ActionSheet {
10556
10578
  connectedCallback() {
10557
10579
  prepareOverlay(this.el);
10558
10580
  this.triggerChanged();
10581
+ // `componentDidLoad` only fires once per instance, so a reconnect has to
10582
+ // rebuild the gesture its disconnect destroyed.
10583
+ this.setupButtonActiveGesture();
10584
+ // Re-apply the root lock if moved without dismiss() being called
10585
+ if (this.presented) {
10586
+ restoreRootFocusTrapAccessibility(this.el);
10587
+ }
10559
10588
  }
10560
10589
  disconnectedCallback() {
10561
10590
  if (this.gesture) {
@@ -10575,24 +10604,32 @@ class ActionSheet {
10575
10604
  // Initialize activeRadioId for radio buttons
10576
10605
  this.buttonsChanged();
10577
10606
  }
10578
- componentDidLoad() {
10579
- /**
10580
- * Only create gesture if:
10581
- * 1. A gesture does not already exist
10582
- * 2. App is running in iOS mode
10583
- * 3. A wrapper ref exists
10584
- * 4. A group ref exists
10585
- */
10607
+ /**
10608
+ * Only create gesture if:
10609
+ * 1. A gesture does not already exist
10610
+ * 2. App is running in iOS mode
10611
+ * 3. A wrapper ref exists
10612
+ * 4. A group ref exists
10613
+ * 5. The host is still connected, since a reconnect can schedule this and
10614
+ * disconnect again before the task runs
10615
+ */
10616
+ setupButtonActiveGesture() {
10586
10617
  const { groupEl, wrapperEl } = this;
10587
- if (!this.gesture && getIonMode$1(this) === 'ios' && wrapperEl && groupEl) {
10588
- readTask(() => {
10589
- const isScrollable = groupEl.scrollHeight > groupEl.clientHeight;
10590
- if (!isScrollable) {
10591
- this.gesture = createButtonActiveGesture(wrapperEl, (refEl) => refEl.classList.contains('action-sheet-button'));
10592
- this.gesture.enable(true);
10593
- }
10594
- });
10618
+ if (getIonMode$1(this) !== 'ios' || !wrapperEl || !groupEl) {
10619
+ return;
10595
10620
  }
10621
+ readTask(() => {
10622
+ // Two calls before the first flushes would otherwise both create a
10623
+ // gesture, orphaning the first with its listeners still bound.
10624
+ if (this.gesture || !this.el.isConnected || groupEl.scrollHeight > groupEl.clientHeight) {
10625
+ return;
10626
+ }
10627
+ this.gesture = createButtonActiveGesture(wrapperEl, (refEl) => refEl.classList.contains('action-sheet-button'));
10628
+ this.gesture.enable(true);
10629
+ });
10630
+ }
10631
+ componentDidLoad() {
10632
+ this.setupButtonActiveGesture();
10596
10633
  /**
10597
10634
  * If action sheet was rendered with isOpen="true"
10598
10635
  * then we should open action sheet immediately.
@@ -10685,17 +10722,17 @@ class ActionSheet {
10685
10722
  const cancelButton = allButtons.find((b) => b.role === 'cancel');
10686
10723
  const buttons = allButtons.filter((b) => b.role !== 'cancel');
10687
10724
  const headerID = `action-sheet-${overlayIndex}-header`;
10688
- return (hAsync(Host, { key: '7685831da9a78b73473246a2cea95cefa79a53c3', role: "dialog", "aria-modal": "true", "aria-labelledby": header !== undefined ? headerID : null, tabindex: "-1", ...htmlAttributes, style: {
10725
+ return (hAsync(Host, { key: '326d4af08e832e10e1882fbbf67dba3221095865', role: "dialog", "aria-modal": "true", "aria-labelledby": header !== undefined ? headerID : null, tabindex: "-1", ...htmlAttributes, style: {
10689
10726
  zIndex: `${20000 + this.overlayIndex}`,
10690
10727
  }, class: {
10691
10728
  [mode]: true,
10692
10729
  ...getClassMap(this.cssClass),
10693
10730
  'overlay-hidden': true,
10694
10731
  'action-sheet-translucent': this.translucent,
10695
- }, onIonActionSheetWillDismiss: this.dispatchCancelHandler, onIonBackdropTap: this.onBackdropTap }, hAsync("ion-backdrop", { key: 'c70f00e401cac99b89412d1adb867f35bc855d57', tappable: this.backdropDismiss }), hAsync("div", { key: '3332893ce3098f1435875480b1269b2821d41660', tabindex: "0", "aria-hidden": "true" }), hAsync("div", { key: 'eb406b0a9e303d6f94c5c7aa99c6f4c089bfbd41', class: "action-sheet-wrapper ion-overlay-wrapper", ref: (el) => (this.wrapperEl = el) }, hAsync("div", { key: '92ec855379f10e1e0bfce6ff68b45d3cda0c137c', class: "action-sheet-container" }, hAsync("div", { key: 'bc88a396d75396f574961471bf7e6c4edb513353', class: "action-sheet-group", ref: (el) => (this.groupEl = el), role: hasRadioButtons ? 'radiogroup' : undefined }, header !== undefined && (hAsync("div", { key: '33329e0193818888bdcaa443ff5ea301802e0787', id: headerID, class: {
10732
+ }, onIonActionSheetWillDismiss: this.dispatchCancelHandler, onIonBackdropTap: this.onBackdropTap }, hAsync("ion-backdrop", { key: '8cb6a0d763a60f61f563a1b7d572ad5e9afd6e40', tappable: this.backdropDismiss }), hAsync("div", { key: 'f8b8da0f52ae674a5e313632ee3d049bed3f813f', tabindex: "0", "aria-hidden": "true" }), hAsync("div", { key: '53cf0d1b01a2cda23c27fc8b96edaccf892e61b3', class: "action-sheet-wrapper ion-overlay-wrapper", ref: (el) => (this.wrapperEl = el) }, hAsync("div", { key: '6df261ff946c3b4496535df04cc70e2cfa3cc2da', class: "action-sheet-container" }, hAsync("div", { key: '6f6f2846d19baa738651b990d8613aa0ecac9479', class: "action-sheet-group", ref: (el) => (this.groupEl = el), role: hasRadioButtons ? 'radiogroup' : undefined }, header !== undefined && (hAsync("div", { key: '3f36df8eaaedb5e61a41bbf44134f25f263d1e7e', id: headerID, class: {
10696
10733
  'action-sheet-title': true,
10697
10734
  'action-sheet-has-sub-title': this.subHeader !== undefined,
10698
- } }, header, this.subHeader && hAsync("div", { key: '92ac5a9217a12b7417f7aca9c4fdb7bf6b051364', class: "action-sheet-sub-title" }, this.subHeader))), this.renderActionSheetButtons(buttons)), cancelButton && (hAsync("div", { key: '020463b830fa48fc3ae647ea64f2aaa4d0969305', class: "action-sheet-group action-sheet-group-cancel" }, hAsync("button", { key: 'cefa9c70a2233f6652a81b1a2eae6e717712144d', ...cancelButton.htmlAttributes, type: "button", class: buttonClass$2(cancelButton), onClick: () => this.buttonClick(cancelButton) }, hAsync("span", { key: '56d7e2f8bfb3644e4476895164d334445fda9b2f', class: "action-sheet-button-inner" }, cancelButton.icon && (hAsync("ion-icon", { key: '6a4a49254ec5cd96f4e0dce9447f90d8cac81913', icon: cancelButton.icon, "aria-hidden": "true", lazy: false, class: "action-sheet-icon" })), cancelButton.text), mode === 'md' && hAsync("ion-ripple-effect", { key: '7d3c6e8d70b0922ea0f75520856285ce1005c891' })))))), hAsync("div", { key: '958fc43e603c6a7f5d1e649d3326fce0f163b5d0', tabindex: "0", "aria-hidden": "true" })));
10735
+ } }, header, this.subHeader && hAsync("div", { key: 'a6b2bf51123eaae4ed873e65c00c426e9c511ac0', class: "action-sheet-sub-title" }, this.subHeader))), this.renderActionSheetButtons(buttons)), cancelButton && (hAsync("div", { key: '4dd96553327003b899bc03a815a06a7cce35db29', class: "action-sheet-group action-sheet-group-cancel" }, hAsync("button", { key: 'a1928040a3d20f2e50230b7d6003467d2916f5b4', ...cancelButton.htmlAttributes, type: "button", class: buttonClass$2(cancelButton), onClick: () => this.buttonClick(cancelButton) }, hAsync("span", { key: '2fa9d0e4072f1fd55f08048966495a627a14ef8f', class: "action-sheet-button-inner" }, cancelButton.icon && (hAsync("ion-icon", { key: 'c2eec9967cb9f0b75d4428bb548674199089203c', icon: cancelButton.icon, "aria-hidden": "true", lazy: false, class: "action-sheet-icon" })), cancelButton.text), mode === 'md' && hAsync("ion-ripple-effect", { key: '09e71f28d77ae16481b832863f49b3f7d7dd76f9' })))))), hAsync("div", { key: '386fbe5ca2a88e9b52bd3b9d8f3daddbc630e6f6', tabindex: "0", "aria-hidden": "true" })));
10699
10736
  }
10700
10737
  get el() { return getElement(this); }
10701
10738
  static get watchers() { return {
@@ -11077,10 +11114,15 @@ class Alert {
11077
11114
  this.triggerChanged();
11078
11115
  /**
11079
11116
  * If the alert was previously connected and is being reattached, the
11080
- * ResizeObserver was disconnected. componentDidLoad only fires once per
11081
- * instance, so re-establish the observer here on reconnect.
11117
+ * `ResizeObserver` and the button gesture were torn down. `componentDidLoad`
11118
+ * only fires once per instance, so re-establish both here on reconnect.
11082
11119
  */
11083
11120
  this.setupButtonGroupResizeObserver();
11121
+ this.setupButtonActiveGesture();
11122
+ // Re-apply the root lock if moved without dismiss() being called
11123
+ if (this.presented) {
11124
+ restoreRootFocusTrapAccessibility(this.el);
11125
+ }
11084
11126
  }
11085
11127
  componentWillLoad() {
11086
11128
  if (!this.htmlAttributes?.id) {
@@ -11102,17 +11144,20 @@ class Alert {
11102
11144
  this.buttonGroupResizeObserver?.disconnect();
11103
11145
  this.buttonGroupResizeObserver = undefined;
11104
11146
  }
11105
- componentDidLoad() {
11106
- /**
11107
- * Only create gesture if:
11108
- * 1. A gesture does not already exist
11109
- * 2. App is running in iOS mode
11110
- * 3. A wrapper ref exists
11111
- */
11147
+ /**
11148
+ * Only create gesture if:
11149
+ * 1. A gesture does not already exist
11150
+ * 2. App is running in iOS mode
11151
+ * 3. A wrapper ref exists
11152
+ */
11153
+ setupButtonActiveGesture() {
11112
11154
  if (!this.gesture && getIonMode$1(this) === 'ios' && this.wrapperEl) {
11113
11155
  this.gesture = createButtonActiveGesture(this.wrapperEl, (refEl) => refEl.classList.contains('alert-button'));
11114
11156
  this.gesture.enable(true);
11115
11157
  }
11158
+ }
11159
+ componentDidLoad() {
11160
+ this.setupButtonActiveGesture();
11116
11161
  this.setupButtonGroupResizeObserver();
11117
11162
  /**
11118
11163
  * If alert was rendered with isOpen="true"
@@ -11433,14 +11478,14 @@ class Alert {
11433
11478
  * If neither are defined, do not set aria-labelledby.
11434
11479
  */
11435
11480
  const ariaLabelledBy = header && subHeader ? `${hdrId} ${subHdrId}` : header ? hdrId : subHeader ? subHdrId : null;
11436
- return (hAsync(Host, { key: '022f3463b8e6c52064b90ec304c524847c3d5ad3', tabindex: "-1", style: {
11481
+ return (hAsync(Host, { key: '083b5250dc4c76e85240e0225abcb7ca2b66de2f', tabindex: "-1", style: {
11437
11482
  zIndex: `${20000 + overlayIndex}`,
11438
11483
  }, class: {
11439
11484
  ...getClassMap(this.cssClass),
11440
11485
  [mode]: true,
11441
11486
  'overlay-hidden': true,
11442
11487
  'alert-translucent': this.translucent,
11443
- }, onIonAlertWillDismiss: this.dispatchCancelHandler, onIonBackdropTap: this.onBackdropTap }, hAsync("ion-backdrop", { key: 'c3cd05738bc2834f54707edeb2fae06ec10d6fd2', tappable: this.backdropDismiss }), hAsync("div", { key: 'b44fadd9ba7ddf073854c5035538d11ae8e66bc2', tabindex: "0", "aria-hidden": "true" }), hAsync("div", { key: 'fafea048141a6c7957e62aef31faa8041dd610c1', class: "alert-wrapper ion-overlay-wrapper", role: role, "aria-modal": "true", "aria-labelledby": ariaLabelledBy, "aria-describedby": message !== undefined ? msgId : null, tabindex: "0", ref: (el) => (this.wrapperEl = el), ...htmlAttributes }, hAsync("div", { key: '3ad9d2d4b7cf425eab8293ddc12eff0fe8df1517', class: "alert-head" }, header && (hAsync("h2", { key: '7d9154f5ee595b7e4da6ecf3a20871f104c1256e', id: hdrId, class: "alert-title" }, header)), subHeader && !header && (hAsync("h2", { key: '1f891f38004be6964e9406b84dd580145c42516a', id: subHdrId, class: "alert-sub-title" }, subHeader)), subHeader && header && (hAsync("h3", { key: '2ab4d344ecb7e384e8f6d3d3e59ee5a1bbcc832c', id: subHdrId, class: "alert-sub-title" }, subHeader))), this.renderAlertMessage(msgId), this.renderAlertInputs(), this.renderAlertButtons()), hAsync("div", { key: '78a4ff09aa3aaafcd0dc2a42d036767d83b3cfa2', tabindex: "0", "aria-hidden": "true" })));
11488
+ }, onIonAlertWillDismiss: this.dispatchCancelHandler, onIonBackdropTap: this.onBackdropTap }, hAsync("ion-backdrop", { key: '65c92a956d998ae9016396dd2a29c42ab7376d0e', tappable: this.backdropDismiss }), hAsync("div", { key: 'f2288fa0b7ef9d0bf031c168fe78c48422cf91c8', tabindex: "0", "aria-hidden": "true" }), hAsync("div", { key: 'dbb109435c378f77c6b0231e58756f8a0467732d', class: "alert-wrapper ion-overlay-wrapper", role: role, "aria-modal": "true", "aria-labelledby": ariaLabelledBy, "aria-describedby": message !== undefined ? msgId : null, tabindex: "0", ref: (el) => (this.wrapperEl = el), ...htmlAttributes }, hAsync("div", { key: '075597f94719673cf1f894a8566e1036849afa75', class: "alert-head" }, header && (hAsync("h2", { key: 'f96f4b1db8473c62040beed6e96108c733978d73', id: hdrId, class: "alert-title" }, header)), subHeader && !header && (hAsync("h2", { key: 'dbd824ef19a07bddde4eb928f11de7c7cadf98b8', id: subHdrId, class: "alert-sub-title" }, subHeader)), subHeader && header && (hAsync("h3", { key: '4774fa13700dd23aec7930492acae80de3bdf5d1', id: subHdrId, class: "alert-sub-title" }, subHeader))), this.renderAlertMessage(msgId), this.renderAlertInputs(), this.renderAlertButtons()), hAsync("div", { key: '5c728b7457e231f64294bbec821bdb547c6437dd', tabindex: "0", "aria-hidden": "true" })));
11444
11489
  }
11445
11490
  get el() { return getElement(this); }
11446
11491
  static get watchers() { return {
@@ -22328,17 +22373,19 @@ class ItemSliding {
22328
22373
  }
22329
22374
  }
22330
22375
  async updateOptions() {
22331
- const options = Array.from(this.el.querySelectorAll('ion-item-options'));
22332
- /**
22333
- * Frameworks that assign element props after inserting the element haven't set
22334
- * `side` while `connectedCallback` runs, so reading it any earlier reports every
22335
- * option as `end`.
22336
- */
22337
- await Promise.all(options.map((option) => new Promise((resolve) => componentOnReady(option, resolve))));
22376
+ const options = this.el.querySelectorAll('ion-item-options');
22338
22377
  let sides = 0;
22339
22378
  // Reset left and right options in case they were removed
22340
22379
  this.leftOptions = this.rightOptions = undefined;
22341
- for (const option of options) {
22380
+ for (let i = 0; i < options.length; i++) {
22381
+ const item = options.item(i);
22382
+ /**
22383
+ * We cannot use the componentOnReady helper
22384
+ * util here since we need to wait for all of these items
22385
+ * to be ready before we set `this.sides` and `this.optsDirty`.
22386
+ */
22387
+ // eslint-disable-next-line custom-rules/no-component-on-ready-method
22388
+ const option = item.componentOnReady !== undefined ? await item.componentOnReady() : item;
22342
22389
  const side = isEndSide(option.side ?? option.getAttribute('side')) ? 'end' : 'start';
22343
22390
  if (side === 'start') {
22344
22391
  this.leftOptions = option;
@@ -22537,7 +22584,7 @@ class ItemSliding {
22537
22584
  }
22538
22585
  render() {
22539
22586
  const mode = getIonMode$1(this);
22540
- return (hAsync(Host, { key: '02174ca963753d3a51a4249068f3d436f8acb03d', class: {
22587
+ return (hAsync(Host, { key: '15f6a98f8c888e86c29827cdf55d98ace08699dd', class: {
22541
22588
  [mode]: true,
22542
22589
  'item-sliding-active-slide': this.state !== 2 /* SlidingState.Disabled */,
22543
22590
  'item-sliding-active-options-end': (this.state & 8 /* SlidingState.End */) !== 0,
@@ -22950,6 +22997,10 @@ class Loading {
22950
22997
  connectedCallback() {
22951
22998
  prepareOverlay(this.el);
22952
22999
  this.triggerChanged();
23000
+ // Re-apply the root lock if moved without dismiss() being called
23001
+ if (this.presented) {
23002
+ restoreRootFocusTrapAccessibility(this.el);
23003
+ }
22953
23004
  }
22954
23005
  componentWillLoad() {
22955
23006
  if (this.spinner === undefined) {
@@ -23050,14 +23101,14 @@ class Loading {
23050
23101
  * Otherwise, don't set aria-labelledby.
23051
23102
  */
23052
23103
  const ariaLabelledBy = message !== undefined ? msgId : null;
23053
- return (hAsync(Host, { key: '2d14122ff3081de73631a7fdd4affdd5c73b8618', role: "dialog", "aria-modal": "true", "aria-labelledby": ariaLabelledBy, tabindex: "-1", ...htmlAttributes, style: {
23104
+ return (hAsync(Host, { key: 'b4430bc66aedeca19d5645667cba73c169c4bd76', role: "dialog", "aria-modal": "true", "aria-labelledby": ariaLabelledBy, tabindex: "-1", ...htmlAttributes, style: {
23054
23105
  zIndex: `${40000 + this.overlayIndex}`,
23055
23106
  }, onIonBackdropTap: this.onBackdropTap, class: {
23056
23107
  ...getClassMap(this.cssClass),
23057
23108
  [mode]: true,
23058
23109
  'overlay-hidden': true,
23059
23110
  'loading-translucent': this.translucent,
23060
- } }, hAsync("ion-backdrop", { key: 'b7d5bb0d670a20c159d7f67327bf3b1489449188', visible: this.showBackdrop, tappable: this.backdropDismiss }), hAsync("div", { key: '085ce92bd2004d323ab47eb472b83826e48dc619', tabindex: "0", "aria-hidden": "true" }), hAsync("div", { key: '4ecd5bfc0bbd3da434d32f0f319f867a44c5e1f1', class: "loading-wrapper ion-overlay-wrapper" }, spinner && (hAsync("div", { key: '5a4498e1421e09d01c0ee4312eae5272e95c3127', class: "loading-spinner" }, hAsync("ion-spinner", { key: '1b3bc7d45d775195657ead3535f65e6b79f37e84', name: spinner, "aria-hidden": "true" }))), message !== undefined && this.renderLoadingMessage(msgId)), hAsync("div", { key: 'bc7c5467b9f1c6ab957f79934e97acc713bdec37', tabindex: "0", "aria-hidden": "true" })));
23111
+ } }, hAsync("ion-backdrop", { key: 'dec0df942ae778c99ebd4dbf08d6c2a0a992639d', visible: this.showBackdrop, tappable: this.backdropDismiss }), hAsync("div", { key: '71b2d5fc259666225047fc901648ada1efcd5d4b', tabindex: "0", "aria-hidden": "true" }), hAsync("div", { key: '1d83dc3b57ee70c9e8c0f006c6fa576bd96ecded', class: "loading-wrapper ion-overlay-wrapper" }, spinner && (hAsync("div", { key: 'd1cd127e044b8831e396b53122322c1db7e89904', class: "loading-spinner" }, hAsync("ion-spinner", { key: '38c2580cf5659da612872f01801a5fbdc2c023ba', name: spinner, "aria-hidden": "true" }))), message !== undefined && this.renderLoadingMessage(msgId)), hAsync("div", { key: '90e5e32ffe0df2c691f364149f43374e676bfaa3', tabindex: "0", "aria-hidden": "true" })));
23061
23112
  }
23062
23113
  get el() { return getElement(this); }
23063
23114
  static get watchers() { return {
@@ -26616,6 +26667,9 @@ class Modal {
26616
26667
  this.inline = false;
26617
26668
  // Whether or not modal is being dismissed via gesture
26618
26669
  this.gestureAnimationDismissing = false;
26670
+ // True from the first safe-area write in `present()` until the enter
26671
+ // animation settles. A position-based read in that window is not the rest position.
26672
+ this.isPresenting = false;
26619
26673
  this.presented = false;
26620
26674
  /** @internal */
26621
26675
  this.hasController = false;
@@ -26852,6 +26906,17 @@ class Modal {
26852
26906
  const { el } = this;
26853
26907
  prepareOverlay(el);
26854
26908
  this.triggerChanged();
26909
+ // A disconnect tears down state this presentation still needs and cannot
26910
+ // tell a re-insert from a removal, so put it back.
26911
+ if (this.presented || this.isPresenting) {
26912
+ this.restoreSafeAreaOverrides();
26913
+ }
26914
+ // A relocation from `willPresent` reaches these before `present()` has
26915
+ // applied the lock, so they apply it instead. Both are idempotent.
26916
+ if (this.presented) {
26917
+ restoreRootFocusTrapAccessibility(el);
26918
+ this.initParentRemovalObserver();
26919
+ }
26855
26920
  }
26856
26921
  disconnectedCallback() {
26857
26922
  this.triggerController.removeClickListener();
@@ -27029,25 +27094,33 @@ class Modal {
27029
27094
  // Recalculate isSheetModal before safe-area setup because framework
27030
27095
  // bindings (e.g., Angular) may not have been applied when componentWillLoad ran.
27031
27096
  this.isSheetModal = this.breakpoints !== undefined && this.initialBreakpoint !== undefined;
27032
- // Set initial safe-area overrides before animation
27033
- this.setInitialSafeAreaOverrides();
27097
+ this.isPresenting = true;
27034
27098
  const hasCardModal = presentingElement !== undefined;
27035
- /**
27036
- * We need to change the status bar at the
27037
- * start of the animation so that it completes
27038
- * by the time the card animation is done.
27039
- */
27040
- if (hasCardModal && getIonMode$1(this) === 'ios') {
27041
- // Cache the original status bar color before the modal is presented
27042
- this.statusBarStyle = await StatusBar.getStyle();
27043
- setCardStatusBarDark();
27099
+ // Wrapped so a throw cannot strand `isPresenting`, which would suppress
27100
+ // the position-based correction for the life of this instance.
27101
+ try {
27102
+ // Set initial safe-area overrides before animation
27103
+ this.setInitialSafeAreaOverrides();
27104
+ /**
27105
+ * We need to change the status bar at the
27106
+ * start of the animation so that it completes
27107
+ * by the time the card animation is done.
27108
+ */
27109
+ if (hasCardModal && getIonMode$1(this) === 'ios') {
27110
+ // Cache the original status bar color before the modal is presented
27111
+ this.statusBarStyle = await StatusBar.getStyle();
27112
+ setCardStatusBarDark();
27113
+ }
27114
+ await present(this, 'modalEnter', iosEnterAnimation$2, mdEnterAnimation$2, {
27115
+ presentingEl: presentingElement,
27116
+ currentBreakpoint: this.initialBreakpoint,
27117
+ backdropBreakpoint: this.backdropBreakpoint,
27118
+ expandToScroll: this.expandToScroll,
27119
+ });
27120
+ }
27121
+ finally {
27122
+ this.isPresenting = false;
27044
27123
  }
27045
- await present(this, 'modalEnter', iosEnterAnimation$2, mdEnterAnimation$2, {
27046
- presentingEl: presentingElement,
27047
- currentBreakpoint: this.initialBreakpoint,
27048
- backdropBreakpoint: this.backdropBreakpoint,
27049
- expandToScroll: this.expandToScroll,
27050
- });
27051
27124
  // Update safe-area based on actual position after animation
27052
27125
  this.updateSafeAreaOverrides();
27053
27126
  // Apply fullscreen safe-area padding if needed
@@ -27549,6 +27622,9 @@ class Modal {
27549
27622
  this.cachedOriginalParent.tagName === 'ION-APP') {
27550
27623
  return;
27551
27624
  }
27625
+ // Both `present()` and a reconnect call this, so drop any existing
27626
+ // observer. Below the guards, so a call that bails cannot leave none.
27627
+ this.cleanupParentRemovalObserver();
27552
27628
  this.parentRemovalObserver = new MutationObserver((mutations) => {
27553
27629
  mutations.forEach((mutation) => {
27554
27630
  if (mutation.type === 'childList' && mutation.removedNodes.length > 0) {
@@ -27627,6 +27703,9 @@ class Modal {
27627
27703
  // Set the internal offset property with the resolved root safe-area-top value
27628
27704
  if (context.isSheetModal) {
27629
27705
  this.updateSheetOffsetTop();
27706
+ // A restore after a DOM move runs this a second time for the same
27707
+ // modal, so drop the previous subscription rather than stacking one.
27708
+ this.unsubscribeRootSafeAreaTop?.();
27630
27709
  this.unsubscribeRootSafeAreaTop = onRootSafeAreaTopChange((safeAreaTop) => this.updateSheetOffsetTop(safeAreaTop));
27631
27710
  }
27632
27711
  }
@@ -27745,6 +27824,31 @@ class Modal {
27745
27824
  const { contentEl } = this.findContentAndFooter();
27746
27825
  this.clearContentSafeAreaPadding(contentEl);
27747
27826
  }
27827
+ /**
27828
+ * Re-applies what `cleanupSafeAreaOverrides()` removed for a modal moved
27829
+ * while presented. Anything needing no measurement goes on synchronously so
27830
+ * the modal is never painted without safe-area. The position-based
27831
+ * correction waits a frame for the layout pass it reads.
27832
+ */
27833
+ restoreSafeAreaOverrides() {
27834
+ this.setInitialSafeAreaOverrides();
27835
+ this.applyFullscreenSafeArea();
27836
+ raf(() => {
27837
+ // A dismiss or another move can land first, and a read before the enter
27838
+ // animation settles is not the rest position. `present()` redoes it.
27839
+ if (!this.presented || !this.el.isConnected || this.isPresenting) {
27840
+ return;
27841
+ }
27842
+ // A hidden subtree carries `display: none`, so there is no box and the
27843
+ // read would write the safe-area for a modal touching no edge. The
27844
+ // prediction applied above holds until the modal is shown again.
27845
+ const { width, height } = this.el.getBoundingClientRect();
27846
+ if (width === 0 && height === 0) {
27847
+ return;
27848
+ }
27849
+ this.updateSafeAreaOverrides();
27850
+ });
27851
+ }
27748
27852
  render() {
27749
27853
  const { handle, isSheetModal, presentingElement, htmlAttributes, handleBehavior, inheritedAttributes, focusTrap, expandToScroll, } = this;
27750
27854
  const showHandle = handle !== false && isSheetModal;
@@ -27752,7 +27856,7 @@ class Modal {
27752
27856
  const isCardModal = presentingElement !== undefined && mode === 'ios';
27753
27857
  const isHandleCycle = handleBehavior === 'cycle';
27754
27858
  const isSheetModalWithHandle = isSheetModal && showHandle;
27755
- return (hAsync(Host, { key: 'a471c293319cb6ee5ffb7ffafec0b8413e4289de', "no-router": true,
27859
+ return (hAsync(Host, { key: '7c9c736052c5a788cf31040b6b2386dd9ea7454b', "no-router": true,
27756
27860
  // Allow the modal to be navigable when the handle is focusable
27757
27861
  tabIndex: isHandleCycle && isSheetModalWithHandle ? 0 : -1, ...htmlAttributes, style: {
27758
27862
  zIndex: `${20000 + this.overlayIndex}`,
@@ -27765,7 +27869,7 @@ class Modal {
27765
27869
  'overlay-hidden': true,
27766
27870
  [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false,
27767
27871
  ...getClassMap(this.cssClass),
27768
- }, onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle, onFocus: this.onModalFocus }, hAsync("ion-backdrop", { key: 'f67934afd4ddad64623856fb641cb6db846df428', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && hAsync("div", { key: 'a23f5cb6cf60c8f717c1dd556bce375829c80a43', class: "modal-shadow" }), hAsync("div", { key: '51eb6cd1070e4b7e49840a78dc7437238c867a01',
27872
+ }, onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle, onFocus: this.onModalFocus }, hAsync("ion-backdrop", { key: '01b5b5765fb3a32393c736065c824bf760728823', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && hAsync("div", { key: '40fa7727a0923f7d7461dd027f1511a6a148d84a', class: "modal-shadow" }), hAsync("div", { key: '9af934b607f60795bd5bff7bee6eacfc9b14fa35',
27769
27873
  /*
27770
27874
  role and aria-modal must be used on the
27771
27875
  same element. They must also be set inside the
@@ -27778,9 +27882,9 @@ class Modal {
27778
27882
  without the tabindex focus() would be a no-op and screen readers
27779
27883
  may not properly announce the dialog and its content when it opens.
27780
27884
  */
27781
- role: "dialog", ...inheritedAttributes, "aria-modal": "true", tabIndex: -1, class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }, showHandle && (hAsync("button", { key: 'f49a144642b5c227c0c2b00b33f4c7e37a2bf088', class: "modal-handle",
27885
+ role: "dialog", ...inheritedAttributes, "aria-modal": "true", tabIndex: -1, class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }, showHandle && (hAsync("button", { key: 'df84a6806413b13efc5b03c862edde83151579a7', class: "modal-handle",
27782
27886
  // Prevents the handle from receiving keyboard focus when it does not cycle
27783
- 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: 'e781c0d5881762c6b61aa432721a38b49580ff64', onSlotchange: this.onSlotChange }))));
27887
+ 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: '072d3929ec6f25481946b184d8ac24219011e783', onSlotchange: this.onSlotChange }))));
27784
27888
  }
27785
27889
  get el() { return getElement(this); }
27786
27890
  static get watchers() { return {
@@ -31216,6 +31320,13 @@ class Popover {
31216
31320
  const { configureTriggerInteraction, el } = this;
31217
31321
  prepareOverlay(el);
31218
31322
  configureTriggerInteraction();
31323
+ // Re-apply the root lock if moved without dismiss() being called
31324
+ if (this.presented) {
31325
+ restoreRootFocusTrapAccessibility(el);
31326
+ // The disconnect tore down the header observer, and `present()` is its
31327
+ // only other caller, so a move mid-layout would lose the recalculation.
31328
+ this.recalculateContentOnHeaderReady();
31329
+ }
31219
31330
  }
31220
31331
  disconnectedCallback() {
31221
31332
  const { destroyTriggerInteraction } = this;
@@ -31393,6 +31504,9 @@ class Popover {
31393
31504
  if (!header || contentElements.length === 0) {
31394
31505
  return;
31395
31506
  }
31507
+ // Both `present()` and a reconnect call this, so drop any existing
31508
+ // observer. Below the guards, so a call that bails cannot leave none.
31509
+ this.headerResizeObserver?.disconnect();
31396
31510
  this.headerResizeObserver = new ResizeObserver(async () => {
31397
31511
  if (header.offsetHeight > 0) {
31398
31512
  this.headerResizeObserver?.disconnect();
@@ -31465,7 +31579,7 @@ class Popover {
31465
31579
  const { onLifecycle, parentPopover, dismissOnSelect, side, arrow, htmlAttributes, focusTrap } = this;
31466
31580
  const desktop = isPlatform('desktop');
31467
31581
  const enableArrow = arrow && !parentPopover;
31468
- return (hAsync(Host, { key: '52ffc7116969ae1b8b927e67f2acbfe5f5434f70', "aria-modal": "true", "no-router": true, tabindex: "-1", ...htmlAttributes, style: {
31582
+ return (hAsync(Host, { key: '5a41565e6129c73112835aab18b7ae213de040f2', "aria-modal": "true", "no-router": true, tabindex: "-1", ...htmlAttributes, style: {
31469
31583
  zIndex: `${20000 + this.overlayIndex}`,
31470
31584
  }, class: {
31471
31585
  ...getClassMap(this.cssClass),
@@ -31476,7 +31590,7 @@ class Popover {
31476
31590
  [`popover-side-${side}`]: true,
31477
31591
  [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false,
31478
31592
  'popover-nested': !!parentPopover,
31479
- }, onIonPopoverDidPresent: onLifecycle, onIonPopoverWillPresent: onLifecycle, onIonPopoverWillDismiss: onLifecycle, onIonPopoverDidDismiss: onLifecycle, onIonBackdropTap: this.onBackdropTap }, !parentPopover && hAsync("ion-backdrop", { key: '79a8e851dbd22119e21ffb2f4709c555251045c8', tappable: this.backdropDismiss, visible: this.showBackdrop, part: "backdrop" }), hAsync("div", { key: 'c46c9f62c3ef3f902e23f27404eaa446a5d8cf88', class: "popover-wrapper ion-overlay-wrapper", onClick: dismissOnSelect ? () => this.dismiss() : undefined }, enableArrow && hAsync("div", { key: '9fdcbbc4ea6c7bde74f646d48eb77296b2c9dd83', class: "popover-arrow", part: "arrow" }), hAsync("div", { key: '138e56bb83462ebb0908edb522b45ecf94b82aeb', class: "popover-content", part: "content" }, hAsync("slot", { key: 'daeefcf002e8d89e91d6e0faf7f63f75b68a2dbe' })))));
31593
+ }, onIonPopoverDidPresent: onLifecycle, onIonPopoverWillPresent: onLifecycle, onIonPopoverWillDismiss: onLifecycle, onIonPopoverDidDismiss: onLifecycle, onIonBackdropTap: this.onBackdropTap }, !parentPopover && hAsync("ion-backdrop", { key: '59e724e4a6ce25eae78ccf1668effd988be7232a', tappable: this.backdropDismiss, visible: this.showBackdrop, part: "backdrop" }), hAsync("div", { key: '88d787ca20ac7cbacc4190bd771645dbe6083ad9', class: "popover-wrapper ion-overlay-wrapper", onClick: dismissOnSelect ? () => this.dismiss() : undefined }, enableArrow && hAsync("div", { key: 'f766e6413cc4545f27a43d5931c033261e3daa2c', class: "popover-arrow", part: "arrow" }), hAsync("div", { key: '675bddff0c071378858bb2d07bec91da68c2652a', class: "popover-content", part: "content" }, hAsync("slot", { key: '1c446b867083016b24b1b3baccd19b9fc08e114a' })))));
31480
31594
  }
31481
31595
  get el() { return getElement(this); }
31482
31596
  static get watchers() { return {
@@ -37271,6 +37385,11 @@ class SegmentButton {
37271
37385
  addEventListener$1(segmentEl, 'ionSelect', this.updateState);
37272
37386
  addEventListener$1(segmentEl, 'ionStyle', this.updateStyle);
37273
37387
  }
37388
+ // Prevent buttons from being disabled when associated with segment content
37389
+ if (this.contentId && this.disabled) {
37390
+ printIonWarning(`[ion-segment-button] - Segment buttons cannot be disabled when associated with an <ion-segment-content>.`);
37391
+ this.disabled = false;
37392
+ }
37274
37393
  }
37275
37394
  disconnectedCallback() {
37276
37395
  const segmentEl = this.segmentEl;
@@ -37287,15 +37406,6 @@ class SegmentButton {
37287
37406
  // Return if there is no contentId defined
37288
37407
  if (!this.contentId)
37289
37408
  return;
37290
- /**
37291
- * Checked here rather than in `connectedCallback` so frameworks that assign element
37292
- * props after inserting the element have set `disabled` by now. A disabled ion-segment
37293
- * pushes that onto its buttons too, which this guard should not undo.
37294
- */
37295
- if (this.disabled && this.segmentEl?.disabled !== true) {
37296
- printIonWarning(`[ion-segment-button] - Segment buttons cannot be disabled when associated with an <ion-segment-content>.`);
37297
- this.disabled = false;
37298
- }
37299
37409
  // Attempt to find the Segment Content by its contentId
37300
37410
  const segmentContent = document.getElementById(this.contentId);
37301
37411
  // If no associated Segment Content exists, log an error and return
@@ -37330,7 +37440,7 @@ class SegmentButton {
37330
37440
  const { checked, type, disabled, hasIcon, hasLabel, layout, segmentEl } = this;
37331
37441
  const mode = getIonMode$1(this);
37332
37442
  const hasSegmentColor = () => segmentEl?.color !== undefined;
37333
- return (hAsync(Host, { key: 'd8acc71d87e26b32f20b2d0f9a6acc9f0dab0dee', class: {
37443
+ return (hAsync(Host, { key: '2b4b7ad8b981d2ee39aba5b9c734de8a5bd045ba', class: {
37334
37444
  [mode]: true,
37335
37445
  'in-toolbar': hostContext('ion-toolbar', this.el),
37336
37446
  'in-toolbar-color': hostContext('ion-toolbar[color]', this.el),
@@ -37346,7 +37456,7 @@ class SegmentButton {
37346
37456
  'ion-activatable': true,
37347
37457
  'ion-activatable-instant': true,
37348
37458
  'ion-focusable': true,
37349
- } }, hAsync("button", { key: 'ce65da07b1a012bce353b3c6c24eecfbd4071d54', "aria-selected": checked ? 'true' : 'false', role: "tab", ref: (el) => (this.nativeEl = el), type: type, class: "button-native", part: "native", disabled: disabled, ...this.inheritedAttributes }, hAsync("span", { key: '6c4b4dcd20e407e5dc31674bea23633d8a09187a', class: "button-inner" }, hAsync("slot", { key: '817145ae77a3c5ada88ab95723d881f1bde96b2a' })), mode === 'md' && hAsync("ion-ripple-effect", { key: '054d7e5e2a13013914fac6bbde8efdb28d9b459e' })), hAsync("div", { key: 'c48074881a302510ad4752eeb9383222cd3a54cb', part: "indicator", class: "segment-button-indicator segment-button-indicator-animated" }, hAsync("div", { key: '7672a6b10ee18ad026b798fbd8207dc3cd5683f9', part: "indicator-background", class: "segment-button-indicator-background" }))));
37459
+ } }, hAsync("button", { key: '9cc58cfbe70844a0f5e1a307002e0d04e044be99', "aria-selected": checked ? 'true' : 'false', role: "tab", ref: (el) => (this.nativeEl = el), type: type, class: "button-native", part: "native", disabled: disabled, ...this.inheritedAttributes }, hAsync("span", { key: '6443551951ce589efdb2d0e1fd1a14e35b82ed19', class: "button-inner" }, hAsync("slot", { key: 'c3548b469ae6e5477d8372cb28bc70dff3a24d18' })), mode === 'md' && hAsync("ion-ripple-effect", { key: 'fb176415ca1702766c4d7a5964ec0bb467bdcb55' })), hAsync("div", { key: 'aa22b4752f8336d0e232a1e0894e87023b284a08', part: "indicator", class: "segment-button-indicator segment-button-indicator-animated" }, hAsync("div", { key: '61e29ea52048fa0583fce6c20c81614a4d0199cb', part: "indicator-background", class: "segment-button-indicator-background" }))));
37350
37460
  }
37351
37461
  get el() { return getElement(this); }
37352
37462
  static get watchers() { return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ionic/core",
3
- "version": "9.0.1-dev.11787248963.10a00c73",
3
+ "version": "9.0.1-dev.11787589191.1e183b55",
4
4
  "description": "Base components for Ionic",
5
5
  "engines": {
6
6
  "node": ">= 16"