@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
@@ -35,6 +35,9 @@ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpo
35
35
  let offset = 0;
36
36
  let canDismissBlocksGesture = false;
37
37
  let cachedScrollEl = null;
38
+ let cachedFooterEl = null;
39
+ let cachedFooterYPosition = null;
40
+ let currentFooterState = null;
38
41
  const canDismissMaxStep = 0.95;
39
42
  const maxBreakpoint = breakpoints[breakpoints.length - 1];
40
43
  const minBreakpoint = breakpoints[0];
@@ -64,29 +67,66 @@ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpo
64
67
  baseEl.classList.add(FOCUS_TRAP_DISABLE_CLASS);
65
68
  };
66
69
  /**
67
- * Toggles the visible modal footer when `expandToScroll` is disabled.
68
- * @param footer The footer to show.
70
+ * Toggles the footer to an absolute position while moving to prevent
71
+ * it from shaking while the sheet is being dragged.
72
+ * @param footer Whether the footer is in a moving or stationary position.
69
73
  */
70
- const swapFooterVisibility = (footer) => {
71
- const originalFooter = baseEl.querySelector('ion-footer');
72
- if (!originalFooter) {
73
- return;
74
+ const swapFooterPosition = (newPosition) => {
75
+ if (!cachedFooterEl) {
76
+ cachedFooterEl = baseEl.querySelector('ion-footer');
77
+ if (!cachedFooterEl) {
78
+ return;
79
+ }
74
80
  }
75
- const clonedFooter = wrapperEl.nextElementSibling;
76
- const footerToHide = footer === 'original' ? clonedFooter : originalFooter;
77
- const footerToShow = footer === 'original' ? originalFooter : clonedFooter;
78
- footerToShow.style.removeProperty('display');
79
- footerToShow.removeAttribute('aria-hidden');
80
81
  const page = baseEl.querySelector('.ion-page');
81
- if (footer === 'original') {
82
- page.style.removeProperty('padding-bottom');
82
+ currentFooterState = newPosition;
83
+ if (newPosition === 'stationary') {
84
+ // Reset positioning styles to allow normal document flow
85
+ cachedFooterEl.classList.remove('modal-footer-moving');
86
+ cachedFooterEl.style.removeProperty('position');
87
+ cachedFooterEl.style.removeProperty('width');
88
+ cachedFooterEl.style.removeProperty('height');
89
+ cachedFooterEl.style.removeProperty('top');
90
+ cachedFooterEl.style.removeProperty('left');
91
+ page === null || page === void 0 ? void 0 : page.style.removeProperty('padding-bottom');
92
+ // Move to page
93
+ page === null || page === void 0 ? void 0 : page.appendChild(cachedFooterEl);
83
94
  }
84
95
  else {
85
- const pagePadding = footerToShow.clientHeight;
86
- page.style.setProperty('padding-bottom', `${pagePadding}px`);
96
+ // Get both the footer and document body positions
97
+ const cachedFooterElRect = cachedFooterEl.getBoundingClientRect();
98
+ const bodyRect = document.body.getBoundingClientRect();
99
+ // Add padding to the parent element to prevent content from being hidden
100
+ // when the footer is positioned absolutely. This has to be done before we
101
+ // make the footer absolutely positioned or we may accidentally cause the
102
+ // sheet to scroll.
103
+ const footerHeight = cachedFooterEl.clientHeight;
104
+ page === null || page === void 0 ? void 0 : page.style.setProperty('padding-bottom', `${footerHeight}px`);
105
+ // Apply positioning styles to keep footer at bottom
106
+ cachedFooterEl.classList.add('modal-footer-moving');
107
+ // Calculate absolute position relative to body
108
+ // We need to subtract the body's offsetTop to get true position within document.body
109
+ const absoluteTop = cachedFooterElRect.top - bodyRect.top;
110
+ const absoluteLeft = cachedFooterElRect.left - bodyRect.left;
111
+ // Capture the footer's current dimensions and hard code them during the drag
112
+ cachedFooterEl.style.setProperty('position', 'absolute');
113
+ cachedFooterEl.style.setProperty('width', `${cachedFooterEl.clientWidth}px`);
114
+ cachedFooterEl.style.setProperty('height', `${cachedFooterEl.clientHeight}px`);
115
+ cachedFooterEl.style.setProperty('top', `${absoluteTop}px`);
116
+ cachedFooterEl.style.setProperty('left', `${absoluteLeft}px`);
117
+ // Also cache the footer Y position, which we use to determine if the
118
+ // sheet has been moved below the footer. When that happens, we need to swap
119
+ // the position back so it will collapse correctly.
120
+ cachedFooterYPosition = absoluteTop;
121
+ // If there's a toolbar, we need to combine the toolbar height with the footer position
122
+ // because the toolbar moves with the drag handle, so when it starts overlapping the footer,
123
+ // we need to account for that.
124
+ const toolbar = baseEl.querySelector('ion-toolbar');
125
+ if (toolbar) {
126
+ cachedFooterYPosition -= toolbar.clientHeight;
127
+ }
128
+ document.body.appendChild(cachedFooterEl);
87
129
  }
88
- footerToHide.style.setProperty('display', 'none');
89
- footerToHide.setAttribute('aria-hidden', 'true');
90
130
  };
91
131
  /**
92
132
  * After the entering animation completes,
@@ -180,12 +220,11 @@ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpo
180
220
  }
181
221
  /**
182
222
  * If expandToScroll is disabled, we need to swap
183
- * the footer visibility to the original, so if the modal
184
- * is dismissed, the footer dismisses with the modal
185
- * and doesn't stay on the screen after the modal is gone.
223
+ * the footer position to moving so that it doesn't shake
224
+ * while the sheet is being dragged.
186
225
  */
187
226
  if (!expandToScroll) {
188
- swapFooterVisibility('original');
227
+ swapFooterPosition('moving');
189
228
  }
190
229
  /**
191
230
  * If we are pulling down, then it is possible we are pulling on the content.
@@ -204,6 +243,21 @@ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpo
204
243
  animation.progressStart(true, 1 - currentBreakpoint);
205
244
  };
206
245
  const onMove = (detail) => {
246
+ /**
247
+ * If `expandToScroll` is disabled, we need to see if we're currently below
248
+ * the footer element and the footer is in a stationary position. If so,
249
+ * we need to make the stationary the original position so that the footer
250
+ * collapses with the sheet.
251
+ */
252
+ if (!expandToScroll && cachedFooterYPosition !== null && currentFooterState !== null) {
253
+ // Check if we need to swap the footer position
254
+ if (detail.currentY >= cachedFooterYPosition && currentFooterState === 'moving') {
255
+ swapFooterPosition('stationary');
256
+ }
257
+ else if (detail.currentY < cachedFooterYPosition && currentFooterState === 'stationary') {
258
+ swapFooterPosition('moving');
259
+ }
260
+ }
207
261
  /**
208
262
  * If `expandToScroll` is disabled, and an upwards swipe gesture is done within
209
263
  * the scrollable content, we should not allow the swipe gesture to continue.
@@ -337,14 +391,6 @@ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpo
337
391
  * snapping animation completes.
338
392
  */
339
393
  gesture.enable(false);
340
- /**
341
- * If expandToScroll is disabled, we need to swap
342
- * the footer visibility to the cloned one so the footer
343
- * doesn't flicker when the sheet's height is animated.
344
- */
345
- if (!expandToScroll && shouldRemainOpen) {
346
- swapFooterVisibility('cloned');
347
- }
348
394
  if (shouldPreventDismiss) {
349
395
  handleCanDismiss(baseEl, animation);
350
396
  }
@@ -361,10 +407,26 @@ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpo
361
407
  if (contentEl && (snapToBreakpoint === breakpoints[breakpoints.length - 1] || !expandToScroll)) {
362
408
  contentEl.scrollY = true;
363
409
  }
410
+ /**
411
+ * If expandToScroll is disabled and we're animating
412
+ * to the close of the sheet, we need to swap
413
+ * the footer position to stationary so that it
414
+ * will collapse correctly. We cannot just always swap
415
+ * here or it'll be jittery while animating movement.
416
+ */
417
+ if (!expandToScroll && snapToBreakpoint === 0) {
418
+ swapFooterPosition('stationary');
419
+ }
364
420
  return new Promise((resolve) => {
365
421
  animation
366
422
  .onFinish(() => {
367
423
  if (shouldRemainOpen) {
424
+ /**
425
+ * If expandToScroll is disabled, we need to swap
426
+ * the footer position to stationary so that it
427
+ * will act as it would by default
428
+ */
429
+ swapFooterPosition('stationary');
368
430
  /**
369
431
  * Once the snapping animation completes,
370
432
  * we need to reset the animation to go
@@ -328,7 +328,7 @@ export class PickerColumnCmp {
328
328
  const colEl = this.optsEl;
329
329
  if (colEl) {
330
330
  // DOM READ
331
- // We perfom a DOM read over a rendered item, this needs to happen after the first render or after the column has changed
331
+ // We perfom a DOM read over a rendered item, this needs to happen after the first render or after the the column has changed
332
332
  this.optHeight = colEl.firstElementChild ? colEl.firstElementChild.clientHeight : 0;
333
333
  }
334
334
  this.refresh(forceRefresh, animated);
@@ -336,9 +336,9 @@ export class PickerColumnCmp {
336
336
  render() {
337
337
  const col = this.col;
338
338
  const mode = getIonMode(this);
339
- return (h(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: {
339
+ return (h(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: {
340
340
  'max-width': this.col.columnWidth,
341
- } }, col.prefix && (h("div", { key: '253066708012034206b1d3d466ea48d0a3be3323', class: "picker-prefix", style: { width: col.prefixWidth } }, col.prefix)), h("div", { key: '15fa07307d4d2b4994504a5bf2de8db05b51cd2c', class: "picker-opts", style: { maxWidth: col.optionsWidth }, ref: (el) => (this.optsEl = el) }, col.options.map((o, index) => (h("button", { "aria-label": o.ariaLabel, class: { 'picker-opt': true, 'picker-opt-disabled': !!o.disabled }, "opt-index": index }, o.text)))), col.suffix && (h("div", { key: '4db779830b1e6aa6b324e5a72541d4f610ac1ff5', class: "picker-suffix", style: { width: col.suffixWidth } }, col.suffix))));
341
+ } }, col.prefix && (h("div", { key: '4491a705d15337e6f45f3cf6fd21af5242474729', class: "picker-prefix", style: { width: col.prefixWidth } }, col.prefix)), h("div", { key: 'b0dd4b7a7a4c1edc4b73e7fb134ac85264072365', class: "picker-opts", style: { maxWidth: col.optionsWidth }, ref: (el) => (this.optsEl = el) }, col.options.map((o, index) => (h("button", { "aria-label": o.ariaLabel, class: { 'picker-opt': true, 'picker-opt-disabled': !!o.disabled }, "opt-index": index }, o.text)))), col.suffix && (h("div", { key: 'c16419ce6481d60fc3ba6b8d102a4edf0ede02aa', class: "picker-suffix", style: { width: col.suffixWidth } }, col.suffix))));
342
342
  }
343
343
  static get is() { return "ion-picker-legacy-column"; }
344
344
  static get originalStyleUrls() {
@@ -378,8 +378,8 @@ export class Searchbar {
378
378
  const clearIcon = this.clearIcon || (mode === 'ios' ? closeCircle : closeSharp);
379
379
  const searchIcon = this.searchIcon || (mode === 'ios' ? searchOutline : searchSharp);
380
380
  const shouldShowCancelButton = this.shouldShowCancelButton();
381
- const cancelButton = this.showCancelButton !== 'never' && (h("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" }, h("div", { key: '24424547e34a80422f617f5597965724a3ef65f0', "aria-hidden": "true" }, mode === 'md' ? (h("ion-icon", { "aria-hidden": "true", mode: mode, icon: this.cancelButtonIcon, lazy: false })) : (cancelButtonText))));
382
- return (h(Host, { key: '0c0e7334cb2af87081a278e5a3f6be3dc646a073', role: "search", "aria-disabled": this.disabled ? 'true' : null, class: createColorClasses(this.color, {
381
+ const cancelButton = this.showCancelButton !== 'never' && (h("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" }, h("div", { key: '7d335d4fde33822dc79d26b748ba2e98db7494bb', "aria-hidden": "true" }, mode === 'md' ? (h("ion-icon", { "aria-hidden": "true", mode: mode, icon: this.cancelButtonIcon, lazy: false })) : (cancelButtonText))));
382
+ return (h(Host, { key: 'd1a1972725e949fb102c91487aaa7b9d10c2d718', role: "search", "aria-disabled": this.disabled ? 'true' : null, class: createColorClasses(this.color, {
383
383
  [mode]: true,
384
384
  'searchbar-animated': animated,
385
385
  'searchbar-disabled': this.disabled,
@@ -389,14 +389,14 @@ export class Searchbar {
389
389
  'searchbar-has-focus': this.focused,
390
390
  'searchbar-should-show-clear': this.shouldShowClearButton(),
391
391
  'searchbar-should-show-cancel': this.shouldShowCancelButton(),
392
- }) }, h("div", { key: '859da78b062b9059701eba166be3bc5417f7395b', class: "searchbar-input-container" }, h("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, h("ion-icon", { key: 'a5aaa6a2204d38433cac283dd47b6197499fa585', "aria-hidden": "true", mode: mode, icon: searchIcon, lazy: false, class: "searchbar-search-icon" }), h("button", { key: 'cf62c8969c5c916ac838e122a0ad45b2ae234791', "aria-label": "reset", type: "button", "no-blur": true, class: "searchbar-clear-button", onPointerDown: (ev) => {
392
+ }) }, h("div", { key: 'add53640b2994cb6b2bf02792dafe51aba6b1684', class: "searchbar-input-container" }, h("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, h("ion-icon", { key: '8825fd13af0d2dea451ccc0e00ae7b5021dc01c4', "aria-hidden": "true", mode: mode, icon: searchIcon, lazy: false, class: "searchbar-search-icon" }), h("button", { key: '8a7b56da278b9ca5c4f5a4ee9c01924fd5ae29d8', "aria-label": "reset", type: "button", "no-blur": true, class: "searchbar-clear-button", onPointerDown: (ev) => {
393
393
  /**
394
394
  * This prevents mobile browsers from
395
395
  * blurring the input when the clear
396
396
  * button is activated.
397
397
  */
398
398
  ev.preventDefault();
399
- }, onClick: () => this.onClearInput(true) }, h("ion-icon", { key: 'b1a75f0964fc2119479e246dc27bef7cc33bd19f', "aria-hidden": "true", mode: mode, icon: clearIcon, lazy: false, class: "searchbar-clear-icon" }))), mode === 'ios' && cancelButton));
399
+ }, onClick: () => this.onClearInput(true) }, h("ion-icon", { key: '24c55274516ab012d8c25f03525c6cdb9409e52f', "aria-hidden": "true", mode: mode, icon: clearIcon, lazy: false, class: "searchbar-clear-icon" }))), mode === 'ios' && cancelButton));
400
400
  }
401
401
  static get is() { return "ion-searchbar"; }
402
402
  static get encapsulation() { return "scoped"; }
@@ -545,7 +545,7 @@ export class Searchbar {
545
545
  "optional": false,
546
546
  "docs": {
547
547
  "tags": [],
548
- "text": "Set the cancel button text. Only applies to `ios` mode."
548
+ "text": "Set the the cancel button text. Only applies to `ios` mode."
549
549
  },
550
550
  "attribute": "cancel-button-text",
551
551
  "reflect": false,
package/dist/docs.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "timestamp": "2025-05-27T23:27:48",
2
+ "timestamp": "2025-05-29T13:38:24",
3
3
  "compiler": {
4
4
  "name": "@stencil/core",
5
5
  "version": "4.20.0",
@@ -25567,7 +25567,7 @@
25567
25567
  "mutable": false,
25568
25568
  "attr": "cancel-button-text",
25569
25569
  "reflectToAttr": false,
25570
- "docs": "Set the cancel button text. Only applies to `ios` mode.",
25570
+ "docs": "Set the the cancel button text. Only applies to `ios` mode.",
25571
25571
  "docsTags": [],
25572
25572
  "default": "'Cancel'",
25573
25573
  "values": [
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
- import { j as getAssetPath, r as registerInstance, c as createEvent, i as forceUpdate, h, e as Host, f as getElement } from './index-527b9e34.js';
4
+ import { j as getAssetPath, r as registerInstance, c as createEvent, h, e as Host, f as getElement } from './index-527b9e34.js';
5
5
  import { m as hasShadowDom, i as inheritAriaAttributes } from './helpers-d94bc8ad.js';
6
6
  import { p as printIonWarning } from './index-cfd9c1f2.js';
7
7
  import { o as openURL, c as createColorClasses$1, h as hostContext } from './theme-01f3f29c.js';
@@ -206,20 +206,6 @@ const Button = class {
206
206
  this.formButtonEl.disabled = disabled;
207
207
  }
208
208
  }
209
- /**
210
- * This component is used within the `ion-input-password-toggle` component
211
- * to toggle the visibility of the password input.
212
- * These attributes need to update based on the state of the password input.
213
- * Otherwise, the values will be stale.
214
- *
215
- * @param newValue
216
- * @param _oldValue
217
- * @param propName
218
- */
219
- onAriaChanged(newValue, _oldValue, propName) {
220
- this.inheritedAttributes = Object.assign(Object.assign({}, this.inheritedAttributes), { [propName]: newValue });
221
- forceUpdate(this);
222
- }
223
209
  /**
224
210
  * This is responsible for rendering a hidden native
225
211
  * button element inside the associated form. This allows
@@ -357,7 +343,7 @@ const Button = class {
357
343
  {
358
344
  type !== 'button' && this.renderHiddenButton();
359
345
  }
360
- return (h(Host, { key: 'b105ad09215adb3ca2298acdadf0dc9154bbb9b0', onClick: this.handleClick, "aria-disabled": disabled ? 'true' : null, class: createColorClasses$1(color, {
346
+ return (h(Host, { key: 'e213b0bb76b3f90f883b1a0ea463bb86c2df69c3', onClick: this.handleClick, "aria-disabled": disabled ? 'true' : null, class: createColorClasses$1(color, {
361
347
  [mode]: true,
362
348
  [buttonType]: true,
363
349
  [`${buttonType}-${expand}`]: expand !== undefined,
@@ -372,13 +358,11 @@ const Button = class {
372
358
  'button-disabled': disabled,
373
359
  'ion-activatable': true,
374
360
  'ion-focusable': true,
375
- }) }, h(TagType, Object.assign({ key: '66b4e7112bcb9e41d5a723fbbadb0a3104f9ee1d' }, attrs, { class: "button-native", part: "native", disabled: disabled, onFocus: this.onFocus, onBlur: this.onBlur }, inheritedAttributes), h("span", { key: '1439fc3da280221028dcf7ce8ec9dab273c4d4bb', class: "button-inner" }, h("slot", { key: 'd5269ae1afc87ec7b99746032f59cbae93720a9f', name: "icon-only", onSlotchange: this.slotChanged }), h("slot", { key: '461c83e97aa246aa86d83e14f1e15a288d35041e', name: "start" }), h("slot", { key: '807170d47101f9f6a333dd4ff489c89284f306fe' }), h("slot", { key: 'e67f116dd0349a0d27893e4f3ff0ccef1d402f80', name: "end" })), mode === 'md' && h("ion-ripple-effect", { key: '273f0bd9645a36c1bfd18a5c2ab4f81e22b7b989', type: this.rippleType }))));
361
+ }) }, h(TagType, Object.assign({ key: 'b7c2a46fb994024841219316f4089335fa463d84' }, attrs, { class: "button-native", part: "native", disabled: disabled, onFocus: this.onFocus, onBlur: this.onBlur }, inheritedAttributes), h("span", { key: '3e07a5c9f86836f9fbaefc6c617bdde6eb6f70cd', class: "button-inner" }, h("slot", { key: '41c08ae09aed16faaa57707d229ff75d97f0731c', name: "icon-only", onSlotchange: this.slotChanged }), h("slot", { key: 'ab8b749e4572884cc04970a7594466b4a24c886e', name: "start" }), h("slot", { key: '397f7ff48ea45e82029414be95d29ae86e12c3a9' }), h("slot", { key: '9a5627713002e8be3738d392b616f6e951b70e12', name: "end" })), mode === 'md' && h("ion-ripple-effect", { key: '105566543ceda102474edab7ca8a44c7e71af589', type: this.rippleType }))));
376
362
  }
377
363
  get el() { return getElement(this); }
378
364
  static get watchers() { return {
379
- "disabled": ["disabledChanged"],
380
- "aria-checked": ["onAriaChanged"],
381
- "aria-label": ["onAriaChanged"]
365
+ "disabled": ["disabledChanged"]
382
366
  }; }
383
367
  };
384
368
  Button.style = {
@@ -683,18 +683,19 @@ const Datetime = class {
683
683
  warnIfValueOutOfBounds(valueToProcess, minParts, maxParts);
684
684
  }
685
685
  /**
686
- * If there are multiple values, clamp to the last one.
687
- * This is because the last value is the one that the user
688
- * has most recently interacted with.
686
+ * If there are multiple values, pick an arbitrary one to clamp to. This way,
687
+ * if the values are across months, we always show at least one of them. Note
688
+ * that the values don't necessarily have to be in order.
689
689
  */
690
- const singleValue = Array.isArray(valueToProcess) ? valueToProcess[valueToProcess.length - 1] : valueToProcess;
690
+ const singleValue = Array.isArray(valueToProcess) ? valueToProcess[0] : valueToProcess;
691
691
  const targetValue = clampDate(singleValue, minParts, maxParts);
692
692
  const { month, day, year, hour, minute } = targetValue;
693
693
  const ampm = parseAmPm(hour);
694
694
  /**
695
- * Since `activeParts` indicates a value that been explicitly selected
696
- * either by the user or the app, only update `activeParts` if the
697
- * `value` property is set.
695
+ * Since `activeParts` indicates a value that
696
+ * been explicitly selected either by the
697
+ * user or the app, only update `activeParts`
698
+ * if the `value` property is set.
698
699
  */
699
700
  if (hasValue) {
700
701
  if (Array.isArray(valueToProcess)) {
@@ -719,28 +720,51 @@ const Datetime = class {
719
720
  */
720
721
  this.activeParts = [];
721
722
  }
723
+ /**
724
+ * Only animate if:
725
+ * 1. We're using grid style (wheel style pickers should just jump to new value)
726
+ * 2. The month and/or year actually changed, and both are defined (otherwise there's nothing to animate to)
727
+ * 3. The calendar body is visible (prevents animation when in collapsed datetime-button, for example)
728
+ * 4. The month/year picker is not open (since you wouldn't see the animation anyway)
729
+ */
722
730
  const didChangeMonth = (month !== undefined && month !== workingParts.month) || (year !== undefined && year !== workingParts.year);
723
731
  const bodyIsVisible = el.classList.contains('datetime-ready');
724
732
  const { isGridStyle, showMonthAndYear } = this;
725
- if (isGridStyle && didChangeMonth && bodyIsVisible && !showMonthAndYear) {
726
- /**
727
- * Only animate if:
728
- * 1. We're using grid style (wheel style pickers should just jump to new value)
729
- * 2. The month and/or year actually changed, and both are defined (otherwise there's nothing to animate to)
730
- * 3. The calendar body is visible (prevents animation when in collapsed datetime-button, for example)
731
- * 4. The month/year picker is not open (since you wouldn't see the animation anyway)
732
- */
733
- this.animateToDate(targetValue);
733
+ let areAllSelectedDatesInSameMonth = true;
734
+ if (Array.isArray(valueToProcess)) {
735
+ const firstMonth = valueToProcess[0].month;
736
+ for (const date of valueToProcess) {
737
+ if (date.month !== firstMonth) {
738
+ areAllSelectedDatesInSameMonth = false;
739
+ break;
740
+ }
741
+ }
734
742
  }
735
- else {
736
- this.setWorkingParts({
737
- month,
738
- day,
739
- year,
740
- hour,
741
- minute,
742
- ampm,
743
- });
743
+ /**
744
+ * If there is more than one date selected
745
+ * and the dates aren't all in the same month,
746
+ * then we should neither animate to the date
747
+ * nor update the working parts because we do
748
+ * not know which date the user wants to view.
749
+ */
750
+ if (areAllSelectedDatesInSameMonth) {
751
+ if (isGridStyle && didChangeMonth && bodyIsVisible && !showMonthAndYear) {
752
+ this.animateToDate(targetValue);
753
+ }
754
+ else {
755
+ /**
756
+ * We only need to do this if we didn't just animate to a new month,
757
+ * since that calls prevMonth/nextMonth which calls setWorkingParts for us.
758
+ */
759
+ this.setWorkingParts({
760
+ month,
761
+ day,
762
+ year,
763
+ hour,
764
+ minute,
765
+ ampm,
766
+ });
767
+ }
744
768
  }
745
769
  };
746
770
  this.animateToDate = async (targetValue) => {
@@ -1735,7 +1759,7 @@ const Datetime = class {
1735
1759
  const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
1736
1760
  const hasWheelVariant = hasDatePresentation && preferWheel;
1737
1761
  renderHiddenInput(true, el, name, formatValue(value), disabled);
1738
- return (h(Host, { key: '20e64fb4cfe3fbd74b24038c89e00651d78b500c', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, createColorClasses(color, {
1762
+ return (h(Host, { key: 'c3dfea8f46fcbcef38eb9e8a69b1b46a4e4b82fd', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, createColorClasses(color, {
1739
1763
  [mode]: true,
1740
1764
  ['datetime-readonly']: readonly,
1741
1765
  ['datetime-disabled']: disabled,
@@ -1745,7 +1769,7 @@ const Datetime = class {
1745
1769
  [`datetime-size-${size}`]: true,
1746
1770
  [`datetime-prefer-wheel`]: hasWheelVariant,
1747
1771
  [`datetime-grid`]: isGridStyle,
1748
- })) }, h("div", { key: '488fe7bf6b9052e208d65206a580d5d65b945a62', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
1772
+ })) }, h("div", { key: '75c91243cf6a51f44b83d7cf7d8c0c96bfd3c83f', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
1749
1773
  }
1750
1774
  get el() { return getElement(this); }
1751
1775
  static get watchers() { return {
@@ -2355,7 +2379,7 @@ const PickerColumnCmp = class {
2355
2379
  const colEl = this.optsEl;
2356
2380
  if (colEl) {
2357
2381
  // DOM READ
2358
- // We perfom a DOM read over a rendered item, this needs to happen after the first render or after the column has changed
2382
+ // We perfom a DOM read over a rendered item, this needs to happen after the first render or after the the column has changed
2359
2383
  this.optHeight = colEl.firstElementChild ? colEl.firstElementChild.clientHeight : 0;
2360
2384
  }
2361
2385
  this.refresh(forceRefresh, animated);
@@ -2363,9 +2387,9 @@ const PickerColumnCmp = class {
2363
2387
  render() {
2364
2388
  const col = this.col;
2365
2389
  const mode = getIonMode(this);
2366
- return (h(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: {
2390
+ return (h(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: {
2367
2391
  'max-width': this.col.columnWidth,
2368
- } }, col.prefix && (h("div", { key: '253066708012034206b1d3d466ea48d0a3be3323', class: "picker-prefix", style: { width: col.prefixWidth } }, col.prefix)), h("div", { key: '15fa07307d4d2b4994504a5bf2de8db05b51cd2c', class: "picker-opts", style: { maxWidth: col.optionsWidth }, ref: (el) => (this.optsEl = el) }, col.options.map((o, index) => (h("button", { "aria-label": o.ariaLabel, class: { 'picker-opt': true, 'picker-opt-disabled': !!o.disabled }, "opt-index": index }, o.text)))), col.suffix && (h("div", { key: '4db779830b1e6aa6b324e5a72541d4f610ac1ff5', class: "picker-suffix", style: { width: col.suffixWidth } }, col.suffix))));
2392
+ } }, col.prefix && (h("div", { key: '4491a705d15337e6f45f3cf6fd21af5242474729', class: "picker-prefix", style: { width: col.prefixWidth } }, col.prefix)), h("div", { key: 'b0dd4b7a7a4c1edc4b73e7fb134ac85264072365', class: "picker-opts", style: { maxWidth: col.optionsWidth }, ref: (el) => (this.optsEl = el) }, col.options.map((o, index) => (h("button", { "aria-label": o.ariaLabel, class: { 'picker-opt': true, 'picker-opt-disabled': !!o.disabled }, "opt-index": index }, o.text)))), col.suffix && (h("div", { key: 'c16419ce6481d60fc3ba6b8d102a4edf0ede02aa', class: "picker-suffix", style: { width: col.suffixWidth } }, col.suffix))));
2369
2393
  }
2370
2394
  get el() { return getElement(this); }
2371
2395
  static get watchers() { return {
@@ -67,14 +67,14 @@ const InputPasswordToggle = class {
67
67
  const isPasswordVisible = type === 'text';
68
68
  return (h(Host, { key: '1a28e078c83e74c72d8bb8189ece93ec2e3fa3d0', class: createColorClasses(color, {
69
69
  [mode]: true,
70
- }) }, h("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) => {
70
+ }) }, h("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) => {
71
71
  /**
72
72
  * This prevents mobile browsers from
73
73
  * blurring the input when the password toggle
74
74
  * button is activated.
75
75
  */
76
76
  ev.preventDefault();
77
- }, onClick: this.togglePasswordVisibility }, h("ion-icon", { key: '9d98e6675d5e2adea5c0f56ab67e98b6f57521dd', slot: "icon-only", "aria-hidden": "true", icon: isPasswordVisible ? hidePasswordIcon : showPasswordIcon }))));
77
+ }, onClick: this.togglePasswordVisibility }, h("ion-icon", { key: '26477ee97b808c3d79944bf5e33d4e05f1ae0b3f', slot: "icon-only", "aria-hidden": "true", icon: isPasswordVisible ? hidePasswordIcon : showPasswordIcon }))));
78
78
  }
79
79
  get el() { return getElement(this); }
80
80
  static get watchers() { return {