@ionic/core 8.7.18-dev.11770916502.174efd7f → 8.7.18-dev.11771365900.125bf49c

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 (338) hide show
  1. package/components/index.js +13 -14
  2. package/components/ion-accordion-group.js +3 -4
  3. package/components/ion-accordion.js +6 -7
  4. package/components/ion-action-sheet.js +1 -1
  5. package/components/ion-alert.js +1 -1
  6. package/components/ion-app.js +11 -12
  7. package/components/ion-avatar.js +3 -3
  8. package/components/ion-back-button.js +8 -9
  9. package/components/ion-backdrop.js +1 -1
  10. package/components/ion-badge.js +4 -4
  11. package/components/ion-breadcrumb.js +7 -7
  12. package/components/ion-breadcrumbs.js +4 -4
  13. package/components/ion-button.js +1 -1
  14. package/components/ion-buttons.js +1 -1
  15. package/components/ion-card-content.js +3 -3
  16. package/components/ion-card-header.js +4 -4
  17. package/components/ion-card-subtitle.js +4 -4
  18. package/components/ion-card-title.js +4 -4
  19. package/components/ion-card.js +6 -6
  20. package/components/ion-checkbox.js +1 -1
  21. package/components/ion-chip.js +5 -5
  22. package/components/ion-col.js +3 -3
  23. package/components/ion-content.js +1 -1
  24. package/components/ion-datetime-button.js +7 -8
  25. package/components/ion-datetime.js +19 -20
  26. package/components/ion-fab-button.js +8 -8
  27. package/components/ion-fab-list.js +3 -3
  28. package/components/ion-fab.js +3 -3
  29. package/components/ion-footer.js +6 -6
  30. package/components/ion-grid.js +3 -3
  31. package/components/ion-header.js +1 -1
  32. package/components/ion-icon.js +1 -1
  33. package/components/ion-img.js +4 -4
  34. package/components/ion-infinite-scroll-content.js +5 -6
  35. package/components/ion-infinite-scroll.js +4 -4
  36. package/components/ion-input-otp.js +6 -7
  37. package/components/ion-input-password-toggle.js +8 -9
  38. package/components/ion-input.js +13 -13
  39. package/components/ion-item-divider.js +6 -6
  40. package/components/ion-item-group.js +4 -4
  41. package/components/ion-item-option.js +7 -7
  42. package/components/ion-item-options.js +5 -5
  43. package/components/ion-item-sliding.js +8 -9
  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 +13 -14
  49. package/components/ion-menu-button.js +12 -13
  50. package/components/ion-menu-toggle.js +7 -7
  51. package/components/ion-menu.js +14 -18
  52. package/components/ion-modal.js +1 -1
  53. package/components/ion-nav-link.js +3 -3
  54. package/components/ion-nav.js +9 -14
  55. package/components/ion-note.js +6 -6
  56. package/components/ion-picker-column-option.js +1 -1
  57. package/components/ion-picker-column.js +1 -1
  58. package/components/ion-picker-legacy-column.js +1 -1
  59. package/components/ion-picker-legacy.js +12 -13
  60. package/components/ion-picker.js +1 -1
  61. package/components/ion-popover.js +1 -1
  62. package/components/ion-progress-bar.js +6 -7
  63. package/components/ion-radio-group.js +1 -1
  64. package/components/ion-radio.js +1 -1
  65. package/components/ion-range.js +11 -12
  66. package/components/ion-refresher-content.js +9 -10
  67. package/components/ion-refresher.js +12 -13
  68. package/components/ion-reorder-group.js +8 -8
  69. package/components/ion-reorder.js +6 -6
  70. package/components/ion-ripple-effect.js +1 -1
  71. package/components/ion-route-redirect.js +2 -2
  72. package/components/ion-route.js +2 -2
  73. package/components/ion-router-link.js +6 -6
  74. package/components/ion-router-outlet.js +10 -11
  75. package/components/ion-router.js +3 -4
  76. package/components/ion-row.js +4 -4
  77. package/components/ion-searchbar.js +12 -13
  78. package/components/ion-segment-button.js +8 -9
  79. package/components/ion-segment-content.js +3 -3
  80. package/components/ion-segment-view.js +5 -5
  81. package/components/ion-segment.js +9 -9
  82. package/components/ion-select-modal.js +1 -1
  83. package/components/ion-select-option.js +4 -4
  84. package/components/ion-select-popover.js +1 -1
  85. package/components/ion-select.js +36 -37
  86. package/components/ion-skeleton-text.js +6 -7
  87. package/components/ion-spinner.js +1 -1
  88. package/components/ion-split-pane.js +5 -12
  89. package/components/ion-tab-bar.js +7 -7
  90. package/components/ion-tab-button.js +7 -8
  91. package/components/ion-tab.js +5 -14
  92. package/components/ion-tabs.js +3 -4
  93. package/components/ion-text.js +6 -6
  94. package/components/ion-textarea.js +13 -13
  95. package/components/ion-thumbnail.js +4 -4
  96. package/components/ion-title.js +1 -1
  97. package/components/ion-toast.js +17 -20
  98. package/components/ion-toggle.js +15 -16
  99. package/components/ion-toolbar.js +1 -1
  100. package/components/{list.js → p-B25GjpND.js} +3 -3
  101. package/components/{buttons.js → p-BBFQmhcD.js} +3 -3
  102. package/components/{index5.js → p-BC-awmYt.js} +6 -6
  103. package/components/{picker.js → p-BHbOsu99.js} +3 -3
  104. package/components/{title.js → p-BTlwXR9e.js} +6 -6
  105. package/components/{alert.js → p-BcazQttQ.js} +12 -13
  106. package/components/{spinner.js → p-BdGshsIJ.js} +5 -6
  107. package/components/{input.utils.js → p-BfS7vSpC.js} +3 -3
  108. package/components/{ios.transition.js → p-BhRFCLuX.js} +2 -2
  109. package/components/{backdrop.js → p-Bhnhnzjz.js} +3 -3
  110. package/components/{notch-controller.js → p-BmcqD0EN.js} +2 -2
  111. package/components/{radio-group.js → p-BnpDIASH.js} +7 -7
  112. package/components/{hardware-back-button.js → p-Boi6hecl.js} +2 -2
  113. package/components/{radio.js → p-Bt_moUyl.js} +8 -8
  114. package/components/{ionic-global.js → p-Bxl5etF4.js} +1 -2
  115. package/components/{picker-column-option.js → p-ByjmWt3s.js} +7 -7
  116. package/components/{md.transition.js → p-C04oPyjT.js} +2 -2
  117. package/components/{capacitor.js → p-CIGNaXM1.js} +1 -1
  118. package/components/{config.js → p-CIJwkzL6.js} +1 -1
  119. package/components/{select-modal.js → p-CJrGvZ1Z.js} +19 -19
  120. package/components/{animation.js → p-CL12ApCQ.js} +2 -2
  121. package/components/{label.js → p-CUfY9DTD.js} +6 -6
  122. package/components/{action-sheet.js → p-CXJR56Oq.js} +12 -12
  123. package/components/{index3.js → p-Cl0B-RWe.js} +1 -1
  124. package/components/{keyboard-controller.js → p-CtWGkNnJ.js} +2 -2
  125. package/components/{index7.js → p-Cyd00tgZ.js} +2 -2
  126. package/components/{picker-column2.js → p-CzAJ3ArC.js} +9 -9
  127. package/components/{menu-toggle-util.js → p-CzW34QBh.js} +1 -1
  128. package/components/{refresher.utils.js → p-D0zXRwcr.js} +3 -3
  129. package/components/{keyboard2.js → p-D13Eaw-8.js} +1 -1
  130. package/components/{select-popover.js → p-D3KEyQ8e.js} +15 -15
  131. package/components/{helpers.js → p-D5hF6rwn.js} +1 -1
  132. package/components/{keyboard.js → p-D6Ynv7Xh.js} +1 -1
  133. package/components/{button-active.js → p-D8eD2iBA.js} +3 -3
  134. package/components/{button.js → p-DK2Bn1Mc.js} +6 -7
  135. package/components/{picker-column.js → p-DKRQWlK2.js} +7 -7
  136. package/components/{index8.js → p-DNDUsygf.js} +2 -2
  137. package/components/{content.js → p-DPm73mCi.js} +7 -7
  138. package/components/{popover.js → p-DRHwNkVo.js} +43 -166
  139. package/components/{index2.js → p-DTWZF6wg.js} +4 -5
  140. package/components/p-DWoUQeZ3.js +3012 -0
  141. package/components/{header.js → p-DX0w75a9.js} +6 -6
  142. package/components/{toolbar.js → p-Dt8zaCLQ.js} +6 -6
  143. package/components/{checkbox.js → p-DyFBFrV7.js} +7 -7
  144. package/components/{status-tap.js → p-DyHPCMyn.js} +3 -3
  145. package/components/{modal.js → p-IHgAGzvW.js} +35 -345
  146. package/components/{ripple-effect.js → p-LgLeKTkH.js} +4 -4
  147. package/components/{list-header.js → p-NhiRFRn9.js} +6 -6
  148. package/components/{input-shims.js → p-OuiHmXO5.js} +4 -4
  149. package/components/{icon.js → p-Wro9IPHE.js} +6 -6
  150. package/components/{item.js → p-aIWC4ZEV.js} +8 -8
  151. package/components/{overlays.js → p-c-XJ9XhZ.js} +7 -7
  152. package/components/{haptic.js → p-cyNmxje6.js} +1 -1
  153. package/components/{swipe-back.js → p-fVuFT3Wd.js} +3 -3
  154. package/components/{framework-delegate.js → p-l_lso3Zl.js} +1 -1
  155. package/components/{data.js → p-mQp4lwQD.js} +2 -2
  156. package/dist/cjs/ion-app_8.cjs.entry.js +5 -5
  157. package/dist/cjs/ion-avatar_3.cjs.entry.js +1 -1
  158. package/dist/cjs/ion-col_3.cjs.entry.js +1 -1
  159. package/dist/cjs/ion-datetime_3.cjs.entry.js +4 -4
  160. package/dist/cjs/ion-item-option_3.cjs.entry.js +4 -4
  161. package/dist/cjs/ion-item_8.cjs.entry.js +11 -11
  162. package/dist/cjs/ion-loading.cjs.entry.js +2 -2
  163. package/dist/cjs/ion-menu_3.cjs.entry.js +6 -6
  164. package/dist/cjs/ion-modal.cjs.entry.js +17 -326
  165. package/dist/cjs/ion-nav_2.cjs.entry.js +2 -2
  166. package/dist/cjs/ion-picker-column-option.cjs.entry.js +2 -2
  167. package/dist/cjs/ion-popover.cjs.entry.js +32 -154
  168. package/dist/cjs/ion-progress-bar.cjs.entry.js +1 -1
  169. package/dist/cjs/ion-radio_2.cjs.entry.js +4 -4
  170. package/dist/cjs/ion-range.cjs.entry.js +3 -3
  171. package/dist/cjs/ion-refresher_2.cjs.entry.js +2 -2
  172. package/dist/cjs/ion-reorder_2.cjs.entry.js +2 -2
  173. package/dist/cjs/ion-ripple-effect.cjs.entry.js +1 -1
  174. package/dist/cjs/ion-route_4.cjs.entry.js +2 -2
  175. package/dist/cjs/ion-searchbar.cjs.entry.js +4 -4
  176. package/dist/cjs/ion-segment-content.cjs.entry.js +1 -1
  177. package/dist/cjs/ion-segment-view.cjs.entry.js +2 -2
  178. package/dist/cjs/ion-segment_2.cjs.entry.js +4 -4
  179. package/dist/cjs/ion-select-modal.cjs.entry.js +1 -1
  180. package/dist/cjs/ion-select_3.cjs.entry.js +4 -4
  181. package/dist/cjs/ion-spinner.cjs.entry.js +1 -1
  182. package/dist/cjs/ion-split-pane.cjs.entry.js +2 -2
  183. package/dist/cjs/ion-tab-bar_2.cjs.entry.js +4 -4
  184. package/dist/cjs/ion-tab_2.cjs.entry.js +3 -3
  185. package/dist/cjs/ion-text.cjs.entry.js +2 -2
  186. package/dist/cjs/ion-textarea.cjs.entry.js +2 -2
  187. package/dist/cjs/ion-toast.cjs.entry.js +2 -2
  188. package/dist/cjs/ion-toggle.cjs.entry.js +3 -3
  189. package/dist/collection/components/item-divider/item-divider.js +2 -2
  190. package/dist/collection/components/item-group/item-group.js +1 -1
  191. package/dist/collection/components/item-option/item-option.js +2 -2
  192. package/dist/collection/components/item-options/item-options.js +1 -1
  193. package/dist/collection/components/item-sliding/item-sliding.js +1 -1
  194. package/dist/collection/components/label/label.js +2 -2
  195. package/dist/collection/components/list-header/list-header.js +2 -2
  196. package/dist/collection/components/loading/loading.js +2 -2
  197. package/dist/collection/components/menu/menu.js +2 -2
  198. package/dist/collection/components/menu-button/menu-button.js +2 -2
  199. package/dist/collection/components/menu-toggle/menu-toggle.js +2 -2
  200. package/dist/collection/components/modal/modal.ios.css +5 -6
  201. package/dist/collection/components/modal/modal.js +15 -164
  202. package/dist/collection/components/modal/modal.md.css +5 -6
  203. package/dist/collection/components/nav/nav.js +1 -1
  204. package/dist/collection/components/nav-link/nav-link.js +1 -1
  205. package/dist/collection/components/note/note.js +2 -2
  206. package/dist/collection/components/picker-column-option/picker-column-option.js +2 -2
  207. package/dist/collection/components/picker-legacy/picker.js +2 -2
  208. package/dist/collection/components/picker-legacy-column/picker-column.js +2 -2
  209. package/dist/collection/components/popover/animations/ios.enter.js +8 -33
  210. package/dist/collection/components/popover/animations/md.enter.js +6 -26
  211. package/dist/collection/components/popover/popover.js +2 -2
  212. package/dist/collection/components/popover/utils.js +19 -96
  213. package/dist/collection/components/progress-bar/progress-bar.js +1 -1
  214. package/dist/collection/components/radio/radio.js +3 -3
  215. package/dist/collection/components/radio-group/radio-group.js +1 -1
  216. package/dist/collection/components/range/range.js +3 -3
  217. package/dist/collection/components/refresher/refresher.js +1 -1
  218. package/dist/collection/components/refresher-content/refresher-content.js +1 -1
  219. package/dist/collection/components/reorder/reorder.js +1 -1
  220. package/dist/collection/components/reorder-group/reorder-group.js +1 -1
  221. package/dist/collection/components/ripple-effect/ripple-effect.js +1 -1
  222. package/dist/collection/components/router-link/router-link.js +2 -2
  223. package/dist/collection/components/router-outlet/router-outlet.js +1 -1
  224. package/dist/collection/components/row/row.js +1 -1
  225. package/dist/collection/components/searchbar/searchbar.js +4 -4
  226. package/dist/collection/components/segment/segment.js +2 -2
  227. package/dist/collection/components/segment-button/segment-button.js +2 -2
  228. package/dist/collection/components/segment-content/segment-content.js +1 -1
  229. package/dist/collection/components/segment-view/segment-view.js +2 -2
  230. package/dist/collection/components/select/select.js +2 -2
  231. package/dist/collection/components/select-modal/select-modal.js +1 -1
  232. package/dist/collection/components/select-option/select-option.js +1 -1
  233. package/dist/collection/components/select-popover/select-popover.js +1 -1
  234. package/dist/collection/components/skeleton-text/skeleton-text.js +2 -2
  235. package/dist/collection/components/spinner/spinner.js +1 -1
  236. package/dist/collection/components/split-pane/split-pane.js +2 -2
  237. package/dist/collection/components/tab/tab.js +2 -2
  238. package/dist/collection/components/tab-bar/tab-bar.js +2 -2
  239. package/dist/collection/components/tab-button/tab-button.js +2 -2
  240. package/dist/collection/components/tabs/tabs.js +1 -1
  241. package/dist/collection/components/text/text.js +2 -2
  242. package/dist/collection/components/textarea/textarea.js +2 -2
  243. package/dist/collection/components/thumbnail/thumbnail.js +1 -1
  244. package/dist/collection/components/title/title.js +2 -2
  245. package/dist/collection/components/toast/toast.js +2 -2
  246. package/dist/collection/components/toggle/toggle.js +3 -3
  247. package/dist/collection/components/toolbar/toolbar.js +2 -2
  248. package/dist/docs.json +1 -1
  249. package/dist/esm/ion-app_8.entry.js +5 -5
  250. package/dist/esm/ion-avatar_3.entry.js +1 -1
  251. package/dist/esm/ion-col_3.entry.js +1 -1
  252. package/dist/esm/ion-datetime_3.entry.js +4 -4
  253. package/dist/esm/ion-item-option_3.entry.js +4 -4
  254. package/dist/esm/ion-item_8.entry.js +11 -11
  255. package/dist/esm/ion-loading.entry.js +2 -2
  256. package/dist/esm/ion-menu_3.entry.js +6 -6
  257. package/dist/esm/ion-modal.entry.js +17 -326
  258. package/dist/esm/ion-nav_2.entry.js +2 -2
  259. package/dist/esm/ion-picker-column-option.entry.js +2 -2
  260. package/dist/esm/ion-popover.entry.js +32 -154
  261. package/dist/esm/ion-progress-bar.entry.js +1 -1
  262. package/dist/esm/ion-radio_2.entry.js +4 -4
  263. package/dist/esm/ion-range.entry.js +3 -3
  264. package/dist/esm/ion-refresher_2.entry.js +2 -2
  265. package/dist/esm/ion-reorder_2.entry.js +2 -2
  266. package/dist/esm/ion-ripple-effect.entry.js +1 -1
  267. package/dist/esm/ion-route_4.entry.js +2 -2
  268. package/dist/esm/ion-searchbar.entry.js +4 -4
  269. package/dist/esm/ion-segment-content.entry.js +1 -1
  270. package/dist/esm/ion-segment-view.entry.js +2 -2
  271. package/dist/esm/ion-segment_2.entry.js +4 -4
  272. package/dist/esm/ion-select-modal.entry.js +1 -1
  273. package/dist/esm/ion-select_3.entry.js +4 -4
  274. package/dist/esm/ion-spinner.entry.js +1 -1
  275. package/dist/esm/ion-split-pane.entry.js +2 -2
  276. package/dist/esm/ion-tab-bar_2.entry.js +4 -4
  277. package/dist/esm/ion-tab_2.entry.js +3 -3
  278. package/dist/esm/ion-text.entry.js +2 -2
  279. package/dist/esm/ion-textarea.entry.js +2 -2
  280. package/dist/esm/ion-toast.entry.js +2 -2
  281. package/dist/esm/ion-toggle.entry.js +3 -3
  282. package/dist/ionic/ionic.esm.js +1 -1
  283. package/dist/ionic/{p-074839fc.entry.js → p-01e27965.entry.js} +1 -1
  284. package/dist/ionic/p-0ca0fe9c.entry.js +4 -0
  285. package/dist/ionic/{p-316c0420.entry.js → p-221a3d8c.entry.js} +1 -1
  286. package/dist/ionic/{p-3a6caca9.entry.js → p-2668188b.entry.js} +1 -1
  287. package/dist/ionic/{p-d3014190.entry.js → p-2bd1ea35.entry.js} +1 -1
  288. package/dist/ionic/{p-a127bee2.entry.js → p-30333874.entry.js} +1 -1
  289. package/dist/ionic/{p-0e8c8a10.entry.js → p-31db96da.entry.js} +1 -1
  290. package/dist/ionic/{p-1647c46c.entry.js → p-363d1209.entry.js} +1 -1
  291. package/dist/ionic/p-3ec563c1.entry.js +4 -0
  292. package/dist/ionic/{p-c19af093.entry.js → p-42db6404.entry.js} +1 -1
  293. package/dist/ionic/{p-db82892c.entry.js → p-46a38cfd.entry.js} +1 -1
  294. package/dist/ionic/{p-eb024a5b.entry.js → p-4eec1a5e.entry.js} +1 -1
  295. package/dist/ionic/{p-0dfa5a37.entry.js → p-530fcd71.entry.js} +1 -1
  296. package/dist/ionic/{p-72c38b88.entry.js → p-5c8f7253.entry.js} +1 -1
  297. package/dist/ionic/{p-172a579f.entry.js → p-5d6fb6e3.entry.js} +1 -1
  298. package/dist/ionic/{p-dbbe606a.entry.js → p-652318c3.entry.js} +1 -1
  299. package/dist/ionic/{p-2a939845.entry.js → p-6f37536a.entry.js} +1 -1
  300. package/dist/ionic/{p-4e41ea20.entry.js → p-72af946b.entry.js} +1 -1
  301. package/dist/ionic/p-7f98e710.entry.js +4 -0
  302. package/dist/ionic/{p-6d070558.entry.js → p-82d5bb3d.entry.js} +1 -1
  303. package/dist/ionic/p-906bb44d.entry.js +4 -0
  304. package/dist/ionic/{p-2dbb90cb.entry.js → p-97eb0812.entry.js} +1 -1
  305. package/dist/ionic/{p-31f7095f.entry.js → p-a4a9f5ae.entry.js} +1 -1
  306. package/dist/ionic/{p-86f53961.entry.js → p-b8551510.entry.js} +1 -1
  307. package/dist/ionic/p-bc293244.entry.js +4 -0
  308. package/dist/ionic/{p-d126e8d3.entry.js → p-bce86e56.entry.js} +1 -1
  309. package/dist/ionic/{p-02d76786.entry.js → p-be263062.entry.js} +1 -1
  310. package/dist/ionic/{p-639dd543.entry.js → p-c175d792.entry.js} +1 -1
  311. package/dist/ionic/{p-020af078.entry.js → p-cc2a9936.entry.js} +1 -1
  312. package/dist/ionic/{p-1ccd6829.entry.js → p-e338f669.entry.js} +1 -1
  313. package/dist/ionic/{p-6241ce47.entry.js → p-eaf3f5ff.entry.js} +1 -1
  314. package/dist/ionic/{p-f8f22cc0.entry.js → p-fb0271ae.entry.js} +1 -1
  315. package/dist/ionic/{p-370e4237.entry.js → p-fbb00634.entry.js} +1 -1
  316. package/dist/types/components/modal/modal.d.ts +0 -35
  317. package/dist/types/components/popover/utils.d.ts +1 -23
  318. package/hydrate/index.js +137 -568
  319. package/hydrate/index.mjs +137 -568
  320. package/package.json +1 -1
  321. package/components/index4.js +0 -121
  322. package/dist/collection/components/modal/safe-area-utils.js +0 -165
  323. package/dist/ionic/p-3e69999d.entry.js +0 -4
  324. package/dist/ionic/p-51a60e0f.entry.js +0 -4
  325. package/dist/ionic/p-94de5cfa.entry.js +0 -4
  326. package/dist/ionic/p-cc3446d5.entry.js +0 -4
  327. package/dist/ionic/p-dd1aef77.entry.js +0 -4
  328. package/dist/types/components/modal/safe-area-utils.d.ts +0 -66
  329. /package/components/{lock-controller.js → p-B-hirT0v.js} +0 -0
  330. /package/components/{gesture-controller.js → p-BTEOs1at.js} +0 -0
  331. /package/components/{focus-visible.js → p-BmVRXR1y.js} +0 -0
  332. /package/components/{dir.js → p-C53feagD.js} +0 -0
  333. /package/components/{index6.js → p-CO7fmmxt.js} +0 -0
  334. /package/components/{validity.js → p-DJztqcrH.js} +0 -0
  335. /package/components/{theme.js → p-DiVJyqlX.js} +0 -0
  336. /package/components/{watch-options.js → p-Dtdm8lKC.js} +0 -0
  337. /package/components/{index9.js → p-ZjP4CjeZ.js} +0 -0
  338. /package/components/{cubic-bezier.js → p-hHmYLOfE.js} +0 -0
@@ -1472,170 +1472,9 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
1472
1472
  };
1473
1473
  };
1474
1474
 
1475
- /**
1476
- * These thresholds match the SCSS media query breakpoints in modal.vars.scss
1477
- * that trigger the centered dialog layout (non-fullscreen modal).
1478
- *
1479
- * SCSS defines two height breakpoints: $modal-inset-min-height-small (600px)
1480
- * and $modal-inset-min-height-large (768px). We use the smaller one because
1481
- * that's the threshold where the modal transitions from fullscreen to centered
1482
- * dialog — the larger breakpoint only increases the dialog's height.
1483
- */
1484
- const MODAL_INSET_MIN_WIDTH = 768;
1485
- const MODAL_INSET_MIN_HEIGHT = 600;
1486
- const EDGE_THRESHOLD = 5;
1487
- /**
1488
- * Cache for resolved root safe-area-top value, invalidated once per frame.
1489
- */
1490
- let cachedRootSafeAreaTop = null;
1491
- let cacheInvalidationScheduled = false;
1492
- /**
1493
- * Determines if the current viewport meets the CSS media query conditions
1494
- * that cause regular modals to render as centered dialogs instead of fullscreen.
1495
- * Matches: @media (min-width: 768px) and (min-height: 600px)
1496
- */
1497
- const isCenteredDialogViewport = () => {
1498
- if (!win)
1499
- return false;
1500
- return win.matchMedia(`(min-width: ${MODAL_INSET_MIN_WIDTH}px) and (min-height: ${MODAL_INSET_MIN_HEIGHT}px)`)
1501
- .matches;
1502
- };
1503
- /**
1504
- * Resolves the current root --ion-safe-area-top value to pixels.
1505
- * Uses a temporary element because getComputedStyle on :root returns
1506
- * the declared value of custom properties (e.g. "env(safe-area-inset-top)")
1507
- * rather than a resolved number.
1508
- *
1509
- * Results are cached for the current frame to avoid repeated reflows.
1510
- */
1511
- const getRootSafeAreaTop = () => {
1512
- if (cachedRootSafeAreaTop !== null) {
1513
- return cachedRootSafeAreaTop;
1514
- }
1515
- const doc = win === null || win === void 0 ? void 0 : win.document;
1516
- if (!(doc === null || doc === void 0 ? void 0 : doc.body)) {
1517
- return 0;
1518
- }
1519
- const el = doc.createElement('div');
1520
- el.style.cssText =
1521
- 'position:fixed;visibility:hidden;pointer-events:none;top:0;left:0;' + 'padding-top:var(--ion-safe-area-top,0px);';
1522
- doc.body.appendChild(el);
1523
- const value = parseFloat(getComputedStyle(el).paddingTop) || 0;
1524
- el.remove();
1525
- cachedRootSafeAreaTop = value;
1526
- if (!cacheInvalidationScheduled) {
1527
- cacheInvalidationScheduled = true;
1528
- raf(() => {
1529
- cachedRootSafeAreaTop = null;
1530
- cacheInvalidationScheduled = false;
1531
- });
1532
- }
1533
- return value;
1534
- };
1535
- /**
1536
- * Returns the initial safe-area configuration based on modal type.
1537
- * This is called before animation starts and uses configuration-based prediction.
1538
- *
1539
- * @param context - Modal context information
1540
- * @returns SafeAreaConfig with initial safe-area values
1541
- */
1542
- const getInitialSafeAreaConfig = (context) => {
1543
- const { isSheetModal, isCardModal } = context;
1544
- // Sheet modals always zero top safe-area. The sheet height offset from the
1545
- // top edge is handled by --ion-modal-offset-top (set in modal.tsx) using
1546
- // the resolved root value, so --ion-safe-area-top is never needed for
1547
- // height calculation. Keeping it at 0px prevents header content from
1548
- // getting double-offset padding.
1549
- if (isSheetModal) {
1550
- return {
1551
- top: '0px',
1552
- bottom: 'inherit',
1553
- left: '0px',
1554
- right: '0px',
1555
- };
1556
- }
1557
- // Card modals need safe-area for height calculation.
1558
- // Note: isCardModal is already gated on mode === 'ios' by the caller.
1559
- if (isCardModal) {
1560
- return {
1561
- top: 'inherit',
1562
- bottom: 'inherit',
1563
- left: '0px',
1564
- right: '0px',
1565
- };
1566
- }
1567
- // On viewports that meet the centered dialog media query breakpoints,
1568
- // regular modals render as centered dialogs (not fullscreen), so they
1569
- // don't touch any screen edges and don't need safe-area insets.
1570
- if (isCenteredDialogViewport()) {
1571
- return {
1572
- top: '0px',
1573
- bottom: '0px',
1574
- left: '0px',
1575
- right: '0px',
1576
- };
1577
- }
1578
- // Fullscreen modals on phone - inherit all safe areas
1579
- return {
1580
- top: 'inherit',
1581
- bottom: 'inherit',
1582
- left: 'inherit',
1583
- right: 'inherit',
1584
- };
1585
- };
1586
- /**
1587
- * Returns safe-area configuration based on actual modal position.
1588
- * Detects which edges the modal overlaps with and only applies safe-area to those edges.
1589
- *
1590
- * Note: On Android edge-to-edge (API 36+), getBoundingClientRect() may report
1591
- * inconsistent values. Sheet and card modals avoid this by using configuration-based
1592
- * prediction instead. Regular modals use coordinate detection which works reliably
1593
- * on web and iOS; Android edge-to-edge may need a configuration-based fallback
1594
- * once a reliable detection mechanism is available.
1595
- *
1596
- * @param wrapperEl - The modal wrapper element to measure
1597
- * @returns SafeAreaConfig based on position
1598
- */
1599
- const getPositionBasedSafeAreaConfig = (wrapperEl) => {
1600
- var _a, _b;
1601
- const rect = wrapperEl.getBoundingClientRect();
1602
- const vh = (_a = win === null || win === void 0 ? void 0 : win.innerHeight) !== null && _a !== void 0 ? _a : 0;
1603
- const vw = (_b = win === null || win === void 0 ? void 0 : win.innerWidth) !== null && _b !== void 0 ? _b : 0;
1604
- // Only apply safe-area to sides where modal overlaps with screen edge
1605
- return {
1606
- top: rect.top <= EDGE_THRESHOLD ? 'inherit' : '0px',
1607
- bottom: rect.bottom >= vh - EDGE_THRESHOLD ? 'inherit' : '0px',
1608
- left: rect.left <= EDGE_THRESHOLD ? 'inherit' : '0px',
1609
- right: rect.right >= vw - EDGE_THRESHOLD ? 'inherit' : '0px',
1610
- };
1611
- };
1612
- /**
1613
- * Applies safe-area CSS custom property overrides to the modal host element.
1614
- *
1615
- * @param hostEl - The modal host element (ion-modal)
1616
- * @param config - Safe-area configuration to apply
1617
- */
1618
- const applySafeAreaOverrides = (hostEl, config) => {
1619
- hostEl.style.setProperty('--ion-safe-area-top', config.top);
1620
- hostEl.style.setProperty('--ion-safe-area-bottom', config.bottom);
1621
- hostEl.style.setProperty('--ion-safe-area-left', config.left);
1622
- hostEl.style.setProperty('--ion-safe-area-right', config.right);
1623
- };
1624
- /**
1625
- * Clears safe-area CSS custom property overrides from the modal host element.
1626
- *
1627
- * @param hostEl - The modal host element (ion-modal)
1628
- */
1629
- const clearSafeAreaOverrides = (hostEl) => {
1630
- hostEl.style.removeProperty('--ion-safe-area-top');
1631
- hostEl.style.removeProperty('--ion-safe-area-bottom');
1632
- hostEl.style.removeProperty('--ion-safe-area-left');
1633
- hostEl.style.removeProperty('--ion-safe-area-right');
1634
- };
1635
-
1636
- const modalIosCss = ":host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:\"\"}:host(.modal-sheet){--height:calc(100% - (var(--ion-modal-offset-top, 0px) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.4)}:host(.modal-card),:host(.modal-sheet){--border-radius:10px}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:10px}}.modal-wrapper{-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0)}@media screen and (max-width: 767px){@supports (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - max(30px, var(--ion-safe-area-top)) - 10px)}}@supports not (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - 40px)}}:host(.modal-card) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}:host(.modal-card){--backdrop-opacity:0;--width:100%;-ms-flex-align:end;align-items:flex-end}:host(.modal-card) .modal-shadow{display:none}:host(.modal-card) ion-backdrop{pointer-events:none}}@media screen and (min-width: 768px){:host(.modal-card){--width:calc(100% - 120px);--height:calc(100% - (120px + var(--ion-safe-area-top) + var(--ion-safe-area-bottom)));--max-width:720px;--max-height:1000px;--backdrop-opacity:0;--box-shadow:0px 0px 30px 10px rgba(0, 0, 0, 0.1);-webkit-transition:all 0.5s ease-in-out;transition:all 0.5s ease-in-out}:host(.modal-card) .modal-wrapper{-webkit-box-shadow:none;box-shadow:none}:host(.modal-card) .modal-shadow{-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow)}}:host(.modal-sheet) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}";
1475
+ const modalIosCss = ":host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px;--ion-safe-area-top:0px;--ion-safe-area-bottom:0px;--ion-safe-area-right:0px;--ion-safe-area-left:0px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:\"\"}:host(.modal-sheet){--height:calc(100% - (var(--ion-safe-area-top) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.4)}:host(.modal-card),:host(.modal-sheet){--border-radius:10px}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:10px}}.modal-wrapper{-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0)}@media screen and (max-width: 767px){@supports (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - max(30px, var(--ion-safe-area-top)) - 10px)}}@supports not (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - 40px)}}:host(.modal-card) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}:host(.modal-card){--backdrop-opacity:0;--width:100%;-ms-flex-align:end;align-items:flex-end}:host(.modal-card) .modal-shadow{display:none}:host(.modal-card) ion-backdrop{pointer-events:none}}@media screen and (min-width: 768px){:host(.modal-card){--width:calc(100% - 120px);--height:calc(100% - (120px + var(--ion-safe-area-top) + var(--ion-safe-area-bottom)));--max-width:720px;--max-height:1000px;--backdrop-opacity:0;--box-shadow:0px 0px 30px 10px rgba(0, 0, 0, 0.1);-webkit-transition:all 0.5s ease-in-out;transition:all 0.5s ease-in-out}:host(.modal-card) .modal-wrapper{-webkit-box-shadow:none;box-shadow:none}:host(.modal-card) .modal-shadow{-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow)}}:host(.modal-sheet) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}";
1637
1476
 
1638
- const modalMdCss = ":host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:\"\"}:host(.modal-sheet){--height:calc(100% - (var(--ion-modal-offset-top, 0px) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.32)}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:2px;--box-shadow:0 28px 48px rgba(0, 0, 0, 0.4)}}.modal-wrapper{-webkit-transform:translate3d(0, 40px, 0);transform:translate3d(0, 40px, 0);opacity:0.01}";
1477
+ const modalMdCss = ":host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px;--ion-safe-area-top:0px;--ion-safe-area-bottom:0px;--ion-safe-area-right:0px;--ion-safe-area-left:0px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:\"\"}:host(.modal-sheet){--height:calc(100% - (var(--ion-safe-area-top) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.32)}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:2px;--box-shadow:0 28px 48px rgba(0, 0, 0, 0.4)}}.modal-wrapper{-webkit-transform:translate3d(0, 40px, 0);transform:translate3d(0, 40px, 0);opacity:0.01}";
1639
1478
 
1640
1479
  const Modal = class {
1641
1480
  constructor(hostRef) {
@@ -1848,31 +1687,13 @@ const Modal = class {
1848
1687
  }
1849
1688
  }
1850
1689
  onWindowResize() {
1851
- if (!this.presented)
1690
+ // Only handle resize for iOS card modals when no custom animations are provided
1691
+ if (getIonMode(this) !== 'ios' || !this.presentingElement || this.enterAnimation || this.leaveAnimation) {
1852
1692
  return;
1693
+ }
1853
1694
  clearTimeout(this.resizeTimeout);
1854
1695
  this.resizeTimeout = setTimeout(() => {
1855
- const context = this.getSafeAreaContext();
1856
- // iOS card modals: handle portrait/landscape view transitions
1857
- if (context.isCardModal && !this.enterAnimation && !this.leaveAnimation) {
1858
- this.handleViewTransition();
1859
- }
1860
- // Sheet modals: re-compute the internal offset property since safe-area
1861
- // values may change on device rotation (e.g., portrait notch vs landscape).
1862
- if (context.isSheetModal) {
1863
- this.updateSheetOffsetTop();
1864
- }
1865
- // Regular (non-sheet, non-card) modals: update safe-area overrides
1866
- // since the viewport may have crossed the centered-dialog breakpoint.
1867
- if (!context.isSheetModal && !context.isCardModal) {
1868
- this.updateSafeAreaOverrides();
1869
- // Re-evaluate fullscreen safe-area padding: clear first, then re-apply
1870
- if (this.wrapperEl) {
1871
- this.wrapperEl.style.removeProperty('height');
1872
- this.wrapperEl.style.removeProperty('padding-bottom');
1873
- }
1874
- this.applyFullscreenSafeArea();
1875
- }
1696
+ this.handleViewTransition();
1876
1697
  }, 50); // Debounce to avoid excessive calls during active resizing
1877
1698
  }
1878
1699
  breakpointsChanged(breakpoints) {
@@ -1889,9 +1710,6 @@ const Modal = class {
1889
1710
  this.triggerController.removeClickListener();
1890
1711
  this.cleanupViewTransitionListener();
1891
1712
  this.cleanupParentRemovalObserver();
1892
- // Also called in dismiss() — intentional dual cleanup covers both
1893
- // dismiss-then-remove and direct DOM removal without dismiss.
1894
- this.cleanupSafeAreaOverrides();
1895
1713
  }
1896
1714
  componentWillLoad() {
1897
1715
  var _a;
@@ -2052,11 +1870,6 @@ const Modal = class {
2052
1870
  await waitForMount();
2053
1871
  }
2054
1872
  writeTask(() => this.el.classList.add('show-modal'));
2055
- // Recalculate isSheetModal before safe-area setup because framework
2056
- // bindings (e.g., Angular) may not have been applied when componentWillLoad ran.
2057
- this.isSheetModal = this.breakpoints !== undefined && this.initialBreakpoint !== undefined;
2058
- // Set initial safe-area overrides before animation
2059
- this.setInitialSafeAreaOverrides();
2060
1873
  const hasCardModal = presentingElement !== undefined;
2061
1874
  /**
2062
1875
  * We need to change the status bar at the
@@ -2074,10 +1887,6 @@ const Modal = class {
2074
1887
  backdropBreakpoint: this.backdropBreakpoint,
2075
1888
  expandToScroll: this.expandToScroll,
2076
1889
  });
2077
- // Update safe-area based on actual position after animation
2078
- this.updateSafeAreaOverrides();
2079
- // Apply fullscreen safe-area padding if needed
2080
- this.applyFullscreenSafeArea();
2081
1890
  /* tslint:disable-next-line */
2082
1891
  if (typeof window !== 'undefined') {
2083
1892
  /**
@@ -2109,7 +1918,13 @@ const Modal = class {
2109
1918
  };
2110
1919
  window.addEventListener(KEYBOARD_DID_OPEN, this.keyboardOpenCallback);
2111
1920
  }
2112
- if (this.isSheetModal) {
1921
+ /**
1922
+ * Recalculate isSheetModal because framework bindings (e.g., Angular)
1923
+ * may not have been applied when componentWillLoad ran.
1924
+ */
1925
+ const isSheetModal = this.breakpoints !== undefined && this.initialBreakpoint !== undefined;
1926
+ this.isSheetModal = isSheetModal;
1927
+ if (isSheetModal) {
2113
1928
  this.initSheetGesture();
2114
1929
  }
2115
1930
  else if (hasCardModal) {
@@ -2299,9 +2114,6 @@ const Modal = class {
2299
2114
  if (this.gestureAnimationDismissing && role !== GESTURE) {
2300
2115
  return false;
2301
2116
  }
2302
- // Cancel any pending resize timeout to prevent stale updates during dismiss
2303
- clearTimeout(this.resizeTimeout);
2304
- this.resizeTimeout = undefined;
2305
2117
  /**
2306
2118
  * Because the canDismiss check below is async,
2307
2119
  * we need to claim a lock before the check happens,
@@ -2356,7 +2168,6 @@ const Modal = class {
2356
2168
  }
2357
2169
  this.cleanupViewTransitionListener();
2358
2170
  this.cleanupParentRemovalObserver();
2359
- this.cleanupSafeAreaOverrides();
2360
2171
  this.cleanupChildRoutePassthrough();
2361
2172
  }
2362
2173
  this.currentBreakpoint = undefined;
@@ -2477,9 +2288,6 @@ const Modal = class {
2477
2288
  this.viewTransitionAnimation = transitionAnimation;
2478
2289
  transitionAnimation.play().then(() => {
2479
2290
  this.viewTransitionAnimation = undefined;
2480
- // Wait for a layout pass after the transition so getBoundingClientRect()
2481
- // in getPositionBasedSafeAreaConfig() reflects the new dimensions.
2482
- raf(() => this.updateSafeAreaOverrides());
2483
2291
  // After orientation transition, recreate the swipe-to-close gesture
2484
2292
  // with updated animation that reflects the new presenting element state
2485
2293
  this.reinitSwipeToClose();
@@ -2606,123 +2414,6 @@ const Modal = class {
2606
2414
  (_a = this.parentRemovalObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
2607
2415
  this.parentRemovalObserver = undefined;
2608
2416
  }
2609
- /**
2610
- * Creates the context object for safe-area utilities.
2611
- */
2612
- getSafeAreaContext() {
2613
- return {
2614
- isSheetModal: this.isSheetModal,
2615
- isCardModal: this.presentingElement !== undefined && getIonMode(this) === 'ios',
2616
- presentingElement: this.presentingElement,
2617
- breakpoints: this.breakpoints,
2618
- currentBreakpoint: this.currentBreakpoint,
2619
- };
2620
- }
2621
- /**
2622
- * Sets initial safe-area overrides before modal animation.
2623
- * Called in present() before animation starts.
2624
- *
2625
- * For sheet modals, the SCSS --height formula uses --ion-modal-offset-top
2626
- * (an internal property) instead of --ion-safe-area-top. We resolve the
2627
- * root safe-area-top to pixels and set --ion-modal-offset-top, decoupling
2628
- * the height calculation from --ion-safe-area-top (which is zeroed for
2629
- * sheets to prevent header content from getting double-offset padding).
2630
- */
2631
- setInitialSafeAreaOverrides() {
2632
- const context = this.getSafeAreaContext();
2633
- const safeAreaConfig = getInitialSafeAreaConfig(context);
2634
- applySafeAreaOverrides(this.el, safeAreaConfig);
2635
- // Set the internal offset property with the resolved root safe-area-top value
2636
- if (context.isSheetModal) {
2637
- this.updateSheetOffsetTop();
2638
- }
2639
- }
2640
- /**
2641
- * Resolves the current root --ion-safe-area-top value and sets the
2642
- * internal --ion-modal-offset-top property on the host element.
2643
- * Called on present and on resize (e.g., device rotation changes safe-area).
2644
- */
2645
- updateSheetOffsetTop() {
2646
- const safeAreaTop = getRootSafeAreaTop();
2647
- this.el.style.setProperty('--ion-modal-offset-top', `${safeAreaTop}px`);
2648
- }
2649
- /**
2650
- * Updates safe-area overrides during dynamic state changes.
2651
- * Called after animations, during gestures, and on orientation changes.
2652
- */
2653
- updateSafeAreaOverrides() {
2654
- const { wrapperEl, el } = this;
2655
- const context = this.getSafeAreaContext();
2656
- // Sheet modals: safe-area is fully determined at presentation time
2657
- // (top is always 0px, height is frozen). Nothing to update.
2658
- if (context.isSheetModal)
2659
- return;
2660
- // Card modals have fixed safe-area requirements set by initial prediction.
2661
- if (context.isCardModal)
2662
- return;
2663
- // wrapperEl is required for position-based detection below
2664
- if (!wrapperEl)
2665
- return;
2666
- // Regular modals: use position-based detection to correctly handle both
2667
- // fullscreen modals and centered dialogs with custom dimensions.
2668
- const safeAreaConfig = getPositionBasedSafeAreaConfig(wrapperEl);
2669
- applySafeAreaOverrides(el, safeAreaConfig);
2670
- }
2671
- /**
2672
- * Applies padding-bottom to fullscreen modal wrapper to prevent
2673
- * content from overlapping system navigation bar.
2674
- */
2675
- applyFullscreenSafeArea() {
2676
- const { wrapperEl, el } = this;
2677
- if (!wrapperEl)
2678
- return;
2679
- const context = this.getSafeAreaContext();
2680
- if (context.isSheetModal || context.isCardModal)
2681
- return;
2682
- // Check for standard Ionic layout children (ion-content, ion-footer),
2683
- // searching one level deep for wrapped components (e.g.,
2684
- // <app-footer><ion-footer>...</ion-footer></app-footer>).
2685
- // Note: uses a manual loop instead of querySelector(':scope > ...') because
2686
- // Stencil's mock-doc (used in spec tests) does not support :scope.
2687
- let hasContent = false;
2688
- let hasFooter = false;
2689
- for (const child of Array.from(el.children)) {
2690
- if (child.tagName === 'ION-CONTENT')
2691
- hasContent = true;
2692
- if (child.tagName === 'ION-FOOTER')
2693
- hasFooter = true;
2694
- for (const grandchild of Array.from(child.children)) {
2695
- if (grandchild.tagName === 'ION-CONTENT')
2696
- hasContent = true;
2697
- if (grandchild.tagName === 'ION-FOOTER')
2698
- hasFooter = true;
2699
- }
2700
- }
2701
- // Only apply wrapper padding for standard Ionic layouts (has ion-content
2702
- // but no ion-footer). Custom modals with raw HTML are fully
2703
- // developer-controlled and should not be modified.
2704
- if (!hasContent || hasFooter)
2705
- return;
2706
- // Reduce wrapper height by safe-area and add equivalent padding so the
2707
- // total visual size stays the same but the flex content area shrinks.
2708
- // Using height + padding instead of box-sizing: border-box avoids
2709
- // breaking custom modals that set --border-width (border-box would
2710
- // include the border inside the height, changing the layout).
2711
- wrapperEl.style.setProperty('height', 'calc(var(--height) - var(--ion-safe-area-bottom, 0px))');
2712
- wrapperEl.style.setProperty('padding-bottom', 'var(--ion-safe-area-bottom, 0px)');
2713
- }
2714
- /**
2715
- * Clears all safe-area overrides and padding from wrapper.
2716
- */
2717
- cleanupSafeAreaOverrides() {
2718
- clearSafeAreaOverrides(this.el);
2719
- // Remove internal sheet offset property
2720
- this.el.style.removeProperty('--ion-modal-offset-top');
2721
- if (this.wrapperEl) {
2722
- this.wrapperEl.style.removeProperty('height');
2723
- this.wrapperEl.style.removeProperty('padding-bottom');
2724
- }
2725
- }
2726
2417
  render() {
2727
2418
  const { handle, isSheetModal, presentingElement, htmlAttributes, handleBehavior, inheritedAttributes, focusTrap, expandToScroll, } = this;
2728
2419
  const showHandle = handle !== false && isSheetModal;
@@ -2730,20 +2421,20 @@ const Modal = class {
2730
2421
  const isCardModal = presentingElement !== undefined && mode === 'ios';
2731
2422
  const isHandleCycle = handleBehavior === 'cycle';
2732
2423
  const isSheetModalWithHandle = isSheetModal && showHandle;
2733
- return (h(Host, Object.assign({ key: '038ae26c2cb040043c7d0c217a4de6a7ae909235', "no-router": true,
2424
+ return (h(Host, Object.assign({ key: '978ba9cc81464b2d9b4caaf36285d5f7bf7e568d', "no-router": true,
2734
2425
  // Allow the modal to be navigable when the handle is focusable
2735
2426
  tabIndex: isHandleCycle && isSheetModalWithHandle ? 0 : -1 }, htmlAttributes, { style: {
2736
2427
  zIndex: `${20000 + this.overlayIndex}`,
2737
- }, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, [`modal-no-expand-scroll`]: isSheetModal && !expandToScroll, 'overlay-hidden': true, [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle, onFocus: this.onModalFocus }), h("ion-backdrop", { key: '6bab796467b370e79b24ce17c5a3d51adb07ee8c', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { key: 'b9a19e86a2c7f079c88ef7a914c7c890aa601887', class: "modal-shadow" }), h("div", Object.assign({ key: 'f4315c34aa78be4e3540361755964be2ddf43265',
2428
+ }, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, [`modal-no-expand-scroll`]: isSheetModal && !expandToScroll, 'overlay-hidden': true, [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle, onFocus: this.onModalFocus }), h("ion-backdrop", { key: '9f95566d8e0c06bb9607f514484848c250f35f1f', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { key: '91ff26d4f3ab4367f3a2940f51c6a5a3d4c972c3', class: "modal-shadow" }), h("div", Object.assign({ key: '064b2dba13854505a4eb1f5e54296ac79cb7a2bd',
2738
2429
  /*
2739
2430
  role and aria-modal must be used on the
2740
2431
  same element. They must also be set inside the
2741
2432
  shadow DOM otherwise ion-button will not be highlighted
2742
2433
  when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
2743
2434
  */
2744
- role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: '3f7792bd65e0f8634e62bf27f9edcb636a03030a', class: "modal-handle",
2435
+ role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: 'b579b08b114022032d078a527111456ceefc7b35', class: "modal-handle",
2745
2436
  // Prevents the handle from receiving keyboard focus when it does not cycle
2746
- tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle", ref: (el) => (this.dragHandleEl = el) })), h("slot", { key: '001e5b01831e240bd98f75ff62446b90b64d8394', onSlotchange: this.onSlotChange }))));
2437
+ tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle", ref: (el) => (this.dragHandleEl = el) })), h("slot", { key: 'dacea58475b72d9c0209934ff31f3be6b9ac8c85', onSlotchange: this.onSlotChange }))));
2747
2438
  }
2748
2439
  get el() { return getElement(this); }
2749
2440
  static get watchers() { return {
@@ -895,7 +895,7 @@ const Nav = class {
895
895
  }
896
896
  }
897
897
  render() {
898
- return h("slot", { key: '8067c9835d255daec61f33dba200fd3a6ff839a0' });
898
+ return h("slot", { key: 'a549286b51b1bb23c9ef51f71148452228d0ab14' });
899
899
  }
900
900
  get el() { return getElement(this); }
901
901
  static get watchers() { return {
@@ -937,7 +937,7 @@ const NavLink = class {
937
937
  };
938
938
  }
939
939
  render() {
940
- return h(Host, { key: '6dbb1ad4f351e9215375aac11ab9b53762e07a08', onClick: this.onClick });
940
+ return h(Host, { key: 'd4d80feb51c0d92b0bedf6952c892f9df3002046', onClick: this.onClick });
941
941
  }
942
942
  get el() { return getElement(this); }
943
943
  };
@@ -97,10 +97,10 @@ const PickerColumnOption = class {
97
97
  render() {
98
98
  const { color, disabled, ariaLabel } = this;
99
99
  const mode = getIonMode(this);
100
- return (h(Host, { key: 'f816729941aabcb31ddfdce3ffe2e2139030d715', class: createColorClasses(color, {
100
+ return (h(Host, { key: 'c45a1c14a351bf57d7113671164852349be5aa8a', class: createColorClasses(color, {
101
101
  [mode]: true,
102
102
  ['option-disabled']: disabled,
103
- }) }, h("div", { key: 'd942de84fd14d7dc06b1e5cf4f7920d1dc3c6371', class: 'picker-column-option-button', role: "button", "aria-label": ariaLabel, onClick: () => this.onClick() }, h("slot", { key: 'b0df5717b42209e649097209a01476e1a66f5c5c' }))));
103
+ }) }, h("div", { key: '824930b658c6e3fb493ac4c6c2451d38c6bc4829', class: 'picker-column-option-button', role: "button", "aria-label": ariaLabel, onClick: () => this.onClick() }, h("slot", { key: '019df4dcf46e629bdbebcd46ed3ab29669feab27' }))));
104
104
  }
105
105
  get el() { return getElement(this); }
106
106
  static get watchers() { return {