voyager-ionic-core 8.7.6 → 8.7.9

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 (251) hide show
  1. package/components/button.js +3 -7
  2. package/components/checkbox.js +4 -7
  3. package/components/header.js +42 -4
  4. package/components/index2.js +74 -3
  5. package/components/ion-accordion.js +93 -14
  6. package/components/ion-input.js +6 -14
  7. package/components/ion-select.js +58 -10
  8. package/components/ion-textarea.js +5 -13
  9. package/components/ion-toggle.js +4 -7
  10. package/components/{notch-controller.js → validity.js} +14 -1
  11. package/dist/cjs/{index-CD5Rjp23.js → index-094mMFB-.js} +76 -5
  12. package/dist/cjs/index.cjs.js +3 -3
  13. package/dist/cjs/ion-accordion_2.cjs.entry.js +91 -13
  14. package/dist/cjs/ion-app_8.cjs.entry.js +43 -5
  15. package/dist/cjs/ion-button_2.cjs.entry.js +3 -7
  16. package/dist/cjs/ion-checkbox.cjs.entry.js +4 -7
  17. package/dist/cjs/ion-input.cjs.entry.js +7 -15
  18. package/dist/cjs/ion-modal.cjs.entry.js +1 -1
  19. package/dist/cjs/ion-nav_2.cjs.entry.js +1 -1
  20. package/dist/cjs/ion-popover.cjs.entry.js +1 -1
  21. package/dist/cjs/ion-select_3.cjs.entry.js +56 -10
  22. package/dist/cjs/ion-textarea.cjs.entry.js +6 -14
  23. package/dist/cjs/ion-toggle.cjs.entry.js +4 -7
  24. package/dist/cjs/ionic.cjs.js +1 -1
  25. package/dist/cjs/{ios.transition-j9CclgEW.js → ios.transition-BOt_uW73.js} +1 -1
  26. package/dist/cjs/loader.cjs.js +1 -1
  27. package/dist/cjs/{md.transition-CwFyRSfv.js → md.transition-Dt968VXB.js} +1 -1
  28. package/dist/cjs/{notch-controller-Bzqhjm4f.js → validity-C8QoAYT2.js} +14 -0
  29. package/dist/collection/components/accordion/accordion.js +93 -14
  30. package/dist/collection/components/button/button.js +3 -7
  31. package/dist/collection/components/checkbox/checkbox.js +4 -7
  32. package/dist/collection/components/header/header.ios.css +27 -1
  33. package/dist/collection/components/header/header.js +5 -4
  34. package/dist/collection/components/header/header.utils.js +37 -0
  35. package/dist/collection/components/input/input.js +6 -14
  36. package/dist/collection/components/select/select.js +59 -11
  37. package/dist/collection/components/textarea/textarea.js +5 -13
  38. package/dist/collection/components/toggle/toggle.js +4 -7
  39. package/dist/collection/utils/forms/index.js +1 -0
  40. package/dist/collection/utils/forms/validity.js +15 -0
  41. package/dist/collection/utils/test/playwright/page/utils/spy-on-event.js +32 -0
  42. package/dist/collection/utils/transition/index.js +74 -3
  43. package/dist/docs.json +1 -1
  44. package/dist/esm/{index-D6G2seR8.js → index-r2D9DEro.js} +76 -5
  45. package/dist/esm/index.js +3 -3
  46. package/dist/esm/ion-accordion_2.entry.js +91 -13
  47. package/dist/esm/ion-app_8.entry.js +43 -5
  48. package/dist/esm/ion-button_2.entry.js +3 -7
  49. package/dist/esm/ion-checkbox.entry.js +4 -7
  50. package/dist/esm/ion-input.entry.js +6 -14
  51. package/dist/esm/ion-modal.entry.js +1 -1
  52. package/dist/esm/ion-nav_2.entry.js +1 -1
  53. package/dist/esm/ion-popover.entry.js +1 -1
  54. package/dist/esm/ion-select_3.entry.js +55 -9
  55. package/dist/esm/ion-textarea.entry.js +5 -13
  56. package/dist/esm/ion-toggle.entry.js +4 -7
  57. package/dist/esm/ionic.js +1 -1
  58. package/dist/esm/{ios.transition-Bpq9ixwv.js → ios.transition-BDzw0_Hm.js} +1 -1
  59. package/dist/esm/loader.js +1 -1
  60. package/dist/esm/{md.transition-zOA0oanq.js → md.transition-BzDYi3qq.js} +1 -1
  61. package/dist/esm/{notch-controller-BwelN_JM.js → validity-B8oWougr.js} +14 -1
  62. package/dist/ionic/index.esm.js +1 -1
  63. package/dist/ionic/ionic.esm.js +1 -1
  64. package/dist/ionic/p-43ed1ef5.entry.js +4 -0
  65. package/dist/ionic/p-4cc26913.entry.js +4 -0
  66. package/dist/ionic/{p-323421af.entry.js → p-5a39a99a.entry.js} +1 -1
  67. package/dist/ionic/p-5fb517e4.entry.js +4 -0
  68. package/dist/ionic/p-8bdfc8f6.entry.js +4 -0
  69. package/dist/ionic/{p-9a36e2e7.entry.js → p-95bddd49.entry.js} +1 -1
  70. package/dist/ionic/{p-DPhQmGJN.js → p-C7hRNDhM.js} +1 -1
  71. package/dist/ionic/p-DUt5fQmA.js +4 -0
  72. package/dist/ionic/{p-9R1XyICs.js → p-DZRJwG4S.js} +1 -1
  73. package/dist/ionic/{p-DCv9sLH2.js → p-DieJyvMP.js} +1 -1
  74. package/dist/ionic/p-d0a2a1ab.entry.js +4 -0
  75. package/dist/ionic/p-dc2e126d.entry.js +4 -0
  76. package/dist/ionic/{p-de7b5fa3.entry.js → p-e16b69e1.entry.js} +1 -1
  77. package/dist/ionic/p-f65f9308.entry.js +4 -0
  78. package/dist/ionic/p-fc278823.entry.js +4 -0
  79. package/dist/ionic/svg/checkbox-outline.svg +1 -0
  80. package/dist/ionic/svg/checkbox-sharp.svg +1 -0
  81. package/dist/ionic/svg/checkbox.svg +1 -0
  82. package/dist/ionic/svg/checkmark-circle-outline.svg +1 -0
  83. package/dist/ionic/svg/checkmark-circle-sharp.svg +1 -0
  84. package/dist/ionic/svg/checkmark-circle.svg +1 -0
  85. package/dist/ionic/svg/checkmark-done-circle-outline.svg +1 -0
  86. package/dist/ionic/svg/checkmark-done-circle-sharp.svg +1 -0
  87. package/dist/ionic/svg/checkmark-done-circle.svg +1 -0
  88. package/dist/ionic/svg/checkmark-done-outline.svg +1 -0
  89. package/dist/ionic/svg/checkmark-done-sharp.svg +1 -0
  90. package/dist/ionic/svg/checkmark-done.svg +1 -0
  91. package/dist/ionic/svg/checkmark-outline.svg +1 -0
  92. package/dist/ionic/svg/checkmark-sharp.svg +1 -0
  93. package/dist/ionic/svg/checkmark.svg +1 -0
  94. package/dist/ionic/svg/chevron-back-circle-outline.svg +1 -0
  95. package/dist/ionic/svg/chevron-back-circle-sharp.svg +1 -0
  96. package/dist/ionic/svg/chevron-back-circle.svg +1 -0
  97. package/dist/ionic/svg/chevron-back-outline.svg +1 -0
  98. package/dist/ionic/svg/chevron-back-sharp.svg +1 -0
  99. package/dist/ionic/svg/chevron-back.svg +1 -0
  100. package/dist/ionic/svg/chevron-collapse-outline.svg +1 -0
  101. package/dist/ionic/svg/chevron-collapse-sharp.svg +1 -0
  102. package/dist/ionic/svg/chevron-collapse.svg +1 -0
  103. package/dist/ionic/svg/chevron-down-circle-outline.svg +1 -0
  104. package/dist/ionic/svg/chevron-down-circle-sharp.svg +1 -0
  105. package/dist/ionic/svg/chevron-down-circle.svg +1 -0
  106. package/dist/ionic/svg/chevron-down-outline.svg +1 -0
  107. package/dist/ionic/svg/chevron-down-sharp.svg +1 -0
  108. package/dist/ionic/svg/chevron-down.svg +1 -0
  109. package/dist/ionic/svg/chevron-expand-outline.svg +1 -0
  110. package/dist/ionic/svg/chevron-expand-sharp.svg +1 -0
  111. package/dist/ionic/svg/chevron-expand.svg +1 -0
  112. package/dist/ionic/svg/chevron-forward-circle-outline.svg +1 -0
  113. package/dist/ionic/svg/chevron-forward-circle-sharp.svg +1 -0
  114. package/dist/ionic/svg/chevron-forward-circle.svg +1 -0
  115. package/dist/ionic/svg/chevron-forward-outline.svg +1 -0
  116. package/dist/ionic/svg/chevron-forward-sharp.svg +1 -0
  117. package/dist/ionic/svg/chevron-forward.svg +1 -0
  118. package/dist/ionic/svg/chevron-up-circle-outline.svg +1 -0
  119. package/dist/ionic/svg/chevron-up-circle-sharp.svg +1 -0
  120. package/dist/ionic/svg/chevron-up-circle.svg +1 -0
  121. package/dist/ionic/svg/chevron-up-outline.svg +1 -0
  122. package/dist/ionic/svg/chevron-up-sharp.svg +1 -0
  123. package/dist/ionic/svg/chevron-up.svg +1 -0
  124. package/dist/ionic/svg/clipboard-outline.svg +1 -0
  125. package/dist/ionic/svg/clipboard-sharp.svg +1 -0
  126. package/dist/ionic/svg/clipboard.svg +1 -0
  127. package/dist/ionic/svg/close-circle-outline.svg +1 -0
  128. package/dist/ionic/svg/close-circle-sharp.svg +1 -0
  129. package/dist/ionic/svg/close-circle.svg +1 -0
  130. package/dist/ionic/svg/close-outline.svg +1 -0
  131. package/dist/ionic/svg/close-sharp.svg +1 -0
  132. package/dist/ionic/svg/close.svg +1 -0
  133. package/dist/ionic/svg/cloud-circle-outline.svg +1 -0
  134. package/dist/ionic/svg/cloud-circle-sharp.svg +1 -0
  135. package/dist/ionic/svg/cloud-circle.svg +1 -0
  136. package/dist/ionic/svg/cloud-done-outline.svg +1 -0
  137. package/dist/ionic/svg/cloud-done-sharp.svg +1 -0
  138. package/dist/ionic/svg/cloud-done.svg +1 -0
  139. package/dist/ionic/svg/cloud-download-outline.svg +1 -0
  140. package/dist/ionic/svg/cloud-download-sharp.svg +1 -0
  141. package/dist/ionic/svg/cloud-download.svg +1 -0
  142. package/dist/ionic/svg/cloud-offline-outline.svg +1 -0
  143. package/dist/ionic/svg/cloud-offline-sharp.svg +1 -0
  144. package/dist/ionic/svg/cloud-offline.svg +1 -0
  145. package/dist/ionic/svg/cloud-outline.svg +1 -0
  146. package/dist/ionic/svg/cloud-sharp.svg +1 -0
  147. package/dist/ionic/svg/cloud-upload-outline.svg +1 -0
  148. package/dist/ionic/svg/cloud-upload-sharp.svg +1 -0
  149. package/dist/ionic/svg/cloud-upload.svg +1 -0
  150. package/dist/ionic/svg/cloud.svg +1 -0
  151. package/dist/ionic/svg/cloudy-night-outline.svg +1 -0
  152. package/dist/ionic/svg/cloudy-night-sharp.svg +1 -0
  153. package/dist/ionic/svg/cloudy-night.svg +1 -0
  154. package/dist/ionic/svg/cloudy-outline.svg +1 -0
  155. package/dist/ionic/svg/cloudy-sharp.svg +1 -0
  156. package/dist/ionic/svg/cloudy.svg +1 -0
  157. package/dist/ionic/svg/code-download-outline.svg +1 -0
  158. package/dist/ionic/svg/code-download-sharp.svg +1 -0
  159. package/dist/ionic/svg/code-download.svg +1 -0
  160. package/dist/ionic/svg/code-outline.svg +1 -0
  161. package/dist/ionic/svg/code-sharp.svg +1 -0
  162. package/dist/ionic/svg/code-slash-outline.svg +1 -0
  163. package/dist/ionic/svg/code-slash-sharp.svg +1 -0
  164. package/dist/ionic/svg/code-slash.svg +1 -0
  165. package/dist/ionic/svg/code-working-outline.svg +1 -0
  166. package/dist/ionic/svg/code-working-sharp.svg +1 -0
  167. package/dist/ionic/svg/code-working.svg +1 -0
  168. package/dist/ionic/svg/code.svg +1 -0
  169. package/dist/ionic/svg/cog-outline.svg +1 -0
  170. package/dist/ionic/svg/cog-sharp.svg +1 -0
  171. package/dist/ionic/svg/cog.svg +1 -0
  172. package/dist/ionic/svg/color-fill-outline.svg +1 -0
  173. package/dist/ionic/svg/color-fill-sharp.svg +1 -0
  174. package/dist/ionic/svg/color-fill.svg +1 -0
  175. package/dist/ionic/svg/color-filter-outline.svg +1 -0
  176. package/dist/ionic/svg/color-filter-sharp.svg +1 -0
  177. package/dist/ionic/svg/color-filter.svg +1 -0
  178. package/dist/ionic/svg/color-palette-outline.svg +1 -0
  179. package/dist/ionic/svg/color-palette-sharp.svg +1 -0
  180. package/dist/ionic/svg/color-palette.svg +1 -0
  181. package/dist/ionic/svg/color-wand-outline.svg +1 -0
  182. package/dist/ionic/svg/color-wand-sharp.svg +1 -0
  183. package/dist/ionic/svg/color-wand.svg +1 -0
  184. package/dist/ionic/svg/compass-outline.svg +1 -0
  185. package/dist/ionic/svg/compass-sharp.svg +1 -0
  186. package/dist/ionic/svg/compass.svg +1 -0
  187. package/dist/ionic/svg/construct-outline.svg +1 -0
  188. package/dist/ionic/svg/construct-sharp.svg +1 -0
  189. package/dist/ionic/svg/construct.svg +1 -0
  190. package/dist/ionic/svg/contract-outline.svg +1 -0
  191. package/dist/ionic/svg/contract-sharp.svg +1 -0
  192. package/dist/ionic/svg/contract.svg +1 -0
  193. package/dist/ionic/svg/contrast-outline.svg +1 -0
  194. package/dist/ionic/svg/contrast-sharp.svg +1 -0
  195. package/dist/ionic/svg/contrast.svg +1 -0
  196. package/dist/ionic/svg/copy-outline.svg +1 -0
  197. package/dist/ionic/svg/copy-sharp.svg +1 -0
  198. package/dist/ionic/svg/copy.svg +1 -0
  199. package/dist/ionic/svg/create-outline.svg +1 -0
  200. package/dist/ionic/svg/create-sharp.svg +1 -0
  201. package/dist/ionic/svg/create.svg +1 -0
  202. package/dist/ionic/svg/crop-outline.svg +1 -0
  203. package/dist/ionic/svg/crop-sharp.svg +1 -0
  204. package/dist/ionic/svg/crop.svg +1 -0
  205. package/dist/ionic/svg/cube-outline.svg +1 -0
  206. package/dist/ionic/svg/cube-sharp.svg +1 -0
  207. package/dist/ionic/svg/cube.svg +1 -0
  208. package/dist/ionic/svg/cut-outline.svg +1 -0
  209. package/dist/ionic/svg/cut-sharp.svg +1 -0
  210. package/dist/ionic/svg/cut.svg +1 -0
  211. package/dist/ionic/svg/desktop-outline.svg +1 -0
  212. package/dist/ionic/svg/desktop-sharp.svg +1 -0
  213. package/dist/ionic/svg/desktop.svg +1 -0
  214. package/dist/ionic/svg/diamond-outline.svg +1 -0
  215. package/dist/ionic/svg/diamond-sharp.svg +1 -0
  216. package/dist/ionic/svg/diamond.svg +1 -0
  217. package/dist/ionic/svg/dice-outline.svg +1 -0
  218. package/dist/ionic/svg/dice-sharp.svg +1 -0
  219. package/dist/ionic/svg/dice.svg +1 -0
  220. package/dist/ionic/svg/disc-outline.svg +1 -0
  221. package/dist/ionic/svg/disc-sharp.svg +1 -0
  222. package/dist/ionic/svg/disc.svg +1 -0
  223. package/dist/ionic/svg/document-attach-outline.svg +1 -0
  224. package/dist/ionic/svg/document-attach-sharp.svg +1 -0
  225. package/dist/ionic/svg/document-attach.svg +1 -0
  226. package/dist/ionic/svg/document-lock-outline.svg +1 -0
  227. package/dist/ionic/svg/document-lock-sharp.svg +1 -0
  228. package/dist/ionic/svg/document-lock.svg +1 -0
  229. package/dist/ionic/svg/document-outline.svg +1 -0
  230. package/dist/types/components/accordion/accordion.d.ts +18 -1
  231. package/dist/types/components/checkbox/checkbox.d.ts +0 -1
  232. package/dist/types/components/header/header.utils.d.ts +10 -0
  233. package/dist/types/components/input/input.d.ts +0 -4
  234. package/dist/types/components/select/select.d.ts +6 -0
  235. package/dist/types/components/textarea/textarea.d.ts +0 -4
  236. package/dist/types/components/toggle/toggle.d.ts +0 -1
  237. package/dist/types/utils/forms/index.d.ts +1 -0
  238. package/dist/types/utils/forms/validity.d.ts +10 -0
  239. package/dist/types/utils/transition/index.d.ts +9 -0
  240. package/hydrate/index.js +262 -73
  241. package/hydrate/index.mjs +262 -73
  242. package/package.json +3 -3
  243. package/dist/ionic/p-1c8a476d.entry.js +0 -4
  244. package/dist/ionic/p-3355a2ff.entry.js +0 -4
  245. package/dist/ionic/p-62e50f80.entry.js +0 -4
  246. package/dist/ionic/p-785026d7.entry.js +0 -4
  247. package/dist/ionic/p-78c74a3e.entry.js +0 -4
  248. package/dist/ionic/p-83fc84e7.entry.js +0 -4
  249. package/dist/ionic/p-913a7c1e.entry.js +0 -4
  250. package/dist/ionic/p-CMhMiYSX.js +0 -4
  251. package/dist/ionic/p-c17c0a01.entry.js +0 -4
@@ -219,11 +219,7 @@ const Button = /*@__PURE__*/ proxyCustomElement(class Button extends HTMLElement
219
219
  target,
220
220
  };
221
221
  let fill = this.fill;
222
- /**
223
- * We check both undefined and null to
224
- * work around https://github.com/ionic-team/stencil/issues/3586.
225
- */
226
- if (fill == null) {
222
+ if (fill === undefined) {
227
223
  fill = this.inToolbar || this.inListHeader ? 'clear' : 'solid';
228
224
  }
229
225
  /**
@@ -236,7 +232,7 @@ const Button = /*@__PURE__*/ proxyCustomElement(class Button extends HTMLElement
236
232
  {
237
233
  type !== 'button' && this.renderHiddenButton();
238
234
  }
239
- return (h(Host, { key: 'b105ad09215adb3ca2298acdadf0dc9154bbb9b0', onClick: this.handleClick, "aria-disabled": disabled ? 'true' : null, class: createColorClasses(color, {
235
+ return (h(Host, { key: 'ed82ea53705523f9afc5f1a9addff44cc6424f27', onClick: this.handleClick, "aria-disabled": disabled ? 'true' : null, class: createColorClasses(color, {
240
236
  [mode]: true,
241
237
  [buttonType]: true,
242
238
  [`${buttonType}-${expand}`]: expand !== undefined,
@@ -251,7 +247,7 @@ const Button = /*@__PURE__*/ proxyCustomElement(class Button extends HTMLElement
251
247
  'button-disabled': disabled,
252
248
  'ion-activatable': true,
253
249
  'ion-focusable': true,
254
- }) }, h(TagType, Object.assign({ key: '66b4e7112bcb9e41d5a723fbbadb0a3104f9ee1d' }, attrs, { class: "button-native", part: "native", disabled: disabled, onFocus: this.onFocus, onBlur: this.onBlur }, inheritedAttributes), h("span", { key: '1439fc3da280221028dcf7ce8ec9dab273c4d4bb', class: "button-inner" }, h("slot", { key: 'd5269ae1afc87ec7b99746032f59cbae93720a9f', name: "icon-only", onSlotchange: this.slotChanged }), h("slot", { key: '461c83e97aa246aa86d83e14f1e15a288d35041e', name: "start" }), h("slot", { key: '807170d47101f9f6a333dd4ff489c89284f306fe' }), h("slot", { key: 'e67f116dd0349a0d27893e4f3ff0ccef1d402f80', name: "end" })), mode === 'md' && h("ion-ripple-effect", { key: '273f0bd9645a36c1bfd18a5c2ab4f81e22b7b989', type: this.rippleType }))));
250
+ }) }, h(TagType, Object.assign({ key: 'fadec13053469dd0405bbbc61b70ced568aa4826' }, attrs, { class: "button-native", part: "native", disabled: disabled, onFocus: this.onFocus, onBlur: this.onBlur }, inheritedAttributes), h("span", { key: '6bf0e5144fb1148002e88038522402b789689d2c', class: "button-inner" }, h("slot", { key: '25da0ca155cfa9e2754842c34f4fd09f576ac2d2', name: "icon-only", onSlotchange: this.slotChanged }), h("slot", { key: '51414065bb11953ec9d818f8d9353589bc9072c5', name: "start" }), h("slot", { key: 'c9b5f8842aeabd20628df2f4600f1257ea913d8d' }), h("slot", { key: '478dd3671c7be1909fc84e672f0fa8dfe6082263', name: "end" })), mode === 'md' && h("ion-ripple-effect", { key: 'e1d55f85a55144d743f58a5914cd116cb065fa8c', type: this.rippleType }))));
255
251
  }
256
252
  get el() { return this; }
257
253
  static get watchers() { return {
@@ -78,7 +78,6 @@ const Checkbox = /*@__PURE__*/ proxyCustomElement(class Checkbox extends HTMLEle
78
78
  };
79
79
  this.toggleChecked = (ev) => {
80
80
  ev.preventDefault();
81
- this.setFocus();
82
81
  this.setChecked(!this.checked);
83
82
  this.indeterminate = false;
84
83
  };
@@ -115,9 +114,7 @@ const Checkbox = /*@__PURE__*/ proxyCustomElement(class Checkbox extends HTMLEle
115
114
  }
116
115
  /** @internal */
117
116
  async setFocus() {
118
- if (this.focusEl) {
119
- this.focusEl.focus();
120
- }
117
+ this.el.focus();
121
118
  }
122
119
  getHintTextID() {
123
120
  const { el, helperText, errorText, helperTextId, errorTextId } = this;
@@ -153,7 +150,7 @@ const Checkbox = /*@__PURE__*/ proxyCustomElement(class Checkbox extends HTMLEle
153
150
  renderHiddenInput(true, el, name, checked ? value : '', disabled);
154
151
  // The host element must have a checkbox role to ensure proper VoiceOver
155
152
  // support in Safari for accessibility.
156
- return (h(Host, { key: '26cbe7220e555107200e9b5deeae754aa534a80b', role: "checkbox", "aria-checked": indeterminate ? 'mixed' : `${checked}`, "aria-describedby": this.getHintTextID(), "aria-invalid": this.getHintTextID() === this.errorTextId, "aria-labelledby": hasLabelContent ? this.inputLabelId : null, "aria-label": inheritedAttributes['aria-label'] || null, "aria-disabled": disabled ? 'true' : null, tabindex: disabled ? undefined : 0, onKeyDown: this.onKeyDown, class: createColorClasses(color, {
153
+ return (h(Host, { key: 'ee2e02d28f9d15a1ec746609f7e9559444f621e5', role: "checkbox", "aria-checked": indeterminate ? 'mixed' : `${checked}`, "aria-describedby": this.getHintTextID(), "aria-invalid": this.getHintTextID() === this.errorTextId, "aria-labelledby": hasLabelContent ? this.inputLabelId : null, "aria-label": inheritedAttributes['aria-label'] || null, "aria-disabled": disabled ? 'true' : null, tabindex: disabled ? undefined : 0, onKeyDown: this.onKeyDown, onFocus: this.onFocus, onBlur: this.onBlur, onClick: this.onClick, class: createColorClasses(color, {
157
154
  [mode]: true,
158
155
  'in-item': hostContext('ion-item', el),
159
156
  'checkbox-checked': checked,
@@ -163,10 +160,10 @@ const Checkbox = /*@__PURE__*/ proxyCustomElement(class Checkbox extends HTMLEle
163
160
  [`checkbox-justify-${justify}`]: justify !== undefined,
164
161
  [`checkbox-alignment-${alignment}`]: alignment !== undefined,
165
162
  [`checkbox-label-placement-${labelPlacement}`]: true,
166
- }), onClick: this.onClick }, h("label", { key: 'f025cec5ff08e8be4487b9cc0324616ca5dfae2a', class: "checkbox-wrapper", htmlFor: inputId }, h("input", Object.assign({ key: 'dc53f7e4e240dc2e18556e6350df2b5c3169f553', type: "checkbox", checked: checked ? true : undefined, disabled: disabled, id: inputId, onChange: this.toggleChecked, onFocus: () => this.onFocus(), onBlur: () => this.onBlur(), ref: (focusEl) => (this.focusEl = focusEl), required: required }, inheritedAttributes)), h("div", { key: 'a625e9b50c3b617de8bbbfd624d772454fecaf2d', class: {
163
+ }) }, h("label", { key: '84d4c33da0348dc65ad36fb0fafd48be366dcf3b', class: "checkbox-wrapper", htmlFor: inputId }, h("input", Object.assign({ key: '427db69a3ab8a17aa0867519c90f585b8930406b', type: "checkbox", checked: checked ? true : undefined, disabled: disabled, id: inputId, onChange: this.toggleChecked, required: required }, inheritedAttributes)), h("div", { key: '9dda7024b3a4f1ee55351f783f9a10f9b4ad0d12', class: {
167
164
  'label-text-wrapper': true,
168
165
  'label-text-wrapper-hidden': !hasLabelContent,
169
- }, part: "label", id: this.inputLabelId, onClick: this.onDivLabelClick }, h("slot", { key: '87d1a90691327945f4343406706e4ab27f453844' }), this.renderHintText()), h("div", { key: 'b57fed8cdecee4df1ef0d57f157267ee77fac653', class: "native-wrapper" }, h("svg", { key: '13a8aac044d46dc99e3b60a1a643785511f216ac', class: "checkbox-icon", viewBox: "0 0 24 24", part: "container", "aria-hidden": "true" }, path)))));
166
+ }, part: "label", id: this.inputLabelId, onClick: this.onDivLabelClick }, h("slot", { key: 'f9d1d545ffd4164b650808241b51ea1bedc6a42c' }), this.renderHintText()), h("div", { key: 'a96d61ac324864228f14caa0e9f2c0d15418882e', class: "native-wrapper" }, h("svg", { key: '64ff3e4d87e190601811ef64323edec18d510cd1', class: "checkbox-icon", viewBox: "0 0 24 24", part: "container", "aria-hidden": "true" }, path)))));
170
167
  }
171
168
  getSVGPath(mode, indeterminate) {
172
169
  let path = indeterminate ? (h("path", { d: "M6 12L18 12", part: "mark" })) : (h("path", { d: "M5.9,12.5l3.8,3.8l8.8-8.8", part: "mark" }));
@@ -8,6 +8,8 @@ import { h as hostContext } from './theme.js';
8
8
  import { b as getIonMode } from './ionic-global.js';
9
9
 
10
10
  const TRANSITION = 'all 0.2s ease-in-out';
11
+ const ROLE_NONE = 'none';
12
+ const ROLE_BANNER = 'banner';
11
13
  const cloneElement = (tagName) => {
12
14
  const getCachedEl = document.querySelector(`${tagName}.ion-cloned-element`);
13
15
  if (getCachedEl !== null) {
@@ -134,6 +136,7 @@ const setHeaderActive = (headerIndex, active = true) => {
134
136
  const toolbars = headerIndex.toolbars;
135
137
  const ionTitles = toolbars.map((toolbar) => toolbar.ionTitleEl);
136
138
  if (active) {
139
+ headerEl.setAttribute('role', ROLE_BANNER);
137
140
  headerEl.classList.remove('header-collapse-condense-inactive');
138
141
  ionTitles.forEach((ionTitle) => {
139
142
  if (ionTitle) {
@@ -142,6 +145,16 @@ const setHeaderActive = (headerIndex, active = true) => {
142
145
  });
143
146
  }
144
147
  else {
148
+ /**
149
+ * There can only be one banner landmark per page.
150
+ * By default, all ion-headers have the banner role.
151
+ * This causes an accessibility issue when using a
152
+ * condensed header since there are two ion-headers
153
+ * on the page at once (active and inactive).
154
+ * To solve this, the role needs to be toggled
155
+ * based on which header is active.
156
+ */
157
+ headerEl.setAttribute('role', ROLE_NONE);
145
158
  headerEl.classList.add('header-collapse-condense-inactive');
146
159
  /**
147
160
  * The small title should only be accessed by screen readers
@@ -201,8 +214,32 @@ const handleHeaderFade = (scrollEl, baseEl, condenseHeader) => {
201
214
  });
202
215
  });
203
216
  };
217
+ /**
218
+ * Get the role type for the ion-header.
219
+ *
220
+ * @param isInsideMenu If ion-header is inside ion-menu.
221
+ * @param isCondensed If ion-header has collapse="condense".
222
+ * @param mode The current mode.
223
+ * @returns 'none' if inside ion-menu or if condensed in md
224
+ * mode, otherwise 'banner'.
225
+ */
226
+ const getRoleType = (isInsideMenu, isCondensed, mode) => {
227
+ // If the header is inside a menu, it should not have the banner role.
228
+ if (isInsideMenu) {
229
+ return ROLE_NONE;
230
+ }
231
+ /**
232
+ * Only apply role="none" to `md` mode condensed headers
233
+ * since the large header is never shown.
234
+ */
235
+ if (isCondensed && mode === 'md') {
236
+ return ROLE_NONE;
237
+ }
238
+ // Default to banner role.
239
+ return ROLE_BANNER;
240
+ };
204
241
 
205
- const headerIosCss = "ion-header{display:block;position:relative;-ms-flex-order:-1;order:-1;width:100%;z-index:10}ion-header ion-toolbar:first-of-type{padding-top:var(--ion-safe-area-top, 0)}.header-ios ion-toolbar:last-of-type{--border-width:0 0 0.55px}@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))){.header-background{left:0;right:0;top:0;bottom:0;position:absolute;-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px)}.header-translucent-ios ion-toolbar{--opacity:.8}.header-collapse-condense-inactive .header-background{-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px)}}.header-ios.ion-no-border ion-toolbar:last-of-type{--border-width:0}.header-collapse-fade ion-toolbar{--opacity-scale:inherit}.header-collapse-condense{z-index:9}.header-collapse-condense ion-toolbar{position:-webkit-sticky;position:sticky;top:0}.header-collapse-condense ion-toolbar:first-of-type{padding-top:0px;z-index:1}.header-collapse-condense ion-toolbar{--background:var(--ion-background-color, #fff);z-index:0}.header-collapse-condense ion-toolbar:last-of-type{--border-width:0px}.header-collapse-condense ion-toolbar ion-searchbar{padding-top:0px;padding-bottom:13px}.header-collapse-main{--opacity-scale:1}.header-collapse-main ion-toolbar{--opacity-scale:inherit}.header-collapse-main ion-toolbar.in-toolbar ion-title,.header-collapse-main ion-toolbar.in-toolbar ion-buttons{-webkit-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}.header-collapse-condense-inactive:not(.header-collapse-condense) ion-toolbar.in-toolbar ion-title,.header-collapse-condense-inactive:not(.header-collapse-condense) ion-toolbar.in-toolbar ion-buttons.buttons-collapse{opacity:0;pointer-events:none}.header-collapse-condense-inactive.header-collapse-condense ion-toolbar.in-toolbar ion-title,.header-collapse-condense-inactive.header-collapse-condense ion-toolbar.in-toolbar ion-buttons.buttons-collapse{visibility:hidden}ion-header.header-ios:not(.header-collapse-main):has(~ion-content ion-header.header-ios[collapse=condense],~ion-content ion-header.header-ios.header-collapse-condense){opacity:0}";
242
+ const headerIosCss = "ion-header{display:block;position:relative;-ms-flex-order:-1;order:-1;width:100%;z-index:10}ion-header ion-toolbar:first-of-type{padding-top:var(--ion-safe-area-top, 0)}.header-ios ion-toolbar:last-of-type{--border-width:0 0 0.55px}@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))){.header-background{left:0;right:0;top:0;bottom:0;position:absolute;-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px)}.header-translucent-ios ion-toolbar{--opacity:.8}.header-collapse-condense-inactive .header-background{-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px)}}.header-ios.ion-no-border ion-toolbar:last-of-type{--border-width:0}.header-collapse-fade ion-toolbar{--opacity-scale:inherit}.header-collapse-fade.header-transitioning ion-toolbar{--background:transparent;--border-style:none}.header-collapse-condense{z-index:9}.header-collapse-condense ion-toolbar{position:-webkit-sticky;position:sticky;top:0}.header-collapse-condense ion-toolbar:first-of-type{padding-top:0px;z-index:1}.header-collapse-condense ion-toolbar{z-index:0}.header-collapse-condense ion-toolbar:last-of-type{--border-width:0px}.header-collapse-condense ion-toolbar ion-searchbar{padding-top:0px;padding-bottom:13px}.header-collapse-main{--opacity-scale:1}.header-collapse-main ion-toolbar{--opacity-scale:inherit}.header-collapse-main ion-toolbar.in-toolbar ion-title,.header-collapse-main ion-toolbar.in-toolbar ion-buttons{-webkit-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}.header-collapse-condense ion-toolbar,.header-collapse-condense-inactive.header-transitioning:not(.header-collapse-condense) ion-toolbar{--background:var(--ion-background-color, #fff)}.header-collapse-condense-inactive.header-transitioning:not(.header-collapse-condense) ion-toolbar{--border-style:none;--opacity-scale:1}.header-collapse-condense-inactive:not(.header-collapse-condense) ion-toolbar.in-toolbar ion-title,.header-collapse-condense-inactive:not(.header-collapse-condense) ion-toolbar.in-toolbar ion-buttons.buttons-collapse{opacity:0;pointer-events:none}.header-collapse-condense-inactive.header-collapse-condense ion-toolbar.in-toolbar ion-title,.header-collapse-condense-inactive.header-collapse-condense ion-toolbar.in-toolbar ion-buttons.buttons-collapse{visibility:hidden}ion-header.header-ios:not(.header-collapse-main):has(~ion-content ion-header.header-ios[collapse=condense],~ion-content ion-header.header-ios.header-collapse-condense){opacity:0}";
206
243
 
207
244
  const headerMdCss = "ion-header{display:block;position:relative;-ms-flex-order:-1;order:-1;width:100%;z-index:10}ion-header ion-toolbar:first-of-type{padding-top:var(--ion-safe-area-top, 0)}.header-md{-webkit-box-shadow:0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12);box-shadow:0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12)}.header-collapse-condense{display:none}.header-md.ion-no-border{-webkit-box-shadow:none;box-shadow:none}";
208
245
 
@@ -345,16 +382,17 @@ const Header = /*@__PURE__*/ proxyCustomElement(class Header extends HTMLElement
345
382
  const { translucent, inheritedAttributes } = this;
346
383
  const mode = getIonMode(this);
347
384
  const collapse = this.collapse || 'none';
385
+ const isCondensed = collapse === 'condense';
348
386
  // banner role must be at top level, so remove role if inside a menu
349
- const roleType = hostContext('ion-menu', this.el) ? 'none' : 'banner';
350
- return (h(Host, Object.assign({ key: 'b6cc27f0b08afc9fcc889683525da765d80ba672', role: roleType, class: {
387
+ const roleType = getRoleType(hostContext('ion-menu', this.el), isCondensed, mode);
388
+ return (h(Host, Object.assign({ key: '863c4568cd7b8c0ec55109f193bbbaed68a1346e', role: roleType, class: {
351
389
  [mode]: true,
352
390
  // Used internally for styling
353
391
  [`header-${mode}`]: true,
354
392
  [`header-translucent`]: this.translucent,
355
393
  [`header-collapse-${collapse}`]: true,
356
394
  [`header-translucent-${mode}`]: this.translucent,
357
- } }, inheritedAttributes), mode === 'ios' && translucent && h("div", { key: '395766d4dcee3398bc91960db21f922095292f14', class: "header-background" }), h("slot", { key: '09a67ece27b258ff1248805d43d92a49b2c6859a' })));
395
+ } }, inheritedAttributes), mode === 'ios' && translucent && h("div", { key: '25c3bdce328b0b35607d154c8b8374679313d881', class: "header-background" }), h("slot", { key: 'b44fab0a9be7920b9650da26117c783e751e1702' })));
358
396
  }
359
397
  get el() { return this; }
360
398
  static get style() { return {
@@ -123,11 +123,22 @@ const iosTransitionAnimation = () => import('./ios.transition.js');
123
123
  const mdTransitionAnimation = () => import('./md.transition.js');
124
124
  const focusController = createFocusController();
125
125
  // TODO(FW-2832): types
126
+ /**
127
+ * Executes the main page transition.
128
+ * It also manages the lifecycle of header visibility (if any)
129
+ * to prevent visual flickering in iOS. The flickering only
130
+ * occurs for a condensed header that is placed above the content.
131
+ *
132
+ * @param opts Options for the transition.
133
+ * @returns A promise that resolves when the transition is complete.
134
+ */
126
135
  const transition = (opts) => {
127
136
  return new Promise((resolve, reject) => {
128
137
  writeTask(() => {
129
- beforeTransition(opts);
130
- runTransition(opts).then((result) => {
138
+ const transitioningInactiveHeader = getIosIonHeader(opts);
139
+ beforeTransition(opts, transitioningInactiveHeader);
140
+ runTransition(opts)
141
+ .then((result) => {
131
142
  if (result.animation) {
132
143
  result.animation.destroy();
133
144
  }
@@ -136,15 +147,21 @@ const transition = (opts) => {
136
147
  }, (error) => {
137
148
  afterTransition(opts);
138
149
  reject(error);
150
+ })
151
+ .finally(() => {
152
+ // Ensure that the header is restored to its original state.
153
+ setHeaderTransitionClass(transitioningInactiveHeader, false);
139
154
  });
140
155
  });
141
156
  });
142
157
  };
143
- const beforeTransition = (opts) => {
158
+ const beforeTransition = (opts, transitioningInactiveHeader) => {
144
159
  const enteringEl = opts.enteringEl;
145
160
  const leavingEl = opts.leavingEl;
146
161
  focusController.saveViewFocus(leavingEl);
147
162
  setZIndex(enteringEl, leavingEl, opts.direction);
163
+ // Prevent flickering of the header by adding a class.
164
+ setHeaderTransitionClass(transitioningInactiveHeader, true);
148
165
  if (opts.showGoBack) {
149
166
  enteringEl.classList.add('can-go-back');
150
167
  }
@@ -333,6 +350,39 @@ const setZIndex = (enteringEl, leavingEl, direction) => {
333
350
  leavingEl.style.zIndex = '100';
334
351
  }
335
352
  };
353
+ /**
354
+ * Add a class to ensure that the header (if any)
355
+ * does not flicker during the transition. By adding the
356
+ * transitioning class, we ensure that the header has
357
+ * the necessary styles to prevent the following flickers:
358
+ * 1. When entering a page with a condensed header, the
359
+ * header should never be visible. However,
360
+ * it briefly renders the background color while
361
+ * the transition is occurring.
362
+ * 2. When leaving a page with a condensed header, the
363
+ * header has an opacity of 0 and the pages
364
+ * have a z-index which causes the entering page to
365
+ * briefly show it's content underneath the leaving page.
366
+ * 3. When entering a page or leaving a page with a fade
367
+ * header, the header should not have a background color.
368
+ * However, it briefly shows the background color while
369
+ * the transition is occurring.
370
+ *
371
+ * @param header The header element to modify.
372
+ * @param isTransitioning Whether the transition is occurring.
373
+ */
374
+ const setHeaderTransitionClass = (header, isTransitioning) => {
375
+ if (!header) {
376
+ return;
377
+ }
378
+ const transitionClass = 'header-transitioning';
379
+ if (isTransitioning) {
380
+ header.classList.add(transitionClass);
381
+ }
382
+ else {
383
+ header.classList.remove(transitionClass);
384
+ }
385
+ };
336
386
  const getIonPageElement = (element) => {
337
387
  if (element.classList.contains('ion-page')) {
338
388
  return element;
@@ -344,5 +394,26 @@ const getIonPageElement = (element) => {
344
394
  // idk, return the original element so at least something animates and we don't have a null pointer
345
395
  return element;
346
396
  };
397
+ /**
398
+ * Retrieves the ion-header element from a page based on the
399
+ * direction of the transition.
400
+ *
401
+ * @param opts Options for the transition.
402
+ * @returns The ion-header element or null if not found or not in 'ios' mode.
403
+ */
404
+ const getIosIonHeader = (opts) => {
405
+ const enteringEl = opts.enteringEl;
406
+ const leavingEl = opts.leavingEl;
407
+ const direction = opts.direction;
408
+ const mode = opts.mode;
409
+ if (mode !== 'ios') {
410
+ return null;
411
+ }
412
+ const element = direction === 'back' ? leavingEl : enteringEl;
413
+ if (!element) {
414
+ return null;
415
+ }
416
+ return element.querySelector('ion-header');
417
+ };
347
418
 
348
419
  export { LIFECYCLE_WILL_ENTER as L, LIFECYCLE_DID_ENTER as a, LIFECYCLE_WILL_LEAVE as b, LIFECYCLE_DID_LEAVE as c, LIFECYCLE_WILL_UNLOAD as d, deepReady as e, getIonPageElement as g, lifecycle as l, setPageHidden as s, transition as t, waitForMount as w };
@@ -19,10 +19,57 @@ const Accordion = /*@__PURE__*/ proxyCustomElement(class Accordion extends HTMLE
19
19
  this.__registerHost();
20
20
  }
21
21
  this.__attachShadow();
22
- this.updateListener = () => this.updateState(false);
22
+ this.accordionGroupUpdateHandler = () => {
23
+ /**
24
+ * Determine if this update will cause an actual state change.
25
+ * We only want to mark as "interacted" if the state is changing.
26
+ */
27
+ const accordionGroup = this.accordionGroupEl;
28
+ if (accordionGroup) {
29
+ const value = accordionGroup.value;
30
+ const accordionValue = this.value;
31
+ const shouldExpand = Array.isArray(value) ? value.includes(accordionValue) : value === accordionValue;
32
+ const isExpanded = this.state === 4 /* AccordionState.Expanded */ || this.state === 8 /* AccordionState.Expanding */;
33
+ const stateWillChange = shouldExpand !== isExpanded;
34
+ /**
35
+ * Only mark as interacted if:
36
+ * 1. This is not the first update we've received with a defined value
37
+ * 2. The state is actually changing (prevents redundant updates from enabling animations)
38
+ */
39
+ if (this.hasReceivedFirstUpdate && stateWillChange) {
40
+ this.hasInteracted = true;
41
+ }
42
+ /**
43
+ * Only count this as the first update if the group value is defined.
44
+ * This prevents the initial undefined value from the group's componentDidLoad
45
+ * from being treated as the first real update.
46
+ */
47
+ if (value !== undefined) {
48
+ this.hasReceivedFirstUpdate = true;
49
+ }
50
+ }
51
+ this.updateState();
52
+ };
23
53
  this.state = 1 /* AccordionState.Collapsed */;
24
54
  this.isNext = false;
25
55
  this.isPrevious = false;
56
+ /**
57
+ * Tracks whether a user-initiated interaction has occurred.
58
+ * Animations are disabled until the first interaction happens.
59
+ * This prevents the accordion from animating when it's programmatically
60
+ * set to an expanded or collapsed state on initial load.
61
+ */
62
+ this.hasInteracted = false;
63
+ /**
64
+ * Tracks if this accordion has ever been expanded.
65
+ * Used to prevent the first expansion from animating.
66
+ */
67
+ this.hasEverBeenExpanded = false;
68
+ /**
69
+ * Tracks if this accordion has received its first update from the group.
70
+ * Used to distinguish initial programmatic sets from user interactions.
71
+ */
72
+ this.hasReceivedFirstUpdate = false;
26
73
  /**
27
74
  * The value of the accordion. Defaults to an autogenerated
28
75
  * value.
@@ -127,10 +174,15 @@ const Accordion = /*@__PURE__*/ proxyCustomElement(class Accordion extends HTMLE
127
174
  iconEl.setAttribute('aria-hidden', 'true');
128
175
  ionItem.appendChild(iconEl);
129
176
  };
130
- this.expandAccordion = (initialUpdate = false) => {
177
+ this.expandAccordion = () => {
131
178
  const { contentEl, contentElWrapper } = this;
132
- if (initialUpdate || contentEl === undefined || contentElWrapper === undefined) {
179
+ /**
180
+ * If the content elements aren't available yet, just set the state.
181
+ * This happens on initial render before the DOM is ready.
182
+ */
183
+ if (contentEl === undefined || contentElWrapper === undefined) {
133
184
  this.state = 4 /* AccordionState.Expanded */;
185
+ this.hasEverBeenExpanded = true;
134
186
  return;
135
187
  }
136
188
  if (this.state === 4 /* AccordionState.Expanded */) {
@@ -139,6 +191,11 @@ const Accordion = /*@__PURE__*/ proxyCustomElement(class Accordion extends HTMLE
139
191
  if (this.currentRaf !== undefined) {
140
192
  cancelAnimationFrame(this.currentRaf);
141
193
  }
194
+ /**
195
+ * Mark that this accordion has been expanded at least once.
196
+ * This allows subsequent expansions to animate.
197
+ */
198
+ this.hasEverBeenExpanded = true;
142
199
  if (this.shouldAnimate()) {
143
200
  raf(() => {
144
201
  this.state = 8 /* AccordionState.Expanding */;
@@ -156,9 +213,13 @@ const Accordion = /*@__PURE__*/ proxyCustomElement(class Accordion extends HTMLE
156
213
  this.state = 4 /* AccordionState.Expanded */;
157
214
  }
158
215
  };
159
- this.collapseAccordion = (initialUpdate = false) => {
216
+ this.collapseAccordion = () => {
160
217
  const { contentEl } = this;
161
- if (initialUpdate || contentEl === undefined) {
218
+ /**
219
+ * If the content element isn't available yet, just set the state.
220
+ * This happens on initial render before the DOM is ready.
221
+ */
222
+ if (contentEl === undefined) {
162
223
  this.state = 1 /* AccordionState.Collapsed */;
163
224
  return;
164
225
  }
@@ -193,6 +254,18 @@ const Accordion = /*@__PURE__*/ proxyCustomElement(class Accordion extends HTMLE
193
254
  * of what is set in the config.
194
255
  */
195
256
  this.shouldAnimate = () => {
257
+ /**
258
+ * Don't animate until after the first user interaction.
259
+ * This prevents animations on initial load when accordions
260
+ * start in an expanded or collapsed state programmatically.
261
+ *
262
+ * Additionally, don't animate the very first expansion even if
263
+ * hasInteracted is true. This handles edge cases like React StrictMode
264
+ * where effects run twice and might incorrectly mark as interacted.
265
+ */
266
+ if (!this.hasInteracted || !this.hasEverBeenExpanded) {
267
+ return false;
268
+ }
196
269
  if (typeof window === 'undefined') {
197
270
  return false;
198
271
  }
@@ -209,7 +282,7 @@ const Accordion = /*@__PURE__*/ proxyCustomElement(class Accordion extends HTMLE
209
282
  }
210
283
  return true;
211
284
  };
212
- this.updateState = async (initialUpdate = false) => {
285
+ this.updateState = async () => {
213
286
  const accordionGroup = this.accordionGroupEl;
214
287
  const accordionValue = this.value;
215
288
  if (!accordionGroup) {
@@ -218,11 +291,11 @@ const Accordion = /*@__PURE__*/ proxyCustomElement(class Accordion extends HTMLE
218
291
  const value = accordionGroup.value;
219
292
  const shouldExpand = Array.isArray(value) ? value.includes(accordionValue) : value === accordionValue;
220
293
  if (shouldExpand) {
221
- this.expandAccordion(initialUpdate);
294
+ this.expandAccordion();
222
295
  this.isNext = this.isPrevious = false;
223
296
  }
224
297
  else {
225
- this.collapseAccordion(initialUpdate);
298
+ this.collapseAccordion();
226
299
  /**
227
300
  * When using popout or inset,
228
301
  * the collapsed accordion items
@@ -270,14 +343,14 @@ const Accordion = /*@__PURE__*/ proxyCustomElement(class Accordion extends HTMLE
270
343
  var _a;
271
344
  const accordionGroupEl = (this.accordionGroupEl = (_a = this.el) === null || _a === void 0 ? void 0 : _a.closest('ion-accordion-group'));
272
345
  if (accordionGroupEl) {
273
- this.updateState(true);
274
- addEventListener(accordionGroupEl, 'ionValueChange', this.updateListener);
346
+ this.updateState();
347
+ addEventListener(accordionGroupEl, 'ionValueChange', this.accordionGroupUpdateHandler);
275
348
  }
276
349
  }
277
350
  disconnectedCallback() {
278
351
  const accordionGroupEl = this.accordionGroupEl;
279
352
  if (accordionGroupEl) {
280
- removeEventListener(accordionGroupEl, 'ionValueChange', this.updateListener);
353
+ removeEventListener(accordionGroupEl, 'ionValueChange', this.accordionGroupUpdateHandler);
281
354
  }
282
355
  }
283
356
  componentDidLoad() {
@@ -301,6 +374,11 @@ const Accordion = /*@__PURE__*/ proxyCustomElement(class Accordion extends HTMLE
301
374
  const { accordionGroupEl, disabled, readonly, value, state } = this;
302
375
  if (disabled || readonly)
303
376
  return;
377
+ /**
378
+ * Mark that the user has interacted with the accordion.
379
+ * This enables animations for all future state changes.
380
+ */
381
+ this.hasInteracted = true;
304
382
  if (accordionGroupEl) {
305
383
  /**
306
384
  * Because the accordion group may or may
@@ -321,7 +399,7 @@ const Accordion = /*@__PURE__*/ proxyCustomElement(class Accordion extends HTMLE
321
399
  const headerPart = expanded ? 'header expanded' : 'header';
322
400
  const contentPart = expanded ? 'content expanded' : 'content';
323
401
  this.setAria(expanded);
324
- return (h(Host, { key: '073e1d02c18dcbc20c68648426e87c14750c031d', class: {
402
+ return (h(Host, { key: '9c90bce01eff7e5774a19f69c872f3761d66cf3c', class: {
325
403
  [mode]: true,
326
404
  'accordion-expanding': this.state === 8 /* AccordionState.Expanding */,
327
405
  'accordion-expanded': this.state === 4 /* AccordionState.Expanded */,
@@ -332,7 +410,7 @@ const Accordion = /*@__PURE__*/ proxyCustomElement(class Accordion extends HTMLE
332
410
  'accordion-disabled': disabled,
333
411
  'accordion-readonly': readonly,
334
412
  'accordion-animated': this.shouldAnimate(),
335
- } }, h("div", { key: '9b4cf326de8bb6b4033992903c0c1bfd7eea9bcc', onClick: () => this.toggleExpanded(), id: "header", part: headerPart, "aria-controls": "content", ref: (headerEl) => (this.headerEl = headerEl) }, h("slot", { key: '464c32a37f64655eacf4218284214f5f30b14a1e', name: "header" })), h("div", { key: '8bb52e6a62d7de0106b253201a89a32e79d9a594', id: "content", part: contentPart, role: "region", "aria-labelledby": "header", ref: (contentEl) => (this.contentEl = contentEl) }, h("div", { key: '1d9dfd952ad493754aaeea7a8f625b33c2dd90a0', id: "content-wrapper", ref: (contentElWrapper) => (this.contentElWrapper = contentElWrapper) }, h("slot", { key: '970dfbc55a612d739d0ca3b7b1a08e5c96d0c479', name: "content" })))));
413
+ } }, h("div", { key: 'cab40d5bcf3c93fd78e70b6d3906a541e725837d', onClick: () => this.toggleExpanded(), id: "header", part: headerPart, "aria-controls": "content", ref: (headerEl) => (this.headerEl = headerEl) }, h("slot", { key: '672bc7fb3f9e18076b41e20fc9eaeab7cafcf3a2', name: "header" })), h("div", { key: 'fd777ca5b4ab04aa4f44c339d58c8cd987c52bcb', id: "content", part: contentPart, role: "region", "aria-labelledby": "header", ref: (contentEl) => (this.contentEl = contentEl) }, h("div", { key: '0aad70a71e2cd2c16b2e98fa0bdd40421d95fe16', id: "content-wrapper", ref: (contentElWrapper) => (this.contentElWrapper = contentElWrapper) }, h("slot", { key: 'd630e10ac7c56b4dbf943b523f26759b83aead55', name: "content" })))));
336
414
  }
337
415
  static get delegatesFocus() { return true; }
338
416
  get el() { return this; }
@@ -351,7 +429,8 @@ const Accordion = /*@__PURE__*/ proxyCustomElement(class Accordion extends HTMLE
351
429
  "toggleIconSlot": [1, "toggle-icon-slot"],
352
430
  "state": [32],
353
431
  "isNext": [32],
354
- "isPrevious": [32]
432
+ "isPrevious": [32],
433
+ "hasInteracted": [32]
355
434
  }, undefined, {
356
435
  "value": ["valueChanged"]
357
436
  }]);
@@ -2,7 +2,7 @@
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
4
  import { proxyCustomElement, HTMLElement, createEvent, forceUpdate, Build, h, Host } from '@stencil/core/internal/client';
5
- import { c as createNotchController } from './notch-controller.js';
5
+ import { c as createNotchController, a as checkInvalidState } from './validity.js';
6
6
  import { l as debounceEvent, i as inheritAriaAttributes, d as inheritAttributes, c as componentOnReady } from './helpers.js';
7
7
  import { c as createSlotMutationController, g as getCounterText } from './input.utils.js';
8
8
  import { h as hostContext, c as createColorClasses } from './theme.js';
@@ -233,14 +233,6 @@ const Input = /*@__PURE__*/ proxyCustomElement(class Input extends HTMLElement {
233
233
  componentWillLoad() {
234
234
  this.inheritedAttributes = Object.assign(Object.assign({}, inheritAriaAttributes(this.el)), inheritAttributes(this.el, ['tabindex', 'title', 'data-form-type', 'dir']));
235
235
  }
236
- /**
237
- * Checks if the input is in an invalid state based on Ionic validation classes
238
- */
239
- checkInvalidState() {
240
- const hasIonTouched = this.el.classList.contains('ion-touched');
241
- const hasIonInvalid = this.el.classList.contains('ion-invalid');
242
- return hasIonTouched && hasIonInvalid;
243
- }
244
236
  connectedCallback() {
245
237
  const { el } = this;
246
238
  this.slotMutationController = createSlotMutationController(el, ['label', 'start', 'end'], () => forceUpdate(this));
@@ -248,7 +240,7 @@ const Input = /*@__PURE__*/ proxyCustomElement(class Input extends HTMLElement {
248
240
  // Watch for class changes to update validation state
249
241
  if (Build.isBrowser && typeof MutationObserver !== 'undefined') {
250
242
  this.validationObserver = new MutationObserver(() => {
251
- const newIsInvalid = this.checkInvalidState();
243
+ const newIsInvalid = checkInvalidState(el);
252
244
  if (this.isInvalid !== newIsInvalid) {
253
245
  this.isInvalid = newIsInvalid;
254
246
  // Force a re-render to update aria-describedby immediately
@@ -261,7 +253,7 @@ const Input = /*@__PURE__*/ proxyCustomElement(class Input extends HTMLElement {
261
253
  });
262
254
  }
263
255
  // Always set initial state
264
- this.isInvalid = this.checkInvalidState();
256
+ this.isInvalid = checkInvalidState(el);
265
257
  this.debounceChanged();
266
258
  if (Build.isBrowser) {
267
259
  document.dispatchEvent(new CustomEvent('ionInputDidLoad', {
@@ -525,7 +517,7 @@ const Input = /*@__PURE__*/ proxyCustomElement(class Input extends HTMLElement {
525
517
  * TODO(FW-5592): Remove hasStartEndSlots condition
526
518
  */
527
519
  const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
528
- return (h(Host, { key: '8a51f0300d5bc66392f9ab9a6fa0b5d388072a33', class: createColorClasses(this.color, {
520
+ return (h(Host, { key: '97b5308021064d9e7434ef2d3d96f27045c1b0c4', class: createColorClasses(this.color, {
529
521
  [mode]: true,
530
522
  'has-value': hasValue,
531
523
  'has-focus': hasFocus,
@@ -536,14 +528,14 @@ const Input = /*@__PURE__*/ proxyCustomElement(class Input extends HTMLElement {
536
528
  'in-item': inItem,
537
529
  'in-item-color': hostContext('ion-item.ion-color', this.el),
538
530
  'input-disabled': disabled,
539
- }) }, h("label", { key: '9f8cf88d7d0e27931b51bd9c67f048c7fc6f5703', class: "input-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), h("div", { key: '7ad30bf9777774062a6ccf9a3ba804f251eef1bb', class: "native-wrapper", onClick: this.onLabelClick }, h("slot", { key: '8af0b0325d101df8eed7d24f2767d6ca4d307319', name: "start" }), h("input", Object.assign({ key: '1c53f7f9fa2567f3df19681cf4e7c21be382eae6', 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 && (h("button", { key: 'b081d0e1ec1444b4c9cca145fc9cd2ad4a68b3da', "aria-label": "reset", type: "button", class: "input-clear-icon", onPointerDown: (ev) => {
531
+ }) }, h("label", { key: '353f68726ce180299bd9adc81e5ff7d26a48f54f', class: "input-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), h("div", { key: '2034b4bad04fc157f3298a1805819216b6f439d0', class: "native-wrapper", onClick: this.onLabelClick }, h("slot", { key: '96bb5e30176b2bd76dfb75bfbf6c1c3d4403f4bb', name: "start" }), h("input", Object.assign({ key: '1a1d75b0e414a95c89d5a760757c33548d234aca', 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 && (h("button", { key: '95f3df17b7691d9a2e7dcd4a51f16a94aa3ca36f', "aria-label": "reset", type: "button", class: "input-clear-icon", onPointerDown: (ev) => {
540
532
  /**
541
533
  * This prevents mobile browsers from
542
534
  * blurring the input when the clear
543
535
  * button is activated.
544
536
  */
545
537
  ev.preventDefault();
546
- }, onClick: this.clearTextInput }, h("ion-icon", { key: '01535299241c3635460c05646420acf62a1ff567', "aria-hidden": "true", icon: clearIconData }))), h("slot", { key: '480f3eb58b08ae792866a5b9b4c068748c5567cc', name: "end" })), shouldRenderHighlight && h("div", { key: 'a8609cacee88e4a09f1cca65b6a47cb79a56f35e', class: "input-highlight" })), this.renderBottomContent()));
538
+ }, onClick: this.clearTextInput }, h("ion-icon", { key: '16b0af75eed50c8115fb5597f73b5fbf71c2530e', "aria-hidden": "true", icon: clearIconData }))), h("slot", { key: 'c48da0f8ddb3764ac43efa705bb4a6bb2d9cc2fd', name: "end" })), shouldRenderHighlight && h("div", { key: 'f15238481fc20de56ca7ecb6e350b3c024cc755e', class: "input-highlight" })), this.renderBottomContent()));
547
539
  }
548
540
  get el() { return this; }
549
541
  static get watchers() { return {