@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
@@ -31,7 +31,47 @@ export const iosEnterAnimation = (baseEl, opts) => {
31
31
  .addElement(baseEl)
32
32
  .easing('cubic-bezier(0.32,0.72,0,1)')
33
33
  .duration(500)
34
- .addAnimation([wrapperAnimation]);
34
+ .addAnimation([wrapperAnimation])
35
+ .beforeAddWrite(() => {
36
+ if (expandToScroll) {
37
+ // Scroll can only be done when the modal is fully expanded.
38
+ return;
39
+ }
40
+ /**
41
+ * There are some browsers that causes flickering when
42
+ * dragging the content when scroll is enabled at every
43
+ * breakpoint. This is due to the wrapper element being
44
+ * transformed off the screen and having a snap animation.
45
+ *
46
+ * A workaround is to clone the footer element and append
47
+ * it outside of the wrapper element. This way, the footer
48
+ * is still visible and the drag can be done without
49
+ * flickering. The original footer is hidden until the modal
50
+ * is dismissed. This maintains the animation of the footer
51
+ * when the modal is dismissed.
52
+ *
53
+ * The workaround needs to be done before the animation starts
54
+ * so there are no flickering issues.
55
+ */
56
+ const ionFooter = baseEl.querySelector('ion-footer');
57
+ /**
58
+ * This check is needed to prevent more than one footer
59
+ * from being appended to the shadow root.
60
+ * Otherwise, iOS and MD enter animations would append
61
+ * the footer twice.
62
+ */
63
+ const ionFooterAlreadyAppended = baseEl.shadowRoot.querySelector('ion-footer');
64
+ if (ionFooter && !ionFooterAlreadyAppended) {
65
+ const footerHeight = ionFooter.clientHeight;
66
+ const clonedFooter = ionFooter.cloneNode(true);
67
+ baseEl.shadowRoot.appendChild(clonedFooter);
68
+ ionFooter.style.setProperty('display', 'none');
69
+ ionFooter.setAttribute('aria-hidden', 'true');
70
+ // Padding is added to prevent some content from being hidden.
71
+ const page = baseEl.querySelector('.ion-page');
72
+ page.style.setProperty('padding-bottom', `${footerHeight}px`);
73
+ }
74
+ });
35
75
  if (contentAnimation) {
36
76
  baseAnimation.addAnimation(contentAnimation);
37
77
  }
@@ -14,7 +14,7 @@ const createLeaveAnimation = () => {
14
14
  * iOS Modal Leave Animation
15
15
  */
16
16
  export const iosLeaveAnimation = (baseEl, opts, duration = 500) => {
17
- const { presentingEl, currentBreakpoint } = opts;
17
+ const { presentingEl, currentBreakpoint, expandToScroll } = opts;
18
18
  const root = getElementRoot(baseEl);
19
19
  const { wrapperAnimation, backdropAnimation } = currentBreakpoint !== undefined ? createSheetLeaveAnimation(opts) : createLeaveAnimation();
20
20
  backdropAnimation.addElement(root.querySelector('ion-backdrop'));
@@ -23,7 +23,29 @@ export const iosLeaveAnimation = (baseEl, opts, duration = 500) => {
23
23
  .addElement(baseEl)
24
24
  .easing('cubic-bezier(0.32,0.72,0,1)')
25
25
  .duration(duration)
26
- .addAnimation(wrapperAnimation);
26
+ .addAnimation(wrapperAnimation)
27
+ .beforeAddWrite(() => {
28
+ if (expandToScroll) {
29
+ // Scroll can only be done when the modal is fully expanded.
30
+ return;
31
+ }
32
+ /**
33
+ * If expandToScroll is disabled, we need to swap
34
+ * the visibility to the original, so the footer
35
+ * dismisses with the modal and doesn't stay
36
+ * until the modal is removed from the DOM.
37
+ */
38
+ const ionFooter = baseEl.querySelector('ion-footer');
39
+ if (ionFooter) {
40
+ const clonedFooter = baseEl.shadowRoot.querySelector('ion-footer');
41
+ ionFooter.style.removeProperty('display');
42
+ ionFooter.removeAttribute('aria-hidden');
43
+ clonedFooter.style.setProperty('display', 'none');
44
+ clonedFooter.setAttribute('aria-hidden', 'true');
45
+ const page = baseEl.querySelector('.ion-page');
46
+ page.style.removeProperty('padding-bottom');
47
+ }
48
+ });
27
49
  if (presentingEl) {
28
50
  const isMobile = window.innerWidth < 768;
29
51
  const hasCardModal = presentingEl.tagName === 'ION-MODAL' && presentingEl.presentingElement !== undefined;
@@ -33,7 +33,47 @@ export const mdEnterAnimation = (baseEl, opts) => {
33
33
  .addElement(baseEl)
34
34
  .easing('cubic-bezier(0.36,0.66,0.04,1)')
35
35
  .duration(280)
36
- .addAnimation([backdropAnimation, wrapperAnimation]);
36
+ .addAnimation([backdropAnimation, wrapperAnimation])
37
+ .beforeAddWrite(() => {
38
+ if (expandToScroll) {
39
+ // Scroll can only be done when the modal is fully expanded.
40
+ return;
41
+ }
42
+ /**
43
+ * There are some browsers that causes flickering when
44
+ * dragging the content when scroll is enabled at every
45
+ * breakpoint. This is due to the wrapper element being
46
+ * transformed off the screen and having a snap animation.
47
+ *
48
+ * A workaround is to clone the footer element and append
49
+ * it outside of the wrapper element. This way, the footer
50
+ * is still visible and the drag can be done without
51
+ * flickering. The original footer is hidden until the modal
52
+ * is dismissed. This maintains the animation of the footer
53
+ * when the modal is dismissed.
54
+ *
55
+ * The workaround needs to be done before the animation starts
56
+ * so there are no flickering issues.
57
+ */
58
+ const ionFooter = baseEl.querySelector('ion-footer');
59
+ /**
60
+ * This check is needed to prevent more than one footer
61
+ * from being appended to the shadow root.
62
+ * Otherwise, iOS and MD enter animations would append
63
+ * the footer twice.
64
+ */
65
+ const ionFooterAlreadyAppended = baseEl.shadowRoot.querySelector('ion-footer');
66
+ if (ionFooter && !ionFooterAlreadyAppended) {
67
+ const footerHeight = ionFooter.clientHeight;
68
+ const clonedFooter = ionFooter.cloneNode(true);
69
+ baseEl.shadowRoot.appendChild(clonedFooter);
70
+ ionFooter.style.setProperty('display', 'none');
71
+ ionFooter.setAttribute('aria-hidden', 'true');
72
+ // Padding is added to prevent some content from being hidden.
73
+ const page = baseEl.querySelector('.ion-page');
74
+ page.style.setProperty('padding-bottom', `${footerHeight}px`);
75
+ }
76
+ });
37
77
  if (contentAnimation) {
38
78
  baseAnimation.addAnimation(contentAnimation);
39
79
  }
@@ -16,7 +16,7 @@ const createLeaveAnimation = () => {
16
16
  * Md Modal Leave Animation
17
17
  */
18
18
  export const mdLeaveAnimation = (baseEl, opts) => {
19
- const { currentBreakpoint } = opts;
19
+ const { currentBreakpoint, expandToScroll } = opts;
20
20
  const root = getElementRoot(baseEl);
21
21
  const { wrapperAnimation, backdropAnimation } = currentBreakpoint !== undefined ? createSheetLeaveAnimation(opts) : createLeaveAnimation();
22
22
  backdropAnimation.addElement(root.querySelector('ion-backdrop'));
@@ -24,6 +24,28 @@ export const mdLeaveAnimation = (baseEl, opts) => {
24
24
  const baseAnimation = createAnimation()
25
25
  .easing('cubic-bezier(0.47,0,0.745,0.715)')
26
26
  .duration(200)
27
- .addAnimation([backdropAnimation, wrapperAnimation]);
27
+ .addAnimation([backdropAnimation, wrapperAnimation])
28
+ .beforeAddWrite(() => {
29
+ if (expandToScroll) {
30
+ // Scroll can only be done when the modal is fully expanded.
31
+ return;
32
+ }
33
+ /**
34
+ * If expandToScroll is disabled, we need to swap
35
+ * the visibility to the original, so the footer
36
+ * dismisses with the modal and doesn't stay
37
+ * until the modal is removed from the DOM.
38
+ */
39
+ const ionFooter = baseEl.querySelector('ion-footer');
40
+ if (ionFooter) {
41
+ const clonedFooter = baseEl.shadowRoot.querySelector('ion-footer');
42
+ ionFooter.style.removeProperty('display');
43
+ ionFooter.removeAttribute('aria-hidden');
44
+ clonedFooter.style.setProperty('display', 'none');
45
+ clonedFooter.setAttribute('aria-hidden', 'true');
46
+ const page = baseEl.querySelector('.ion-page');
47
+ page.style.removeProperty('padding-bottom');
48
+ }
49
+ });
28
50
  return baseAnimation;
29
51
  };
@@ -35,9 +35,6 @@ 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;
41
38
  const canDismissMaxStep = 0.95;
42
39
  const maxBreakpoint = breakpoints[breakpoints.length - 1];
43
40
  const minBreakpoint = breakpoints[0];
@@ -67,45 +64,29 @@ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpo
67
64
  baseEl.classList.add(FOCUS_TRAP_DISABLE_CLASS);
68
65
  };
69
66
  /**
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.
67
+ * Toggles the visible modal footer when `expandToScroll` is disabled.
68
+ * @param footer The footer to show.
73
69
  */
74
- const swapFooterPosition = (newPosition) => {
75
- if (!cachedFooterEl) {
76
- cachedFooterEl = baseEl.querySelector('ion-footer');
77
- if (!cachedFooterEl) {
78
- return;
79
- }
70
+ const swapFooterVisibility = (footer) => {
71
+ const originalFooter = baseEl.querySelector('ion-footer');
72
+ if (!originalFooter) {
73
+ return;
80
74
  }
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');
81
80
  const page = baseEl.querySelector('.ion-page');
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('bottom');
88
- page === null || page === void 0 ? void 0 : page.style.removeProperty('padding-bottom');
89
- // Move to page
90
- page === null || page === void 0 ? void 0 : page.appendChild(cachedFooterEl);
81
+ if (footer === 'original') {
82
+ page.style.removeProperty('padding-bottom');
91
83
  }
92
84
  else {
93
- // Add padding to the parent element to prevent content from being hidden
94
- // when the footer is positioned absolutely. This has to be done before we
95
- // make the footer absolutely positioned or we may accidentally cause the
96
- // sheet to scroll.
97
- const footerHeight = cachedFooterEl.clientHeight;
98
- page === null || page === void 0 ? void 0 : page.style.setProperty('padding-bottom', `${footerHeight}px`);
99
- // Apply positioning styles to keep footer at bottom
100
- cachedFooterEl.classList.add('modal-footer-moving');
101
- cachedFooterEl.style.setProperty('position', 'absolute');
102
- cachedFooterEl.style.setProperty('bottom', '0');
103
- // Also cache the footer Y position, which we use to determine if the
104
- // sheet has been moved below the footer. When that happens, we need to swap
105
- // the position back so it will collapse correctly.
106
- cachedFooterYPosition = cachedFooterEl.getBoundingClientRect().top + window.scrollY;
107
- document.body.appendChild(cachedFooterEl);
85
+ const pagePadding = footerToShow.clientHeight;
86
+ page.style.setProperty('padding-bottom', `${pagePadding}px`);
108
87
  }
88
+ footerToHide.style.setProperty('display', 'none');
89
+ footerToHide.setAttribute('aria-hidden', 'true');
109
90
  };
110
91
  /**
111
92
  * After the entering animation completes,
@@ -199,11 +180,12 @@ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpo
199
180
  }
200
181
  /**
201
182
  * If expandToScroll is disabled, we need to swap
202
- * the footer position to moving so that it doesn't shake
203
- * while the sheet is being dragged.
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.
204
186
  */
205
187
  if (!expandToScroll) {
206
- swapFooterPosition('moving');
188
+ swapFooterVisibility('original');
207
189
  }
208
190
  /**
209
191
  * If we are pulling down, then it is possible we are pulling on the content.
@@ -222,21 +204,6 @@ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpo
222
204
  animation.progressStart(true, 1 - currentBreakpoint);
223
205
  };
224
206
  const onMove = (detail) => {
225
- /**
226
- * If `expandToScroll` is disabled, we need to see if we're currently below
227
- * the footer element and the footer is in a stationary position. If so,
228
- * we need to make the stationary the original position so that the footer
229
- * collapses with the sheet.
230
- */
231
- if (!expandToScroll && cachedFooterYPosition !== null && currentFooterState !== null) {
232
- // Check if we need to swap the footer position
233
- if (detail.currentY >= cachedFooterYPosition && currentFooterState === 'moving') {
234
- swapFooterPosition('stationary');
235
- }
236
- else if (detail.currentY < cachedFooterYPosition && currentFooterState === 'stationary') {
237
- swapFooterPosition('moving');
238
- }
239
- }
240
207
  /**
241
208
  * If `expandToScroll` is disabled, and an upwards swipe gesture is done within
242
209
  * the scrollable content, we should not allow the swipe gesture to continue.
@@ -370,6 +337,14 @@ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpo
370
337
  * snapping animation completes.
371
338
  */
372
339
  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
+ }
373
348
  if (shouldPreventDismiss) {
374
349
  handleCanDismiss(baseEl, animation);
375
350
  }
@@ -390,14 +365,6 @@ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpo
390
365
  animation
391
366
  .onFinish(() => {
392
367
  if (shouldRemainOpen) {
393
- /**
394
- * If expandToScroll is disabled, we need to swap
395
- * the footer position to stationary so that it
396
- * will act as it would by default
397
- */
398
- if (!expandToScroll) {
399
- swapFooterPosition('stationary');
400
- }
401
368
  /**
402
369
  * Once the snapping animation completes,
403
370
  * 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 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 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: '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: {
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: {
340
340
  'max-width': this.col.columnWidth,
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))));
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))));
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: '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, {
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, {
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: '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) => {
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) => {
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: '24c55274516ab012d8c25f03525c6cdb9409e52f', "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: 'b1a75f0964fc2119479e246dc27bef7cc33bd19f', "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 the cancel button text. Only applies to `ios` mode."
548
+ "text": "Set 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-27T19:38:24",
2
+ "timestamp": "2025-05-27T23:27:48",
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 the cancel button text. Only applies to `ios` mode.",
25570
+ "docs": "Set 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, h, e as Host, f as getElement } from './index-527b9e34.js';
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';
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,6 +206,20 @@ 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
+ }
209
223
  /**
210
224
  * This is responsible for rendering a hidden native
211
225
  * button element inside the associated form. This allows
@@ -343,7 +357,7 @@ const Button = class {
343
357
  {
344
358
  type !== 'button' && this.renderHiddenButton();
345
359
  }
346
- return (h(Host, { key: 'e213b0bb76b3f90f883b1a0ea463bb86c2df69c3', onClick: this.handleClick, "aria-disabled": disabled ? 'true' : null, class: createColorClasses$1(color, {
360
+ return (h(Host, { key: 'b105ad09215adb3ca2298acdadf0dc9154bbb9b0', onClick: this.handleClick, "aria-disabled": disabled ? 'true' : null, class: createColorClasses$1(color, {
347
361
  [mode]: true,
348
362
  [buttonType]: true,
349
363
  [`${buttonType}-${expand}`]: expand !== undefined,
@@ -358,11 +372,13 @@ const Button = class {
358
372
  'button-disabled': disabled,
359
373
  'ion-activatable': true,
360
374
  'ion-focusable': true,
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 }))));
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 }))));
362
376
  }
363
377
  get el() { return getElement(this); }
364
378
  static get watchers() { return {
365
- "disabled": ["disabledChanged"]
379
+ "disabled": ["disabledChanged"],
380
+ "aria-checked": ["onAriaChanged"],
381
+ "aria-label": ["onAriaChanged"]
366
382
  }; }
367
383
  };
368
384
  Button.style = {
@@ -683,19 +683,18 @@ const Datetime = class {
683
683
  warnIfValueOutOfBounds(valueToProcess, minParts, maxParts);
684
684
  }
685
685
  /**
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.
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.
689
689
  */
690
- const singleValue = Array.isArray(valueToProcess) ? valueToProcess[0] : valueToProcess;
690
+ const singleValue = Array.isArray(valueToProcess) ? valueToProcess[valueToProcess.length - 1] : 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
696
- * been explicitly selected either by the
697
- * user or the app, only update `activeParts`
698
- * if the `value` property is set.
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.
699
698
  */
700
699
  if (hasValue) {
701
700
  if (Array.isArray(valueToProcess)) {
@@ -720,51 +719,28 @@ const Datetime = class {
720
719
  */
721
720
  this.activeParts = [];
722
721
  }
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
- */
730
722
  const didChangeMonth = (month !== undefined && month !== workingParts.month) || (year !== undefined && year !== workingParts.year);
731
723
  const bodyIsVisible = el.classList.contains('datetime-ready');
732
724
  const { isGridStyle, showMonthAndYear } = this;
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
- }
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);
742
734
  }
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
- }
735
+ else {
736
+ this.setWorkingParts({
737
+ month,
738
+ day,
739
+ year,
740
+ hour,
741
+ minute,
742
+ ampm,
743
+ });
768
744
  }
769
745
  };
770
746
  this.animateToDate = async (targetValue) => {
@@ -1759,7 +1735,7 @@ const Datetime = class {
1759
1735
  const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
1760
1736
  const hasWheelVariant = hasDatePresentation && preferWheel;
1761
1737
  renderHiddenInput(true, el, name, formatValue(value), disabled);
1762
- return (h(Host, { key: 'c3dfea8f46fcbcef38eb9e8a69b1b46a4e4b82fd', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, createColorClasses(color, {
1738
+ return (h(Host, { key: '20e64fb4cfe3fbd74b24038c89e00651d78b500c', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, createColorClasses(color, {
1763
1739
  [mode]: true,
1764
1740
  ['datetime-readonly']: readonly,
1765
1741
  ['datetime-disabled']: disabled,
@@ -1769,7 +1745,7 @@ const Datetime = class {
1769
1745
  [`datetime-size-${size}`]: true,
1770
1746
  [`datetime-prefer-wheel`]: hasWheelVariant,
1771
1747
  [`datetime-grid`]: isGridStyle,
1772
- })) }, h("div", { key: '75c91243cf6a51f44b83d7cf7d8c0c96bfd3c83f', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
1748
+ })) }, h("div", { key: '488fe7bf6b9052e208d65206a580d5d65b945a62', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
1773
1749
  }
1774
1750
  get el() { return getElement(this); }
1775
1751
  static get watchers() { return {
@@ -2379,7 +2355,7 @@ const PickerColumnCmp = class {
2379
2355
  const colEl = this.optsEl;
2380
2356
  if (colEl) {
2381
2357
  // DOM READ
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
2358
+ // We perfom a DOM read over a rendered item, this needs to happen after the first render or after the column has changed
2383
2359
  this.optHeight = colEl.firstElementChild ? colEl.firstElementChild.clientHeight : 0;
2384
2360
  }
2385
2361
  this.refresh(forceRefresh, animated);
@@ -2387,9 +2363,9 @@ const PickerColumnCmp = class {
2387
2363
  render() {
2388
2364
  const col = this.col;
2389
2365
  const mode = getIonMode(this);
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: {
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: {
2391
2367
  'max-width': this.col.columnWidth,
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))));
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))));
2393
2369
  }
2394
2370
  get el() { return getElement(this); }
2395
2371
  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: '039d1bab764093bb6fe4a34299b0872abda087fd', mode: mode, color: color, fill: "clear", shape: "round", "aria-checked": isPasswordVisible ? 'true' : 'false', "aria-label": "show password", role: "switch", type: "button", onPointerDown: (ev) => {
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) => {
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: '26477ee97b808c3d79944bf5e33d4e05f1ae0b3f', slot: "icon-only", "aria-hidden": "true", icon: isPasswordVisible ? hidePasswordIcon : showPasswordIcon }))));
77
+ }, onClick: this.togglePasswordVisibility }, h("ion-icon", { key: '9d98e6675d5e2adea5c0f56ab67e98b6f57521dd', 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 {