@ionic/core 8.7.4-dev.11756220757.185b8cbf → 8.7.4-dev.11756388042.1a103a79

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 (84) hide show
  1. package/components/ion-datetime.js +4 -3
  2. package/components/ion-input.js +8 -63
  3. package/components/ion-menu.js +5 -2
  4. package/components/ion-textarea.js +7 -62
  5. package/components/overlays.js +18 -109
  6. package/components/picker-column-option.js +3 -3
  7. package/components/picker-column.js +3 -39
  8. package/dist/cjs/index.cjs.js +1 -1
  9. package/dist/cjs/ion-action-sheet.cjs.entry.js +1 -1
  10. package/dist/cjs/ion-alert.cjs.entry.js +1 -1
  11. package/dist/cjs/ion-datetime_3.cjs.entry.js +4 -4
  12. package/dist/cjs/ion-input.cjs.entry.js +8 -62
  13. package/dist/cjs/ion-loading.cjs.entry.js +1 -1
  14. package/dist/cjs/ion-menu_3.cjs.entry.js +6 -3
  15. package/dist/cjs/ion-modal.cjs.entry.js +1 -1
  16. package/dist/cjs/ion-picker-column-option.cjs.entry.js +3 -3
  17. package/dist/cjs/ion-picker-column.cjs.entry.js +3 -39
  18. package/dist/cjs/ion-popover.cjs.entry.js +1 -1
  19. package/dist/cjs/ion-select-modal.cjs.entry.js +1 -1
  20. package/dist/cjs/ion-select_3.cjs.entry.js +1 -1
  21. package/dist/cjs/ion-textarea.cjs.entry.js +7 -61
  22. package/dist/cjs/ion-toast.cjs.entry.js +1 -1
  23. package/dist/cjs/ionic.cjs.js +1 -1
  24. package/dist/cjs/loader.cjs.js +1 -1
  25. package/dist/cjs/{overlays-CglR7j-u.js → overlays-v_jc1Hok.js} +17 -108
  26. package/dist/collection/components/datetime/datetime.js +4 -3
  27. package/dist/collection/components/input/input.js +9 -64
  28. package/dist/collection/components/menu/menu.js +9 -2
  29. package/dist/collection/components/picker-column/picker-column.js +3 -39
  30. package/dist/collection/components/picker-column-option/picker-column-option.ios.css +2 -2
  31. package/dist/collection/components/picker-column-option/picker-column-option.js +1 -1
  32. package/dist/collection/components/picker-column-option/picker-column-option.md.css +2 -2
  33. package/dist/collection/components/textarea/textarea.js +8 -63
  34. package/dist/collection/utils/overlays.js +17 -109
  35. package/dist/docs.json +5 -1
  36. package/dist/esm/index.js +1 -1
  37. package/dist/esm/ion-action-sheet.entry.js +1 -1
  38. package/dist/esm/ion-alert.entry.js +1 -1
  39. package/dist/esm/ion-datetime_3.entry.js +4 -4
  40. package/dist/esm/ion-input.entry.js +8 -62
  41. package/dist/esm/ion-loading.entry.js +1 -1
  42. package/dist/esm/ion-menu_3.entry.js +6 -3
  43. package/dist/esm/ion-modal.entry.js +1 -1
  44. package/dist/esm/ion-picker-column-option.entry.js +3 -3
  45. package/dist/esm/ion-picker-column.entry.js +3 -39
  46. package/dist/esm/ion-popover.entry.js +1 -1
  47. package/dist/esm/ion-select-modal.entry.js +1 -1
  48. package/dist/esm/ion-select_3.entry.js +1 -1
  49. package/dist/esm/ion-textarea.entry.js +7 -61
  50. package/dist/esm/ion-toast.entry.js +1 -1
  51. package/dist/esm/ionic.js +1 -1
  52. package/dist/esm/loader.js +1 -1
  53. package/dist/esm/{overlays-ZX_4-t_r.js → overlays-BJaRj3Rj.js} +18 -109
  54. package/dist/ionic/index.esm.js +1 -1
  55. package/dist/ionic/ionic.esm.js +1 -1
  56. package/dist/ionic/{p-f2884bc2.entry.js → p-095073c6.entry.js} +1 -1
  57. package/dist/ionic/p-1488b7cc.entry.js +4 -0
  58. package/dist/ionic/p-1ab0fc21.entry.js +4 -0
  59. package/dist/ionic/{p-92e8f208.entry.js → p-2060feb1.entry.js} +1 -1
  60. package/dist/ionic/p-22a0f820.entry.js +4 -0
  61. package/dist/ionic/{p-c575e7ce.entry.js → p-5a9be5a3.entry.js} +1 -1
  62. package/dist/ionic/{p-7bac2c5f.entry.js → p-60ff6bf6.entry.js} +1 -1
  63. package/dist/ionic/p-8888efe4.entry.js +4 -0
  64. package/dist/ionic/{p-ab33ef20.entry.js → p-89c2e0a3.entry.js} +1 -1
  65. package/dist/ionic/p-CoDfkBuk.js +4 -0
  66. package/dist/ionic/{p-91d6ccb0.entry.js → p-b17f0554.entry.js} +1 -1
  67. package/dist/ionic/p-b292804d.entry.js +4 -0
  68. package/dist/ionic/p-c5210d3e.entry.js +4 -0
  69. package/dist/ionic/{p-ac434970.entry.js → p-cd93c119.entry.js} +1 -1
  70. package/dist/ionic/p-dc8d0bb9.entry.js +4 -0
  71. package/dist/types/components/input/input.d.ts +0 -9
  72. package/dist/types/components/picker-column/picker-column.d.ts +0 -7
  73. package/dist/types/components/textarea/textarea.d.ts +0 -9
  74. package/hydrate/index.js +46 -248
  75. package/hydrate/index.mjs +46 -248
  76. package/package.json +2 -2
  77. package/dist/ionic/p-0816f67c.entry.js +0 -4
  78. package/dist/ionic/p-1d5b934a.entry.js +0 -4
  79. package/dist/ionic/p-29032e49.entry.js +0 -4
  80. package/dist/ionic/p-8d96a0cd.entry.js +0 -4
  81. package/dist/ionic/p-8e2de06f.entry.js +0 -4
  82. package/dist/ionic/p-982fe1c4.entry.js +0 -4
  83. package/dist/ionic/p-CSwZyt05.js +0 -4
  84. package/dist/ionic/p-f456d176.entry.js +0 -4
package/hydrate/index.mjs CHANGED
@@ -6159,15 +6159,17 @@ const getPresentedOverlay = (doc, overlayTag, id) => {
6159
6159
  */
6160
6160
  const setRootAriaHidden = (hidden = false) => {
6161
6161
  const root = getAppRoot(document);
6162
- const viewContainer = root.querySelector('ion-router-outlet, ion-nav, #ion-view-container-root');
6162
+ const viewContainer = root.querySelector('ion-router-outlet, #ion-view-container-root');
6163
6163
  if (!viewContainer) {
6164
6164
  return;
6165
6165
  }
6166
6166
  if (hidden) {
6167
6167
  viewContainer.setAttribute('aria-hidden', 'true');
6168
+ viewContainer.setAttribute('inert', '');
6168
6169
  }
6169
6170
  else {
6170
6171
  viewContainer.removeAttribute('aria-hidden');
6172
+ viewContainer.removeAttribute('inert');
6171
6173
  }
6172
6174
  };
6173
6175
  const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts) => {
@@ -6175,6 +6177,17 @@ const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts)
6175
6177
  if (overlay.presented) {
6176
6178
  return;
6177
6179
  }
6180
+ /**
6181
+ * When an overlay that steals focus
6182
+ * is dismissed, focus should be returned
6183
+ * to the element that was focused
6184
+ * prior to the overlay opening. Toast
6185
+ * does not steal focus and is excluded
6186
+ * from returning focus as a result.
6187
+ */
6188
+ if (overlay.el.tagName !== 'ION-TOAST') {
6189
+ restoreElementFocus(overlay.el);
6190
+ }
6178
6191
  /**
6179
6192
  * Due to accessibility guidelines, toasts do not have
6180
6193
  * focus traps.
@@ -6186,8 +6199,6 @@ const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts)
6186
6199
  setRootAriaHidden(true);
6187
6200
  document.body.classList.add(BACKDROP_NO_SCROLL);
6188
6201
  }
6189
- hideUnderlyingOverlaysFromScreenReaders(overlay.el);
6190
- hideAnimatingOverlayFromScreenReaders(overlay.el);
6191
6202
  overlay.presented = true;
6192
6203
  overlay.willPresent.emit();
6193
6204
  (_a = overlay.willPresentShorthand) === null || _a === void 0 ? void 0 : _a.emit();
@@ -6201,17 +6212,6 @@ const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts)
6201
6212
  overlay.didPresent.emit();
6202
6213
  (_b = overlay.didPresentShorthand) === null || _b === void 0 ? void 0 : _b.emit();
6203
6214
  }
6204
- /**
6205
- * When an overlay that steals focus
6206
- * is dismissed, focus should be returned
6207
- * to the element that was focused
6208
- * prior to the overlay opening. Toast
6209
- * does not steal focus and is excluded
6210
- * from returning focus as a result.
6211
- */
6212
- if (overlay.el.tagName !== 'ION-TOAST') {
6213
- restoreElementFocus(overlay.el);
6214
- }
6215
6215
  /**
6216
6216
  * If the focused element is already
6217
6217
  * inside the overlay component then
@@ -6234,6 +6234,7 @@ const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts)
6234
6234
  * screen readers.
6235
6235
  */
6236
6236
  overlay.el.removeAttribute('aria-hidden');
6237
+ overlay.el.removeAttribute('inert');
6237
6238
  };
6238
6239
  /**
6239
6240
  * When an overlay component is dismissed,
@@ -6250,6 +6251,8 @@ const restoreElementFocus = async (overlayEl) => {
6250
6251
  if (!previousElement) {
6251
6252
  return;
6252
6253
  }
6254
+ // Ensure active element is blurred to prevent a11y warning issues
6255
+ previousElement.blur();
6253
6256
  const shadowRoot = previousElement === null || previousElement === void 0 ? void 0 : previousElement.shadowRoot;
6254
6257
  if (shadowRoot) {
6255
6258
  // If there are no inner focusable elements, just focus the host element.
@@ -6313,12 +6316,6 @@ const dismiss = async (overlay, data, role, name, iosLeaveAnimation, mdLeaveAnim
6313
6316
  }
6314
6317
  overlay.presented = false;
6315
6318
  try {
6316
- /**
6317
- * There is no need to show the overlay to screen readers during
6318
- * the dismiss animation. This is because the overlay will be removed
6319
- * from the DOM after the animation is complete.
6320
- */
6321
- hideAnimatingOverlayFromScreenReaders(overlay.el);
6322
6319
  // Overlay contents should not be clickable during dismiss
6323
6320
  overlay.el.style.setProperty('pointer-events', 'none');
6324
6321
  overlay.willDismiss.emit({ data, role });
@@ -6357,7 +6354,6 @@ const dismiss = async (overlay, data, role, name, iosLeaveAnimation, mdLeaveAnim
6357
6354
  printIonError(`[${overlay.el.tagName.toLowerCase()}] - `, err);
6358
6355
  }
6359
6356
  overlay.el.remove();
6360
- revealOverlaysToScreenReaders();
6361
6357
  return true;
6362
6358
  };
6363
6359
  const getAppRoot = (doc) => {
@@ -6553,93 +6549,6 @@ const createTriggerController = () => {
6553
6549
  removeClickListener,
6554
6550
  };
6555
6551
  };
6556
- /**
6557
- * The overlay that is being animated also needs to hide from screen
6558
- * readers during its animation. This ensures that assistive technologies
6559
- * like TalkBack do not announce or interact with the content until the
6560
- * animation is complete, avoiding confusion for users.
6561
- *
6562
- * When the overlay is presented on an Android device, TalkBack's focus rings
6563
- * may appear in the wrong position due to the transition (specifically
6564
- * `transform` styles). This occurs because the focus rings are initially
6565
- * displayed at the starting position of the elements before the transition
6566
- * begins. This workaround ensures the focus rings do not appear in the
6567
- * incorrect location.
6568
- *
6569
- * If this solution is applied to iOS devices, then it leads to a bug where
6570
- * the overlays cannot be accessed by screen readers. This is due to
6571
- * VoiceOver not being able to update the accessibility tree when the
6572
- * `aria-hidden` is removed.
6573
- *
6574
- * @param overlay - The overlay that is being animated.
6575
- */
6576
- const hideAnimatingOverlayFromScreenReaders = (overlay) => {
6577
- if (doc === undefined)
6578
- return;
6579
- if (isPlatform('android')) {
6580
- /**
6581
- * Once the animation is complete, this attribute will be removed.
6582
- * This is done at the end of the `present` method.
6583
- */
6584
- overlay.setAttribute('aria-hidden', 'true');
6585
- }
6586
- };
6587
- /**
6588
- * Ensure that underlying overlays have aria-hidden if necessary so that screen readers
6589
- * cannot move focus to these elements. Note that we cannot rely on focus/focusin/focusout
6590
- * events here because those events do not fire when the screen readers moves to a non-focusable
6591
- * element such as text.
6592
- * Without this logic screen readers would be able to move focus outside of the top focus-trapped overlay.
6593
- *
6594
- * @param newTopMostOverlay - The overlay that is being presented. Since the overlay has not been
6595
- * fully presented yet at the time this function is called it will not be included in the getPresentedOverlays result.
6596
- */
6597
- const hideUnderlyingOverlaysFromScreenReaders = (newTopMostOverlay) => {
6598
- var _a;
6599
- if (doc === undefined)
6600
- return;
6601
- const overlays = getPresentedOverlays(doc);
6602
- for (let i = overlays.length - 1; i >= 0; i--) {
6603
- const presentedOverlay = overlays[i];
6604
- const nextPresentedOverlay = (_a = overlays[i + 1]) !== null && _a !== void 0 ? _a : newTopMostOverlay;
6605
- /**
6606
- * If next overlay has aria-hidden then all remaining overlays will have it too.
6607
- * Or, if the next overlay is a Toast that does not have aria-hidden then current overlay
6608
- * should not have aria-hidden either so focus can remain in the current overlay.
6609
- */
6610
- if (nextPresentedOverlay.hasAttribute('aria-hidden') || nextPresentedOverlay.tagName !== 'ION-TOAST') {
6611
- presentedOverlay.setAttribute('aria-hidden', 'true');
6612
- }
6613
- }
6614
- };
6615
- /**
6616
- * When dismissing an overlay we need to reveal the new top-most overlay to screen readers.
6617
- * If the top-most overlay is a Toast we potentially need to reveal more overlays since
6618
- * focus is never automatically moved to the Toast.
6619
- */
6620
- const revealOverlaysToScreenReaders = () => {
6621
- if (doc === undefined)
6622
- return;
6623
- const overlays = getPresentedOverlays(doc);
6624
- for (let i = overlays.length - 1; i >= 0; i--) {
6625
- const currentOverlay = overlays[i];
6626
- /**
6627
- * If the current we are looking at is a Toast then we can remove aria-hidden.
6628
- * However, we potentially need to keep looking at the overlay stack because there
6629
- * could be more Toasts underneath. Additionally, we need to unhide the closest non-Toast
6630
- * overlay too so focus can move there since focus is never automatically moved to the Toast.
6631
- */
6632
- currentOverlay.removeAttribute('aria-hidden');
6633
- /**
6634
- * If we found a non-Toast element then we can just remove aria-hidden and stop searching entirely
6635
- * since this overlay should always receive focus. As a result, all underlying overlays should still
6636
- * be hidden from screen readers.
6637
- */
6638
- if (currentOverlay.tagName !== 'ION-TOAST') {
6639
- break;
6640
- }
6641
- }
6642
- };
6643
6552
  const FOCUS_TRAP_DISABLE_CLASS = 'ion-disable-focus-trap';
6644
6553
 
6645
6554
  const hostContext = (selector, el) => {
@@ -13529,7 +13438,7 @@ class Datetime {
13529
13438
  const renderArray = forcePresentation === 'time-date'
13530
13439
  ? [this.renderTimePickerColumns(forcePresentation), this.renderDatePickerColumns(forcePresentation)]
13531
13440
  : [this.renderDatePickerColumns(forcePresentation), this.renderTimePickerColumns(forcePresentation)];
13532
- return hAsync("ion-picker", null, renderArray);
13441
+ return hAsync("ion-picker", { class: FOCUS_TRAP_DISABLE_CLASS }, renderArray);
13533
13442
  }
13534
13443
  renderDatePickerColumns(forcePresentation) {
13535
13444
  return forcePresentation === 'date-time' || forcePresentation === 'time-date'
@@ -14086,7 +13995,7 @@ class Datetime {
14086
13995
  const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
14087
13996
  const hasWheelVariant = hasDatePresentation && preferWheel;
14088
13997
  renderHiddenInput(true, el, name, formatValue(value), disabled);
14089
- return (hAsync(Host, { key: 'f35cf200ff05d33074576e3d2754d3b2a0735b96', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, createColorClasses$1(color, {
13998
+ return (hAsync(Host, { key: '57492534800ea059a7c2bbd9f0059cc0b75ae8d2', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, createColorClasses$1(color, {
14090
13999
  [mode]: true,
14091
14000
  ['datetime-readonly']: readonly,
14092
14001
  ['datetime-disabled']: disabled,
@@ -14096,7 +14005,7 @@ class Datetime {
14096
14005
  [`datetime-size-${size}`]: true,
14097
14006
  [`datetime-prefer-wheel`]: hasWheelVariant,
14098
14007
  [`datetime-grid`]: isGridStyle,
14099
- })) }, hAsync("div", { key: '859e9354a12bfa58ac3f964c2e66839f17071c00', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
14008
+ })) }, hAsync("div", { key: '97dac5e5195635ac0bc5fb472b9d09e5c3c6bbc3', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
14100
14009
  }
14101
14010
  get el() { return getElement(this); }
14102
14011
  static get watchers() { return {
@@ -16627,10 +16536,6 @@ class Input {
16627
16536
  * is applied in both cases.
16628
16537
  */
16629
16538
  this.hasFocus = false;
16630
- /**
16631
- * Track validation state for proper aria-live announcements
16632
- */
16633
- this.isInvalid = false;
16634
16539
  /**
16635
16540
  * Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user.
16636
16541
  * Available options: `"off"`, `"none"`, `"on"`, `"sentences"`, `"words"`, `"characters"`.
@@ -16716,18 +16621,6 @@ class Input {
16716
16621
  }
16717
16622
  this.didInputClearOnEdit = false;
16718
16623
  this.ionBlur.emit(ev);
16719
- /**
16720
- * Check validation state after blur to handle framework-managed classes.
16721
- * Frameworks like Angular update classes asynchronously, often using
16722
- * requestAnimationFrame or promises. Using setTimeout ensures we check
16723
- * after all microtasks and animation frames have completed.
16724
- */
16725
- setTimeout(() => {
16726
- const newIsInvalid = this.checkValidationState();
16727
- if (this.isInvalid !== newIsInvalid) {
16728
- this.isInvalid = newIsInvalid;
16729
- }
16730
- }, 100);
16731
16624
  };
16732
16625
  this.onFocus = (ev) => {
16733
16626
  this.hasFocus = true;
@@ -16826,27 +16719,10 @@ class Input {
16826
16719
  componentWillLoad() {
16827
16720
  this.inheritedAttributes = Object.assign(Object.assign({}, inheritAriaAttributes(this.el)), inheritAttributes$1(this.el, ['tabindex', 'title', 'data-form-type', 'dir']));
16828
16721
  }
16829
- /**
16830
- * Checks if the input is in an invalid state based on validation classes
16831
- */
16832
- checkValidationState() {
16833
- // Check for both Ionic and Angular validation classes on the element itself
16834
- // Angular applies ng-touched/ng-invalid directly to the host element with ngModel
16835
- const hasIonTouched = this.el.classList.contains('ion-touched');
16836
- const hasIonInvalid = this.el.classList.contains('ion-invalid');
16837
- const hasNgTouched = this.el.classList.contains('ng-touched');
16838
- const hasNgInvalid = this.el.classList.contains('ng-invalid');
16839
- // Return true if we have both touched and invalid states from either framework
16840
- const isTouched = hasIonTouched || hasNgTouched;
16841
- const isInvalid = hasIonInvalid || hasNgInvalid;
16842
- return isTouched && isInvalid;
16843
- }
16844
16722
  connectedCallback() {
16845
16723
  const { el } = this;
16846
16724
  this.slotMutationController = createSlotMutationController(el, ['label', 'start', 'end'], () => forceUpdate());
16847
16725
  this.notchController = createNotchController(el, () => this.notchSpacerEl, () => this.labelSlot);
16848
- // Always set initial state
16849
- this.isInvalid = this.checkValidationState();
16850
16726
  this.debounceChanged();
16851
16727
  }
16852
16728
  componentDidLoad() {
@@ -16873,11 +16749,6 @@ class Input {
16873
16749
  this.notchController.destroy();
16874
16750
  this.notchController = undefined;
16875
16751
  }
16876
- // Clean up validation observer to prevent memory leaks
16877
- if (this.validationObserver) {
16878
- this.validationObserver.disconnect();
16879
- this.validationObserver = undefined;
16880
- }
16881
16752
  }
16882
16753
  /**
16883
16754
  * Sets focus on the native `input` in `ion-input`. Use this method instead of the global
@@ -16979,15 +16850,15 @@ class Input {
16979
16850
  * Renders the helper text or error text values
16980
16851
  */
16981
16852
  renderHintText() {
16982
- const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
16853
+ const { helperText, errorText, helperTextId, errorTextId } = this;
16983
16854
  return [
16984
- hAsync("div", { id: helperTextId, class: "helper-text", "aria-live": "polite" }, !isInvalid ? helperText : null),
16985
- hAsync("div", { id: errorTextId, class: "error-text", role: "alert" }, isInvalid ? errorText : null),
16855
+ hAsync("div", { id: helperTextId, class: "helper-text" }, helperText),
16856
+ hAsync("div", { id: errorTextId, class: "error-text" }, errorText),
16986
16857
  ];
16987
16858
  }
16988
16859
  getHintTextID() {
16989
- const { isInvalid, helperText, errorText, helperTextId, errorTextId } = this;
16990
- if (isInvalid && errorText) {
16860
+ const { el, helperText, errorText, helperTextId, errorTextId } = this;
16861
+ if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
16991
16862
  return errorTextId;
16992
16863
  }
16993
16864
  if (helperText) {
@@ -17100,7 +16971,7 @@ class Input {
17100
16971
  * TODO(FW-5592): Remove hasStartEndSlots condition
17101
16972
  */
17102
16973
  const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
17103
- return (hAsync(Host, { key: '7b7a7ffdf1b3528b2d6dff693beea2ae7553fd8c', class: createColorClasses$1(this.color, {
16974
+ return (hAsync(Host, { key: '41b2526627e7d2773a80f011b123284203a71ca0', class: createColorClasses$1(this.color, {
17104
16975
  [mode]: true,
17105
16976
  'has-value': hasValue,
17106
16977
  'has-focus': hasFocus,
@@ -17111,14 +16982,14 @@ class Input {
17111
16982
  'in-item': inItem,
17112
16983
  'in-item-color': hostContext('ion-item.ion-color', this.el),
17113
16984
  'input-disabled': disabled,
17114
- }) }, hAsync("label", { key: 'd8c75416ad9cc7623bcc68acd718cc1f71b56a31', class: "input-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), hAsync("div", { key: 'cfd382a5aa284e8248c6c4eb658ee3a97df73fdf', class: "native-wrapper", onClick: this.onLabelClick }, hAsync("slot", { key: '03237fe5befc1c6f6f54a751613a8f8cdee0106b', name: "start" }), hAsync("input", Object.assign({ key: 'cfb1a1fa653e9b6c91702f134adbef42568feab1', 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.isInvalid ? 'true' : undefined }, this.inheritedAttributes)), this.clearInput && !readonly && !disabled && (hAsync("button", { key: '446a5575018472bb2d916ce301c7faa92f7e0ffc', "aria-label": "reset", type: "button", class: "input-clear-icon", onPointerDown: (ev) => {
16985
+ }) }, hAsync("label", { key: '9ab078363e32528102b441ad1791d83f86fdcbdc', class: "input-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), hAsync("div", { key: 'e34b594980ec62e4c618e827fadf7669a39ad0d8', class: "native-wrapper", onClick: this.onLabelClick }, hAsync("slot", { key: '12dc04ead5502e9e5736240e918bf9331bf7b5d9', name: "start" }), hAsync("input", Object.assign({ key: 'df356eb4ced23109b2c0242f36dc043aba8782d6', 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: 'f79f68cabcd4ea99419331174a377827db0c0741', "aria-label": "reset", type: "button", class: "input-clear-icon", onPointerDown: (ev) => {
17115
16986
  /**
17116
16987
  * This prevents mobile browsers from
17117
16988
  * blurring the input when the clear
17118
16989
  * button is activated.
17119
16990
  */
17120
16991
  ev.preventDefault();
17121
- }, onClick: this.clearTextInput }, hAsync("ion-icon", { key: '2c3e12a424cba56b03eb0f0c2d1dca58ba1c81a8', "aria-hidden": "true", icon: clearIconData }))), hAsync("slot", { key: '5c01c0549264f08ac05bbca6caba7597bb435c9c', name: "end" })), shouldRenderHighlight && hAsync("div", { key: '3f26a10f86971a1e07ca7a9cb2b53989b51e0bca', class: "input-highlight" })), this.renderBottomContent()));
16992
+ }, onClick: this.clearTextInput }, hAsync("ion-icon", { key: '237ec07ec2e10f08818a332bb596578c2c49f770', "aria-hidden": "true", icon: clearIconData }))), hAsync("slot", { key: '1f0a3624aa3e8dc3c307a6762230ab698768a5e5', name: "end" })), shouldRenderHighlight && hAsync("div", { key: '8a8cbb82695a722a0010b53dd0b1f1f97534a20b', class: "input-highlight" })), this.renderBottomContent()));
17122
16993
  }
17123
16994
  get el() { return getElement(this); }
17124
16995
  static get watchers() { return {
@@ -17170,7 +17041,6 @@ class Input {
17170
17041
  "type": [1],
17171
17042
  "value": [1032],
17172
17043
  "hasFocus": [32],
17173
- "isInvalid": [32],
17174
17044
  "setFocus": [64],
17175
17045
  "getInputElement": [64]
17176
17046
  },
@@ -20046,6 +19916,9 @@ class Menu {
20046
19916
  * @param role The role of the element that is closing the menu.
20047
19917
  */
20048
19918
  setOpen(shouldOpen, animated = true, role) {
19919
+ var _a;
19920
+ // Blur the active element to prevent it from being kept focused inside an element that will be set with aria-hidden="true"
19921
+ (_a = document.activeElement) === null || _a === void 0 ? void 0 : _a.blur();
20049
19922
  return menuController._setOpen(this, shouldOpen, animated, role);
20050
19923
  }
20051
19924
  trapKeyboardFocus(ev, doc) {
@@ -20408,14 +20281,14 @@ class Menu {
20408
20281
  * the ionBackButton listener in the menu controller
20409
20282
  * will handle closing the menu when Escape is pressed.
20410
20283
  */
20411
- return (hAsync(Host, { key: 'a5c75aa40a34530b56ee3b98d706a5ac5ae300de', onKeyDown: shouldUseCloseWatcher() ? null : this.onKeydown, role: "navigation", "aria-label": inheritedAttributes['aria-label'] || 'menu', class: {
20284
+ return (hAsync(Host, { key: '70a427f3414a476414c3386efe6c8723fd37eccf', onKeyDown: shouldUseCloseWatcher() ? null : this.onKeydown, role: "navigation", "aria-label": inheritedAttributes['aria-label'] || 'menu', class: {
20412
20285
  [mode]: true,
20413
20286
  [`menu-type-${type}`]: true,
20414
20287
  'menu-enabled': !disabled,
20415
20288
  [`menu-side-${side}`]: true,
20416
20289
  'menu-pane-visible': isPaneVisible,
20417
20290
  'split-pane-side': hostContext('ion-split-pane', el),
20418
- } }, hAsync("div", { key: '3f5f70acd4d3ed6bb445122f4f01d73db738a75f', class: "menu-inner", part: "container", ref: (el) => (this.menuInnerEl = el) }, hAsync("slot", { key: '3161326c9330e7f7441299c428b87a91b31a83e9' })), hAsync("ion-backdrop", { key: '917b50f38489bdf03d0c642af8b4e4e172c7dc4c', ref: (el) => (this.backdropEl = el), class: "menu-backdrop", tappable: false, stopPropagation: false, part: "backdrop" })));
20291
+ } }, hAsync("div", { key: '83af04e5a47d5a92caafaf06088a7114ae61984b', class: "menu-inner", part: "container", ref: (el) => (this.menuInnerEl = el) }, hAsync("slot", { key: '7b35048642864bd0f30de9f6b61c949c1b601692' })), hAsync("ion-backdrop", { key: '347af516c7970d80dd11c6d1ed61e9a040ceb5fb', ref: (el) => (this.backdropEl = el), class: "menu-backdrop", tappable: false, stopPropagation: false, part: "backdrop" })));
20419
20292
  }
20420
20293
  get el() { return getElement(this); }
20421
20294
  static get watchers() { return {
@@ -25541,23 +25414,6 @@ class PickerColumn {
25541
25414
  var _a;
25542
25415
  return el ? (_a = el.getAttribute('aria-label')) !== null && _a !== void 0 ? _a : el.innerText : '';
25543
25416
  };
25544
- /**
25545
- * Render an element that overlays the column. This element is for assistive
25546
- * tech to allow users to navigate the column up/down. This element should receive
25547
- * focus as it listens for synthesized keyboard events as required by the
25548
- * slider role: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/slider_role
25549
- */
25550
- this.renderAssistiveFocusable = () => {
25551
- const { activeItem } = this;
25552
- const valueText = this.getOptionValueText(activeItem);
25553
- /**
25554
- * When using the picker, the valuetext provides important context that valuenow
25555
- * does not. Additionally, using non-zero valuemin/valuemax values can cause
25556
- * WebKit to incorrectly announce numeric valuetext values (such as a year
25557
- * like "2024") as percentages: https://bugs.webkit.org/show_bug.cgi?id=273126
25558
- */
25559
- return (hAsync("div", { ref: (el) => (this.assistiveFocusable = el), class: "assistive-focusable", role: "slider", tabindex: this.disabled ? undefined : 0, "aria-label": this.ariaLabel, "aria-valuemin": 0, "aria-valuemax": 0, "aria-valuenow": 0, "aria-valuetext": valueText, "aria-orientation": "vertical", onKeyDown: (ev) => this.onKeyDown(ev) }));
25560
- };
25561
25417
  }
25562
25418
  ariaLabelChanged(newValue) {
25563
25419
  this.ariaLabel = newValue;
@@ -25698,33 +25554,14 @@ class PickerColumn {
25698
25554
  render() {
25699
25555
  const { color, disabled, isActive, numericInput } = this;
25700
25556
  const mode = getIonMode$1(this);
25701
- return (hAsync(Host, { key: 'ea0280355b2f87895bf7dddd289ccf473aa759f3', class: createColorClasses$1(color, {
25557
+ return (hAsync(Host, { key: 'db903fd415f8a2d91994dececca481c1af8ba6a9', class: createColorClasses$1(color, {
25702
25558
  [mode]: true,
25703
25559
  ['picker-column-active']: isActive,
25704
25560
  ['picker-column-numeric-input']: numericInput,
25705
25561
  ['picker-column-disabled']: disabled,
25706
- }) }, this.renderAssistiveFocusable(), hAsync("slot", { key: '482992131cdeb85b1f61430d7fe1322a16345769', name: "prefix" }), hAsync("div", { key: '43f7f80d621d411ef366b3ca1396299e8c9a0c97', "aria-hidden": "true", class: "picker-opts", ref: (el) => {
25562
+ }) }, hAsync("slot", { key: '02ce9e1dd7df91afcd50b06416552bcffb5dec98', name: "prefix" }), hAsync("div", { key: '6dfd7d2429bec19244a6b1afb4448121963a031b', class: "picker-opts", ref: (el) => {
25707
25563
  this.scrollEl = el;
25708
- },
25709
- /**
25710
- * When an element has an overlay scroll style and
25711
- * a fixed height, Firefox will focus the scrollable
25712
- * container if the content exceeds the container's
25713
- * dimensions.
25714
- *
25715
- * This causes keyboard navigation to focus to this
25716
- * element instead of going to the next element in
25717
- * the tab order.
25718
- *
25719
- * The desired behavior is for the user to be able to
25720
- * focus the assistive focusable element and tab to
25721
- * the next element in the tab order. Instead of tabbing
25722
- * to this element.
25723
- *
25724
- * To prevent this, we set the tabIndex to -1. This
25725
- * will match the behavior of the other browsers.
25726
- */
25727
- tabIndex: -1 }, hAsync("div", { key: '13a9ee686132af32240710730765de4c0003a9e8', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), hAsync("div", { key: 'dbccba4920833cfcebe9b0fc763458ec3053705a', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), hAsync("div", { key: '682b43f83a5ea2e46067457f3af118535e111edb', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), hAsync("slot", { key: 'd27e1e1dc0504b2f4627a29912a05bb91e8e413a' }), hAsync("div", { key: '61c948dbb9cf7469aed3018542bc0954211585ba', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), hAsync("div", { key: 'cf46c277fbee65e35ff44ce0d53ce12aa9cbf9db', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), hAsync("div", { key: 'bbc0e2d491d3f836ab849493ade2f7fa6ad9244e', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0")), hAsync("slot", { key: 'd25cbbe14b2914fe7b878d43b4e3f4a8c8177d24', name: "suffix" })));
25564
+ }, role: "slider", tabindex: this.disabled ? undefined : 0, "aria-label": this.ariaLabel, "aria-valuemin": 0, "aria-valuemax": 0, "aria-valuenow": 0, "aria-valuetext": this.getOptionValueText(this.activeItem), "aria-orientation": "vertical", onKeyDown: (ev) => this.onKeyDown(ev) }, hAsync("div", { key: 'e30ce0b9cefbfe4d4441fa33acf595da31855c3f', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), hAsync("div", { key: '8be2bd293c12c6ba720d9b31d0d561a96f42e97d', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), hAsync("div", { key: '8afdcddddabbf646fbb55cb0ba4448309a2c1dd9', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), hAsync("slot", { key: '6aa0dacc34d6848575ad5b122b9046982308ca43' }), hAsync("div", { key: '92ec8a357414c1b779b11d1dd18fb87a7ee63982', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), hAsync("div", { key: 'b89457cb74b5907c25594ff6720ac54ca537e933', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), hAsync("div", { key: '5bbc92e6bc24de08e39873bf08c5b668373ac0f8', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0")), hAsync("slot", { key: 'd7bf2b519214f0f3576a4ca79844ad97827dd97f', name: "suffix" })));
25728
25565
  }
25729
25566
  get el() { return getElement(this); }
25730
25567
  static get watchers() { return {
@@ -26116,9 +25953,9 @@ const DECELERATION_FRICTION = 0.97;
26116
25953
  const MAX_PICKER_SPEED = 90;
26117
25954
  const TRANSITION_DURATION = 150;
26118
25955
 
26119
- const pickerColumnOptionIosCss = "button{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;width:100%;height:34px;border:0px;outline:none;background:transparent;color:inherit;font-family:var(--ion-font-family, inherit);font-size:inherit;line-height:34px;text-align:inherit;text-overflow:ellipsis;white-space:nowrap;cursor:pointer;overflow:hidden}:host(.option-disabled){opacity:0.4}:host(.option-disabled) button{cursor:default}";
25956
+ const pickerColumnOptionIosCss = ".picker-column-option-button{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;width:100%;height:34px;border:0px;outline:none;background:transparent;color:inherit;font-family:var(--ion-font-family, inherit);font-size:inherit;line-height:34px;text-align:inherit;text-overflow:ellipsis;white-space:nowrap;cursor:pointer;overflow:hidden}:host(.option-disabled){opacity:0.4}:host(.option-disabled) .picker-column-option-button{cursor:default}";
26120
25957
 
26121
- const pickerColumnOptionMdCss = "button{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;width:100%;height:34px;border:0px;outline:none;background:transparent;color:inherit;font-family:var(--ion-font-family, inherit);font-size:inherit;line-height:34px;text-align:inherit;text-overflow:ellipsis;white-space:nowrap;cursor:pointer;overflow:hidden}:host(.option-disabled){opacity:0.4}:host(.option-disabled) button{cursor:default}:host(.option-active){color:var(--ion-color-base)}";
25958
+ const pickerColumnOptionMdCss = ".picker-column-option-button{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;width:100%;height:34px;border:0px;outline:none;background:transparent;color:inherit;font-family:var(--ion-font-family, inherit);font-size:inherit;line-height:34px;text-align:inherit;text-overflow:ellipsis;white-space:nowrap;cursor:pointer;overflow:hidden}:host(.option-disabled){opacity:0.4}:host(.option-disabled) .picker-column-option-button{cursor:default}:host(.option-active){color:var(--ion-color-base)}";
26122
25959
 
26123
25960
  class PickerColumnOption {
26124
25961
  constructor(hostRef) {
@@ -26210,7 +26047,7 @@ class PickerColumnOption {
26210
26047
  return (hAsync(Host, { key: 'f816729941aabcb31ddfdce3ffe2e2139030d715', class: createColorClasses$1(color, {
26211
26048
  [mode]: true,
26212
26049
  ['option-disabled']: disabled,
26213
- }) }, hAsync("button", { key: '48dff7833bb60fc8331cd353a0885e6affa683d1', tabindex: "-1", "aria-label": ariaLabel, disabled: disabled, onClick: () => this.onClick() }, hAsync("slot", { key: 'f9224d0e7b7aa6c05b29abfdcfe0f30ad6ee3141' }))));
26050
+ }) }, hAsync("div", { key: 'd942de84fd14d7dc06b1e5cf4f7920d1dc3c6371', class: 'picker-column-option-button', role: "button", "aria-label": ariaLabel, onClick: () => this.onClick() }, hAsync("slot", { key: 'b0df5717b42209e649097209a01476e1a66f5c5c' }))));
26214
26051
  }
26215
26052
  get el() { return getElement(this); }
26216
26053
  static get watchers() { return {
@@ -34930,10 +34767,6 @@ class Textarea {
34930
34767
  * is applied in both cases.
34931
34768
  */
34932
34769
  this.hasFocus = false;
34933
- /**
34934
- * Track validation state for proper aria-live announcements
34935
- */
34936
- this.isInvalid = false;
34937
34770
  /**
34938
34771
  * Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user.
34939
34772
  * Available options: `"off"`, `"none"`, `"on"`, `"sentences"`, `"words"`, `"characters"`.
@@ -35023,18 +34856,6 @@ class Textarea {
35023
34856
  }
35024
34857
  this.didTextareaClearOnEdit = false;
35025
34858
  this.ionBlur.emit(ev);
35026
- /**
35027
- * Check validation state after blur to handle framework-managed classes.
35028
- * Frameworks like Angular update classes asynchronously, often using
35029
- * requestAnimationFrame or promises. Using setTimeout ensures we check
35030
- * after all microtasks and animation frames have completed.
35031
- */
35032
- setTimeout(() => {
35033
- const newIsInvalid = this.checkValidationState();
35034
- if (this.isInvalid !== newIsInvalid) {
35035
- this.isInvalid = newIsInvalid;
35036
- }
35037
- }, 100);
35038
34859
  };
35039
34860
  this.onKeyDown = (ev) => {
35040
34861
  this.checkClearOnEdit(ev);
@@ -35091,27 +34912,10 @@ class Textarea {
35091
34912
  this.el.click();
35092
34913
  }
35093
34914
  }
35094
- /**
35095
- * Checks if the textarea is in an invalid state based on validation classes
35096
- */
35097
- checkValidationState() {
35098
- // Check for both Ionic and Angular validation classes on the element itself
35099
- // Angular applies ng-touched/ng-invalid directly to the host element with ngModel
35100
- const hasIonTouched = this.el.classList.contains('ion-touched');
35101
- const hasIonInvalid = this.el.classList.contains('ion-invalid');
35102
- const hasNgTouched = this.el.classList.contains('ng-touched');
35103
- const hasNgInvalid = this.el.classList.contains('ng-invalid');
35104
- // Return true if we have both touched and invalid states from either framework
35105
- const isTouched = hasIonTouched || hasNgTouched;
35106
- const isInvalid = hasIonInvalid || hasNgInvalid;
35107
- return isTouched && isInvalid;
35108
- }
35109
34915
  connectedCallback() {
35110
34916
  const { el } = this;
35111
34917
  this.slotMutationController = createSlotMutationController(el, ['label', 'start', 'end'], () => forceUpdate());
35112
34918
  this.notchController = createNotchController(el, () => this.notchSpacerEl, () => this.labelSlot);
35113
- // Always set initial state
35114
- this.isInvalid = this.checkValidationState();
35115
34919
  this.debounceChanged();
35116
34920
  }
35117
34921
  disconnectedCallback() {
@@ -35123,11 +34927,6 @@ class Textarea {
35123
34927
  this.notchController.destroy();
35124
34928
  this.notchController = undefined;
35125
34929
  }
35126
- // Clean up validation observer to prevent memory leaks
35127
- if (this.validationObserver) {
35128
- this.validationObserver.disconnect();
35129
- this.validationObserver = undefined;
35130
- }
35131
34930
  }
35132
34931
  componentWillLoad() {
35133
34932
  this.inheritedAttributes = Object.assign(Object.assign({}, inheritAriaAttributes(this.el)), inheritAttributes$1(this.el, ['data-form-type', 'title', 'tabindex', 'dir']));
@@ -35298,15 +35097,15 @@ class Textarea {
35298
35097
  * Renders the helper text or error text values
35299
35098
  */
35300
35099
  renderHintText() {
35301
- const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
35100
+ const { helperText, errorText, helperTextId, errorTextId } = this;
35302
35101
  return [
35303
- hAsync("div", { id: helperTextId, class: "helper-text", "aria-live": "polite" }, !isInvalid ? helperText : null),
35304
- hAsync("div", { id: errorTextId, class: "error-text", role: "alert" }, isInvalid ? errorText : null),
35102
+ hAsync("div", { id: helperTextId, class: "helper-text" }, helperText),
35103
+ hAsync("div", { id: errorTextId, class: "error-text" }, errorText),
35305
35104
  ];
35306
35105
  }
35307
35106
  getHintTextID() {
35308
- const { isInvalid, helperText, errorText, helperTextId, errorTextId } = this;
35309
- if (isInvalid && errorText) {
35107
+ const { el, helperText, errorText, helperTextId, errorTextId } = this;
35108
+ if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
35310
35109
  return errorTextId;
35311
35110
  }
35312
35111
  if (helperText) {
@@ -35365,7 +35164,7 @@ class Textarea {
35365
35164
  * TODO(FW-5592): Remove hasStartEndSlots condition
35366
35165
  */
35367
35166
  const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
35368
- return (hAsync(Host, { key: 'e7e09574df34c1b51b97b3ed89c2af2747c32308', class: createColorClasses$1(this.color, {
35167
+ return (hAsync(Host, { key: 'd9f2ede0107987fc42c99e310cd2336bad5a5755', class: createColorClasses$1(this.color, {
35369
35168
  [mode]: true,
35370
35169
  'has-value': hasValue,
35371
35170
  'has-focus': hasFocus,
@@ -35374,7 +35173,7 @@ class Textarea {
35374
35173
  [`textarea-shape-${shape}`]: shape !== undefined,
35375
35174
  [`textarea-label-placement-${labelPlacement}`]: true,
35376
35175
  'textarea-disabled': disabled,
35377
- }) }, hAsync("label", { key: '8a8809ea9b9b39241adc38fbb0cdb23048f35eea', class: "textarea-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), hAsync("div", { key: '206f75a83d3177c9de4ba22ca5e826406c989de6', class: "textarea-wrapper-inner" }, hAsync("div", { key: '43bca68664d9abe3e397bd27cd4439fa8d4311db', class: "start-slot-wrapper" }, hAsync("slot", { key: 'f1eb97f407bdb000431f736243650f38858046f8', name: "start" })), hAsync("div", { key: '788d344ef9be934a1e83e29216cf23bede42f160', class: "native-wrapper", ref: (el) => (this.textareaWrapper = el) }, hAsync("textarea", Object.assign({ key: '5ef713d4781f7c49e2f66002ae0d9feb69b3bddb', 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.isInvalid ? 'true' : undefined }, this.inheritedAttributes), value)), hAsync("div", { key: '775d7866f86709904d0a57fc47e9ba94e5b052e9', class: "end-slot-wrapper" }, hAsync("slot", { key: 'cdb98adb014a3bf02579a729c33d8ee18731f692', name: "end" }))), shouldRenderHighlight && hAsync("div", { key: '4c319ec9615a125b3cef774c73f55a23a938d6d9', class: "textarea-highlight" })), this.renderBottomContent()));
35176
+ }) }, hAsync("label", { key: '9de598b95237462bb3bccffaefe83afbb43554b8', class: "textarea-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), hAsync("div", { key: 'e33c426c6541d723ccc246bb404c03687726ff83', class: "textarea-wrapper-inner" }, hAsync("div", { key: '521e11af9d54d281b0a2b1c25bcfc6f742c18296', class: "start-slot-wrapper" }, hAsync("slot", { key: '515523f6ca3ce0e5dd08f3275c21a190fb1ca177', name: "start" })), hAsync("div", { key: '916e01e00de8400ae00ef06bc1fb62d8be2eee08', class: "native-wrapper", ref: (el) => (this.textareaWrapper = el) }, hAsync("textarea", Object.assign({ key: '810271e6532d90e27dab1fcb26546113c1ce9cb0', 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: '80aca9ea9546dca9d38efd291a6b0be384bb6978', class: "end-slot-wrapper" }, hAsync("slot", { key: '407fab16c66a9f4a542369bfecc0d9afa0065977', name: "end" }))), shouldRenderHighlight && hAsync("div", { key: 'f00523a6698fac8a1996e04303487bef01d10f25', class: "textarea-highlight" })), this.renderBottomContent()));
35378
35177
  }
35379
35178
  get el() { return getElement(this); }
35380
35179
  static get watchers() { return {
@@ -35419,7 +35218,6 @@ class Textarea {
35419
35218
  "labelPlacement": [1, "label-placement"],
35420
35219
  "shape": [1],
35421
35220
  "hasFocus": [32],
35422
- "isInvalid": [32],
35423
35221
  "setFocus": [64],
35424
35222
  "getInputElement": [64]
35425
35223
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ionic/core",
3
- "version": "8.7.4-dev.11756220757.185b8cbf",
3
+ "version": "8.7.4-dev.11756388042.1a103a79",
4
4
  "description": "Base components for Ionic",
5
5
  "keywords": [
6
6
  "ionic",
@@ -44,7 +44,7 @@
44
44
  "@clack/prompts": "^0.11.0",
45
45
  "@ionic/eslint-config": "^0.3.0",
46
46
  "@ionic/prettier-config": "^2.0.0",
47
- "@playwright/test": "^1.54.2",
47
+ "@playwright/test": "^1.55.0",
48
48
  "@rollup/plugin-node-resolve": "^8.4.0",
49
49
  "@rollup/plugin-virtual": "^2.0.3",
50
50
  "@stencil/angular-output-target": "^0.10.0",