@ionic/core 7.5.7-dev.11701203423.1b6a8829 → 7.5.7-dev.11701273756.1eb73d4c

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 (388) hide show
  1. package/components/animation.js +12 -11
  2. package/components/checkbox.js +2 -0
  3. package/components/icon.js +23 -14
  4. package/components/index4.js +10 -12
  5. package/components/index5.js +0 -22
  6. package/components/index7.js +1 -1
  7. package/components/input-shims.js +12 -7
  8. package/components/input.utils.js +3 -2
  9. package/components/ion-datetime.js +2 -2
  10. package/components/ion-input.js +31 -8
  11. package/components/ion-modal.js +2 -2
  12. package/components/ion-range.js +2 -0
  13. package/components/ion-select.js +44 -29
  14. package/components/ion-skeleton-text.js +14 -1
  15. package/components/ion-textarea.js +30 -7
  16. package/components/ion-toast.js +419 -74
  17. package/components/ion-toggle.js +2 -0
  18. package/components/item.js +2 -2
  19. package/components/label.js +2 -2
  20. package/components/overlays.js +2 -1
  21. package/components/radio-group.js +2 -0
  22. package/components/radio.js +42 -2
  23. package/dist/cjs/{animation-1083855c.js → animation-d101aa7a.js} +13 -12
  24. package/dist/cjs/{button-active-af897e0e.js → button-active-ba107e4e.js} +1 -1
  25. package/dist/cjs/{capacitor-2ffba62a.js → capacitor-f68447d3.js} +1 -1
  26. package/dist/cjs/compare-with-utils-c0444525.js +44 -0
  27. package/dist/cjs/{haptic-678abc9f.js → haptic-a74c2767.js} +1 -1
  28. package/dist/cjs/{index-5ea49600.js → index-09471526.js} +1 -1
  29. package/dist/cjs/{index-d7561763.js → index-4f0c67e1.js} +11 -13
  30. package/dist/cjs/{index-573877f3.js → index-56d41f51.js} +2 -2
  31. package/dist/cjs/index-c8d52405.js +10 -0
  32. package/dist/cjs/{index-9f379eaa.js → index-e9634bc9.js} +1 -1
  33. package/dist/cjs/index.cjs.js +8 -8
  34. package/dist/cjs/{input-shims-b0a75a01.js → input-shims-3e3f35b9.js} +15 -10
  35. package/dist/cjs/{input.utils-0fe3097c.js → input.utils-bdb6953c.js} +4 -3
  36. package/dist/cjs/ion-accordion_2.cjs.entry.js +1 -1
  37. package/dist/cjs/ion-action-sheet.cjs.entry.js +6 -6
  38. package/dist/cjs/ion-alert.cjs.entry.js +6 -6
  39. package/dist/cjs/ion-app_8.cjs.entry.js +8 -8
  40. package/dist/cjs/ion-back-button.cjs.entry.js +1 -1
  41. package/dist/cjs/ion-breadcrumb_2.cjs.entry.js +1 -1
  42. package/dist/cjs/ion-button_2.cjs.entry.js +23 -14
  43. package/dist/cjs/ion-checkbox.cjs.entry.js +2 -0
  44. package/dist/cjs/ion-datetime_3.cjs.entry.js +8 -8
  45. package/dist/cjs/ion-fab_3.cjs.entry.js +1 -1
  46. package/dist/cjs/ion-input.cjs.entry.js +35 -12
  47. package/dist/cjs/ion-item_8.cjs.entry.js +18 -5
  48. package/dist/cjs/ion-loading.cjs.entry.js +3 -3
  49. package/dist/cjs/ion-menu_3.cjs.entry.js +6 -6
  50. package/dist/cjs/ion-modal.cjs.entry.js +8 -8
  51. package/dist/cjs/ion-nav_2.cjs.entry.js +1 -1
  52. package/dist/cjs/ion-picker-column-internal.cjs.entry.js +3 -3
  53. package/dist/cjs/ion-popover.cjs.entry.js +4 -4
  54. package/dist/cjs/ion-radio_2.cjs.entry.js +6 -1
  55. package/dist/cjs/ion-range.cjs.entry.js +2 -0
  56. package/dist/cjs/ion-refresher_2.cjs.entry.js +5 -5
  57. package/dist/cjs/ion-reorder_2.cjs.entry.js +4 -4
  58. package/dist/cjs/ion-searchbar.cjs.entry.js +1 -1
  59. package/dist/cjs/ion-select_3.cjs.entry.js +52 -36
  60. package/dist/cjs/ion-tab-bar_2.cjs.entry.js +4 -4
  61. package/dist/cjs/ion-textarea.cjs.entry.js +33 -10
  62. package/dist/cjs/ion-toast.cjs.entry.js +434 -92
  63. package/dist/cjs/ion-toggle.cjs.entry.js +6 -4
  64. package/dist/cjs/ionic.cjs.js +1 -1
  65. package/dist/cjs/{ios.transition-ac909bc8.js → ios.transition-f4caf640.js} +3 -3
  66. package/dist/cjs/{keyboard-fd7db491.js → keyboard-43df0428.js} +1 -1
  67. package/dist/cjs/{keyboard-38f2bb7b.js → keyboard-840107b3.js} +3 -3
  68. package/dist/cjs/{keyboard-controller-50beb83a.js → keyboard-controller-019f42df.js} +2 -2
  69. package/dist/cjs/loader.cjs.js +1 -1
  70. package/dist/cjs/{md.transition-907af519.js → md.transition-33331e93.js} +3 -3
  71. package/dist/cjs/{notch-controller-f4f6af5d.js → notch-controller-c22d1344.js} +1 -1
  72. package/dist/cjs/{overlays-2ffc5f27.js → overlays-4d8897dc.js} +3 -1
  73. package/dist/collection/components/checkbox/checkbox.js +2 -0
  74. package/dist/collection/components/datetime/datetime.ios.css +1 -0
  75. package/dist/collection/components/datetime/datetime.md.css +1 -0
  76. package/dist/collection/components/input/input.ios.css +10 -3
  77. package/dist/collection/components/input/input.js +31 -6
  78. package/dist/collection/components/input/input.md.css +13 -12
  79. package/dist/collection/components/input/test/slot/input.e2e.js +51 -0
  80. package/dist/collection/components/item/item.ios.css +25 -3
  81. package/dist/collection/components/item/item.md.css +25 -3
  82. package/dist/collection/components/item/test/basic/item.e2e.js +1 -1
  83. package/dist/collection/components/item/test/disabled/item.e2e.js +0 -1
  84. package/dist/collection/components/label/label.ios.css +14 -3
  85. package/dist/collection/components/label/label.md.css +14 -3
  86. package/dist/collection/components/modal/gestures/swipe-to-close.js +2 -1
  87. package/dist/collection/components/note/test/a11y/note.e2e.js +43 -0
  88. package/dist/collection/components/radio/radio.js +5 -2
  89. package/dist/collection/components/radio-group/radio-group.js +24 -0
  90. package/dist/collection/components/radio-group/test/radio-group.spec.js +69 -0
  91. package/dist/collection/components/range/range.js +2 -0
  92. package/dist/collection/components/select/select.ios.css +61 -7
  93. package/dist/collection/components/select/select.js +45 -28
  94. package/dist/collection/components/select/select.md.css +64 -19
  95. package/dist/collection/components/select/test/label/select.e2e.js +1 -1
  96. package/dist/collection/components/select/test/legacy/wrapping/select.e2e.js +1 -1
  97. package/dist/collection/components/select/test/slot/select.e2e.js +67 -0
  98. package/dist/collection/components/skeleton-text/skeleton-text.js +39 -0
  99. package/dist/collection/components/textarea/test/slot/textarea.e2e.js +51 -0
  100. package/dist/collection/components/textarea/textarea.ios.css +37 -5
  101. package/dist/collection/components/textarea/textarea.js +30 -5
  102. package/dist/collection/components/textarea/textarea.md.css +47 -14
  103. package/dist/collection/components/toast/animations/ios.enter.js +2 -1
  104. package/dist/collection/components/toast/animations/md.enter.js +4 -3
  105. package/dist/collection/components/toast/animations/utils.js +20 -14
  106. package/dist/collection/components/toast/gestures/swipe-to-dismiss.js +267 -0
  107. package/dist/collection/components/toast/test/swipe-gesture/toast.e2e.js +84 -0
  108. package/dist/collection/components/toast/test/toast-config.spec.js +25 -0
  109. package/dist/collection/components/toast/test/toast.spec.js +80 -0
  110. package/dist/collection/components/toast/toast.ios.css +10 -10
  111. package/dist/collection/components/toast/toast.js +104 -1
  112. package/dist/collection/components/toast/toast.md.css +10 -0
  113. package/dist/collection/components/toggle/toggle.js +2 -0
  114. package/dist/collection/utils/animation/animation.js +12 -11
  115. package/dist/collection/utils/animation/test/animation.spec.js +16 -0
  116. package/dist/collection/utils/browser/index.js +0 -22
  117. package/dist/collection/utils/forms/compare-with-utils.js +39 -0
  118. package/dist/collection/utils/forms/index.js +1 -0
  119. package/dist/collection/utils/input-shims/input-shims.js +12 -6
  120. package/dist/collection/utils/menu-controller/index.js +10 -12
  121. package/dist/collection/utils/overlays.js +1 -0
  122. package/dist/collection/utils/slot-mutation-controller.js +3 -2
  123. package/dist/docs.json +127 -2
  124. package/dist/esm/{animation-8aa13916.js → animation-cf3dd234.js} +13 -12
  125. package/dist/esm/{button-active-ce5cba4c.js → button-active-47196c40.js} +1 -1
  126. package/dist/esm/{capacitor-b4979570.js → capacitor-f1f25364.js} +1 -1
  127. package/dist/esm/compare-with-utils-4928c09d.js +41 -0
  128. package/dist/esm/{haptic-1243b917.js → haptic-1a66d69f.js} +1 -1
  129. package/dist/esm/{index-0aa6e61f.js → index-23c05a55.js} +11 -13
  130. package/dist/esm/{index-6a0ccabb.js → index-702b3cd3.js} +2 -2
  131. package/dist/esm/index-a5d50daf.js +7 -0
  132. package/dist/esm/{index-d1a56aed.js → index-c132c5f1.js} +1 -1
  133. package/dist/esm/{index-f0cc4e14.js → index-c9e82353.js} +1 -1
  134. package/dist/esm/index.js +8 -8
  135. package/dist/esm/{input-shims-d0c93e5d.js → input-shims-1d767845.js} +14 -9
  136. package/dist/esm/{input.utils-ec063df4.js → input.utils-2cf5e372.js} +4 -3
  137. package/dist/esm/ion-accordion_2.entry.js +1 -1
  138. package/dist/esm/ion-action-sheet.entry.js +6 -6
  139. package/dist/esm/ion-alert.entry.js +6 -6
  140. package/dist/esm/ion-app_8.entry.js +8 -8
  141. package/dist/esm/ion-back-button.entry.js +1 -1
  142. package/dist/esm/ion-breadcrumb_2.entry.js +1 -1
  143. package/dist/esm/ion-button_2.entry.js +23 -14
  144. package/dist/esm/ion-checkbox.entry.js +2 -0
  145. package/dist/esm/ion-datetime_3.entry.js +8 -8
  146. package/dist/esm/ion-fab_3.entry.js +1 -1
  147. package/dist/esm/ion-input.entry.js +35 -12
  148. package/dist/esm/ion-item_8.entry.js +18 -5
  149. package/dist/esm/ion-loading.entry.js +3 -3
  150. package/dist/esm/ion-menu_3.entry.js +6 -6
  151. package/dist/esm/ion-modal.entry.js +8 -8
  152. package/dist/esm/ion-nav_2.entry.js +1 -1
  153. package/dist/esm/ion-picker-column-internal.entry.js +3 -3
  154. package/dist/esm/ion-popover.entry.js +4 -4
  155. package/dist/esm/ion-radio_2.entry.js +6 -1
  156. package/dist/esm/ion-range.entry.js +2 -0
  157. package/dist/esm/ion-refresher_2.entry.js +5 -5
  158. package/dist/esm/ion-reorder_2.entry.js +4 -4
  159. package/dist/esm/ion-searchbar.entry.js +1 -1
  160. package/dist/esm/ion-select_3.entry.js +48 -32
  161. package/dist/esm/ion-tab-bar_2.entry.js +4 -4
  162. package/dist/esm/ion-textarea.entry.js +33 -10
  163. package/dist/esm/ion-toast.entry.js +417 -75
  164. package/dist/esm/ion-toggle.entry.js +6 -4
  165. package/dist/esm/ionic.js +1 -1
  166. package/dist/esm/{ios.transition-1651c430.js → ios.transition-c3e77862.js} +3 -3
  167. package/dist/esm/{keyboard-b551279d.js → keyboard-9f771a04.js} +3 -3
  168. package/dist/esm/{keyboard-b063f012.js → keyboard-b6230bfb.js} +1 -1
  169. package/dist/esm/{keyboard-controller-0c2dce71.js → keyboard-controller-3f0faa10.js} +2 -2
  170. package/dist/esm/loader.js +1 -1
  171. package/dist/esm/{md.transition-66f18369.js → md.transition-1173eca9.js} +3 -3
  172. package/dist/esm/{notch-controller-8c9c0e54.js → notch-controller-3f79197e.js} +1 -1
  173. package/dist/esm/{overlays-6c9feb7e.js → overlays-34169295.js} +3 -2
  174. package/dist/esm-es5/{animation-8aa13916.js → animation-cf3dd234.js} +1 -1
  175. package/dist/esm-es5/{button-active-ce5cba4c.js → button-active-47196c40.js} +1 -1
  176. package/dist/esm-es5/{capacitor-b4979570.js → capacitor-f1f25364.js} +1 -1
  177. package/dist/esm-es5/compare-with-utils-4928c09d.js +4 -0
  178. package/dist/esm-es5/{haptic-1243b917.js → haptic-1a66d69f.js} +1 -1
  179. package/dist/esm-es5/index-23c05a55.js +4 -0
  180. package/dist/esm-es5/{index-6a0ccabb.js → index-702b3cd3.js} +1 -1
  181. package/dist/esm-es5/index-c9e82353.js +4 -0
  182. package/dist/esm-es5/index.js +1 -1
  183. package/dist/esm-es5/input-shims-1d767845.js +4 -0
  184. package/dist/esm-es5/input.utils-2cf5e372.js +4 -0
  185. package/dist/esm-es5/ion-accordion_2.entry.js +1 -1
  186. package/dist/esm-es5/ion-action-sheet.entry.js +1 -1
  187. package/dist/esm-es5/ion-alert.entry.js +1 -1
  188. package/dist/esm-es5/ion-app_8.entry.js +1 -1
  189. package/dist/esm-es5/ion-back-button.entry.js +1 -1
  190. package/dist/esm-es5/ion-breadcrumb_2.entry.js +1 -1
  191. package/dist/esm-es5/ion-button_2.entry.js +1 -1
  192. package/dist/esm-es5/ion-checkbox.entry.js +1 -1
  193. package/dist/esm-es5/ion-datetime_3.entry.js +1 -1
  194. package/dist/esm-es5/ion-fab_3.entry.js +1 -1
  195. package/dist/esm-es5/ion-input.entry.js +1 -1
  196. package/dist/esm-es5/ion-item_8.entry.js +1 -1
  197. package/dist/esm-es5/ion-loading.entry.js +1 -1
  198. package/dist/esm-es5/ion-menu_3.entry.js +1 -1
  199. package/dist/esm-es5/ion-modal.entry.js +1 -1
  200. package/dist/esm-es5/ion-nav_2.entry.js +1 -1
  201. package/dist/esm-es5/ion-picker-column-internal.entry.js +1 -1
  202. package/dist/esm-es5/ion-popover.entry.js +1 -1
  203. package/dist/esm-es5/ion-radio_2.entry.js +1 -1
  204. package/dist/esm-es5/ion-range.entry.js +1 -1
  205. package/dist/esm-es5/ion-refresher_2.entry.js +1 -1
  206. package/dist/esm-es5/ion-reorder_2.entry.js +1 -1
  207. package/dist/esm-es5/ion-searchbar.entry.js +1 -1
  208. package/dist/esm-es5/ion-select_3.entry.js +1 -1
  209. package/dist/esm-es5/ion-tab-bar_2.entry.js +1 -1
  210. package/dist/esm-es5/ion-textarea.entry.js +1 -1
  211. package/dist/esm-es5/ion-toast.entry.js +1 -1
  212. package/dist/esm-es5/ion-toggle.entry.js +1 -1
  213. package/dist/esm-es5/ionic.js +1 -1
  214. package/dist/esm-es5/{ios.transition-1651c430.js → ios.transition-c3e77862.js} +1 -1
  215. package/dist/esm-es5/{keyboard-b551279d.js → keyboard-9f771a04.js} +1 -1
  216. package/dist/esm-es5/{keyboard-b063f012.js → keyboard-b6230bfb.js} +1 -1
  217. package/dist/esm-es5/{keyboard-controller-0c2dce71.js → keyboard-controller-3f0faa10.js} +1 -1
  218. package/dist/esm-es5/loader.js +1 -1
  219. package/dist/esm-es5/md.transition-1173eca9.js +4 -0
  220. package/dist/esm-es5/{notch-controller-8c9c0e54.js → notch-controller-3f79197e.js} +1 -1
  221. package/dist/esm-es5/{overlays-6c9feb7e.js → overlays-34169295.js} +1 -1
  222. package/dist/html.html-data.json +14 -1
  223. package/dist/ionic/index.esm.js +1 -1
  224. package/dist/ionic/ionic.esm.js +1 -1
  225. package/dist/ionic/{p-67e644bd.system.entry.js → p-03ed6107.system.entry.js} +1 -1
  226. package/dist/ionic/p-0547e914.entry.js +4 -0
  227. package/dist/ionic/{p-c429a314.system.entry.js → p-07d9e9cd.system.entry.js} +1 -1
  228. package/dist/ionic/{p-81c818e7.js → p-11cb4e19.js} +1 -1
  229. package/dist/ionic/p-131761b4.entry.js +4 -0
  230. package/dist/ionic/{p-04dca48d.entry.js → p-14aca3fb.entry.js} +1 -1
  231. package/dist/ionic/{p-ddfc4ef4.system.entry.js → p-196f2123.system.entry.js} +1 -1
  232. package/dist/ionic/{p-64ed03a3.entry.js → p-1abc74d9.entry.js} +1 -1
  233. package/dist/ionic/p-1cf5e8d6.entry.js +4 -0
  234. package/dist/ionic/p-1dc91702.entry.js +4 -0
  235. package/dist/ionic/{p-a43603ce.entry.js → p-1e86a71b.entry.js} +1 -1
  236. package/dist/ionic/{p-c4042875.system.js → p-21b4981c.system.js} +1 -1
  237. package/dist/ionic/p-2207f3c2.js +4 -0
  238. package/dist/ionic/p-27eb8a91.system.entry.js +4 -0
  239. package/dist/ionic/{p-800ef057.js → p-2a41d4d1.js} +1 -1
  240. package/dist/ionic/{p-b91fe549.entry.js → p-31189dae.entry.js} +1 -1
  241. package/dist/ionic/p-314c4dee.js +4 -0
  242. package/dist/ionic/{p-7d7fdaf0.system.entry.js → p-37c69d34.system.entry.js} +1 -1
  243. package/dist/ionic/p-385c51f8.system.entry.js +4 -0
  244. package/dist/ionic/{p-8d5a30dd.entry.js → p-3abf5b7a.entry.js} +1 -1
  245. package/dist/ionic/p-3bc3d880.system.js +4 -0
  246. package/dist/ionic/{p-8e1bded3.entry.js → p-3e655d4c.entry.js} +1 -1
  247. package/dist/ionic/{p-8659f9a9.system.entry.js → p-3fb57e1b.system.entry.js} +1 -1
  248. package/dist/ionic/p-40903d34.system.js +1 -1
  249. package/dist/ionic/p-43716898.js +4 -0
  250. package/dist/ionic/p-450a26bf.js +4 -0
  251. package/dist/ionic/p-485668f0.entry.js +4 -0
  252. package/dist/ionic/p-48c59094.system.entry.js +4 -0
  253. package/dist/ionic/{p-899fb2da.entry.js → p-48d9faa7.entry.js} +1 -1
  254. package/dist/ionic/p-494e75ad.js +4 -0
  255. package/dist/ionic/{p-0e23256e.system.entry.js → p-54824705.system.entry.js} +1 -1
  256. package/dist/ionic/p-561cc050.system.js +4 -0
  257. package/dist/ionic/{p-4a142496.system.entry.js → p-587afb80.system.entry.js} +1 -1
  258. package/dist/ionic/{p-8cf94fc1.js → p-5885e9af.js} +1 -1
  259. package/dist/ionic/{p-6594d76a.system.entry.js → p-5da0eb3e.system.entry.js} +1 -1
  260. package/dist/ionic/{p-61c30156.system.entry.js → p-5e6bc319.system.entry.js} +1 -1
  261. package/dist/ionic/{p-f37b4b79.entry.js → p-64ab3eb3.entry.js} +1 -1
  262. package/dist/ionic/{p-42435018.system.entry.js → p-664d2b07.system.entry.js} +1 -1
  263. package/dist/ionic/p-671dbd61.js +4 -0
  264. package/dist/ionic/{p-702d85d8.system.js → p-67951604.system.js} +1 -1
  265. package/dist/ionic/{p-68166ba6.entry.js → p-6797887a.entry.js} +1 -1
  266. package/dist/ionic/{p-b923f3d7.js → p-6a309574.js} +1 -1
  267. package/dist/ionic/{p-f3c82f74.system.entry.js → p-7047a40c.system.entry.js} +1 -1
  268. package/dist/ionic/p-70dcf429.js +4 -0
  269. package/dist/ionic/p-710cea83.system.js +4 -0
  270. package/dist/ionic/p-7b44e419.js +4 -0
  271. package/dist/ionic/p-80a9b397.entry.js +4 -0
  272. package/dist/ionic/{p-1cb5f2f8.system.entry.js → p-823890d5.system.entry.js} +1 -1
  273. package/dist/ionic/{p-09d142b3.system.js → p-83a455fd.system.js} +1 -1
  274. package/dist/ionic/{p-bd76524d.entry.js → p-8b15ca22.entry.js} +1 -1
  275. package/dist/ionic/p-8ddfecbf.entry.js +4 -0
  276. package/dist/ionic/{p-b4b4bb29.system.js → p-9292fd42.system.js} +1 -1
  277. package/dist/ionic/{p-41477ad9.system.js → p-958f1c70.system.js} +1 -1
  278. package/dist/ionic/{p-29fe18ef.entry.js → p-9c6787e2.entry.js} +1 -1
  279. package/dist/ionic/p-a11c1aff.system.entry.js +4 -0
  280. package/dist/ionic/{p-419eb426.js → p-a135e3ba.js} +1 -1
  281. package/dist/ionic/p-a31099a4.entry.js +4 -0
  282. package/dist/ionic/p-a6bc00ab.entry.js +4 -0
  283. package/dist/ionic/{p-0838e6bb.entry.js → p-a8e68fd9.entry.js} +1 -1
  284. package/dist/ionic/{p-14923cd7.system.entry.js → p-abacb44b.system.entry.js} +1 -1
  285. package/dist/ionic/p-ac668fb8.entry.js +4 -0
  286. package/dist/ionic/p-ad4b4f73.system.entry.js +4 -0
  287. package/dist/ionic/{p-ab4cff27.system.js → p-aec8a70a.system.js} +1 -1
  288. package/dist/ionic/{p-f54ddd19.entry.js → p-b673ee9b.entry.js} +1 -1
  289. package/dist/ionic/p-be0f6600.system.js +4 -0
  290. package/dist/ionic/{p-deab76dc.entry.js → p-c1e725db.entry.js} +1 -1
  291. package/dist/ionic/p-c2db1374.system.js +4 -0
  292. package/dist/ionic/p-c3547c7a.system.js +4 -0
  293. package/dist/ionic/{p-a936d224.system.js → p-c4de53af.system.js} +1 -1
  294. package/dist/ionic/p-c700acef.system.js +4 -0
  295. package/dist/ionic/{p-67ed452a.system.entry.js → p-cc615985.system.entry.js} +1 -1
  296. package/dist/ionic/{p-97e31c0a.system.js → p-d48872b1.system.js} +1 -1
  297. package/dist/ionic/p-d4fba36b.system.entry.js +4 -0
  298. package/dist/ionic/{p-dbf7d6e5.system.entry.js → p-d61a2cee.system.entry.js} +1 -1
  299. package/dist/ionic/p-e5b8f2f7.js +4 -0
  300. package/dist/ionic/{p-3bad5c1a.js → p-e5fd9f10.js} +1 -1
  301. package/dist/ionic/{p-ccdcb022.system.js → p-e7d20dfb.system.js} +1 -1
  302. package/dist/ionic/{p-14b4348c.system.js → p-e9e5755c.system.js} +1 -1
  303. package/dist/ionic/{p-18e01b30.system.entry.js → p-ea9addc8.system.entry.js} +1 -1
  304. package/dist/ionic/p-edd07654.system.entry.js +4 -0
  305. package/dist/ionic/{p-64296b15.entry.js → p-f36112b4.entry.js} +1 -1
  306. package/dist/ionic/p-f43f4102.entry.js +4 -0
  307. package/dist/ionic/{p-97a96f5f.entry.js → p-f4cc91f6.entry.js} +1 -1
  308. package/dist/ionic/{p-640efee6.system.entry.js → p-f5a750e4.system.entry.js} +1 -1
  309. package/dist/ionic/p-f5d78105.entry.js +4 -0
  310. package/dist/ionic/p-f7769c83.js +4 -0
  311. package/dist/ionic/{p-bba2ce59.system.js → p-f9a641fa.system.js} +1 -1
  312. package/dist/ionic/{p-cf425ec5.system.entry.js → p-fcb148dc.system.entry.js} +1 -1
  313. package/dist/ionic/p-fcc23f25.system.entry.js +4 -0
  314. package/dist/ionic/{p-7b4cd5fc.system.entry.js → p-fce6b76a.system.entry.js} +1 -1
  315. package/dist/ionic/{p-c56b6570.system.entry.js → p-fdcf04c3.system.entry.js} +1 -1
  316. package/dist/ionic/{p-a0b6d438.js → p-fe1f93f2.js} +1 -1
  317. package/dist/node_modules/ionicons/dist/collection/components/icon/icon.css +0 -1
  318. package/dist/types/components/input/input.d.ts +2 -0
  319. package/dist/types/components/radio-group/radio-group-interface.d.ts +1 -0
  320. package/dist/types/components/radio-group/radio-group.d.ts +8 -1
  321. package/dist/types/components/router/router.d.ts +2 -1
  322. package/dist/types/components/select/select.d.ts +6 -1
  323. package/dist/types/components/skeleton-text/skeleton-text.d.ts +9 -1
  324. package/dist/types/components/textarea/textarea.d.ts +2 -0
  325. package/dist/types/components/toast/animations/utils.d.ts +15 -4
  326. package/dist/types/components/toast/gestures/swipe-to-dismiss.d.ts +9 -0
  327. package/dist/types/components/toast/toast-interface.d.ts +2 -0
  328. package/dist/types/components/toast/toast.d.ts +28 -1
  329. package/dist/types/components.d.ts +37 -6
  330. package/dist/types/interface.d.ts +1 -5
  331. package/dist/types/utils/animation/animation-interface.d.ts +4 -4
  332. package/dist/types/utils/browser/index.d.ts +11 -2
  333. package/dist/types/utils/forms/compare-with-utils.d.ts +18 -0
  334. package/dist/types/utils/forms/index.d.ts +1 -0
  335. package/dist/types/utils/hardware-back-button.d.ts +4 -0
  336. package/dist/types/utils/overlays.d.ts +1 -0
  337. package/dist/types/utils/slot-mutation-controller.d.ts +2 -2
  338. package/hydrate/index.js +639 -184
  339. package/package.json +2 -2
  340. package/dist/cjs/index-306a7476.js +0 -32
  341. package/dist/collection/components/item/test/text/item.e2e.js +0 -14
  342. package/dist/esm/index-7a14ecec.js +0 -29
  343. package/dist/esm-es5/index-0aa6e61f.js +0 -4
  344. package/dist/esm-es5/index-f0cc4e14.js +0 -4
  345. package/dist/esm-es5/input-shims-d0c93e5d.js +0 -4
  346. package/dist/esm-es5/input.utils-ec063df4.js +0 -4
  347. package/dist/esm-es5/md.transition-66f18369.js +0 -4
  348. package/dist/ionic/p-0d8e9393.entry.js +0 -4
  349. package/dist/ionic/p-19a7c660.system.entry.js +0 -4
  350. package/dist/ionic/p-1e5165db.system.entry.js +0 -4
  351. package/dist/ionic/p-20cf4994.js +0 -4
  352. package/dist/ionic/p-276afddd.js +0 -4
  353. package/dist/ionic/p-29adc040.entry.js +0 -4
  354. package/dist/ionic/p-2e8e0045.js +0 -4
  355. package/dist/ionic/p-352c0232.system.entry.js +0 -4
  356. package/dist/ionic/p-3602001b.system.js +0 -4
  357. package/dist/ionic/p-3632220b.system.js +0 -4
  358. package/dist/ionic/p-431151f2.entry.js +0 -4
  359. package/dist/ionic/p-4cd588b3.system.entry.js +0 -4
  360. package/dist/ionic/p-4d786d1f.system.entry.js +0 -4
  361. package/dist/ionic/p-4fa201a7.entry.js +0 -4
  362. package/dist/ionic/p-52360c7a.entry.js +0 -4
  363. package/dist/ionic/p-67aab78f.js +0 -4
  364. package/dist/ionic/p-67eecef4.system.js +0 -4
  365. package/dist/ionic/p-6d812360.system.entry.js +0 -4
  366. package/dist/ionic/p-7176cea3.entry.js +0 -4
  367. package/dist/ionic/p-77e7a9c8.entry.js +0 -4
  368. package/dist/ionic/p-86b2394a.entry.js +0 -4
  369. package/dist/ionic/p-8cbf0979.entry.js +0 -4
  370. package/dist/ionic/p-97c65aa5.js +0 -4
  371. package/dist/ionic/p-9ab6f3e6.system.js +0 -4
  372. package/dist/ionic/p-9b89cbde.js +0 -4
  373. package/dist/ionic/p-b0cee324.entry.js +0 -4
  374. package/dist/ionic/p-b1142133.entry.js +0 -4
  375. package/dist/ionic/p-c6be7737.system.entry.js +0 -4
  376. package/dist/ionic/p-cc196b34.js +0 -4
  377. package/dist/ionic/p-cd2808f5.system.entry.js +0 -4
  378. package/dist/ionic/p-d1de1188.js +0 -4
  379. package/dist/ionic/p-dfa756ed.system.js +0 -4
  380. package/dist/ionic/p-e6b240a0.js +0 -4
  381. package/dist/ionic/p-ee2469c1.entry.js +0 -4
  382. package/dist/ionic/p-ff5a10f9.system.js +0 -4
  383. /package/dist/esm-es5/{index-7a14ecec.js → index-a5d50daf.js} +0 -0
  384. /package/dist/esm-es5/{index-d1a56aed.js → index-c132c5f1.js} +0 -0
  385. /package/dist/ionic/{p-0e94957a.system.js → p-792919fd.system.js} +0 -0
  386. /package/dist/ionic/{p-b347cfd1.js → p-7b30edcc.js} +0 -0
  387. /package/dist/ionic/{p-84c6dece.system.js → p-8050b9b9.system.js} +0 -0
  388. /package/dist/ionic/{p-6e383534.js → p-ea96fa73.js} +0 -0
@@ -0,0 +1,51 @@
1
+ /*!
2
+ * (C) Ionic http://ionicframework.com - MIT License
3
+ */
4
+ import { expect } from "@playwright/test";
5
+ import { configs, test } from "../../../../utils/test/playwright/index";
6
+ configs().forEach(({ title, screenshot, config }) => {
7
+ test.describe(title('textarea: start and end slots (visual checks)'), () => {
8
+ test('should not have visual regressions with a start-positioned label', async ({ page }) => {
9
+ await page.setContent(`
10
+ <ion-textarea label-placement="start" fill="solid" value="100" label="Weight">
11
+ <ion-icon slot="start" name="barbell" aria-hidden="true"></ion-icon>
12
+ <ion-label slot="end">lbs</ion-label>
13
+ </ion-textarea>
14
+ `, config);
15
+ const textarea = page.locator('ion-textarea');
16
+ await expect(textarea).toHaveScreenshot(screenshot(`textarea-slots-label-start`));
17
+ });
18
+ test('should not have visual regressions with a floating label', async ({ page }) => {
19
+ await page.setContent(`
20
+ <ion-textarea label-placement="floating" fill="solid" value="100" label="Weight">
21
+ <ion-icon slot="start" name="barbell" aria-hidden="true"></ion-icon>
22
+ <ion-label slot="end">lbs</ion-label>
23
+ </ion-textarea>
24
+ `, config);
25
+ const textarea = page.locator('ion-textarea');
26
+ await expect(textarea).toHaveScreenshot(screenshot(`textarea-slots-label-floating`));
27
+ });
28
+ });
29
+ });
30
+ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
31
+ test.describe(title('textarea: start and end slots (functionality checks)'), () => {
32
+ test('should raise floating label when there is content in the start slot', async ({ page }) => {
33
+ await page.setContent(`
34
+ <ion-textarea label-placement="floating" fill="solid" label="Weight">
35
+ <ion-icon slot="start" name="barbell" aria-hidden="true"></ion-icon>
36
+ </ion-textarea>
37
+ `, config);
38
+ const textarea = page.locator('ion-textarea');
39
+ await expect(textarea).toHaveClass(/label-floating/);
40
+ });
41
+ test('should raise floating label when there is content in the end slot', async ({ page }) => {
42
+ await page.setContent(`
43
+ <ion-textarea label-placement="floating" fill="solid" label="Weight">
44
+ <ion-icon slot="end" name="barbell" aria-hidden="true"></ion-icon>
45
+ </ion-textarea>
46
+ `, config);
47
+ const textarea = page.locator('ion-textarea');
48
+ await expect(textarea).toHaveClass(/label-floating/);
49
+ });
50
+ });
51
+ });
@@ -356,9 +356,7 @@
356
356
  }
357
357
 
358
358
  .native-wrapper {
359
- display: flex;
360
359
  position: relative;
361
- flex-grow: 1;
362
360
  width: 100%;
363
361
  height: 100%;
364
362
  }
@@ -429,6 +427,12 @@
429
427
  word-break: break-word;
430
428
  }
431
429
 
430
+ .textarea-wrapper-inner {
431
+ display: flex;
432
+ width: 100%;
433
+ min-height: inherit;
434
+ }
435
+
432
436
  :host(.ion-touched.ion-invalid) {
433
437
  --highlight-color: var(--highlight-color-invalid);
434
438
  }
@@ -704,6 +708,13 @@
704
708
  margin-bottom: 0px;
705
709
  }
706
710
 
711
+ :host(.textarea-label-placement-stacked) ::slotted([slot=start]),
712
+ :host(.textarea-label-placement-stacked) ::slotted([slot=end]),
713
+ :host(.textarea-label-placement-floating) ::slotted([slot=start]),
714
+ :host(.textarea-label-placement-floating) ::slotted([slot=end]) {
715
+ margin-top: 8px;
716
+ }
717
+
707
718
  /**
708
719
  * This makes the label sit over the textarea
709
720
  * when the textarea is blurred and has no value.
@@ -729,9 +740,7 @@
729
740
  /**
730
741
  * This makes the label sit above the textarea.
731
742
  */
732
- :host(.textarea-label-placement-stacked) .label-text-wrapper,
733
- :host(.has-focus.textarea-label-placement-floating) .label-text-wrapper,
734
- :host(.has-value.textarea-label-placement-floating) .label-text-wrapper {
743
+ :host(.label-floating) .label-text-wrapper {
735
744
  transform: translateY(50%) scale(0.75);
736
745
  /**
737
746
  * Label text should not extend
@@ -740,6 +749,29 @@
740
749
  max-width: calc(100% / 0.75);
741
750
  }
742
751
 
752
+ .start-slot-wrapper, .end-slot-wrapper {
753
+ padding-left: 0;
754
+ padding-right: 0;
755
+ padding-top: var(--padding-top);
756
+ padding-bottom: var(--padding-bottom);
757
+ display: flex;
758
+ flex-shrink: 0;
759
+ align-self: start;
760
+ }
761
+
762
+ ::slotted([slot=start]),
763
+ ::slotted([slot=end]) {
764
+ margin-top: 0;
765
+ }
766
+
767
+ ::slotted([slot=start]) {
768
+ margin-inline-end: 16px;
769
+ }
770
+
771
+ ::slotted([slot=end]) {
772
+ margin-inline-start: 16px;
773
+ }
774
+
743
775
  /**
744
776
  * Convert a font size to a dynamic font size.
745
777
  * Fonts that participate in Dynamic Type should use
@@ -13,6 +13,8 @@ import { getCounterText } from "../input/input.utils";
13
13
  * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
14
14
  *
15
15
  * @slot label - The label text to associate with the textarea. Use the `labelPlacement` property to control where the label is placed relative to the textarea. Use this if you need to render a label with custom HTML. (EXPERIMENTAL)
16
+ * @slot start - Content to display at the leading edge of the textarea. (EXPERIMENTAL)
17
+ * @slot end - Content to display at the trailing edge of the textarea. (EXPERIMENTAL)
16
18
  */
17
19
  export class Textarea {
18
20
  constructor() {
@@ -121,7 +123,7 @@ export class Textarea {
121
123
  connectedCallback() {
122
124
  const { el } = this;
123
125
  this.legacyFormController = createLegacyFormController(el);
124
- this.slotMutationController = createSlotMutationController(el, 'label', () => forceUpdate(this));
126
+ this.slotMutationController = createSlotMutationController(el, ['label', 'start', 'end'], () => forceUpdate(this));
125
127
  this.notchController = createNotchController(el, () => this.notchSpacerEl, () => this.labelSlot);
126
128
  this.emitStyle();
127
129
  this.debounceChanged();
@@ -189,6 +191,8 @@ export class Textarea {
189
191
  'has-placeholder': this.placeholder !== undefined,
190
192
  'has-value': this.hasValue(),
191
193
  'has-focus': this.hasFocus,
194
+ // TODO(FW-2876): remove this
195
+ legacy: !!this.legacy,
192
196
  });
193
197
  }
194
198
  }
@@ -360,20 +364,41 @@ Developers can use the "legacy" property to continue using the legacy form marku
360
364
  return (h("div", { class: "textarea-bottom" }, this.renderHintText(), this.renderCounter()));
361
365
  }
362
366
  renderTextarea() {
363
- const { inputId, disabled, fill, shape, labelPlacement } = this;
367
+ const { inputId, disabled, fill, shape, labelPlacement, el, hasFocus } = this;
364
368
  const mode = getIonMode(this);
365
369
  const value = this.getValue();
366
370
  const inItem = hostContext('ion-item', this.el);
367
371
  const shouldRenderHighlight = mode === 'md' && fill !== 'outline' && !inItem;
372
+ const hasValue = this.hasValue();
373
+ const hasStartEndSlots = el.querySelector('[slot="start"], [slot="end"]') !== null;
374
+ /**
375
+ * If the label is stacked, it should always sit above the textarea.
376
+ * For floating labels, the label should move above the textarea if
377
+ * the textarea has a value, is focused, or has anything in either
378
+ * the start or end slot.
379
+ *
380
+ * If there is content in the start slot, the label would overlap
381
+ * it if not forced to float. This is also applied to the end slot
382
+ * because with the default or solid fills, the textarea is not
383
+ * vertically centered in the container, but the label is. This
384
+ * causes the slots and label to appear vertically offset from each
385
+ * other when the label isn't floating above the input. This doesn't
386
+ * apply to the outline fill, but this was not accounted for to keep
387
+ * things consistent.
388
+ *
389
+ * TODO(FW-5592): Remove hasStartEndSlots condition
390
+ */
391
+ const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
368
392
  return (h(Host, { class: createColorClasses(this.color, {
369
393
  [mode]: true,
370
- 'has-value': this.hasValue(),
371
- 'has-focus': this.hasFocus,
394
+ 'has-value': hasValue,
395
+ 'has-focus': hasFocus,
396
+ 'label-floating': labelShouldFloat,
372
397
  [`textarea-fill-${fill}`]: fill !== undefined,
373
398
  [`textarea-shape-${shape}`]: shape !== undefined,
374
399
  [`textarea-label-placement-${labelPlacement}`]: true,
375
400
  'textarea-disabled': disabled,
376
- }) }, h("label", { class: "textarea-wrapper" }, this.renderLabelContainer(), h("div", { class: "native-wrapper", ref: (el) => (this.textareaWrapper = el) }, h("textarea", Object.assign({ class: "native-textarea", ref: (el) => (this.nativeInput = el), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, minLength: this.minlength, maxLength: this.maxlength, name: this.name, placeholder: this.placeholder || '', readOnly: this.readonly, required: this.required, spellcheck: this.spellcheck, cols: this.cols, rows: this.rows, wrap: this.wrap, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeyDown }, this.inheritedAttributes), value)), shouldRenderHighlight && h("div", { class: "textarea-highlight" })), this.renderBottomContent()));
401
+ }) }, h("label", { class: "textarea-wrapper", htmlFor: inputId }, this.renderLabelContainer(), h("div", { class: "textarea-wrapper-inner" }, h("div", { class: "start-slot-wrapper" }, h("slot", { name: "start" })), h("div", { class: "native-wrapper", ref: (el) => (this.textareaWrapper = el) }, h("textarea", Object.assign({ class: "native-textarea", ref: (el) => (this.nativeInput = el), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, minLength: this.minlength, maxLength: this.maxlength, name: this.name, placeholder: this.placeholder || '', readOnly: this.readonly, required: this.required, spellcheck: this.spellcheck, cols: this.cols, rows: this.rows, wrap: this.wrap, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeyDown }, this.inheritedAttributes), value)), h("div", { class: "end-slot-wrapper" }, h("slot", { name: "end" }))), shouldRenderHighlight && h("div", { class: "textarea-highlight" })), this.renderBottomContent()));
377
402
  }
378
403
  render() {
379
404
  const { legacyFormController } = this;
@@ -356,9 +356,7 @@
356
356
  }
357
357
 
358
358
  .native-wrapper {
359
- display: flex;
360
359
  position: relative;
361
- flex-grow: 1;
362
360
  width: 100%;
363
361
  height: 100%;
364
362
  }
@@ -429,6 +427,12 @@
429
427
  word-break: break-word;
430
428
  }
431
429
 
430
+ .textarea-wrapper-inner {
431
+ display: flex;
432
+ width: 100%;
433
+ min-height: inherit;
434
+ }
435
+
432
436
  :host(.ion-touched.ion-invalid) {
433
437
  --highlight-color: var(--highlight-color-invalid);
434
438
  }
@@ -704,6 +708,13 @@
704
708
  margin-bottom: 0px;
705
709
  }
706
710
 
711
+ :host(.textarea-label-placement-stacked) ::slotted([slot=start]),
712
+ :host(.textarea-label-placement-stacked) ::slotted([slot=end]),
713
+ :host(.textarea-label-placement-floating) ::slotted([slot=start]),
714
+ :host(.textarea-label-placement-floating) ::slotted([slot=end]) {
715
+ margin-top: 8px;
716
+ }
717
+
707
718
  /**
708
719
  * This makes the label sit over the textarea
709
720
  * when the textarea is blurred and has no value.
@@ -729,9 +740,7 @@
729
740
  /**
730
741
  * This makes the label sit above the textarea.
731
742
  */
732
- :host(.textarea-label-placement-stacked) .label-text-wrapper,
733
- :host(.has-focus.textarea-label-placement-floating) .label-text-wrapper,
734
- :host(.has-value.textarea-label-placement-floating) .label-text-wrapper {
743
+ :host(.label-floating) .label-text-wrapper {
735
744
  transform: translateY(50%) scale(0.75);
736
745
  /**
737
746
  * Label text should not extend
@@ -740,6 +749,29 @@
740
749
  max-width: calc(100% / 0.75);
741
750
  }
742
751
 
752
+ .start-slot-wrapper, .end-slot-wrapper {
753
+ padding-left: 0;
754
+ padding-right: 0;
755
+ padding-top: var(--padding-top);
756
+ padding-bottom: var(--padding-bottom);
757
+ display: flex;
758
+ flex-shrink: 0;
759
+ align-self: start;
760
+ }
761
+
762
+ ::slotted([slot=start]),
763
+ ::slotted([slot=end]) {
764
+ margin-top: 0;
765
+ }
766
+
767
+ ::slotted([slot=start]) {
768
+ margin-inline-end: 16px;
769
+ }
770
+
771
+ ::slotted([slot=end]) {
772
+ margin-inline-start: 16px;
773
+ }
774
+
743
775
  /**
744
776
  * Convert a font size to a dynamic font size.
745
777
  * Fonts that participate in Dynamic Type should use
@@ -1037,9 +1069,7 @@
1037
1069
  }
1038
1070
  }
1039
1071
 
1040
- :host(.textarea-fill-solid.textarea-label-placement-stacked) .label-text-wrapper,
1041
- :host(.has-focus.textarea-fill-solid.textarea-label-placement-floating) .label-text-wrapper,
1042
- :host(.has-value.textarea-fill-solid.textarea-label-placement-floating) .label-text-wrapper {
1072
+ :host(.label-floating.textarea-fill-solid) .label-text-wrapper {
1043
1073
  /**
1044
1074
  * Label text should not extend
1045
1075
  * beyond the bounds of the textarea.
@@ -1193,9 +1223,7 @@
1193
1223
  /**
1194
1224
  * This makes the label sit above the textarea.
1195
1225
  */
1196
- :host(.has-focus.textarea-fill-outline.textarea-label-placement-floating) .label-text-wrapper,
1197
- :host(.has-value.textarea-fill-outline.textarea-label-placement-floating) .label-text-wrapper,
1198
- :host(.textarea-fill-outline.textarea-label-placement-stacked) .label-text-wrapper {
1226
+ :host(.label-floating.textarea-fill-outline) .label-text-wrapper {
1199
1227
  transform: translateY(-32%) scale(0.75);
1200
1228
  margin-left: 0;
1201
1229
  margin-right: 0;
@@ -1227,6 +1255,13 @@
1227
1255
  margin-bottom: 0px;
1228
1256
  }
1229
1257
 
1258
+ :host(.textarea-fill-outline.textarea-label-placement-stacked) ::slotted([slot=start]),
1259
+ :host(.textarea-fill-outline.textarea-label-placement-stacked) ::slotted([slot=end]),
1260
+ :host(.textarea-fill-outline.textarea-label-placement-floating) ::slotted([slot=start]),
1261
+ :host(.textarea-fill-outline.textarea-label-placement-floating) ::slotted([slot=end]) {
1262
+ margin-top: 12px;
1263
+ }
1264
+
1230
1265
  :host(.textarea-fill-outline) .textarea-outline-container {
1231
1266
  left: 0;
1232
1267
  right: 0;
@@ -1362,9 +1397,7 @@
1362
1397
  * the floating/stacked label. We simulate this "cut out"
1363
1398
  * by removing the top border from the notch fragment.
1364
1399
  */
1365
- :host(.has-focus.textarea-fill-outline.textarea-label-placement-floating) .textarea-outline-notch,
1366
- :host(.has-value.textarea-fill-outline.textarea-label-placement-floating) .textarea-outline-notch,
1367
- :host(.textarea-fill-outline.textarea-label-placement-stacked) .textarea-outline-notch {
1400
+ :host(.label-floating.textarea-fill-outline) .textarea-outline-notch {
1368
1401
  border-top: none;
1369
1402
  }
1370
1403
 
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import { createAnimation } from "../../../utils/animation/animation";
5
5
  import { getElementRoot } from "../../../utils/helpers";
6
+ import { getOffsetForMiddlePosition } from "./utils";
6
7
  /**
7
8
  * iOS Toast Enter Animation
8
9
  */
@@ -18,7 +19,7 @@ export const iosEnterAnimation = (baseEl, opts) => {
18
19
  wrapperAnimation.fromTo('transform', 'translateY(-100%)', `translateY(${top})`);
19
20
  break;
20
21
  case 'middle':
21
- const topPosition = Math.floor(baseEl.clientHeight / 2 - wrapperEl.clientHeight / 2);
22
+ const topPosition = getOffsetForMiddlePosition(baseEl.clientHeight, wrapperEl.clientHeight);
22
23
  wrapperEl.style.top = `${topPosition}px`;
23
24
  wrapperAnimation.fromTo('opacity', 0.01, 1);
24
25
  break;
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import { createAnimation } from "../../../utils/animation/animation";
5
5
  import { getElementRoot } from "../../../utils/helpers";
6
+ import { getOffsetForMiddlePosition } from "./utils";
6
7
  /**
7
8
  * MD Toast Enter Animation
8
9
  */
@@ -15,16 +16,16 @@ export const mdEnterAnimation = (baseEl, opts) => {
15
16
  wrapperAnimation.addElement(wrapperEl);
16
17
  switch (position) {
17
18
  case 'top':
18
- wrapperEl.style.top = top;
19
+ wrapperEl.style.setProperty('transform', `translateY(${top})`);
19
20
  wrapperAnimation.fromTo('opacity', 0.01, 1);
20
21
  break;
21
22
  case 'middle':
22
- const topPosition = Math.floor(baseEl.clientHeight / 2 - wrapperEl.clientHeight / 2);
23
+ const topPosition = getOffsetForMiddlePosition(baseEl.clientHeight, wrapperEl.clientHeight);
23
24
  wrapperEl.style.top = `${topPosition}px`;
24
25
  wrapperAnimation.fromTo('opacity', 0.01, 1);
25
26
  break;
26
27
  default:
27
- wrapperEl.style.bottom = bottom;
28
+ wrapperEl.style.setProperty('transform', `translateY(${bottom})`);
28
29
  wrapperAnimation.fromTo('opacity', 0.01, 1);
29
30
  break;
30
31
  }
@@ -7,10 +7,12 @@ import { printIonWarning } from "../../../utils/logging/index";
7
7
  * Calculate the CSS top and bottom position of the toast, to be used
8
8
  * as starting points for the animation keyframes.
9
9
  *
10
- * Note that MD animates bottom-positioned toasts using style.bottom,
11
- * which calculates from the bottom edge of the screen, while iOS uses
12
- * translateY, which calculates from the top edge of the screen. This
13
- * is why the bottom calculates differ slightly between modes.
10
+ * The default animations for both MD and iOS
11
+ * use translateY, which calculates from the
12
+ * top edge of the screen. This behavior impacts
13
+ * how we compute the offset when a toast has
14
+ * position='bottom' since we need to calculate from
15
+ * the bottom edge of the screen instead.
14
16
  *
15
17
  * @param position The value of the toast's position prop.
16
18
  * @param positionAnchor The element the toast should be anchored to,
@@ -25,7 +27,7 @@ export function getAnimationPosition(position, positionAnchor, mode, toast) {
25
27
  */
26
28
  let offset;
27
29
  if (mode === 'md') {
28
- offset = 8;
30
+ offset = position === 'top' ? 8 : -8;
29
31
  }
30
32
  else {
31
33
  offset = position === 'top' ? 10 : -10;
@@ -48,12 +50,7 @@ export function getAnimationPosition(position, positionAnchor, mode, toast) {
48
50
  * to the top edge of the anchor. We want to calculate from the
49
51
  * bottom edge of the screen instead.
50
52
  */
51
- if (mode === 'md') {
52
- offset += win.innerHeight - box.top;
53
- }
54
- else {
55
- offset -= win.innerHeight - box.top;
56
- }
53
+ offset -= win.innerHeight - box.top;
57
54
  }
58
55
  /**
59
56
  * We don't include safe area here because that should already be
@@ -67,9 +64,7 @@ export function getAnimationPosition(position, positionAnchor, mode, toast) {
67
64
  else {
68
65
  return {
69
66
  top: `calc(${offset}px + var(--ion-safe-area-top, 0px))`,
70
- bottom: mode === 'md'
71
- ? `calc(${offset}px + var(--ion-safe-area-bottom, 0px))`
72
- : `calc(${offset}px - var(--ion-safe-area-bottom, 0px))`,
67
+ bottom: `calc(${offset}px - var(--ion-safe-area-bottom, 0px))`,
73
68
  };
74
69
  }
75
70
  }
@@ -83,3 +78,14 @@ function warnIfAnchorIsHidden(positionAnchor, toast) {
83
78
  printIonWarning('The positionAnchor element for ion-toast was found in the DOM, but appears to be hidden. This may lead to unexpected positioning of the toast.', toast);
84
79
  }
85
80
  }
81
+ /**
82
+ * Returns the top offset required to place
83
+ * the toast in the middle of the screen.
84
+ * Only needed when position="toast".
85
+ * @param toastHeight - The height of the ion-toast element
86
+ * @param wrapperHeight - The height of the .toast-wrapper element
87
+ * inside the toast's shadow root.
88
+ */
89
+ export const getOffsetForMiddlePosition = (toastHeight, wrapperHeight) => {
90
+ return Math.floor(toastHeight / 2 - wrapperHeight / 2);
91
+ };