@ionic/core 8.5.8-dev.11748374591.17686118 → 8.5.8-dev.11748388365.11ad9dfe

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 (67) hide show
  1. package/components/button.js +23 -5
  2. package/components/ion-datetime.js +27 -51
  3. package/components/ion-input-password-toggle.js +2 -2
  4. package/components/ion-searchbar.js +4 -4
  5. package/components/modal.js +159 -68
  6. package/components/picker-column2.js +3 -3
  7. package/css/core.css +1 -1
  8. package/css/core.css.map +1 -1
  9. package/css/ionic.bundle.css +1 -1
  10. package/css/ionic.bundle.css.map +1 -1
  11. package/dist/cjs/ion-button_2.cjs.entry.js +19 -3
  12. package/dist/cjs/ion-datetime_3.cjs.entry.js +30 -54
  13. package/dist/cjs/ion-input-password-toggle.cjs.entry.js +2 -2
  14. package/dist/cjs/ion-modal.cjs.entry.js +159 -68
  15. package/dist/cjs/ion-searchbar.cjs.entry.js +4 -4
  16. package/dist/cjs/ionic.cjs.js +1 -1
  17. package/dist/cjs/loader.cjs.js +1 -1
  18. package/dist/collection/components/button/button.js +23 -3
  19. package/dist/collection/components/datetime/datetime.js +27 -51
  20. package/dist/collection/components/input-password-toggle/input-password-toggle.js +2 -2
  21. package/dist/collection/components/modal/animations/ios.enter.js +41 -1
  22. package/dist/collection/components/modal/animations/ios.leave.js +24 -2
  23. package/dist/collection/components/modal/animations/md.enter.js +41 -1
  24. package/dist/collection/components/modal/animations/md.leave.js +24 -2
  25. package/dist/collection/components/modal/gestures/sheet.js +29 -62
  26. package/dist/collection/components/picker-legacy-column/picker-column.js +3 -3
  27. package/dist/collection/components/searchbar/searchbar.js +5 -5
  28. package/dist/docs.json +2 -2
  29. package/dist/esm/ion-button_2.entry.js +20 -4
  30. package/dist/esm/ion-datetime_3.entry.js +30 -54
  31. package/dist/esm/ion-input-password-toggle.entry.js +2 -2
  32. package/dist/esm/ion-modal.entry.js +159 -68
  33. package/dist/esm/ion-searchbar.entry.js +4 -4
  34. package/dist/esm/ionic.js +1 -1
  35. package/dist/esm/loader.js +1 -1
  36. package/dist/esm-es5/ion-button_2.entry.js +1 -1
  37. package/dist/esm-es5/ion-datetime_3.entry.js +1 -1
  38. package/dist/esm-es5/ion-input-password-toggle.entry.js +1 -1
  39. package/dist/esm-es5/ion-modal.entry.js +1 -1
  40. package/dist/esm-es5/ion-searchbar.entry.js +1 -1
  41. package/dist/esm-es5/ionic.js +1 -1
  42. package/dist/esm-es5/loader.js +1 -1
  43. package/dist/html.html-data.json +1 -1
  44. package/dist/ionic/ionic.esm.js +1 -1
  45. package/dist/ionic/p-12914457.entry.js +4 -0
  46. package/dist/ionic/{p-50cb2e8b.system.entry.js → p-3cee5d7c.system.entry.js} +2 -2
  47. package/dist/ionic/p-3d2b2787.system.entry.js +4 -0
  48. package/dist/ionic/{p-7611ede3.system.entry.js → p-3ec227cd.system.entry.js} +1 -1
  49. package/dist/ionic/p-4090ce24.entry.js +4 -0
  50. package/dist/ionic/p-8b8b4530.system.entry.js +4 -0
  51. package/dist/ionic/p-94a18d00.entry.js +4 -0
  52. package/dist/ionic/p-cec902a0.system.entry.js +4 -0
  53. package/dist/ionic/{p-891553d8.entry.js → p-e7f732ef.entry.js} +1 -1
  54. package/dist/ionic/p-f725bf9e.system.js +2 -2
  55. package/dist/ionic/{p-a835aca8.entry.js → p-ffa2125f.entry.js} +1 -1
  56. package/dist/types/components/button/button.d.ts +11 -0
  57. package/dist/types/components/searchbar/searchbar.d.ts +1 -1
  58. package/dist/types/components.d.ts +2 -2
  59. package/hydrate/index.js +213 -131
  60. package/hydrate/index.mjs +213 -131
  61. package/package.json +2 -2
  62. package/dist/ionic/p-57957c0f.entry.js +0 -4
  63. package/dist/ionic/p-6b8530f5.system.entry.js +0 -4
  64. package/dist/ionic/p-b5432d15.entry.js +0 -4
  65. package/dist/ionic/p-b7242f55.entry.js +0 -4
  66. package/dist/ionic/p-c1b7d311.system.entry.js +0 -4
  67. package/dist/ionic/p-db06d822.system.entry.js +0 -4
package/hydrate/index.mjs CHANGED
@@ -7986,6 +7986,19 @@ class Button {
7986
7986
  this.formButtonEl.disabled = disabled;
7987
7987
  }
7988
7988
  }
7989
+ /**
7990
+ * This component is used within the `ion-input-password-toggle` component
7991
+ * to toggle the visibility of the password input.
7992
+ * These attributes need to update based on the state of the password input.
7993
+ * Otherwise, the values will be stale.
7994
+ *
7995
+ * @param newValue
7996
+ * @param _oldValue
7997
+ * @param propName
7998
+ */
7999
+ onAriaChanged(newValue, _oldValue, propName) {
8000
+ this.inheritedAttributes = Object.assign(Object.assign({}, this.inheritedAttributes), { [propName]: newValue });
8001
+ }
7989
8002
  /**
7990
8003
  * This is responsible for rendering a hidden native
7991
8004
  * button element inside the associated form. This allows
@@ -8123,7 +8136,7 @@ class Button {
8123
8136
  {
8124
8137
  type !== 'button' && this.renderHiddenButton();
8125
8138
  }
8126
- return (hAsync(Host, { key: 'e213b0bb76b3f90f883b1a0ea463bb86c2df69c3', onClick: this.handleClick, "aria-disabled": disabled ? 'true' : null, class: createColorClasses$1(color, {
8139
+ return (hAsync(Host, { key: 'b105ad09215adb3ca2298acdadf0dc9154bbb9b0', onClick: this.handleClick, "aria-disabled": disabled ? 'true' : null, class: createColorClasses$1(color, {
8127
8140
  [mode]: true,
8128
8141
  [buttonType]: true,
8129
8142
  [`${buttonType}-${expand}`]: expand !== undefined,
@@ -8138,11 +8151,13 @@ class Button {
8138
8151
  'button-disabled': disabled,
8139
8152
  'ion-activatable': true,
8140
8153
  'ion-focusable': true,
8141
- }) }, hAsync(TagType, Object.assign({ key: 'b7c2a46fb994024841219316f4089335fa463d84' }, attrs, { class: "button-native", part: "native", disabled: disabled, onFocus: this.onFocus, onBlur: this.onBlur }, inheritedAttributes), hAsync("span", { key: '3e07a5c9f86836f9fbaefc6c617bdde6eb6f70cd', class: "button-inner" }, hAsync("slot", { key: '41c08ae09aed16faaa57707d229ff75d97f0731c', name: "icon-only", onSlotchange: this.slotChanged }), hAsync("slot", { key: 'ab8b749e4572884cc04970a7594466b4a24c886e', name: "start" }), hAsync("slot", { key: '397f7ff48ea45e82029414be95d29ae86e12c3a9' }), hAsync("slot", { key: '9a5627713002e8be3738d392b616f6e951b70e12', name: "end" })), mode === 'md' && hAsync("ion-ripple-effect", { key: '105566543ceda102474edab7ca8a44c7e71af589', type: this.rippleType }))));
8154
+ }) }, hAsync(TagType, Object.assign({ key: '66b4e7112bcb9e41d5a723fbbadb0a3104f9ee1d' }, attrs, { class: "button-native", part: "native", disabled: disabled, onFocus: this.onFocus, onBlur: this.onBlur }, inheritedAttributes), hAsync("span", { key: '1439fc3da280221028dcf7ce8ec9dab273c4d4bb', class: "button-inner" }, hAsync("slot", { key: 'd5269ae1afc87ec7b99746032f59cbae93720a9f', name: "icon-only", onSlotchange: this.slotChanged }), hAsync("slot", { key: '461c83e97aa246aa86d83e14f1e15a288d35041e', name: "start" }), hAsync("slot", { key: '807170d47101f9f6a333dd4ff489c89284f306fe' }), hAsync("slot", { key: 'e67f116dd0349a0d27893e4f3ff0ccef1d402f80', name: "end" })), mode === 'md' && hAsync("ion-ripple-effect", { key: '273f0bd9645a36c1bfd18a5c2ab4f81e22b7b989', type: this.rippleType }))));
8142
8155
  }
8143
8156
  get el() { return getElement(this); }
8144
8157
  static get watchers() { return {
8145
- "disabled": ["disabledChanged"]
8158
+ "disabled": ["disabledChanged"],
8159
+ "aria-checked": ["onAriaChanged"],
8160
+ "aria-label": ["onAriaChanged"]
8146
8161
  }; }
8147
8162
  static get style() { return {
8148
8163
  ios: IonButtonIosStyle0,
@@ -11633,19 +11648,18 @@ class Datetime {
11633
11648
  warnIfValueOutOfBounds(valueToProcess, minParts, maxParts);
11634
11649
  }
11635
11650
  /**
11636
- * If there are multiple values, pick an arbitrary one to clamp to. This way,
11637
- * if the values are across months, we always show at least one of them. Note
11638
- * that the values don't necessarily have to be in order.
11651
+ * If there are multiple values, clamp to the last one.
11652
+ * This is because the last value is the one that the user
11653
+ * has most recently interacted with.
11639
11654
  */
11640
- const singleValue = Array.isArray(valueToProcess) ? valueToProcess[0] : valueToProcess;
11655
+ const singleValue = Array.isArray(valueToProcess) ? valueToProcess[valueToProcess.length - 1] : valueToProcess;
11641
11656
  const targetValue = clampDate(singleValue, minParts, maxParts);
11642
11657
  const { month, day, year, hour, minute } = targetValue;
11643
11658
  const ampm = parseAmPm(hour);
11644
11659
  /**
11645
- * Since `activeParts` indicates a value that
11646
- * been explicitly selected either by the
11647
- * user or the app, only update `activeParts`
11648
- * if the `value` property is set.
11660
+ * Since `activeParts` indicates a value that been explicitly selected
11661
+ * either by the user or the app, only update `activeParts` if the
11662
+ * `value` property is set.
11649
11663
  */
11650
11664
  if (hasValue) {
11651
11665
  if (Array.isArray(valueToProcess)) {
@@ -11670,51 +11684,28 @@ class Datetime {
11670
11684
  */
11671
11685
  this.activeParts = [];
11672
11686
  }
11673
- /**
11674
- * Only animate if:
11675
- * 1. We're using grid style (wheel style pickers should just jump to new value)
11676
- * 2. The month and/or year actually changed, and both are defined (otherwise there's nothing to animate to)
11677
- * 3. The calendar body is visible (prevents animation when in collapsed datetime-button, for example)
11678
- * 4. The month/year picker is not open (since you wouldn't see the animation anyway)
11679
- */
11680
11687
  const didChangeMonth = (month !== undefined && month !== workingParts.month) || (year !== undefined && year !== workingParts.year);
11681
11688
  const bodyIsVisible = el.classList.contains('datetime-ready');
11682
11689
  const { isGridStyle, showMonthAndYear } = this;
11683
- let areAllSelectedDatesInSameMonth = true;
11684
- if (Array.isArray(valueToProcess)) {
11685
- const firstMonth = valueToProcess[0].month;
11686
- for (const date of valueToProcess) {
11687
- if (date.month !== firstMonth) {
11688
- areAllSelectedDatesInSameMonth = false;
11689
- break;
11690
- }
11691
- }
11690
+ if (isGridStyle && didChangeMonth && bodyIsVisible && !showMonthAndYear) {
11691
+ /**
11692
+ * Only animate if:
11693
+ * 1. We're using grid style (wheel style pickers should just jump to new value)
11694
+ * 2. The month and/or year actually changed, and both are defined (otherwise there's nothing to animate to)
11695
+ * 3. The calendar body is visible (prevents animation when in collapsed datetime-button, for example)
11696
+ * 4. The month/year picker is not open (since you wouldn't see the animation anyway)
11697
+ */
11698
+ this.animateToDate(targetValue);
11692
11699
  }
11693
- /**
11694
- * If there is more than one date selected
11695
- * and the dates aren't all in the same month,
11696
- * then we should neither animate to the date
11697
- * nor update the working parts because we do
11698
- * not know which date the user wants to view.
11699
- */
11700
- if (areAllSelectedDatesInSameMonth) {
11701
- if (isGridStyle && didChangeMonth && bodyIsVisible && !showMonthAndYear) {
11702
- this.animateToDate(targetValue);
11703
- }
11704
- else {
11705
- /**
11706
- * We only need to do this if we didn't just animate to a new month,
11707
- * since that calls prevMonth/nextMonth which calls setWorkingParts for us.
11708
- */
11709
- this.setWorkingParts({
11710
- month,
11711
- day,
11712
- year,
11713
- hour,
11714
- minute,
11715
- ampm,
11716
- });
11717
- }
11700
+ else {
11701
+ this.setWorkingParts({
11702
+ month,
11703
+ day,
11704
+ year,
11705
+ hour,
11706
+ minute,
11707
+ ampm,
11708
+ });
11718
11709
  }
11719
11710
  };
11720
11711
  this.animateToDate = async (targetValue) => {
@@ -12709,7 +12700,7 @@ class Datetime {
12709
12700
  const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
12710
12701
  const hasWheelVariant = hasDatePresentation && preferWheel;
12711
12702
  renderHiddenInput(true, el, name, formatValue(value), disabled);
12712
- return (hAsync(Host, { key: 'c3dfea8f46fcbcef38eb9e8a69b1b46a4e4b82fd', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, createColorClasses$1(color, {
12703
+ return (hAsync(Host, { key: '20e64fb4cfe3fbd74b24038c89e00651d78b500c', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, createColorClasses$1(color, {
12713
12704
  [mode]: true,
12714
12705
  ['datetime-readonly']: readonly,
12715
12706
  ['datetime-disabled']: disabled,
@@ -12719,7 +12710,7 @@ class Datetime {
12719
12710
  [`datetime-size-${size}`]: true,
12720
12711
  [`datetime-prefer-wheel`]: hasWheelVariant,
12721
12712
  [`datetime-grid`]: isGridStyle,
12722
- })) }, hAsync("div", { key: '75c91243cf6a51f44b83d7cf7d8c0c96bfd3c83f', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
12713
+ })) }, hAsync("div", { key: '488fe7bf6b9052e208d65206a580d5d65b945a62', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
12723
12714
  }
12724
12715
  get el() { return getElement(this); }
12725
12716
  static get watchers() { return {
@@ -15693,14 +15684,14 @@ class InputPasswordToggle {
15693
15684
  const isPasswordVisible = type === 'text';
15694
15685
  return (hAsync(Host, { key: '1a28e078c83e74c72d8bb8189ece93ec2e3fa3d0', class: createColorClasses$1(color, {
15695
15686
  [mode]: true,
15696
- }) }, hAsync("ion-button", { key: '039d1bab764093bb6fe4a34299b0872abda087fd', mode: mode, color: color, fill: "clear", shape: "round", "aria-checked": isPasswordVisible ? 'true' : 'false', "aria-label": "show password", role: "switch", type: "button", onPointerDown: (ev) => {
15687
+ }) }, hAsync("ion-button", { key: '61591d11d97f3065240e51d8887f831339fd36cf', mode: mode, color: color, fill: "clear", shape: "round", "aria-checked": isPasswordVisible ? 'true' : 'false', "aria-label": isPasswordVisible ? 'Hide password' : 'Show password', role: "switch", type: "button", onPointerDown: (ev) => {
15697
15688
  /**
15698
15689
  * This prevents mobile browsers from
15699
15690
  * blurring the input when the password toggle
15700
15691
  * button is activated.
15701
15692
  */
15702
15693
  ev.preventDefault();
15703
- }, onClick: this.togglePasswordVisibility }, hAsync("ion-icon", { key: '26477ee97b808c3d79944bf5e33d4e05f1ae0b3f', slot: "icon-only", "aria-hidden": "true", icon: isPasswordVisible ? hidePasswordIcon : showPasswordIcon }))));
15694
+ }, onClick: this.togglePasswordVisibility }, hAsync("ion-icon", { key: '9d98e6675d5e2adea5c0f56ab67e98b6f57521dd', slot: "icon-only", "aria-hidden": "true", icon: isPasswordVisible ? hidePasswordIcon : showPasswordIcon }))));
15704
15695
  }
15705
15696
  get el() { return getElement(this); }
15706
15697
  static get watchers() { return {
@@ -19210,7 +19201,47 @@ const iosEnterAnimation$3 = (baseEl, opts) => {
19210
19201
  .addElement(baseEl)
19211
19202
  .easing('cubic-bezier(0.32,0.72,0,1)')
19212
19203
  .duration(500)
19213
- .addAnimation([wrapperAnimation]);
19204
+ .addAnimation([wrapperAnimation])
19205
+ .beforeAddWrite(() => {
19206
+ if (expandToScroll) {
19207
+ // Scroll can only be done when the modal is fully expanded.
19208
+ return;
19209
+ }
19210
+ /**
19211
+ * There are some browsers that causes flickering when
19212
+ * dragging the content when scroll is enabled at every
19213
+ * breakpoint. This is due to the wrapper element being
19214
+ * transformed off the screen and having a snap animation.
19215
+ *
19216
+ * A workaround is to clone the footer element and append
19217
+ * it outside of the wrapper element. This way, the footer
19218
+ * is still visible and the drag can be done without
19219
+ * flickering. The original footer is hidden until the modal
19220
+ * is dismissed. This maintains the animation of the footer
19221
+ * when the modal is dismissed.
19222
+ *
19223
+ * The workaround needs to be done before the animation starts
19224
+ * so there are no flickering issues.
19225
+ */
19226
+ const ionFooter = baseEl.querySelector('ion-footer');
19227
+ /**
19228
+ * This check is needed to prevent more than one footer
19229
+ * from being appended to the shadow root.
19230
+ * Otherwise, iOS and MD enter animations would append
19231
+ * the footer twice.
19232
+ */
19233
+ const ionFooterAlreadyAppended = baseEl.shadowRoot.querySelector('ion-footer');
19234
+ if (ionFooter && !ionFooterAlreadyAppended) {
19235
+ const footerHeight = ionFooter.clientHeight;
19236
+ const clonedFooter = ionFooter.cloneNode(true);
19237
+ baseEl.shadowRoot.appendChild(clonedFooter);
19238
+ ionFooter.style.setProperty('display', 'none');
19239
+ ionFooter.setAttribute('aria-hidden', 'true');
19240
+ // Padding is added to prevent some content from being hidden.
19241
+ const page = baseEl.querySelector('.ion-page');
19242
+ page.style.setProperty('padding-bottom', `${footerHeight}px`);
19243
+ }
19244
+ });
19214
19245
  if (contentAnimation) {
19215
19246
  baseAnimation.addAnimation(contentAnimation);
19216
19247
  }
@@ -19291,7 +19322,7 @@ const createLeaveAnimation$1 = () => {
19291
19322
  * iOS Modal Leave Animation
19292
19323
  */
19293
19324
  const iosLeaveAnimation$3 = (baseEl, opts, duration = 500) => {
19294
- const { presentingEl, currentBreakpoint } = opts;
19325
+ const { presentingEl, currentBreakpoint, expandToScroll } = opts;
19295
19326
  const root = getElementRoot(baseEl);
19296
19327
  const { wrapperAnimation, backdropAnimation } = currentBreakpoint !== undefined ? createSheetLeaveAnimation(opts) : createLeaveAnimation$1();
19297
19328
  backdropAnimation.addElement(root.querySelector('ion-backdrop'));
@@ -19300,7 +19331,29 @@ const iosLeaveAnimation$3 = (baseEl, opts, duration = 500) => {
19300
19331
  .addElement(baseEl)
19301
19332
  .easing('cubic-bezier(0.32,0.72,0,1)')
19302
19333
  .duration(duration)
19303
- .addAnimation(wrapperAnimation);
19334
+ .addAnimation(wrapperAnimation)
19335
+ .beforeAddWrite(() => {
19336
+ if (expandToScroll) {
19337
+ // Scroll can only be done when the modal is fully expanded.
19338
+ return;
19339
+ }
19340
+ /**
19341
+ * If expandToScroll is disabled, we need to swap
19342
+ * the visibility to the original, so the footer
19343
+ * dismisses with the modal and doesn't stay
19344
+ * until the modal is removed from the DOM.
19345
+ */
19346
+ const ionFooter = baseEl.querySelector('ion-footer');
19347
+ if (ionFooter) {
19348
+ const clonedFooter = baseEl.shadowRoot.querySelector('ion-footer');
19349
+ ionFooter.style.removeProperty('display');
19350
+ ionFooter.removeAttribute('aria-hidden');
19351
+ clonedFooter.style.setProperty('display', 'none');
19352
+ clonedFooter.setAttribute('aria-hidden', 'true');
19353
+ const page = baseEl.querySelector('.ion-page');
19354
+ page.style.removeProperty('padding-bottom');
19355
+ }
19356
+ });
19304
19357
  if (presentingEl) {
19305
19358
  const isMobile = window.innerWidth < 768;
19306
19359
  const hasCardModal = presentingEl.tagName === 'ION-MODAL' && presentingEl.presentingElement !== undefined;
@@ -19396,7 +19449,47 @@ const mdEnterAnimation$2 = (baseEl, opts) => {
19396
19449
  .addElement(baseEl)
19397
19450
  .easing('cubic-bezier(0.36,0.66,0.04,1)')
19398
19451
  .duration(280)
19399
- .addAnimation([backdropAnimation, wrapperAnimation]);
19452
+ .addAnimation([backdropAnimation, wrapperAnimation])
19453
+ .beforeAddWrite(() => {
19454
+ if (expandToScroll) {
19455
+ // Scroll can only be done when the modal is fully expanded.
19456
+ return;
19457
+ }
19458
+ /**
19459
+ * There are some browsers that causes flickering when
19460
+ * dragging the content when scroll is enabled at every
19461
+ * breakpoint. This is due to the wrapper element being
19462
+ * transformed off the screen and having a snap animation.
19463
+ *
19464
+ * A workaround is to clone the footer element and append
19465
+ * it outside of the wrapper element. This way, the footer
19466
+ * is still visible and the drag can be done without
19467
+ * flickering. The original footer is hidden until the modal
19468
+ * is dismissed. This maintains the animation of the footer
19469
+ * when the modal is dismissed.
19470
+ *
19471
+ * The workaround needs to be done before the animation starts
19472
+ * so there are no flickering issues.
19473
+ */
19474
+ const ionFooter = baseEl.querySelector('ion-footer');
19475
+ /**
19476
+ * This check is needed to prevent more than one footer
19477
+ * from being appended to the shadow root.
19478
+ * Otherwise, iOS and MD enter animations would append
19479
+ * the footer twice.
19480
+ */
19481
+ const ionFooterAlreadyAppended = baseEl.shadowRoot.querySelector('ion-footer');
19482
+ if (ionFooter && !ionFooterAlreadyAppended) {
19483
+ const footerHeight = ionFooter.clientHeight;
19484
+ const clonedFooter = ionFooter.cloneNode(true);
19485
+ baseEl.shadowRoot.appendChild(clonedFooter);
19486
+ ionFooter.style.setProperty('display', 'none');
19487
+ ionFooter.setAttribute('aria-hidden', 'true');
19488
+ // Padding is added to prevent some content from being hidden.
19489
+ const page = baseEl.querySelector('.ion-page');
19490
+ page.style.setProperty('padding-bottom', `${footerHeight}px`);
19491
+ }
19492
+ });
19400
19493
  if (contentAnimation) {
19401
19494
  baseAnimation.addAnimation(contentAnimation);
19402
19495
  }
@@ -19415,7 +19508,7 @@ const createLeaveAnimation = () => {
19415
19508
  * Md Modal Leave Animation
19416
19509
  */
19417
19510
  const mdLeaveAnimation$2 = (baseEl, opts) => {
19418
- const { currentBreakpoint } = opts;
19511
+ const { currentBreakpoint, expandToScroll } = opts;
19419
19512
  const root = getElementRoot(baseEl);
19420
19513
  const { wrapperAnimation, backdropAnimation } = currentBreakpoint !== undefined ? createSheetLeaveAnimation(opts) : createLeaveAnimation();
19421
19514
  backdropAnimation.addElement(root.querySelector('ion-backdrop'));
@@ -19423,7 +19516,29 @@ const mdLeaveAnimation$2 = (baseEl, opts) => {
19423
19516
  const baseAnimation = createAnimation()
19424
19517
  .easing('cubic-bezier(0.47,0,0.745,0.715)')
19425
19518
  .duration(200)
19426
- .addAnimation([backdropAnimation, wrapperAnimation]);
19519
+ .addAnimation([backdropAnimation, wrapperAnimation])
19520
+ .beforeAddWrite(() => {
19521
+ if (expandToScroll) {
19522
+ // Scroll can only be done when the modal is fully expanded.
19523
+ return;
19524
+ }
19525
+ /**
19526
+ * If expandToScroll is disabled, we need to swap
19527
+ * the visibility to the original, so the footer
19528
+ * dismisses with the modal and doesn't stay
19529
+ * until the modal is removed from the DOM.
19530
+ */
19531
+ const ionFooter = baseEl.querySelector('ion-footer');
19532
+ if (ionFooter) {
19533
+ const clonedFooter = baseEl.shadowRoot.querySelector('ion-footer');
19534
+ ionFooter.style.removeProperty('display');
19535
+ ionFooter.removeAttribute('aria-hidden');
19536
+ clonedFooter.style.setProperty('display', 'none');
19537
+ clonedFooter.setAttribute('aria-hidden', 'true');
19538
+ const page = baseEl.querySelector('.ion-page');
19539
+ page.style.removeProperty('padding-bottom');
19540
+ }
19541
+ });
19427
19542
  return baseAnimation;
19428
19543
  };
19429
19544
 
@@ -19455,9 +19570,6 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
19455
19570
  let offset = 0;
19456
19571
  let canDismissBlocksGesture = false;
19457
19572
  let cachedScrollEl = null;
19458
- let cachedFooterEl = null;
19459
- let cachedFooterYPosition = null;
19460
- let currentFooterState = null;
19461
19573
  const canDismissMaxStep = 0.95;
19462
19574
  const maxBreakpoint = breakpoints[breakpoints.length - 1];
19463
19575
  const minBreakpoint = breakpoints[0];
@@ -19487,45 +19599,29 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
19487
19599
  baseEl.classList.add(FOCUS_TRAP_DISABLE_CLASS);
19488
19600
  };
19489
19601
  /**
19490
- * Toggles the footer to an absolute position while moving to prevent
19491
- * it from shaking while the sheet is being dragged.
19492
- * @param footer Whether the footer is in a moving or stationary position.
19602
+ * Toggles the visible modal footer when `expandToScroll` is disabled.
19603
+ * @param footer The footer to show.
19493
19604
  */
19494
- const swapFooterPosition = (newPosition) => {
19495
- if (!cachedFooterEl) {
19496
- cachedFooterEl = baseEl.querySelector('ion-footer');
19497
- if (!cachedFooterEl) {
19498
- return;
19499
- }
19605
+ const swapFooterVisibility = (footer) => {
19606
+ const originalFooter = baseEl.querySelector('ion-footer');
19607
+ if (!originalFooter) {
19608
+ return;
19500
19609
  }
19610
+ const clonedFooter = wrapperEl.nextElementSibling;
19611
+ const footerToHide = footer === 'original' ? clonedFooter : originalFooter;
19612
+ const footerToShow = footer === 'original' ? originalFooter : clonedFooter;
19613
+ footerToShow.style.removeProperty('display');
19614
+ footerToShow.removeAttribute('aria-hidden');
19501
19615
  const page = baseEl.querySelector('.ion-page');
19502
- currentFooterState = newPosition;
19503
- if (newPosition === 'stationary') {
19504
- // Reset positioning styles to allow normal document flow
19505
- cachedFooterEl.classList.remove('modal-footer-moving');
19506
- cachedFooterEl.style.removeProperty('position');
19507
- cachedFooterEl.style.removeProperty('bottom');
19508
- page === null || page === void 0 ? void 0 : page.style.removeProperty('padding-bottom');
19509
- // Move to page
19510
- page === null || page === void 0 ? void 0 : page.appendChild(cachedFooterEl);
19616
+ if (footer === 'original') {
19617
+ page.style.removeProperty('padding-bottom');
19511
19618
  }
19512
19619
  else {
19513
- // Add padding to the parent element to prevent content from being hidden
19514
- // when the footer is positioned absolutely. This has to be done before we
19515
- // make the footer absolutely positioned or we may accidentally cause the
19516
- // sheet to scroll.
19517
- const footerHeight = cachedFooterEl.clientHeight;
19518
- page === null || page === void 0 ? void 0 : page.style.setProperty('padding-bottom', `${footerHeight}px`);
19519
- // Apply positioning styles to keep footer at bottom
19520
- cachedFooterEl.classList.add('modal-footer-moving');
19521
- cachedFooterEl.style.setProperty('position', 'absolute');
19522
- cachedFooterEl.style.setProperty('bottom', '0');
19523
- // Also cache the footer Y position, which we use to determine if the
19524
- // sheet has been moved below the footer. When that happens, we need to swap
19525
- // the position back so it will collapse correctly.
19526
- cachedFooterYPosition = cachedFooterEl.getBoundingClientRect().top + window.scrollY;
19527
- document.body.appendChild(cachedFooterEl);
19620
+ const pagePadding = footerToShow.clientHeight;
19621
+ page.style.setProperty('padding-bottom', `${pagePadding}px`);
19528
19622
  }
19623
+ footerToHide.style.setProperty('display', 'none');
19624
+ footerToHide.setAttribute('aria-hidden', 'true');
19529
19625
  };
19530
19626
  /**
19531
19627
  * After the entering animation completes,
@@ -19619,11 +19715,12 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
19619
19715
  }
19620
19716
  /**
19621
19717
  * If expandToScroll is disabled, we need to swap
19622
- * the footer position to moving so that it doesn't shake
19623
- * while the sheet is being dragged.
19718
+ * the footer visibility to the original, so if the modal
19719
+ * is dismissed, the footer dismisses with the modal
19720
+ * and doesn't stay on the screen after the modal is gone.
19624
19721
  */
19625
19722
  if (!expandToScroll) {
19626
- swapFooterPosition('moving');
19723
+ swapFooterVisibility('original');
19627
19724
  }
19628
19725
  /**
19629
19726
  * If we are pulling down, then it is possible we are pulling on the content.
@@ -19642,21 +19739,6 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
19642
19739
  animation.progressStart(true, 1 - currentBreakpoint);
19643
19740
  };
19644
19741
  const onMove = (detail) => {
19645
- /**
19646
- * If `expandToScroll` is disabled, we need to see if we're currently below
19647
- * the footer element and the footer is in a stationary position. If so,
19648
- * we need to make the stationary the original position so that the footer
19649
- * collapses with the sheet.
19650
- */
19651
- if (!expandToScroll && cachedFooterYPosition !== null && currentFooterState !== null) {
19652
- // Check if we need to swap the footer position
19653
- if (detail.currentY >= cachedFooterYPosition && currentFooterState === 'moving') {
19654
- swapFooterPosition('stationary');
19655
- }
19656
- else if (detail.currentY < cachedFooterYPosition && currentFooterState === 'stationary') {
19657
- swapFooterPosition('moving');
19658
- }
19659
- }
19660
19742
  /**
19661
19743
  * If `expandToScroll` is disabled, and an upwards swipe gesture is done within
19662
19744
  * the scrollable content, we should not allow the swipe gesture to continue.
@@ -19790,6 +19872,14 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
19790
19872
  * snapping animation completes.
19791
19873
  */
19792
19874
  gesture.enable(false);
19875
+ /**
19876
+ * If expandToScroll is disabled, we need to swap
19877
+ * the footer visibility to the cloned one so the footer
19878
+ * doesn't flicker when the sheet's height is animated.
19879
+ */
19880
+ if (!expandToScroll && shouldRemainOpen) {
19881
+ swapFooterVisibility('cloned');
19882
+ }
19793
19883
  if (shouldPreventDismiss) {
19794
19884
  handleCanDismiss(baseEl, animation);
19795
19885
  }
@@ -19810,14 +19900,6 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
19810
19900
  animation
19811
19901
  .onFinish(() => {
19812
19902
  if (shouldRemainOpen) {
19813
- /**
19814
- * If expandToScroll is disabled, we need to swap
19815
- * the footer position to stationary so that it
19816
- * will act as it would by default
19817
- */
19818
- if (!expandToScroll) {
19819
- swapFooterPosition('stationary');
19820
- }
19821
19903
  /**
19822
19904
  * Once the snapping animation completes,
19823
19905
  * we need to reset the animation to go
@@ -23234,7 +23316,7 @@ class PickerColumnCmp {
23234
23316
  const colEl = this.optsEl;
23235
23317
  if (colEl) {
23236
23318
  // DOM READ
23237
- // We perfom a DOM read over a rendered item, this needs to happen after the first render or after the the column has changed
23319
+ // We perfom a DOM read over a rendered item, this needs to happen after the first render or after the column has changed
23238
23320
  this.optHeight = colEl.firstElementChild ? colEl.firstElementChild.clientHeight : 0;
23239
23321
  }
23240
23322
  this.refresh(forceRefresh, animated);
@@ -23242,9 +23324,9 @@ class PickerColumnCmp {
23242
23324
  render() {
23243
23325
  const col = this.col;
23244
23326
  const mode = getIonMode$1(this);
23245
- return (hAsync(Host, { key: '88a3c9397c9ac92dd814074c8ae6ecf8e3420a2c', class: Object.assign({ [mode]: true, 'picker-col': true, 'picker-opts-left': this.col.align === 'left', 'picker-opts-right': this.col.align === 'right' }, getClassMap(col.cssClass)), style: {
23327
+ return (hAsync(Host, { key: '10ef653cbae8e1ed92a23fa17f3396082e35951f', class: Object.assign({ [mode]: true, 'picker-col': true, 'picker-opts-left': this.col.align === 'left', 'picker-opts-right': this.col.align === 'right' }, getClassMap(col.cssClass)), style: {
23246
23328
  'max-width': this.col.columnWidth,
23247
- } }, col.prefix && (hAsync("div", { key: '4491a705d15337e6f45f3cf6fd21af5242474729', class: "picker-prefix", style: { width: col.prefixWidth } }, col.prefix)), hAsync("div", { key: 'b0dd4b7a7a4c1edc4b73e7fb134ac85264072365', class: "picker-opts", style: { maxWidth: col.optionsWidth }, ref: (el) => (this.optsEl = el) }, col.options.map((o, index) => (hAsync("button", { "aria-label": o.ariaLabel, class: { 'picker-opt': true, 'picker-opt-disabled': !!o.disabled }, "opt-index": index }, o.text)))), col.suffix && (hAsync("div", { key: 'c16419ce6481d60fc3ba6b8d102a4edf0ede02aa', class: "picker-suffix", style: { width: col.suffixWidth } }, col.suffix))));
23329
+ } }, col.prefix && (hAsync("div", { key: '253066708012034206b1d3d466ea48d0a3be3323', class: "picker-prefix", style: { width: col.prefixWidth } }, col.prefix)), hAsync("div", { key: '15fa07307d4d2b4994504a5bf2de8db05b51cd2c', class: "picker-opts", style: { maxWidth: col.optionsWidth }, ref: (el) => (this.optsEl = el) }, col.options.map((o, index) => (hAsync("button", { "aria-label": o.ariaLabel, class: { 'picker-opt': true, 'picker-opt-disabled': !!o.disabled }, "opt-index": index }, o.text)))), col.suffix && (hAsync("div", { key: '4db779830b1e6aa6b324e5a72541d4f610ac1ff5', class: "picker-suffix", style: { width: col.suffixWidth } }, col.suffix))));
23248
23330
  }
23249
23331
  get el() { return getElement(this); }
23250
23332
  static get watchers() { return {
@@ -28956,8 +29038,8 @@ class Searchbar {
28956
29038
  const clearIcon = this.clearIcon || (mode === 'ios' ? closeCircle : closeSharp);
28957
29039
  const searchIcon = this.searchIcon || (mode === 'ios' ? searchOutline : searchSharp);
28958
29040
  const shouldShowCancelButton = this.shouldShowCancelButton();
28959
- const cancelButton = this.showCancelButton !== 'never' && (hAsync("button", { key: '989f3e84c472ada6e66dd9b249d0d268bf17ce26', "aria-label": cancelButtonText, "aria-hidden": shouldShowCancelButton ? undefined : 'true', type: "button", tabIndex: mode === 'ios' && !shouldShowCancelButton ? -1 : undefined, onMouseDown: this.onCancelSearchbar, onTouchStart: this.onCancelSearchbar, class: "searchbar-cancel-button" }, hAsync("div", { key: '7d335d4fde33822dc79d26b748ba2e98db7494bb', "aria-hidden": "true" }, mode === 'md' ? (hAsync("ion-icon", { "aria-hidden": "true", mode: mode, icon: this.cancelButtonIcon, lazy: false })) : (cancelButtonText))));
28960
- return (hAsync(Host, { key: 'd1a1972725e949fb102c91487aaa7b9d10c2d718', role: "search", "aria-disabled": this.disabled ? 'true' : null, class: createColorClasses$1(this.color, {
29041
+ const cancelButton = this.showCancelButton !== 'never' && (hAsync("button", { key: '4a4bddfaf44acb9ea71d37d11c3fc11450134a5c', "aria-label": cancelButtonText, "aria-hidden": shouldShowCancelButton ? undefined : 'true', type: "button", tabIndex: mode === 'ios' && !shouldShowCancelButton ? -1 : undefined, onMouseDown: this.onCancelSearchbar, onTouchStart: this.onCancelSearchbar, class: "searchbar-cancel-button" }, hAsync("div", { key: '24424547e34a80422f617f5597965724a3ef65f0', "aria-hidden": "true" }, mode === 'md' ? (hAsync("ion-icon", { "aria-hidden": "true", mode: mode, icon: this.cancelButtonIcon, lazy: false })) : (cancelButtonText))));
29042
+ return (hAsync(Host, { key: '0c0e7334cb2af87081a278e5a3f6be3dc646a073', role: "search", "aria-disabled": this.disabled ? 'true' : null, class: createColorClasses$1(this.color, {
28961
29043
  [mode]: true,
28962
29044
  'searchbar-animated': animated,
28963
29045
  'searchbar-disabled': this.disabled,
@@ -28967,14 +29049,14 @@ class Searchbar {
28967
29049
  'searchbar-has-focus': this.focused,
28968
29050
  'searchbar-should-show-clear': this.shouldShowClearButton(),
28969
29051
  'searchbar-should-show-cancel': this.shouldShowCancelButton(),
28970
- }) }, hAsync("div", { key: 'add53640b2994cb6b2bf02792dafe51aba6b1684', class: "searchbar-input-container" }, hAsync("input", Object.assign({ key: '160cc36459a4a652e7f41ccd14dcdc782278779e', "aria-label": "search text", disabled: this.disabled, ref: (el) => (this.nativeInput = el), class: "searchbar-input", inputMode: this.inputmode, enterKeyHint: this.enterkeyhint, name: this.name, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, minLength: this.minlength, maxLength: this.maxlength, placeholder: this.placeholder, type: this.type, value: this.getValue(), autoCapitalize: autocapitalize === 'default' ? undefined : autocapitalize, autoComplete: this.autocomplete, autoCorrect: this.autocorrect, spellcheck: this.spellcheck }, this.inheritedAttributes)), mode === 'md' && cancelButton, hAsync("ion-icon", { key: '8825fd13af0d2dea451ccc0e00ae7b5021dc01c4', "aria-hidden": "true", mode: mode, icon: searchIcon, lazy: false, class: "searchbar-search-icon" }), hAsync("button", { key: '8a7b56da278b9ca5c4f5a4ee9c01924fd5ae29d8', "aria-label": "reset", type: "button", "no-blur": true, class: "searchbar-clear-button", onPointerDown: (ev) => {
29052
+ }) }, hAsync("div", { key: '859da78b062b9059701eba166be3bc5417f7395b', class: "searchbar-input-container" }, hAsync("input", Object.assign({ key: '840fd06a1e4b5a8d7f6d7439d02aef9fcb9720b6', "aria-label": "search text", disabled: this.disabled, ref: (el) => (this.nativeInput = el), class: "searchbar-input", inputMode: this.inputmode, enterKeyHint: this.enterkeyhint, name: this.name, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, minLength: this.minlength, maxLength: this.maxlength, placeholder: this.placeholder, type: this.type, value: this.getValue(), autoCapitalize: autocapitalize === 'default' ? undefined : autocapitalize, autoComplete: this.autocomplete, autoCorrect: this.autocorrect, spellcheck: this.spellcheck }, this.inheritedAttributes)), mode === 'md' && cancelButton, hAsync("ion-icon", { key: 'a5aaa6a2204d38433cac283dd47b6197499fa585', "aria-hidden": "true", mode: mode, icon: searchIcon, lazy: false, class: "searchbar-search-icon" }), hAsync("button", { key: 'cf62c8969c5c916ac838e122a0ad45b2ae234791', "aria-label": "reset", type: "button", "no-blur": true, class: "searchbar-clear-button", onPointerDown: (ev) => {
28971
29053
  /**
28972
29054
  * This prevents mobile browsers from
28973
29055
  * blurring the input when the clear
28974
29056
  * button is activated.
28975
29057
  */
28976
29058
  ev.preventDefault();
28977
- }, onClick: () => this.onClearInput(true) }, hAsync("ion-icon", { key: '24c55274516ab012d8c25f03525c6cdb9409e52f', "aria-hidden": "true", mode: mode, icon: clearIcon, lazy: false, class: "searchbar-clear-icon" }))), mode === 'ios' && cancelButton));
29059
+ }, onClick: () => this.onClearInput(true) }, hAsync("ion-icon", { key: 'b1a75f0964fc2119479e246dc27bef7cc33bd19f', "aria-hidden": "true", mode: mode, icon: clearIcon, lazy: false, class: "searchbar-clear-icon" }))), mode === 'ios' && cancelButton));
28978
29060
  }
28979
29061
  get el() { return getElement(this); }
28980
29062
  static get watchers() { return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ionic/core",
3
- "version": "8.5.8-dev.11748374591.17686118",
3
+ "version": "8.5.8-dev.11748388365.11ad9dfe",
4
4
  "description": "Base components for Ionic",
5
5
  "keywords": [
6
6
  "ionic",
@@ -41,7 +41,7 @@
41
41
  "@capacitor/haptics": "^7.0.0",
42
42
  "@capacitor/keyboard": "^7.0.0",
43
43
  "@capacitor/status-bar": "^7.0.0",
44
- "@clack/prompts": "^0.10.0",
44
+ "@clack/prompts": "^0.11.0",
45
45
  "@ionic/eslint-config": "^0.3.0",
46
46
  "@ionic/prettier-config": "^2.0.0",
47
47
  "@playwright/test": "^1.52.0",