@ionic/core 8.5.8-dev.11748388365.11ad9dfe → 8.5.8-dev.11748525800.1cdc649b

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 +5 -23
  2. package/components/ion-datetime.js +51 -27
  3. package/components/ion-input-password-toggle.js +2 -2
  4. package/components/ion-searchbar.js +4 -4
  5. package/components/modal.js +97 -159
  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 +3 -19
  12. package/dist/cjs/ion-datetime_3.cjs.entry.js +54 -30
  13. package/dist/cjs/ion-input-password-toggle.cjs.entry.js +2 -2
  14. package/dist/cjs/ion-modal.cjs.entry.js +97 -159
  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 +3 -23
  19. package/dist/collection/components/datetime/datetime.js +51 -27
  20. package/dist/collection/components/input-password-toggle/input-password-toggle.js +2 -2
  21. package/dist/collection/components/modal/animations/ios.enter.js +1 -41
  22. package/dist/collection/components/modal/animations/ios.leave.js +2 -24
  23. package/dist/collection/components/modal/animations/md.enter.js +1 -41
  24. package/dist/collection/components/modal/animations/md.leave.js +2 -24
  25. package/dist/collection/components/modal/gestures/sheet.js +91 -29
  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 +4 -20
  30. package/dist/esm/ion-datetime_3.entry.js +54 -30
  31. package/dist/esm/ion-input-password-toggle.entry.js +2 -2
  32. package/dist/esm/ion-modal.entry.js +97 -159
  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-3cee5d7c.system.entry.js → p-50cb2e8b.system.entry.js} +2 -2
  46. package/dist/ionic/p-57957c0f.entry.js +4 -0
  47. package/dist/ionic/p-5dbf1f31.entry.js +4 -0
  48. package/dist/ionic/p-6b8530f5.system.entry.js +4 -0
  49. package/dist/ionic/{p-3ec227cd.system.entry.js → p-7611ede3.system.entry.js} +1 -1
  50. package/dist/ionic/p-76407fc5.system.entry.js +4 -0
  51. package/dist/ionic/{p-e7f732ef.entry.js → p-891553d8.entry.js} +1 -1
  52. package/dist/ionic/{p-ffa2125f.entry.js → p-a835aca8.entry.js} +1 -1
  53. package/dist/ionic/p-b5432d15.entry.js +4 -0
  54. package/dist/ionic/p-c1b7d311.system.entry.js +4 -0
  55. package/dist/ionic/p-f725bf9e.system.js +2 -2
  56. package/dist/types/components/button/button.d.ts +0 -11
  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 +160 -213
  60. package/hydrate/index.mjs +160 -213
  61. package/package.json +2 -2
  62. package/dist/ionic/p-12914457.entry.js +0 -4
  63. package/dist/ionic/p-3d2b2787.system.entry.js +0 -4
  64. package/dist/ionic/p-4090ce24.entry.js +0 -4
  65. package/dist/ionic/p-8b8b4530.system.entry.js +0 -4
  66. package/dist/ionic/p-94a18d00.entry.js +0 -4
  67. package/dist/ionic/p-cec902a0.system.entry.js +0 -4
package/hydrate/index.mjs CHANGED
@@ -7986,19 +7986,6 @@ 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
- }
8002
7989
  /**
8003
7990
  * This is responsible for rendering a hidden native
8004
7991
  * button element inside the associated form. This allows
@@ -8136,7 +8123,7 @@ class Button {
8136
8123
  {
8137
8124
  type !== 'button' && this.renderHiddenButton();
8138
8125
  }
8139
- return (hAsync(Host, { key: 'b105ad09215adb3ca2298acdadf0dc9154bbb9b0', onClick: this.handleClick, "aria-disabled": disabled ? 'true' : null, class: createColorClasses$1(color, {
8126
+ return (hAsync(Host, { key: 'e213b0bb76b3f90f883b1a0ea463bb86c2df69c3', onClick: this.handleClick, "aria-disabled": disabled ? 'true' : null, class: createColorClasses$1(color, {
8140
8127
  [mode]: true,
8141
8128
  [buttonType]: true,
8142
8129
  [`${buttonType}-${expand}`]: expand !== undefined,
@@ -8151,13 +8138,11 @@ class Button {
8151
8138
  'button-disabled': disabled,
8152
8139
  'ion-activatable': true,
8153
8140
  'ion-focusable': true,
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 }))));
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 }))));
8155
8142
  }
8156
8143
  get el() { return getElement(this); }
8157
8144
  static get watchers() { return {
8158
- "disabled": ["disabledChanged"],
8159
- "aria-checked": ["onAriaChanged"],
8160
- "aria-label": ["onAriaChanged"]
8145
+ "disabled": ["disabledChanged"]
8161
8146
  }; }
8162
8147
  static get style() { return {
8163
8148
  ios: IonButtonIosStyle0,
@@ -11648,18 +11633,19 @@ class Datetime {
11648
11633
  warnIfValueOutOfBounds(valueToProcess, minParts, maxParts);
11649
11634
  }
11650
11635
  /**
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.
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.
11654
11639
  */
11655
- const singleValue = Array.isArray(valueToProcess) ? valueToProcess[valueToProcess.length - 1] : valueToProcess;
11640
+ const singleValue = Array.isArray(valueToProcess) ? valueToProcess[0] : valueToProcess;
11656
11641
  const targetValue = clampDate(singleValue, minParts, maxParts);
11657
11642
  const { month, day, year, hour, minute } = targetValue;
11658
11643
  const ampm = parseAmPm(hour);
11659
11644
  /**
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.
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.
11663
11649
  */
11664
11650
  if (hasValue) {
11665
11651
  if (Array.isArray(valueToProcess)) {
@@ -11684,28 +11670,51 @@ class Datetime {
11684
11670
  */
11685
11671
  this.activeParts = [];
11686
11672
  }
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
+ */
11687
11680
  const didChangeMonth = (month !== undefined && month !== workingParts.month) || (year !== undefined && year !== workingParts.year);
11688
11681
  const bodyIsVisible = el.classList.contains('datetime-ready');
11689
11682
  const { isGridStyle, showMonthAndYear } = this;
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);
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
+ }
11699
11692
  }
11700
- else {
11701
- this.setWorkingParts({
11702
- month,
11703
- day,
11704
- year,
11705
- hour,
11706
- minute,
11707
- ampm,
11708
- });
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
+ }
11709
11718
  }
11710
11719
  };
11711
11720
  this.animateToDate = async (targetValue) => {
@@ -12700,7 +12709,7 @@ class Datetime {
12700
12709
  const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
12701
12710
  const hasWheelVariant = hasDatePresentation && preferWheel;
12702
12711
  renderHiddenInput(true, el, name, formatValue(value), disabled);
12703
- return (hAsync(Host, { key: '20e64fb4cfe3fbd74b24038c89e00651d78b500c', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, createColorClasses$1(color, {
12712
+ return (hAsync(Host, { key: 'c3dfea8f46fcbcef38eb9e8a69b1b46a4e4b82fd', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, createColorClasses$1(color, {
12704
12713
  [mode]: true,
12705
12714
  ['datetime-readonly']: readonly,
12706
12715
  ['datetime-disabled']: disabled,
@@ -12710,7 +12719,7 @@ class Datetime {
12710
12719
  [`datetime-size-${size}`]: true,
12711
12720
  [`datetime-prefer-wheel`]: hasWheelVariant,
12712
12721
  [`datetime-grid`]: isGridStyle,
12713
- })) }, hAsync("div", { key: '488fe7bf6b9052e208d65206a580d5d65b945a62', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
12722
+ })) }, hAsync("div", { key: '75c91243cf6a51f44b83d7cf7d8c0c96bfd3c83f', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
12714
12723
  }
12715
12724
  get el() { return getElement(this); }
12716
12725
  static get watchers() { return {
@@ -15684,14 +15693,14 @@ class InputPasswordToggle {
15684
15693
  const isPasswordVisible = type === 'text';
15685
15694
  return (hAsync(Host, { key: '1a28e078c83e74c72d8bb8189ece93ec2e3fa3d0', class: createColorClasses$1(color, {
15686
15695
  [mode]: true,
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) => {
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) => {
15688
15697
  /**
15689
15698
  * This prevents mobile browsers from
15690
15699
  * blurring the input when the password toggle
15691
15700
  * button is activated.
15692
15701
  */
15693
15702
  ev.preventDefault();
15694
- }, onClick: this.togglePasswordVisibility }, hAsync("ion-icon", { key: '9d98e6675d5e2adea5c0f56ab67e98b6f57521dd', slot: "icon-only", "aria-hidden": "true", icon: isPasswordVisible ? hidePasswordIcon : showPasswordIcon }))));
15703
+ }, onClick: this.togglePasswordVisibility }, hAsync("ion-icon", { key: '26477ee97b808c3d79944bf5e33d4e05f1ae0b3f', slot: "icon-only", "aria-hidden": "true", icon: isPasswordVisible ? hidePasswordIcon : showPasswordIcon }))));
15695
15704
  }
15696
15705
  get el() { return getElement(this); }
15697
15706
  static get watchers() { return {
@@ -19201,47 +19210,7 @@ const iosEnterAnimation$3 = (baseEl, opts) => {
19201
19210
  .addElement(baseEl)
19202
19211
  .easing('cubic-bezier(0.32,0.72,0,1)')
19203
19212
  .duration(500)
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
- });
19213
+ .addAnimation([wrapperAnimation]);
19245
19214
  if (contentAnimation) {
19246
19215
  baseAnimation.addAnimation(contentAnimation);
19247
19216
  }
@@ -19322,7 +19291,7 @@ const createLeaveAnimation$1 = () => {
19322
19291
  * iOS Modal Leave Animation
19323
19292
  */
19324
19293
  const iosLeaveAnimation$3 = (baseEl, opts, duration = 500) => {
19325
- const { presentingEl, currentBreakpoint, expandToScroll } = opts;
19294
+ const { presentingEl, currentBreakpoint } = opts;
19326
19295
  const root = getElementRoot(baseEl);
19327
19296
  const { wrapperAnimation, backdropAnimation } = currentBreakpoint !== undefined ? createSheetLeaveAnimation(opts) : createLeaveAnimation$1();
19328
19297
  backdropAnimation.addElement(root.querySelector('ion-backdrop'));
@@ -19331,29 +19300,7 @@ const iosLeaveAnimation$3 = (baseEl, opts, duration = 500) => {
19331
19300
  .addElement(baseEl)
19332
19301
  .easing('cubic-bezier(0.32,0.72,0,1)')
19333
19302
  .duration(duration)
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
- });
19303
+ .addAnimation(wrapperAnimation);
19357
19304
  if (presentingEl) {
19358
19305
  const isMobile = window.innerWidth < 768;
19359
19306
  const hasCardModal = presentingEl.tagName === 'ION-MODAL' && presentingEl.presentingElement !== undefined;
@@ -19449,47 +19396,7 @@ const mdEnterAnimation$2 = (baseEl, opts) => {
19449
19396
  .addElement(baseEl)
19450
19397
  .easing('cubic-bezier(0.36,0.66,0.04,1)')
19451
19398
  .duration(280)
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
- });
19399
+ .addAnimation([backdropAnimation, wrapperAnimation]);
19493
19400
  if (contentAnimation) {
19494
19401
  baseAnimation.addAnimation(contentAnimation);
19495
19402
  }
@@ -19508,7 +19415,7 @@ const createLeaveAnimation = () => {
19508
19415
  * Md Modal Leave Animation
19509
19416
  */
19510
19417
  const mdLeaveAnimation$2 = (baseEl, opts) => {
19511
- const { currentBreakpoint, expandToScroll } = opts;
19418
+ const { currentBreakpoint } = opts;
19512
19419
  const root = getElementRoot(baseEl);
19513
19420
  const { wrapperAnimation, backdropAnimation } = currentBreakpoint !== undefined ? createSheetLeaveAnimation(opts) : createLeaveAnimation();
19514
19421
  backdropAnimation.addElement(root.querySelector('ion-backdrop'));
@@ -19516,29 +19423,7 @@ const mdLeaveAnimation$2 = (baseEl, opts) => {
19516
19423
  const baseAnimation = createAnimation()
19517
19424
  .easing('cubic-bezier(0.47,0,0.745,0.715)')
19518
19425
  .duration(200)
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
- });
19426
+ .addAnimation([backdropAnimation, wrapperAnimation]);
19542
19427
  return baseAnimation;
19543
19428
  };
19544
19429
 
@@ -19570,6 +19455,9 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
19570
19455
  let offset = 0;
19571
19456
  let canDismissBlocksGesture = false;
19572
19457
  let cachedScrollEl = null;
19458
+ let cachedFooterEl = null;
19459
+ let cachedFooterYPosition = null;
19460
+ let currentFooterState = null;
19573
19461
  const canDismissMaxStep = 0.95;
19574
19462
  const maxBreakpoint = breakpoints[breakpoints.length - 1];
19575
19463
  const minBreakpoint = breakpoints[0];
@@ -19599,29 +19487,66 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
19599
19487
  baseEl.classList.add(FOCUS_TRAP_DISABLE_CLASS);
19600
19488
  };
19601
19489
  /**
19602
- * Toggles the visible modal footer when `expandToScroll` is disabled.
19603
- * @param footer The footer to show.
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.
19604
19493
  */
19605
- const swapFooterVisibility = (footer) => {
19606
- const originalFooter = baseEl.querySelector('ion-footer');
19607
- if (!originalFooter) {
19608
- return;
19494
+ const swapFooterPosition = (newPosition) => {
19495
+ if (!cachedFooterEl) {
19496
+ cachedFooterEl = baseEl.querySelector('ion-footer');
19497
+ if (!cachedFooterEl) {
19498
+ return;
19499
+ }
19609
19500
  }
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');
19615
19501
  const page = baseEl.querySelector('.ion-page');
19616
- if (footer === 'original') {
19617
- page.style.removeProperty('padding-bottom');
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('width');
19508
+ cachedFooterEl.style.removeProperty('height');
19509
+ cachedFooterEl.style.removeProperty('top');
19510
+ cachedFooterEl.style.removeProperty('left');
19511
+ page === null || page === void 0 ? void 0 : page.style.removeProperty('padding-bottom');
19512
+ // Move to page
19513
+ page === null || page === void 0 ? void 0 : page.appendChild(cachedFooterEl);
19618
19514
  }
19619
19515
  else {
19620
- const pagePadding = footerToShow.clientHeight;
19621
- page.style.setProperty('padding-bottom', `${pagePadding}px`);
19516
+ // Get both the footer and document body positions
19517
+ const cachedFooterElRect = cachedFooterEl.getBoundingClientRect();
19518
+ const bodyRect = document.body.getBoundingClientRect();
19519
+ // Add padding to the parent element to prevent content from being hidden
19520
+ // when the footer is positioned absolutely. This has to be done before we
19521
+ // make the footer absolutely positioned or we may accidentally cause the
19522
+ // sheet to scroll.
19523
+ const footerHeight = cachedFooterEl.clientHeight;
19524
+ page === null || page === void 0 ? void 0 : page.style.setProperty('padding-bottom', `${footerHeight}px`);
19525
+ // Apply positioning styles to keep footer at bottom
19526
+ cachedFooterEl.classList.add('modal-footer-moving');
19527
+ // Calculate absolute position relative to body
19528
+ // We need to subtract the body's offsetTop to get true position within document.body
19529
+ const absoluteTop = cachedFooterElRect.top - bodyRect.top;
19530
+ const absoluteLeft = cachedFooterElRect.left - bodyRect.left;
19531
+ // Capture the footer's current dimensions and hard code them during the drag
19532
+ cachedFooterEl.style.setProperty('position', 'absolute');
19533
+ cachedFooterEl.style.setProperty('width', `${cachedFooterEl.clientWidth}px`);
19534
+ cachedFooterEl.style.setProperty('height', `${cachedFooterEl.clientHeight}px`);
19535
+ cachedFooterEl.style.setProperty('top', `${absoluteTop}px`);
19536
+ cachedFooterEl.style.setProperty('left', `${absoluteLeft}px`);
19537
+ // Also cache the footer Y position, which we use to determine if the
19538
+ // sheet has been moved below the footer. When that happens, we need to swap
19539
+ // the position back so it will collapse correctly.
19540
+ cachedFooterYPosition = absoluteTop;
19541
+ // If there's a toolbar, we need to combine the toolbar height with the footer position
19542
+ // because the toolbar moves with the drag handle, so when it starts overlapping the footer,
19543
+ // we need to account for that.
19544
+ const toolbar = baseEl.querySelector('ion-toolbar');
19545
+ if (toolbar) {
19546
+ cachedFooterYPosition -= toolbar.clientHeight;
19547
+ }
19548
+ document.body.appendChild(cachedFooterEl);
19622
19549
  }
19623
- footerToHide.style.setProperty('display', 'none');
19624
- footerToHide.setAttribute('aria-hidden', 'true');
19625
19550
  };
19626
19551
  /**
19627
19552
  * After the entering animation completes,
@@ -19715,12 +19640,11 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
19715
19640
  }
19716
19641
  /**
19717
19642
  * If expandToScroll is disabled, we need to swap
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.
19643
+ * the footer position to moving so that it doesn't shake
19644
+ * while the sheet is being dragged.
19721
19645
  */
19722
19646
  if (!expandToScroll) {
19723
- swapFooterVisibility('original');
19647
+ swapFooterPosition('moving');
19724
19648
  }
19725
19649
  /**
19726
19650
  * If we are pulling down, then it is possible we are pulling on the content.
@@ -19739,6 +19663,21 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
19739
19663
  animation.progressStart(true, 1 - currentBreakpoint);
19740
19664
  };
19741
19665
  const onMove = (detail) => {
19666
+ /**
19667
+ * If `expandToScroll` is disabled, we need to see if we're currently below
19668
+ * the footer element and the footer is in a stationary position. If so,
19669
+ * we need to make the stationary the original position so that the footer
19670
+ * collapses with the sheet.
19671
+ */
19672
+ if (!expandToScroll && cachedFooterYPosition !== null && currentFooterState !== null) {
19673
+ // Check if we need to swap the footer position
19674
+ if (detail.currentY >= cachedFooterYPosition && currentFooterState === 'moving') {
19675
+ swapFooterPosition('stationary');
19676
+ }
19677
+ else if (detail.currentY < cachedFooterYPosition && currentFooterState === 'stationary') {
19678
+ swapFooterPosition('moving');
19679
+ }
19680
+ }
19742
19681
  /**
19743
19682
  * If `expandToScroll` is disabled, and an upwards swipe gesture is done within
19744
19683
  * the scrollable content, we should not allow the swipe gesture to continue.
@@ -19872,14 +19811,6 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
19872
19811
  * snapping animation completes.
19873
19812
  */
19874
19813
  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
- }
19883
19814
  if (shouldPreventDismiss) {
19884
19815
  handleCanDismiss(baseEl, animation);
19885
19816
  }
@@ -19896,10 +19827,26 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
19896
19827
  if (contentEl && (snapToBreakpoint === breakpoints[breakpoints.length - 1] || !expandToScroll)) {
19897
19828
  contentEl.scrollY = true;
19898
19829
  }
19830
+ /**
19831
+ * If expandToScroll is disabled and we're animating
19832
+ * to the close of the sheet, we need to swap
19833
+ * the footer position to stationary so that it
19834
+ * will collapse correctly. We cannot just always swap
19835
+ * here or it'll be jittery while animating movement.
19836
+ */
19837
+ if (!expandToScroll && snapToBreakpoint === 0) {
19838
+ swapFooterPosition('stationary');
19839
+ }
19899
19840
  return new Promise((resolve) => {
19900
19841
  animation
19901
19842
  .onFinish(() => {
19902
19843
  if (shouldRemainOpen) {
19844
+ /**
19845
+ * If expandToScroll is disabled, we need to swap
19846
+ * the footer position to stationary so that it
19847
+ * will act as it would by default
19848
+ */
19849
+ swapFooterPosition('stationary');
19903
19850
  /**
19904
19851
  * Once the snapping animation completes,
19905
19852
  * we need to reset the animation to go
@@ -23316,7 +23263,7 @@ class PickerColumnCmp {
23316
23263
  const colEl = this.optsEl;
23317
23264
  if (colEl) {
23318
23265
  // DOM READ
23319
- // We perfom a DOM read over a rendered item, this needs to happen after the first render or after the column has changed
23266
+ // We perfom a DOM read over a rendered item, this needs to happen after the first render or after the the column has changed
23320
23267
  this.optHeight = colEl.firstElementChild ? colEl.firstElementChild.clientHeight : 0;
23321
23268
  }
23322
23269
  this.refresh(forceRefresh, animated);
@@ -23324,9 +23271,9 @@ class PickerColumnCmp {
23324
23271
  render() {
23325
23272
  const col = this.col;
23326
23273
  const mode = getIonMode$1(this);
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: {
23274
+ 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: {
23328
23275
  'max-width': this.col.columnWidth,
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))));
23276
+ } }, 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))));
23330
23277
  }
23331
23278
  get el() { return getElement(this); }
23332
23279
  static get watchers() { return {
@@ -29038,8 +28985,8 @@ class Searchbar {
29038
28985
  const clearIcon = this.clearIcon || (mode === 'ios' ? closeCircle : closeSharp);
29039
28986
  const searchIcon = this.searchIcon || (mode === 'ios' ? searchOutline : searchSharp);
29040
28987
  const shouldShowCancelButton = this.shouldShowCancelButton();
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, {
28988
+ 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))));
28989
+ return (hAsync(Host, { key: 'd1a1972725e949fb102c91487aaa7b9d10c2d718', role: "search", "aria-disabled": this.disabled ? 'true' : null, class: createColorClasses$1(this.color, {
29043
28990
  [mode]: true,
29044
28991
  'searchbar-animated': animated,
29045
28992
  'searchbar-disabled': this.disabled,
@@ -29049,14 +28996,14 @@ class Searchbar {
29049
28996
  'searchbar-has-focus': this.focused,
29050
28997
  'searchbar-should-show-clear': this.shouldShowClearButton(),
29051
28998
  'searchbar-should-show-cancel': this.shouldShowCancelButton(),
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) => {
28999
+ }) }, 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) => {
29053
29000
  /**
29054
29001
  * This prevents mobile browsers from
29055
29002
  * blurring the input when the clear
29056
29003
  * button is activated.
29057
29004
  */
29058
29005
  ev.preventDefault();
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));
29006
+ }, 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));
29060
29007
  }
29061
29008
  get el() { return getElement(this); }
29062
29009
  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.11748388365.11ad9dfe",
3
+ "version": "8.5.8-dev.11748525800.1cdc649b",
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.11.0",
44
+ "@clack/prompts": "^0.10.0",
45
45
  "@ionic/eslint-config": "^0.3.0",
46
46
  "@ionic/prettier-config": "^2.0.0",
47
47
  "@playwright/test": "^1.52.0",