@ionic/core 9.0.0 → 9.0.1-dev.11787248963.10a00c73

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 (596) hide show
  1. package/components/index.js +1 -1
  2. package/components/ion-accordion-group.js +1 -1
  3. package/components/ion-accordion.js +1 -1
  4. package/components/ion-action-sheet.js +1 -1
  5. package/components/ion-alert.js +1 -1
  6. package/components/ion-app.js +1 -1
  7. package/components/ion-avatar.js +1 -1
  8. package/components/ion-back-button.js +1 -1
  9. package/components/ion-backdrop.js +1 -1
  10. package/components/ion-badge.js +1 -1
  11. package/components/ion-breadcrumb.js +1 -1
  12. package/components/ion-breadcrumbs.js +1 -1
  13. package/components/ion-button.js +1 -1
  14. package/components/ion-buttons.js +1 -1
  15. package/components/ion-card-content.js +1 -1
  16. package/components/ion-card-header.js +1 -1
  17. package/components/ion-card-subtitle.js +1 -1
  18. package/components/ion-card-title.js +1 -1
  19. package/components/ion-card.js +1 -1
  20. package/components/ion-checkbox.js +1 -1
  21. package/components/ion-chip.js +1 -1
  22. package/components/ion-col.js +1 -1
  23. package/components/ion-content.js +1 -1
  24. package/components/ion-datetime-button.js +1 -1
  25. package/components/ion-datetime.js +1 -1
  26. package/components/ion-fab-button.js +1 -1
  27. package/components/ion-fab-list.js +1 -1
  28. package/components/ion-fab.js +1 -1
  29. package/components/ion-footer.js +1 -1
  30. package/components/ion-grid.js +1 -1
  31. package/components/ion-header.js +1 -1
  32. package/components/ion-icon.js +1 -1
  33. package/components/ion-img.js +1 -1
  34. package/components/ion-infinite-scroll-content.js +1 -1
  35. package/components/ion-infinite-scroll.js +1 -1
  36. package/components/ion-input-otp.js +1 -1
  37. package/components/ion-input-password-toggle.js +1 -1
  38. package/components/ion-input.js +1 -1
  39. package/components/ion-item-divider.js +1 -1
  40. package/components/ion-item-group.js +1 -1
  41. package/components/ion-item-option.js +1 -1
  42. package/components/ion-item-options.js +1 -1
  43. package/components/ion-item-sliding.js +1 -1
  44. package/components/ion-item.js +1 -1
  45. package/components/ion-label.js +1 -1
  46. package/components/ion-list-header.js +1 -1
  47. package/components/ion-list.js +1 -1
  48. package/components/ion-loading.js +1 -1
  49. package/components/ion-menu-button.js +1 -1
  50. package/components/ion-menu-toggle.js +1 -1
  51. package/components/ion-menu.js +1 -1
  52. package/components/ion-modal.js +1 -1
  53. package/components/ion-nav-link.js +1 -1
  54. package/components/ion-nav.js +1 -1
  55. package/components/ion-note.js +1 -1
  56. package/components/ion-picker-column-option.js +1 -1
  57. package/components/ion-picker-column.js +1 -1
  58. package/components/ion-picker.js +1 -1
  59. package/components/ion-popover.js +1 -1
  60. package/components/ion-progress-bar.js +1 -1
  61. package/components/ion-radio-group.js +1 -1
  62. package/components/ion-radio.js +1 -1
  63. package/components/ion-range.js +1 -1
  64. package/components/ion-refresher-content.js +1 -1
  65. package/components/ion-refresher.js +1 -1
  66. package/components/ion-reorder-group.js +1 -1
  67. package/components/ion-reorder.js +1 -1
  68. package/components/ion-ripple-effect.js +1 -1
  69. package/components/ion-route-redirect.js +1 -1
  70. package/components/ion-route.js +1 -1
  71. package/components/ion-router-link.js +1 -1
  72. package/components/ion-router-outlet.js +1 -1
  73. package/components/ion-router.js +1 -1
  74. package/components/ion-row.js +1 -1
  75. package/components/ion-searchbar.js +1 -1
  76. package/components/ion-segment-button.js +1 -1
  77. package/components/ion-segment-content.js +1 -1
  78. package/components/ion-segment-view.js +1 -1
  79. package/components/ion-segment.js +1 -1
  80. package/components/ion-select-modal.js +1 -1
  81. package/components/ion-select-option.js +1 -1
  82. package/components/ion-select-popover.js +1 -1
  83. package/components/ion-select.js +1 -1
  84. package/components/ion-skeleton-text.js +1 -1
  85. package/components/ion-spinner.js +1 -1
  86. package/components/ion-split-pane.js +1 -1
  87. package/components/ion-tab-bar.js +1 -1
  88. package/components/ion-tab-button.js +1 -1
  89. package/components/ion-tab.js +1 -1
  90. package/components/ion-tabs.js +1 -1
  91. package/components/ion-text.js +1 -1
  92. package/components/ion-textarea.js +1 -1
  93. package/components/ion-thumbnail.js +1 -1
  94. package/components/ion-title.js +1 -1
  95. package/components/ion-toast.js +1 -1
  96. package/components/ion-toggle.js +1 -1
  97. package/components/ion-toolbar.js +1 -1
  98. package/components/{p-63OhffQv.js → p-66ogmUZU.js} +1 -1
  99. package/components/p-6Vp915Y7.js +4 -0
  100. package/components/p-7PNwKFZi.js +4 -0
  101. package/components/{p-G0TxqHfe.js → p-A8MJRBIY.js} +1 -1
  102. package/components/p-AQcCdH2_.js +4 -0
  103. package/{dist/ionic/p-Dn0mqQ_R.js → components/p-B6x5_b9w.js} +1 -1
  104. package/components/p-B8MQjdvk.js +4 -0
  105. package/components/p-BA_4ZIEg.js +4 -0
  106. package/components/p-BFtL8t1r.js +4 -0
  107. package/components/{p-DaA_8eqt.js → p-BMfgF-Tv.js} +1 -1
  108. package/components/p-BPDxVIRr.js +4 -0
  109. package/components/p-BSARlp49.js +4 -0
  110. package/components/p-B_gJaBk0.js +4 -0
  111. package/components/p-BdwCtX8Y.js +4 -0
  112. package/components/p-Bg4OwDwb.js +4 -0
  113. package/components/{p-DV85C0e0.js → p-BgUIV8NQ.js} +1 -1
  114. package/components/p-Bnc0m4SW.js +4 -0
  115. package/components/p-BpLt_Ptn.js +4 -0
  116. package/components/p-BqBDq1Ma.js +4 -0
  117. package/components/{p-C_phlPMC.js → p-BrFaQbGY.js} +1 -1
  118. package/{dist/ionic/p-Cdjxf_yg.js → components/p-BuPAFTWI.js} +1 -1
  119. package/components/p-Bx2saTHs.js +4 -0
  120. package/components/p-BxhE2W85.js +4 -0
  121. package/components/p-CHswSpKy.js +4 -0
  122. package/components/{p-fruGqVHh.js → p-CQAjyETU.js} +1 -1
  123. package/components/{p-1jI5oW-W.js → p-CR9OgE6N.js} +1 -1
  124. package/components/p-CWETxTjE.js +4 -0
  125. package/components/p-CaZeZIL2.js +4 -0
  126. package/components/p-CaiZOhfC.js +4 -0
  127. package/components/p-CgvDC7hC.js +4 -0
  128. package/components/{p-BqPNzJf6.js → p-CqyGR9Aq.js} +1 -1
  129. package/components/{p-UIBJkZf8.js → p-D0YpjgON.js} +1 -1
  130. package/components/p-D7ysFE2B.js +4 -0
  131. package/{dist/ionic/p-4eOQC00Z.js → components/p-DCWfzDM8.js} +1 -1
  132. package/components/{p-DwpKZ6rl.js → p-DDdkefwf.js} +1 -1
  133. package/components/{p-DzRT60Tw.js → p-DEW7CnUc.js} +1 -1
  134. package/components/p-DQ1IPvZO.js +4 -0
  135. package/components/p-DcOH6-o5.js +4 -0
  136. package/components/{p-DD5fQ4EQ.js → p-DfdYCsov.js} +1 -1
  137. package/components/{p-DSzSbVP2.js → p-DhOoEIAs.js} +1 -1
  138. package/components/{p-DM-PrAoh.js → p-Dl_7b_UJ.js} +1 -1
  139. package/components/p-DqAI6tg7.js +4 -0
  140. package/components/p-DrehWDfv.js +4 -0
  141. package/components/{p-ryyf_ItD.js → p-DysqCsJu.js} +1 -1
  142. package/components/p-H1f2qsk4.js +4 -0
  143. package/components/p-HVYBAhFx.js +4 -0
  144. package/components/{p-CbhUdtjf.js → p-Kmrg3Fed.js} +1 -1
  145. package/components/{p-Bjig0DJK.js → p-RFfE9hF6.js} +1 -1
  146. package/{dist/ionic/p-CBWAXjA5.js → components/p-SR-LLqp_.js} +1 -1
  147. package/components/p-eFI3mtEX.js +4 -0
  148. package/components/p-gFwXiYC_.js +4 -0
  149. package/components/p-tX3UxCnU.js +4 -0
  150. package/components/p-v2NpoOHp.js +4 -0
  151. package/dist/cjs/{animation-C0mOHzej.js → animation-D-OqR4a4.js} +1 -1
  152. package/dist/cjs/{app-globals-BREG4twP.js → app-globals-BzgwARwJ.js} +1 -1
  153. package/dist/cjs/{button-active-CVMevT9a.js → button-active-BlWSD7uK.js} +2 -2
  154. package/dist/cjs/{format-pp0Du3K-.js → format-D7ig6Vm0.js} +1 -1
  155. package/dist/cjs/{framework-delegate-Dfo5XsGv.js → framework-delegate-BZUx4TnE.js} +1 -1
  156. package/dist/cjs/{gesture-controller-BDUH7687.js → gesture-controller-CeJslptU.js} +6 -14
  157. package/dist/cjs/{hardware-back-button-fqpYh-kd.js → hardware-back-button-JOAEFSzc.js} +1 -1
  158. package/dist/cjs/{helpers-YPQybDph.js → helpers-Dj5o76mq.js} +1 -1
  159. package/dist/cjs/{index-BLdJCcJY.js → index-2sO-zkZ2.js} +4 -4
  160. package/dist/cjs/{index-uvry__L4.js → index-BrVMoqUk.js} +3 -1
  161. package/dist/cjs/{index-zVCah4Uz.js → index-C8zH6b3d.js} +2 -2
  162. package/dist/cjs/{index-DXsPSne6.js → index-CZ6vzt_q.js} +5 -5
  163. package/dist/cjs/{index-DDg31ZF5.js → index-Csue6G3m.js} +2 -2
  164. package/dist/cjs/{index-DwlRtFZe.js → index-DRPqwSvU.js} +1 -1
  165. package/dist/cjs/{index-B7zJsYWS.js → index-EJLjthTK.js} +1 -2
  166. package/dist/cjs/index.cjs.js +14 -14
  167. package/dist/cjs/{input-shims-Cbu1fcye.js → input-shims-Bh7bnt2v.js} +3 -3
  168. package/dist/cjs/{input.utils-BZdMWVrt.js → input.utils-Cq3g9uHy.js} +1 -1
  169. package/dist/cjs/ion-accordion_2.cjs.entry.js +335 -364
  170. package/dist/cjs/ion-action-sheet.cjs.entry.js +60 -140
  171. package/dist/cjs/ion-alert.cjs.entry.js +67 -159
  172. package/dist/cjs/ion-app_8.cjs.entry.js +163 -258
  173. package/dist/cjs/ion-avatar_3.cjs.entry.js +2 -8
  174. package/dist/cjs/ion-back-button.cjs.entry.js +21 -45
  175. package/dist/cjs/ion-backdrop.cjs.entry.js +14 -18
  176. package/dist/cjs/ion-breadcrumb_2.cjs.entry.js +117 -195
  177. package/dist/cjs/ion-button_2.cjs.entry.js +61 -130
  178. package/dist/cjs/ion-card_5.cjs.entry.js +28 -80
  179. package/dist/cjs/ion-checkbox.cjs.entry.js +98 -147
  180. package/dist/cjs/ion-chip.cjs.entry.js +10 -16
  181. package/dist/cjs/ion-col_3.cjs.entry.js +6 -126
  182. package/dist/cjs/ion-datetime-button.cjs.entry.js +232 -248
  183. package/dist/cjs/ion-datetime.cjs.entry.js +775 -953
  184. package/dist/cjs/ion-fab_3.cjs.entry.js +78 -136
  185. package/dist/cjs/ion-img.cjs.entry.js +11 -31
  186. package/dist/cjs/ion-infinite-scroll_2.cjs.entry.js +71 -98
  187. package/dist/cjs/ion-input-otp.cjs.entry.js +352 -424
  188. package/dist/cjs/ion-input-password-toggle.cjs.entry.js +14 -29
  189. package/dist/cjs/ion-input.cjs.entry.js +158 -302
  190. package/dist/cjs/ion-item-option_3.cjs.entry.js +54 -98
  191. package/dist/cjs/ion-item_8.cjs.entry.js +61 -157
  192. package/dist/cjs/ion-loading.cjs.entry.js +54 -131
  193. package/dist/cjs/ion-menu_3.cjs.entry.js +94 -158
  194. package/dist/cjs/ion-modal.cjs.entry.js +206 -362
  195. package/dist/cjs/ion-nav_2.cjs.entry.js +26 -78
  196. package/dist/cjs/ion-picker-column-option.cjs.entry.js +23 -33
  197. package/dist/cjs/ion-picker-column.cjs.entry.js +389 -410
  198. package/dist/cjs/ion-picker.cjs.entry.js +390 -400
  199. package/dist/cjs/ion-popover.cjs.entry.js +184 -292
  200. package/dist/cjs/ion-progress-bar.cjs.entry.js +23 -29
  201. package/dist/cjs/ion-radio_2.cjs.entry.js +128 -201
  202. package/dist/cjs/ion-range.cjs.entry.js +223 -293
  203. package/dist/cjs/ion-refresher_2.cjs.entry.js +89 -154
  204. package/dist/cjs/ion-reorder_2.cjs.entry.js +19 -49
  205. package/dist/cjs/ion-ripple-effect.cjs.entry.js +13 -13
  206. package/dist/cjs/ion-route_4.cjs.entry.js +45 -144
  207. package/dist/cjs/ion-searchbar.cjs.entry.js +182 -268
  208. package/dist/cjs/ion-segment-content.cjs.entry.js +1 -1
  209. package/dist/cjs/ion-segment-view.cjs.entry.js +12 -24
  210. package/dist/cjs/ion-segment_2.cjs.entry.js +122 -161
  211. package/dist/cjs/ion-select-modal.cjs.entry.js +19 -21
  212. package/dist/cjs/ion-select_3.cjs.entry.js +151 -319
  213. package/dist/cjs/ion-spinner.cjs.entry.js +6 -21
  214. package/dist/cjs/ion-split-pane.cjs.entry.js +14 -27
  215. package/dist/cjs/ion-tab-bar_2.cjs.entry.js +32 -89
  216. package/dist/cjs/ion-tab_2.cjs.entry.js +22 -49
  217. package/dist/cjs/ion-text.cjs.entry.js +2 -8
  218. package/dist/cjs/ion-textarea.cjs.entry.js +139 -256
  219. package/dist/cjs/ion-toast.cjs.entry.js +106 -221
  220. package/dist/cjs/ion-toggle.cjs.entry.js +114 -165
  221. package/dist/cjs/{ionic-global-k6hOWWpn.js → ionic-global-DvgIzM2F.js} +1 -1
  222. package/dist/cjs/ionic.cjs.js +4 -4
  223. package/dist/cjs/{ios.transition-zTmJz8T-.js → ios.transition-zIgdoSYe.js} +4 -4
  224. package/dist/cjs/{item-multiple-inputs-BdYSbfKN.js → item-multiple-inputs-DG-ZGm6j.js} +1 -1
  225. package/dist/cjs/loader.cjs.js +4 -4
  226. package/dist/cjs/{md.transition-nb_4pUXu.js → md.transition-CXeJ9rfh.js} +4 -4
  227. package/dist/cjs/{overlays-KaNVDNqC.js → overlays-Bg0auTQa.js} +6 -6
  228. package/dist/cjs/{select-option-render-pULCGldr.js → select-option-render-7m1WdFzF.js} +2 -2
  229. package/dist/cjs/{slot-mutation-controller-DPHmqXdV.js → slot-mutation-controller-BJEJzx_e.js} +1 -1
  230. package/dist/cjs/{status-tap-o9IIymsP.js → status-tap-DxbUM5XX.js} +3 -3
  231. package/dist/cjs/{swipe-back-B7X9VOlH.js → swipe-back-F_DBt-Aw.js} +4 -4
  232. package/dist/collection/components/accordion/accordion.js +310 -314
  233. package/dist/collection/components/accordion-group/accordion-group.js +23 -46
  234. package/dist/collection/components/action-sheet/action-sheet.js +49 -128
  235. package/dist/collection/components/action-sheet/test/basic/fixture.js +0 -3
  236. package/dist/collection/components/alert/alert.js +56 -147
  237. package/dist/collection/components/app/app.js +0 -3
  238. package/dist/collection/components/back-button/back-button.js +19 -42
  239. package/dist/collection/components/backdrop/backdrop.js +14 -16
  240. package/dist/collection/components/badge/badge.js +0 -6
  241. package/dist/collection/components/breadcrumb/breadcrumb.js +29 -90
  242. package/dist/collection/components/breadcrumbs/breadcrumbs.js +87 -102
  243. package/dist/collection/components/button/button.js +59 -127
  244. package/dist/collection/components/buttons/buttons.js +15 -13
  245. package/dist/collection/components/card/card.js +20 -53
  246. package/dist/collection/components/card-header/card-header.js +8 -12
  247. package/dist/collection/components/card-subtitle/card-subtitle.js +0 -6
  248. package/dist/collection/components/card-title/card-title.js +0 -6
  249. package/dist/collection/components/checkbox/checkbox.js +95 -143
  250. package/dist/collection/components/chip/chip.js +10 -14
  251. package/dist/collection/components/col/col.js +0 -120
  252. package/dist/collection/components/content/content.js +60 -90
  253. package/dist/collection/components/datetime/datetime.js +762 -939
  254. package/dist/collection/components/datetime-button/datetime-button.js +229 -244
  255. package/dist/collection/components/fab/fab.js +13 -20
  256. package/dist/collection/components/fab-button/fab-button.js +54 -103
  257. package/dist/collection/components/fab-list/fab-list.js +11 -10
  258. package/dist/collection/components/footer/footer.js +43 -49
  259. package/dist/collection/components/grid/grid.js +6 -4
  260. package/dist/collection/components/header/header.js +23 -33
  261. package/dist/collection/components/img/img.js +9 -28
  262. package/dist/collection/components/infinite-scroll/infinite-scroll.js +66 -73
  263. package/dist/collection/components/infinite-scroll-content/infinite-scroll-content.js +3 -20
  264. package/dist/collection/components/input/input.js +154 -297
  265. package/dist/collection/components/input-otp/input-otp.js +350 -421
  266. package/dist/collection/components/input-password-toggle/input-password-toggle.js +13 -27
  267. package/dist/collection/components/item/item.js +37 -80
  268. package/dist/collection/components/item-divider/item-divider.js +10 -15
  269. package/dist/collection/components/item-option/item-option.js +20 -48
  270. package/dist/collection/components/item-options/item-options.js +7 -10
  271. package/dist/collection/components/item-sliding/item-sliding.js +26 -36
  272. package/dist/collection/components/label/label.js +4 -24
  273. package/dist/collection/components/list/list.js +6 -9
  274. package/dist/collection/components/list-header/list-header.js +0 -10
  275. package/dist/collection/components/loading/loading.js +46 -122
  276. package/dist/collection/components/menu/menu.js +55 -99
  277. package/dist/collection/components/menu-button/menu-button.js +19 -28
  278. package/dist/collection/components/menu-toggle/menu-toggle.js +13 -20
  279. package/dist/collection/components/modal/modal.js +196 -351
  280. package/dist/collection/components/modal/test/fixtures.js +0 -3
  281. package/dist/collection/components/nav/nav.js +12 -45
  282. package/dist/collection/components/nav/view-controller.js +1 -7
  283. package/dist/collection/components/nav-link/nav-link.js +9 -20
  284. package/dist/collection/components/note/note.js +0 -6
  285. package/dist/collection/components/picker/picker.js +388 -397
  286. package/dist/collection/components/picker-column/picker-column.js +389 -409
  287. package/dist/collection/components/picker-column-option/picker-column-option.js +21 -30
  288. package/dist/collection/components/popover/popover.js +176 -283
  289. package/dist/collection/components/popover/test/fixture.js +0 -1
  290. package/dist/collection/components/progress-bar/progress-bar.js +22 -26
  291. package/dist/collection/components/radio/radio.js +62 -98
  292. package/dist/collection/components/radio-group/radio-group.js +64 -99
  293. package/dist/collection/components/radio-group/test/fixtures.js +0 -2
  294. package/dist/collection/components/range/range.js +220 -289
  295. package/dist/collection/components/refresher/refresher.js +79 -105
  296. package/dist/collection/components/refresher-content/refresher-content.js +3 -40
  297. package/dist/collection/components/reorder/reorder.js +0 -1
  298. package/dist/collection/components/reorder-group/reorder-group.js +14 -43
  299. package/dist/collection/components/ripple-effect/ripple-effect.js +12 -11
  300. package/dist/collection/components/route/route.js +9 -38
  301. package/dist/collection/components/route-redirect/route-redirect.js +0 -31
  302. package/dist/collection/components/router/router.js +27 -35
  303. package/dist/collection/components/router/utils/matching.js +0 -1
  304. package/dist/collection/components/router-link/router-link.js +10 -35
  305. package/dist/collection/components/router-outlet/router-outlet.js +12 -34
  306. package/dist/collection/components/searchbar/searchbar.js +180 -265
  307. package/dist/collection/components/segment/segment.js +76 -113
  308. package/dist/collection/components/segment-button/segment-button.js +44 -44
  309. package/dist/collection/components/segment-view/segment-view.js +12 -23
  310. package/dist/collection/components/select/select.js +127 -240
  311. package/dist/collection/components/select-modal/select-modal.js +11 -12
  312. package/dist/collection/components/select-modal/test/fixtures.js +1 -8
  313. package/dist/collection/components/select-option/select-option.js +7 -44
  314. package/dist/collection/components/select-popover/select-popover.js +10 -25
  315. package/dist/collection/components/select-popover/test/fixtures.js +1 -8
  316. package/dist/collection/components/skeleton-text/skeleton-text.js +6 -10
  317. package/dist/collection/components/spinner/spinner.js +6 -19
  318. package/dist/collection/components/split-pane/split-pane.js +13 -25
  319. package/dist/collection/components/tab/tab.js +4 -15
  320. package/dist/collection/components/tab-bar/tab-bar.js +12 -30
  321. package/dist/collection/components/tab-button/tab-button.js +19 -56
  322. package/dist/collection/components/tabs/tabs.js +17 -31
  323. package/dist/collection/components/text/text.js +0 -6
  324. package/dist/collection/components/textarea/textarea.js +135 -251
  325. package/dist/collection/components/title/title.js +0 -16
  326. package/dist/collection/components/toast/toast.js +97 -211
  327. package/dist/collection/components/toggle/toggle.js +111 -161
  328. package/dist/collection/components/toolbar/toolbar.js +3 -8
  329. package/dist/collection/global/config.js +3 -1
  330. package/dist/collection/utils/gesture/gesture-controller.js +6 -14
  331. package/dist/collection/utils/sanitization/index.js +0 -1
  332. package/dist/collection/utils/test/late-props/late-props.js +69 -0
  333. package/dist/collection/utils/test/playwright/page/event-spy.js +8 -9
  334. package/dist/collection/utils/test/press-keys.js +1 -4
  335. package/dist/docs.json +1 -1
  336. package/dist/esm/{animation-CGFdmGk9.js → animation-TxGPYeDn.js} +1 -1
  337. package/dist/esm/{app-globals-CYmMeGdU.js → app-globals-Do8rJest.js} +1 -1
  338. package/dist/esm/{button-active-BDOsVAiZ.js → button-active-ChA4D-ml.js} +2 -2
  339. package/dist/esm/{format-Dcwga61t.js → format-CVk5e_GP.js} +2 -2
  340. package/dist/esm/{framework-delegate-BHTU2Ip9.js → framework-delegate-DaLWnISz.js} +1 -1
  341. package/dist/esm/{gesture-controller-TXPDHL13.js → gesture-controller-B_gJaBk0.js} +6 -14
  342. package/dist/esm/{hardware-back-button-gLJHMX_F.js → hardware-back-button-D8W4L0JP.js} +1 -1
  343. package/dist/esm/{helpers-CAGf8Wgp.js → helpers-BIgoInJU.js} +1 -1
  344. package/dist/esm/{index-DcPaH5uL.js → index-BmLuEdV7.js} +1 -1
  345. package/dist/esm/{index-T0JxBI8V.js → index-BmOR8tCv.js} +2 -2
  346. package/dist/esm/{index-CqneaaGd.js → index-C5ZdL0qp.js} +5 -5
  347. package/dist/esm/{index-WlteAIqz.js → index-C8Dsa6li.js} +4 -4
  348. package/dist/esm/{index-ChhhtsGZ.js → index-CKYcsw8f.js} +3 -1
  349. package/dist/esm/{index-Clc-28O1.js → index-DHw2lZxe.js} +2 -2
  350. package/dist/esm/{index-CKM1DdGm.js → index-elneMH8y.js} +1 -2
  351. package/dist/esm/index.js +14 -14
  352. package/dist/esm/{input-shims-B8sfni1e.js → input-shims-09NN97kF.js} +3 -3
  353. package/dist/esm/{input.utils-B1ValN_N.js → input.utils-BxyH9l1w.js} +1 -1
  354. package/dist/esm/ion-accordion_2.entry.js +335 -364
  355. package/dist/esm/ion-action-sheet.entry.js +60 -140
  356. package/dist/esm/ion-alert.entry.js +67 -159
  357. package/dist/esm/ion-app_8.entry.js +163 -258
  358. package/dist/esm/ion-avatar_3.entry.js +2 -8
  359. package/dist/esm/ion-back-button.entry.js +21 -45
  360. package/dist/esm/ion-backdrop.entry.js +14 -18
  361. package/dist/esm/ion-breadcrumb_2.entry.js +117 -195
  362. package/dist/esm/ion-button_2.entry.js +61 -130
  363. package/dist/esm/ion-card_5.entry.js +28 -80
  364. package/dist/esm/ion-checkbox.entry.js +98 -147
  365. package/dist/esm/ion-chip.entry.js +10 -16
  366. package/dist/esm/ion-col_3.entry.js +6 -126
  367. package/dist/esm/ion-datetime-button.entry.js +232 -248
  368. package/dist/esm/ion-datetime.entry.js +775 -953
  369. package/dist/esm/ion-fab_3.entry.js +78 -136
  370. package/dist/esm/ion-img.entry.js +11 -31
  371. package/dist/esm/ion-infinite-scroll_2.entry.js +71 -98
  372. package/dist/esm/ion-input-otp.entry.js +352 -424
  373. package/dist/esm/ion-input-password-toggle.entry.js +14 -29
  374. package/dist/esm/ion-input.entry.js +158 -302
  375. package/dist/esm/ion-item-option_3.entry.js +54 -98
  376. package/dist/esm/ion-item_8.entry.js +61 -157
  377. package/dist/esm/ion-loading.entry.js +54 -131
  378. package/dist/esm/ion-menu_3.entry.js +94 -158
  379. package/dist/esm/ion-modal.entry.js +206 -362
  380. package/dist/esm/ion-nav_2.entry.js +26 -78
  381. package/dist/esm/ion-picker-column-option.entry.js +23 -33
  382. package/dist/esm/ion-picker-column.entry.js +389 -410
  383. package/dist/esm/ion-picker.entry.js +390 -400
  384. package/dist/esm/ion-popover.entry.js +184 -292
  385. package/dist/esm/ion-progress-bar.entry.js +23 -29
  386. package/dist/esm/ion-radio_2.entry.js +128 -201
  387. package/dist/esm/ion-range.entry.js +223 -293
  388. package/dist/esm/ion-refresher_2.entry.js +89 -154
  389. package/dist/esm/ion-reorder_2.entry.js +19 -49
  390. package/dist/esm/ion-ripple-effect.entry.js +13 -13
  391. package/dist/esm/ion-route_4.entry.js +45 -144
  392. package/dist/esm/ion-searchbar.entry.js +182 -268
  393. package/dist/esm/ion-segment-content.entry.js +1 -1
  394. package/dist/esm/ion-segment-view.entry.js +12 -24
  395. package/dist/esm/ion-segment_2.entry.js +122 -161
  396. package/dist/esm/ion-select-modal.entry.js +19 -21
  397. package/dist/esm/ion-select_3.entry.js +151 -319
  398. package/dist/esm/ion-spinner.entry.js +6 -21
  399. package/dist/esm/ion-split-pane.entry.js +14 -27
  400. package/dist/esm/ion-tab-bar_2.entry.js +32 -89
  401. package/dist/esm/ion-tab_2.entry.js +22 -49
  402. package/dist/esm/ion-text.entry.js +2 -8
  403. package/dist/esm/ion-textarea.entry.js +139 -256
  404. package/dist/esm/ion-toast.entry.js +106 -221
  405. package/dist/esm/ion-toggle.entry.js +114 -165
  406. package/dist/esm/{ionic-global-BVB7BrLT.js → ionic-global-lrowsHfi.js} +1 -1
  407. package/dist/esm/ionic.js +5 -5
  408. package/dist/esm/{ios.transition-DXRCmcbC.js → ios.transition-BQhADrk1.js} +4 -4
  409. package/dist/esm/{item-multiple-inputs-rU8VaNNg.js → item-multiple-inputs-D_N3fDkD.js} +1 -1
  410. package/dist/esm/loader.js +5 -5
  411. package/dist/esm/{md.transition-BMngO4i_.js → md.transition-D58NpmRa.js} +4 -4
  412. package/dist/esm/{overlays-CPmIs9Ls.js → overlays-BpnIFlXI.js} +6 -6
  413. package/dist/esm/{select-option-render-C4m76VGH.js → select-option-render-lIuu64EV.js} +2 -2
  414. package/dist/esm/{slot-mutation-controller-DiE_C9un.js → slot-mutation-controller-rS_T3FDR.js} +1 -1
  415. package/dist/esm/{status-tap-CHB7KwIb.js → status-tap-CpFQMLl6.js} +3 -3
  416. package/dist/esm/{swipe-back-C9HW1bug.js → swipe-back-rmc7zeNW.js} +4 -4
  417. package/dist/ionic/index.esm.js +1 -1
  418. package/dist/ionic/ionic.esm.js +1 -1
  419. package/dist/ionic/p-05800a02.entry.js +4 -0
  420. package/dist/ionic/p-0eb50dca.entry.js +4 -0
  421. package/dist/ionic/p-16e9f542.entry.js +4 -0
  422. package/dist/ionic/p-18d532a3.entry.js +4 -0
  423. package/dist/ionic/p-1db2afb4.entry.js +4 -0
  424. package/dist/ionic/p-1df75f9e.entry.js +4 -0
  425. package/dist/ionic/p-295ff427.entry.js +4 -0
  426. package/dist/ionic/p-34b9379b.entry.js +4 -0
  427. package/dist/ionic/p-39a8d4e0.entry.js +4 -0
  428. package/dist/ionic/p-4437015c.entry.js +4 -0
  429. package/dist/ionic/p-478035a7.entry.js +4 -0
  430. package/dist/ionic/p-485fb218.entry.js +4 -0
  431. package/dist/ionic/p-48c859fe.entry.js +4 -0
  432. package/dist/ionic/p-49b9d405.entry.js +4 -0
  433. package/dist/ionic/p-56307aea.entry.js +4 -0
  434. package/dist/ionic/p-5b906fd6.entry.js +4 -0
  435. package/dist/ionic/p-5ee2d7b1.entry.js +4 -0
  436. package/dist/ionic/p-5f216b79.entry.js +4 -0
  437. package/dist/ionic/p-61c799d1.entry.js +4 -0
  438. package/dist/ionic/p-63bbba8d.entry.js +4 -0
  439. package/dist/ionic/p-68507e70.entry.js +4 -0
  440. package/dist/ionic/{p-ded69ceb.entry.js → p-6f048604.entry.js} +1 -1
  441. package/dist/ionic/p-70ee8888.entry.js +4 -0
  442. package/dist/ionic/p-72ad7c64.entry.js +4 -0
  443. package/dist/ionic/p-75887ee0.entry.js +4 -0
  444. package/dist/ionic/p-873a315a.entry.js +4 -0
  445. package/dist/ionic/p-881b6954.entry.js +4 -0
  446. package/dist/ionic/p-886d9e66.entry.js +4 -0
  447. package/dist/ionic/p-8dd4c026.entry.js +4 -0
  448. package/dist/ionic/p-8e007f11.entry.js +4 -0
  449. package/dist/ionic/p-8f51110d.entry.js +4 -0
  450. package/dist/ionic/p-90ba736e.entry.js +4 -0
  451. package/dist/ionic/p-959df5f8.entry.js +4 -0
  452. package/dist/ionic/p-9e455875.entry.js +4 -0
  453. package/dist/ionic/{p-CBR_W98Z.js → p-9wczfs_v.js} +1 -1
  454. package/dist/ionic/p-B1Y7LZhV.js +4 -0
  455. package/dist/ionic/p-B5RyLYvl.js +4 -0
  456. package/dist/ionic/{p-CPcPmkGv.js → p-BQv5i5Kf.js} +1 -1
  457. package/{components/p-8FN7p701.js → dist/ionic/p-BZVE25Gu.js} +1 -1
  458. package/{components/p-DFvZn99E.js → dist/ionic/p-BZxjcGRP.js} +1 -1
  459. package/dist/ionic/p-B_gJaBk0.js +4 -0
  460. package/dist/ionic/p-BnGA34Pd.js +4 -0
  461. package/dist/ionic/p-ByLaqOPm.js +4 -0
  462. package/dist/ionic/p-C06QNN45.js +4 -0
  463. package/dist/ionic/p-C4IBDDj6.js +4 -0
  464. package/dist/ionic/p-CCVlNZ__.js +4 -0
  465. package/dist/ionic/{p-CMRtMbJc.js → p-CDBop-kz.js} +1 -1
  466. package/dist/ionic/p-CKYcsw8f.js +5 -0
  467. package/dist/ionic/p-CazSodad.js +4 -0
  468. package/{components/p-ia3IDdJS.js → dist/ionic/p-ClrlQU2y.js} +1 -1
  469. package/dist/ionic/{p-UIBJkZf8.js → p-D0YpjgON.js} +1 -1
  470. package/dist/ionic/p-D0dfUysx.js +4 -0
  471. package/dist/ionic/{p-BB0LlG4y.js → p-D9yvytgv.js} +1 -1
  472. package/{components/p-C5KYjZWD.js → dist/ionic/p-DF_Uqql8.js} +1 -1
  473. package/dist/ionic/{p-BYEAtHr-.js → p-DXJgZWgi.js} +1 -1
  474. package/dist/ionic/{p-D94_RztK.js → p-DdhHqKj-.js} +1 -1
  475. package/dist/ionic/p-De0eY881.js +4 -0
  476. package/dist/ionic/p-DgUL3JbO.js +4 -0
  477. package/dist/ionic/{p-7CBuOvEo.js → p-RzUn7cKs.js} +1 -1
  478. package/dist/ionic/p-VquyMbjp.js +4 -0
  479. package/dist/ionic/p-a0fee899.entry.js +4 -0
  480. package/dist/ionic/p-a54bcd16.entry.js +4 -0
  481. package/dist/ionic/p-aebc4d69.entry.js +4 -0
  482. package/dist/ionic/p-b5f37106.entry.js +4 -0
  483. package/dist/ionic/{p-40424a88.entry.js → p-b62bfce8.entry.js} +1 -1
  484. package/dist/ionic/p-b7a11b58.entry.js +4 -0
  485. package/dist/ionic/p-bbf6878c.entry.js +4 -0
  486. package/dist/ionic/p-c49165af.entry.js +4 -0
  487. package/dist/ionic/p-cad4eccf.entry.js +4 -0
  488. package/dist/ionic/p-cdc5115e.entry.js +4 -0
  489. package/dist/ionic/p-d3384a40.entry.js +4 -0
  490. package/dist/ionic/p-d8bae128.entry.js +4 -0
  491. package/dist/ionic/p-d8deff43.entry.js +4 -0
  492. package/dist/ionic/p-ddfb7e5f.entry.js +4 -0
  493. package/dist/ionic/p-e538f18d.entry.js +4 -0
  494. package/dist/ionic/p-f376876b.entry.js +4 -0
  495. package/dist/ionic/p-f7dd1ed9.entry.js +4 -0
  496. package/dist/ionic/p-fbd83d4c.entry.js +4 -0
  497. package/dist/types/components/refresher/refresher.d.ts +7 -0
  498. package/hydrate/index.js +5450 -8380
  499. package/hydrate/index.mjs +5450 -8380
  500. package/package.json +1 -1
  501. package/components/p--m5cCjbK.js +0 -4
  502. package/components/p-B4uHHhPK.js +0 -4
  503. package/components/p-BNJOu1Q2.js +0 -4
  504. package/components/p-BOvLNVKq.js +0 -4
  505. package/components/p-BeamQXHF.js +0 -4
  506. package/components/p-BjluhQMI.js +0 -4
  507. package/components/p-BlsIikdZ.js +0 -4
  508. package/components/p-BrD9Xv62.js +0 -4
  509. package/components/p-BvJqoZ5R.js +0 -4
  510. package/components/p-Bz6z3Asd.js +0 -4
  511. package/components/p-C6HnVvHO.js +0 -4
  512. package/components/p-C7jvh5Wy.js +0 -4
  513. package/components/p-C9BGR5fy.js +0 -4
  514. package/components/p-CB-y1CdP.js +0 -4
  515. package/components/p-CHH3loEE.js +0 -4
  516. package/components/p-CJKUWjmg.js +0 -4
  517. package/components/p-CMLAwl_N.js +0 -4
  518. package/components/p-CejmQs3h.js +0 -4
  519. package/components/p-CtZqa4HM.js +0 -4
  520. package/components/p-D9qIVSWm.js +0 -4
  521. package/components/p-DE-3iMNW.js +0 -4
  522. package/components/p-DHFt2rdc.js +0 -4
  523. package/components/p-D_RCyzwu.js +0 -4
  524. package/components/p-D_tD8r3L.js +0 -4
  525. package/components/p-DjCtLZbF.js +0 -4
  526. package/components/p-Dmd2xqCe.js +0 -4
  527. package/components/p-G6JR-cr_.js +0 -4
  528. package/components/p-GG5GhznE.js +0 -4
  529. package/components/p-TXPDHL13.js +0 -4
  530. package/components/p-_IKFD3ID.js +0 -4
  531. package/components/p-dKq2jIum.js +0 -4
  532. package/components/p-iYhH60Tc.js +0 -4
  533. package/dist/ionic/p-06ec7136.entry.js +0 -4
  534. package/dist/ionic/p-09fe4fa3.entry.js +0 -4
  535. package/dist/ionic/p-10d45a07.entry.js +0 -4
  536. package/dist/ionic/p-208c8a07.entry.js +0 -4
  537. package/dist/ionic/p-212474fa.entry.js +0 -4
  538. package/dist/ionic/p-2eef1396.entry.js +0 -4
  539. package/dist/ionic/p-347e005d.entry.js +0 -4
  540. package/dist/ionic/p-3a0b3f1d.entry.js +0 -4
  541. package/dist/ionic/p-3b071259.entry.js +0 -4
  542. package/dist/ionic/p-4204184c.entry.js +0 -4
  543. package/dist/ionic/p-47464391.entry.js +0 -4
  544. package/dist/ionic/p-4f9c9126.entry.js +0 -4
  545. package/dist/ionic/p-5JsKPLJD.js +0 -4
  546. package/dist/ionic/p-5bc485c6.entry.js +0 -4
  547. package/dist/ionic/p-603a61e6.entry.js +0 -4
  548. package/dist/ionic/p-60576951.entry.js +0 -4
  549. package/dist/ionic/p-67a81d33.entry.js +0 -4
  550. package/dist/ionic/p-6affb775.entry.js +0 -4
  551. package/dist/ionic/p-6f120c25.entry.js +0 -4
  552. package/dist/ionic/p-71c82b60.entry.js +0 -4
  553. package/dist/ionic/p-79325ffe.entry.js +0 -4
  554. package/dist/ionic/p-7e4d51fa.entry.js +0 -4
  555. package/dist/ionic/p-7f5d4664.entry.js +0 -4
  556. package/dist/ionic/p-80ee82fc.entry.js +0 -4
  557. package/dist/ionic/p-84af7dbc.entry.js +0 -4
  558. package/dist/ionic/p-89ca830a.entry.js +0 -4
  559. package/dist/ionic/p-93b8ec8f.entry.js +0 -4
  560. package/dist/ionic/p-946f65c2.entry.js +0 -4
  561. package/dist/ionic/p-9c4b39fb.entry.js +0 -4
  562. package/dist/ionic/p-B1NEZUzQ.js +0 -4
  563. package/dist/ionic/p-B1ck5iy-.js +0 -4
  564. package/dist/ionic/p-B4FrqdW0.js +0 -4
  565. package/dist/ionic/p-C-94tAim.js +0 -4
  566. package/dist/ionic/p-C-eHZMYE.js +0 -4
  567. package/dist/ionic/p-CaRuIadB.js +0 -4
  568. package/dist/ionic/p-ChhhtsGZ.js +0 -5
  569. package/dist/ionic/p-CzS1qWve.js +0 -4
  570. package/dist/ionic/p-DjjfauRM.js +0 -4
  571. package/dist/ionic/p-DkUB-ROc.js +0 -4
  572. package/dist/ionic/p-DplOqGUv.js +0 -4
  573. package/dist/ionic/p-Dst_XmZh.js +0 -4
  574. package/dist/ionic/p-TXPDHL13.js +0 -4
  575. package/dist/ionic/p-a438b193.entry.js +0 -4
  576. package/dist/ionic/p-babaaaa7.entry.js +0 -4
  577. package/dist/ionic/p-be08d500.entry.js +0 -4
  578. package/dist/ionic/p-be9a4f51.entry.js +0 -4
  579. package/dist/ionic/p-c00d3092.entry.js +0 -4
  580. package/dist/ionic/p-c36dc8f5.entry.js +0 -4
  581. package/dist/ionic/p-c72a7e17.entry.js +0 -4
  582. package/dist/ionic/p-c8edd88c.entry.js +0 -4
  583. package/dist/ionic/p-ce0e380b.entry.js +0 -4
  584. package/dist/ionic/p-ce32912b.entry.js +0 -4
  585. package/dist/ionic/p-d07cf130.entry.js +0 -4
  586. package/dist/ionic/p-d27edeb3.entry.js +0 -4
  587. package/dist/ionic/p-d5d2c506.entry.js +0 -4
  588. package/dist/ionic/p-d5e31ca9.entry.js +0 -4
  589. package/dist/ionic/p-de91444f.entry.js +0 -4
  590. package/dist/ionic/p-df72866d.entry.js +0 -4
  591. package/dist/ionic/p-e47e3151.entry.js +0 -4
  592. package/dist/ionic/p-e621e5e8.entry.js +0 -4
  593. package/dist/ionic/p-eea9cf93.entry.js +0 -4
  594. package/dist/ionic/p-f402f5a4.entry.js +0 -4
  595. package/dist/ionic/p-fe1bfbcf.entry.js +0 -4
  596. package/dist/ionic/p-ffb90460.entry.js +0 -4
@@ -1,19 +1,19 @@
1
1
  /*!
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
- import { j as printIonError, f as printIonWarning, r as registerInstance, c as createEvent, g as getElement, w as writeTask, e as config, h, d as Host } from './index-ChhhtsGZ.js';
4
+ import { j as printIonError, f as printIonWarning, r as registerInstance, c as createEvent, w as writeTask, e as config, h, d as Host, g as getElement } from './index-CKYcsw8f.js';
5
5
  import { startFocusVisible } from './focus-visible-BmVRXR1y.js';
6
- import { r as raf, g as getElementRoot, a as renderHiddenInput } from './helpers-CAGf8Wgp.js';
7
- import { F as FOCUS_TRAP_DISABLE_CLASS } from './overlays-CPmIs9Ls.js';
6
+ import { r as raf, g as getElementRoot, a as renderHiddenInput } from './helpers-BIgoInJU.js';
7
+ import { F as FOCUS_TRAP_DISABLE_CLASS } from './overlays-BpnIFlXI.js';
8
8
  import { i as isRTL } from './dir-Dojwmvde.js';
9
9
  import { c as createColorClasses } from './theme-byZM6qHV.js';
10
10
  import { b as chevronDown, d as caretUpSharp, e as chevronForward, f as caretDownSharp, c as chevronBack } from './index-BvabGprD.js';
11
- import { b as getIonMode } from './ionic-global-BVB7BrLT.js';
12
- import { r as removeDateTzOffset, g as getNextMonth, a as getPreviousMonth, b as getTodayLabel, c as getYear, d as getHourCycle, e as getInternalHourValue, f as getFormattedHour, h as addTimePadding, i as getLocalizedDayPeriod, j as isBefore, k as isSameDay, l as isAfter, m as is24Hour, n as getNumDaysInMonth, o as getDay, p as generateDayAriaLabel, q as convertToArrayOfNumbers, s as convertDataToISO, v as validateParts, t as getPartsFromCalendarDay, u as getNextYear, w as getPreviousYear, x as getEndOfWeek, y as getStartOfWeek, z as getPreviousDay, A as getNextDay, B as getPreviousWeek, C as getNextWeek, D as parseMinParts, E as parseMaxParts, F as parseDate, G as warnIfValueOutOfBounds, H as parseAmPm, I as clampDate, J as getClosestValidDate, K as isMonthFirstLocale, L as isLocaleDayPeriodRTL, M as calculateHourFromAMPM, N as getMonthAndYear, O as getLocalizedTime, P as getLocalizedDateTime, Q as formatValue } from './format-Dcwga61t.js';
11
+ import { b as getIonMode } from './ionic-global-lrowsHfi.js';
12
+ import { r as removeDateTzOffset, g as getNextMonth, a as getPreviousMonth, b as getTodayLabel, c as getYear, d as getHourCycle, e as getInternalHourValue, f as getFormattedHour, h as addTimePadding, i as getLocalizedDayPeriod, j as isBefore, k as isSameDay, l as isAfter, m as is24Hour, n as getNumDaysInMonth, o as getDay, p as generateDayAriaLabel, v as validateParts, q as getPartsFromCalendarDay, s as getNextYear, t as getPreviousYear, u as getEndOfWeek, w as getStartOfWeek, x as getPreviousDay, y as getNextDay, z as getPreviousWeek, A as getNextWeek, B as parseMinParts, C as parseMaxParts, D as parseDate, E as warnIfValueOutOfBounds, F as parseAmPm, G as clampDate, H as convertToArrayOfNumbers, I as convertDataToISO, J as getClosestValidDate, K as isMonthFirstLocale, L as isLocaleDayPeriodRTL, M as calculateHourFromAMPM, N as getMonthAndYear, O as getLocalizedTime, P as getLocalizedDateTime, Q as formatValue } from './format-CVk5e_GP.js';
13
13
  import './index-ZjP4CjeZ.js';
14
- import './hardware-back-button-gLJHMX_F.js';
15
- import './framework-delegate-BHTU2Ip9.js';
16
- import './gesture-controller-TXPDHL13.js';
14
+ import './hardware-back-button-D8W4L0JP.js';
15
+ import './framework-delegate-DaLWnISz.js';
16
+ import './gesture-controller-B_gJaBk0.js';
17
17
 
18
18
  /**
19
19
  * Returns the current date as
@@ -766,144 +766,781 @@ const Datetime = class {
766
766
  this.ionBlur = createEvent(this, "ionBlur", 7);
767
767
  this.ionStyle = createEvent(this, "ionStyle", 7);
768
768
  this.ionRender = createEvent(this, "ionRender", 7);
769
+ this.inputId = `ion-dt-${datetimeIds++}`;
770
+ /**
771
+ * Set true only by `visibleCallback`. Lets `hiddenCallback` ignore the
772
+ * synthetic "not intersecting" entry IntersectionObserver fires on
773
+ * `observe()` when the host mounts offscreen.
774
+ *
775
+ * Don't reset this in `disconnectedCallback`. Overlays disconnect and
776
+ * reconnect the host without re-creating the observers, so a reset there
777
+ * makes `hiddenCallback` miss the dismissal.
778
+ */
779
+ this.hasBeenIntersecting = false;
780
+ this.prevPresentation = null;
781
+ this.showMonthAndYear = false;
782
+ this.activeParts = [];
783
+ this.workingParts = {
784
+ month: 5,
785
+ day: 28,
786
+ year: 2021,
787
+ hour: 13,
788
+ minute: 52,
789
+ ampm: 'pm',
790
+ isAdjacentDay: false,
791
+ };
792
+ this.isTimePopoverOpen = false;
793
+ /**
794
+ * The name of the control, which is submitted with the form data.
795
+ */
796
+ this.name = this.inputId;
797
+ /**
798
+ * If `true`, the user cannot interact with the datetime.
799
+ */
800
+ this.disabled = false;
801
+ /**
802
+ * If `true`, the datetime appears normal but the selected date cannot be changed.
803
+ */
804
+ this.readonly = false;
805
+ /**
806
+ * If `true`, the datetime calendar displays a six-week (42-day) layout,
807
+ * including days from the previous and next months to fill the grid.
808
+ * These adjacent days are selectable unless disabled.
809
+ */
810
+ this.showAdjacentDays = false;
811
+ /**
812
+ * Which values you want to select. `"date"` will show
813
+ * a calendar picker to select the month, day, and year. `"time"`
814
+ * will show a time picker to select the hour, minute, and (optionally)
815
+ * AM/PM. `"date-time"` will show the date picker first and time picker second.
816
+ * `"time-date"` will show the time picker first and date picker second.
817
+ */
818
+ this.presentation = 'date-time';
819
+ /**
820
+ * The text to display on the picker's cancel button.
821
+ */
822
+ this.cancelText = 'Cancel';
823
+ /**
824
+ * The text to display on the picker's "Done" button.
825
+ */
826
+ this.doneText = 'Done';
827
+ /**
828
+ * The text to display on the picker's "Clear" button.
829
+ */
830
+ this.clearText = 'Clear';
831
+ /**
832
+ * The locale to use for `ion-datetime`. This
833
+ * impacts month and day name formatting.
834
+ * The `"default"` value refers to the default
835
+ * locale set by your device.
836
+ */
837
+ this.locale = 'default';
838
+ /**
839
+ * The first day of the week to use for `ion-datetime`. The
840
+ * default value is `0` and represents Sunday.
841
+ */
842
+ this.firstDayOfWeek = 0;
843
+ /**
844
+ * If `true`, multiple dates can be selected at once. Only
845
+ * applies to `presentation="date"` and `preferWheel="false"`.
846
+ */
847
+ this.multiple = false;
848
+ /**
849
+ * If `true`, a header will be shown above the calendar
850
+ * picker. This will include both the slotted title, and
851
+ * the selected date.
852
+ */
853
+ this.showDefaultTitle = false;
854
+ /**
855
+ * If `true`, the default "Cancel" and "OK" buttons
856
+ * will be rendered at the bottom of the `ion-datetime`
857
+ * component. Developers can also use the `button` slot
858
+ * if they want to customize these buttons. If custom
859
+ * buttons are set in the `button` slot then the
860
+ * default buttons will not be rendered.
861
+ */
862
+ this.showDefaultButtons = false;
863
+ /**
864
+ * If `true`, a "Clear" button will be rendered alongside
865
+ * the default "Cancel" and "OK" buttons at the bottom of the `ion-datetime`
866
+ * component. Developers can also use the `button` slot
867
+ * if they want to customize these buttons. If custom
868
+ * buttons are set in the `button` slot then the
869
+ * default buttons will not be rendered.
870
+ */
871
+ this.showClearButton = false;
872
+ /**
873
+ * If `true`, the default "Time" label will be rendered
874
+ * for the time selector of the `ion-datetime` component.
875
+ * Developers can also use the `time-label` slot
876
+ * if they want to customize this label. If a custom
877
+ * label is set in the `time-label` slot then the
878
+ * default label will not be rendered.
879
+ */
880
+ this.showDefaultTimeLabel = true;
881
+ /**
882
+ * If `cover`, the `ion-datetime` will expand to cover the full width of its container.
883
+ * If `fixed`, the `ion-datetime` will have a fixed width.
884
+ */
885
+ this.size = 'fixed';
886
+ /**
887
+ * If `true`, a wheel picker will be rendered instead of a calendar grid
888
+ * where possible. If `false`, a calendar grid will be rendered instead of
889
+ * a wheel picker where possible.
890
+ *
891
+ * A wheel picker can be rendered instead of a grid when `presentation` is
892
+ * one of the following values: `"date"`, `"date-time"`, or `"time-date"`.
893
+ *
894
+ * A wheel picker will always be rendered regardless of
895
+ * the `preferWheel` value when `presentation` is one of the following values:
896
+ * `"time"`, `"month"`, `"month-year"`, or `"year"`.
897
+ */
898
+ this.preferWheel = false;
899
+ this.warnIfIncorrectValueUsage = () => {
900
+ const { multiple, value } = this;
901
+ if (!multiple && Array.isArray(value)) {
902
+ /**
903
+ * We do some processing on the `value` array so
904
+ * that it looks more like an array when logged to
905
+ * the console.
906
+ * Example given ['a', 'b']
907
+ * Default toString() behavior: a,b
908
+ * Custom behavior: ['a', 'b']
909
+ */
910
+ printIonWarning(`[ion-datetime] - An array of values was passed, but multiple is "false". This is incorrect usage and may result in unexpected behaviors. To dismiss this warning, pass a string to the "value" property when multiple="false".
911
+
912
+ Value Passed: [${value.map((v) => `'${v}'`).join(', ')}]
913
+ `, this.el);
914
+ }
915
+ };
916
+ this.setValue = (value) => {
917
+ this.value = value;
918
+ this.ionChange.emit({ value });
919
+ };
920
+ /**
921
+ * Returns the DatetimePart interface
922
+ * to use when rendering an initial set of
923
+ * data. This should be used when rendering an
924
+ * interface in an environment where the `value`
925
+ * may not be set. This function works
926
+ * by returning the first selected date and then
927
+ * falling back to defaultParts if no active date
928
+ * is selected.
929
+ */
930
+ this.getActivePartsWithFallback = () => {
931
+ const { defaultParts } = this;
932
+ return this.getActivePart() ?? defaultParts;
933
+ };
934
+ this.getActivePart = () => {
935
+ const { activeParts } = this;
936
+ return Array.isArray(activeParts) ? activeParts[0] : activeParts;
937
+ };
938
+ this.closeParentOverlay = (role) => {
939
+ const popoverOrModal = this.el.closest('ion-modal, ion-popover');
940
+ if (popoverOrModal) {
941
+ popoverOrModal.dismiss(undefined, role);
942
+ }
943
+ };
944
+ this.setWorkingParts = (parts) => {
945
+ this.workingParts = {
946
+ ...parts,
947
+ };
948
+ };
949
+ this.setActiveParts = (parts, removeDate = false) => {
950
+ /** if the datetime component is in readonly mode,
951
+ * allow browsing of the calendar without changing
952
+ * the set value
953
+ */
954
+ if (this.readonly) {
955
+ return;
956
+ }
957
+ const { multiple, minParts, maxParts, activeParts } = this;
958
+ /**
959
+ * When setting the active parts, it is possible
960
+ * to set invalid data. For example,
961
+ * when updating January 31 to February,
962
+ * February 31 does not exist. As a result
963
+ * we need to validate the active parts and
964
+ * ensure that we are only setting valid dates.
965
+ * Additionally, we need to update the working parts
966
+ * too in the event that the validated parts are different.
967
+ */
968
+ const validatedParts = validateParts(parts, minParts, maxParts);
969
+ this.setWorkingParts(validatedParts);
970
+ if (multiple) {
971
+ const activePartsArray = Array.isArray(activeParts) ? activeParts : [activeParts];
972
+ if (removeDate) {
973
+ this.activeParts = activePartsArray.filter((p) => !isSameDay(p, validatedParts));
974
+ }
975
+ else {
976
+ this.activeParts = [...activePartsArray, validatedParts];
977
+ }
978
+ }
979
+ else {
980
+ this.activeParts = {
981
+ ...validatedParts,
982
+ };
983
+ }
984
+ const hasSlottedButtons = this.el.querySelector('[slot="buttons"]') !== null;
985
+ if (hasSlottedButtons || this.showDefaultButtons) {
986
+ return;
987
+ }
988
+ this.confirm();
989
+ };
990
+ this.initializeKeyboardListeners = () => {
991
+ const calendarBodyRef = this.calendarBodyRef;
992
+ if (!calendarBodyRef) {
993
+ return;
994
+ }
995
+ const root = this.el.shadowRoot;
996
+ /**
997
+ * Get a reference to the month
998
+ * element we are currently viewing.
999
+ */
1000
+ const currentMonth = calendarBodyRef.querySelector('.calendar-month:nth-of-type(2)');
1001
+ /**
1002
+ * When focusing the calendar body, we want to pass focus
1003
+ * to the working day, but other days should
1004
+ * only be accessible using the arrow keys. Pressing
1005
+ * Tab should jump between bodies of selectable content.
1006
+ */
1007
+ const checkCalendarBodyFocus = (ev) => {
1008
+ const record = ev[0];
1009
+ /**
1010
+ * If calendar body was already focused
1011
+ * when this fired or if the calendar body
1012
+ * if not currently focused, we should not re-focus
1013
+ * the inner day.
1014
+ */
1015
+ if (record.oldValue?.includes('ion-focused') || !calendarBodyRef.classList.contains('ion-focused')) {
1016
+ return;
1017
+ }
1018
+ this.focusWorkingDay(currentMonth);
1019
+ };
1020
+ const mo = new MutationObserver(checkCalendarBodyFocus);
1021
+ mo.observe(calendarBodyRef, { attributeFilter: ['class'], attributeOldValue: true });
1022
+ this.destroyKeyboardMO = () => {
1023
+ mo?.disconnect();
1024
+ };
1025
+ /**
1026
+ * We must use keydown not keyup as we want
1027
+ * to prevent scrolling when using the arrow keys.
1028
+ */
1029
+ calendarBodyRef.addEventListener('keydown', (ev) => {
1030
+ const activeElement = root.activeElement;
1031
+ if (!activeElement || !activeElement.classList.contains('calendar-day')) {
1032
+ return;
1033
+ }
1034
+ const parts = getPartsFromCalendarDay(activeElement);
1035
+ let partsToFocus;
1036
+ switch (ev.key) {
1037
+ case 'ArrowDown':
1038
+ ev.preventDefault();
1039
+ partsToFocus = getNextWeek(parts);
1040
+ break;
1041
+ case 'ArrowUp':
1042
+ ev.preventDefault();
1043
+ partsToFocus = getPreviousWeek(parts);
1044
+ break;
1045
+ case 'ArrowRight':
1046
+ ev.preventDefault();
1047
+ partsToFocus = getNextDay(parts);
1048
+ break;
1049
+ case 'ArrowLeft':
1050
+ ev.preventDefault();
1051
+ partsToFocus = getPreviousDay(parts);
1052
+ break;
1053
+ case 'Home':
1054
+ ev.preventDefault();
1055
+ partsToFocus = getStartOfWeek(parts);
1056
+ break;
1057
+ case 'End':
1058
+ ev.preventDefault();
1059
+ partsToFocus = getEndOfWeek(parts);
1060
+ break;
1061
+ case 'PageUp':
1062
+ ev.preventDefault();
1063
+ partsToFocus = ev.shiftKey ? getPreviousYear(parts) : getPreviousMonth(parts);
1064
+ break;
1065
+ case 'PageDown':
1066
+ ev.preventDefault();
1067
+ partsToFocus = ev.shiftKey ? getNextYear(parts) : getNextMonth(parts);
1068
+ break;
1069
+ /**
1070
+ * Do not preventDefault here
1071
+ * as we do not want to override other
1072
+ * browser defaults such as pressing Enter/Space
1073
+ * to select a day.
1074
+ */
1075
+ default:
1076
+ return;
1077
+ }
1078
+ /**
1079
+ * If the day we want to move focus to is
1080
+ * disabled, do not do anything.
1081
+ */
1082
+ if (isDayDisabled(partsToFocus, this.minParts, this.maxParts)) {
1083
+ return;
1084
+ }
1085
+ this.setWorkingParts({
1086
+ ...this.workingParts,
1087
+ ...partsToFocus,
1088
+ });
1089
+ /**
1090
+ * Give view a chance to re-render
1091
+ * then move focus to the new working day
1092
+ */
1093
+ requestAnimationFrame(() => this.focusWorkingDay(currentMonth));
1094
+ });
1095
+ };
1096
+ this.focusWorkingDay = (currentMonth) => {
1097
+ /**
1098
+ * Get the number of offset days so
1099
+ * we know how much to offset our next selector by
1100
+ * to grab the correct calendar-day element.
1101
+ */
1102
+ const { day, month, year } = this.workingParts;
1103
+ const firstOfMonth = new Date(`${month}/1/${year}`).getDay();
1104
+ const offset = firstOfMonth >= this.firstDayOfWeek
1105
+ ? firstOfMonth - this.firstDayOfWeek
1106
+ : 7 - (this.firstDayOfWeek - firstOfMonth);
1107
+ if (day === null) {
1108
+ return;
1109
+ }
1110
+ /**
1111
+ * Get the calendar day element
1112
+ * and focus it.
1113
+ */
1114
+ const dayEl = currentMonth.querySelector(`.calendar-day-wrapper:nth-of-type(${offset + day}) .calendar-day`);
1115
+ if (dayEl) {
1116
+ dayEl.focus();
1117
+ }
1118
+ };
1119
+ this.processMinParts = () => {
1120
+ const { min, defaultParts } = this;
1121
+ if (min === undefined) {
1122
+ this.minParts = undefined;
1123
+ return;
1124
+ }
1125
+ this.minParts = parseMinParts(min, defaultParts);
1126
+ };
1127
+ this.processMaxParts = () => {
1128
+ const { max, defaultParts } = this;
1129
+ if (max === undefined) {
1130
+ this.maxParts = undefined;
1131
+ return;
1132
+ }
1133
+ this.maxParts = parseMaxParts(max, defaultParts);
1134
+ };
1135
+ this.initializeCalendarListener = () => {
1136
+ const calendarBodyRef = this.calendarBodyRef;
1137
+ if (!calendarBodyRef) {
1138
+ return;
1139
+ }
1140
+ /**
1141
+ * For performance reasons, we only render 3
1142
+ * months at a time: The current month, the previous
1143
+ * month, and the next month. We have a scroll listener
1144
+ * on the calendar body to append/prepend new months.
1145
+ *
1146
+ * We can do this because Stencil is smart enough to not
1147
+ * re-create the .calendar-month containers, but rather
1148
+ * update the content within those containers.
1149
+ *
1150
+ * As an added bonus, WebKit has some troubles with
1151
+ * scroll-snap-stop: always, so not rendering all of
1152
+ * the months in a row allows us to mostly sidestep
1153
+ * that issue.
1154
+ */
1155
+ const months = calendarBodyRef.querySelectorAll('.calendar-month');
1156
+ const startMonth = months[0];
1157
+ const workingMonth = months[1];
1158
+ const endMonth = months[2];
1159
+ const mode = getIonMode(this);
1160
+ const needsiOSRubberBandFix = mode === 'ios' && typeof navigator !== 'undefined' && navigator.maxTouchPoints > 1;
1161
+ /**
1162
+ * Before setting up the scroll listener,
1163
+ * scroll the middle month into view.
1164
+ * scrollIntoView() will scroll entire page
1165
+ * if element is not in viewport. Use scrollLeft instead.
1166
+ */
1167
+ writeTask(() => {
1168
+ calendarBodyRef.scrollLeft = startMonth.clientWidth * (isRTL(this.el) ? -1 : 1);
1169
+ const getChangedMonth = (parts) => {
1170
+ const box = calendarBodyRef.getBoundingClientRect();
1171
+ /**
1172
+ * If the current scroll position is all the way to the left
1173
+ * then we have scrolled to the previous month.
1174
+ * Otherwise, assume that we have scrolled to the next
1175
+ * month. We have a tolerance of 2px to account for
1176
+ * sub pixel rendering.
1177
+ *
1178
+ * Check below the next line ensures that we did not
1179
+ * swipe and abort (i.e. we swiped but we are still on the current month).
1180
+ */
1181
+ const condition = isRTL(this.el) ? calendarBodyRef.scrollLeft >= -2 : calendarBodyRef.scrollLeft <= 2;
1182
+ const month = condition ? startMonth : endMonth;
1183
+ /**
1184
+ * The edge of the month must be lined up with
1185
+ * the edge of the calendar body in order for
1186
+ * the component to update. Otherwise, it
1187
+ * may be the case that the user has paused their
1188
+ * swipe or the browser has not finished snapping yet.
1189
+ * Rather than check if the x values are equal,
1190
+ * we give it a tolerance of 2px to account for
1191
+ * sub pixel rendering.
1192
+ */
1193
+ const monthBox = month.getBoundingClientRect();
1194
+ if (Math.abs(monthBox.x - box.x) > 2)
1195
+ return;
1196
+ /**
1197
+ * If we're force-rendering a month, assume we've
1198
+ * scrolled to that and return it.
1199
+ *
1200
+ * If forceRenderDate is ever used in a context where the
1201
+ * forced month is not immediately auto-scrolled to, this
1202
+ * should be updated to also check whether `month` has the
1203
+ * same month and year as the forced date.
1204
+ */
1205
+ const { forceRenderDate } = this;
1206
+ if (forceRenderDate !== undefined) {
1207
+ return { month: forceRenderDate.month, year: forceRenderDate.year, day: forceRenderDate.day };
1208
+ }
1209
+ /**
1210
+ * From here, we can determine if the start
1211
+ * month or the end month was scrolled into view.
1212
+ * If no month was changed, then we can return from
1213
+ * the scroll callback early.
1214
+ */
1215
+ if (month === startMonth) {
1216
+ return getPreviousMonth(parts);
1217
+ }
1218
+ else if (month === endMonth) {
1219
+ return getNextMonth(parts);
1220
+ }
1221
+ else {
1222
+ return;
1223
+ }
1224
+ };
1225
+ const updateActiveMonth = () => {
1226
+ if (needsiOSRubberBandFix) {
1227
+ calendarBodyRef.style.removeProperty('pointer-events');
1228
+ appliediOSRubberBandFix = false;
1229
+ }
1230
+ /**
1231
+ * If the month did not change
1232
+ * then we can return early.
1233
+ */
1234
+ const newDate = getChangedMonth(this.workingParts);
1235
+ if (!newDate)
1236
+ return;
1237
+ const { month, day, year } = newDate;
1238
+ if (isMonthDisabled({ month, year, day: null }, {
1239
+ minParts: { ...this.minParts, day: null },
1240
+ maxParts: { ...this.maxParts, day: null },
1241
+ })) {
1242
+ return;
1243
+ }
1244
+ /**
1245
+ * Prevent scrolling for other browsers
1246
+ * to give the DOM time to update and the container
1247
+ * time to properly snap.
1248
+ */
1249
+ calendarBodyRef.style.setProperty('overflow', 'hidden');
1250
+ /**
1251
+ * Use a writeTask here to ensure
1252
+ * that the state is updated and the
1253
+ * correct month is scrolled into view
1254
+ * in the same frame. This is not
1255
+ * typically a problem on newer devices
1256
+ * but older/slower device may have a flicker
1257
+ * if we did not do this.
1258
+ */
1259
+ writeTask(() => {
1260
+ this.setWorkingParts({
1261
+ ...this.workingParts,
1262
+ month,
1263
+ day: day,
1264
+ year,
1265
+ });
1266
+ calendarBodyRef.scrollLeft = workingMonth.clientWidth * (isRTL(this.el) ? -1 : 1);
1267
+ calendarBodyRef.style.removeProperty('overflow');
1268
+ if (this.resolveForceDateScrolling) {
1269
+ this.resolveForceDateScrolling();
1270
+ }
1271
+ const activeEl = this.el.shadowRoot.activeElement;
1272
+ if (activeEl && activeEl.classList.contains('calendar-day')) {
1273
+ activeEl.closest('.calendar-body')?.focus();
1274
+ }
1275
+ });
1276
+ };
1277
+ /**
1278
+ * When the container finishes scrolling we
1279
+ * need to update the DOM with the selected month.
1280
+ */
1281
+ let scrollTimeout;
1282
+ /**
1283
+ * We do not want to attempt to set pointer-events
1284
+ * multiple times within a single swipe gesture as
1285
+ * that adds unnecessary work to the main thread.
1286
+ */
1287
+ let appliediOSRubberBandFix = false;
1288
+ const scrollCallback = () => {
1289
+ if (scrollTimeout) {
1290
+ clearTimeout(scrollTimeout);
1291
+ }
1292
+ /**
1293
+ * On iOS it is possible to quickly rubber band
1294
+ * the scroll area before the scroll timeout has fired.
1295
+ * This results in users reaching the end of the scrollable
1296
+ * container before the DOM has updated.
1297
+ * By setting `pointer-events: none` we can ensure that
1298
+ * subsequent swipes do not happen while the container
1299
+ * is snapping.
1300
+ */
1301
+ if (!appliediOSRubberBandFix && needsiOSRubberBandFix) {
1302
+ calendarBodyRef.style.setProperty('pointer-events', 'none');
1303
+ appliediOSRubberBandFix = true;
1304
+ }
1305
+ // Wait ~3 frames
1306
+ scrollTimeout = setTimeout(updateActiveMonth, 50);
1307
+ };
1308
+ calendarBodyRef.addEventListener('scroll', scrollCallback);
1309
+ this.destroyCalendarListener = () => {
1310
+ calendarBodyRef.removeEventListener('scroll', scrollCallback);
1311
+ };
1312
+ });
1313
+ };
1314
+ /**
1315
+ * Clean up all listeners except for the overlay
1316
+ * listener. This is so that we can re-create the listeners
1317
+ * if the datetime has been hidden/presented by a modal or popover.
1318
+ */
1319
+ this.destroyInteractionListeners = () => {
1320
+ const { destroyCalendarListener, destroyKeyboardMO } = this;
1321
+ if (destroyCalendarListener !== undefined) {
1322
+ destroyCalendarListener();
1323
+ }
1324
+ if (destroyKeyboardMO !== undefined) {
1325
+ destroyKeyboardMO();
1326
+ }
1327
+ };
1328
+ /**
1329
+ * TODO(FW-6931): Remove this fallback upon solving the root cause
1330
+ * Fallback to ensure the datetime becomes ready even if
1331
+ * IntersectionObserver never reports it as intersecting.
1332
+ *
1333
+ * This is primarily used in environments where the observer
1334
+ * might not fire as expected, such as when running under
1335
+ * synthetic tests that stub IntersectionObserver.
1336
+ */
1337
+ this.ensureReadyIfVisible = () => {
1338
+ if (this.el.classList.contains('datetime-ready')) {
1339
+ return;
1340
+ }
1341
+ const rect = this.el.getBoundingClientRect();
1342
+ if (rect.width === 0 || rect.height === 0) {
1343
+ return;
1344
+ }
1345
+ this.markReady();
1346
+ };
1347
+ this.markReady = () => {
1348
+ if (this.el.classList.contains('datetime-ready')) {
1349
+ return;
1350
+ }
1351
+ this.initializeListeners();
1352
+ /**
1353
+ * TODO FW-2793: Datetime needs a frame to ensure that it
1354
+ * can properly scroll contents into view. As a result
1355
+ * we hide the scrollable content until after that frame
1356
+ * so users do not see the content quickly shifting. The downside
1357
+ * is that the content will pop into view a frame after. Maybe there
1358
+ * is a better way to handle this?
1359
+ */
1360
+ writeTask(() => {
1361
+ this.el.classList.add('datetime-ready');
1362
+ });
1363
+ };
1364
+ this.loadTimeoutCleanup = () => {
1365
+ if (this.loadTimeout) {
1366
+ clearTimeout(this.loadTimeout);
1367
+ this.loadTimeout = undefined;
1368
+ }
1369
+ };
1370
+ this.processValue = (value) => {
1371
+ const hasValue = value !== null && value !== undefined && value !== '' && (!Array.isArray(value) || value.length > 0);
1372
+ const valueToProcess = hasValue ? parseDate(value) : this.defaultParts;
1373
+ const { minParts, maxParts, workingParts, el } = this;
1374
+ this.warnIfIncorrectValueUsage();
1375
+ /**
1376
+ * Return early if the value wasn't parsed correctly, such as
1377
+ * if an improperly formatted date string was provided.
1378
+ */
1379
+ if (!valueToProcess) {
1380
+ return;
1381
+ }
1382
+ /**
1383
+ * Datetime should only warn of out of bounds values
1384
+ * if set by the user. If the `value` is undefined,
1385
+ * we will default to today's date which may be out
1386
+ * of bounds. In this case, the warning makes it look
1387
+ * like the developer did something wrong which is
1388
+ * not true.
1389
+ */
1390
+ if (hasValue) {
1391
+ warnIfValueOutOfBounds(valueToProcess, minParts, maxParts);
1392
+ }
1393
+ /**
1394
+ * If there are multiple values, clamp to the last one.
1395
+ * This is because the last value is the one that the user
1396
+ * has most recently interacted with.
1397
+ */
1398
+ const singleValue = Array.isArray(valueToProcess) ? valueToProcess[valueToProcess.length - 1] : valueToProcess;
1399
+ const targetValue = clampDate(singleValue, minParts, maxParts);
1400
+ const { month, day, year, hour, minute } = targetValue;
1401
+ const ampm = parseAmPm(hour);
1402
+ /**
1403
+ * Since `activeParts` indicates a value that been explicitly selected
1404
+ * either by the user or the app, only update `activeParts` if the
1405
+ * `value` property is set.
1406
+ */
1407
+ if (hasValue) {
1408
+ if (Array.isArray(valueToProcess)) {
1409
+ this.activeParts = [...valueToProcess];
1410
+ }
1411
+ else {
1412
+ this.activeParts = {
1413
+ month,
1414
+ day,
1415
+ year,
1416
+ hour,
1417
+ minute,
1418
+ ampm,
1419
+ };
1420
+ }
1421
+ }
1422
+ else {
1423
+ /**
1424
+ * Reset the active parts if the value is not set.
1425
+ * This will clear the selected calendar day when
1426
+ * performing a clear action or using the reset() method.
1427
+ */
1428
+ this.activeParts = [];
1429
+ }
1430
+ const didChangeMonth = (month !== undefined && month !== workingParts.month) || (year !== undefined && year !== workingParts.year);
1431
+ const bodyIsVisible = el.classList.contains('datetime-ready');
1432
+ const { isGridStyle, showMonthAndYear } = this;
1433
+ if (isGridStyle && didChangeMonth && bodyIsVisible && !showMonthAndYear) {
1434
+ /**
1435
+ * Only animate if:
1436
+ * 1. We're using grid style (wheel style pickers should just jump to new value)
1437
+ * 2. The month and/or year actually changed, and both are defined (otherwise there's nothing to animate to)
1438
+ * 3. The calendar body is visible (prevents animation when in collapsed datetime-button, for example)
1439
+ * 4. The month/year picker is not open (since you wouldn't see the animation anyway)
1440
+ */
1441
+ this.animateToDate(targetValue);
1442
+ }
1443
+ else {
1444
+ this.setWorkingParts({
1445
+ month,
1446
+ day,
1447
+ year,
1448
+ hour,
1449
+ minute,
1450
+ ampm,
1451
+ });
1452
+ }
1453
+ };
1454
+ this.animateToDate = async (targetValue) => {
1455
+ const { workingParts } = this;
1456
+ /**
1457
+ * Tell other render functions that we need to force the
1458
+ * target month to appear in place of the actual next/prev month.
1459
+ * Because this is a State variable, a rerender will be triggered
1460
+ * automatically, updating the rendered months.
1461
+ */
1462
+ this.forceRenderDate = targetValue;
1463
+ /**
1464
+ * Flag that we've started scrolling to the forced date.
1465
+ * The resolve function will be called by the datetime's
1466
+ * scroll listener when it's done updating everything.
1467
+ * This is a replacement for making prev/nextMonth async,
1468
+ * since the logic we're waiting on is in a listener.
1469
+ */
1470
+ const forceDateScrollingPromise = new Promise((resolve) => {
1471
+ this.resolveForceDateScrolling = resolve;
1472
+ });
1473
+ /**
1474
+ * Animate smoothly to the forced month. This will also update
1475
+ * workingParts and correct the surrounding months for us.
1476
+ */
1477
+ const targetMonthIsBefore = isBefore(targetValue, workingParts);
1478
+ targetMonthIsBefore ? this.prevMonth() : this.nextMonth();
1479
+ await forceDateScrollingPromise;
1480
+ this.resolveForceDateScrolling = undefined;
1481
+ this.forceRenderDate = undefined;
1482
+ };
1483
+ this.onFocus = () => {
1484
+ this.ionFocus.emit();
1485
+ };
1486
+ this.onBlur = () => {
1487
+ this.ionBlur.emit();
1488
+ };
1489
+ this.hasValue = () => {
1490
+ return this.value != null;
1491
+ };
1492
+ this.nextMonth = () => {
1493
+ const calendarBodyRef = this.calendarBodyRef;
1494
+ if (!calendarBodyRef) {
1495
+ return;
1496
+ }
1497
+ const nextMonth = calendarBodyRef.querySelector('.calendar-month:last-of-type');
1498
+ if (!nextMonth) {
1499
+ return;
1500
+ }
1501
+ const left = nextMonth.offsetWidth * 2;
1502
+ const scrollMode = config.getBoolean('animated', true) ? 'smooth' : 'instant';
1503
+ calendarBodyRef.scrollTo({
1504
+ top: 0,
1505
+ left: left * (isRTL(this.el) ? -1 : 1),
1506
+ behavior: scrollMode,
1507
+ });
1508
+ };
1509
+ this.prevMonth = () => {
1510
+ const calendarBodyRef = this.calendarBodyRef;
1511
+ if (!calendarBodyRef) {
1512
+ return;
1513
+ }
1514
+ const prevMonth = calendarBodyRef.querySelector('.calendar-month:first-of-type');
1515
+ if (!prevMonth) {
1516
+ return;
1517
+ }
1518
+ const left = prevMonth.offsetWidth * 2;
1519
+ const scrollMode = config.getBoolean('animated', true) ? 'smooth' : 'instant';
1520
+ calendarBodyRef.scrollTo({
1521
+ top: 0,
1522
+ left: left * (isRTL(this.el) ? 1 : -1),
1523
+ behavior: scrollMode,
1524
+ });
1525
+ };
1526
+ this.toggleMonthAndYearView = () => {
1527
+ this.showMonthAndYear = !this.showMonthAndYear;
1528
+ };
769
1529
  }
770
- inputId = `ion-dt-${datetimeIds++}`;
771
- calendarBodyRef;
772
- popoverRef;
773
- intersectionTrackerRef;
774
- clearFocusVisible;
775
- parsedMinuteValues;
776
- parsedHourValues;
777
- parsedMonthValues;
778
- parsedYearValues;
779
- parsedDayValues;
780
- destroyCalendarListener;
781
- destroyKeyboardMO;
782
- // TODO(FW-2832): types (DatetimeParts causes some errors that need untangling)
783
- minParts;
784
- maxParts;
785
- todayParts;
786
- defaultParts;
787
- loadTimeout;
788
- /**
789
- * Set true only by `visibleCallback`. Lets `hiddenCallback` ignore the
790
- * synthetic "not intersecting" entry IntersectionObserver fires on
791
- * `observe()` when the host mounts offscreen.
792
- *
793
- * Don't reset this in `disconnectedCallback`. Overlays disconnect and
794
- * reconnect the host without re-creating the observers, so a reset there
795
- * makes `hiddenCallback` miss the dismissal.
796
- */
797
- hasBeenIntersecting = false;
798
- prevPresentation = null;
799
- resolveForceDateScrolling;
800
- showMonthAndYear = false;
801
- activeParts = [];
802
- workingParts = {
803
- month: 5,
804
- day: 28,
805
- year: 2021,
806
- hour: 13,
807
- minute: 52,
808
- ampm: 'pm',
809
- isAdjacentDay: false,
810
- };
811
- get el() { return getElement(this); }
812
- isTimePopoverOpen = false;
813
- /**
814
- * When defined, will force the datetime to render the month
815
- * containing the specified date. Currently, this should only
816
- * be used to enable immediately auto-scrolling to the new month,
817
- * and should then be reset to undefined once the transition is
818
- * finished and the forced month is now in view.
819
- *
820
- * Applies to grid-style datetimes only.
821
- */
822
- forceRenderDate;
823
- /**
824
- * The color to use from your application's color palette.
825
- * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`.
826
- * For more information on colors, refer to [theming](/docs/theming/basics).
827
- */
828
- color;
829
- /**
830
- * The name of the control, which is submitted with the form data.
831
- */
832
- name = this.inputId;
833
- /**
834
- * If `true`, the user cannot interact with the datetime.
835
- */
836
- disabled = false;
837
- /**
838
- * Formatting options for dates and times.
839
- * Should include a 'date' and/or 'time' object, each of which is of type [Intl.DateTimeFormatOptions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#options).
840
- *
841
- */
842
- formatOptions;
843
1530
  formatOptionsChanged() {
844
1531
  const { el, formatOptions, presentation } = this;
845
1532
  checkForPresentationFormatMismatch(el, presentation, formatOptions);
846
1533
  warnIfTimeZoneProvided(el, formatOptions);
847
1534
  }
848
- /**
849
- * If `true`, the datetime appears normal but the selected date cannot be changed.
850
- */
851
- readonly = false;
852
- /**
853
- * Returns if an individual date (calendar day) is enabled or disabled.
854
- *
855
- * If `true`, the day will be enabled/interactive.
856
- * If `false`, the day will be disabled/non-interactive.
857
- *
858
- * The function accepts an ISO 8601 date string of a given day.
859
- * By default, all days are enabled. Developers can use this function
860
- * to write custom logic to disable certain days.
861
- *
862
- * The function is called for each rendered calendar day, for the previous, current and next month.
863
- * Custom implementations should be optimized for performance to avoid jank.
864
- */
865
- isDateEnabled;
866
- /**
867
- * If `true`, the datetime calendar displays a six-week (42-day) layout,
868
- * including days from the previous and next months to fill the grid.
869
- * These adjacent days are selectable unless disabled.
870
- */
871
- showAdjacentDays = false;
872
1535
  disabledChanged() {
873
1536
  this.emitStyle();
874
1537
  }
875
- /**
876
- * The minimum datetime allowed. Value must be a date string
877
- * following the
878
- * [ISO 8601 datetime format standard](https://www.w3.org/TR/NOTE-datetime),
879
- * such as `1996-12-19`. The format does not have to be specific to an exact
880
- * datetime. For example, the minimum could just be the year, such as `1994`.
881
- * Defaults to the beginning of the year, 100 years ago from today.
882
- */
883
- min;
884
1538
  minChanged() {
885
1539
  this.processMinParts();
886
1540
  }
887
- /**
888
- * The maximum datetime allowed. Value must be a date string
889
- * following the
890
- * [ISO 8601 datetime format standard](https://www.w3.org/TR/NOTE-datetime),
891
- * `1996-12-19`. The format does not have to be specific to an exact
892
- * datetime. For example, the maximum could just be the year, such as `1994`.
893
- * Defaults to the end of this year.
894
- */
895
- max;
896
1541
  maxChanged() {
897
1542
  this.processMaxParts();
898
1543
  }
899
- /**
900
- * Which values you want to select. `"date"` will show
901
- * a calendar picker to select the month, day, and year. `"time"`
902
- * will show a time picker to select the hour, minute, and (optionally)
903
- * AM/PM. `"date-time"` will show the date picker first and time picker second.
904
- * `"time-date"` will show the time picker first and date picker second.
905
- */
906
- presentation = 'date-time';
907
1544
  presentationChanged() {
908
1545
  const { el, formatOptions, presentation } = this;
909
1546
  checkForPresentationFormatMismatch(el, presentation, formatOptions);
@@ -913,116 +1550,21 @@ const Datetime = class {
913
1550
  const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
914
1551
  return hasDatePresentation && !preferWheel;
915
1552
  }
916
- /**
917
- * The text to display on the picker's cancel button.
918
- */
919
- cancelText = 'Cancel';
920
- /**
921
- * The text to display on the picker's "Done" button.
922
- */
923
- doneText = 'Done';
924
- /**
925
- * The text to display on the picker's "Clear" button.
926
- */
927
- clearText = 'Clear';
928
- /**
929
- * Values used to create the list of selectable years. By default
930
- * the year values range between the `min` and `max` datetime inputs. However, to
931
- * control exactly which years to display, the `yearValues` input can take a number, an array
932
- * of numbers, or string of comma separated numbers. For example, to show upcoming and
933
- * recent leap years, then this input's value would be `yearValues="2008,2012,2016,2020,2024"`.
934
- */
935
- yearValues;
936
1553
  yearValuesChanged() {
937
1554
  this.parsedYearValues = convertToArrayOfNumbers(this.yearValues);
938
1555
  }
939
- /**
940
- * Values used to create the list of selectable months. By default
941
- * the month values range from `1` to `12`. However, to control exactly which months to
942
- * display, the `monthValues` input can take a number, an array of numbers, or a string of
943
- * comma separated numbers. For example, if only summer months should be shown, then this
944
- * input value would be `monthValues="6,7,8"`. Note that month numbers do *not* have a
945
- * zero-based index, meaning January's value is `1`, and December's is `12`.
946
- */
947
- monthValues;
948
1556
  monthValuesChanged() {
949
1557
  this.parsedMonthValues = convertToArrayOfNumbers(this.monthValues);
950
1558
  }
951
- /**
952
- * Values used to create the list of selectable days. By default
953
- * every day is shown for the given month. However, to control exactly which days of
954
- * the month to display, the `dayValues` input can take a number, an array of numbers, or
955
- * a string of comma separated numbers. Note that even if the array days have an invalid
956
- * number for the selected month, like `31` in February, it will correctly not show
957
- * days which are not valid for the selected month.
958
- */
959
- dayValues;
960
1559
  dayValuesChanged() {
961
1560
  this.parsedDayValues = convertToArrayOfNumbers(this.dayValues);
962
1561
  }
963
- /**
964
- * Values used to create the list of selectable hours. By default
965
- * the hour values range from `0` to `23` for 24-hour, or `1` to `12` for 12-hour. However,
966
- * to control exactly which hours to display, the `hourValues` input can take a number, an
967
- * array of numbers, or a string of comma separated numbers.
968
- */
969
- hourValues;
970
- hourValuesChanged() {
971
- this.parsedHourValues = convertToArrayOfNumbers(this.hourValues);
972
- }
973
- /**
974
- * Values used to create the list of selectable minutes. By default
975
- * the minutes range from `0` to `59`. However, to control exactly which minutes to display,
976
- * the `minuteValues` input can take a number, an array of numbers, or a string of comma
977
- * separated numbers. For example, if the minute selections should only be every 15 minutes,
978
- * then this input value would be `minuteValues="0,15,30,45"`.
979
- */
980
- minuteValues;
981
- minuteValuesChanged() {
982
- this.parsedMinuteValues = convertToArrayOfNumbers(this.minuteValues);
983
- }
984
- /**
985
- * The locale to use for `ion-datetime`. This
986
- * impacts month and day name formatting.
987
- * The `"default"` value refers to the default
988
- * locale set by your device.
989
- */
990
- locale = 'default';
991
- /**
992
- * The first day of the week to use for `ion-datetime`. The
993
- * default value is `0` and represents Sunday.
994
- */
995
- firstDayOfWeek = 0;
996
- /**
997
- * A callback used to format the header text that shows how many
998
- * dates are selected. Only used if there are 0 or more than 1
999
- * selected (i.e. unused for exactly 1). By default, the header
1000
- * text is set to "numberOfDates days".
1001
- *
1002
- * See https://ionicframework.com/docs/troubleshooting/runtime#accessing-this
1003
- * if you need to access `this` from within the callback.
1004
- */
1005
- titleSelectedDatesFormatter;
1006
- /**
1007
- * If `true`, multiple dates can be selected at once. Only
1008
- * applies to `presentation="date"` and `preferWheel="false"`.
1009
- */
1010
- multiple = false;
1011
- /**
1012
- * Used to apply custom text and background colors to specific dates.
1013
- *
1014
- * Can be either an array of objects containing ISO strings and colors,
1015
- * or a callback that receives an ISO string and returns the colors.
1016
- *
1017
- * Only applies to the `date`, `date-time`, and `time-date` presentations,
1018
- * with `preferWheel="false"`.
1019
- */
1020
- highlightedDates;
1021
- /**
1022
- * The value of the datetime as a valid ISO 8601 datetime string.
1023
- * This should be an array of strings only when `multiple="true"`.
1024
- */
1025
- value;
1562
+ hourValuesChanged() {
1563
+ this.parsedHourValues = convertToArrayOfNumbers(this.hourValues);
1564
+ }
1565
+ minuteValuesChanged() {
1566
+ this.parsedMinuteValues = convertToArrayOfNumbers(this.minuteValues);
1567
+ }
1026
1568
  /**
1027
1569
  * Update the datetime value when the value changes
1028
1570
  */
@@ -1034,97 +1576,6 @@ const Datetime = class {
1034
1576
  this.emitStyle();
1035
1577
  this.ionValueChange.emit({ value });
1036
1578
  }
1037
- /**
1038
- * If `true`, a header will be shown above the calendar
1039
- * picker. This will include both the slotted title, and
1040
- * the selected date.
1041
- */
1042
- showDefaultTitle = false;
1043
- /**
1044
- * If `true`, the default "Cancel" and "OK" buttons
1045
- * will be rendered at the bottom of the `ion-datetime`
1046
- * component. Developers can also use the `button` slot
1047
- * if they want to customize these buttons. If custom
1048
- * buttons are set in the `button` slot then the
1049
- * default buttons will not be rendered.
1050
- */
1051
- showDefaultButtons = false;
1052
- /**
1053
- * If `true`, a "Clear" button will be rendered alongside
1054
- * the default "Cancel" and "OK" buttons at the bottom of the `ion-datetime`
1055
- * component. Developers can also use the `button` slot
1056
- * if they want to customize these buttons. If custom
1057
- * buttons are set in the `button` slot then the
1058
- * default buttons will not be rendered.
1059
- */
1060
- showClearButton = false;
1061
- /**
1062
- * If `true`, the default "Time" label will be rendered
1063
- * for the time selector of the `ion-datetime` component.
1064
- * Developers can also use the `time-label` slot
1065
- * if they want to customize this label. If a custom
1066
- * label is set in the `time-label` slot then the
1067
- * default label will not be rendered.
1068
- */
1069
- showDefaultTimeLabel = true;
1070
- /**
1071
- * The hour cycle of the `ion-datetime`. If no value is set, this is
1072
- * specified by the current locale.
1073
- */
1074
- hourCycle;
1075
- /**
1076
- * If `cover`, the `ion-datetime` will expand to cover the full width of its container.
1077
- * If `fixed`, the `ion-datetime` will have a fixed width.
1078
- */
1079
- size = 'fixed';
1080
- /**
1081
- * If `true`, a wheel picker will be rendered instead of a calendar grid
1082
- * where possible. If `false`, a calendar grid will be rendered instead of
1083
- * a wheel picker where possible.
1084
- *
1085
- * A wheel picker can be rendered instead of a grid when `presentation` is
1086
- * one of the following values: `"date"`, `"date-time"`, or `"time-date"`.
1087
- *
1088
- * A wheel picker will always be rendered regardless of
1089
- * the `preferWheel` value when `presentation` is one of the following values:
1090
- * `"time"`, `"month"`, `"month-year"`, or `"year"`.
1091
- */
1092
- preferWheel = false;
1093
- /**
1094
- * Emitted when the datetime selection was cancelled.
1095
- */
1096
- ionCancel;
1097
- /**
1098
- * Emitted when the value (selected date) has changed.
1099
- *
1100
- * This event will not emit when programmatically setting the `value` property.
1101
- */
1102
- ionChange;
1103
- /**
1104
- * Emitted when the value property has changed.
1105
- * This is used to ensure that ion-datetime-button can respond
1106
- * to any value property changes.
1107
- * @internal
1108
- */
1109
- ionValueChange;
1110
- /**
1111
- * Emitted when the datetime has focus.
1112
- */
1113
- ionFocus;
1114
- /**
1115
- * Emitted when the datetime loses focus.
1116
- */
1117
- ionBlur;
1118
- /**
1119
- * Emitted when the styles change.
1120
- * @internal
1121
- */
1122
- ionStyle;
1123
- /**
1124
- * Emitted when componentDidRender is fired.
1125
- * @internal
1126
- */
1127
- ionRender;
1128
1579
  /**
1129
1580
  * Confirms the selected datetime value, updates the
1130
1581
  * `value` property, and optionally closes the popover
@@ -1194,425 +1645,10 @@ const Datetime = class {
1194
1645
  async getDefaultPart() {
1195
1646
  return this.defaultParts;
1196
1647
  }
1197
- warnIfIncorrectValueUsage = () => {
1198
- const { multiple, value } = this;
1199
- if (!multiple && Array.isArray(value)) {
1200
- /**
1201
- * We do some processing on the `value` array so
1202
- * that it looks more like an array when logged to
1203
- * the console.
1204
- * Example given ['a', 'b']
1205
- * Default toString() behavior: a,b
1206
- * Custom behavior: ['a', 'b']
1207
- */
1208
- printIonWarning(`[ion-datetime] - An array of values was passed, but multiple is "false". This is incorrect usage and may result in unexpected behaviors. To dismiss this warning, pass a string to the "value" property when multiple="false".
1209
-
1210
- Value Passed: [${value.map((v) => `'${v}'`).join(', ')}]
1211
- `, this.el);
1212
- }
1213
- };
1214
- setValue = (value) => {
1215
- this.value = value;
1216
- this.ionChange.emit({ value });
1217
- };
1218
- /**
1219
- * Returns the DatetimePart interface
1220
- * to use when rendering an initial set of
1221
- * data. This should be used when rendering an
1222
- * interface in an environment where the `value`
1223
- * may not be set. This function works
1224
- * by returning the first selected date and then
1225
- * falling back to defaultParts if no active date
1226
- * is selected.
1227
- */
1228
- getActivePartsWithFallback = () => {
1229
- const { defaultParts } = this;
1230
- return this.getActivePart() ?? defaultParts;
1231
- };
1232
- getActivePart = () => {
1233
- const { activeParts } = this;
1234
- return Array.isArray(activeParts) ? activeParts[0] : activeParts;
1235
- };
1236
- closeParentOverlay = (role) => {
1237
- const popoverOrModal = this.el.closest('ion-modal, ion-popover');
1238
- if (popoverOrModal) {
1239
- popoverOrModal.dismiss(undefined, role);
1240
- }
1241
- };
1242
- setWorkingParts = (parts) => {
1243
- this.workingParts = {
1244
- ...parts,
1245
- };
1246
- };
1247
- setActiveParts = (parts, removeDate = false) => {
1248
- /** if the datetime component is in readonly mode,
1249
- * allow browsing of the calendar without changing
1250
- * the set value
1251
- */
1252
- if (this.readonly) {
1253
- return;
1254
- }
1255
- const { multiple, minParts, maxParts, activeParts } = this;
1256
- /**
1257
- * When setting the active parts, it is possible
1258
- * to set invalid data. For example,
1259
- * when updating January 31 to February,
1260
- * February 31 does not exist. As a result
1261
- * we need to validate the active parts and
1262
- * ensure that we are only setting valid dates.
1263
- * Additionally, we need to update the working parts
1264
- * too in the event that the validated parts are different.
1265
- */
1266
- const validatedParts = validateParts(parts, minParts, maxParts);
1267
- this.setWorkingParts(validatedParts);
1268
- if (multiple) {
1269
- const activePartsArray = Array.isArray(activeParts) ? activeParts : [activeParts];
1270
- if (removeDate) {
1271
- this.activeParts = activePartsArray.filter((p) => !isSameDay(p, validatedParts));
1272
- }
1273
- else {
1274
- this.activeParts = [...activePartsArray, validatedParts];
1275
- }
1276
- }
1277
- else {
1278
- this.activeParts = {
1279
- ...validatedParts,
1280
- };
1281
- }
1282
- const hasSlottedButtons = this.el.querySelector('[slot="buttons"]') !== null;
1283
- if (hasSlottedButtons || this.showDefaultButtons) {
1284
- return;
1285
- }
1286
- this.confirm();
1287
- };
1288
1648
  get isCalendarPicker() {
1289
1649
  const { presentation } = this;
1290
1650
  return presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
1291
1651
  }
1292
- initializeKeyboardListeners = () => {
1293
- const calendarBodyRef = this.calendarBodyRef;
1294
- if (!calendarBodyRef) {
1295
- return;
1296
- }
1297
- const root = this.el.shadowRoot;
1298
- /**
1299
- * Get a reference to the month
1300
- * element we are currently viewing.
1301
- */
1302
- const currentMonth = calendarBodyRef.querySelector('.calendar-month:nth-of-type(2)');
1303
- /**
1304
- * When focusing the calendar body, we want to pass focus
1305
- * to the working day, but other days should
1306
- * only be accessible using the arrow keys. Pressing
1307
- * Tab should jump between bodies of selectable content.
1308
- */
1309
- const checkCalendarBodyFocus = (ev) => {
1310
- const record = ev[0];
1311
- /**
1312
- * If calendar body was already focused
1313
- * when this fired or if the calendar body
1314
- * if not currently focused, we should not re-focus
1315
- * the inner day.
1316
- */
1317
- if (record.oldValue?.includes('ion-focused') || !calendarBodyRef.classList.contains('ion-focused')) {
1318
- return;
1319
- }
1320
- this.focusWorkingDay(currentMonth);
1321
- };
1322
- const mo = new MutationObserver(checkCalendarBodyFocus);
1323
- mo.observe(calendarBodyRef, { attributeFilter: ['class'], attributeOldValue: true });
1324
- this.destroyKeyboardMO = () => {
1325
- mo?.disconnect();
1326
- };
1327
- /**
1328
- * We must use keydown not keyup as we want
1329
- * to prevent scrolling when using the arrow keys.
1330
- */
1331
- calendarBodyRef.addEventListener('keydown', (ev) => {
1332
- const activeElement = root.activeElement;
1333
- if (!activeElement || !activeElement.classList.contains('calendar-day')) {
1334
- return;
1335
- }
1336
- const parts = getPartsFromCalendarDay(activeElement);
1337
- let partsToFocus;
1338
- switch (ev.key) {
1339
- case 'ArrowDown':
1340
- ev.preventDefault();
1341
- partsToFocus = getNextWeek(parts);
1342
- break;
1343
- case 'ArrowUp':
1344
- ev.preventDefault();
1345
- partsToFocus = getPreviousWeek(parts);
1346
- break;
1347
- case 'ArrowRight':
1348
- ev.preventDefault();
1349
- partsToFocus = getNextDay(parts);
1350
- break;
1351
- case 'ArrowLeft':
1352
- ev.preventDefault();
1353
- partsToFocus = getPreviousDay(parts);
1354
- break;
1355
- case 'Home':
1356
- ev.preventDefault();
1357
- partsToFocus = getStartOfWeek(parts);
1358
- break;
1359
- case 'End':
1360
- ev.preventDefault();
1361
- partsToFocus = getEndOfWeek(parts);
1362
- break;
1363
- case 'PageUp':
1364
- ev.preventDefault();
1365
- partsToFocus = ev.shiftKey ? getPreviousYear(parts) : getPreviousMonth(parts);
1366
- break;
1367
- case 'PageDown':
1368
- ev.preventDefault();
1369
- partsToFocus = ev.shiftKey ? getNextYear(parts) : getNextMonth(parts);
1370
- break;
1371
- /**
1372
- * Do not preventDefault here
1373
- * as we do not want to override other
1374
- * browser defaults such as pressing Enter/Space
1375
- * to select a day.
1376
- */
1377
- default:
1378
- return;
1379
- }
1380
- /**
1381
- * If the day we want to move focus to is
1382
- * disabled, do not do anything.
1383
- */
1384
- if (isDayDisabled(partsToFocus, this.minParts, this.maxParts)) {
1385
- return;
1386
- }
1387
- this.setWorkingParts({
1388
- ...this.workingParts,
1389
- ...partsToFocus,
1390
- });
1391
- /**
1392
- * Give view a chance to re-render
1393
- * then move focus to the new working day
1394
- */
1395
- requestAnimationFrame(() => this.focusWorkingDay(currentMonth));
1396
- });
1397
- };
1398
- focusWorkingDay = (currentMonth) => {
1399
- /**
1400
- * Get the number of offset days so
1401
- * we know how much to offset our next selector by
1402
- * to grab the correct calendar-day element.
1403
- */
1404
- const { day, month, year } = this.workingParts;
1405
- const firstOfMonth = new Date(`${month}/1/${year}`).getDay();
1406
- const offset = firstOfMonth >= this.firstDayOfWeek
1407
- ? firstOfMonth - this.firstDayOfWeek
1408
- : 7 - (this.firstDayOfWeek - firstOfMonth);
1409
- if (day === null) {
1410
- return;
1411
- }
1412
- /**
1413
- * Get the calendar day element
1414
- * and focus it.
1415
- */
1416
- const dayEl = currentMonth.querySelector(`.calendar-day-wrapper:nth-of-type(${offset + day}) .calendar-day`);
1417
- if (dayEl) {
1418
- dayEl.focus();
1419
- }
1420
- };
1421
- processMinParts = () => {
1422
- const { min, defaultParts } = this;
1423
- if (min === undefined) {
1424
- this.minParts = undefined;
1425
- return;
1426
- }
1427
- this.minParts = parseMinParts(min, defaultParts);
1428
- };
1429
- processMaxParts = () => {
1430
- const { max, defaultParts } = this;
1431
- if (max === undefined) {
1432
- this.maxParts = undefined;
1433
- return;
1434
- }
1435
- this.maxParts = parseMaxParts(max, defaultParts);
1436
- };
1437
- initializeCalendarListener = () => {
1438
- const calendarBodyRef = this.calendarBodyRef;
1439
- if (!calendarBodyRef) {
1440
- return;
1441
- }
1442
- /**
1443
- * For performance reasons, we only render 3
1444
- * months at a time: The current month, the previous
1445
- * month, and the next month. We have a scroll listener
1446
- * on the calendar body to append/prepend new months.
1447
- *
1448
- * We can do this because Stencil is smart enough to not
1449
- * re-create the .calendar-month containers, but rather
1450
- * update the content within those containers.
1451
- *
1452
- * As an added bonus, WebKit has some troubles with
1453
- * scroll-snap-stop: always, so not rendering all of
1454
- * the months in a row allows us to mostly sidestep
1455
- * that issue.
1456
- */
1457
- const months = calendarBodyRef.querySelectorAll('.calendar-month');
1458
- const startMonth = months[0];
1459
- const workingMonth = months[1];
1460
- const endMonth = months[2];
1461
- const mode = getIonMode(this);
1462
- const needsiOSRubberBandFix = mode === 'ios' && typeof navigator !== 'undefined' && navigator.maxTouchPoints > 1;
1463
- /**
1464
- * Before setting up the scroll listener,
1465
- * scroll the middle month into view.
1466
- * scrollIntoView() will scroll entire page
1467
- * if element is not in viewport. Use scrollLeft instead.
1468
- */
1469
- writeTask(() => {
1470
- calendarBodyRef.scrollLeft = startMonth.clientWidth * (isRTL(this.el) ? -1 : 1);
1471
- const getChangedMonth = (parts) => {
1472
- const box = calendarBodyRef.getBoundingClientRect();
1473
- /**
1474
- * If the current scroll position is all the way to the left
1475
- * then we have scrolled to the previous month.
1476
- * Otherwise, assume that we have scrolled to the next
1477
- * month. We have a tolerance of 2px to account for
1478
- * sub pixel rendering.
1479
- *
1480
- * Check below the next line ensures that we did not
1481
- * swipe and abort (i.e. we swiped but we are still on the current month).
1482
- */
1483
- const condition = isRTL(this.el) ? calendarBodyRef.scrollLeft >= -2 : calendarBodyRef.scrollLeft <= 2;
1484
- const month = condition ? startMonth : endMonth;
1485
- /**
1486
- * The edge of the month must be lined up with
1487
- * the edge of the calendar body in order for
1488
- * the component to update. Otherwise, it
1489
- * may be the case that the user has paused their
1490
- * swipe or the browser has not finished snapping yet.
1491
- * Rather than check if the x values are equal,
1492
- * we give it a tolerance of 2px to account for
1493
- * sub pixel rendering.
1494
- */
1495
- const monthBox = month.getBoundingClientRect();
1496
- if (Math.abs(monthBox.x - box.x) > 2)
1497
- return;
1498
- /**
1499
- * If we're force-rendering a month, assume we've
1500
- * scrolled to that and return it.
1501
- *
1502
- * If forceRenderDate is ever used in a context where the
1503
- * forced month is not immediately auto-scrolled to, this
1504
- * should be updated to also check whether `month` has the
1505
- * same month and year as the forced date.
1506
- */
1507
- const { forceRenderDate } = this;
1508
- if (forceRenderDate !== undefined) {
1509
- return { month: forceRenderDate.month, year: forceRenderDate.year, day: forceRenderDate.day };
1510
- }
1511
- /**
1512
- * From here, we can determine if the start
1513
- * month or the end month was scrolled into view.
1514
- * If no month was changed, then we can return from
1515
- * the scroll callback early.
1516
- */
1517
- if (month === startMonth) {
1518
- return getPreviousMonth(parts);
1519
- }
1520
- else if (month === endMonth) {
1521
- return getNextMonth(parts);
1522
- }
1523
- else {
1524
- return;
1525
- }
1526
- };
1527
- const updateActiveMonth = () => {
1528
- if (needsiOSRubberBandFix) {
1529
- calendarBodyRef.style.removeProperty('pointer-events');
1530
- appliediOSRubberBandFix = false;
1531
- }
1532
- /**
1533
- * If the month did not change
1534
- * then we can return early.
1535
- */
1536
- const newDate = getChangedMonth(this.workingParts);
1537
- if (!newDate)
1538
- return;
1539
- const { month, day, year } = newDate;
1540
- if (isMonthDisabled({ month, year, day: null }, {
1541
- minParts: { ...this.minParts, day: null },
1542
- maxParts: { ...this.maxParts, day: null },
1543
- })) {
1544
- return;
1545
- }
1546
- /**
1547
- * Prevent scrolling for other browsers
1548
- * to give the DOM time to update and the container
1549
- * time to properly snap.
1550
- */
1551
- calendarBodyRef.style.setProperty('overflow', 'hidden');
1552
- /**
1553
- * Use a writeTask here to ensure
1554
- * that the state is updated and the
1555
- * correct month is scrolled into view
1556
- * in the same frame. This is not
1557
- * typically a problem on newer devices
1558
- * but older/slower device may have a flicker
1559
- * if we did not do this.
1560
- */
1561
- writeTask(() => {
1562
- this.setWorkingParts({
1563
- ...this.workingParts,
1564
- month,
1565
- day: day,
1566
- year,
1567
- });
1568
- calendarBodyRef.scrollLeft = workingMonth.clientWidth * (isRTL(this.el) ? -1 : 1);
1569
- calendarBodyRef.style.removeProperty('overflow');
1570
- if (this.resolveForceDateScrolling) {
1571
- this.resolveForceDateScrolling();
1572
- }
1573
- const activeEl = this.el.shadowRoot.activeElement;
1574
- if (activeEl && activeEl.classList.contains('calendar-day')) {
1575
- activeEl.closest('.calendar-body')?.focus();
1576
- }
1577
- });
1578
- };
1579
- /**
1580
- * When the container finishes scrolling we
1581
- * need to update the DOM with the selected month.
1582
- */
1583
- let scrollTimeout;
1584
- /**
1585
- * We do not want to attempt to set pointer-events
1586
- * multiple times within a single swipe gesture as
1587
- * that adds unnecessary work to the main thread.
1588
- */
1589
- let appliediOSRubberBandFix = false;
1590
- const scrollCallback = () => {
1591
- if (scrollTimeout) {
1592
- clearTimeout(scrollTimeout);
1593
- }
1594
- /**
1595
- * On iOS it is possible to quickly rubber band
1596
- * the scroll area before the scroll timeout has fired.
1597
- * This results in users reaching the end of the scrollable
1598
- * container before the DOM has updated.
1599
- * By setting `pointer-events: none` we can ensure that
1600
- * subsequent swipes do not happen while the container
1601
- * is snapping.
1602
- */
1603
- if (!appliediOSRubberBandFix && needsiOSRubberBandFix) {
1604
- calendarBodyRef.style.setProperty('pointer-events', 'none');
1605
- appliediOSRubberBandFix = true;
1606
- }
1607
- // Wait ~3 frames
1608
- scrollTimeout = setTimeout(updateActiveMonth, 50);
1609
- };
1610
- calendarBodyRef.addEventListener('scroll', scrollCallback);
1611
- this.destroyCalendarListener = () => {
1612
- calendarBodyRef.removeEventListener('scroll', scrollCallback);
1613
- };
1614
- });
1615
- };
1616
1652
  connectedCallback() {
1617
1653
  this.clearFocusVisible = startFocusVisible(this.el).destroy;
1618
1654
  this.loadTimeout = setTimeout(() => {
@@ -1626,66 +1662,10 @@ const Datetime = class {
1626
1662
  }
1627
1663
  this.loadTimeoutCleanup();
1628
1664
  }
1629
- /**
1630
- * Clean up all listeners except for the overlay
1631
- * listener. This is so that we can re-create the listeners
1632
- * if the datetime has been hidden/presented by a modal or popover.
1633
- */
1634
- destroyInteractionListeners = () => {
1635
- const { destroyCalendarListener, destroyKeyboardMO } = this;
1636
- if (destroyCalendarListener !== undefined) {
1637
- destroyCalendarListener();
1638
- }
1639
- if (destroyKeyboardMO !== undefined) {
1640
- destroyKeyboardMO();
1641
- }
1642
- };
1643
1665
  initializeListeners() {
1644
1666
  this.initializeCalendarListener();
1645
1667
  this.initializeKeyboardListeners();
1646
1668
  }
1647
- /**
1648
- * TODO(FW-6931): Remove this fallback upon solving the root cause
1649
- * Fallback to ensure the datetime becomes ready even if
1650
- * IntersectionObserver never reports it as intersecting.
1651
- *
1652
- * This is primarily used in environments where the observer
1653
- * might not fire as expected, such as when running under
1654
- * synthetic tests that stub IntersectionObserver.
1655
- */
1656
- ensureReadyIfVisible = () => {
1657
- if (this.el.classList.contains('datetime-ready')) {
1658
- return;
1659
- }
1660
- const rect = this.el.getBoundingClientRect();
1661
- if (rect.width === 0 || rect.height === 0) {
1662
- return;
1663
- }
1664
- this.markReady();
1665
- };
1666
- markReady = () => {
1667
- if (this.el.classList.contains('datetime-ready')) {
1668
- return;
1669
- }
1670
- this.initializeListeners();
1671
- /**
1672
- * TODO FW-2793: Datetime needs a frame to ensure that it
1673
- * can properly scroll contents into view. As a result
1674
- * we hide the scrollable content until after that frame
1675
- * so users do not see the content quickly shifting. The downside
1676
- * is that the content will pop into view a frame after. Maybe there
1677
- * is a better way to handle this?
1678
- */
1679
- writeTask(() => {
1680
- this.el.classList.add('datetime-ready');
1681
- });
1682
- };
1683
- loadTimeoutCleanup = () => {
1684
- if (this.loadTimeout) {
1685
- clearTimeout(this.loadTimeout);
1686
- this.loadTimeout = undefined;
1687
- }
1688
- };
1689
1669
  componentDidLoad() {
1690
1670
  const { el, intersectionTrackerRef } = this;
1691
1671
  /**
@@ -1829,119 +1809,6 @@ const Datetime = class {
1829
1809
  this.ionRender.emit();
1830
1810
  });
1831
1811
  }
1832
- processValue = (value) => {
1833
- const hasValue = value !== null && value !== undefined && value !== '' && (!Array.isArray(value) || value.length > 0);
1834
- const valueToProcess = hasValue ? parseDate(value) : this.defaultParts;
1835
- const { minParts, maxParts, workingParts, el } = this;
1836
- this.warnIfIncorrectValueUsage();
1837
- /**
1838
- * Return early if the value wasn't parsed correctly, such as
1839
- * if an improperly formatted date string was provided.
1840
- */
1841
- if (!valueToProcess) {
1842
- return;
1843
- }
1844
- /**
1845
- * Datetime should only warn of out of bounds values
1846
- * if set by the user. If the `value` is undefined,
1847
- * we will default to today's date which may be out
1848
- * of bounds. In this case, the warning makes it look
1849
- * like the developer did something wrong which is
1850
- * not true.
1851
- */
1852
- if (hasValue) {
1853
- warnIfValueOutOfBounds(valueToProcess, minParts, maxParts);
1854
- }
1855
- /**
1856
- * If there are multiple values, clamp to the last one.
1857
- * This is because the last value is the one that the user
1858
- * has most recently interacted with.
1859
- */
1860
- const singleValue = Array.isArray(valueToProcess) ? valueToProcess[valueToProcess.length - 1] : valueToProcess;
1861
- const targetValue = clampDate(singleValue, minParts, maxParts);
1862
- const { month, day, year, hour, minute } = targetValue;
1863
- const ampm = parseAmPm(hour);
1864
- /**
1865
- * Since `activeParts` indicates a value that been explicitly selected
1866
- * either by the user or the app, only update `activeParts` if the
1867
- * `value` property is set.
1868
- */
1869
- if (hasValue) {
1870
- if (Array.isArray(valueToProcess)) {
1871
- this.activeParts = [...valueToProcess];
1872
- }
1873
- else {
1874
- this.activeParts = {
1875
- month,
1876
- day,
1877
- year,
1878
- hour,
1879
- minute,
1880
- ampm,
1881
- };
1882
- }
1883
- }
1884
- else {
1885
- /**
1886
- * Reset the active parts if the value is not set.
1887
- * This will clear the selected calendar day when
1888
- * performing a clear action or using the reset() method.
1889
- */
1890
- this.activeParts = [];
1891
- }
1892
- const didChangeMonth = (month !== undefined && month !== workingParts.month) || (year !== undefined && year !== workingParts.year);
1893
- const bodyIsVisible = el.classList.contains('datetime-ready');
1894
- const { isGridStyle, showMonthAndYear } = this;
1895
- if (isGridStyle && didChangeMonth && bodyIsVisible && !showMonthAndYear) {
1896
- /**
1897
- * Only animate if:
1898
- * 1. We're using grid style (wheel style pickers should just jump to new value)
1899
- * 2. The month and/or year actually changed, and both are defined (otherwise there's nothing to animate to)
1900
- * 3. The calendar body is visible (prevents animation when in collapsed datetime-button, for example)
1901
- * 4. The month/year picker is not open (since you wouldn't see the animation anyway)
1902
- */
1903
- this.animateToDate(targetValue);
1904
- }
1905
- else {
1906
- this.setWorkingParts({
1907
- month,
1908
- day,
1909
- year,
1910
- hour,
1911
- minute,
1912
- ampm,
1913
- });
1914
- }
1915
- };
1916
- animateToDate = async (targetValue) => {
1917
- const { workingParts } = this;
1918
- /**
1919
- * Tell other render functions that we need to force the
1920
- * target month to appear in place of the actual next/prev month.
1921
- * Because this is a State variable, a rerender will be triggered
1922
- * automatically, updating the rendered months.
1923
- */
1924
- this.forceRenderDate = targetValue;
1925
- /**
1926
- * Flag that we've started scrolling to the forced date.
1927
- * The resolve function will be called by the datetime's
1928
- * scroll listener when it's done updating everything.
1929
- * This is a replacement for making prev/nextMonth async,
1930
- * since the logic we're waiting on is in a listener.
1931
- */
1932
- const forceDateScrollingPromise = new Promise((resolve) => {
1933
- this.resolveForceDateScrolling = resolve;
1934
- });
1935
- /**
1936
- * Animate smoothly to the forced month. This will also update
1937
- * workingParts and correct the surrounding months for us.
1938
- */
1939
- const targetMonthIsBefore = isBefore(targetValue, workingParts);
1940
- targetMonthIsBefore ? this.prevMonth() : this.nextMonth();
1941
- await forceDateScrollingPromise;
1942
- this.resolveForceDateScrolling = undefined;
1943
- this.forceRenderDate = undefined;
1944
- };
1945
1812
  componentWillLoad() {
1946
1813
  const { el, formatOptions, highlightedDates, multiple, presentation, preferWheel } = this;
1947
1814
  if (multiple) {
@@ -1992,52 +1859,6 @@ const Datetime = class {
1992
1859
  'interactive-disabled': this.disabled,
1993
1860
  });
1994
1861
  }
1995
- onFocus = () => {
1996
- this.ionFocus.emit();
1997
- };
1998
- onBlur = () => {
1999
- this.ionBlur.emit();
2000
- };
2001
- hasValue = () => {
2002
- return this.value != null;
2003
- };
2004
- nextMonth = () => {
2005
- const calendarBodyRef = this.calendarBodyRef;
2006
- if (!calendarBodyRef) {
2007
- return;
2008
- }
2009
- const nextMonth = calendarBodyRef.querySelector('.calendar-month:last-of-type');
2010
- if (!nextMonth) {
2011
- return;
2012
- }
2013
- const left = nextMonth.offsetWidth * 2;
2014
- const scrollMode = config.getBoolean('animated', true) ? 'smooth' : 'instant';
2015
- calendarBodyRef.scrollTo({
2016
- top: 0,
2017
- left: left * (isRTL(this.el) ? -1 : 1),
2018
- behavior: scrollMode,
2019
- });
2020
- };
2021
- prevMonth = () => {
2022
- const calendarBodyRef = this.calendarBodyRef;
2023
- if (!calendarBodyRef) {
2024
- return;
2025
- }
2026
- const prevMonth = calendarBodyRef.querySelector('.calendar-month:first-of-type');
2027
- if (!prevMonth) {
2028
- return;
2029
- }
2030
- const left = prevMonth.offsetWidth * 2;
2031
- const scrollMode = config.getBoolean('animated', true) ? 'smooth' : 'instant';
2032
- calendarBodyRef.scrollTo({
2033
- top: 0,
2034
- left: left * (isRTL(this.el) ? 1 : -1),
2035
- behavior: scrollMode,
2036
- });
2037
- };
2038
- toggleMonthAndYearView = () => {
2039
- this.showMonthAndYear = !this.showMonthAndYear;
2040
- };
2041
1862
  /**
2042
1863
  * Universal render methods
2043
1864
  * These are pieces of datetime that
@@ -2718,6 +2539,7 @@ const Datetime = class {
2718
2539
  }),
2719
2540
  } }, h("div", { key: '20889d3c68dd5109633c0e214411a63d6f3025bb', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
2720
2541
  }
2542
+ get el() { return getElement(this); }
2721
2543
  static get watchers() { return {
2722
2544
  "formatOptions": [{
2723
2545
  "formatOptionsChanged": 0