voyager-ionic-core 8.3.3 → 8.3.4

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 (103) hide show
  1. package/components/action-sheet.js +2 -2
  2. package/components/alert.js +1 -1
  3. package/components/backdrop.js +1 -1
  4. package/components/ion-input.js +20 -5
  5. package/components/ion-loading.js +1 -1
  6. package/components/ion-picker-legacy.js +1 -1
  7. package/components/ion-textarea.js +19 -4
  8. package/components/overlays.js +62 -7
  9. package/dist/cjs/index.cjs.js +1 -1
  10. package/dist/cjs/ion-action-sheet.cjs.entry.js +3 -3
  11. package/dist/cjs/ion-alert.cjs.entry.js +2 -2
  12. package/dist/cjs/ion-backdrop.cjs.entry.js +1 -1
  13. package/dist/cjs/ion-datetime_3.cjs.entry.js +2 -2
  14. package/dist/cjs/ion-input.cjs.entry.js +20 -5
  15. package/dist/cjs/ion-loading.cjs.entry.js +2 -2
  16. package/dist/cjs/ion-menu_3.cjs.entry.js +1 -1
  17. package/dist/cjs/ion-modal.cjs.entry.js +1 -1
  18. package/dist/cjs/ion-popover.cjs.entry.js +1 -1
  19. package/dist/cjs/ion-select_3.cjs.entry.js +1 -1
  20. package/dist/cjs/ion-textarea.cjs.entry.js +19 -4
  21. package/dist/cjs/ion-toast.cjs.entry.js +1 -1
  22. package/dist/cjs/{overlays-0123d7d4.js → overlays-ba0f6986.js} +62 -7
  23. package/dist/collection/components/action-sheet/action-sheet.js +2 -2
  24. package/dist/collection/components/alert/alert.js +1 -1
  25. package/dist/collection/components/backdrop/backdrop.js +1 -1
  26. package/dist/collection/components/input/input.js +20 -5
  27. package/dist/collection/components/loading/loading.js +1 -1
  28. package/dist/collection/components/picker-legacy/picker.js +1 -1
  29. package/dist/collection/components/textarea/textarea.js +19 -4
  30. package/dist/collection/utils/overlays.js +62 -7
  31. package/dist/docs.json +1 -1
  32. package/dist/esm/index.js +1 -1
  33. package/dist/esm/ion-action-sheet.entry.js +3 -3
  34. package/dist/esm/ion-alert.entry.js +2 -2
  35. package/dist/esm/ion-backdrop.entry.js +1 -1
  36. package/dist/esm/ion-datetime_3.entry.js +2 -2
  37. package/dist/esm/ion-input.entry.js +20 -5
  38. package/dist/esm/ion-loading.entry.js +2 -2
  39. package/dist/esm/ion-menu_3.entry.js +1 -1
  40. package/dist/esm/ion-modal.entry.js +1 -1
  41. package/dist/esm/ion-popover.entry.js +1 -1
  42. package/dist/esm/ion-select_3.entry.js +1 -1
  43. package/dist/esm/ion-textarea.entry.js +19 -4
  44. package/dist/esm/ion-toast.entry.js +1 -1
  45. package/dist/esm/{overlays-9c75ec54.js → overlays-ae10d43d.js} +62 -7
  46. package/dist/esm-es5/index.js +1 -1
  47. package/dist/esm-es5/ion-action-sheet.entry.js +1 -1
  48. package/dist/esm-es5/ion-alert.entry.js +1 -1
  49. package/dist/esm-es5/ion-backdrop.entry.js +1 -1
  50. package/dist/esm-es5/ion-datetime_3.entry.js +1 -1
  51. package/dist/esm-es5/ion-input.entry.js +1 -1
  52. package/dist/esm-es5/ion-loading.entry.js +1 -1
  53. package/dist/esm-es5/ion-menu_3.entry.js +1 -1
  54. package/dist/esm-es5/ion-modal.entry.js +1 -1
  55. package/dist/esm-es5/ion-popover.entry.js +1 -1
  56. package/dist/esm-es5/ion-select_3.entry.js +1 -1
  57. package/dist/esm-es5/ion-textarea.entry.js +1 -1
  58. package/dist/esm-es5/ion-toast.entry.js +1 -1
  59. package/dist/esm-es5/overlays-ae10d43d.js +4 -0
  60. package/dist/ionic/index.esm.js +1 -1
  61. package/dist/ionic/ionic.esm.js +1 -1
  62. package/dist/ionic/p-04fc24ee.system.js +4 -0
  63. package/dist/ionic/{p-ecb57d24.system.entry.js → p-0790b342.system.entry.js} +1 -1
  64. package/dist/ionic/{p-100b83fd.system.entry.js → p-110e03be.system.entry.js} +1 -1
  65. package/dist/ionic/p-148b8abb.entry.js +4 -0
  66. package/dist/ionic/{p-4b0fedb7.system.entry.js → p-18105026.system.entry.js} +1 -1
  67. package/dist/ionic/p-322c5fb4.system.js +1 -1
  68. package/dist/ionic/{p-d57661a1.entry.js → p-41c89b8d.entry.js} +1 -1
  69. package/dist/ionic/{p-772dacba.system.entry.js → p-53add985.system.entry.js} +1 -1
  70. package/dist/ionic/p-5c831f49.js +4 -0
  71. package/dist/ionic/p-60cc7986.entry.js +4 -0
  72. package/dist/ionic/{p-a72fb8a1.system.entry.js → p-63d65dbc.system.entry.js} +1 -1
  73. package/dist/ionic/p-6ceb04b5.entry.js +4 -0
  74. package/dist/ionic/{p-9fef1364.entry.js → p-6d50faff.entry.js} +1 -1
  75. package/dist/ionic/{p-a4d51b8d.system.js → p-79b12fda.system.js} +1 -1
  76. package/dist/ionic/{p-8ed31163.system.entry.js → p-79e7be3a.system.entry.js} +1 -1
  77. package/dist/ionic/{p-22c020db.system.entry.js → p-857ca696.system.entry.js} +1 -1
  78. package/dist/ionic/{p-9c23044d.entry.js → p-87a4407b.entry.js} +1 -1
  79. package/dist/ionic/{p-2b7c93b4.entry.js → p-9895e7f3.entry.js} +1 -1
  80. package/dist/ionic/p-9910f786.entry.js +4 -0
  81. package/dist/ionic/{p-5e66bcf2.entry.js → p-9e208825.entry.js} +1 -1
  82. package/dist/ionic/p-a89dac49.entry.js +4 -0
  83. package/dist/ionic/{p-755b27f0.system.entry.js → p-be715dd3.system.entry.js} +1 -1
  84. package/dist/ionic/{p-ed6962d3.system.entry.js → p-be71fe0f.system.entry.js} +1 -1
  85. package/dist/ionic/{p-cff5585e.system.entry.js → p-c71f301f.system.entry.js} +1 -1
  86. package/dist/ionic/{p-a41699db.entry.js → p-d58f21d2.entry.js} +1 -1
  87. package/dist/ionic/{p-f50ae0d5.system.entry.js → p-d754c709.system.entry.js} +1 -1
  88. package/dist/ionic/p-dda5c73d.entry.js +4 -0
  89. package/dist/ionic/{p-9cc3bcc5.system.entry.js → p-f0ab13a8.system.entry.js} +1 -1
  90. package/dist/types/components/input/input.d.ts +3 -0
  91. package/dist/types/components/textarea/textarea.d.ts +3 -0
  92. package/hydrate/index.js +107 -22
  93. package/hydrate/index.mjs +107 -22
  94. package/package.json +1 -1
  95. package/dist/esm-es5/overlays-9c75ec54.js +0 -4
  96. package/dist/ionic/p-0fa0c92b.entry.js +0 -4
  97. package/dist/ionic/p-2c4bdd9d.entry.js +0 -4
  98. package/dist/ionic/p-98871496.system.js +0 -4
  99. package/dist/ionic/p-a440397c.js +0 -4
  100. package/dist/ionic/p-ab8a2ff1.entry.js +0 -4
  101. package/dist/ionic/p-b4c950f8.entry.js +0 -4
  102. package/dist/ionic/p-bfa2e81c.entry.js +0 -4
  103. package/dist/ionic/p-d77e12ca.entry.js +0 -4
package/hydrate/index.js CHANGED
@@ -5014,9 +5014,19 @@ const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts)
5014
5014
  if (overlay.presented) {
5015
5015
  return;
5016
5016
  }
5017
- setRootAriaHidden(true);
5017
+ /**
5018
+ * Due to accessibility guidelines, toasts do not have
5019
+ * focus traps.
5020
+ *
5021
+ * All other overlays should have focus traps to prevent
5022
+ * the keyboard focus from leaving the overlay.
5023
+ */
5024
+ if (overlay.el.tagName !== 'ION-TOAST') {
5025
+ setRootAriaHidden(true);
5026
+ }
5018
5027
  document.body.classList.add(BACKDROP_NO_SCROLL);
5019
- hideOverlaysFromScreenReaders(overlay.el);
5028
+ hideUnderlyingOverlaysFromScreenReaders(overlay.el);
5029
+ hideAnimatingOverlayFromScreenReaders(overlay.el);
5020
5030
  overlay.presented = true;
5021
5031
  overlay.willPresent.emit();
5022
5032
  (_a = overlay.willPresentShorthand) === null || _a === void 0 ? void 0 : _a.emit();
@@ -5056,6 +5066,11 @@ const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts)
5056
5066
  * it would still have aria-hidden on being presented again.
5057
5067
  * Removing it here ensures the overlay is visible to screen
5058
5068
  * readers.
5069
+ *
5070
+ * If this overlay was being presented, then it was hidden
5071
+ * from screen readers during the animation. Now that the
5072
+ * animation is complete, we can reveal the overlay to
5073
+ * screen readers.
5059
5074
  */
5060
5075
  overlay.el.removeAttribute('aria-hidden');
5061
5076
  };
@@ -5113,17 +5128,35 @@ const dismiss = async (overlay, data, role, name, iosLeaveAnimation, mdLeaveAnim
5113
5128
  if (!overlay.presented) {
5114
5129
  return false;
5115
5130
  }
5116
- const lastOverlay = doc !== undefined && getPresentedOverlays(doc).length === 1;
5117
5131
  /**
5118
- * If this is the last visible overlay then
5119
- * we want to re-add the root to the accessibility tree.
5132
+ * For accessibility, toasts lack focus traps and don’t receive
5133
+ * `aria-hidden` on the root element when presented.
5134
+ *
5135
+ * All other overlays use focus traps to keep keyboard focus
5136
+ * within the overlay, setting `aria-hidden` on the root element
5137
+ * to enhance accessibility.
5138
+ *
5139
+ * Therefore, we must remove `aria-hidden` from the root element
5140
+ * when the last non-toast overlay is dismissed.
5120
5141
  */
5121
- if (lastOverlay) {
5142
+ const overlaysNotToast = doc !== undefined ? getPresentedOverlays(doc).filter((o) => o.tagName !== 'ION-TOAST') : [];
5143
+ const lastOverlayNotToast = overlaysNotToast.length === 1 && overlaysNotToast[0].id === overlay.el.id;
5144
+ /**
5145
+ * If this is the last visible overlay that is not a toast
5146
+ * then we want to re-add the root to the accessibility tree.
5147
+ */
5148
+ if (lastOverlayNotToast) {
5122
5149
  setRootAriaHidden(false);
5123
5150
  document.body.classList.remove(BACKDROP_NO_SCROLL);
5124
5151
  }
5125
5152
  overlay.presented = false;
5126
5153
  try {
5154
+ /**
5155
+ * There is no need to show the overlay to screen readers during
5156
+ * the dismiss animation. This is because the overlay will be removed
5157
+ * from the DOM after the animation is complete.
5158
+ */
5159
+ hideAnimatingOverlayFromScreenReaders(overlay.el);
5127
5160
  // Overlay contents should not be clickable during dismiss
5128
5161
  overlay.el.style.setProperty('pointer-events', 'none');
5129
5162
  overlay.willDismiss.emit({ data, role });
@@ -5358,6 +5391,28 @@ const createTriggerController = () => {
5358
5391
  removeClickListener,
5359
5392
  };
5360
5393
  };
5394
+ /**
5395
+ * The overlay that is being animated also needs to hide from screen
5396
+ * readers during its animation. This ensures that assistive technologies
5397
+ * like TalkBack do not announce or interact with the content until the
5398
+ * animation is complete, avoiding confusion for users.
5399
+ *
5400
+ * If the overlay is being presented, it prevents focus rings from appearing
5401
+ * in incorrect positions due to the transition (specifically `transform`
5402
+ * styles), ensuring that when aria-hidden is removed, the focus rings are
5403
+ * correctly displayed in the final location of the elements.
5404
+ *
5405
+ * @param overlay - The overlay that is being animated.
5406
+ */
5407
+ const hideAnimatingOverlayFromScreenReaders = (overlay) => {
5408
+ if (doc === undefined)
5409
+ return;
5410
+ /**
5411
+ * Once the animation is complete, this attribute will be removed.
5412
+ * This is done at the end of the `present` method.
5413
+ */
5414
+ overlay.setAttribute('aria-hidden', 'true');
5415
+ };
5361
5416
  /**
5362
5417
  * Ensure that underlying overlays have aria-hidden if necessary so that screen readers
5363
5418
  * cannot move focus to these elements. Note that we cannot rely on focus/focusin/focusout
@@ -5368,7 +5423,7 @@ const createTriggerController = () => {
5368
5423
  * @param newTopMostOverlay - The overlay that is being presented. Since the overlay has not been
5369
5424
  * fully presented yet at the time this function is called it will not be included in the getPresentedOverlays result.
5370
5425
  */
5371
- const hideOverlaysFromScreenReaders = (newTopMostOverlay) => {
5426
+ const hideUnderlyingOverlaysFromScreenReaders = (newTopMostOverlay) => {
5372
5427
  var _a;
5373
5428
  if (doc === undefined)
5374
5429
  return;
@@ -6551,10 +6606,10 @@ class ActionSheet {
6551
6606
  const headerID = `action-sheet-${overlayIndex}-header`;
6552
6607
  return (hAsync(Host, Object.assign({ key: '7bbd202ca9e19727e7514abbe073687d982f80c3', role: "dialog", "aria-modal": "true", "aria-labelledby": header !== undefined ? headerID : null, tabindex: "-1" }, htmlAttributes, { style: {
6553
6608
  zIndex: `${20000 + this.overlayIndex}`,
6554
- }, class: Object.assign(Object.assign({ [mode]: true }, getClassMap(this.cssClass)), { 'overlay-hidden': true, 'action-sheet-translucent': this.translucent }), onIonActionSheetWillDismiss: this.dispatchCancelHandler, onIonBackdropTap: this.onBackdropTap }), hAsync("ion-backdrop", { key: '23344a9221a2e6720d7b9de5249dc37256cafa7b', tappable: this.backdropDismiss }), hAsync("div", { key: 'd46361bb5cdc32a7922dcf76b566f358a6174bfa', tabindex: "0" }), hAsync("div", { key: '136c3f2e77c8a2eac8e9ae4bb13d735e1d62598d', class: "action-sheet-wrapper ion-overlay-wrapper", ref: (el) => (this.wrapperEl = el) }, hAsync("div", { key: '6168ea8b2be42020b2edeb8ff3a0f3d1254be37a', class: "action-sheet-container" }, hAsync("div", { key: '29b9e6619dc54574733a704d6bf885839151bd84', class: "action-sheet-group", ref: (el) => (this.groupEl = el) }, header !== undefined && (hAsync("div", { key: '536ce764bfddb3816ea3512d90f4acef2ccb8589', id: headerID, class: {
6609
+ }, class: Object.assign(Object.assign({ [mode]: true }, getClassMap(this.cssClass)), { 'overlay-hidden': true, 'action-sheet-translucent': this.translucent }), onIonActionSheetWillDismiss: this.dispatchCancelHandler, onIonBackdropTap: this.onBackdropTap }), hAsync("ion-backdrop", { key: '23344a9221a2e6720d7b9de5249dc37256cafa7b', tappable: this.backdropDismiss }), hAsync("div", { key: 'fbc2ba15549c2ab04e759e82df6e177fd80cc0a6', tabindex: "0", "aria-hidden": "true" }), hAsync("div", { key: '748ee5235d0b4cb26d6f1b7589f77af2e37ad28a', class: "action-sheet-wrapper ion-overlay-wrapper", ref: (el) => (this.wrapperEl = el) }, hAsync("div", { key: '7ce5fa236cf75e9b1e49c4725c9a811078706554', class: "action-sheet-container" }, hAsync("div", { key: 'dc2251f3bcee4a93e3449f09621cbd2b65d329e9', class: "action-sheet-group", ref: (el) => (this.groupEl = el) }, header !== undefined && (hAsync("div", { key: '48d325c8a852f56ed57a9ada1a6709d05ba32ee2', id: headerID, class: {
6555
6610
  'action-sheet-title': true,
6556
6611
  'action-sheet-has-sub-title': this.subHeader !== undefined,
6557
- } }, header, this.subHeader && hAsync("div", { key: '6d888219145824fd36cdfe0d3c8388bbf2769777', class: "action-sheet-sub-title" }, this.subHeader))), buttons.map((b) => (hAsync("button", Object.assign({}, b.htmlAttributes, { type: "button", id: b.id, class: buttonClass$3(b), onClick: () => this.buttonClick(b), disabled: b.disabled }), hAsync("span", { class: "action-sheet-button-inner" }, b.icon && hAsync("ion-icon", { icon: b.icon, "aria-hidden": "true", lazy: false, class: "action-sheet-icon" }), b.text), mode === 'md' && hAsync("ion-ripple-effect", null))))), cancelButton && (hAsync("div", { key: '46f98f0ed5a9bdb3e35feb9ae71c4489c17b7d77', class: "action-sheet-group action-sheet-group-cancel" }, hAsync("button", Object.assign({ key: 'e3c457bced8ad5f692e48de26e65f731fd631b4f' }, cancelButton.htmlAttributes, { type: "button", class: buttonClass$3(cancelButton), onClick: () => this.buttonClick(cancelButton) }), hAsync("span", { key: '4cba6dc559f734ecc852e024959210cd0dd25354', class: "action-sheet-button-inner" }, cancelButton.icon && (hAsync("ion-icon", { key: '9df64989aad1b4d1e75edf4d37ab208965cfe37f', icon: cancelButton.icon, "aria-hidden": "true", lazy: false, class: "action-sheet-icon" })), cancelButton.text), mode === 'md' && hAsync("ion-ripple-effect", { key: '558089275a29177cefdb2e38eefc9b5c8b62872b' })))))), hAsync("div", { key: 'fa4df6e043b00a6e4126dbc71cb344cfc2b2e7bc', tabindex: "0" })));
6612
+ } }, header, this.subHeader && hAsync("div", { key: '66093728052eb67f37a35f3232761ce4a08896f3', class: "action-sheet-sub-title" }, this.subHeader))), buttons.map((b) => (hAsync("button", Object.assign({}, b.htmlAttributes, { type: "button", id: b.id, class: buttonClass$3(b), onClick: () => this.buttonClick(b), disabled: b.disabled }), hAsync("span", { class: "action-sheet-button-inner" }, b.icon && hAsync("ion-icon", { icon: b.icon, "aria-hidden": "true", lazy: false, class: "action-sheet-icon" }), b.text), mode === 'md' && hAsync("ion-ripple-effect", null))))), cancelButton && (hAsync("div", { key: 'f4eb8e3e2885b85af5080df18d0de0bdd1d719de', class: "action-sheet-group action-sheet-group-cancel" }, hAsync("button", Object.assign({ key: '169f4eb09255aba85062baad49ceb151239fbfb7' }, cancelButton.htmlAttributes, { type: "button", class: buttonClass$3(cancelButton), onClick: () => this.buttonClick(cancelButton) }), hAsync("span", { key: '25fb8a466dd67ea94c79cfb4f9965527e1ce6d42', class: "action-sheet-button-inner" }, cancelButton.icon && (hAsync("ion-icon", { key: 'eb5b071e120a2c86afdf967af6a763a43044d1ca', icon: cancelButton.icon, "aria-hidden": "true", lazy: false, class: "action-sheet-icon" })), cancelButton.text), mode === 'md' && hAsync("ion-ripple-effect", { key: '452ad7e1052b2c681e2d98de8193949755ad4d54' })))))), hAsync("div", { key: 'e1cecf280c987c050d9445e2c458b903f153089b', tabindex: "0", "aria-hidden": "true" })));
6558
6613
  }
6559
6614
  get el() { return getElement(this); }
6560
6615
  static get watchers() { return {
@@ -7242,7 +7297,7 @@ class Alert {
7242
7297
  const ariaLabelledBy = header ? hdrId : subHeader ? subHdrId : null;
7243
7298
  return (hAsync(Host, Object.assign({ key: 'c7d53f48b359f2bc3480a2e1ba34948fc9378fb0', role: role, "aria-modal": "true", "aria-labelledby": ariaLabelledBy, "aria-describedby": message !== undefined ? msgId : null, tabindex: "-1" }, htmlAttributes, { style: {
7244
7299
  zIndex: `${20000 + overlayIndex}`,
7245
- }, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'overlay-hidden': true, 'alert-translucent': this.translucent }), onIonAlertWillDismiss: this.dispatchCancelHandler, onIonBackdropTap: this.onBackdropTap }), hAsync("ion-backdrop", { key: '18c7e6b5d63435d9a6a82bda951158e7e1af6e92', tappable: this.backdropDismiss }), hAsync("div", { key: 'e35e1a4b81286976c8a6bab570c986f3196b21f4', tabindex: "0" }), hAsync("div", { key: '9089864c80d96ed834bf723f3de863cf1c4a5b97', class: "alert-wrapper ion-overlay-wrapper", ref: (el) => (this.wrapperEl = el) }, hAsync("div", { key: 'dd600f02c84352059c6cdf98821b9c9a831bcdcb', class: "alert-head" }, header && (hAsync("h2", { key: '11afb605e1ccefc889fbdd2533d491bea8fbf183', id: hdrId, class: "alert-title" }, header)), subHeader && (hAsync("h2", { key: 'e53b0613d09d26e5a2cd7c9c6e63ec2535625ce5', id: subHdrId, class: "alert-sub-title" }, subHeader))), this.renderAlertMessage(msgId), this.renderAlertInputs(), this.renderAlertButtons()), hAsync("div", { key: 'cef60ec8b34c9aec8bc698f16f55324d1ce67c72', tabindex: "0" })));
7300
+ }, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'overlay-hidden': true, 'alert-translucent': this.translucent }), onIonAlertWillDismiss: this.dispatchCancelHandler, onIonBackdropTap: this.onBackdropTap }), hAsync("ion-backdrop", { key: '18c7e6b5d63435d9a6a82bda951158e7e1af6e92', tappable: this.backdropDismiss }), hAsync("div", { key: '8ea08a2a70239e817442c12596f51b108aca428c', tabindex: "0", "aria-hidden": "true" }), hAsync("div", { key: '215ca5d72b8b180788e9748f5f22de01fa5a152a', class: "alert-wrapper ion-overlay-wrapper", ref: (el) => (this.wrapperEl = el) }, hAsync("div", { key: '9880acd318428d4b5d670c67dd156477877f99f2', class: "alert-head" }, header && (hAsync("h2", { key: '612dec8dc9bfdcb36e1e4655dc214b7c229b20c8', id: hdrId, class: "alert-title" }, header)), subHeader && (hAsync("h2", { key: 'e3c54c80a1cd9399595064b5a0a887c16fdc8ff8', id: subHdrId, class: "alert-sub-title" }, subHeader))), this.renderAlertMessage(msgId), this.renderAlertInputs(), this.renderAlertButtons()), hAsync("div", { key: '9062655e906b5caf36df6f742fd412552ae510be', tabindex: "0", "aria-hidden": "true" })));
7246
7301
  }
7247
7302
  get el() { return getElement(this); }
7248
7303
  static get watchers() { return {
@@ -7502,7 +7557,7 @@ class Backdrop {
7502
7557
  }
7503
7558
  render() {
7504
7559
  const mode = getIonMode$1(this);
7505
- return (hAsync(Host, { key: 'c803b4302c8e722064feb03dafe3cb6e190b4f2b', tabindex: "-1", "aria-hidden": "true", class: {
7560
+ return (hAsync(Host, { key: 'fe191068e2aaadfdbe7a463c08d227a1b36d7a98', "aria-hidden": "true", class: {
7506
7561
  [mode]: true,
7507
7562
  'backdrop-hide': !this.visible,
7508
7563
  'backdrop-no-tappable': !this.tappable,
@@ -14961,6 +15016,8 @@ class Input {
14961
15016
  this.ionBlur = createEvent(this, "ionBlur", 7);
14962
15017
  this.ionFocus = createEvent(this, "ionFocus", 7);
14963
15018
  this.inputId = `ion-input-${inputIds++}`;
15019
+ this.helperTextId = `${this.inputId}-helper-text`;
15020
+ this.errorTextId = `${this.inputId}-error-text`;
14964
15021
  this.inheritedAttributes = {};
14965
15022
  this.isComposing = false;
14966
15023
  /**
@@ -15223,8 +15280,21 @@ class Input {
15223
15280
  * Renders the helper text or error text values
15224
15281
  */
15225
15282
  renderHintText() {
15226
- const { helperText, errorText } = this;
15227
- return [hAsync("div", { class: "helper-text" }, helperText), hAsync("div", { class: "error-text" }, errorText)];
15283
+ const { helperText, errorText, helperTextId, errorTextId } = this;
15284
+ return [
15285
+ hAsync("div", { id: helperTextId, class: "helper-text" }, helperText),
15286
+ hAsync("div", { id: errorTextId, class: "error-text" }, errorText),
15287
+ ];
15288
+ }
15289
+ getHintTextID() {
15290
+ const { el, helperText, errorText, helperTextId, errorTextId } = this;
15291
+ if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
15292
+ return errorTextId;
15293
+ }
15294
+ if (helperText) {
15295
+ return helperTextId;
15296
+ }
15297
+ return undefined;
15228
15298
  }
15229
15299
  renderCounter() {
15230
15300
  const { counter, maxlength, counterFormatter, value } = this;
@@ -15331,7 +15401,7 @@ class Input {
15331
15401
  * TODO(FW-5592): Remove hasStartEndSlots condition
15332
15402
  */
15333
15403
  const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
15334
- return (hAsync(Host, { key: '907ce98a82b5cfae5a08504cd79e00a2330b7444', class: createColorClasses$1(this.color, {
15404
+ return (hAsync(Host, { key: 'cdde9963d71685e6a4f3f3b3bc52e75d022435cb', class: createColorClasses$1(this.color, {
15335
15405
  [mode]: true,
15336
15406
  'has-value': hasValue,
15337
15407
  'has-focus': hasFocus,
@@ -15342,7 +15412,7 @@ class Input {
15342
15412
  'in-item': inItem,
15343
15413
  'in-item-color': hostContext('ion-item.ion-color', this.el),
15344
15414
  'input-disabled': disabled,
15345
- }) }, hAsync("label", { key: '59d5bb45d2a5b828bba0ed8687a632a551e2f4d8', class: "input-wrapper", htmlFor: inputId }, this.renderLabelContainer(), hAsync("div", { key: 'f93f129d08246d0e9a601c100d718534d6403853', class: "native-wrapper" }, hAsync("slot", { key: '54eeb1a6bace662b7eb0d7e27180ea3d7e3a3729', name: "start" }), hAsync("input", Object.assign({ key: 'b3e0be55bc1a4a539ae3b0fdcf7fc078723cca16', class: "native-input", ref: (input) => (this.nativeInput = input), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoComplete: this.autocomplete, autoCorrect: this.autocorrect, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, min: this.min, max: this.max, minLength: this.minlength, maxLength: this.maxlength, multiple: this.multiple, name: this.name, pattern: this.pattern, placeholder: this.placeholder || '', readOnly: readonly, required: this.required, spellcheck: this.spellcheck, step: this.step, type: this.type, value: value, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeydown, onCompositionstart: this.onCompositionStart, onCompositionend: this.onCompositionEnd }, this.inheritedAttributes)), this.clearInput && !readonly && !disabled && (hAsync("button", { key: '5f6373504a6d0d074bfbf875c794d45ea2748175', "aria-label": "reset", type: "button", class: "input-clear-icon", onPointerDown: (ev) => {
15415
+ }) }, hAsync("label", { key: '4412791c93405f20e50e50363879265180b6078f', class: "input-wrapper", htmlFor: inputId }, this.renderLabelContainer(), hAsync("div", { key: '5c71c43ef3eeb44dde76ed64ce10763834c8fbc7', class: "native-wrapper" }, hAsync("slot", { key: '1d86b58dc299a4208dd02ccdc9ceaea7576698c3', name: "start" }), hAsync("input", Object.assign({ key: '7fc932174485f7d09e6a797dfd49ea11fbad71b6', class: "native-input", ref: (input) => (this.nativeInput = input), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoComplete: this.autocomplete, autoCorrect: this.autocorrect, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, min: this.min, max: this.max, minLength: this.minlength, maxLength: this.maxlength, multiple: this.multiple, name: this.name, pattern: this.pattern, placeholder: this.placeholder || '', readOnly: readonly, required: this.required, spellcheck: this.spellcheck, step: this.step, type: this.type, value: value, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeydown, onCompositionstart: this.onCompositionStart, onCompositionend: this.onCompositionEnd, "aria-describedby": this.getHintTextID(), "aria-invalid": this.getHintTextID() === this.errorTextId }, this.inheritedAttributes)), this.clearInput && !readonly && !disabled && (hAsync("button", { key: '46de455e4e308b8d7640b04778f7c7559b4124c6', "aria-label": "reset", type: "button", class: "input-clear-icon", onPointerDown: (ev) => {
15346
15416
  /**
15347
15417
  * This prevents mobile browsers from
15348
15418
  * blurring the input when the clear
@@ -15357,7 +15427,7 @@ class Input {
15357
15427
  * for screen readers as it means users would be unable to swipe past the clear button.
15358
15428
  */
15359
15429
  ev.stopPropagation();
15360
- }, onClick: this.clearTextInput }, hAsync("ion-icon", { key: '230d77973aa83458ceb32bf52e3abe9bc322cfe6', "aria-hidden": "true", icon: clearIconData }))), hAsync("slot", { key: '9d69ac6e8a3c4b2b303dba2478f82695d5755ed2', name: "end" })), shouldRenderHighlight && hAsync("div", { key: 'ac61f16237ce731e0745ab72d0fc3f066252464a', class: "input-highlight" })), this.renderBottomContent()));
15430
+ }, onClick: this.clearTextInput }, hAsync("ion-icon", { key: '375e860a20e1807ce0db0e1934a0650fe9929966', "aria-hidden": "true", icon: clearIconData }))), hAsync("slot", { key: '859d47a1b88aa8377479e5d11e52a6a1c1c30e7e', name: "end" })), shouldRenderHighlight && hAsync("div", { key: 'd2d4286b348107e33247b5c0afda0f8bd697ecee', class: "input-highlight" })), this.renderBottomContent()));
15361
15431
  }
15362
15432
  get el() { return getElement(this); }
15363
15433
  static get watchers() { return {
@@ -16893,7 +16963,7 @@ class Loading {
16893
16963
  const ariaLabelledBy = message !== undefined ? msgId : null;
16894
16964
  return (hAsync(Host, Object.assign({ key: 'fb3d2cd7cd0539ed6540d8be50e243c7916b3ca2', role: "dialog", "aria-modal": "true", "aria-labelledby": ariaLabelledBy, tabindex: "-1" }, htmlAttributes, { style: {
16895
16965
  zIndex: `${40000 + this.overlayIndex}`,
16896
- }, onIonBackdropTap: this.onBackdropTap, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'overlay-hidden': true, 'loading-translucent': this.translucent }) }), hAsync("ion-backdrop", { key: 'c8bd30782f3040b1b80e88aa924861e439d40754', visible: this.showBackdrop, tappable: this.backdropDismiss }), hAsync("div", { key: '4ebfbb67c92e8eb56c27dd7c199b35bf6be1cf63', tabindex: "0" }), hAsync("div", { key: '9492723cd87f1ef75534e449d4bc2b2deb0cb3cc', class: "loading-wrapper ion-overlay-wrapper" }, spinner && (hAsync("div", { key: 'd9eb42454e48c82704d974a68b80ceb4de990417', class: "loading-spinner" }, hAsync("ion-spinner", { key: 'cdb046bad89872f4208ae466979315652766bf3a', name: spinner, "aria-hidden": "true" }))), message !== undefined && this.renderLoadingMessage(msgId)), hAsync("div", { key: '412d1bb537dafa6e6863d07ddc15f5969fe0617d', tabindex: "0" })));
16966
+ }, onIonBackdropTap: this.onBackdropTap, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'overlay-hidden': true, 'loading-translucent': this.translucent }) }), hAsync("ion-backdrop", { key: 'c8bd30782f3040b1b80e88aa924861e439d40754', visible: this.showBackdrop, tappable: this.backdropDismiss }), hAsync("div", { key: '7ad4447fafa49aa861d311221b8c2e8171b4c610', tabindex: "0", "aria-hidden": "true" }), hAsync("div", { key: '1879df0d895eb8ee20ccdc94dd35d708c1140b91', class: "loading-wrapper ion-overlay-wrapper" }, spinner && (hAsync("div", { key: '220f292c136681f5fa91f94669aac75b15e490ce', class: "loading-spinner" }, hAsync("ion-spinner", { key: 'd599084a1426d941bdd080a988d8ad5b9589b823', name: spinner, "aria-hidden": "true" }))), message !== undefined && this.renderLoadingMessage(msgId)), hAsync("div", { key: 'e443897b353a48e0c72718dba04d83d7c5070d73', tabindex: "0", "aria-hidden": "true" })));
16897
16967
  }
16898
16968
  get el() { return getElement(this); }
16899
16969
  static get watchers() { return {
@@ -21887,7 +21957,7 @@ class Picker {
21887
21957
  zIndex: `${20000 + this.overlayIndex}`,
21888
21958
  }, class: Object.assign({ [mode]: true,
21889
21959
  // Used internally for styling
21890
- [`picker-${mode}`]: true, 'overlay-hidden': true }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonPickerWillDismiss: this.dispatchCancelHandler }), hAsync("ion-backdrop", { key: 'da4224447bdbcfbadd1bd63ebe7a7bfdb8aa3129', visible: this.showBackdrop, tappable: this.backdropDismiss }), hAsync("div", { key: '211475c859b7acf4d64556905c45993201d92d43', tabindex: "0" }), hAsync("div", { key: 'c3b3674038155809caea84ae6348ff0d66897a64', class: "picker-wrapper ion-overlay-wrapper", role: "dialog" }, hAsync("div", { key: 'a21757da70dc7864945a5751d9da3ca4bf87897b', class: "picker-toolbar" }, this.buttons.map((b) => (hAsync("div", { class: buttonWrapperClass(b) }, hAsync("button", { type: "button", onClick: () => this.buttonClick(b), class: buttonClass$1(b) }, b.text))))), hAsync("div", { key: '0220da1854d09ef22d2d9a32eaa3c3b222be5a0a', class: "picker-columns" }, hAsync("div", { key: '55757c165ba9e38e56b4dee76a9b13d3ff8b21e6', class: "picker-above-highlight" }), this.presented && this.columns.map((c) => hAsync("ion-picker-legacy-column", { col: c })), hAsync("div", { key: '160092a46a48287bf75e5dfe3502f1755a2d0c70', class: "picker-below-highlight" }))), hAsync("div", { key: 'e212db6cca7d75fc0eda0baf4312dd51b9b7a4ef', tabindex: "0" })));
21960
+ [`picker-${mode}`]: true, 'overlay-hidden': true }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonPickerWillDismiss: this.dispatchCancelHandler }), hAsync("ion-backdrop", { key: 'da4224447bdbcfbadd1bd63ebe7a7bfdb8aa3129', visible: this.showBackdrop, tappable: this.backdropDismiss }), hAsync("div", { key: '65eba425990a21be00fdac90de20a630d284cf97', tabindex: "0", "aria-hidden": "true" }), hAsync("div", { key: 'd78ada360801b2c051baa030751f3d83ac81e697', class: "picker-wrapper ion-overlay-wrapper", role: "dialog" }, hAsync("div", { key: 'd5bd9ddfbdbdaf42048a1496e7939eb3aee6da65', class: "picker-toolbar" }, this.buttons.map((b) => (hAsync("div", { class: buttonWrapperClass(b) }, hAsync("button", { type: "button", onClick: () => this.buttonClick(b), class: buttonClass$1(b) }, b.text))))), hAsync("div", { key: '96ee1e3ec77c57174b1a93135b66bea6b7002555', class: "picker-columns" }, hAsync("div", { key: 'e11b1c238f350e65bde2ee67eee9d71c830e74e7', class: "picker-above-highlight" }), this.presented && this.columns.map((c) => hAsync("ion-picker-legacy-column", { col: c })), hAsync("div", { key: '4d5fc7c723185111ec01fd34ef95a897c301238d', class: "picker-below-highlight" }))), hAsync("div", { key: '899bcad97609c1d971c1b886551db5ba0248a9f4', tabindex: "0", "aria-hidden": "true" })));
21891
21961
  }
21892
21962
  get el() { return getElement(this); }
21893
21963
  static get watchers() { return {
@@ -30704,6 +30774,8 @@ class Textarea {
30704
30774
  this.ionBlur = createEvent(this, "ionBlur", 7);
30705
30775
  this.ionFocus = createEvent(this, "ionFocus", 7);
30706
30776
  this.inputId = `ion-textarea-${textareaIds++}`;
30777
+ this.helperTextId = `${this.inputId}-helper-text`;
30778
+ this.errorTextId = `${this.inputId}-error-text`;
30707
30779
  /**
30708
30780
  * `true` if the textarea was cleared as a result of the user typing
30709
30781
  * with `clearOnEdit` enabled.
@@ -30981,8 +31053,21 @@ class Textarea {
30981
31053
  * Renders the helper text or error text values
30982
31054
  */
30983
31055
  renderHintText() {
30984
- const { helperText, errorText } = this;
30985
- return [hAsync("div", { class: "helper-text" }, helperText), hAsync("div", { class: "error-text" }, errorText)];
31056
+ const { helperText, errorText, helperTextId, errorTextId } = this;
31057
+ return [
31058
+ hAsync("div", { id: helperTextId, class: "helper-text" }, helperText),
31059
+ hAsync("div", { id: errorTextId, class: "error-text" }, errorText),
31060
+ ];
31061
+ }
31062
+ getHintTextID() {
31063
+ const { el, helperText, errorText, helperTextId, errorTextId } = this;
31064
+ if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
31065
+ return errorTextId;
31066
+ }
31067
+ if (helperText) {
31068
+ return helperTextId;
31069
+ }
31070
+ return undefined;
30986
31071
  }
30987
31072
  renderCounter() {
30988
31073
  const { counter, maxlength, counterFormatter, value } = this;
@@ -31035,7 +31120,7 @@ class Textarea {
31035
31120
  * TODO(FW-5592): Remove hasStartEndSlots condition
31036
31121
  */
31037
31122
  const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
31038
- return (hAsync(Host, { key: '37595a18d77dea1a337ac1c672e5f08a4128111d', class: createColorClasses$1(this.color, {
31123
+ return (hAsync(Host, { key: 'e8a5b5727c6a018bbd6f5507b690bc5f0959e352', class: createColorClasses$1(this.color, {
31039
31124
  [mode]: true,
31040
31125
  'has-value': hasValue,
31041
31126
  'has-focus': hasFocus,
@@ -31044,7 +31129,7 @@ class Textarea {
31044
31129
  [`textarea-shape-${shape}`]: shape !== undefined,
31045
31130
  [`textarea-label-placement-${labelPlacement}`]: true,
31046
31131
  'textarea-disabled': disabled,
31047
- }) }, hAsync("label", { key: '67342758743e5a40448a32ff695876d39778621f', class: "textarea-wrapper", htmlFor: inputId }, this.renderLabelContainer(), hAsync("div", { key: 'a994be8264bf5652811cf816d79a04178954e83f', class: "textarea-wrapper-inner" }, hAsync("div", { key: 'e09c93ebcd5b3d227d51e682ca23dfc7fd7027ad', class: "start-slot-wrapper" }, hAsync("slot", { key: 'd39758f21f19ae70aea21e9a9a7b7c20991fe593', name: "start" })), hAsync("div", { key: '6a4e10e53de4bb235ee30def4c9ae5bdee888816', class: "native-wrapper", ref: (el) => (this.textareaWrapper = el) }, hAsync("textarea", Object.assign({ key: '9e254e551f124d972e9bc6b09ef0f2bb55890be5', class: "native-textarea", ref: (el) => (this.nativeInput = el), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, minLength: this.minlength, maxLength: this.maxlength, name: this.name, placeholder: this.placeholder || '', readOnly: this.readonly, required: this.required, spellcheck: this.spellcheck, cols: this.cols, rows: this.rows, wrap: this.wrap, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeyDown }, this.inheritedAttributes), value)), hAsync("div", { key: 'a66aa2d2bc4778a0bec56a8b9ec9052a832eb3b2', class: "end-slot-wrapper" }, hAsync("slot", { key: '8e6a90b4475de32e23afc593da4108610dcca663', name: "end" }))), shouldRenderHighlight && hAsync("div", { key: '6da03205a8daff45581b20f0af3938634a9d5f8c', class: "textarea-highlight" })), this.renderBottomContent()));
31132
+ }) }, hAsync("label", { key: '48e889571e2d3e7e150b038e4b4b15862b418288', class: "textarea-wrapper", htmlFor: inputId }, this.renderLabelContainer(), hAsync("div", { key: '6c6c7872ae4d351d8b8d772ad18ce3ba7a0e9a87', class: "textarea-wrapper-inner" }, hAsync("div", { key: '03aef5dfa59af0fa78a3e5c92e0ed72396717d72', class: "start-slot-wrapper" }, hAsync("slot", { key: '39aee9faebb0f1d10de5a5817fd9d9771b074b96', name: "start" })), hAsync("div", { key: '738e8ff603f4c9b9083b3139db861f4b7ec20f79', class: "native-wrapper", ref: (el) => (this.textareaWrapper = el) }, hAsync("textarea", Object.assign({ key: '7763fb4f8ffe94635167331c70d21d661544c4f8', class: "native-textarea", ref: (el) => (this.nativeInput = el), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, minLength: this.minlength, maxLength: this.maxlength, name: this.name, placeholder: this.placeholder || '', readOnly: this.readonly, required: this.required, spellcheck: this.spellcheck, cols: this.cols, rows: this.rows, wrap: this.wrap, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeyDown, "aria-describedby": this.getHintTextID(), "aria-invalid": this.getHintTextID() === this.errorTextId }, this.inheritedAttributes), value)), hAsync("div", { key: 'b3af9ec0982c6dbd381afaa02df153d7e90471be', class: "end-slot-wrapper" }, hAsync("slot", { key: '60f99bcd49a5ec2e1fa6e3e77809aefeb9d2d0d6', name: "end" }))), shouldRenderHighlight && hAsync("div", { key: '6a7f45639ba027f4da573adae53f1197a6dec383', class: "textarea-highlight" })), this.renderBottomContent()));
31048
31133
  }
31049
31134
  get el() { return getElement(this); }
31050
31135
  static get watchers() { return {
package/hydrate/index.mjs CHANGED
@@ -5010,9 +5010,19 @@ const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts)
5010
5010
  if (overlay.presented) {
5011
5011
  return;
5012
5012
  }
5013
- setRootAriaHidden(true);
5013
+ /**
5014
+ * Due to accessibility guidelines, toasts do not have
5015
+ * focus traps.
5016
+ *
5017
+ * All other overlays should have focus traps to prevent
5018
+ * the keyboard focus from leaving the overlay.
5019
+ */
5020
+ if (overlay.el.tagName !== 'ION-TOAST') {
5021
+ setRootAriaHidden(true);
5022
+ }
5014
5023
  document.body.classList.add(BACKDROP_NO_SCROLL);
5015
- hideOverlaysFromScreenReaders(overlay.el);
5024
+ hideUnderlyingOverlaysFromScreenReaders(overlay.el);
5025
+ hideAnimatingOverlayFromScreenReaders(overlay.el);
5016
5026
  overlay.presented = true;
5017
5027
  overlay.willPresent.emit();
5018
5028
  (_a = overlay.willPresentShorthand) === null || _a === void 0 ? void 0 : _a.emit();
@@ -5052,6 +5062,11 @@ const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts)
5052
5062
  * it would still have aria-hidden on being presented again.
5053
5063
  * Removing it here ensures the overlay is visible to screen
5054
5064
  * readers.
5065
+ *
5066
+ * If this overlay was being presented, then it was hidden
5067
+ * from screen readers during the animation. Now that the
5068
+ * animation is complete, we can reveal the overlay to
5069
+ * screen readers.
5055
5070
  */
5056
5071
  overlay.el.removeAttribute('aria-hidden');
5057
5072
  };
@@ -5109,17 +5124,35 @@ const dismiss = async (overlay, data, role, name, iosLeaveAnimation, mdLeaveAnim
5109
5124
  if (!overlay.presented) {
5110
5125
  return false;
5111
5126
  }
5112
- const lastOverlay = doc !== undefined && getPresentedOverlays(doc).length === 1;
5113
5127
  /**
5114
- * If this is the last visible overlay then
5115
- * we want to re-add the root to the accessibility tree.
5128
+ * For accessibility, toasts lack focus traps and don’t receive
5129
+ * `aria-hidden` on the root element when presented.
5130
+ *
5131
+ * All other overlays use focus traps to keep keyboard focus
5132
+ * within the overlay, setting `aria-hidden` on the root element
5133
+ * to enhance accessibility.
5134
+ *
5135
+ * Therefore, we must remove `aria-hidden` from the root element
5136
+ * when the last non-toast overlay is dismissed.
5116
5137
  */
5117
- if (lastOverlay) {
5138
+ const overlaysNotToast = doc !== undefined ? getPresentedOverlays(doc).filter((o) => o.tagName !== 'ION-TOAST') : [];
5139
+ const lastOverlayNotToast = overlaysNotToast.length === 1 && overlaysNotToast[0].id === overlay.el.id;
5140
+ /**
5141
+ * If this is the last visible overlay that is not a toast
5142
+ * then we want to re-add the root to the accessibility tree.
5143
+ */
5144
+ if (lastOverlayNotToast) {
5118
5145
  setRootAriaHidden(false);
5119
5146
  document.body.classList.remove(BACKDROP_NO_SCROLL);
5120
5147
  }
5121
5148
  overlay.presented = false;
5122
5149
  try {
5150
+ /**
5151
+ * There is no need to show the overlay to screen readers during
5152
+ * the dismiss animation. This is because the overlay will be removed
5153
+ * from the DOM after the animation is complete.
5154
+ */
5155
+ hideAnimatingOverlayFromScreenReaders(overlay.el);
5123
5156
  // Overlay contents should not be clickable during dismiss
5124
5157
  overlay.el.style.setProperty('pointer-events', 'none');
5125
5158
  overlay.willDismiss.emit({ data, role });
@@ -5354,6 +5387,28 @@ const createTriggerController = () => {
5354
5387
  removeClickListener,
5355
5388
  };
5356
5389
  };
5390
+ /**
5391
+ * The overlay that is being animated also needs to hide from screen
5392
+ * readers during its animation. This ensures that assistive technologies
5393
+ * like TalkBack do not announce or interact with the content until the
5394
+ * animation is complete, avoiding confusion for users.
5395
+ *
5396
+ * If the overlay is being presented, it prevents focus rings from appearing
5397
+ * in incorrect positions due to the transition (specifically `transform`
5398
+ * styles), ensuring that when aria-hidden is removed, the focus rings are
5399
+ * correctly displayed in the final location of the elements.
5400
+ *
5401
+ * @param overlay - The overlay that is being animated.
5402
+ */
5403
+ const hideAnimatingOverlayFromScreenReaders = (overlay) => {
5404
+ if (doc === undefined)
5405
+ return;
5406
+ /**
5407
+ * Once the animation is complete, this attribute will be removed.
5408
+ * This is done at the end of the `present` method.
5409
+ */
5410
+ overlay.setAttribute('aria-hidden', 'true');
5411
+ };
5357
5412
  /**
5358
5413
  * Ensure that underlying overlays have aria-hidden if necessary so that screen readers
5359
5414
  * cannot move focus to these elements. Note that we cannot rely on focus/focusin/focusout
@@ -5364,7 +5419,7 @@ const createTriggerController = () => {
5364
5419
  * @param newTopMostOverlay - The overlay that is being presented. Since the overlay has not been
5365
5420
  * fully presented yet at the time this function is called it will not be included in the getPresentedOverlays result.
5366
5421
  */
5367
- const hideOverlaysFromScreenReaders = (newTopMostOverlay) => {
5422
+ const hideUnderlyingOverlaysFromScreenReaders = (newTopMostOverlay) => {
5368
5423
  var _a;
5369
5424
  if (doc === undefined)
5370
5425
  return;
@@ -6547,10 +6602,10 @@ class ActionSheet {
6547
6602
  const headerID = `action-sheet-${overlayIndex}-header`;
6548
6603
  return (hAsync(Host, Object.assign({ key: '7bbd202ca9e19727e7514abbe073687d982f80c3', role: "dialog", "aria-modal": "true", "aria-labelledby": header !== undefined ? headerID : null, tabindex: "-1" }, htmlAttributes, { style: {
6549
6604
  zIndex: `${20000 + this.overlayIndex}`,
6550
- }, class: Object.assign(Object.assign({ [mode]: true }, getClassMap(this.cssClass)), { 'overlay-hidden': true, 'action-sheet-translucent': this.translucent }), onIonActionSheetWillDismiss: this.dispatchCancelHandler, onIonBackdropTap: this.onBackdropTap }), hAsync("ion-backdrop", { key: '23344a9221a2e6720d7b9de5249dc37256cafa7b', tappable: this.backdropDismiss }), hAsync("div", { key: 'd46361bb5cdc32a7922dcf76b566f358a6174bfa', tabindex: "0" }), hAsync("div", { key: '136c3f2e77c8a2eac8e9ae4bb13d735e1d62598d', class: "action-sheet-wrapper ion-overlay-wrapper", ref: (el) => (this.wrapperEl = el) }, hAsync("div", { key: '6168ea8b2be42020b2edeb8ff3a0f3d1254be37a', class: "action-sheet-container" }, hAsync("div", { key: '29b9e6619dc54574733a704d6bf885839151bd84', class: "action-sheet-group", ref: (el) => (this.groupEl = el) }, header !== undefined && (hAsync("div", { key: '536ce764bfddb3816ea3512d90f4acef2ccb8589', id: headerID, class: {
6605
+ }, class: Object.assign(Object.assign({ [mode]: true }, getClassMap(this.cssClass)), { 'overlay-hidden': true, 'action-sheet-translucent': this.translucent }), onIonActionSheetWillDismiss: this.dispatchCancelHandler, onIonBackdropTap: this.onBackdropTap }), hAsync("ion-backdrop", { key: '23344a9221a2e6720d7b9de5249dc37256cafa7b', tappable: this.backdropDismiss }), hAsync("div", { key: 'fbc2ba15549c2ab04e759e82df6e177fd80cc0a6', tabindex: "0", "aria-hidden": "true" }), hAsync("div", { key: '748ee5235d0b4cb26d6f1b7589f77af2e37ad28a', class: "action-sheet-wrapper ion-overlay-wrapper", ref: (el) => (this.wrapperEl = el) }, hAsync("div", { key: '7ce5fa236cf75e9b1e49c4725c9a811078706554', class: "action-sheet-container" }, hAsync("div", { key: 'dc2251f3bcee4a93e3449f09621cbd2b65d329e9', class: "action-sheet-group", ref: (el) => (this.groupEl = el) }, header !== undefined && (hAsync("div", { key: '48d325c8a852f56ed57a9ada1a6709d05ba32ee2', id: headerID, class: {
6551
6606
  'action-sheet-title': true,
6552
6607
  'action-sheet-has-sub-title': this.subHeader !== undefined,
6553
- } }, header, this.subHeader && hAsync("div", { key: '6d888219145824fd36cdfe0d3c8388bbf2769777', class: "action-sheet-sub-title" }, this.subHeader))), buttons.map((b) => (hAsync("button", Object.assign({}, b.htmlAttributes, { type: "button", id: b.id, class: buttonClass$3(b), onClick: () => this.buttonClick(b), disabled: b.disabled }), hAsync("span", { class: "action-sheet-button-inner" }, b.icon && hAsync("ion-icon", { icon: b.icon, "aria-hidden": "true", lazy: false, class: "action-sheet-icon" }), b.text), mode === 'md' && hAsync("ion-ripple-effect", null))))), cancelButton && (hAsync("div", { key: '46f98f0ed5a9bdb3e35feb9ae71c4489c17b7d77', class: "action-sheet-group action-sheet-group-cancel" }, hAsync("button", Object.assign({ key: 'e3c457bced8ad5f692e48de26e65f731fd631b4f' }, cancelButton.htmlAttributes, { type: "button", class: buttonClass$3(cancelButton), onClick: () => this.buttonClick(cancelButton) }), hAsync("span", { key: '4cba6dc559f734ecc852e024959210cd0dd25354', class: "action-sheet-button-inner" }, cancelButton.icon && (hAsync("ion-icon", { key: '9df64989aad1b4d1e75edf4d37ab208965cfe37f', icon: cancelButton.icon, "aria-hidden": "true", lazy: false, class: "action-sheet-icon" })), cancelButton.text), mode === 'md' && hAsync("ion-ripple-effect", { key: '558089275a29177cefdb2e38eefc9b5c8b62872b' })))))), hAsync("div", { key: 'fa4df6e043b00a6e4126dbc71cb344cfc2b2e7bc', tabindex: "0" })));
6608
+ } }, header, this.subHeader && hAsync("div", { key: '66093728052eb67f37a35f3232761ce4a08896f3', class: "action-sheet-sub-title" }, this.subHeader))), buttons.map((b) => (hAsync("button", Object.assign({}, b.htmlAttributes, { type: "button", id: b.id, class: buttonClass$3(b), onClick: () => this.buttonClick(b), disabled: b.disabled }), hAsync("span", { class: "action-sheet-button-inner" }, b.icon && hAsync("ion-icon", { icon: b.icon, "aria-hidden": "true", lazy: false, class: "action-sheet-icon" }), b.text), mode === 'md' && hAsync("ion-ripple-effect", null))))), cancelButton && (hAsync("div", { key: 'f4eb8e3e2885b85af5080df18d0de0bdd1d719de', class: "action-sheet-group action-sheet-group-cancel" }, hAsync("button", Object.assign({ key: '169f4eb09255aba85062baad49ceb151239fbfb7' }, cancelButton.htmlAttributes, { type: "button", class: buttonClass$3(cancelButton), onClick: () => this.buttonClick(cancelButton) }), hAsync("span", { key: '25fb8a466dd67ea94c79cfb4f9965527e1ce6d42', class: "action-sheet-button-inner" }, cancelButton.icon && (hAsync("ion-icon", { key: 'eb5b071e120a2c86afdf967af6a763a43044d1ca', icon: cancelButton.icon, "aria-hidden": "true", lazy: false, class: "action-sheet-icon" })), cancelButton.text), mode === 'md' && hAsync("ion-ripple-effect", { key: '452ad7e1052b2c681e2d98de8193949755ad4d54' })))))), hAsync("div", { key: 'e1cecf280c987c050d9445e2c458b903f153089b', tabindex: "0", "aria-hidden": "true" })));
6554
6609
  }
6555
6610
  get el() { return getElement(this); }
6556
6611
  static get watchers() { return {
@@ -7238,7 +7293,7 @@ class Alert {
7238
7293
  const ariaLabelledBy = header ? hdrId : subHeader ? subHdrId : null;
7239
7294
  return (hAsync(Host, Object.assign({ key: 'c7d53f48b359f2bc3480a2e1ba34948fc9378fb0', role: role, "aria-modal": "true", "aria-labelledby": ariaLabelledBy, "aria-describedby": message !== undefined ? msgId : null, tabindex: "-1" }, htmlAttributes, { style: {
7240
7295
  zIndex: `${20000 + overlayIndex}`,
7241
- }, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'overlay-hidden': true, 'alert-translucent': this.translucent }), onIonAlertWillDismiss: this.dispatchCancelHandler, onIonBackdropTap: this.onBackdropTap }), hAsync("ion-backdrop", { key: '18c7e6b5d63435d9a6a82bda951158e7e1af6e92', tappable: this.backdropDismiss }), hAsync("div", { key: 'e35e1a4b81286976c8a6bab570c986f3196b21f4', tabindex: "0" }), hAsync("div", { key: '9089864c80d96ed834bf723f3de863cf1c4a5b97', class: "alert-wrapper ion-overlay-wrapper", ref: (el) => (this.wrapperEl = el) }, hAsync("div", { key: 'dd600f02c84352059c6cdf98821b9c9a831bcdcb', class: "alert-head" }, header && (hAsync("h2", { key: '11afb605e1ccefc889fbdd2533d491bea8fbf183', id: hdrId, class: "alert-title" }, header)), subHeader && (hAsync("h2", { key: 'e53b0613d09d26e5a2cd7c9c6e63ec2535625ce5', id: subHdrId, class: "alert-sub-title" }, subHeader))), this.renderAlertMessage(msgId), this.renderAlertInputs(), this.renderAlertButtons()), hAsync("div", { key: 'cef60ec8b34c9aec8bc698f16f55324d1ce67c72', tabindex: "0" })));
7296
+ }, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'overlay-hidden': true, 'alert-translucent': this.translucent }), onIonAlertWillDismiss: this.dispatchCancelHandler, onIonBackdropTap: this.onBackdropTap }), hAsync("ion-backdrop", { key: '18c7e6b5d63435d9a6a82bda951158e7e1af6e92', tappable: this.backdropDismiss }), hAsync("div", { key: '8ea08a2a70239e817442c12596f51b108aca428c', tabindex: "0", "aria-hidden": "true" }), hAsync("div", { key: '215ca5d72b8b180788e9748f5f22de01fa5a152a', class: "alert-wrapper ion-overlay-wrapper", ref: (el) => (this.wrapperEl = el) }, hAsync("div", { key: '9880acd318428d4b5d670c67dd156477877f99f2', class: "alert-head" }, header && (hAsync("h2", { key: '612dec8dc9bfdcb36e1e4655dc214b7c229b20c8', id: hdrId, class: "alert-title" }, header)), subHeader && (hAsync("h2", { key: 'e3c54c80a1cd9399595064b5a0a887c16fdc8ff8', id: subHdrId, class: "alert-sub-title" }, subHeader))), this.renderAlertMessage(msgId), this.renderAlertInputs(), this.renderAlertButtons()), hAsync("div", { key: '9062655e906b5caf36df6f742fd412552ae510be', tabindex: "0", "aria-hidden": "true" })));
7242
7297
  }
7243
7298
  get el() { return getElement(this); }
7244
7299
  static get watchers() { return {
@@ -7498,7 +7553,7 @@ class Backdrop {
7498
7553
  }
7499
7554
  render() {
7500
7555
  const mode = getIonMode$1(this);
7501
- return (hAsync(Host, { key: 'c803b4302c8e722064feb03dafe3cb6e190b4f2b', tabindex: "-1", "aria-hidden": "true", class: {
7556
+ return (hAsync(Host, { key: 'fe191068e2aaadfdbe7a463c08d227a1b36d7a98', "aria-hidden": "true", class: {
7502
7557
  [mode]: true,
7503
7558
  'backdrop-hide': !this.visible,
7504
7559
  'backdrop-no-tappable': !this.tappable,
@@ -14957,6 +15012,8 @@ class Input {
14957
15012
  this.ionBlur = createEvent(this, "ionBlur", 7);
14958
15013
  this.ionFocus = createEvent(this, "ionFocus", 7);
14959
15014
  this.inputId = `ion-input-${inputIds++}`;
15015
+ this.helperTextId = `${this.inputId}-helper-text`;
15016
+ this.errorTextId = `${this.inputId}-error-text`;
14960
15017
  this.inheritedAttributes = {};
14961
15018
  this.isComposing = false;
14962
15019
  /**
@@ -15219,8 +15276,21 @@ class Input {
15219
15276
  * Renders the helper text or error text values
15220
15277
  */
15221
15278
  renderHintText() {
15222
- const { helperText, errorText } = this;
15223
- return [hAsync("div", { class: "helper-text" }, helperText), hAsync("div", { class: "error-text" }, errorText)];
15279
+ const { helperText, errorText, helperTextId, errorTextId } = this;
15280
+ return [
15281
+ hAsync("div", { id: helperTextId, class: "helper-text" }, helperText),
15282
+ hAsync("div", { id: errorTextId, class: "error-text" }, errorText),
15283
+ ];
15284
+ }
15285
+ getHintTextID() {
15286
+ const { el, helperText, errorText, helperTextId, errorTextId } = this;
15287
+ if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
15288
+ return errorTextId;
15289
+ }
15290
+ if (helperText) {
15291
+ return helperTextId;
15292
+ }
15293
+ return undefined;
15224
15294
  }
15225
15295
  renderCounter() {
15226
15296
  const { counter, maxlength, counterFormatter, value } = this;
@@ -15327,7 +15397,7 @@ class Input {
15327
15397
  * TODO(FW-5592): Remove hasStartEndSlots condition
15328
15398
  */
15329
15399
  const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
15330
- return (hAsync(Host, { key: '907ce98a82b5cfae5a08504cd79e00a2330b7444', class: createColorClasses$1(this.color, {
15400
+ return (hAsync(Host, { key: 'cdde9963d71685e6a4f3f3b3bc52e75d022435cb', class: createColorClasses$1(this.color, {
15331
15401
  [mode]: true,
15332
15402
  'has-value': hasValue,
15333
15403
  'has-focus': hasFocus,
@@ -15338,7 +15408,7 @@ class Input {
15338
15408
  'in-item': inItem,
15339
15409
  'in-item-color': hostContext('ion-item.ion-color', this.el),
15340
15410
  'input-disabled': disabled,
15341
- }) }, hAsync("label", { key: '59d5bb45d2a5b828bba0ed8687a632a551e2f4d8', class: "input-wrapper", htmlFor: inputId }, this.renderLabelContainer(), hAsync("div", { key: 'f93f129d08246d0e9a601c100d718534d6403853', class: "native-wrapper" }, hAsync("slot", { key: '54eeb1a6bace662b7eb0d7e27180ea3d7e3a3729', name: "start" }), hAsync("input", Object.assign({ key: 'b3e0be55bc1a4a539ae3b0fdcf7fc078723cca16', class: "native-input", ref: (input) => (this.nativeInput = input), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoComplete: this.autocomplete, autoCorrect: this.autocorrect, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, min: this.min, max: this.max, minLength: this.minlength, maxLength: this.maxlength, multiple: this.multiple, name: this.name, pattern: this.pattern, placeholder: this.placeholder || '', readOnly: readonly, required: this.required, spellcheck: this.spellcheck, step: this.step, type: this.type, value: value, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeydown, onCompositionstart: this.onCompositionStart, onCompositionend: this.onCompositionEnd }, this.inheritedAttributes)), this.clearInput && !readonly && !disabled && (hAsync("button", { key: '5f6373504a6d0d074bfbf875c794d45ea2748175', "aria-label": "reset", type: "button", class: "input-clear-icon", onPointerDown: (ev) => {
15411
+ }) }, hAsync("label", { key: '4412791c93405f20e50e50363879265180b6078f', class: "input-wrapper", htmlFor: inputId }, this.renderLabelContainer(), hAsync("div", { key: '5c71c43ef3eeb44dde76ed64ce10763834c8fbc7', class: "native-wrapper" }, hAsync("slot", { key: '1d86b58dc299a4208dd02ccdc9ceaea7576698c3', name: "start" }), hAsync("input", Object.assign({ key: '7fc932174485f7d09e6a797dfd49ea11fbad71b6', class: "native-input", ref: (input) => (this.nativeInput = input), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoComplete: this.autocomplete, autoCorrect: this.autocorrect, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, min: this.min, max: this.max, minLength: this.minlength, maxLength: this.maxlength, multiple: this.multiple, name: this.name, pattern: this.pattern, placeholder: this.placeholder || '', readOnly: readonly, required: this.required, spellcheck: this.spellcheck, step: this.step, type: this.type, value: value, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeydown, onCompositionstart: this.onCompositionStart, onCompositionend: this.onCompositionEnd, "aria-describedby": this.getHintTextID(), "aria-invalid": this.getHintTextID() === this.errorTextId }, this.inheritedAttributes)), this.clearInput && !readonly && !disabled && (hAsync("button", { key: '46de455e4e308b8d7640b04778f7c7559b4124c6', "aria-label": "reset", type: "button", class: "input-clear-icon", onPointerDown: (ev) => {
15342
15412
  /**
15343
15413
  * This prevents mobile browsers from
15344
15414
  * blurring the input when the clear
@@ -15353,7 +15423,7 @@ class Input {
15353
15423
  * for screen readers as it means users would be unable to swipe past the clear button.
15354
15424
  */
15355
15425
  ev.stopPropagation();
15356
- }, onClick: this.clearTextInput }, hAsync("ion-icon", { key: '230d77973aa83458ceb32bf52e3abe9bc322cfe6', "aria-hidden": "true", icon: clearIconData }))), hAsync("slot", { key: '9d69ac6e8a3c4b2b303dba2478f82695d5755ed2', name: "end" })), shouldRenderHighlight && hAsync("div", { key: 'ac61f16237ce731e0745ab72d0fc3f066252464a', class: "input-highlight" })), this.renderBottomContent()));
15426
+ }, onClick: this.clearTextInput }, hAsync("ion-icon", { key: '375e860a20e1807ce0db0e1934a0650fe9929966', "aria-hidden": "true", icon: clearIconData }))), hAsync("slot", { key: '859d47a1b88aa8377479e5d11e52a6a1c1c30e7e', name: "end" })), shouldRenderHighlight && hAsync("div", { key: 'd2d4286b348107e33247b5c0afda0f8bd697ecee', class: "input-highlight" })), this.renderBottomContent()));
15357
15427
  }
15358
15428
  get el() { return getElement(this); }
15359
15429
  static get watchers() { return {
@@ -16889,7 +16959,7 @@ class Loading {
16889
16959
  const ariaLabelledBy = message !== undefined ? msgId : null;
16890
16960
  return (hAsync(Host, Object.assign({ key: 'fb3d2cd7cd0539ed6540d8be50e243c7916b3ca2', role: "dialog", "aria-modal": "true", "aria-labelledby": ariaLabelledBy, tabindex: "-1" }, htmlAttributes, { style: {
16891
16961
  zIndex: `${40000 + this.overlayIndex}`,
16892
- }, onIonBackdropTap: this.onBackdropTap, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'overlay-hidden': true, 'loading-translucent': this.translucent }) }), hAsync("ion-backdrop", { key: 'c8bd30782f3040b1b80e88aa924861e439d40754', visible: this.showBackdrop, tappable: this.backdropDismiss }), hAsync("div", { key: '4ebfbb67c92e8eb56c27dd7c199b35bf6be1cf63', tabindex: "0" }), hAsync("div", { key: '9492723cd87f1ef75534e449d4bc2b2deb0cb3cc', class: "loading-wrapper ion-overlay-wrapper" }, spinner && (hAsync("div", { key: 'd9eb42454e48c82704d974a68b80ceb4de990417', class: "loading-spinner" }, hAsync("ion-spinner", { key: 'cdb046bad89872f4208ae466979315652766bf3a', name: spinner, "aria-hidden": "true" }))), message !== undefined && this.renderLoadingMessage(msgId)), hAsync("div", { key: '412d1bb537dafa6e6863d07ddc15f5969fe0617d', tabindex: "0" })));
16962
+ }, onIonBackdropTap: this.onBackdropTap, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'overlay-hidden': true, 'loading-translucent': this.translucent }) }), hAsync("ion-backdrop", { key: 'c8bd30782f3040b1b80e88aa924861e439d40754', visible: this.showBackdrop, tappable: this.backdropDismiss }), hAsync("div", { key: '7ad4447fafa49aa861d311221b8c2e8171b4c610', tabindex: "0", "aria-hidden": "true" }), hAsync("div", { key: '1879df0d895eb8ee20ccdc94dd35d708c1140b91', class: "loading-wrapper ion-overlay-wrapper" }, spinner && (hAsync("div", { key: '220f292c136681f5fa91f94669aac75b15e490ce', class: "loading-spinner" }, hAsync("ion-spinner", { key: 'd599084a1426d941bdd080a988d8ad5b9589b823', name: spinner, "aria-hidden": "true" }))), message !== undefined && this.renderLoadingMessage(msgId)), hAsync("div", { key: 'e443897b353a48e0c72718dba04d83d7c5070d73', tabindex: "0", "aria-hidden": "true" })));
16893
16963
  }
16894
16964
  get el() { return getElement(this); }
16895
16965
  static get watchers() { return {
@@ -21883,7 +21953,7 @@ class Picker {
21883
21953
  zIndex: `${20000 + this.overlayIndex}`,
21884
21954
  }, class: Object.assign({ [mode]: true,
21885
21955
  // Used internally for styling
21886
- [`picker-${mode}`]: true, 'overlay-hidden': true }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonPickerWillDismiss: this.dispatchCancelHandler }), hAsync("ion-backdrop", { key: 'da4224447bdbcfbadd1bd63ebe7a7bfdb8aa3129', visible: this.showBackdrop, tappable: this.backdropDismiss }), hAsync("div", { key: '211475c859b7acf4d64556905c45993201d92d43', tabindex: "0" }), hAsync("div", { key: 'c3b3674038155809caea84ae6348ff0d66897a64', class: "picker-wrapper ion-overlay-wrapper", role: "dialog" }, hAsync("div", { key: 'a21757da70dc7864945a5751d9da3ca4bf87897b', class: "picker-toolbar" }, this.buttons.map((b) => (hAsync("div", { class: buttonWrapperClass(b) }, hAsync("button", { type: "button", onClick: () => this.buttonClick(b), class: buttonClass$1(b) }, b.text))))), hAsync("div", { key: '0220da1854d09ef22d2d9a32eaa3c3b222be5a0a', class: "picker-columns" }, hAsync("div", { key: '55757c165ba9e38e56b4dee76a9b13d3ff8b21e6', class: "picker-above-highlight" }), this.presented && this.columns.map((c) => hAsync("ion-picker-legacy-column", { col: c })), hAsync("div", { key: '160092a46a48287bf75e5dfe3502f1755a2d0c70', class: "picker-below-highlight" }))), hAsync("div", { key: 'e212db6cca7d75fc0eda0baf4312dd51b9b7a4ef', tabindex: "0" })));
21956
+ [`picker-${mode}`]: true, 'overlay-hidden': true }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonPickerWillDismiss: this.dispatchCancelHandler }), hAsync("ion-backdrop", { key: 'da4224447bdbcfbadd1bd63ebe7a7bfdb8aa3129', visible: this.showBackdrop, tappable: this.backdropDismiss }), hAsync("div", { key: '65eba425990a21be00fdac90de20a630d284cf97', tabindex: "0", "aria-hidden": "true" }), hAsync("div", { key: 'd78ada360801b2c051baa030751f3d83ac81e697', class: "picker-wrapper ion-overlay-wrapper", role: "dialog" }, hAsync("div", { key: 'd5bd9ddfbdbdaf42048a1496e7939eb3aee6da65', class: "picker-toolbar" }, this.buttons.map((b) => (hAsync("div", { class: buttonWrapperClass(b) }, hAsync("button", { type: "button", onClick: () => this.buttonClick(b), class: buttonClass$1(b) }, b.text))))), hAsync("div", { key: '96ee1e3ec77c57174b1a93135b66bea6b7002555', class: "picker-columns" }, hAsync("div", { key: 'e11b1c238f350e65bde2ee67eee9d71c830e74e7', class: "picker-above-highlight" }), this.presented && this.columns.map((c) => hAsync("ion-picker-legacy-column", { col: c })), hAsync("div", { key: '4d5fc7c723185111ec01fd34ef95a897c301238d', class: "picker-below-highlight" }))), hAsync("div", { key: '899bcad97609c1d971c1b886551db5ba0248a9f4', tabindex: "0", "aria-hidden": "true" })));
21887
21957
  }
21888
21958
  get el() { return getElement(this); }
21889
21959
  static get watchers() { return {
@@ -30700,6 +30770,8 @@ class Textarea {
30700
30770
  this.ionBlur = createEvent(this, "ionBlur", 7);
30701
30771
  this.ionFocus = createEvent(this, "ionFocus", 7);
30702
30772
  this.inputId = `ion-textarea-${textareaIds++}`;
30773
+ this.helperTextId = `${this.inputId}-helper-text`;
30774
+ this.errorTextId = `${this.inputId}-error-text`;
30703
30775
  /**
30704
30776
  * `true` if the textarea was cleared as a result of the user typing
30705
30777
  * with `clearOnEdit` enabled.
@@ -30977,8 +31049,21 @@ class Textarea {
30977
31049
  * Renders the helper text or error text values
30978
31050
  */
30979
31051
  renderHintText() {
30980
- const { helperText, errorText } = this;
30981
- return [hAsync("div", { class: "helper-text" }, helperText), hAsync("div", { class: "error-text" }, errorText)];
31052
+ const { helperText, errorText, helperTextId, errorTextId } = this;
31053
+ return [
31054
+ hAsync("div", { id: helperTextId, class: "helper-text" }, helperText),
31055
+ hAsync("div", { id: errorTextId, class: "error-text" }, errorText),
31056
+ ];
31057
+ }
31058
+ getHintTextID() {
31059
+ const { el, helperText, errorText, helperTextId, errorTextId } = this;
31060
+ if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
31061
+ return errorTextId;
31062
+ }
31063
+ if (helperText) {
31064
+ return helperTextId;
31065
+ }
31066
+ return undefined;
30982
31067
  }
30983
31068
  renderCounter() {
30984
31069
  const { counter, maxlength, counterFormatter, value } = this;
@@ -31031,7 +31116,7 @@ class Textarea {
31031
31116
  * TODO(FW-5592): Remove hasStartEndSlots condition
31032
31117
  */
31033
31118
  const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
31034
- return (hAsync(Host, { key: '37595a18d77dea1a337ac1c672e5f08a4128111d', class: createColorClasses$1(this.color, {
31119
+ return (hAsync(Host, { key: 'e8a5b5727c6a018bbd6f5507b690bc5f0959e352', class: createColorClasses$1(this.color, {
31035
31120
  [mode]: true,
31036
31121
  'has-value': hasValue,
31037
31122
  'has-focus': hasFocus,
@@ -31040,7 +31125,7 @@ class Textarea {
31040
31125
  [`textarea-shape-${shape}`]: shape !== undefined,
31041
31126
  [`textarea-label-placement-${labelPlacement}`]: true,
31042
31127
  'textarea-disabled': disabled,
31043
- }) }, hAsync("label", { key: '67342758743e5a40448a32ff695876d39778621f', class: "textarea-wrapper", htmlFor: inputId }, this.renderLabelContainer(), hAsync("div", { key: 'a994be8264bf5652811cf816d79a04178954e83f', class: "textarea-wrapper-inner" }, hAsync("div", { key: 'e09c93ebcd5b3d227d51e682ca23dfc7fd7027ad', class: "start-slot-wrapper" }, hAsync("slot", { key: 'd39758f21f19ae70aea21e9a9a7b7c20991fe593', name: "start" })), hAsync("div", { key: '6a4e10e53de4bb235ee30def4c9ae5bdee888816', class: "native-wrapper", ref: (el) => (this.textareaWrapper = el) }, hAsync("textarea", Object.assign({ key: '9e254e551f124d972e9bc6b09ef0f2bb55890be5', class: "native-textarea", ref: (el) => (this.nativeInput = el), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, minLength: this.minlength, maxLength: this.maxlength, name: this.name, placeholder: this.placeholder || '', readOnly: this.readonly, required: this.required, spellcheck: this.spellcheck, cols: this.cols, rows: this.rows, wrap: this.wrap, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeyDown }, this.inheritedAttributes), value)), hAsync("div", { key: 'a66aa2d2bc4778a0bec56a8b9ec9052a832eb3b2', class: "end-slot-wrapper" }, hAsync("slot", { key: '8e6a90b4475de32e23afc593da4108610dcca663', name: "end" }))), shouldRenderHighlight && hAsync("div", { key: '6da03205a8daff45581b20f0af3938634a9d5f8c', class: "textarea-highlight" })), this.renderBottomContent()));
31128
+ }) }, hAsync("label", { key: '48e889571e2d3e7e150b038e4b4b15862b418288', class: "textarea-wrapper", htmlFor: inputId }, this.renderLabelContainer(), hAsync("div", { key: '6c6c7872ae4d351d8b8d772ad18ce3ba7a0e9a87', class: "textarea-wrapper-inner" }, hAsync("div", { key: '03aef5dfa59af0fa78a3e5c92e0ed72396717d72', class: "start-slot-wrapper" }, hAsync("slot", { key: '39aee9faebb0f1d10de5a5817fd9d9771b074b96', name: "start" })), hAsync("div", { key: '738e8ff603f4c9b9083b3139db861f4b7ec20f79', class: "native-wrapper", ref: (el) => (this.textareaWrapper = el) }, hAsync("textarea", Object.assign({ key: '7763fb4f8ffe94635167331c70d21d661544c4f8', class: "native-textarea", ref: (el) => (this.nativeInput = el), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, minLength: this.minlength, maxLength: this.maxlength, name: this.name, placeholder: this.placeholder || '', readOnly: this.readonly, required: this.required, spellcheck: this.spellcheck, cols: this.cols, rows: this.rows, wrap: this.wrap, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeyDown, "aria-describedby": this.getHintTextID(), "aria-invalid": this.getHintTextID() === this.errorTextId }, this.inheritedAttributes), value)), hAsync("div", { key: 'b3af9ec0982c6dbd381afaa02df153d7e90471be', class: "end-slot-wrapper" }, hAsync("slot", { key: '60f99bcd49a5ec2e1fa6e3e77809aefeb9d2d0d6', name: "end" }))), shouldRenderHighlight && hAsync("div", { key: '6a7f45639ba027f4da573adae53f1197a6dec383', class: "textarea-highlight" })), this.renderBottomContent()));
31044
31129
  }
31045
31130
  get el() { return getElement(this); }
31046
31131
  static get watchers() { return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "voyager-ionic-core",
3
- "version": "8.3.3",
3
+ "version": "8.3.4",
4
4
  "description": "Base components for Ionic",
5
5
  "keywords": [
6
6
  "ionic",