@ionic/core 9.0.4 → 9.0.5-nightly.20260918

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 (476) hide show
  1. package/components/index.js +1 -1
  2. package/components/ion-accordion-group.js +1 -1
  3. package/components/ion-accordion.js +1 -1
  4. package/components/ion-action-sheet.js +1 -1
  5. package/components/ion-alert.js +1 -1
  6. package/components/ion-app.js +1 -1
  7. package/components/ion-avatar.js +1 -1
  8. package/components/ion-back-button.js +1 -1
  9. package/components/ion-backdrop.js +1 -1
  10. package/components/ion-badge.js +1 -1
  11. package/components/ion-breadcrumb.js +1 -1
  12. package/components/ion-breadcrumbs.js +1 -1
  13. package/components/ion-button.js +1 -1
  14. package/components/ion-buttons.js +1 -1
  15. package/components/ion-card-content.js +1 -1
  16. package/components/ion-card-header.js +1 -1
  17. package/components/ion-card-subtitle.js +1 -1
  18. package/components/ion-card-title.js +1 -1
  19. package/components/ion-card.js +1 -1
  20. package/components/ion-checkbox.js +1 -1
  21. package/components/ion-chip.js +1 -1
  22. package/components/ion-col.js +1 -1
  23. package/components/ion-content.js +1 -1
  24. package/components/ion-datetime-button.js +1 -1
  25. package/components/ion-datetime.js +1 -1
  26. package/components/ion-fab-button.js +1 -1
  27. package/components/ion-fab-list.js +1 -1
  28. package/components/ion-fab.js +1 -1
  29. package/components/ion-footer.js +1 -1
  30. package/components/ion-grid.js +1 -1
  31. package/components/ion-header.js +1 -1
  32. package/components/ion-icon.js +1 -1
  33. package/components/ion-img.js +1 -1
  34. package/components/ion-infinite-scroll-content.js +1 -1
  35. package/components/ion-infinite-scroll.js +1 -1
  36. package/components/ion-input-otp.js +1 -1
  37. package/components/ion-input-password-toggle.js +1 -1
  38. package/components/ion-input.js +1 -1
  39. package/components/ion-item-divider.js +1 -1
  40. package/components/ion-item-group.js +1 -1
  41. package/components/ion-item-option.js +1 -1
  42. package/components/ion-item-options.js +1 -1
  43. package/components/ion-item-sliding.js +1 -1
  44. package/components/ion-item.js +1 -1
  45. package/components/ion-label.js +1 -1
  46. package/components/ion-list-header.js +1 -1
  47. package/components/ion-list.js +1 -1
  48. package/components/ion-loading.js +1 -1
  49. package/components/ion-menu-button.js +1 -1
  50. package/components/ion-menu-toggle.js +1 -1
  51. package/components/ion-menu.js +1 -1
  52. package/components/ion-modal.js +1 -1
  53. package/components/ion-nav-link.js +1 -1
  54. package/components/ion-nav.js +1 -1
  55. package/components/ion-note.js +1 -1
  56. package/components/ion-picker-column-option.js +1 -1
  57. package/components/ion-picker-column.js +1 -1
  58. package/components/ion-picker.js +1 -1
  59. package/components/ion-popover.js +1 -1
  60. package/components/ion-progress-bar.js +1 -1
  61. package/components/ion-radio-group.js +1 -1
  62. package/components/ion-radio.js +1 -1
  63. package/components/ion-range.js +1 -1
  64. package/components/ion-refresher-content.js +1 -1
  65. package/components/ion-refresher.js +1 -1
  66. package/components/ion-reorder-group.js +1 -1
  67. package/components/ion-reorder.js +1 -1
  68. package/components/ion-ripple-effect.js +1 -1
  69. package/components/ion-route-redirect.js +1 -1
  70. package/components/ion-route.js +1 -1
  71. package/components/ion-router-link.js +1 -1
  72. package/components/ion-router-outlet.js +1 -1
  73. package/components/ion-router.js +1 -1
  74. package/components/ion-row.js +1 -1
  75. package/components/ion-searchbar.js +1 -1
  76. package/components/ion-segment-button.js +1 -1
  77. package/components/ion-segment-content.js +1 -1
  78. package/components/ion-segment-view.js +1 -1
  79. package/components/ion-segment.js +1 -1
  80. package/components/ion-select-modal.js +1 -1
  81. package/components/ion-select-option.js +1 -1
  82. package/components/ion-select-popover.js +1 -1
  83. package/components/ion-select.js +1 -1
  84. package/components/ion-skeleton-text.js +1 -1
  85. package/components/ion-spinner.js +1 -1
  86. package/components/ion-split-pane.js +1 -1
  87. package/components/ion-tab-bar.js +1 -1
  88. package/components/ion-tab-button.js +1 -1
  89. package/components/ion-tab.js +1 -1
  90. package/components/ion-tabs.js +1 -1
  91. package/components/ion-text.js +1 -1
  92. package/components/ion-textarea.js +1 -1
  93. package/components/ion-thumbnail.js +1 -1
  94. package/components/ion-title.js +1 -1
  95. package/components/ion-toast.js +1 -1
  96. package/components/ion-toggle.js +1 -1
  97. package/components/ion-toolbar.js +1 -1
  98. package/components/p--8XqAiDn.js +4 -0
  99. package/components/{p-CkffScdn.js → p-2NFckEWF.js} +1 -1
  100. package/components/p-3D5X__KW.js +4 -0
  101. package/components/{p-C6WYVtle.js → p-B2SADtq2.js} +1 -1
  102. package/components/{p-gyjG_IM4.js → p-B4i_guWa.js} +1 -1
  103. package/components/p-B7NtI9LF.js +4 -0
  104. package/components/{p-MLplUp3U.js → p-B7UPvS1C.js} +1 -1
  105. package/components/{p-8MzqWBTT.js → p-BBPjLr6a.js} +1 -1
  106. package/components/p-BGu4rI5P.js +4 -0
  107. package/components/{p-Csi6iX-c.js → p-BNnwTu4u.js} +1 -1
  108. package/components/p-BQ1TznDx.js +4 -0
  109. package/components/p-BXD1texH.js +4 -0
  110. package/components/{p-BPbgEuCf.js → p-Bi7c_bt3.js} +1 -1
  111. package/components/p-BjIkK172.js +4 -0
  112. package/components/{p-CthoZqG1.js → p-BoK0Zxin.js} +1 -1
  113. package/components/p-C9CGVt9y.js +4 -0
  114. package/components/{p-BjizFeM6.js → p-CTh7oRWR.js} +1 -1
  115. package/components/{p-BMHhG7Xh.js → p-CTykhCkJ.js} +1 -1
  116. package/components/{p-BuxZkazO.js → p-CU8SQ6hA.js} +1 -1
  117. package/components/p-CVNoHMcR.js +4 -0
  118. package/components/p-CVqR_xzT.js +4 -0
  119. package/components/{p-BxCcX93a.js → p-CXAF_kfJ.js} +1 -1
  120. package/components/p-CXR6mbDq.js +4 -0
  121. package/components/p-CYqC-Atm.js +4 -0
  122. package/components/{p-S-gGoI4A.js → p-CaLdTi8C.js} +1 -1
  123. package/components/p-CbnQxifG.js +4 -0
  124. package/{dist/ionic/p-DlvB1Idh.js → components/p-CfKxueOn.js} +1 -1
  125. package/components/{p-CMT0YmOj.js → p-CtMgk_1c.js} +1 -1
  126. package/components/p-D2peGJYg.js +4 -0
  127. package/components/{p-MSr4IlyS.js → p-D6fVxd5I.js} +1 -1
  128. package/components/p-D6pn9UkD.js +4 -0
  129. package/components/{p-DOwsU7Mc.js → p-D8cczurE.js} +1 -1
  130. package/{dist/ionic/p-Bu6uWqQM.js → components/p-D9_ODaPJ.js} +1 -1
  131. package/components/p-DCryg-Sq.js +4 -0
  132. package/components/{p-2ta4uE9-.js → p-DF5FRPZh.js} +1 -1
  133. package/components/p-DF8r3KSX.js +4 -0
  134. package/components/{p-CcOl6jEv.js → p-DNT7yQ4z.js} +1 -1
  135. package/components/{p-PWHvigWP.js → p-DSRinNB2.js} +1 -1
  136. package/components/{p-DBGxvxkE.js → p-DTo_pxeB.js} +1 -1
  137. package/components/{p-DEvF_E6y.js → p-DUE1XLJD.js} +1 -1
  138. package/components/{p-DMT-4tHM.js → p-DVoewOZH.js} +1 -1
  139. package/components/p-DhUgaaqJ.js +4 -0
  140. package/components/{p-DSuBagxs.js → p-DiqHxuia.js} +1 -1
  141. package/components/{p-DKX1mWld.js → p-Do82ooMy.js} +1 -1
  142. package/components/{p-DcrAT6v8.js → p-DrzCm5Hh.js} +1 -1
  143. package/components/{p-CXuRZoWE.js → p-J7HaBhyh.js} +1 -1
  144. package/{dist/ionic/p-BT0-h-eD.js → components/p-TsPC4TcB.js} +1 -1
  145. package/components/p-Wl4YKqiE.js +4 -0
  146. package/components/p-gYw-RCaQ.js +4 -0
  147. package/components/p-lbvS3btC.js +4 -0
  148. package/components/p-ls85vUWB.js +4 -0
  149. package/components/{p-Bi8VGu4M.js → p-vg50UO6j.js} +1 -1
  150. package/dist/cjs/{animation-2DHlng-f.js → animation-C-JWwKgy.js} +2 -2
  151. package/dist/cjs/{app-globals-BeC95igM.js → app-globals-TXtzYAPy.js} +1 -1
  152. package/dist/cjs/attribute-controller-B0BsgXV8.js +131 -0
  153. package/dist/cjs/{button-active-CTyeZB16.js → button-active-DG3sHT6d.js} +2 -2
  154. package/dist/cjs/{capacitor-cADDPMtd.js → capacitor-CtkuLHaA.js} +1 -1
  155. package/dist/cjs/{format-BbkxKT7p.js → format-BHIqanHK.js} +1 -1
  156. package/dist/cjs/{framework-delegate-DYIuFqQx.js → framework-delegate-CvJ6SkeA.js} +1 -1
  157. package/dist/cjs/{haptic-CqPss9_L.js → haptic-C-wyDL4O.js} +1 -1
  158. package/dist/cjs/{helpers-DHjAEaU9.js → helpers-CJUjGJOS.js} +6 -3
  159. package/dist/cjs/{index-D_D542p0.js → index-78cPCZwH.js} +4 -4
  160. package/dist/cjs/{index-B-R-H1Z2.js → index-7glr9oHu.js} +2 -2
  161. package/dist/cjs/{index-MdIUU940.js → index-D9PPKWTO.js} +1 -1
  162. package/dist/cjs/{index-T36W_eKv.js → index-DLQNazpt.js} +4 -0
  163. package/dist/cjs/{index-Da83wbmS.js → index-DqKXmMKk.js} +5 -5
  164. package/dist/cjs/{index-BLq7TkUV.js → index-m83Rr85o.js} +2 -2
  165. package/dist/cjs/index.cjs.js +13 -11
  166. package/dist/cjs/{input-shims-DYxL0Fdm.js → input-shims-gtEasMEV.js} +5 -5
  167. package/dist/cjs/{input.utils-B_32Xwga.js → input.utils-C1JNUKzb.js} +1 -1
  168. package/dist/cjs/ion-accordion_2.cjs.entry.js +3 -3
  169. package/dist/cjs/ion-action-sheet.cjs.entry.js +11 -11
  170. package/dist/cjs/ion-alert.cjs.entry.js +11 -11
  171. package/dist/cjs/ion-app_8.cjs.entry.js +16 -16
  172. package/dist/cjs/ion-avatar_3.cjs.entry.js +2 -2
  173. package/dist/cjs/ion-back-button.cjs.entry.js +3 -3
  174. package/dist/cjs/ion-backdrop.cjs.entry.js +2 -2
  175. package/dist/cjs/ion-breadcrumb_2.cjs.entry.js +3 -3
  176. package/dist/cjs/ion-button_2.cjs.entry.js +23 -34
  177. package/dist/cjs/ion-card_5.cjs.entry.js +19 -7
  178. package/dist/cjs/ion-checkbox.cjs.entry.js +4 -4
  179. package/dist/cjs/ion-chip.cjs.entry.js +2 -2
  180. package/dist/cjs/ion-col_3.cjs.entry.js +2 -2
  181. package/dist/cjs/ion-datetime-button.cjs.entry.js +4 -4
  182. package/dist/cjs/ion-datetime.cjs.entry.js +6 -6
  183. package/dist/cjs/ion-fab_3.cjs.entry.js +3 -3
  184. package/dist/cjs/ion-img.cjs.entry.js +3 -3
  185. package/dist/cjs/ion-infinite-scroll_2.cjs.entry.js +5 -5
  186. package/dist/cjs/ion-input-otp.cjs.entry.js +3 -3
  187. package/dist/cjs/ion-input-password-toggle.cjs.entry.js +2 -2
  188. package/dist/cjs/ion-input.cjs.entry.js +5 -5
  189. package/dist/cjs/ion-item-option_3.cjs.entry.js +4 -4
  190. package/dist/cjs/ion-item_8.cjs.entry.js +17 -8
  191. package/dist/cjs/ion-loading.cjs.entry.js +7 -7
  192. package/dist/cjs/ion-menu_3.cjs.entry.js +7 -7
  193. package/dist/cjs/ion-modal.cjs.entry.js +11 -11
  194. package/dist/cjs/ion-nav_2.cjs.entry.js +6 -6
  195. package/dist/cjs/ion-picker-column-option.cjs.entry.js +3 -3
  196. package/dist/cjs/ion-picker-column.cjs.entry.js +5 -5
  197. package/dist/cjs/ion-picker.cjs.entry.js +2 -2
  198. package/dist/cjs/ion-popover.cjs.entry.js +108 -29
  199. package/dist/cjs/ion-progress-bar.cjs.entry.js +3 -3
  200. package/dist/cjs/ion-radio_2.cjs.entry.js +4 -4
  201. package/dist/cjs/ion-range.cjs.entry.js +4 -4
  202. package/dist/cjs/ion-refresher_2.cjs.entry.js +8 -8
  203. package/dist/cjs/ion-reorder_2.cjs.entry.js +6 -6
  204. package/dist/cjs/ion-ripple-effect.cjs.entry.js +2 -2
  205. package/dist/cjs/ion-route_4.cjs.entry.js +4 -4
  206. package/dist/cjs/ion-searchbar.cjs.entry.js +3 -3
  207. package/dist/cjs/ion-segment-content.cjs.entry.js +1 -1
  208. package/dist/cjs/ion-segment-view.cjs.entry.js +1 -1
  209. package/dist/cjs/ion-segment_2.cjs.entry.js +3 -3
  210. package/dist/cjs/ion-select-modal.cjs.entry.js +7 -7
  211. package/dist/cjs/ion-select_3.cjs.entry.js +8 -8
  212. package/dist/cjs/ion-spinner.cjs.entry.js +2 -2
  213. package/dist/cjs/ion-split-pane.cjs.entry.js +2 -2
  214. package/dist/cjs/ion-tab-bar_2.cjs.entry.js +6 -6
  215. package/dist/cjs/ion-tab_2.cjs.entry.js +3 -3
  216. package/dist/cjs/ion-text.cjs.entry.js +2 -2
  217. package/dist/cjs/ion-textarea.cjs.entry.js +5 -5
  218. package/dist/cjs/ion-toast.cjs.entry.js +7 -7
  219. package/dist/cjs/ion-toggle.cjs.entry.js +6 -6
  220. package/dist/cjs/{ionic-global-BWd7usAF.js → ionic-global-t_WpJo84.js} +1 -1
  221. package/dist/cjs/ionic.cjs.js +4 -4
  222. package/dist/cjs/{ios.transition-6AFNO6uU.js → ios.transition-DZLrW8ga.js} +4 -4
  223. package/dist/cjs/{item-multiple-inputs-BaBx_Te8.js → item-multiple-inputs-n1sInjA_.js} +1 -1
  224. package/dist/cjs/{keyboard-DstMw6u1.js → keyboard-C06ZtyfO.js} +1 -1
  225. package/dist/cjs/{keyboard-BJEm-3HF.js → keyboard-CrDGk8Si.js} +4 -4
  226. package/dist/cjs/{keyboard-controller-DaUNT15d.js → keyboard-controller-CMLPZLrw.js} +2 -2
  227. package/dist/cjs/loader.cjs.js +4 -4
  228. package/dist/cjs/{md.transition-CPq0ckrU.js → md.transition-BKWfxYYf.js} +4 -4
  229. package/dist/cjs/{overlays-DwMDYc_O.js → overlays-BEVysBKh.js} +4 -4
  230. package/dist/cjs/{select-option-render-Cu-ABBRH.js → select-option-render-CSPIWz_C.js} +2 -2
  231. package/dist/cjs/{slot-mutation-controller-CtYZdaWI.js → slot-mutation-controller-ByWHY518.js} +1 -1
  232. package/dist/cjs/{status-tap-BUfv_eD4.js → status-tap-CL5oy8nW.js} +3 -3
  233. package/dist/cjs/{swipe-back-DYKxJU5r.js → swipe-back-CMxnx1Rv.js} +2 -2
  234. package/dist/collection/components/button/button.js +21 -32
  235. package/dist/collection/components/card/card.js +17 -6
  236. package/dist/collection/components/item/item.js +15 -6
  237. package/dist/collection/components/popover/animations/ios.enter.js +20 -6
  238. package/dist/collection/components/popover/animations/md.enter.js +19 -5
  239. package/dist/collection/components/popover/utils.js +64 -13
  240. package/dist/collection/index.js +1 -1
  241. package/dist/collection/utils/attribute-controller.js +126 -0
  242. package/dist/collection/utils/helpers.js +5 -3
  243. package/dist/collection/utils/logging/index.js +4 -0
  244. package/dist/docs.json +1 -1
  245. package/dist/esm/{animation-CAzXJ2I1.js → animation-DRatc9mc.js} +2 -2
  246. package/dist/esm/{app-globals-DGJXnnkm.js → app-globals-BAPWjQRi.js} +1 -1
  247. package/dist/esm/attribute-controller-BrbFqJRn.js +128 -0
  248. package/dist/esm/{button-active-DyyWVqU3.js → button-active-Cn0mS9NP.js} +2 -2
  249. package/dist/esm/{capacitor-C041I3qZ.js → capacitor-DOXE6jIG.js} +1 -1
  250. package/dist/esm/{format-D78cdY12.js → format-Cd2aRger.js} +1 -1
  251. package/dist/esm/{framework-delegate-CUDbUfWS.js → framework-delegate-Dyvjs63n.js} +1 -1
  252. package/dist/esm/{haptic-D3njgGLB.js → haptic-B3RodENJ.js} +1 -1
  253. package/dist/esm/{helpers-BJFnZngp.js → helpers-D3HlaZqB.js} +6 -4
  254. package/dist/esm/{index-CdoVp_rZ.js → index-65Eftz2j.js} +4 -4
  255. package/dist/esm/{index-DmnOg_xm.js → index-B2E_HqxY.js} +1 -1
  256. package/dist/esm/{index-obGyiHiO.js → index-BBArCvE7.js} +2 -2
  257. package/dist/esm/{index-DoY4e_3F.js → index-BcTd8Van.js} +2 -2
  258. package/dist/esm/{index-iurdcGHg.js → index-C3hi0PAx.js} +5 -5
  259. package/dist/esm/{index-Dvqtt_WK.js → index-Ci0c0wtC.js} +5 -1
  260. package/dist/esm/index.js +11 -11
  261. package/dist/esm/{input-shims-DognYvwv.js → input-shims-pdb7CjZn.js} +5 -5
  262. package/dist/esm/{input.utils-C3mVJhji.js → input.utils-DTipZVu0.js} +1 -1
  263. package/dist/esm/ion-accordion_2.entry.js +3 -3
  264. package/dist/esm/ion-action-sheet.entry.js +11 -11
  265. package/dist/esm/ion-alert.entry.js +11 -11
  266. package/dist/esm/ion-app_8.entry.js +16 -16
  267. package/dist/esm/ion-avatar_3.entry.js +2 -2
  268. package/dist/esm/ion-back-button.entry.js +3 -3
  269. package/dist/esm/ion-backdrop.entry.js +2 -2
  270. package/dist/esm/ion-breadcrumb_2.entry.js +3 -3
  271. package/dist/esm/ion-button_2.entry.js +23 -34
  272. package/dist/esm/ion-card_5.entry.js +19 -7
  273. package/dist/esm/ion-checkbox.entry.js +4 -4
  274. package/dist/esm/ion-chip.entry.js +2 -2
  275. package/dist/esm/ion-col_3.entry.js +2 -2
  276. package/dist/esm/ion-datetime-button.entry.js +4 -4
  277. package/dist/esm/ion-datetime.entry.js +6 -6
  278. package/dist/esm/ion-fab_3.entry.js +3 -3
  279. package/dist/esm/ion-img.entry.js +3 -3
  280. package/dist/esm/ion-infinite-scroll_2.entry.js +5 -5
  281. package/dist/esm/ion-input-otp.entry.js +3 -3
  282. package/dist/esm/ion-input-password-toggle.entry.js +2 -2
  283. package/dist/esm/ion-input.entry.js +5 -5
  284. package/dist/esm/ion-item-option_3.entry.js +4 -4
  285. package/dist/esm/ion-item_8.entry.js +17 -8
  286. package/dist/esm/ion-loading.entry.js +7 -7
  287. package/dist/esm/ion-menu_3.entry.js +7 -7
  288. package/dist/esm/ion-modal.entry.js +11 -11
  289. package/dist/esm/ion-nav_2.entry.js +6 -6
  290. package/dist/esm/ion-picker-column-option.entry.js +3 -3
  291. package/dist/esm/ion-picker-column.entry.js +5 -5
  292. package/dist/esm/ion-picker.entry.js +2 -2
  293. package/dist/esm/ion-popover.entry.js +108 -29
  294. package/dist/esm/ion-progress-bar.entry.js +3 -3
  295. package/dist/esm/ion-radio_2.entry.js +4 -4
  296. package/dist/esm/ion-range.entry.js +4 -4
  297. package/dist/esm/ion-refresher_2.entry.js +8 -8
  298. package/dist/esm/ion-reorder_2.entry.js +6 -6
  299. package/dist/esm/ion-ripple-effect.entry.js +2 -2
  300. package/dist/esm/ion-route_4.entry.js +4 -4
  301. package/dist/esm/ion-searchbar.entry.js +3 -3
  302. package/dist/esm/ion-segment-content.entry.js +1 -1
  303. package/dist/esm/ion-segment-view.entry.js +1 -1
  304. package/dist/esm/ion-segment_2.entry.js +3 -3
  305. package/dist/esm/ion-select-modal.entry.js +7 -7
  306. package/dist/esm/ion-select_3.entry.js +8 -8
  307. package/dist/esm/ion-spinner.entry.js +2 -2
  308. package/dist/esm/ion-split-pane.entry.js +2 -2
  309. package/dist/esm/ion-tab-bar_2.entry.js +6 -6
  310. package/dist/esm/ion-tab_2.entry.js +3 -3
  311. package/dist/esm/ion-text.entry.js +2 -2
  312. package/dist/esm/ion-textarea.entry.js +5 -5
  313. package/dist/esm/ion-toast.entry.js +7 -7
  314. package/dist/esm/ion-toggle.entry.js +6 -6
  315. package/dist/esm/{ionic-global-BSaFA7np.js → ionic-global-D319UM2i.js} +1 -1
  316. package/dist/esm/ionic.js +5 -5
  317. package/dist/esm/{ios.transition-ofa92pAl.js → ios.transition-CjR-iczx.js} +4 -4
  318. package/dist/esm/{item-multiple-inputs-CffmpUe9.js → item-multiple-inputs-CtLCJNiL.js} +1 -1
  319. package/dist/esm/{keyboard-Dsc85bts.js → keyboard-BPq0DuxS.js} +4 -4
  320. package/dist/esm/{keyboard-Cz4hUjuj.js → keyboard-Fuj-w2n0.js} +1 -1
  321. package/dist/esm/{keyboard-controller-BLvRgxgP.js → keyboard-controller-kCdrbtXb.js} +2 -2
  322. package/dist/esm/loader.js +5 -5
  323. package/dist/esm/{md.transition-DnFfqsAv.js → md.transition-BFmU8zjI.js} +4 -4
  324. package/dist/esm/{overlays-a_5AhqWk.js → overlays-D2Bo1FJ7.js} +4 -4
  325. package/dist/esm/{select-option-render-C_PCwA67.js → select-option-render-m4fqbKrD.js} +2 -2
  326. package/dist/esm/{slot-mutation-controller-D7n8Peo2.js → slot-mutation-controller-B_Gyzsmn.js} +1 -1
  327. package/dist/esm/{status-tap-BsTKKfug.js → status-tap-D3yqZrEP.js} +3 -3
  328. package/dist/esm/{swipe-back-ibFGqXH2.js → swipe-back-DDOJz7NH.js} +2 -2
  329. package/dist/ionic/index.esm.js +1 -1
  330. package/dist/ionic/ionic.esm.js +1 -1
  331. package/dist/ionic/p-011a08e9.entry.js +4 -0
  332. package/dist/ionic/{p-59305088.entry.js → p-0e8ae661.entry.js} +1 -1
  333. package/dist/ionic/p-12d381c2.entry.js +4 -0
  334. package/dist/ionic/{p-28952272.entry.js → p-12f0fc68.entry.js} +1 -1
  335. package/dist/ionic/{p-26d89234.entry.js → p-1daca166.entry.js} +1 -1
  336. package/dist/ionic/{p-fc3312a4.entry.js → p-2619b489.entry.js} +1 -1
  337. package/dist/ionic/{p-89e04e63.entry.js → p-28b0a9c7.entry.js} +1 -1
  338. package/dist/ionic/{p-cb893f35.entry.js → p-29e6a8d4.entry.js} +1 -1
  339. package/dist/ionic/{p-88cf4127.entry.js → p-2b32af08.entry.js} +1 -1
  340. package/dist/ionic/{p-41ae57ea.entry.js → p-304f92d1.entry.js} +1 -1
  341. package/dist/ionic/{p-fd220f9c.entry.js → p-35469a67.entry.js} +1 -1
  342. package/dist/ionic/{p-12ea6d13.entry.js → p-3fa7f61a.entry.js} +1 -1
  343. package/dist/ionic/{p-84dea138.entry.js → p-4253fc9f.entry.js} +1 -1
  344. package/dist/ionic/{p-5272e103.entry.js → p-44046266.entry.js} +1 -1
  345. package/dist/ionic/{p-416bec74.entry.js → p-45ca4440.entry.js} +1 -1
  346. package/dist/ionic/{p-5eadc64e.entry.js → p-49b1f0c1.entry.js} +1 -1
  347. package/dist/ionic/{p-efa78f73.entry.js → p-50ce079e.entry.js} +1 -1
  348. package/dist/ionic/p-51eb3f6f.entry.js +4 -0
  349. package/dist/ionic/{p-ac6a1168.entry.js → p-584579e7.entry.js} +1 -1
  350. package/dist/ionic/{p-0a824cef.entry.js → p-5dc1ad24.entry.js} +1 -1
  351. package/dist/ionic/p-5f41981f.entry.js +4 -0
  352. package/dist/ionic/{p-dd89474c.entry.js → p-62528b98.entry.js} +1 -1
  353. package/dist/ionic/p-636baa66.entry.js +4 -0
  354. package/dist/ionic/{p-d8a6ebfd.entry.js → p-64d0e766.entry.js} +1 -1
  355. package/dist/ionic/p-6f52068e.entry.js +4 -0
  356. package/dist/ionic/p-78d66dbf.entry.js +4 -0
  357. package/dist/ionic/{p-689f7a37.entry.js → p-84f30235.entry.js} +1 -1
  358. package/dist/ionic/{p-60ca717e.entry.js → p-87d878dc.entry.js} +1 -1
  359. package/dist/ionic/p-8WDtqI_V.js +4 -0
  360. package/dist/ionic/{p-063769cf.entry.js → p-8d6e044e.entry.js} +1 -1
  361. package/dist/ionic/p-920e067d.entry.js +4 -0
  362. package/dist/ionic/p-950c9b8b.entry.js +4 -0
  363. package/dist/ionic/p-BIiK2pe9.js +4 -0
  364. package/{components/p-BezPzC13.js → dist/ionic/p-BKzIpETv.js} +1 -1
  365. package/dist/ionic/p-BZlmYZid.js +4 -0
  366. package/dist/ionic/p-BiQyyAay.js +4 -0
  367. package/dist/ionic/p-Bl3GtrLa.js +4 -0
  368. package/dist/ionic/{p-C5SsTfux.js → p-BlIL832I.js} +1 -1
  369. package/dist/ionic/p-C-f6azUS.js +4 -0
  370. package/dist/ionic/p-C7ycgP4B.js +4 -0
  371. package/dist/ionic/p-CDm80Rj3.js +4 -0
  372. package/dist/ionic/p-CHFzrYxP.js +4 -0
  373. package/dist/ionic/{p-yiP8rgDC.js → p-CKXT3wQs.js} +1 -1
  374. package/dist/ionic/p-CM0qxZsb.js +4 -0
  375. package/dist/ionic/p-CQ_2X4AT.js +4 -0
  376. package/dist/ionic/p-CVrhKnjg.js +4 -0
  377. package/dist/ionic/{p-g9SK-dv1.js → p-CeBx7xPk.js} +1 -1
  378. package/dist/ionic/{p-Dvqtt_WK.js → p-Ci0c0wtC.js} +1 -1
  379. package/dist/ionic/{p-BIj0Lfim.js → p-DBXYO0BD.js} +1 -1
  380. package/dist/ionic/p-DMhM7rpA.js +4 -0
  381. package/dist/ionic/p-DR3KphGG.js +4 -0
  382. package/{components/p-CaY8IRMT.js → dist/ionic/p-DRhfTaQ0.js} +1 -1
  383. package/dist/ionic/p-DYjohhqj.js +4 -0
  384. package/dist/ionic/{p-BRlwrQ6h.js → p-DgorWJ0n.js} +1 -1
  385. package/dist/ionic/p-Dk5f_kFq.js +4 -0
  386. package/dist/ionic/{p-e0g1fYYm.js → p-DrPUIWm0.js} +1 -1
  387. package/dist/ionic/p-M3xPAPEh.js +4 -0
  388. package/dist/ionic/p-RgtmfsTX.js +4 -0
  389. package/dist/ionic/p-YkyvCGQx.js +4 -0
  390. package/dist/ionic/{p-e04a7110.entry.js → p-a72282cf.entry.js} +1 -1
  391. package/dist/ionic/p-a848f8d2.entry.js +4 -0
  392. package/dist/ionic/{p-df272a41.entry.js → p-a9e92328.entry.js} +1 -1
  393. package/dist/ionic/{p-8af458bf.entry.js → p-b08bcb06.entry.js} +1 -1
  394. package/dist/ionic/p-c176a425.entry.js +4 -0
  395. package/dist/ionic/{p-41254776.entry.js → p-c6c32f6d.entry.js} +1 -1
  396. package/dist/ionic/p-c913bd7d.entry.js +4 -0
  397. package/dist/ionic/{p-0a14a6a3.entry.js → p-d1687c72.entry.js} +1 -1
  398. package/dist/ionic/{p-c9952851.entry.js → p-d2a4fcf9.entry.js} +1 -1
  399. package/dist/ionic/{p-a1d733a3.entry.js → p-d428580a.entry.js} +1 -1
  400. package/dist/ionic/{p-25abc69d.entry.js → p-d7c9b618.entry.js} +1 -1
  401. package/dist/ionic/{p-d7fb1d2a.entry.js → p-dc0c071c.entry.js} +1 -1
  402. package/dist/ionic/{p-097a0cf5.entry.js → p-dc531e27.entry.js} +1 -1
  403. package/dist/ionic/p-de9cbee0.entry.js +4 -0
  404. package/dist/ionic/{p-302e4d74.entry.js → p-e223cd26.entry.js} +1 -1
  405. package/dist/ionic/{p-c0dd14f4.entry.js → p-f5a0d31b.entry.js} +1 -1
  406. package/dist/ionic/{p-7da532af.entry.js → p-f930dcb4.entry.js} +1 -1
  407. package/dist/ionic/{p-a4a2ce90.entry.js → p-f93bd399.entry.js} +1 -1
  408. package/dist/ionic/p-fa45723d.entry.js +4 -0
  409. package/dist/ionic/{p-38d3e1cb.entry.js → p-fab0961c.entry.js} +1 -1
  410. package/dist/ionic/p-fbf4767c.entry.js +4 -0
  411. package/dist/ionic/{p-CESQIy-V.js → p-vGIL6Nbe.js} +1 -1
  412. package/dist/types/components/button/button.d.ts +3 -12
  413. package/dist/types/components/card/card.d.ts +3 -1
  414. package/dist/types/components/item/item.d.ts +1 -1
  415. package/dist/types/components/popover/utils.d.ts +16 -3
  416. package/dist/types/index.d.ts +1 -1
  417. package/dist/types/utils/attribute-controller.d.ts +56 -0
  418. package/dist/types/utils/helpers.d.ts +10 -2
  419. package/dist/types/utils/logging/index.d.ts +4 -0
  420. package/hydrate/index.js +278 -63
  421. package/hydrate/index.mjs +278 -63
  422. package/package.json +1 -1
  423. package/components/p--pR3YKVX.js +0 -4
  424. package/components/p-47h0_nN4.js +0 -4
  425. package/components/p-BGChz0G8.js +0 -4
  426. package/components/p-BLe-edUh.js +0 -4
  427. package/components/p-Bc-3W2an.js +0 -4
  428. package/components/p-BezRi1ML.js +0 -4
  429. package/components/p-C0tpzcpi.js +0 -4
  430. package/components/p-CDt7Q7Dj.js +0 -4
  431. package/components/p-CDvyV0r0.js +0 -4
  432. package/components/p-CEs5NmKW.js +0 -4
  433. package/components/p-CLVgYpRn.js +0 -4
  434. package/components/p-CPGp3WWG.js +0 -4
  435. package/components/p-CeGQfrDU.js +0 -4
  436. package/components/p-CpcdCRug.js +0 -4
  437. package/components/p-DVHC9GYb.js +0 -4
  438. package/components/p-DWe-YApm.js +0 -4
  439. package/components/p-DX_3N4fh.js +0 -4
  440. package/components/p-DftucGJR.js +0 -4
  441. package/components/p-HO1CDBeU.js +0 -4
  442. package/components/p-MOwrp7hX.js +0 -4
  443. package/components/p-k92zpBT6.js +0 -4
  444. package/components/p-rDUBp56G.js +0 -4
  445. package/dist/ionic/p-1c4926e9.entry.js +0 -4
  446. package/dist/ionic/p-1dac4211.entry.js +0 -4
  447. package/dist/ionic/p-23afeeb2.entry.js +0 -4
  448. package/dist/ionic/p-29687c0b.entry.js +0 -4
  449. package/dist/ionic/p-2ecebfd9.entry.js +0 -4
  450. package/dist/ionic/p-4dc3f2b3.entry.js +0 -4
  451. package/dist/ionic/p-5b9b245e.entry.js +0 -4
  452. package/dist/ionic/p-5f695204.entry.js +0 -4
  453. package/dist/ionic/p-63eb4550.entry.js +0 -4
  454. package/dist/ionic/p-8d68604a.entry.js +0 -4
  455. package/dist/ionic/p-B13Uv-FT.js +0 -4
  456. package/dist/ionic/p-B8K6OHqa.js +0 -4
  457. package/dist/ionic/p-BD0v0Sx_.js +0 -4
  458. package/dist/ionic/p-BDs20Dfe.js +0 -4
  459. package/dist/ionic/p-BRZstBYy.js +0 -4
  460. package/dist/ionic/p-Ba_yQZdQ.js +0 -4
  461. package/dist/ionic/p-BnMJqJBa.js +0 -4
  462. package/dist/ionic/p-BrbwGxm1.js +0 -4
  463. package/dist/ionic/p-Bx46Dlpo.js +0 -4
  464. package/dist/ionic/p-C0vJzNM9.js +0 -4
  465. package/dist/ionic/p-C4FdGOym.js +0 -4
  466. package/dist/ionic/p-CD77BF32.js +0 -4
  467. package/dist/ionic/p-CazJOH5P.js +0 -4
  468. package/dist/ionic/p-D14knedj.js +0 -4
  469. package/dist/ionic/p-DQcKi6P6.js +0 -4
  470. package/dist/ionic/p-NL1pxcde.js +0 -4
  471. package/dist/ionic/p-a6a95175.entry.js +0 -4
  472. package/dist/ionic/p-bcf18c26.entry.js +0 -4
  473. package/dist/ionic/p-be8ae1cc.entry.js +0 -4
  474. package/dist/ionic/p-e3a98575.entry.js +0 -4
  475. package/dist/ionic/p-f97ef975.entry.js +0 -4
  476. package/dist/ionic/p-yYEBg4iw.js +0 -4
@@ -30,10 +30,18 @@ export type Attributes = {
30
30
  * helper function should be called in componentWillLoad and assigned to a variable
31
31
  * that is later used in the render function.
32
32
  *
33
- * This does not need to be reactive as changing attributes on the host element
34
- * does not trigger a re-render.
33
+ * This copies once. Use `createAttributeController` instead when the attributes can
34
+ * change after load, since a host attribute change does not trigger a re-render.
35
35
  */
36
36
  export declare const inheritAttributes: (el: HTMLElement, attributes?: string[]) => Attributes;
37
+ /**
38
+ * List of available ARIA attributes + `role`.
39
+ * Removed deprecated attributes.
40
+ * https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes
41
+ *
42
+ * @internal Exported for `attribute-controller.ts`, which needs the same set.
43
+ */
44
+ export declare const ariaAttributes: string[];
37
45
  /**
38
46
  * Returns an array of aria attributes that should be copied from
39
47
  * the shadow host element to a target within the light DOM.
@@ -9,6 +9,8 @@ export declare enum LogLevel {
9
9
  * to indicate the library that is warning the developer.
10
10
  *
11
11
  * @param message - The string message to be logged to the console.
12
+ *
13
+ * @internal
12
14
  */
13
15
  export declare const printIonWarning: (message: string, ...params: any[]) => void;
14
16
  /**
@@ -17,6 +19,8 @@ export declare const printIonWarning: (message: string, ...params: any[]) => voi
17
19
  *
18
20
  * @param message - The string message to be logged to the console.
19
21
  * @param params - Additional arguments to supply to the console.error.
22
+ *
23
+ * @internal
20
24
  */
21
25
  export declare const printIonError: (message: string, ...params: any[]) => void;
22
26
  /**
package/hydrate/index.js CHANGED
@@ -286,6 +286,8 @@ const isLogLevelEnabled = (minimum) => {
286
286
  * to indicate the library that is warning the developer.
287
287
  *
288
288
  * @param message - The string message to be logged to the console.
289
+ *
290
+ * @internal
289
291
  */
290
292
  const printIonWarning = (message, ...params) => {
291
293
  if (isLogLevelEnabled(LogLevel.WARN)) {
@@ -298,6 +300,8 @@ const printIonWarning = (message, ...params) => {
298
300
  *
299
301
  * @param message - The string message to be logged to the console.
300
302
  * @param params - Additional arguments to supply to the console.error.
303
+ *
304
+ * @internal
301
305
  */
302
306
  const printIonError = (message, ...params) => {
303
307
  if (isLogLevelEnabled(LogLevel.ERROR)) {
@@ -5945,8 +5949,8 @@ const hasLazyBuild = (stencilEl) => {
5945
5949
  * helper function should be called in componentWillLoad and assigned to a variable
5946
5950
  * that is later used in the render function.
5947
5951
  *
5948
- * This does not need to be reactive as changing attributes on the host element
5949
- * does not trigger a re-render.
5952
+ * This copies once. Use `createAttributeController` instead when the attributes can
5953
+ * change after load, since a host attribute change does not trigger a re-render.
5950
5954
  */
5951
5955
  const inheritAttributes$1 = (el, attributes = []) => {
5952
5956
  const attributeObject = {};
@@ -5965,6 +5969,8 @@ const inheritAttributes$1 = (el, attributes = []) => {
5965
5969
  * List of available ARIA attributes + `role`.
5966
5970
  * Removed deprecated attributes.
5967
5971
  * https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes
5972
+ *
5973
+ * @internal Exported for `attribute-controller.ts`, which needs the same set.
5968
5974
  */
5969
5975
  const ariaAttributes = [
5970
5976
  'role',
@@ -12263,6 +12269,128 @@ class Breadcrumbs {
12263
12269
  }; }
12264
12270
  }
12265
12271
 
12272
+ /**
12273
+ * Copies a set of attributes off the host element so they can be applied to an element
12274
+ * inside the shadow root, then keeps that copy in sync as the host attributes change.
12275
+ * Using `inheritAttributes` alone copies once at load, so anything written to the host
12276
+ * afterwards never reaches the element the assistive technology reads.
12277
+ *
12278
+ * Create the controller in `componentWillLoad`. It takes the initial copy and starts
12279
+ * watching right away, so `init()` is only needed to resume after a move.
12280
+ *
12281
+ * Two things to know before adopting it. Only the initial copy removes the attributes
12282
+ * from the host, so a value written after load sits on the host as well as on the
12283
+ * element it is applied to, which matters if the host has a role of its own. And an
12284
+ * attribute from the initial markup can never be removed, only overwritten, since the
12285
+ * copy already took it off the host and a `removeAttribute` there fires no mutation.
12286
+ * An empty string works for `aria-label` and friends, but a token-valued attribute
12287
+ * has to be set to its default instead, so `aria-pressed="false"` rather than empty.
12288
+ *
12289
+ * @internal
12290
+ * @param el The host element to copy from and watch.
12291
+ * @param attributes The attributes to copy and watch.
12292
+ * @param onChange Called after `attributes` changes, so the component can re-render.
12293
+ * @param hostOwnedAttributes Attributes copied at load but not watched. Use it for
12294
+ * attributes the component renders on its own `<Host>`, since a later change to one of
12295
+ * those is the component's own write, and for attributes that would put a second node in
12296
+ * the accessibility tree if the host kept a copy alongside the one we apply.
12297
+ */
12298
+ const createAttributeController = (el, attributes, onChange, hostOwnedAttributes = []) => {
12299
+ let inherited = inheritAttributes$1(el, attributes);
12300
+ let observer;
12301
+ const watchedAttributes = attributes.filter((attr) => !hostOwnedAttributes.includes(attr));
12302
+ /**
12303
+ * The names still on the host, which is everything written after load. The initial
12304
+ * copy removes what it captures, so a missing attribute only counts as a removal
12305
+ * when its name is in here.
12306
+ */
12307
+ const hostWritten = new Set();
12308
+ const setPresence = (name, value) => {
12309
+ if (value === null) {
12310
+ hostWritten.delete(name);
12311
+ }
12312
+ else {
12313
+ hostWritten.add(name);
12314
+ }
12315
+ };
12316
+ /**
12317
+ * Nothing is watching while the host is out of the tree, since `disconnectedCallback`
12318
+ * calls `destroy()`, and `forceUpdate` is a no-op on a disconnected host anyway. So
12319
+ * the host has to be re-read on the way back in.
12320
+ */
12321
+ const readMissedChanges = () => {
12322
+ const changed = {};
12323
+ for (const name of watchedAttributes) {
12324
+ const value = el.getAttribute(name);
12325
+ const wasOnHost = hostWritten.has(name);
12326
+ setPresence(name, value);
12327
+ /**
12328
+ * An attribute that was never written to the host is missing because the initial
12329
+ * copy took it, not because the developer cleared it.
12330
+ */
12331
+ if ((value === null && !wasOnHost) || value === inherited[name]) {
12332
+ continue;
12333
+ }
12334
+ changed[name] = value;
12335
+ }
12336
+ if (Object.keys(changed).length > 0) {
12337
+ inherited = { ...inherited, ...changed };
12338
+ onChange();
12339
+ }
12340
+ };
12341
+ const init = () => {
12342
+ // There is no MutationObserver in SSR or the hydrate build.
12343
+ if (observer !== undefined || watchedAttributes.length === 0 || win$1 === undefined || !('MutationObserver' in win$1)) {
12344
+ return;
12345
+ }
12346
+ readMissedChanges();
12347
+ observer = new MutationObserver((mutations) => {
12348
+ const changed = {};
12349
+ for (const mutation of mutations) {
12350
+ const name = mutation.attributeName;
12351
+ // A removed attribute reads back as null, which clears it from the element the
12352
+ // values are spread onto.
12353
+ const value = el.getAttribute(name);
12354
+ setPresence(name, value);
12355
+ changed[name] = value;
12356
+ }
12357
+ inherited = { ...inherited, ...changed };
12358
+ onChange();
12359
+ });
12360
+ observer.observe(el, { attributeFilter: watchedAttributes });
12361
+ };
12362
+ const destroy = () => {
12363
+ observer?.disconnect();
12364
+ observer = undefined;
12365
+ };
12366
+ /**
12367
+ * Has to run after the initial copy, because that copy removes the attributes from the
12368
+ * host and an observer armed any earlier would read the removal as a developer clearing
12369
+ * them.
12370
+ */
12371
+ init();
12372
+ return {
12373
+ get attributes() {
12374
+ return inherited;
12375
+ },
12376
+ init,
12377
+ destroy,
12378
+ };
12379
+ };
12380
+ /**
12381
+ * The `createAttributeController` equivalent of `inheritAriaAttributes`, which copies and
12382
+ * watches every ARIA attribute plus `role`.
12383
+ *
12384
+ * @internal
12385
+ * @param el The host element to copy from and watch.
12386
+ * @param onChange Called after the attributes change, so the component can re-render.
12387
+ * @param hostOwnedAttributes Attributes copied at load but not watched. See
12388
+ * `createAttributeController`.
12389
+ */
12390
+ const createAriaAttributeController = (el, onChange, hostOwnedAttributes = []) => {
12391
+ return createAttributeController(el, ariaAttributes, onChange, hostOwnedAttributes);
12392
+ };
12393
+
12266
12394
  const buttonIosCss = () => `:host{--overflow:hidden;--ripple-color:currentColor;--border-width:initial;--border-color:initial;--border-style:initial;--color-activated:var(--color);--color-focused:var(--color);--color-hover:var(--color);--box-shadow:none;display:inline-block;width:auto;color:var(--color);font-family:var(--ion-font-family, inherit);text-align:center;text-decoration:none;white-space:normal;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:top;vertical-align:-webkit-baseline-middle;-webkit-font-kerning:none;font-kerning:none}:host(.button-disabled){cursor:default;opacity:0.5;pointer-events:none}:host(.button-solid){--background:var(--ion-color-primary, #0054e9);--color:var(--ion-color-primary-contrast, #fff)}:host(.button-outline){--border-color:var(--ion-color-primary, #0054e9);--background:transparent;--color:var(--ion-color-primary, #0054e9)}:host(.button-clear){--border-width:0;--background:transparent;--color:var(--ion-color-primary, #0054e9)}:host(.button-block){display:block}:host(.button-block) .button-native{margin-left:0;margin-right:0;width:100%;clear:both;contain:content}:host(.button-block) .button-native::after{clear:both}:host(.button-full){display:block}:host(.button-full) .button-native{margin-left:0;margin-right:0;width:100%;contain:content}:host(.button-full:not(.button-round)) .button-native{border-radius:0;border-right-width:0;border-left-width:0}.button-native{border-radius:var(--border-radius);-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;display:-ms-flexbox;display:flex;position:relative;-ms-flex-align:center;align-items:center;width:100%;height:100%;min-height:inherit;-webkit-transition:var(--transition);transition:var(--transition);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);outline:none;background:var(--background);line-height:1;-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);contain:layout style;cursor:pointer;opacity:var(--opacity);overflow:var(--overflow);z-index:0;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none;appearance:none}.button-native::-moz-focus-inner{border:0}.button-inner{display:-ms-flexbox;display:flex;position:relative;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;z-index:1}::slotted([slot=start]),::slotted([slot=end]){-ms-flex-negative:0;flex-shrink:0}::slotted(ion-icon){font-size:1.35em;pointer-events:none}::slotted(ion-icon[slot=start]){-webkit-margin-start:-0.3em;margin-inline-start:-0.3em;-webkit-margin-end:0.3em;margin-inline-end:0.3em;margin-top:0;margin-bottom:0}::slotted(ion-icon[slot=end]){-webkit-margin-start:0.3em;margin-inline-start:0.3em;-webkit-margin-end:-0.2em;margin-inline-end:-0.2em;margin-top:0;margin-bottom:0}ion-ripple-effect{color:var(--ripple-color)}.button-native::after{left:0;right:0;top:0;bottom:0;position:absolute;content:"";opacity:0}:host(.ion-focused){color:var(--color-focused)}:host(.ion-focused) .button-native::after{background:var(--background-focused);opacity:var(--background-focused-opacity)}@media (any-hover: hover){:host(:hover){color:var(--color-hover)}:host(:hover) .button-native::after{background:var(--background-hover);opacity:var(--background-hover-opacity)}}:host(.ion-activated){color:var(--color-activated)}:host(.ion-activated) .button-native::after{background:var(--background-activated);opacity:var(--background-activated-opacity)}:host(.button-solid.ion-color) .button-native{background:var(--ion-color-base);color:var(--ion-color-contrast)}:host(.button-outline.ion-color) .button-native{border-color:var(--ion-color-base);background:transparent;color:var(--ion-color-base)}:host(.button-clear.ion-color) .button-native{background:transparent;color:var(--ion-color-base)}:host(.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native{color:var(--ion-toolbar-color, var(--color))}:host(.button-outline.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native{border-color:var(--ion-toolbar-color, var(--color, var(--border-color)))}:host(.button-solid.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native{background:var(--ion-toolbar-color, var(--background));color:var(--ion-toolbar-background, var(--color))}:host{--border-radius:14px;--padding-top:13px;--padding-bottom:13px;--padding-start:1em;--padding-end:1em;--transition:background-color, opacity 100ms linear;-webkit-margin-start:2px;margin-inline-start:2px;-webkit-margin-end:2px;margin-inline-end:2px;margin-top:4px;margin-bottom:4px;min-height:3.1em;font-size:min(1rem, 48px);font-weight:500;letter-spacing:0}:host(.button-solid){--background-activated:var(--ion-color-primary-shade, #004acd);--background-focused:var(--ion-color-primary-shade, #004acd);--background-hover:var(--ion-color-primary-tint, #1a65eb);--background-activated-opacity:1;--background-focused-opacity:1;--background-hover-opacity:1}:host(.button-outline){--border-radius:14px;--border-width:1px;--border-style:solid;--background-activated:var(--ion-color-primary, #0054e9);--background-focused:var(--ion-color-primary, #0054e9);--background-hover:transparent;--background-focused-opacity:.1;--color-activated:var(--ion-color-primary-contrast, #fff)}:host(.button-clear){--background-activated:transparent;--background-activated-opacity:0;--background-focused:var(--ion-color-primary, #0054e9);--background-hover:transparent;--background-focused-opacity:.1;font-size:min(1.0625rem, 51px);font-weight:normal}:host(.in-buttons){font-size:clamp(17px, 1.0625rem, 21.08px);font-weight:400}:host(.button-large){--border-radius:16px;--padding-top:17px;--padding-start:1em;--padding-end:1em;--padding-bottom:17px;min-height:3.1em;font-size:min(1.25rem, 60px)}:host(.button-small){--border-radius:6px;--padding-top:4px;--padding-start:0.9em;--padding-end:0.9em;--padding-bottom:4px;min-height:2.1em;font-size:min(0.8125rem, 39px)}:host(.button-round){--border-radius:999px;--padding-top:0;--padding-start:26px;--padding-end:26px;--padding-bottom:0}:host(.button-strong){font-weight:600}:host(.button-has-icon-only){--padding-top:0;--padding-bottom:var(--padding-top);--padding-end:var(--padding-top);--padding-start:var(--padding-end);min-width:clamp(30px, 2.125em, 60px);min-height:clamp(30px, 2.125em, 60px)}::slotted(ion-icon[slot=icon-only]){font-size:clamp(15.12px, 1.125em, 43.02px)}:host(.button-small.button-has-icon-only){min-width:clamp(23px, 2.16em, 54px);min-height:clamp(23px, 2.16em, 54px)}:host(.button-small) ::slotted(ion-icon[slot=icon-only]){font-size:clamp(12.1394px, 1.308125em, 40.1856px)}:host(.button-large.button-has-icon-only){min-width:clamp(46px, 2.5em, 78px);min-height:clamp(46px, 2.5em, 78px)}:host(.button-large) ::slotted(ion-icon[slot=icon-only]){font-size:clamp(15.12px, 0.9em, 43.056px)}:host(.button-outline.ion-focused.ion-color) .button-native,:host(.button-clear.ion-focused.ion-color) .button-native{color:var(--ion-color-base)}:host(.button-outline.ion-focused.ion-color) .button-native::after,:host(.button-clear.ion-focused.ion-color) .button-native::after{background:var(--ion-color-base)}:host(.button-solid.ion-color.ion-focused) .button-native::after{background:var(--ion-color-shade)}@media (any-hover: hover){:host(.button-clear:not(.ion-activated):hover),:host(.button-outline:not(.ion-activated):hover){opacity:0.6}:host(.button-clear.ion-color:hover) .button-native,:host(.button-outline.ion-color:hover) .button-native{color:var(--ion-color-base)}:host(.button-clear.ion-color:hover) .button-native::after,:host(.button-outline.ion-color:hover) .button-native::after{background:transparent}:host(.button-solid.ion-color:hover) .button-native::after{background:var(--ion-color-tint)}:host(:hover.button-solid.in-toolbar:not(.ion-color):not(.in-toolbar-color):not(.ion-activated)) .button-native::after{background:#fff;opacity:0.1}}:host(.button-clear.ion-activated){opacity:0.4}:host(.button-outline.ion-activated.ion-color) .button-native{color:var(--ion-color-contrast)}:host(.button-outline.ion-activated.ion-color) .button-native::after{background:var(--ion-color-base)}:host(.button-solid.ion-color.ion-activated) .button-native::after{background:var(--ion-color-shade)}:host(.button-outline.ion-activated.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native{background:var(--ion-toolbar-color, var(--color));color:var(--ion-toolbar-background, var(--background), var(--ion-color-primary-contrast, #fff))}`;
12267
12395
 
12268
12396
  const buttonMdCss = () => `:host{--overflow:hidden;--ripple-color:currentColor;--border-width:initial;--border-color:initial;--border-style:initial;--color-activated:var(--color);--color-focused:var(--color);--color-hover:var(--color);--box-shadow:none;display:inline-block;width:auto;color:var(--color);font-family:var(--ion-font-family, inherit);text-align:center;text-decoration:none;white-space:normal;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:top;vertical-align:-webkit-baseline-middle;-webkit-font-kerning:none;font-kerning:none}:host(.button-disabled){cursor:default;opacity:0.5;pointer-events:none}:host(.button-solid){--background:var(--ion-color-primary, #0054e9);--color:var(--ion-color-primary-contrast, #fff)}:host(.button-outline){--border-color:var(--ion-color-primary, #0054e9);--background:transparent;--color:var(--ion-color-primary, #0054e9)}:host(.button-clear){--border-width:0;--background:transparent;--color:var(--ion-color-primary, #0054e9)}:host(.button-block){display:block}:host(.button-block) .button-native{margin-left:0;margin-right:0;width:100%;clear:both;contain:content}:host(.button-block) .button-native::after{clear:both}:host(.button-full){display:block}:host(.button-full) .button-native{margin-left:0;margin-right:0;width:100%;contain:content}:host(.button-full:not(.button-round)) .button-native{border-radius:0;border-right-width:0;border-left-width:0}.button-native{border-radius:var(--border-radius);-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;display:-ms-flexbox;display:flex;position:relative;-ms-flex-align:center;align-items:center;width:100%;height:100%;min-height:inherit;-webkit-transition:var(--transition);transition:var(--transition);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);outline:none;background:var(--background);line-height:1;-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);contain:layout style;cursor:pointer;opacity:var(--opacity);overflow:var(--overflow);z-index:0;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none;appearance:none}.button-native::-moz-focus-inner{border:0}.button-inner{display:-ms-flexbox;display:flex;position:relative;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;z-index:1}::slotted([slot=start]),::slotted([slot=end]){-ms-flex-negative:0;flex-shrink:0}::slotted(ion-icon){font-size:1.35em;pointer-events:none}::slotted(ion-icon[slot=start]){-webkit-margin-start:-0.3em;margin-inline-start:-0.3em;-webkit-margin-end:0.3em;margin-inline-end:0.3em;margin-top:0;margin-bottom:0}::slotted(ion-icon[slot=end]){-webkit-margin-start:0.3em;margin-inline-start:0.3em;-webkit-margin-end:-0.2em;margin-inline-end:-0.2em;margin-top:0;margin-bottom:0}ion-ripple-effect{color:var(--ripple-color)}.button-native::after{left:0;right:0;top:0;bottom:0;position:absolute;content:"";opacity:0}:host(.ion-focused){color:var(--color-focused)}:host(.ion-focused) .button-native::after{background:var(--background-focused);opacity:var(--background-focused-opacity)}@media (any-hover: hover){:host(:hover){color:var(--color-hover)}:host(:hover) .button-native::after{background:var(--background-hover);opacity:var(--background-hover-opacity)}}:host(.ion-activated){color:var(--color-activated)}:host(.ion-activated) .button-native::after{background:var(--background-activated);opacity:var(--background-activated-opacity)}:host(.button-solid.ion-color) .button-native{background:var(--ion-color-base);color:var(--ion-color-contrast)}:host(.button-outline.ion-color) .button-native{border-color:var(--ion-color-base);background:transparent;color:var(--ion-color-base)}:host(.button-clear.ion-color) .button-native{background:transparent;color:var(--ion-color-base)}:host(.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native{color:var(--ion-toolbar-color, var(--color))}:host(.button-outline.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native{border-color:var(--ion-toolbar-color, var(--color, var(--border-color)))}:host(.button-solid.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native{background:var(--ion-toolbar-color, var(--background));color:var(--ion-toolbar-background, var(--color))}:host{--border-radius:4px;--padding-top:8px;--padding-bottom:8px;--padding-start:1.1em;--padding-end:1.1em;--transition:box-shadow 280ms cubic-bezier(.4, 0, .2, 1), background-color 15ms linear, color 15ms linear;-webkit-margin-start:2px;margin-inline-start:2px;-webkit-margin-end:2px;margin-inline-end:2px;margin-top:4px;margin-bottom:4px;min-height:36px;font-size:0.875rem;font-weight:500;letter-spacing:0.06em;text-transform:uppercase}:host(.button-solid){--background-activated:transparent;--background-hover:var(--ion-color-primary-contrast, #fff);--background-focused:var(--ion-color-primary-contrast, #fff);--background-activated-opacity:0;--background-focused-opacity:.24;--background-hover-opacity:.08;--box-shadow:0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12)}:host(.button-solid.ion-activated){--box-shadow:0 5px 5px -3px rgba(0, 0, 0, 0.2), 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12)}:host(.button-outline){--border-width:2px;--border-style:solid;--box-shadow:none;--background-activated:transparent;--background-focused:var(--ion-color-primary, #0054e9);--background-hover:var(--ion-color-primary, #0054e9);--background-activated-opacity:0;--background-focused-opacity:.12;--background-hover-opacity:.04}:host(.button-outline.ion-activated.ion-color) .button-native{background:transparent}:host(.button-clear){--background-activated:transparent;--background-focused:var(--ion-color-primary, #0054e9);--background-hover:var(--ion-color-primary, #0054e9);--background-activated-opacity:0;--background-focused-opacity:.12;--background-hover-opacity:.04}:host(.button-round){--border-radius:999px;--padding-top:0;--padding-start:26px;--padding-end:26px;--padding-bottom:0}:host(.button-large){--padding-top:14px;--padding-start:1em;--padding-end:1em;--padding-bottom:14px;min-height:2.8em;font-size:1.25rem}:host(.button-small){--padding-top:4px;--padding-start:0.9em;--padding-end:0.9em;--padding-bottom:4px;min-height:2.1em;font-size:0.8125rem}:host(.button-strong){font-weight:bold}:host(.button-has-icon-only){--padding-top:0;--padding-bottom:var(--padding-top);--padding-end:var(--padding-top);--padding-start:var(--padding-end);min-width:clamp(30px, 2.86em, 60px);min-height:clamp(30px, 2.86em, 60px)}::slotted(ion-icon[slot=icon-only]){font-size:clamp(15.104px, 1.6em, 43.008px)}:host(.button-small.button-has-icon-only){min-width:clamp(23px, 2.16em, 54px);min-height:clamp(23px, 2.16em, 54px)}:host(.button-small) ::slotted(ion-icon[slot=icon-only]){font-size:clamp(13.002px, 1.23125em, 40.385px)}:host(.button-large.button-has-icon-only){min-width:clamp(46px, 2.5em, 78px);min-height:clamp(46px, 2.5em, 78px)}:host(.button-large) ::slotted(ion-icon[slot=icon-only]){font-size:clamp(15.008px, 1.4em, 43.008px)}:host(.button-solid.ion-color.ion-focused) .button-native::after{background:var(--ion-color-contrast)}:host(.button-clear.ion-color.ion-focused) .button-native::after,:host(.button-outline.ion-color.ion-focused) .button-native::after{background:var(--ion-color-base)}@media (any-hover: hover){:host(.button-solid.ion-color:hover) .button-native::after{background:var(--ion-color-contrast)}:host(.button-clear.ion-color:hover) .button-native::after,:host(.button-outline.ion-color:hover) .button-native::after{background:var(--ion-color-base)}}:host(.button-outline.ion-activated.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native{background:var(--ion-toolbar-background, var(--color));color:var(--ion-toolbar-color, var(--background), var(--ion-color-primary-contrast, #fff))}`;
@@ -12287,7 +12415,6 @@ class Button {
12287
12415
  this.inToolbar = false;
12288
12416
  this.formButtonEl = null;
12289
12417
  this.formEl = null;
12290
- this.inheritedAttributes = {};
12291
12418
  /**
12292
12419
  * If `true`, the button only has an icon.
12293
12420
  */
@@ -12346,22 +12473,6 @@ class Button {
12346
12473
  this.formButtonEl.disabled = disabled;
12347
12474
  }
12348
12475
  }
12349
- /**
12350
- * This component is used within the `ion-input-password-toggle` component
12351
- * to toggle the visibility of the password input.
12352
- * These attributes need to update based on the state of the password input.
12353
- * Otherwise, the values will be stale.
12354
- *
12355
- * @param newValue
12356
- * @param _oldValue
12357
- * @param propName
12358
- */
12359
- onAriaChanged(newValue, _oldValue, propName) {
12360
- this.inheritedAttributes = {
12361
- ...this.inheritedAttributes,
12362
- [propName]: newValue,
12363
- };
12364
- }
12365
12476
  /**
12366
12477
  * This is responsible for rendering a hidden native
12367
12478
  * button element inside the associated form. This allows
@@ -12399,7 +12510,21 @@ class Button {
12399
12510
  this.inToolbar = !!this.el.closest('ion-buttons');
12400
12511
  this.inListHeader = !!this.el.closest('ion-list-header');
12401
12512
  this.inItem = !!this.el.closest('ion-item') || !!this.el.closest('ion-item-divider');
12402
- this.inheritedAttributes = inheritAriaAttributes(this.el);
12513
+ /**
12514
+ * The ARIA state has to stay live, since `ion-input-password-toggle` rewrites
12515
+ * `aria-label` and `aria-pressed` on its `ion-button` on every toggle. We keep
12516
+ * `aria-disabled` out of the watch because the `<Host>` below renders it from the
12517
+ * `disabled` prop and those writes would clobber a developer's value, and `role` out
12518
+ * because a post-load write stays on the host too, which would put the same role on
12519
+ * two elements in the accessibility tree.
12520
+ */
12521
+ this.ariaController = createAriaAttributeController(this.el, () => forceUpdate(), ['aria-disabled', 'role']);
12522
+ }
12523
+ connectedCallback() {
12524
+ this.ariaController?.init();
12525
+ }
12526
+ disconnectedCallback() {
12527
+ this.ariaController?.destroy();
12403
12528
  }
12404
12529
  get hasIconOnly() {
12405
12530
  return !!this.el.querySelector('[slot="icon-only"]');
@@ -12474,7 +12599,8 @@ class Button {
12474
12599
  }
12475
12600
  render() {
12476
12601
  const mode = getIonMode$1(this);
12477
- const { buttonType, type, disabled, rel, target, size, href, color, expand, hasIconOnly, shape, strong, inheritedAttributes, } = this;
12602
+ const { buttonType, type, disabled, rel, target, size, href, color, expand, hasIconOnly, shape, strong } = this;
12603
+ const inheritedAttributes = this.ariaController?.attributes ?? {};
12478
12604
  const finalSize = size === undefined && this.inItem ? 'small' : size;
12479
12605
  const TagType = href === undefined ? 'button' : 'a';
12480
12606
  const attrs = TagType === 'button'
@@ -12499,7 +12625,7 @@ class Button {
12499
12625
  {
12500
12626
  type !== 'button' && this.renderHiddenButton();
12501
12627
  }
12502
- return (hAsync(Host, { key: '82c71b8cbf3bb51e443f4aa99c375bf5be6b8dc7', onClick: this.handleClick, "aria-disabled": disabled ? 'true' : null, class: createColorClasses$1(color, {
12628
+ return (hAsync(Host, { key: 'fd42d1a5836c148cddd6c474c130ce4bb36286ea', onClick: this.handleClick, "aria-disabled": disabled ? 'true' : null, class: createColorClasses$1(color, {
12503
12629
  [mode]: true,
12504
12630
  [buttonType]: true,
12505
12631
  [`${buttonType}-${expand}`]: expand !== undefined,
@@ -12514,21 +12640,12 @@ class Button {
12514
12640
  'button-disabled': disabled,
12515
12641
  'ion-activatable': true,
12516
12642
  'ion-focusable': true,
12517
- }) }, hAsync(TagType, { key: '53f4cb366bac796ab38f609e858bc1a55fce7641', ...attrs, class: "button-native", part: "native", disabled: disabled, onFocus: this.onFocus, onBlur: this.onBlur, ...inheritedAttributes }, hAsync("span", { key: '40e127fc11c889e77b8bf02e8714f0dea83bfce7', class: "button-inner" }, hAsync("slot", { key: 'e11c8c86d3f0894658a8999129425c9c111f5540', name: "icon-only", onSlotchange: this.slotChanged }), hAsync("slot", { key: '105ea9259ea17036359e6fe7eced8b267ab8e0f6', name: "start" }), hAsync("slot", { key: '0d7b0966e328a5b10b0562dacbd638dfd08d92af' }), hAsync("slot", { key: 'c542b40685802464d69f57ecc0a7c3465d24a417', name: "end" })), mode === 'md' && hAsync("ion-ripple-effect", { key: '46df4cbeb057b0a8daab92226121d8bbb8c0ee07', type: this.rippleType }))));
12643
+ }) }, hAsync(TagType, { key: '97dbf689ea912aed38182dbe0097a2bf5b768816', ...attrs, class: "button-native", part: "native", disabled: disabled, onFocus: this.onFocus, onBlur: this.onBlur, ...inheritedAttributes }, hAsync("span", { key: '0f1ff4c667e95a8e3dc787fee43fe529b95477b7', class: "button-inner" }, hAsync("slot", { key: 'fc1e8b8080d02828c392e9edd6a70e0255435f82', name: "icon-only", onSlotchange: this.slotChanged }), hAsync("slot", { key: 'c1ece4c0d935f4d023d38fee4cf529dd4123d487', name: "start" }), hAsync("slot", { key: '970db0ee1e3633bc9cbff52eca446e4891ff6851' }), hAsync("slot", { key: 'ef8d7d894f01dbe881f381b985620c2a482e55fe', name: "end" })), mode === 'md' && hAsync("ion-ripple-effect", { key: 'fea5e49a54b0efd07b1bd35d9fd5d2d862a2bac1', type: this.rippleType }))));
12518
12644
  }
12519
12645
  get el() { return getElement(this); }
12520
12646
  static get watchers() { return {
12521
12647
  "disabled": [{
12522
12648
  "disabledChanged": 0
12523
- }],
12524
- "aria-checked": [{
12525
- "onAriaChanged": 0
12526
- }],
12527
- "aria-label": [{
12528
- "onAriaChanged": 0
12529
- }],
12530
- "aria-pressed": [{
12531
- "onAriaChanged": 0
12532
12649
  }]
12533
12650
  }; }
12534
12651
  static get style() { return {
@@ -12619,7 +12736,6 @@ const cardMdCss = () => `:host{--ion-safe-area-left:0px;--ion-safe-area-right:0p
12619
12736
  class Card {
12620
12737
  constructor(hostRef) {
12621
12738
  registerInstance(this, hostRef);
12622
- this.inheritedAriaAttributes = {};
12623
12739
  /**
12624
12740
  * If `true`, a button tag will be rendered and the card will be tappable.
12625
12741
  */
@@ -12639,7 +12755,18 @@ class Card {
12639
12755
  this.routerDirection = 'forward';
12640
12756
  }
12641
12757
  componentWillLoad() {
12642
- this.inheritedAriaAttributes = inheritAttributes$1(this.el, ['aria-label']);
12758
+ /**
12759
+ * Only the initial copy takes the attribute off the host, so an `aria-label` written
12760
+ * after load stays on the host too. That's harmless here, because unlike `ion-item`
12761
+ * the card host renders no role of its own, so nothing reads the leftover copy.
12762
+ */
12763
+ this.ariaController = createAttributeController(this.el, ['aria-label'], () => forceUpdate());
12764
+ }
12765
+ connectedCallback() {
12766
+ this.ariaController?.init();
12767
+ }
12768
+ disconnectedCallback() {
12769
+ this.ariaController?.destroy();
12643
12770
  }
12644
12771
  isClickable() {
12645
12772
  return this.href !== undefined || this.button;
@@ -12649,7 +12776,8 @@ class Card {
12649
12776
  if (!clickable) {
12650
12777
  return [hAsync("slot", null)];
12651
12778
  }
12652
- const { href, routerAnimation, routerDirection, inheritedAriaAttributes } = this;
12779
+ const { href, routerAnimation, routerDirection } = this;
12780
+ const inheritedAriaAttributes = this.ariaController?.attributes ?? {};
12653
12781
  const TagType = clickable ? (href === undefined ? 'button' : 'a') : 'div';
12654
12782
  const attrs = TagType === 'button'
12655
12783
  ? { type: this.type }
@@ -12663,7 +12791,7 @@ class Card {
12663
12791
  }
12664
12792
  render() {
12665
12793
  const mode = getIonMode$1(this);
12666
- return (hAsync(Host, { key: '85e9b30bd81e79a0c7ac75cb3664bdcf9e4afc4d', class: createColorClasses$1(this.color, {
12794
+ return (hAsync(Host, { key: '104412c26f53cce36432c3bb4d9e38bbe00c5816', class: createColorClasses$1(this.color, {
12667
12795
  [mode]: true,
12668
12796
  'card-disabled': this.disabled,
12669
12797
  'ion-activatable': this.isClickable(),
@@ -21872,7 +22000,6 @@ class Item {
21872
22000
  registerInstance(this, hostRef);
21873
22001
  this.labelColorStyles = {};
21874
22002
  this.itemStyles = new Map();
21875
- this.inheritedAriaAttributes = {};
21876
22003
  this.didLoad = false;
21877
22004
  this.multipleInputs = false;
21878
22005
  this.focusable = true;
@@ -21952,9 +22079,16 @@ class Item {
21952
22079
  this.watchForIndicatorControls();
21953
22080
  this.updateInteractivityOnSlotChange();
21954
22081
  }
22082
+ this.ariaController?.init();
21955
22083
  }
21956
22084
  componentWillLoad() {
21957
- this.inheritedAriaAttributes = inheritAttributes$1(this.el, ['aria-label']);
22085
+ /**
22086
+ * Only the initial copy takes the attribute off the host, so an `aria-label` written
22087
+ * after load names both the native element and the Host, which is a `listitem` when
22088
+ * the item is in an `ion-list`. The two names always agree, so a screen reader just
22089
+ * reads it twice.
22090
+ */
22091
+ this.ariaController = createAttributeController(this.el, ['aria-label'], () => forceUpdate());
21958
22092
  }
21959
22093
  componentDidLoad() {
21960
22094
  raf(() => {
@@ -21971,6 +22105,7 @@ class Item {
21971
22105
  this.indicatorControlObserver.disconnect();
21972
22106
  this.indicatorControlObserver = undefined;
21973
22107
  }
22108
+ this.ariaController?.destroy();
21974
22109
  }
21975
22110
  totalNestedInputs() {
21976
22111
  // The following elements have a clickable cover that is relative to the entire item
@@ -22067,7 +22202,8 @@ class Item {
22067
22202
  return controls[0];
22068
22203
  }
22069
22204
  render() {
22070
- const { detail, detailIcon, download, labelColorStyles, lines, disabled, href, rel, target, routerAnimation, routerDirection, inheritedAriaAttributes, multipleInputs, } = this;
22205
+ const { detail, detailIcon, download, labelColorStyles, lines, disabled, href, rel, target, routerAnimation, routerDirection, multipleInputs, } = this;
22206
+ const inheritedAriaAttributes = this.ariaController?.attributes ?? {};
22071
22207
  const childStyles = {};
22072
22208
  const mode = getIonMode$1(this);
22073
22209
  const clickable = this.isClickable();
@@ -22143,7 +22279,7 @@ class Item {
22143
22279
  * multi-input item, and in a clickable item, which is a second tab stop.
22144
22280
  */
22145
22281
  const slottedIndicatorNeedsRoom = this.hasSlottedIndicatorControl && (multipleInputs || this.isClickable());
22146
- return (hAsync(Host, { key: '0dc161ad7ac2fdedc5005015fceb34ed176010a6', "aria-disabled": ariaDisabled, class: {
22282
+ return (hAsync(Host, { key: '7fe924642310c19f057ae1bfa29c1acdf5cc7ed6', "aria-disabled": ariaDisabled, class: {
22147
22283
  ...childStyles,
22148
22284
  ...labelColorStyles,
22149
22285
  ...createColorClasses$1(this.color, {
@@ -22160,7 +22296,7 @@ class Item {
22160
22296
  'ion-focusable': this.focusable,
22161
22297
  'item-rtl': document.dir === 'rtl',
22162
22298
  }),
22163
- }, role: inList ? 'listitem' : null }, hAsync(TagType, { key: 'd42583cf62133b2553de2e7a5357168640bb1834', ...attrs, ...inheritedAriaAttributes, class: "item-native", part: "native", disabled: disabled, ...clickFn }, hAsync("slot", { key: 'bd805ce49946cd52280d1c4b370104ee2472f1e2', name: "start", onSlotchange: this.updateInteractivityOnSlotChange }), hAsync("div", { key: '0de589f9c5c13c31b6c8838566a7ad6f78f81028', class: "item-inner", part: "inner" }, hAsync("div", { key: 'faaf6a39e072fb352753c645736ab1f47c2d7d25', class: "input-wrapper", part: "container" }, hAsync("slot", { key: '70a34c31de29a0786a14b4a7d3156ba8d4d92eb4', onSlotchange: this.updateInteractivityOnSlotChange })), hAsync("slot", { key: 'c8e764b62c5c30f67750896741ca266b741d5999', name: "end", onSlotchange: this.updateInteractivityOnSlotChange }), showDetail && (hAsync("ion-icon", { key: 'af006856d8c4ed69174534261344215957cc751a', icon: detailIcon, lazy: false, class: "item-detail-icon", part: "detail-icon", "aria-hidden": "true", "flip-rtl": detailIcon === chevronForward }))), canActivate && mode === 'md' && hAsync("ion-ripple-effect", { key: 'e5e151bafedd38feb8f71a387a0059aa1e9e90de' }))));
22299
+ }, role: inList ? 'listitem' : null }, hAsync(TagType, { key: '8fddfb2a076b4b98e45ee8b23579d011dba12acb', ...attrs, ...inheritedAriaAttributes, class: "item-native", part: "native", disabled: disabled, ...clickFn }, hAsync("slot", { key: '7f888b62b2023cf501fd308e32629e7a291c2d05', name: "start", onSlotchange: this.updateInteractivityOnSlotChange }), hAsync("div", { key: '6d5cdde307caa65b131edb65cb0a5f8294cf151c', class: "item-inner", part: "inner" }, hAsync("div", { key: '9fbfffdff4cf51adf1f02d573953cf8b145574b0', class: "input-wrapper", part: "container" }, hAsync("slot", { key: '574c7e61cdaa3959a28bad7353105ef217a76ed9', onSlotchange: this.updateInteractivityOnSlotChange })), hAsync("slot", { key: 'ed7e211960cd65ed17f865a6d50d5bdde069416b', name: "end", onSlotchange: this.updateInteractivityOnSlotChange }), showDetail && (hAsync("ion-icon", { key: '2847bb21f42e9d5ab8ea86262b2bc1c3b3f7c902', icon: detailIcon, lazy: false, class: "item-detail-icon", part: "detail-icon", "aria-hidden": "true", "flip-rtl": detailIcon === chevronForward }))), canActivate && mode === 'md' && hAsync("ion-ripple-effect", { key: '55502ef394db0953144387fa3baebf9fa6a976a9' }))));
22164
22300
  }
22165
22301
  get el() { return getElement(this); }
22166
22302
  static get watchers() { return {
@@ -30522,30 +30658,81 @@ const getSafeAreaInsets = (doc) => {
30522
30658
  }
30523
30659
  return insets;
30524
30660
  };
30661
+ /**
30662
+ * Largest difference from 1 that the `offsetWidth` based zoom detection below
30663
+ * attributes to integer rounding rather than to an actual CSS `zoom`. The
30664
+ * rounding error is at most half a pixel over the width of the popover, which
30665
+ * is well under this threshold for any realistic popover size.
30666
+ */
30667
+ const ZOOM_ROUNDING_TOLERANCE = 0.01;
30668
+ /**
30669
+ * Returns the cumulative CSS `zoom` factor applied to an element.
30670
+ *
30671
+ * When a CSS `zoom` other than 1 is set on an ancestor (e.g. the `html`
30672
+ * element, as recommended by the docs for dynamic font scaling on Chrome for
30673
+ * Android), `getBoundingClientRect()`, `clientX`/`clientY` and other geometry
30674
+ * APIs report values in the *zoomed* (visual) coordinate space, while inline
30675
+ * `top`/`left`/`--width` styles we set are interpreted in the *unzoomed*
30676
+ * (layout) space and re-scaled by the browser. Dividing the rect-derived
30677
+ * values by this factor converts them back to layout space so the popover is
30678
+ * positioned and sized correctly. Returns 1 when no zoom is applied.
30679
+ */
30680
+ const getElementCSSZoom = (el) => {
30681
+ if (!el) {
30682
+ return 1;
30683
+ }
30684
+ /**
30685
+ * `currentCSSZoom` exposes the exact effective zoom of an element
30686
+ * (Chromium 128+). When available we use it directly.
30687
+ */
30688
+ const currentCSSZoom = el.currentCSSZoom;
30689
+ if (typeof currentCSSZoom === 'number' && currentCSSZoom > 0) {
30690
+ return currentCSSZoom;
30691
+ }
30692
+ /**
30693
+ * Fallback for browsers without `currentCSSZoom`: compare the rendered
30694
+ * (zoomed) width from `getBoundingClientRect()` against the layout width
30695
+ * from `offsetWidth`, which is not affected by CSS `zoom`.
30696
+ */
30697
+ const { width } = el.getBoundingClientRect();
30698
+ const { offsetWidth } = el;
30699
+ if (offsetWidth > 0 && width > 0) {
30700
+ const ratio = width / offsetWidth;
30701
+ /**
30702
+ * `offsetWidth` is rounded to an integer while the bounding rect is not,
30703
+ * so the ratio is rarely exactly 1 even when no zoom is applied. Treat
30704
+ * sub-pixel differences as "no zoom" so that unzoomed popovers are not
30705
+ * shifted by the rounding error. A real zoom deviates far more, though
30706
+ * the same rounding leaves the detected factor approximate.
30707
+ */
30708
+ return Math.abs(ratio - 1) < ZOOM_ROUNDING_TOLERANCE ? 1 : ratio;
30709
+ }
30710
+ return 1;
30711
+ };
30525
30712
  /**
30526
30713
  * Returns the dimensions of the popover
30527
30714
  * arrow on `ios` mode. If arrow is disabled
30528
30715
  * returns (0, 0).
30529
30716
  */
30530
- const getArrowDimensions = (arrowEl) => {
30717
+ const getArrowDimensions = (arrowEl, zoom = 1) => {
30531
30718
  if (!arrowEl) {
30532
30719
  return { arrowWidth: 0, arrowHeight: 0 };
30533
30720
  }
30534
30721
  const { width, height } = arrowEl.getBoundingClientRect();
30535
- return { arrowWidth: width, arrowHeight: height };
30722
+ return { arrowWidth: width / zoom, arrowHeight: height / zoom };
30536
30723
  };
30537
30724
  /**
30538
30725
  * Returns the recommended dimensions of the popover
30539
30726
  * that takes into account whether or not the width
30540
30727
  * should match the trigger width.
30541
30728
  */
30542
- const getPopoverDimensions = (size, contentEl, triggerEl) => {
30729
+ const getPopoverDimensions = (size, contentEl, triggerEl, zoom = 1) => {
30543
30730
  const contentDimentions = contentEl.getBoundingClientRect();
30544
- const contentHeight = contentDimentions.height;
30545
- let contentWidth = contentDimentions.width;
30731
+ const contentHeight = contentDimentions.height / zoom;
30732
+ let contentWidth = contentDimentions.width / zoom;
30546
30733
  if (size === 'cover' && triggerEl) {
30547
30734
  const triggerDimensions = triggerEl.getBoundingClientRect();
30548
- contentWidth = triggerDimensions.width;
30735
+ contentWidth = triggerDimensions.width / zoom;
30549
30736
  }
30550
30737
  return {
30551
30738
  contentWidth,
@@ -30885,7 +31072,7 @@ const configureKeyboardInteraction = (popoverEl) => {
30885
31072
  * the reference point, preferred side, alignment
30886
31073
  * and viewport dimensions.
30887
31074
  */
30888
- const getPopoverPosition = (isRTL, contentWidth, contentHeight, arrowWidth, arrowHeight, reference, side, align, defaultPosition, triggerEl, event) => {
31075
+ const getPopoverPosition = (isRTL, contentWidth, contentHeight, arrowWidth, arrowHeight, reference, side, align, defaultPosition, triggerEl, event, zoom = 1) => {
30889
31076
  let referenceCoordinates = {
30890
31077
  top: 0,
30891
31078
  left: 0,
@@ -30904,8 +31091,8 @@ const getPopoverPosition = (isRTL, contentWidth, contentHeight, arrowWidth, arro
30904
31091
  }
30905
31092
  const mouseEv = event;
30906
31093
  referenceCoordinates = {
30907
- top: mouseEv.clientY,
30908
- left: mouseEv.clientX,
31094
+ top: mouseEv.clientY / zoom,
31095
+ left: mouseEv.clientX / zoom,
30909
31096
  width: 1,
30910
31097
  height: 1,
30911
31098
  };
@@ -30937,10 +31124,10 @@ const getPopoverPosition = (isRTL, contentWidth, contentHeight, arrowWidth, arro
30937
31124
  }
30938
31125
  const triggerBoundingBox = actualTriggerEl.getBoundingClientRect();
30939
31126
  referenceCoordinates = {
30940
- top: triggerBoundingBox.top,
30941
- left: triggerBoundingBox.left,
30942
- width: triggerBoundingBox.width,
30943
- height: triggerBoundingBox.height,
31127
+ top: triggerBoundingBox.top / zoom,
31128
+ left: triggerBoundingBox.left / zoom,
31129
+ width: triggerBoundingBox.width / zoom,
31130
+ height: triggerBoundingBox.height / zoom,
30944
31131
  };
30945
31132
  break;
30946
31133
  }
@@ -31303,21 +31490,35 @@ const iosEnterAnimation$1 = (baseEl, opts) => {
31303
31490
  const { event: ev, size, trigger, reference, side, align } = opts;
31304
31491
  const doc = baseEl.ownerDocument;
31305
31492
  const isRTL = doc.dir === 'rtl';
31306
- const bodyWidth = doc.defaultView.innerWidth;
31307
- const bodyHeight = doc.defaultView.innerHeight;
31308
31493
  const root = getElementRoot(baseEl);
31309
31494
  const contentEl = root.querySelector('.popover-content');
31310
31495
  const arrowEl = root.querySelector('.popover-arrow');
31496
+ /**
31497
+ * A CSS `zoom` other than 1 on an ancestor (e.g. the `html` element) causes
31498
+ * geometry APIs like `getBoundingClientRect()` to report zoomed values while
31499
+ * inline `top`/`left`/`--width` styles are interpreted in the unzoomed layout
31500
+ * space. Normalize all rect-derived measurements by this factor so the
31501
+ * popover is positioned and sized correctly.
31502
+ */
31503
+ const zoom = getElementCSSZoom(contentEl);
31504
+ /**
31505
+ * `innerWidth`/`innerHeight` are not affected by CSS `zoom`, so they must be
31506
+ * scaled down to the same layout space as the normalized measurements above.
31507
+ * Otherwise the popover would be clamped against a viewport that is larger
31508
+ * than the space actually available to it.
31509
+ */
31510
+ const bodyWidth = doc.defaultView.innerWidth / zoom;
31511
+ const bodyHeight = doc.defaultView.innerHeight / zoom;
31311
31512
  const referenceSizeEl = trigger || ev?.detail?.ionShadowTarget || ev?.target;
31312
- const { contentWidth, contentHeight } = getPopoverDimensions(size, contentEl, referenceSizeEl);
31313
- const { arrowWidth, arrowHeight } = getArrowDimensions(arrowEl);
31513
+ const { contentWidth, contentHeight } = getPopoverDimensions(size, contentEl, referenceSizeEl, zoom);
31514
+ const { arrowWidth, arrowHeight } = getArrowDimensions(arrowEl, zoom);
31314
31515
  const defaultPosition = {
31315
31516
  top: bodyHeight / 2 - contentHeight / 2,
31316
31517
  left: bodyWidth / 2 - contentWidth / 2,
31317
31518
  originX: isRTL ? 'right' : 'left',
31318
31519
  originY: 'top',
31319
31520
  };
31320
- const results = getPopoverPosition(isRTL, contentWidth, contentHeight, arrowWidth, arrowHeight, reference, side, align, defaultPosition, trigger, ev);
31521
+ const results = getPopoverPosition(isRTL, contentWidth, contentHeight, arrowWidth, arrowHeight, reference, side, align, defaultPosition, trigger, ev, zoom);
31321
31522
  const padding = size === 'cover' ? 0 : POPOVER_IOS_BODY_PADDING;
31322
31523
  const rawSafeArea = getSafeAreaInsets(doc);
31323
31524
  const safeArea = size === 'cover'
@@ -31439,19 +31640,33 @@ const mdEnterAnimation$1 = (baseEl, opts) => {
31439
31640
  const { event: ev, size, trigger, reference, side, align } = opts;
31440
31641
  const doc = baseEl.ownerDocument;
31441
31642
  const isRTL = doc.dir === 'rtl';
31442
- const bodyWidth = doc.defaultView.innerWidth;
31443
- const bodyHeight = doc.defaultView.innerHeight;
31444
31643
  const root = getElementRoot(baseEl);
31445
31644
  const contentEl = root.querySelector('.popover-content');
31645
+ /**
31646
+ * A CSS `zoom` other than 1 on an ancestor (e.g. the `html` element) causes
31647
+ * geometry APIs like `getBoundingClientRect()` to report zoomed values while
31648
+ * inline `top`/`left`/`--width` styles are interpreted in the unzoomed layout
31649
+ * space. Normalize all rect-derived measurements by this factor so the
31650
+ * popover is positioned and sized correctly.
31651
+ */
31652
+ const zoom = getElementCSSZoom(contentEl);
31653
+ /**
31654
+ * `innerWidth`/`innerHeight` are not affected by CSS `zoom`, so they must be
31655
+ * scaled down to the same layout space as the normalized measurements above.
31656
+ * Otherwise the popover would be clamped against a viewport that is larger
31657
+ * than the space actually available to it.
31658
+ */
31659
+ const bodyWidth = doc.defaultView.innerWidth / zoom;
31660
+ const bodyHeight = doc.defaultView.innerHeight / zoom;
31446
31661
  const referenceSizeEl = trigger || ev?.detail?.ionShadowTarget || ev?.target;
31447
- const { contentWidth, contentHeight } = getPopoverDimensions(size, contentEl, referenceSizeEl);
31662
+ const { contentWidth, contentHeight } = getPopoverDimensions(size, contentEl, referenceSizeEl, zoom);
31448
31663
  const defaultPosition = {
31449
31664
  top: bodyHeight / 2 - contentHeight / 2,
31450
31665
  left: bodyWidth / 2 - contentWidth / 2,
31451
31666
  originX: isRTL ? 'right' : 'left',
31452
31667
  originY: 'top',
31453
31668
  };
31454
- const results = getPopoverPosition(isRTL, contentWidth, contentHeight, 0, 0, reference, side, align, defaultPosition, trigger, ev);
31669
+ const results = getPopoverPosition(isRTL, contentWidth, contentHeight, 0, 0, reference, side, align, defaultPosition, trigger, ev, zoom);
31455
31670
  const padding = size === 'cover' ? 0 : POPOVER_MD_BODY_PADDING;
31456
31671
  // MD mode now applies safe-area insets (previously passed 0, ignoring all safe areas).
31457
31672
  // This is needed for Android edge-to-edge (API 36+) where system bars overlap content.