@ionic/core 8.8.17 → 8.8.18-dev.11786108988.1fd94742

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 (782) 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-0tt0PTAe.js +4 -0
  99. package/components/p-3dKnMgX5.js +4 -0
  100. package/components/p-6e_5igwn.js +4 -0
  101. package/components/{p--JUspHvy.js → p-AqD_wmvU.js} +1 -1
  102. package/components/p-B-FxiyeI.js +4 -0
  103. package/components/p-B4COLbAV.js +4 -0
  104. package/components/p-B9zzUBwR.js +4 -0
  105. package/components/p-BFU7kgcj.js +4 -0
  106. package/components/p-BMPN55of.js +4 -0
  107. package/components/p-BPbRjpb2.js +4 -0
  108. package/components/p-BSQPZ79H.js +4 -0
  109. package/{dist/ionic/p-KjNvRoEp.js → components/p-BXQ7upSC.js} +1 -1
  110. package/components/p-BhamHSw3.js +4 -0
  111. package/components/p-BrXE0XUu.js +4 -0
  112. package/components/p-Bv7Rqz3Z.js +4 -0
  113. package/components/p-Bw7MMRH7.js +4 -0
  114. package/components/p-C-X5vb8f.js +4 -0
  115. package/components/p-C117Majq.js +4 -0
  116. package/components/{p-ChIZKXUu.js → p-C6JOi8wS.js} +1 -1
  117. package/components/p-CCVPk59A.js +4 -0
  118. package/components/p-CEW4RXZO.js +4 -0
  119. package/components/p-CKMc290p.js +4 -0
  120. package/components/{p-BkKAANMJ.js → p-CO5nI-BZ.js} +1 -1
  121. package/components/p-COQ_7Wwc.js +4 -0
  122. package/components/p-CQbh6Be_.js +4 -0
  123. package/components/p-CQtcj8t7.js +4 -0
  124. package/components/p-Cap9bvqr.js +4 -0
  125. package/components/p-CdP7ze2J.js +4 -0
  126. package/components/p-CfyJ_Ogc.js +4 -0
  127. package/components/p-ChWC4-vA.js +4 -0
  128. package/components/p-CmKf4pgI.js +4 -0
  129. package/components/p-CqYSqB9_.js +4 -0
  130. package/{dist/ionic/p-DC3RagnA.js → components/p-Cwsd9bue.js} +1 -1
  131. package/components/{p-D3xo7hqU.js → p-D0pL_HuH.js} +1 -1
  132. package/components/p-D0xd6h3Q.js +4 -0
  133. package/components/p-D28LaDuR.js +4 -0
  134. package/components/p-D7-vHX0A.js +4 -0
  135. package/components/p-D9KqizZs.js +4 -0
  136. package/components/p-DIZE3CVV.js +4 -0
  137. package/components/p-DL8rd5jo.js +4 -0
  138. package/components/p-DRcApg6F.js +4 -0
  139. package/components/p-DTTnwMiS.js +4 -0
  140. package/components/p-DWCzVL3Y.js +4 -0
  141. package/components/p-DYmrV1HT.js +4 -0
  142. package/components/{p-DqLB8yFQ.js → p-Dcu-SAJG.js} +1 -1
  143. package/components/p-DnINLmwC.js +4 -0
  144. package/components/{p-DRugphUN.js → p-DsNz6_gM.js} +1 -1
  145. package/components/p-DtiuiOTk.js +4 -0
  146. package/components/p-DunYzubP.js +4 -0
  147. package/components/p-DwcSJ9u1.js +4 -0
  148. package/components/p-QCPSB1bo.js +4 -0
  149. package/components/p-RvtofbHn.js +4 -0
  150. package/components/p-TXPDHL13.js +4 -0
  151. package/components/p-WOFp6fXj.js +4 -0
  152. package/components/p-byZM6qHV.js +4 -0
  153. package/components/{p-C_hpsif8.js → p-ltNYIRmI.js} +1 -1
  154. package/components/p-miSGCTAU.js +4 -0
  155. package/components/p-mpdX3emm.js +4 -0
  156. package/components/p-nvqVLrWC.js +4 -0
  157. package/components/p-qiWM96Sz.js +4 -0
  158. package/components/p-vlF0Bcfd.js +4 -0
  159. package/dist/cjs/{animation-BJq0kcy2.js → animation-D5WDBRvT.js} +4 -4
  160. package/dist/cjs/{app-globals-BlqrqKTN.js → app-globals-C2s3Cbal.js} +1 -1
  161. package/dist/cjs/{button-active-0mPOKmV2.js → button-active-CXI2TseG.js} +3 -3
  162. package/dist/cjs/config-CjUbvdPW.js +36 -0
  163. package/dist/cjs/{dir-Cn0z1rJH.js → dir-Brx7VkvP.js} +1 -1
  164. package/dist/cjs/{format-PxvGiOik.js → format-ZfKtcdit.js} +40 -30
  165. package/dist/cjs/{framework-delegate-BtICZDHr.js → framework-delegate-Bdvk3JQO.js} +5 -7
  166. package/dist/cjs/{gesture-controller-dtqlP_q4.js → gesture-controller-BDUH7687.js} +15 -8
  167. package/dist/cjs/{haptic-ClPPQ_PS.js → haptic-Ch-X4gRx.js} +2 -3
  168. package/dist/cjs/{hardware-back-button-iUuF_76h.js → hardware-back-button-zr8zeYaH.js} +4 -4
  169. package/dist/cjs/{helpers-Cv23MFHM.js → helpers-DURh1XdY.js} +3 -3
  170. package/dist/cjs/{index-aC4x3Fk3.js → index-B7sCu6vN.js} +6 -7
  171. package/dist/cjs/{index-CIrkNXqJ.js → index-BnhnwL1o.js} +2 -2
  172. package/dist/cjs/{index-D81eLYUM.js → index-Btdix80K.js} +2 -2
  173. package/dist/cjs/{index-Ct7gcRif.js → index-CAThePqm.js} +4 -6
  174. package/dist/cjs/index-DhSx3VvD.js +429 -0
  175. package/dist/cjs/{index-BERfRao3.js → index-DsoHs7Ly.js} +5 -5
  176. package/dist/cjs/{index-CAvQ7Tka.js → index-P1nQxrpZ.js} +10 -4
  177. package/dist/cjs/{index-DqmRDbxg.js → index-wOmugbdg.js} +1 -1
  178. package/dist/cjs/index.cjs.js +18 -18
  179. package/dist/cjs/{input-shims-CFLg7uzj.js → input-shims-CPbWb84M.js} +9 -11
  180. package/dist/cjs/{input.utils-DetjmtH2.js → input.utils-CkASW3mE.js} +3 -4
  181. package/dist/cjs/ion-accordion_2.cjs.entry.js +368 -340
  182. package/dist/cjs/ion-action-sheet.cjs.entry.js +187 -76
  183. package/dist/cjs/ion-alert.cjs.entry.js +273 -111
  184. package/dist/cjs/ion-app_8.cjs.entry.js +306 -190
  185. package/dist/cjs/ion-avatar_3.cjs.entry.js +10 -4
  186. package/dist/cjs/ion-back-button.cjs.entry.js +47 -23
  187. package/dist/cjs/ion-backdrop.cjs.entry.js +18 -14
  188. package/dist/cjs/ion-breadcrumb_2.cjs.entry.js +199 -121
  189. package/dist/cjs/ion-button_2.cjs.entry.js +138 -66
  190. package/dist/cjs/ion-card_5.cjs.entry.js +82 -30
  191. package/dist/cjs/ion-checkbox.cjs.entry.js +152 -101
  192. package/dist/cjs/ion-chip.cjs.entry.js +17 -11
  193. package/dist/cjs/ion-col_3.cjs.entry.js +134 -10
  194. package/dist/cjs/ion-datetime-button.cjs.entry.js +253 -241
  195. package/dist/cjs/ion-datetime.cjs.entry.js +2767 -0
  196. package/dist/cjs/ion-fab_3.cjs.entry.js +139 -81
  197. package/dist/cjs/ion-img.cjs.entry.js +34 -12
  198. package/dist/cjs/ion-infinite-scroll_2.cjs.entry.js +100 -72
  199. package/dist/cjs/ion-input-otp.cjs.entry.js +433 -370
  200. package/dist/cjs/ion-input-password-toggle.cjs.entry.js +33 -19
  201. package/dist/cjs/ion-input.cjs.entry.js +314 -168
  202. package/dist/cjs/ion-item-option_3.cjs.entry.js +91 -51
  203. package/dist/cjs/ion-item_8.cjs.entry.js +181 -82
  204. package/dist/cjs/ion-loading.cjs.entry.js +146 -60
  205. package/dist/cjs/ion-menu_3.cjs.entry.js +163 -101
  206. package/dist/cjs/ion-modal.cjs.entry.js +418 -251
  207. package/dist/cjs/ion-nav_2.cjs.entry.js +100 -157
  208. package/dist/cjs/ion-picker-column-option.cjs.entry.js +37 -33
  209. package/dist/cjs/ion-picker-column.cjs.entry.js +417 -405
  210. package/dist/cjs/ion-picker.cjs.entry.js +401 -392
  211. package/dist/cjs/ion-popover.cjs.entry.js +319 -205
  212. package/dist/cjs/ion-progress-bar.cjs.entry.js +31 -25
  213. package/dist/cjs/ion-radio_2.cjs.entry.js +206 -133
  214. package/dist/cjs/ion-range.cjs.entry.js +302 -237
  215. package/dist/cjs/ion-refresher_2.cjs.entry.js +165 -93
  216. package/dist/cjs/ion-reorder_2.cjs.entry.js +53 -23
  217. package/dist/cjs/ion-ripple-effect.cjs.entry.js +14 -14
  218. package/dist/cjs/ion-route_4.cjs.entry.js +175 -71
  219. package/dist/cjs/ion-searchbar.cjs.entry.js +291 -200
  220. package/dist/cjs/ion-segment-content.cjs.entry.js +2 -2
  221. package/dist/cjs/ion-segment-view.cjs.entry.js +28 -17
  222. package/dist/cjs/ion-segment_2.cjs.entry.js +169 -126
  223. package/dist/cjs/ion-select-modal.cjs.entry.js +104 -48
  224. package/dist/cjs/ion-select_3.cjs.entry.js +759 -214
  225. package/dist/cjs/ion-spinner.cjs.entry.js +24 -10
  226. package/dist/cjs/ion-split-pane.cjs.entry.js +29 -16
  227. package/dist/cjs/ion-tab-bar_2.cjs.entry.js +100 -41
  228. package/dist/cjs/ion-tab_2.cjs.entry.js +53 -27
  229. package/dist/cjs/ion-text.cjs.entry.js +11 -5
  230. package/dist/cjs/ion-textarea.cjs.entry.js +263 -144
  231. package/dist/cjs/ion-toast.cjs.entry.js +236 -117
  232. package/dist/cjs/ion-toggle.cjs.entry.js +175 -122
  233. package/dist/cjs/{ionic-global-B-cA6LkY.js → ionic-global-dMut1Czp.js} +13 -8
  234. package/dist/cjs/ionic.cjs.js +4 -4
  235. package/dist/cjs/{ios.transition-BOSWOaiK.js → ios.transition-CeaFa0y2.js} +13 -17
  236. package/dist/cjs/{item-multiple-inputs-D-gyg57c.js → item-multiple-inputs-HQO5Iy9I.js} +1 -1
  237. package/dist/cjs/{keyboard-hHzlEQpk.js → keyboard-Cix5TVkD.js} +2 -2
  238. package/dist/cjs/{keyboard-UuAS4D_9.js → keyboard-cHxZlTyz.js} +2 -2
  239. package/dist/cjs/{keyboard-controller-GXBiBRKS.js → keyboard-controller-PtZoN2GS.js} +6 -6
  240. package/dist/cjs/loader.cjs.js +4 -4
  241. package/dist/cjs/{md.transition-B8-wBZqt.js → md.transition-D4Q5jny7.js} +7 -8
  242. package/dist/cjs/{notch-controller-18PzRGXd.js → notch-controller-fMfidI-7.js} +1 -1
  243. package/dist/cjs/overlay-control-label-D2sdL2O8.js +50 -0
  244. package/dist/cjs/{overlays-DdtIYQUH.js → overlays-C2qrqpHm.js} +48 -33
  245. package/dist/cjs/select-option-render-Dh16lTnA.js +123 -0
  246. package/dist/cjs/{status-tap-BXX8H8_Y.js → status-tap-CgjQ-6jq.js} +3 -3
  247. package/dist/cjs/{swipe-back-C0GCB18x.js → swipe-back-CmfRYdWQ.js} +5 -5
  248. package/dist/cjs/{theme-CeDs6Hcv.js → theme-Bw0rpaNN.js} +6 -1
  249. package/dist/collection/collection-manifest.json +6 -10
  250. package/dist/collection/components/accordion/accordion.js +315 -312
  251. package/dist/collection/components/accordion-group/accordion-group.js +48 -25
  252. package/dist/collection/components/action-sheet/action-sheet.ios.css +228 -2
  253. package/dist/collection/components/action-sheet/action-sheet.js +173 -64
  254. package/dist/collection/components/action-sheet/action-sheet.md.css +174 -2
  255. package/dist/collection/components/action-sheet/test/basic/fixture.js +3 -0
  256. package/dist/collection/components/alert/alert.ios.css +279 -10
  257. package/dist/collection/components/alert/alert.js +257 -97
  258. package/dist/collection/components/alert/alert.md.css +268 -20
  259. package/dist/collection/components/app/app.js +3 -0
  260. package/dist/collection/components/back-button/back-button.js +42 -19
  261. package/dist/collection/components/backdrop/backdrop.js +16 -14
  262. package/dist/collection/components/badge/badge.js +6 -0
  263. package/dist/collection/components/breadcrumb/breadcrumb.js +91 -30
  264. package/dist/collection/components/breadcrumbs/breadcrumbs.js +103 -88
  265. package/dist/collection/components/button/button.js +132 -61
  266. package/dist/collection/components/buttons/buttons.js +13 -15
  267. package/dist/collection/components/card/card.js +54 -21
  268. package/dist/collection/components/card-header/card-header.js +12 -8
  269. package/dist/collection/components/card-subtitle/card-subtitle.js +6 -0
  270. package/dist/collection/components/card-title/card-title.js +6 -0
  271. package/dist/collection/components/checkbox/checkbox.js +147 -97
  272. package/dist/collection/components/chip/chip.js +14 -10
  273. package/dist/collection/components/col/col.js +127 -3
  274. package/dist/collection/components/content/content.js +92 -64
  275. package/dist/collection/components/datetime/datetime.ios.css +42 -2
  276. package/dist/collection/components/datetime/datetime.js +1038 -803
  277. package/dist/collection/components/datetime/datetime.md.css +42 -1
  278. package/dist/collection/components/datetime/utils/data.js +13 -14
  279. package/dist/collection/components/datetime/utils/format.js +21 -11
  280. package/dist/collection/components/datetime/utils/manipulation.js +8 -8
  281. package/dist/collection/components/datetime/utils/parse.js +10 -10
  282. package/dist/collection/components/datetime/utils/state.js +8 -2
  283. package/dist/collection/components/datetime/utils/validate.js +4 -5
  284. package/dist/collection/components/datetime-button/datetime-button.ios.css +5 -0
  285. package/dist/collection/components/datetime-button/datetime-button.js +247 -237
  286. package/dist/collection/components/datetime-button/datetime-button.md.css +5 -0
  287. package/dist/collection/components/fab/fab.js +20 -13
  288. package/dist/collection/components/fab-button/fab-button.js +104 -55
  289. package/dist/collection/components/fab-list/fab-list.js +10 -11
  290. package/dist/collection/components/footer/footer.js +50 -44
  291. package/dist/collection/components/grid/grid.js +4 -6
  292. package/dist/collection/components/header/header.js +35 -25
  293. package/dist/collection/components/img/img.js +34 -10
  294. package/dist/collection/components/infinite-scroll/infinite-scroll.js +73 -66
  295. package/dist/collection/components/infinite-scroll-content/infinite-scroll-content.js +20 -3
  296. package/dist/collection/components/input/input.ios.css +1 -2
  297. package/dist/collection/components/input/input.js +309 -164
  298. package/dist/collection/components/input/input.md.css +1 -2
  299. package/dist/collection/components/input-otp/input-otp.js +428 -366
  300. package/dist/collection/components/input-password-toggle/input-password-toggle.js +29 -16
  301. package/dist/collection/components/item/item.js +99 -53
  302. package/dist/collection/components/item-divider/item-divider.js +15 -10
  303. package/dist/collection/components/item-option/item-option.js +49 -21
  304. package/dist/collection/components/item-options/item-options.js +10 -7
  305. package/dist/collection/components/item-sliding/item-sliding.js +26 -20
  306. package/dist/collection/components/label/label.js +24 -4
  307. package/dist/collection/components/list/list.js +10 -7
  308. package/dist/collection/components/list-header/list-header.js +10 -0
  309. package/dist/collection/components/loading/loading.js +135 -51
  310. package/dist/collection/components/menu/menu.js +101 -59
  311. package/dist/collection/components/menu-button/menu-button.js +29 -20
  312. package/dist/collection/components/menu-toggle/menu-toggle.js +20 -13
  313. package/dist/collection/components/modal/animations/ios.enter.js +1 -1
  314. package/dist/collection/components/modal/animations/md.enter.js +1 -1
  315. package/dist/collection/components/modal/gestures/sheet.js +6 -7
  316. package/dist/collection/components/modal/gestures/swipe-to-close.js +1 -2
  317. package/dist/collection/components/modal/modal.js +393 -224
  318. package/dist/collection/components/modal/safe-area-utils.js +4 -5
  319. package/dist/collection/components/modal/test/fixtures.js +3 -0
  320. package/dist/collection/components/nav/nav.js +69 -247
  321. package/dist/collection/components/nav/view-controller.js +7 -1
  322. package/dist/collection/components/nav-link/nav-link.js +20 -9
  323. package/dist/collection/components/note/note.js +6 -0
  324. package/dist/collection/components/picker/picker.js +398 -390
  325. package/dist/collection/components/picker-column/picker-column.css +3 -0
  326. package/dist/collection/components/picker-column/picker-column.js +414 -404
  327. package/dist/collection/components/picker-column-option/picker-column-option.js +33 -31
  328. package/dist/collection/components/picker-column-option/picker-column-option.md.css +6 -1
  329. package/dist/collection/components/popover/animations/ios.enter.js +1 -2
  330. package/dist/collection/components/popover/animations/md.enter.js +1 -2
  331. package/dist/collection/components/popover/popover.ios.css +15 -0
  332. package/dist/collection/components/popover/popover.js +302 -185
  333. package/dist/collection/components/popover/popover.md.css +15 -0
  334. package/dist/collection/components/popover/test/fixture.js +1 -0
  335. package/dist/collection/components/popover/utils.js +4 -6
  336. package/dist/collection/components/progress-bar/progress-bar.js +27 -23
  337. package/dist/collection/components/radio/radio.js +102 -66
  338. package/dist/collection/components/radio-group/radio-group.js +100 -65
  339. package/dist/collection/components/radio-group/test/fixtures.js +2 -0
  340. package/dist/collection/components/range/range.js +296 -232
  341. package/dist/collection/components/refresher/refresher.js +110 -78
  342. package/dist/collection/components/refresher-content/refresher-content.js +41 -4
  343. package/dist/collection/components/reorder/reorder.js +2 -1
  344. package/dist/collection/components/reorder-group/reorder-group.js +44 -15
  345. package/dist/collection/components/ripple-effect/ripple-effect.js +12 -13
  346. package/dist/collection/components/route/route.js +39 -10
  347. package/dist/collection/components/route-redirect/route-redirect.js +31 -0
  348. package/dist/collection/components/router/router.js +37 -33
  349. package/dist/collection/components/router/utils/dom.js +25 -7
  350. package/dist/collection/components/router/utils/matching.js +7 -9
  351. package/dist/collection/components/router/utils/parser.js +1 -1
  352. package/dist/collection/components/router/utils/path.js +0 -1
  353. package/dist/collection/components/router-link/router-link.js +37 -12
  354. package/dist/collection/components/router-outlet/router-outlet.js +82 -21
  355. package/dist/collection/components/row/row.js +1 -1
  356. package/dist/collection/components/searchbar/searchbar.js +289 -199
  357. package/dist/collection/components/segment/segment.js +120 -85
  358. package/dist/collection/components/segment-button/segment-button.js +43 -37
  359. package/dist/collection/components/segment-content/segment-content.js +1 -1
  360. package/dist/collection/components/segment-view/segment-view.js +26 -16
  361. package/dist/collection/components/select/select.ios.css +33 -0
  362. package/dist/collection/components/select/select.js +597 -166
  363. package/dist/collection/components/select/select.md.css +33 -0
  364. package/dist/collection/components/select-modal/select-modal.ios.css +218 -0
  365. package/dist/collection/components/select-modal/select-modal.js +92 -38
  366. package/dist/collection/components/select-modal/select-modal.md.css +164 -0
  367. package/dist/collection/components/select-modal/test/fixtures.js +8 -1
  368. package/dist/collection/components/select-option/select-option.js +110 -9
  369. package/dist/collection/components/select-popover/select-popover.ios.css +218 -0
  370. package/dist/collection/components/select-popover/select-popover.js +103 -36
  371. package/dist/collection/components/select-popover/select-popover.md.css +164 -0
  372. package/dist/collection/components/select-popover/test/fixtures.js +8 -1
  373. package/dist/collection/components/skeleton-text/skeleton-text.js +12 -8
  374. package/dist/collection/components/spinner/spinner.js +21 -9
  375. package/dist/collection/components/split-pane/split-pane.js +27 -15
  376. package/dist/collection/components/tab/tab.js +17 -6
  377. package/dist/collection/components/tab-bar/tab-bar.js +32 -14
  378. package/dist/collection/components/tab-button/tab-button.js +62 -23
  379. package/dist/collection/components/tabs/tabs.js +33 -20
  380. package/dist/collection/components/text/text.js +8 -2
  381. package/dist/collection/components/textarea/textarea.js +257 -139
  382. package/dist/collection/components/thumbnail/thumbnail.js +1 -1
  383. package/dist/collection/components/title/title.js +18 -2
  384. package/dist/collection/components/toast/toast.js +223 -106
  385. package/dist/collection/components/toggle/toggle.js +167 -115
  386. package/dist/collection/components/toolbar/toolbar.js +15 -7
  387. package/dist/collection/global/config.js +4 -6
  388. package/dist/collection/global/ionic-global.js +8 -2
  389. package/dist/collection/index.js +1 -1
  390. package/dist/collection/utils/animation/animation.js +3 -3
  391. package/dist/collection/utils/config.js +5 -4
  392. package/dist/collection/utils/focus-controller/index.js +1 -1
  393. package/dist/collection/utils/focus-trap.js +3 -3
  394. package/dist/collection/utils/framework-delegate.js +4 -6
  395. package/dist/collection/utils/gesture/gesture-controller.js +15 -8
  396. package/dist/collection/utils/gesture/index.js +10 -2
  397. package/dist/collection/utils/gesture/listener.js +1 -1
  398. package/dist/collection/utils/hardware-back-button.js +3 -3
  399. package/dist/collection/utils/helpers.js +2 -2
  400. package/dist/collection/utils/input-shims/hacks/scroll-assist.js +4 -5
  401. package/dist/collection/utils/input-shims/hacks/scroll-data.js +1 -2
  402. package/dist/collection/utils/keyboard/keyboard-controller.js +5 -5
  403. package/dist/collection/utils/keyboard/keyboard.js +1 -1
  404. package/dist/collection/utils/menu-controller/index.js +1 -2
  405. package/dist/collection/utils/native/haptic.js +2 -3
  406. package/dist/collection/utils/native/keyboard.js +2 -2
  407. package/dist/collection/utils/native/status-bar.js +1 -1
  408. package/dist/collection/utils/overlay-control-label.js +45 -0
  409. package/dist/collection/utils/overlays.js +38 -23
  410. package/dist/collection/utils/platform.js +4 -5
  411. package/dist/collection/utils/rtl/dir.js +1 -1
  412. package/dist/collection/utils/sanitization/index.js +276 -20
  413. package/dist/collection/utils/select-option-render.js +118 -0
  414. package/dist/collection/utils/slot-mutation-controller.js +1 -2
  415. package/dist/collection/utils/test/playwright/apply-keyboard-focus.js +1 -1
  416. package/dist/collection/utils/test/playwright/drag-element.js +2 -3
  417. package/dist/collection/utils/test/playwright/generator.js +3 -4
  418. package/dist/collection/utils/test/playwright/page/event-spy.js +11 -12
  419. package/dist/collection/utils/test/playwright/page/utils/goto.js +4 -5
  420. package/dist/collection/utils/test/playwright/page/utils/set-content.js +1 -1
  421. package/dist/collection/utils/test/playwright/page/utils/set-ion-viewport.js +2 -3
  422. package/dist/collection/utils/test/press-keys.js +10 -17
  423. package/dist/collection/utils/theme.js +6 -1
  424. package/dist/collection/utils/transition/ios.transition.js +9 -13
  425. package/dist/collection/utils/transition/md.transition.js +3 -4
  426. package/dist/docs.json +556 -1272
  427. package/dist/esm/{animation-DLJpuoEz.js → animation-CVK55yMY.js} +4 -4
  428. package/dist/esm/{app-globals-D0C5S4hU.js → app-globals-Bk1_t4sH.js} +1 -1
  429. package/dist/esm/{button-active-BSpTQmS9.js → button-active-CdCqmeT0.js} +3 -3
  430. package/dist/esm/config-DWCzVL3Y.js +32 -0
  431. package/dist/esm/{dir-C53feagD.js → dir-B-FxiyeI.js} +1 -1
  432. package/dist/esm/{format-CAmvpAez.js → format-sMi4BZ_l.js} +41 -31
  433. package/dist/esm/{framework-delegate-FnPGymXL.js → framework-delegate-BfAlKlW5.js} +5 -7
  434. package/dist/esm/{gesture-controller-BTEOs1at.js → gesture-controller-TXPDHL13.js} +15 -8
  435. package/dist/esm/{haptic-DzAMWJuk.js → haptic-Cq4UAeka.js} +2 -3
  436. package/dist/esm/{hardware-back-button-B93Gru0Y.js → hardware-back-button-DcHMMB9j.js} +4 -4
  437. package/dist/esm/{helpers-HEqiOzXb.js → helpers-BPcITY5s.js} +3 -3
  438. package/dist/esm/{index-BRHzoo00.js → index-B9GsUd2c.js} +2 -2
  439. package/dist/esm/{index-DV3sJJW8.js → index-BvabGprD.js} +2 -2
  440. package/dist/esm/{index-tcQvqkiX.js → index-D1CQtpUN.js} +5 -7
  441. package/dist/esm/index-DDa8edAS.js +424 -0
  442. package/dist/esm/{index-MEDq2S8l.js → index-DcUt1pPn.js} +2 -2
  443. package/dist/esm/{index-CfgBF1SE.js → index-DppOcPFQ.js} +10 -4
  444. package/dist/esm/{index-B_dQk_WE.js → index-DqVqy_Cy.js} +5 -5
  445. package/dist/esm/{index-Q6UPU0Ay.js → index-ks-BjikL.js} +6 -7
  446. package/dist/esm/index.js +16 -15
  447. package/dist/esm/{input-shims-D10mwcw1.js → input-shims-C1dCKVMO.js} +9 -11
  448. package/dist/esm/{input.utils-Y6NgW8bw.js → input.utils-Dd5xwlP6.js} +3 -4
  449. package/dist/esm/ion-accordion_2.entry.js +368 -340
  450. package/dist/esm/ion-action-sheet.entry.js +187 -76
  451. package/dist/esm/ion-alert.entry.js +272 -110
  452. package/dist/esm/ion-app_8.entry.js +306 -190
  453. package/dist/esm/ion-avatar_3.entry.js +10 -4
  454. package/dist/esm/ion-back-button.entry.js +47 -23
  455. package/dist/esm/ion-backdrop.entry.js +18 -14
  456. package/dist/esm/ion-breadcrumb_2.entry.js +199 -121
  457. package/dist/esm/ion-button_2.entry.js +138 -66
  458. package/dist/esm/ion-card_5.entry.js +82 -30
  459. package/dist/esm/ion-checkbox.entry.js +152 -101
  460. package/dist/esm/ion-chip.entry.js +17 -11
  461. package/dist/esm/ion-col_3.entry.js +134 -10
  462. package/dist/esm/ion-datetime-button.entry.js +253 -241
  463. package/dist/esm/ion-datetime.entry.js +2765 -0
  464. package/dist/esm/ion-fab_3.entry.js +139 -81
  465. package/dist/esm/ion-img.entry.js +34 -12
  466. package/dist/esm/ion-infinite-scroll_2.entry.js +99 -71
  467. package/dist/esm/ion-input-otp.entry.js +433 -370
  468. package/dist/esm/ion-input-password-toggle.entry.js +33 -19
  469. package/dist/esm/ion-input.entry.js +314 -168
  470. package/dist/esm/ion-item-option_3.entry.js +91 -51
  471. package/dist/esm/ion-item_8.entry.js +181 -82
  472. package/dist/esm/ion-loading.entry.js +145 -59
  473. package/dist/esm/ion-menu_3.entry.js +163 -101
  474. package/dist/esm/ion-modal.entry.js +418 -251
  475. package/dist/esm/ion-nav_2.entry.js +100 -157
  476. package/dist/esm/ion-picker-column-option.entry.js +37 -33
  477. package/dist/esm/ion-picker-column.entry.js +417 -405
  478. package/dist/esm/ion-picker.entry.js +401 -392
  479. package/dist/esm/ion-popover.entry.js +319 -205
  480. package/dist/esm/ion-progress-bar.entry.js +31 -25
  481. package/dist/esm/ion-radio_2.entry.js +206 -133
  482. package/dist/esm/ion-range.entry.js +302 -237
  483. package/dist/esm/ion-refresher_2.entry.js +163 -91
  484. package/dist/esm/ion-reorder_2.entry.js +53 -23
  485. package/dist/esm/ion-ripple-effect.entry.js +14 -14
  486. package/dist/esm/ion-route_4.entry.js +175 -71
  487. package/dist/esm/ion-searchbar.entry.js +291 -200
  488. package/dist/esm/ion-segment-content.entry.js +2 -2
  489. package/dist/esm/ion-segment-view.entry.js +28 -17
  490. package/dist/esm/ion-segment_2.entry.js +169 -126
  491. package/dist/esm/ion-select-modal.entry.js +104 -48
  492. package/dist/esm/ion-select_3.entry.js +760 -215
  493. package/dist/esm/ion-spinner.entry.js +24 -10
  494. package/dist/esm/ion-split-pane.entry.js +29 -16
  495. package/dist/esm/ion-tab-bar_2.entry.js +100 -41
  496. package/dist/esm/ion-tab_2.entry.js +53 -27
  497. package/dist/esm/ion-text.entry.js +11 -5
  498. package/dist/esm/ion-textarea.entry.js +263 -144
  499. package/dist/esm/ion-toast.entry.js +235 -116
  500. package/dist/esm/ion-toggle.entry.js +175 -122
  501. package/dist/esm/{ionic-global-Cp_eT4sZ.js → ionic-global-5bZ91kOL.js} +13 -8
  502. package/dist/esm/ionic.js +5 -5
  503. package/dist/esm/{ios.transition-ClFrsIrS.js → ios.transition-OcwIGkv9.js} +13 -17
  504. package/dist/esm/{item-multiple-inputs-DlNuqNJm.js → item-multiple-inputs-ifd3ZrqY.js} +1 -1
  505. package/dist/esm/{keyboard-ywgs5efA.js → keyboard-Cj8mLJeq.js} +2 -2
  506. package/dist/esm/{keyboard-CUw4ekVy.js → keyboard-DAF8GNJ9.js} +2 -2
  507. package/dist/esm/{keyboard-controller-BaaVITYt.js → keyboard-controller-DEwoa1ev.js} +6 -6
  508. package/dist/esm/loader.js +5 -5
  509. package/dist/esm/{md.transition-D0msQmzI.js → md.transition-BetdF0bc.js} +7 -8
  510. package/dist/esm/{notch-controller-DKDjU_O7.js → notch-controller-DBSn-Uat.js} +1 -1
  511. package/dist/esm/overlay-control-label-BSQPZ79H.js +47 -0
  512. package/dist/esm/{overlays-Dg0q2_tJ.js → overlays-DUzb9CQf.js} +48 -33
  513. package/dist/esm/select-option-render-DsW8svRr.js +121 -0
  514. package/dist/esm/{status-tap-Kan2W7sh.js → status-tap-C-wNhea0.js} +3 -3
  515. package/dist/esm/{swipe-back-DQ1q5MgD.js → swipe-back-D6YSgAn7.js} +5 -5
  516. package/dist/esm/{theme-DiVJyqlX.js → theme-byZM6qHV.js} +6 -1
  517. package/dist/html.html-data.json +52 -80
  518. package/dist/ionic/index.esm.js +1 -1
  519. package/dist/ionic/ionic.esm.js +1 -1
  520. package/dist/ionic/p-01eaee58.entry.js +4 -0
  521. package/dist/ionic/p-0c567140.entry.js +4 -0
  522. package/dist/ionic/p-105bb794.entry.js +4 -0
  523. package/dist/ionic/p-10d55bb6.entry.js +4 -0
  524. package/dist/ionic/p-173a87d8.entry.js +4 -0
  525. package/dist/ionic/p-178da672.entry.js +4 -0
  526. package/dist/ionic/p-1ead2857.entry.js +4 -0
  527. package/dist/ionic/p-224e2464.entry.js +4 -0
  528. package/dist/ionic/p-2268e718.entry.js +4 -0
  529. package/dist/ionic/p-2b5283f3.entry.js +4 -0
  530. package/dist/ionic/p-2b6decac.entry.js +4 -0
  531. package/dist/ionic/p-2da5d9c6.entry.js +4 -0
  532. package/dist/ionic/p-31890acd.entry.js +4 -0
  533. package/dist/ionic/p-34ef7425.entry.js +4 -0
  534. package/dist/ionic/p-34f7c1d8.entry.js +4 -0
  535. package/dist/ionic/p-3b1e6fa4.entry.js +4 -0
  536. package/dist/ionic/p-42fefd2c.entry.js +4 -0
  537. package/dist/ionic/p-440cd489.entry.js +4 -0
  538. package/dist/ionic/{p-aaeedb6b.entry.js → p-460da491.entry.js} +1 -1
  539. package/dist/ionic/p-53f680e8.entry.js +4 -0
  540. package/dist/ionic/p-57ba508f.entry.js +4 -0
  541. package/dist/ionic/p-599e5a75.entry.js +4 -0
  542. package/dist/ionic/p-5f670a9e.entry.js +4 -0
  543. package/dist/ionic/p-63502088.entry.js +4 -0
  544. package/dist/ionic/p-6e6bf45d.entry.js +4 -0
  545. package/dist/ionic/p-6f0b6a48.entry.js +4 -0
  546. package/dist/ionic/p-7438c462.entry.js +4 -0
  547. package/dist/ionic/p-747716e7.entry.js +4 -0
  548. package/dist/ionic/p-7759fcaf.entry.js +4 -0
  549. package/dist/ionic/p-7a8338e2.entry.js +4 -0
  550. package/dist/ionic/p-80f9f1dc.entry.js +4 -0
  551. package/dist/ionic/p-83ff4dcb.entry.js +4 -0
  552. package/dist/ionic/p-86f03895.entry.js +4 -0
  553. package/dist/ionic/p-87b8d70e.entry.js +4 -0
  554. package/dist/ionic/p-888236bf.entry.js +4 -0
  555. package/dist/ionic/p-8a92ca23.entry.js +4 -0
  556. package/dist/ionic/p-8c9af4ad.entry.js +4 -0
  557. package/dist/ionic/p-9669f546.entry.js +4 -0
  558. package/dist/ionic/p-9bcd8b74.entry.js +4 -0
  559. package/dist/ionic/p-B-FxiyeI.js +4 -0
  560. package/dist/ionic/p-B2trYd8K.js +4 -0
  561. package/dist/ionic/p-BMPN55of.js +4 -0
  562. package/dist/ionic/{p-DIuEbVLu.js → p-BNKr91bi.js} +1 -1
  563. package/dist/ionic/p-BSQPZ79H.js +4 -0
  564. package/dist/ionic/p-BSzG1VcX.js +4 -0
  565. package/dist/ionic/p-BVgBHS96.js +4 -0
  566. package/dist/ionic/p-BX2IOAqC.js +4 -0
  567. package/dist/ionic/p-BhamHSw3.js +4 -0
  568. package/dist/ionic/p-BufXJ_A8.js +4 -0
  569. package/dist/ionic/{p-DV3sJJW8.js → p-BvabGprD.js} +1 -1
  570. package/dist/ionic/p-C73UOs4m.js +4 -0
  571. package/{components/p-B-JJgYSG.js → dist/ionic/p-CHpEzg-o.js} +1 -1
  572. package/dist/ionic/p-CUSwMljM.js +4 -0
  573. package/dist/ionic/p-CeOSrSdu.js +4 -0
  574. package/dist/ionic/p-CfkB7_FV.js +4 -0
  575. package/dist/ionic/p-CmKf4pgI.js +4 -0
  576. package/dist/ionic/p-CnM-CMw7.js +4 -0
  577. package/dist/ionic/p-D1CQtpUN.js +5 -0
  578. package/dist/ionic/p-D5t_-oMk.js +4 -0
  579. package/dist/ionic/p-DVYb1IVZ.js +4 -0
  580. package/dist/ionic/p-DWCzVL3Y.js +4 -0
  581. package/dist/ionic/p-DfJ-SVJf.js +4 -0
  582. package/dist/ionic/p-DmXrLsoD.js +4 -0
  583. package/dist/ionic/p-DtLHAMFW.js +4 -0
  584. package/dist/ionic/p-Dtlob2JL.js +4 -0
  585. package/dist/ionic/p-F7ipfyOA.js +4 -0
  586. package/dist/ionic/{p-DoJvtrbw.js → p-I9ETXg5W.js} +1 -1
  587. package/dist/ionic/{p-Wk5HzclC.js → p-IaXd5VMv.js} +1 -1
  588. package/dist/ionic/p-T71k3C35.js +4 -0
  589. package/dist/ionic/p-TXPDHL13.js +4 -0
  590. package/dist/ionic/p-aL0G45tD.js +4 -0
  591. package/dist/ionic/p-acbb97c3.entry.js +4 -0
  592. package/dist/ionic/p-aeb85531.entry.js +4 -0
  593. package/dist/ionic/p-b157f80d.entry.js +4 -0
  594. package/dist/ionic/p-b158de5d.entry.js +4 -0
  595. package/dist/ionic/{p-c6e49f3f.entry.js → p-b40c9715.entry.js} +1 -1
  596. package/dist/ionic/p-b852101e.entry.js +4 -0
  597. package/dist/ionic/p-byZM6qHV.js +4 -0
  598. package/dist/ionic/p-c0d81bee.entry.js +4 -0
  599. package/dist/ionic/p-c8a327fb.entry.js +4 -0
  600. package/dist/ionic/p-d42ae99f.entry.js +4 -0
  601. package/dist/ionic/p-d47ff529.entry.js +4 -0
  602. package/dist/ionic/p-eHi73fGE.js +4 -0
  603. package/dist/ionic/p-eeabce92.entry.js +4 -0
  604. package/dist/ionic/p-efc66d77.entry.js +4 -0
  605. package/dist/ionic/p-f6d203dc.entry.js +4 -0
  606. package/dist/ionic/p-u2a770LZ.js +4 -0
  607. package/dist/types/components/img/img.d.ts +2 -0
  608. package/dist/types/components/input/input.d.ts +1 -1
  609. package/dist/types/components/modal/modal.d.ts +11 -4
  610. package/dist/types/components/nav/nav-interface.d.ts +0 -1
  611. package/dist/types/components/nav/nav.d.ts +2 -22
  612. package/dist/types/components/route/route.d.ts +1 -1
  613. package/dist/types/components/router-outlet/router-outlet.d.ts +7 -0
  614. package/dist/types/components/searchbar/searchbar.d.ts +1 -1
  615. package/dist/types/components/select/select-interface.d.ts +31 -0
  616. package/dist/types/components/select/select.d.ts +18 -0
  617. package/dist/types/components/select-option/select-option.d.ts +42 -1
  618. package/dist/types/components.d.ts +74 -311
  619. package/dist/types/index.d.ts +1 -1
  620. package/dist/types/interface.d.ts +0 -1
  621. package/dist/types/utils/config.d.ts +0 -8
  622. package/dist/types/utils/overlay-control-label.d.ts +32 -0
  623. package/dist/types/utils/overlays.d.ts +11 -9
  624. package/dist/types/utils/sanitization/index.d.ts +58 -2
  625. package/dist/types/utils/select-option-render.d.ts +53 -0
  626. package/dist/types/utils/test/playwright/playwright-page.d.ts +1 -1
  627. package/dist/types/utils/test/playwright/testExpect.d.ts +1 -1
  628. package/hydrate/index.js +10278 -7052
  629. package/hydrate/index.mjs +10278 -7052
  630. package/package.json +54 -11
  631. package/components/ion-picker-legacy-column.d.ts +0 -11
  632. package/components/ion-picker-legacy-column.js +0 -4
  633. package/components/ion-picker-legacy.d.ts +0 -11
  634. package/components/ion-picker-legacy.js +0 -4
  635. package/components/p-A3O24YmY.js +0 -4
  636. package/components/p-ABkNVeU9.js +0 -4
  637. package/components/p-B9jFTlwE.js +0 -4
  638. package/components/p-BLmJ0zRm.js +0 -4
  639. package/components/p-BMI53wYL.js +0 -4
  640. package/components/p-BSEgsdFI.js +0 -4
  641. package/components/p-BTEOs1at.js +0 -4
  642. package/components/p-BlIAuGv2.js +0 -4
  643. package/components/p-Bnsn6KaP.js +0 -4
  644. package/components/p-BsBCoGa-.js +0 -4
  645. package/components/p-Bz0dSlXZ.js +0 -4
  646. package/components/p-C53feagD.js +0 -4
  647. package/components/p-CHqRYvYm.js +0 -4
  648. package/components/p-CQGnMY3n.js +0 -4
  649. package/components/p-CSZf8_j0.js +0 -4
  650. package/components/p-C_xFdyXe.js +0 -4
  651. package/components/p-Cf2jSDS8.js +0 -4
  652. package/components/p-Cfx4M1Bn.js +0 -4
  653. package/components/p-CkMSOsFF.js +0 -4
  654. package/components/p-Cl0B-RWe.js +0 -4
  655. package/components/p-CmR5uXej.js +0 -4
  656. package/components/p-CsNJ1ULL.js +0 -4
  657. package/components/p-CtWGkNnJ.js +0 -4
  658. package/components/p-CzCbeKys.js +0 -4
  659. package/components/p-D-aHdMxW.js +0 -4
  660. package/components/p-D0d8qTwj.js +0 -4
  661. package/components/p-D13Eaw-8.js +0 -4
  662. package/components/p-D6Ynv7Xh.js +0 -4
  663. package/components/p-DCnGU1fF.js +0 -4
  664. package/components/p-DGvrK8dD.js +0 -4
  665. package/components/p-DHTSTb52.js +0 -4
  666. package/components/p-DJZp0KTQ.js +0 -4
  667. package/components/p-DOFCbuQR.js +0 -4
  668. package/components/p-DV5mPYQS.js +0 -4
  669. package/components/p-DWkAgceV.js +0 -4
  670. package/components/p-DiVJyqlX.js +0 -4
  671. package/components/p-DqZAXv2t.js +0 -4
  672. package/components/p-KEFO0w3i.js +0 -4
  673. package/components/p-Osve4qkc.js +0 -4
  674. package/components/p-SLS1rDZM.js +0 -4
  675. package/components/p-VWbRkLT7.js +0 -4
  676. package/components/p-aJ6PBUvj.js +0 -4
  677. package/components/p-cyNmxje6.js +0 -4
  678. package/components/p-gAg0kXZp.js +0 -4
  679. package/components/p-j5IxBIan.js +0 -4
  680. package/components/p-k_E4tX5Z.js +0 -4
  681. package/components/p-oD4kcBRX.js +0 -4
  682. package/components/p-rCa2eL0j.js +0 -4
  683. package/components/p-scxfI1Dd.js +0 -4
  684. package/components/p-sijaAIYG.js +0 -4
  685. package/components/p-yzCsOZE2.js +0 -4
  686. package/dist/cjs/config-xninhj0J.js +0 -201
  687. package/dist/cjs/ion-datetime_3.cjs.entry.js +0 -3164
  688. package/dist/collection/components/picker-legacy/animations/ios.enter.js +0 -27
  689. package/dist/collection/components/picker-legacy/animations/ios.leave.js +0 -23
  690. package/dist/collection/components/picker-legacy/picker-interface.js +0 -1
  691. package/dist/collection/components/picker-legacy/picker.ios.css +0 -300
  692. package/dist/collection/components/picker-legacy/picker.js +0 -890
  693. package/dist/collection/components/picker-legacy/picker.md.css +0 -287
  694. package/dist/collection/components/picker-legacy-column/picker-column.ios.css +0 -231
  695. package/dist/collection/components/picker-legacy-column/picker-column.js +0 -422
  696. package/dist/collection/components/picker-legacy-column/picker-column.md.css +0 -222
  697. package/dist/collection/components/picker-legacy-column/test/test.utils.js +0 -43
  698. package/dist/esm/config-DQCONYYp.js +0 -195
  699. package/dist/esm/ion-datetime_3.entry.js +0 -3160
  700. package/dist/ionic/p-01f81ea5.entry.js +0 -4
  701. package/dist/ionic/p-06c232a4.entry.js +0 -4
  702. package/dist/ionic/p-0dc33652.entry.js +0 -4
  703. package/dist/ionic/p-0fa9c382.entry.js +0 -4
  704. package/dist/ionic/p-10e833ef.entry.js +0 -4
  705. package/dist/ionic/p-20b1a044.entry.js +0 -4
  706. package/dist/ionic/p-21eb76d5.entry.js +0 -4
  707. package/dist/ionic/p-27d30585.entry.js +0 -4
  708. package/dist/ionic/p-2a05aa64.entry.js +0 -4
  709. package/dist/ionic/p-2b204c59.entry.js +0 -4
  710. package/dist/ionic/p-2bb2cb18.entry.js +0 -4
  711. package/dist/ionic/p-2fa58e80.entry.js +0 -4
  712. package/dist/ionic/p-3353c229.entry.js +0 -4
  713. package/dist/ionic/p-34586ead.entry.js +0 -4
  714. package/dist/ionic/p-37e720da.entry.js +0 -4
  715. package/dist/ionic/p-390ca786.entry.js +0 -4
  716. package/dist/ionic/p-3ae5f277.entry.js +0 -4
  717. package/dist/ionic/p-4654ae1c.entry.js +0 -4
  718. package/dist/ionic/p-4745f534.entry.js +0 -4
  719. package/dist/ionic/p-4858af1f.entry.js +0 -4
  720. package/dist/ionic/p-485fda23.entry.js +0 -4
  721. package/dist/ionic/p-4ac4f3d6.entry.js +0 -4
  722. package/dist/ionic/p-4baa5b82.entry.js +0 -4
  723. package/dist/ionic/p-4e92a11f.entry.js +0 -4
  724. package/dist/ionic/p-5018dfc8.entry.js +0 -4
  725. package/dist/ionic/p-50e1194a.entry.js +0 -4
  726. package/dist/ionic/p-5d1da0a2.entry.js +0 -4
  727. package/dist/ionic/p-5eb8e86d.entry.js +0 -4
  728. package/dist/ionic/p-65ebdf1b.entry.js +0 -4
  729. package/dist/ionic/p-75dc25ba.entry.js +0 -4
  730. package/dist/ionic/p-7c319341.entry.js +0 -4
  731. package/dist/ionic/p-829367ed.entry.js +0 -4
  732. package/dist/ionic/p-84d5ce05.entry.js +0 -4
  733. package/dist/ionic/p-874b4bd8.entry.js +0 -4
  734. package/dist/ionic/p-8eb8ee76.entry.js +0 -4
  735. package/dist/ionic/p-8fce95d5.entry.js +0 -4
  736. package/dist/ionic/p-9eeaBrnk.js +0 -4
  737. package/dist/ionic/p-9f1103ce.entry.js +0 -4
  738. package/dist/ionic/p-9f9db3a2.entry.js +0 -4
  739. package/dist/ionic/p-BGqMS-oh.js +0 -4
  740. package/dist/ionic/p-BTEOs1at.js +0 -4
  741. package/dist/ionic/p-BUFIpxKM.js +0 -4
  742. package/dist/ionic/p-C0eMdTCW.js +0 -4
  743. package/dist/ionic/p-C53feagD.js +0 -4
  744. package/dist/ionic/p-CFlfIb2g.js +0 -4
  745. package/dist/ionic/p-CKvCXMs9.js +0 -4
  746. package/dist/ionic/p-Cl0B-RWe.js +0 -4
  747. package/dist/ionic/p-CtWGkNnJ.js +0 -4
  748. package/dist/ionic/p-Cx3IXROA.js +0 -4
  749. package/dist/ionic/p-D-3ycHmd.js +0 -4
  750. package/dist/ionic/p-D13Eaw-8.js +0 -4
  751. package/dist/ionic/p-D4uTWt4-.js +0 -4
  752. package/dist/ionic/p-DSG2s2Eb.js +0 -4
  753. package/dist/ionic/p-Dfbt-q2k.js +0 -4
  754. package/dist/ionic/p-DiVJyqlX.js +0 -4
  755. package/dist/ionic/p-DqN5EA2O.js +0 -4
  756. package/dist/ionic/p-DzWaWHGc.js +0 -4
  757. package/dist/ionic/p-Nqf6uvGh.js +0 -4
  758. package/dist/ionic/p-SNAkTDfm.js +0 -4
  759. package/dist/ionic/p-VAemlbDS.js +0 -4
  760. package/dist/ionic/p-a3bdcae6.entry.js +0 -4
  761. package/dist/ionic/p-ad306193.entry.js +0 -4
  762. package/dist/ionic/p-b6a7397c.entry.js +0 -4
  763. package/dist/ionic/p-c0fb8edd.entry.js +0 -4
  764. package/dist/ionic/p-c38b648e.entry.js +0 -4
  765. package/dist/ionic/p-c4d8641b.entry.js +0 -4
  766. package/dist/ionic/p-ca2ab74d.entry.js +0 -4
  767. package/dist/ionic/p-d889ff6d.entry.js +0 -4
  768. package/dist/ionic/p-dfa8d673.entry.js +0 -4
  769. package/dist/ionic/p-e0be05c5.entry.js +0 -4
  770. package/dist/ionic/p-ef4c3bee.entry.js +0 -4
  771. package/dist/ionic/p-f386f6ae.entry.js +0 -4
  772. package/dist/ionic/p-mjKAFv89.js +0 -4
  773. package/dist/ionic/p-tcQvqkiX.js +0 -5
  774. package/dist/ionic/p-viFHDgRs.js +0 -4
  775. package/dist/ionic/p-xWb6fgfq.js +0 -4
  776. package/dist/types/components/picker-legacy/animations/ios.enter.d.ts +0 -5
  777. package/dist/types/components/picker-legacy/animations/ios.leave.d.ts +0 -5
  778. package/dist/types/components/picker-legacy/picker-interface.d.ts +0 -52
  779. package/dist/types/components/picker-legacy/picker.d.ts +0 -158
  780. package/dist/types/components/picker-legacy-column/picker-column.d.ts +0 -46
  781. package/dist/types/components/picker-legacy-column/test/test.utils.d.ts +0 -9
  782. /package/components/{p-CO7fmmxt.js → p-LpMHEu3v.js} +0 -0
@@ -54,775 +54,139 @@ import { checkForPresentationFormatMismatch, warnIfTimeZoneProvided } from "./ut
54
54
  * @part datetime-selected-date - The element that contains the selected date.
55
55
  */
56
56
  export class Datetime {
57
- constructor() {
58
- this.inputId = `ion-dt-${datetimeIds++}`;
59
- /**
60
- * Set true only by `visibleCallback`. Lets `hiddenCallback` ignore the
61
- * synthetic "not intersecting" entry IntersectionObserver fires on
62
- * `observe()` when the host mounts offscreen.
63
- */
64
- this.hasBeenIntersecting = false;
65
- this.prevPresentation = null;
66
- this.showMonthAndYear = false;
67
- this.activeParts = [];
68
- this.workingParts = {
69
- month: 5,
70
- day: 28,
71
- year: 2021,
72
- hour: 13,
73
- minute: 52,
74
- ampm: 'pm',
75
- isAdjacentDay: false,
76
- };
77
- this.isTimePopoverOpen = false;
78
- /**
79
- * The color to use from your application's color palette.
80
- * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`.
81
- * For more information on colors, see [theming](/docs/theming/basics).
82
- */
83
- this.color = 'primary';
84
- /**
85
- * The name of the control, which is submitted with the form data.
86
- */
87
- this.name = this.inputId;
88
- /**
89
- * If `true`, the user cannot interact with the datetime.
90
- */
91
- this.disabled = false;
92
- /**
93
- * If `true`, the datetime appears normal but the selected date cannot be changed.
94
- */
95
- this.readonly = false;
96
- /**
97
- * If `true`, the datetime calendar displays a six-week (42-day) layout,
98
- * including days from the previous and next months to fill the grid.
99
- * These adjacent days are selectable unless disabled.
100
- */
101
- this.showAdjacentDays = false;
102
- /**
103
- * Which values you want to select. `"date"` will show
104
- * a calendar picker to select the month, day, and year. `"time"`
105
- * will show a time picker to select the hour, minute, and (optionally)
106
- * AM/PM. `"date-time"` will show the date picker first and time picker second.
107
- * `"time-date"` will show the time picker first and date picker second.
108
- */
109
- this.presentation = 'date-time';
110
- /**
111
- * The text to display on the picker's cancel button.
112
- */
113
- this.cancelText = 'Cancel';
114
- /**
115
- * The text to display on the picker's "Done" button.
116
- */
117
- this.doneText = 'Done';
118
- /**
119
- * The text to display on the picker's "Clear" button.
120
- */
121
- this.clearText = 'Clear';
122
- /**
123
- * The locale to use for `ion-datetime`. This
124
- * impacts month and day name formatting.
125
- * The `"default"` value refers to the default
126
- * locale set by your device.
127
- */
128
- this.locale = 'default';
129
- /**
130
- * The first day of the week to use for `ion-datetime`. The
131
- * default value is `0` and represents Sunday.
132
- */
133
- this.firstDayOfWeek = 0;
134
- /**
135
- * If `true`, multiple dates can be selected at once. Only
136
- * applies to `presentation="date"` and `preferWheel="false"`.
137
- */
138
- this.multiple = false;
139
- /**
140
- * If `true`, a header will be shown above the calendar
141
- * picker. This will include both the slotted title, and
142
- * the selected date.
143
- */
144
- this.showDefaultTitle = false;
145
- /**
146
- * If `true`, the default "Cancel" and "OK" buttons
147
- * will be rendered at the bottom of the `ion-datetime`
148
- * component. Developers can also use the `button` slot
149
- * if they want to customize these buttons. If custom
150
- * buttons are set in the `button` slot then the
151
- * default buttons will not be rendered.
152
- */
153
- this.showDefaultButtons = false;
154
- /**
155
- * If `true`, a "Clear" button will be rendered alongside
156
- * the default "Cancel" and "OK" buttons at the bottom of the `ion-datetime`
157
- * component. Developers can also use the `button` slot
158
- * if they want to customize these buttons. If custom
159
- * buttons are set in the `button` slot then the
160
- * default buttons will not be rendered.
161
- */
162
- this.showClearButton = false;
163
- /**
164
- * If `true`, the default "Time" label will be rendered
165
- * for the time selector of the `ion-datetime` component.
166
- * Developers can also use the `time-label` slot
167
- * if they want to customize this label. If a custom
168
- * label is set in the `time-label` slot then the
169
- * default label will not be rendered.
170
- */
171
- this.showDefaultTimeLabel = true;
172
- /**
173
- * If `cover`, the `ion-datetime` will expand to cover the full width of its container.
174
- * If `fixed`, the `ion-datetime` will have a fixed width.
175
- */
176
- this.size = 'fixed';
177
- /**
178
- * If `true`, a wheel picker will be rendered instead of a calendar grid
179
- * where possible. If `false`, a calendar grid will be rendered instead of
180
- * a wheel picker where possible.
181
- *
182
- * A wheel picker can be rendered instead of a grid when `presentation` is
183
- * one of the following values: `"date"`, `"date-time"`, or `"time-date"`.
184
- *
185
- * A wheel picker will always be rendered regardless of
186
- * the `preferWheel` value when `presentation` is one of the following values:
187
- * `"time"`, `"month"`, `"month-year"`, or `"year"`.
188
- */
189
- this.preferWheel = false;
190
- this.warnIfIncorrectValueUsage = () => {
191
- const { multiple, value } = this;
192
- if (!multiple && Array.isArray(value)) {
193
- /**
194
- * We do some processing on the `value` array so
195
- * that it looks more like an array when logged to
196
- * the console.
197
- * Example given ['a', 'b']
198
- * Default toString() behavior: a,b
199
- * Custom behavior: ['a', 'b']
200
- */
201
- 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".
202
-
203
- Value Passed: [${value.map((v) => `'${v}'`).join(', ')}]
204
- `, this.el);
205
- }
206
- };
207
- this.setValue = (value) => {
208
- this.value = value;
209
- this.ionChange.emit({ value });
210
- };
211
- /**
212
- * Returns the DatetimePart interface
213
- * to use when rendering an initial set of
214
- * data. This should be used when rendering an
215
- * interface in an environment where the `value`
216
- * may not be set. This function works
217
- * by returning the first selected date and then
218
- * falling back to defaultParts if no active date
219
- * is selected.
220
- */
221
- this.getActivePartsWithFallback = () => {
222
- var _a;
223
- const { defaultParts } = this;
224
- return (_a = this.getActivePart()) !== null && _a !== void 0 ? _a : defaultParts;
225
- };
226
- this.getActivePart = () => {
227
- const { activeParts } = this;
228
- return Array.isArray(activeParts) ? activeParts[0] : activeParts;
229
- };
230
- this.closeParentOverlay = (role) => {
231
- const popoverOrModal = this.el.closest('ion-modal, ion-popover');
232
- if (popoverOrModal) {
233
- popoverOrModal.dismiss(undefined, role);
234
- }
235
- };
236
- this.setWorkingParts = (parts) => {
237
- this.workingParts = Object.assign({}, parts);
238
- };
239
- this.setActiveParts = (parts, removeDate = false) => {
240
- /** if the datetime component is in readonly mode,
241
- * allow browsing of the calendar without changing
242
- * the set value
243
- */
244
- if (this.readonly) {
245
- return;
246
- }
247
- const { multiple, minParts, maxParts, activeParts } = this;
248
- /**
249
- * When setting the active parts, it is possible
250
- * to set invalid data. For example,
251
- * when updating January 31 to February,
252
- * February 31 does not exist. As a result
253
- * we need to validate the active parts and
254
- * ensure that we are only setting valid dates.
255
- * Additionally, we need to update the working parts
256
- * too in the event that the validated parts are different.
257
- */
258
- const validatedParts = validateParts(parts, minParts, maxParts);
259
- this.setWorkingParts(validatedParts);
260
- if (multiple) {
261
- const activePartsArray = Array.isArray(activeParts) ? activeParts : [activeParts];
262
- if (removeDate) {
263
- this.activeParts = activePartsArray.filter((p) => !isSameDay(p, validatedParts));
264
- }
265
- else {
266
- this.activeParts = [...activePartsArray, validatedParts];
267
- }
268
- }
269
- else {
270
- this.activeParts = Object.assign({}, validatedParts);
271
- }
272
- const hasSlottedButtons = this.el.querySelector('[slot="buttons"]') !== null;
273
- if (hasSlottedButtons || this.showDefaultButtons) {
274
- return;
275
- }
276
- this.confirm();
277
- };
278
- this.initializeKeyboardListeners = () => {
279
- const calendarBodyRef = this.calendarBodyRef;
280
- if (!calendarBodyRef) {
281
- return;
282
- }
283
- const root = this.el.shadowRoot;
284
- /**
285
- * Get a reference to the month
286
- * element we are currently viewing.
287
- */
288
- const currentMonth = calendarBodyRef.querySelector('.calendar-month:nth-of-type(2)');
289
- /**
290
- * When focusing the calendar body, we want to pass focus
291
- * to the working day, but other days should
292
- * only be accessible using the arrow keys. Pressing
293
- * Tab should jump between bodies of selectable content.
294
- */
295
- const checkCalendarBodyFocus = (ev) => {
296
- var _a;
297
- const record = ev[0];
298
- /**
299
- * If calendar body was already focused
300
- * when this fired or if the calendar body
301
- * if not currently focused, we should not re-focus
302
- * the inner day.
303
- */
304
- if (((_a = record.oldValue) === null || _a === void 0 ? void 0 : _a.includes('ion-focused')) || !calendarBodyRef.classList.contains('ion-focused')) {
305
- return;
306
- }
307
- this.focusWorkingDay(currentMonth);
308
- };
309
- const mo = new MutationObserver(checkCalendarBodyFocus);
310
- mo.observe(calendarBodyRef, { attributeFilter: ['class'], attributeOldValue: true });
311
- this.destroyKeyboardMO = () => {
312
- mo === null || mo === void 0 ? void 0 : mo.disconnect();
313
- };
314
- /**
315
- * We must use keydown not keyup as we want
316
- * to prevent scrolling when using the arrow keys.
317
- */
318
- calendarBodyRef.addEventListener('keydown', (ev) => {
319
- const activeElement = root.activeElement;
320
- if (!activeElement || !activeElement.classList.contains('calendar-day')) {
321
- return;
322
- }
323
- const parts = getPartsFromCalendarDay(activeElement);
324
- let partsToFocus;
325
- switch (ev.key) {
326
- case 'ArrowDown':
327
- ev.preventDefault();
328
- partsToFocus = getNextWeek(parts);
329
- break;
330
- case 'ArrowUp':
331
- ev.preventDefault();
332
- partsToFocus = getPreviousWeek(parts);
333
- break;
334
- case 'ArrowRight':
335
- ev.preventDefault();
336
- partsToFocus = getNextDay(parts);
337
- break;
338
- case 'ArrowLeft':
339
- ev.preventDefault();
340
- partsToFocus = getPreviousDay(parts);
341
- break;
342
- case 'Home':
343
- ev.preventDefault();
344
- partsToFocus = getStartOfWeek(parts);
345
- break;
346
- case 'End':
347
- ev.preventDefault();
348
- partsToFocus = getEndOfWeek(parts);
349
- break;
350
- case 'PageUp':
351
- ev.preventDefault();
352
- partsToFocus = ev.shiftKey ? getPreviousYear(parts) : getPreviousMonth(parts);
353
- break;
354
- case 'PageDown':
355
- ev.preventDefault();
356
- partsToFocus = ev.shiftKey ? getNextYear(parts) : getNextMonth(parts);
357
- break;
358
- /**
359
- * Do not preventDefault here
360
- * as we do not want to override other
361
- * browser defaults such as pressing Enter/Space
362
- * to select a day.
363
- */
364
- default:
365
- return;
366
- }
367
- /**
368
- * If the day we want to move focus to is
369
- * disabled, do not do anything.
370
- */
371
- if (isDayDisabled(partsToFocus, this.minParts, this.maxParts)) {
372
- return;
373
- }
374
- this.setWorkingParts(Object.assign(Object.assign({}, this.workingParts), partsToFocus));
375
- /**
376
- * Give view a chance to re-render
377
- * then move focus to the new working day
378
- */
379
- requestAnimationFrame(() => this.focusWorkingDay(currentMonth));
380
- });
381
- };
382
- this.focusWorkingDay = (currentMonth) => {
383
- /**
384
- * Get the number of offset days so
385
- * we know how much to offset our next selector by
386
- * to grab the correct calendar-day element.
387
- */
388
- const { day, month, year } = this.workingParts;
389
- const firstOfMonth = new Date(`${month}/1/${year}`).getDay();
390
- const offset = firstOfMonth >= this.firstDayOfWeek
391
- ? firstOfMonth - this.firstDayOfWeek
392
- : 7 - (this.firstDayOfWeek - firstOfMonth);
393
- if (day === null) {
394
- return;
395
- }
396
- /**
397
- * Get the calendar day element
398
- * and focus it.
399
- */
400
- const dayEl = currentMonth.querySelector(`.calendar-day-wrapper:nth-of-type(${offset + day}) .calendar-day`);
401
- if (dayEl) {
402
- dayEl.focus();
403
- }
404
- };
405
- this.processMinParts = () => {
406
- const { min, defaultParts } = this;
407
- if (min === undefined) {
408
- this.minParts = undefined;
409
- return;
410
- }
411
- this.minParts = parseMinParts(min, defaultParts);
412
- };
413
- this.processMaxParts = () => {
414
- const { max, defaultParts } = this;
415
- if (max === undefined) {
416
- this.maxParts = undefined;
417
- return;
418
- }
419
- this.maxParts = parseMaxParts(max, defaultParts);
420
- };
421
- this.initializeCalendarListener = () => {
422
- const calendarBodyRef = this.calendarBodyRef;
423
- if (!calendarBodyRef) {
424
- return;
425
- }
426
- /**
427
- * For performance reasons, we only render 3
428
- * months at a time: The current month, the previous
429
- * month, and the next month. We have a scroll listener
430
- * on the calendar body to append/prepend new months.
431
- *
432
- * We can do this because Stencil is smart enough to not
433
- * re-create the .calendar-month containers, but rather
434
- * update the content within those containers.
435
- *
436
- * As an added bonus, WebKit has some troubles with
437
- * scroll-snap-stop: always, so not rendering all of
438
- * the months in a row allows us to mostly sidestep
439
- * that issue.
440
- */
441
- const months = calendarBodyRef.querySelectorAll('.calendar-month');
442
- const startMonth = months[0];
443
- const workingMonth = months[1];
444
- const endMonth = months[2];
445
- const mode = getIonMode(this);
446
- const needsiOSRubberBandFix = mode === 'ios' && typeof navigator !== 'undefined' && navigator.maxTouchPoints > 1;
447
- /**
448
- * Before setting up the scroll listener,
449
- * scroll the middle month into view.
450
- * scrollIntoView() will scroll entire page
451
- * if element is not in viewport. Use scrollLeft instead.
452
- */
453
- writeTask(() => {
454
- calendarBodyRef.scrollLeft = startMonth.clientWidth * (isRTL(this.el) ? -1 : 1);
455
- const getChangedMonth = (parts) => {
456
- const box = calendarBodyRef.getBoundingClientRect();
457
- /**
458
- * If the current scroll position is all the way to the left
459
- * then we have scrolled to the previous month.
460
- * Otherwise, assume that we have scrolled to the next
461
- * month. We have a tolerance of 2px to account for
462
- * sub pixel rendering.
463
- *
464
- * Check below the next line ensures that we did not
465
- * swipe and abort (i.e. we swiped but we are still on the current month).
466
- */
467
- const condition = isRTL(this.el) ? calendarBodyRef.scrollLeft >= -2 : calendarBodyRef.scrollLeft <= 2;
468
- const month = condition ? startMonth : endMonth;
469
- /**
470
- * The edge of the month must be lined up with
471
- * the edge of the calendar body in order for
472
- * the component to update. Otherwise, it
473
- * may be the case that the user has paused their
474
- * swipe or the browser has not finished snapping yet.
475
- * Rather than check if the x values are equal,
476
- * we give it a tolerance of 2px to account for
477
- * sub pixel rendering.
478
- */
479
- const monthBox = month.getBoundingClientRect();
480
- if (Math.abs(monthBox.x - box.x) > 2)
481
- return;
482
- /**
483
- * If we're force-rendering a month, assume we've
484
- * scrolled to that and return it.
485
- *
486
- * If forceRenderDate is ever used in a context where the
487
- * forced month is not immediately auto-scrolled to, this
488
- * should be updated to also check whether `month` has the
489
- * same month and year as the forced date.
490
- */
491
- const { forceRenderDate } = this;
492
- if (forceRenderDate !== undefined) {
493
- return { month: forceRenderDate.month, year: forceRenderDate.year, day: forceRenderDate.day };
494
- }
495
- /**
496
- * From here, we can determine if the start
497
- * month or the end month was scrolled into view.
498
- * If no month was changed, then we can return from
499
- * the scroll callback early.
500
- */
501
- if (month === startMonth) {
502
- return getPreviousMonth(parts);
503
- }
504
- else if (month === endMonth) {
505
- return getNextMonth(parts);
506
- }
507
- else {
508
- return;
509
- }
510
- };
511
- const updateActiveMonth = () => {
512
- if (needsiOSRubberBandFix) {
513
- calendarBodyRef.style.removeProperty('pointer-events');
514
- appliediOSRubberBandFix = false;
515
- }
516
- /**
517
- * If the month did not change
518
- * then we can return early.
519
- */
520
- const newDate = getChangedMonth(this.workingParts);
521
- if (!newDate)
522
- return;
523
- const { month, day, year } = newDate;
524
- if (isMonthDisabled({ month, year, day: null }, {
525
- minParts: Object.assign(Object.assign({}, this.minParts), { day: null }),
526
- maxParts: Object.assign(Object.assign({}, this.maxParts), { day: null }),
527
- })) {
528
- return;
529
- }
530
- /**
531
- * Prevent scrolling for other browsers
532
- * to give the DOM time to update and the container
533
- * time to properly snap.
534
- */
535
- calendarBodyRef.style.setProperty('overflow', 'hidden');
536
- /**
537
- * Use a writeTask here to ensure
538
- * that the state is updated and the
539
- * correct month is scrolled into view
540
- * in the same frame. This is not
541
- * typically a problem on newer devices
542
- * but older/slower device may have a flicker
543
- * if we did not do this.
544
- */
545
- writeTask(() => {
546
- var _a;
547
- this.setWorkingParts(Object.assign(Object.assign({}, this.workingParts), { month, day: day, year }));
548
- calendarBodyRef.scrollLeft = workingMonth.clientWidth * (isRTL(this.el) ? -1 : 1);
549
- calendarBodyRef.style.removeProperty('overflow');
550
- if (this.resolveForceDateScrolling) {
551
- this.resolveForceDateScrolling();
552
- }
553
- const activeEl = this.el.shadowRoot.activeElement;
554
- if (activeEl && activeEl.classList.contains('calendar-day')) {
555
- (_a = activeEl.closest('.calendar-body')) === null || _a === void 0 ? void 0 : _a.focus();
556
- }
557
- });
558
- };
559
- /**
560
- * When the container finishes scrolling we
561
- * need to update the DOM with the selected month.
562
- */
563
- let scrollTimeout;
564
- /**
565
- * We do not want to attempt to set pointer-events
566
- * multiple times within a single swipe gesture as
567
- * that adds unnecessary work to the main thread.
568
- */
569
- let appliediOSRubberBandFix = false;
570
- const scrollCallback = () => {
571
- if (scrollTimeout) {
572
- clearTimeout(scrollTimeout);
573
- }
574
- /**
575
- * On iOS it is possible to quickly rubber band
576
- * the scroll area before the scroll timeout has fired.
577
- * This results in users reaching the end of the scrollable
578
- * container before the DOM has updated.
579
- * By setting `pointer-events: none` we can ensure that
580
- * subsequent swipes do not happen while the container
581
- * is snapping.
582
- */
583
- if (!appliediOSRubberBandFix && needsiOSRubberBandFix) {
584
- calendarBodyRef.style.setProperty('pointer-events', 'none');
585
- appliediOSRubberBandFix = true;
586
- }
587
- // Wait ~3 frames
588
- scrollTimeout = setTimeout(updateActiveMonth, 50);
589
- };
590
- calendarBodyRef.addEventListener('scroll', scrollCallback);
591
- this.destroyCalendarListener = () => {
592
- calendarBodyRef.removeEventListener('scroll', scrollCallback);
593
- };
594
- });
595
- };
596
- /**
597
- * Clean up all listeners except for the overlay
598
- * listener. This is so that we can re-create the listeners
599
- * if the datetime has been hidden/presented by a modal or popover.
600
- */
601
- this.destroyInteractionListeners = () => {
602
- const { destroyCalendarListener, destroyKeyboardMO } = this;
603
- if (destroyCalendarListener !== undefined) {
604
- destroyCalendarListener();
605
- }
606
- if (destroyKeyboardMO !== undefined) {
607
- destroyKeyboardMO();
608
- }
609
- };
610
- /**
611
- * TODO(FW-6931): Remove this fallback upon solving the root cause
612
- * Fallback to ensure the datetime becomes ready even if
613
- * IntersectionObserver never reports it as intersecting.
614
- *
615
- * This is primarily used in environments where the observer
616
- * might not fire as expected, such as when running under
617
- * synthetic tests that stub IntersectionObserver.
618
- */
619
- this.ensureReadyIfVisible = () => {
620
- if (this.el.classList.contains('datetime-ready')) {
621
- return;
622
- }
623
- const rect = this.el.getBoundingClientRect();
624
- if (rect.width === 0 || rect.height === 0) {
625
- return;
626
- }
627
- this.markReady();
628
- };
629
- this.markReady = () => {
630
- if (this.el.classList.contains('datetime-ready')) {
631
- return;
632
- }
633
- this.initializeListeners();
634
- /**
635
- * TODO FW-2793: Datetime needs a frame to ensure that it
636
- * can properly scroll contents into view. As a result
637
- * we hide the scrollable content until after that frame
638
- * so users do not see the content quickly shifting. The downside
639
- * is that the content will pop into view a frame after. Maybe there
640
- * is a better way to handle this?
641
- */
642
- writeTask(() => {
643
- this.el.classList.add('datetime-ready');
644
- });
645
- };
646
- this.loadTimeoutCleanup = () => {
647
- if (this.loadTimeout) {
648
- clearTimeout(this.loadTimeout);
649
- this.loadTimeout = undefined;
650
- }
651
- };
652
- this.processValue = (value) => {
653
- const hasValue = value !== null && value !== undefined && value !== '' && (!Array.isArray(value) || value.length > 0);
654
- const valueToProcess = hasValue ? parseDate(value) : this.defaultParts;
655
- const { minParts, maxParts, workingParts, el } = this;
656
- this.warnIfIncorrectValueUsage();
657
- /**
658
- * Return early if the value wasn't parsed correctly, such as
659
- * if an improperly formatted date string was provided.
660
- */
661
- if (!valueToProcess) {
662
- return;
663
- }
664
- /**
665
- * Datetime should only warn of out of bounds values
666
- * if set by the user. If the `value` is undefined,
667
- * we will default to today's date which may be out
668
- * of bounds. In this case, the warning makes it look
669
- * like the developer did something wrong which is
670
- * not true.
671
- */
672
- if (hasValue) {
673
- warnIfValueOutOfBounds(valueToProcess, minParts, maxParts);
674
- }
675
- /**
676
- * If there are multiple values, clamp to the last one.
677
- * This is because the last value is the one that the user
678
- * has most recently interacted with.
679
- */
680
- const singleValue = Array.isArray(valueToProcess) ? valueToProcess[valueToProcess.length - 1] : valueToProcess;
681
- const targetValue = clampDate(singleValue, minParts, maxParts);
682
- const { month, day, year, hour, minute } = targetValue;
683
- const ampm = parseAmPm(hour);
684
- /**
685
- * Since `activeParts` indicates a value that been explicitly selected
686
- * either by the user or the app, only update `activeParts` if the
687
- * `value` property is set.
688
- */
689
- if (hasValue) {
690
- if (Array.isArray(valueToProcess)) {
691
- this.activeParts = [...valueToProcess];
692
- }
693
- else {
694
- this.activeParts = {
695
- month,
696
- day,
697
- year,
698
- hour,
699
- minute,
700
- ampm,
701
- };
702
- }
703
- }
704
- else {
705
- /**
706
- * Reset the active parts if the value is not set.
707
- * This will clear the selected calendar day when
708
- * performing a clear action or using the reset() method.
709
- */
710
- this.activeParts = [];
711
- }
712
- const didChangeMonth = (month !== undefined && month !== workingParts.month) || (year !== undefined && year !== workingParts.year);
713
- const bodyIsVisible = el.classList.contains('datetime-ready');
714
- const { isGridStyle, showMonthAndYear } = this;
715
- if (isGridStyle && didChangeMonth && bodyIsVisible && !showMonthAndYear) {
716
- /**
717
- * Only animate if:
718
- * 1. We're using grid style (wheel style pickers should just jump to new value)
719
- * 2. The month and/or year actually changed, and both are defined (otherwise there's nothing to animate to)
720
- * 3. The calendar body is visible (prevents animation when in collapsed datetime-button, for example)
721
- * 4. The month/year picker is not open (since you wouldn't see the animation anyway)
722
- */
723
- this.animateToDate(targetValue);
724
- }
725
- else {
726
- this.setWorkingParts({
727
- month,
728
- day,
729
- year,
730
- hour,
731
- minute,
732
- ampm,
733
- });
734
- }
735
- };
736
- this.animateToDate = async (targetValue) => {
737
- const { workingParts } = this;
738
- /**
739
- * Tell other render functions that we need to force the
740
- * target month to appear in place of the actual next/prev month.
741
- * Because this is a State variable, a rerender will be triggered
742
- * automatically, updating the rendered months.
743
- */
744
- this.forceRenderDate = targetValue;
745
- /**
746
- * Flag that we've started scrolling to the forced date.
747
- * The resolve function will be called by the datetime's
748
- * scroll listener when it's done updating everything.
749
- * This is a replacement for making prev/nextMonth async,
750
- * since the logic we're waiting on is in a listener.
751
- */
752
- const forceDateScrollingPromise = new Promise((resolve) => {
753
- this.resolveForceDateScrolling = resolve;
754
- });
755
- /**
756
- * Animate smoothly to the forced month. This will also update
757
- * workingParts and correct the surrounding months for us.
758
- */
759
- const targetMonthIsBefore = isBefore(targetValue, workingParts);
760
- targetMonthIsBefore ? this.prevMonth() : this.nextMonth();
761
- await forceDateScrollingPromise;
762
- this.resolveForceDateScrolling = undefined;
763
- this.forceRenderDate = undefined;
764
- };
765
- this.onFocus = () => {
766
- this.ionFocus.emit();
767
- };
768
- this.onBlur = () => {
769
- this.ionBlur.emit();
770
- };
771
- this.hasValue = () => {
772
- return this.value != null;
773
- };
774
- this.nextMonth = () => {
775
- const calendarBodyRef = this.calendarBodyRef;
776
- if (!calendarBodyRef) {
777
- return;
778
- }
779
- const nextMonth = calendarBodyRef.querySelector('.calendar-month:last-of-type');
780
- if (!nextMonth) {
781
- return;
782
- }
783
- const left = nextMonth.offsetWidth * 2;
784
- const scrollMode = config.getBoolean('animated', true) ? 'smooth' : 'instant';
785
- calendarBodyRef.scrollTo({
786
- top: 0,
787
- left: left * (isRTL(this.el) ? -1 : 1),
788
- behavior: scrollMode,
789
- });
790
- };
791
- this.prevMonth = () => {
792
- const calendarBodyRef = this.calendarBodyRef;
793
- if (!calendarBodyRef) {
794
- return;
795
- }
796
- const prevMonth = calendarBodyRef.querySelector('.calendar-month:first-of-type');
797
- if (!prevMonth) {
798
- return;
799
- }
800
- const left = prevMonth.offsetWidth * 2;
801
- const scrollMode = config.getBoolean('animated', true) ? 'smooth' : 'instant';
802
- calendarBodyRef.scrollTo({
803
- top: 0,
804
- left: left * (isRTL(this.el) ? 1 : -1),
805
- behavior: scrollMode,
806
- });
807
- };
808
- this.toggleMonthAndYearView = () => {
809
- this.showMonthAndYear = !this.showMonthAndYear;
810
- };
811
- }
57
+ inputId = `ion-dt-${datetimeIds++}`;
58
+ calendarBodyRef;
59
+ popoverRef;
60
+ intersectionTrackerRef;
61
+ clearFocusVisible;
62
+ parsedMinuteValues;
63
+ parsedHourValues;
64
+ parsedMonthValues;
65
+ parsedYearValues;
66
+ parsedDayValues;
67
+ destroyCalendarListener;
68
+ destroyKeyboardMO;
69
+ // TODO(FW-2832): types (DatetimeParts causes some errors that need untangling)
70
+ minParts;
71
+ maxParts;
72
+ todayParts;
73
+ defaultParts;
74
+ loadTimeout;
75
+ /**
76
+ * Set true only by `visibleCallback`. Lets `hiddenCallback` ignore the
77
+ * synthetic "not intersecting" entry IntersectionObserver fires on
78
+ * `observe()` when the host mounts offscreen.
79
+ */
80
+ hasBeenIntersecting = false;
81
+ prevPresentation = null;
82
+ resolveForceDateScrolling;
83
+ showMonthAndYear = false;
84
+ activeParts = [];
85
+ workingParts = {
86
+ month: 5,
87
+ day: 28,
88
+ year: 2021,
89
+ hour: 13,
90
+ minute: 52,
91
+ ampm: 'pm',
92
+ isAdjacentDay: false,
93
+ };
94
+ el;
95
+ isTimePopoverOpen = false;
96
+ /**
97
+ * When defined, will force the datetime to render the month
98
+ * containing the specified date. Currently, this should only
99
+ * be used to enable immediately auto-scrolling to the new month,
100
+ * and should then be reset to undefined once the transition is
101
+ * finished and the forced month is now in view.
102
+ *
103
+ * Applies to grid-style datetimes only.
104
+ */
105
+ forceRenderDate;
106
+ /**
107
+ * The color to use from your application's color palette.
108
+ * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`.
109
+ * For more information on colors, see [theming](/docs/theming/basics).
110
+ */
111
+ color;
112
+ /**
113
+ * The name of the control, which is submitted with the form data.
114
+ */
115
+ name = this.inputId;
116
+ /**
117
+ * If `true`, the user cannot interact with the datetime.
118
+ */
119
+ disabled = false;
120
+ /**
121
+ * Formatting options for dates and times.
122
+ * 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).
123
+ *
124
+ */
125
+ formatOptions;
812
126
  formatOptionsChanged() {
813
127
  const { el, formatOptions, presentation } = this;
814
128
  checkForPresentationFormatMismatch(el, presentation, formatOptions);
815
129
  warnIfTimeZoneProvided(el, formatOptions);
816
130
  }
131
+ /**
132
+ * If `true`, the datetime appears normal but the selected date cannot be changed.
133
+ */
134
+ readonly = false;
135
+ /**
136
+ * Returns if an individual date (calendar day) is enabled or disabled.
137
+ *
138
+ * If `true`, the day will be enabled/interactive.
139
+ * If `false`, the day will be disabled/non-interactive.
140
+ *
141
+ * The function accepts an ISO 8601 date string of a given day.
142
+ * By default, all days are enabled. Developers can use this function
143
+ * to write custom logic to disable certain days.
144
+ *
145
+ * The function is called for each rendered calendar day, for the previous, current and next month.
146
+ * Custom implementations should be optimized for performance to avoid jank.
147
+ */
148
+ isDateEnabled;
149
+ /**
150
+ * If `true`, the datetime calendar displays a six-week (42-day) layout,
151
+ * including days from the previous and next months to fill the grid.
152
+ * These adjacent days are selectable unless disabled.
153
+ */
154
+ showAdjacentDays = false;
817
155
  disabledChanged() {
818
156
  this.emitStyle();
819
157
  }
158
+ /**
159
+ * The minimum datetime allowed. Value must be a date string
160
+ * following the
161
+ * [ISO 8601 datetime format standard](https://www.w3.org/TR/NOTE-datetime),
162
+ * such as `1996-12-19`. The format does not have to be specific to an exact
163
+ * datetime. For example, the minimum could just be the year, such as `1994`.
164
+ * Defaults to the beginning of the year, 100 years ago from today.
165
+ */
166
+ min;
820
167
  minChanged() {
821
168
  this.processMinParts();
822
169
  }
170
+ /**
171
+ * The maximum datetime allowed. Value must be a date string
172
+ * following the
173
+ * [ISO 8601 datetime format standard](https://www.w3.org/TR/NOTE-datetime),
174
+ * `1996-12-19`. The format does not have to be specific to an exact
175
+ * datetime. For example, the maximum could just be the year, such as `1994`.
176
+ * Defaults to the end of this year.
177
+ */
178
+ max;
823
179
  maxChanged() {
824
180
  this.processMaxParts();
825
181
  }
182
+ /**
183
+ * Which values you want to select. `"date"` will show
184
+ * a calendar picker to select the month, day, and year. `"time"`
185
+ * will show a time picker to select the hour, minute, and (optionally)
186
+ * AM/PM. `"date-time"` will show the date picker first and time picker second.
187
+ * `"time-date"` will show the time picker first and date picker second.
188
+ */
189
+ presentation = 'date-time';
826
190
  presentationChanged() {
827
191
  const { el, formatOptions, presentation } = this;
828
192
  checkForPresentationFormatMismatch(el, presentation, formatOptions);
@@ -832,21 +196,116 @@ export class Datetime {
832
196
  const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
833
197
  return hasDatePresentation && !preferWheel;
834
198
  }
199
+ /**
200
+ * The text to display on the picker's cancel button.
201
+ */
202
+ cancelText = 'Cancel';
203
+ /**
204
+ * The text to display on the picker's "Done" button.
205
+ */
206
+ doneText = 'Done';
207
+ /**
208
+ * The text to display on the picker's "Clear" button.
209
+ */
210
+ clearText = 'Clear';
211
+ /**
212
+ * Values used to create the list of selectable years. By default
213
+ * the year values range between the `min` and `max` datetime inputs. However, to
214
+ * control exactly which years to display, the `yearValues` input can take a number, an array
215
+ * of numbers, or string of comma separated numbers. For example, to show upcoming and
216
+ * recent leap years, then this input's value would be `yearValues="2008,2012,2016,2020,2024"`.
217
+ */
218
+ yearValues;
835
219
  yearValuesChanged() {
836
220
  this.parsedYearValues = convertToArrayOfNumbers(this.yearValues);
837
221
  }
222
+ /**
223
+ * Values used to create the list of selectable months. By default
224
+ * the month values range from `1` to `12`. However, to control exactly which months to
225
+ * display, the `monthValues` input can take a number, an array of numbers, or a string of
226
+ * comma separated numbers. For example, if only summer months should be shown, then this
227
+ * input value would be `monthValues="6,7,8"`. Note that month numbers do *not* have a
228
+ * zero-based index, meaning January's value is `1`, and December's is `12`.
229
+ */
230
+ monthValues;
838
231
  monthValuesChanged() {
839
232
  this.parsedMonthValues = convertToArrayOfNumbers(this.monthValues);
840
233
  }
234
+ /**
235
+ * Values used to create the list of selectable days. By default
236
+ * every day is shown for the given month. However, to control exactly which days of
237
+ * the month to display, the `dayValues` input can take a number, an array of numbers, or
238
+ * a string of comma separated numbers. Note that even if the array days have an invalid
239
+ * number for the selected month, like `31` in February, it will correctly not show
240
+ * days which are not valid for the selected month.
241
+ */
242
+ dayValues;
841
243
  dayValuesChanged() {
842
244
  this.parsedDayValues = convertToArrayOfNumbers(this.dayValues);
843
245
  }
246
+ /**
247
+ * Values used to create the list of selectable hours. By default
248
+ * the hour values range from `0` to `23` for 24-hour, or `1` to `12` for 12-hour. However,
249
+ * to control exactly which hours to display, the `hourValues` input can take a number, an
250
+ * array of numbers, or a string of comma separated numbers.
251
+ */
252
+ hourValues;
844
253
  hourValuesChanged() {
845
254
  this.parsedHourValues = convertToArrayOfNumbers(this.hourValues);
846
255
  }
256
+ /**
257
+ * Values used to create the list of selectable minutes. By default
258
+ * the minutes range from `0` to `59`. However, to control exactly which minutes to display,
259
+ * the `minuteValues` input can take a number, an array of numbers, or a string of comma
260
+ * separated numbers. For example, if the minute selections should only be every 15 minutes,
261
+ * then this input value would be `minuteValues="0,15,30,45"`.
262
+ */
263
+ minuteValues;
847
264
  minuteValuesChanged() {
848
265
  this.parsedMinuteValues = convertToArrayOfNumbers(this.minuteValues);
849
266
  }
267
+ /**
268
+ * The locale to use for `ion-datetime`. This
269
+ * impacts month and day name formatting.
270
+ * The `"default"` value refers to the default
271
+ * locale set by your device.
272
+ */
273
+ locale = 'default';
274
+ /**
275
+ * The first day of the week to use for `ion-datetime`. The
276
+ * default value is `0` and represents Sunday.
277
+ */
278
+ firstDayOfWeek = 0;
279
+ /**
280
+ * A callback used to format the header text that shows how many
281
+ * dates are selected. Only used if there are 0 or more than 1
282
+ * selected (i.e. unused for exactly 1). By default, the header
283
+ * text is set to "numberOfDates days".
284
+ *
285
+ * See https://ionicframework.com/docs/troubleshooting/runtime#accessing-this
286
+ * if you need to access `this` from within the callback.
287
+ */
288
+ titleSelectedDatesFormatter;
289
+ /**
290
+ * If `true`, multiple dates can be selected at once. Only
291
+ * applies to `presentation="date"` and `preferWheel="false"`.
292
+ */
293
+ multiple = false;
294
+ /**
295
+ * Used to apply custom text and background colors to specific dates.
296
+ *
297
+ * Can be either an array of objects containing ISO strings and colors,
298
+ * or a callback that receives an ISO string and returns the colors.
299
+ *
300
+ * Only applies to the `date`, `date-time`, and `time-date` presentations,
301
+ * with `preferWheel="false"`.
302
+ */
303
+ highlightedDates;
304
+ /**
305
+ * The value of the datetime as a valid ISO 8601 datetime string.
306
+ * This should be an array of strings only when `multiple="true"`.
307
+ */
308
+ value;
850
309
  /**
851
310
  * Update the datetime value when the value changes
852
311
  */
@@ -858,6 +317,97 @@ export class Datetime {
858
317
  this.emitStyle();
859
318
  this.ionValueChange.emit({ value });
860
319
  }
320
+ /**
321
+ * If `true`, a header will be shown above the calendar
322
+ * picker. This will include both the slotted title, and
323
+ * the selected date.
324
+ */
325
+ showDefaultTitle = false;
326
+ /**
327
+ * If `true`, the default "Cancel" and "OK" buttons
328
+ * will be rendered at the bottom of the `ion-datetime`
329
+ * component. Developers can also use the `button` slot
330
+ * if they want to customize these buttons. If custom
331
+ * buttons are set in the `button` slot then the
332
+ * default buttons will not be rendered.
333
+ */
334
+ showDefaultButtons = false;
335
+ /**
336
+ * If `true`, a "Clear" button will be rendered alongside
337
+ * the default "Cancel" and "OK" buttons at the bottom of the `ion-datetime`
338
+ * component. Developers can also use the `button` slot
339
+ * if they want to customize these buttons. If custom
340
+ * buttons are set in the `button` slot then the
341
+ * default buttons will not be rendered.
342
+ */
343
+ showClearButton = false;
344
+ /**
345
+ * If `true`, the default "Time" label will be rendered
346
+ * for the time selector of the `ion-datetime` component.
347
+ * Developers can also use the `time-label` slot
348
+ * if they want to customize this label. If a custom
349
+ * label is set in the `time-label` slot then the
350
+ * default label will not be rendered.
351
+ */
352
+ showDefaultTimeLabel = true;
353
+ /**
354
+ * The hour cycle of the `ion-datetime`. If no value is set, this is
355
+ * specified by the current locale.
356
+ */
357
+ hourCycle;
358
+ /**
359
+ * If `cover`, the `ion-datetime` will expand to cover the full width of its container.
360
+ * If `fixed`, the `ion-datetime` will have a fixed width.
361
+ */
362
+ size = 'fixed';
363
+ /**
364
+ * If `true`, a wheel picker will be rendered instead of a calendar grid
365
+ * where possible. If `false`, a calendar grid will be rendered instead of
366
+ * a wheel picker where possible.
367
+ *
368
+ * A wheel picker can be rendered instead of a grid when `presentation` is
369
+ * one of the following values: `"date"`, `"date-time"`, or `"time-date"`.
370
+ *
371
+ * A wheel picker will always be rendered regardless of
372
+ * the `preferWheel` value when `presentation` is one of the following values:
373
+ * `"time"`, `"month"`, `"month-year"`, or `"year"`.
374
+ */
375
+ preferWheel = false;
376
+ /**
377
+ * Emitted when the datetime selection was cancelled.
378
+ */
379
+ ionCancel;
380
+ /**
381
+ * Emitted when the value (selected date) has changed.
382
+ *
383
+ * This event will not emit when programmatically setting the `value` property.
384
+ */
385
+ ionChange;
386
+ /**
387
+ * Emitted when the value property has changed.
388
+ * This is used to ensure that ion-datetime-button can respond
389
+ * to any value property changes.
390
+ * @internal
391
+ */
392
+ ionValueChange;
393
+ /**
394
+ * Emitted when the datetime has focus.
395
+ */
396
+ ionFocus;
397
+ /**
398
+ * Emitted when the datetime loses focus.
399
+ */
400
+ ionBlur;
401
+ /**
402
+ * Emitted when the styles change.
403
+ * @internal
404
+ */
405
+ ionStyle;
406
+ /**
407
+ * Emitted when componentDidRender is fired.
408
+ * @internal
409
+ */
410
+ ionRender;
861
411
  /**
862
412
  * Confirms the selected datetime value, updates the
863
413
  * `value` property, and optionally closes the popover
@@ -927,10 +477,425 @@ export class Datetime {
927
477
  async getDefaultPart() {
928
478
  return this.defaultParts;
929
479
  }
480
+ warnIfIncorrectValueUsage = () => {
481
+ const { multiple, value } = this;
482
+ if (!multiple && Array.isArray(value)) {
483
+ /**
484
+ * We do some processing on the `value` array so
485
+ * that it looks more like an array when logged to
486
+ * the console.
487
+ * Example given ['a', 'b']
488
+ * Default toString() behavior: a,b
489
+ * Custom behavior: ['a', 'b']
490
+ */
491
+ 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".
492
+
493
+ Value Passed: [${value.map((v) => `'${v}'`).join(', ')}]
494
+ `, this.el);
495
+ }
496
+ };
497
+ setValue = (value) => {
498
+ this.value = value;
499
+ this.ionChange.emit({ value });
500
+ };
501
+ /**
502
+ * Returns the DatetimePart interface
503
+ * to use when rendering an initial set of
504
+ * data. This should be used when rendering an
505
+ * interface in an environment where the `value`
506
+ * may not be set. This function works
507
+ * by returning the first selected date and then
508
+ * falling back to defaultParts if no active date
509
+ * is selected.
510
+ */
511
+ getActivePartsWithFallback = () => {
512
+ const { defaultParts } = this;
513
+ return this.getActivePart() ?? defaultParts;
514
+ };
515
+ getActivePart = () => {
516
+ const { activeParts } = this;
517
+ return Array.isArray(activeParts) ? activeParts[0] : activeParts;
518
+ };
519
+ closeParentOverlay = (role) => {
520
+ const popoverOrModal = this.el.closest('ion-modal, ion-popover');
521
+ if (popoverOrModal) {
522
+ popoverOrModal.dismiss(undefined, role);
523
+ }
524
+ };
525
+ setWorkingParts = (parts) => {
526
+ this.workingParts = {
527
+ ...parts,
528
+ };
529
+ };
530
+ setActiveParts = (parts, removeDate = false) => {
531
+ /** if the datetime component is in readonly mode,
532
+ * allow browsing of the calendar without changing
533
+ * the set value
534
+ */
535
+ if (this.readonly) {
536
+ return;
537
+ }
538
+ const { multiple, minParts, maxParts, activeParts } = this;
539
+ /**
540
+ * When setting the active parts, it is possible
541
+ * to set invalid data. For example,
542
+ * when updating January 31 to February,
543
+ * February 31 does not exist. As a result
544
+ * we need to validate the active parts and
545
+ * ensure that we are only setting valid dates.
546
+ * Additionally, we need to update the working parts
547
+ * too in the event that the validated parts are different.
548
+ */
549
+ const validatedParts = validateParts(parts, minParts, maxParts);
550
+ this.setWorkingParts(validatedParts);
551
+ if (multiple) {
552
+ const activePartsArray = Array.isArray(activeParts) ? activeParts : [activeParts];
553
+ if (removeDate) {
554
+ this.activeParts = activePartsArray.filter((p) => !isSameDay(p, validatedParts));
555
+ }
556
+ else {
557
+ this.activeParts = [...activePartsArray, validatedParts];
558
+ }
559
+ }
560
+ else {
561
+ this.activeParts = {
562
+ ...validatedParts,
563
+ };
564
+ }
565
+ const hasSlottedButtons = this.el.querySelector('[slot="buttons"]') !== null;
566
+ if (hasSlottedButtons || this.showDefaultButtons) {
567
+ return;
568
+ }
569
+ this.confirm();
570
+ };
930
571
  get isCalendarPicker() {
931
572
  const { presentation } = this;
932
573
  return presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
933
574
  }
575
+ initializeKeyboardListeners = () => {
576
+ const calendarBodyRef = this.calendarBodyRef;
577
+ if (!calendarBodyRef) {
578
+ return;
579
+ }
580
+ const root = this.el.shadowRoot;
581
+ /**
582
+ * Get a reference to the month
583
+ * element we are currently viewing.
584
+ */
585
+ const currentMonth = calendarBodyRef.querySelector('.calendar-month:nth-of-type(2)');
586
+ /**
587
+ * When focusing the calendar body, we want to pass focus
588
+ * to the working day, but other days should
589
+ * only be accessible using the arrow keys. Pressing
590
+ * Tab should jump between bodies of selectable content.
591
+ */
592
+ const checkCalendarBodyFocus = (ev) => {
593
+ const record = ev[0];
594
+ /**
595
+ * If calendar body was already focused
596
+ * when this fired or if the calendar body
597
+ * if not currently focused, we should not re-focus
598
+ * the inner day.
599
+ */
600
+ if (record.oldValue?.includes('ion-focused') || !calendarBodyRef.classList.contains('ion-focused')) {
601
+ return;
602
+ }
603
+ this.focusWorkingDay(currentMonth);
604
+ };
605
+ const mo = new MutationObserver(checkCalendarBodyFocus);
606
+ mo.observe(calendarBodyRef, { attributeFilter: ['class'], attributeOldValue: true });
607
+ this.destroyKeyboardMO = () => {
608
+ mo?.disconnect();
609
+ };
610
+ /**
611
+ * We must use keydown not keyup as we want
612
+ * to prevent scrolling when using the arrow keys.
613
+ */
614
+ calendarBodyRef.addEventListener('keydown', (ev) => {
615
+ const activeElement = root.activeElement;
616
+ if (!activeElement || !activeElement.classList.contains('calendar-day')) {
617
+ return;
618
+ }
619
+ const parts = getPartsFromCalendarDay(activeElement);
620
+ let partsToFocus;
621
+ switch (ev.key) {
622
+ case 'ArrowDown':
623
+ ev.preventDefault();
624
+ partsToFocus = getNextWeek(parts);
625
+ break;
626
+ case 'ArrowUp':
627
+ ev.preventDefault();
628
+ partsToFocus = getPreviousWeek(parts);
629
+ break;
630
+ case 'ArrowRight':
631
+ ev.preventDefault();
632
+ partsToFocus = getNextDay(parts);
633
+ break;
634
+ case 'ArrowLeft':
635
+ ev.preventDefault();
636
+ partsToFocus = getPreviousDay(parts);
637
+ break;
638
+ case 'Home':
639
+ ev.preventDefault();
640
+ partsToFocus = getStartOfWeek(parts);
641
+ break;
642
+ case 'End':
643
+ ev.preventDefault();
644
+ partsToFocus = getEndOfWeek(parts);
645
+ break;
646
+ case 'PageUp':
647
+ ev.preventDefault();
648
+ partsToFocus = ev.shiftKey ? getPreviousYear(parts) : getPreviousMonth(parts);
649
+ break;
650
+ case 'PageDown':
651
+ ev.preventDefault();
652
+ partsToFocus = ev.shiftKey ? getNextYear(parts) : getNextMonth(parts);
653
+ break;
654
+ /**
655
+ * Do not preventDefault here
656
+ * as we do not want to override other
657
+ * browser defaults such as pressing Enter/Space
658
+ * to select a day.
659
+ */
660
+ default:
661
+ return;
662
+ }
663
+ /**
664
+ * If the day we want to move focus to is
665
+ * disabled, do not do anything.
666
+ */
667
+ if (isDayDisabled(partsToFocus, this.minParts, this.maxParts)) {
668
+ return;
669
+ }
670
+ this.setWorkingParts({
671
+ ...this.workingParts,
672
+ ...partsToFocus,
673
+ });
674
+ /**
675
+ * Give view a chance to re-render
676
+ * then move focus to the new working day
677
+ */
678
+ requestAnimationFrame(() => this.focusWorkingDay(currentMonth));
679
+ });
680
+ };
681
+ focusWorkingDay = (currentMonth) => {
682
+ /**
683
+ * Get the number of offset days so
684
+ * we know how much to offset our next selector by
685
+ * to grab the correct calendar-day element.
686
+ */
687
+ const { day, month, year } = this.workingParts;
688
+ const firstOfMonth = new Date(`${month}/1/${year}`).getDay();
689
+ const offset = firstOfMonth >= this.firstDayOfWeek
690
+ ? firstOfMonth - this.firstDayOfWeek
691
+ : 7 - (this.firstDayOfWeek - firstOfMonth);
692
+ if (day === null) {
693
+ return;
694
+ }
695
+ /**
696
+ * Get the calendar day element
697
+ * and focus it.
698
+ */
699
+ const dayEl = currentMonth.querySelector(`.calendar-day-wrapper:nth-of-type(${offset + day}) .calendar-day`);
700
+ if (dayEl) {
701
+ dayEl.focus();
702
+ }
703
+ };
704
+ processMinParts = () => {
705
+ const { min, defaultParts } = this;
706
+ if (min === undefined) {
707
+ this.minParts = undefined;
708
+ return;
709
+ }
710
+ this.minParts = parseMinParts(min, defaultParts);
711
+ };
712
+ processMaxParts = () => {
713
+ const { max, defaultParts } = this;
714
+ if (max === undefined) {
715
+ this.maxParts = undefined;
716
+ return;
717
+ }
718
+ this.maxParts = parseMaxParts(max, defaultParts);
719
+ };
720
+ initializeCalendarListener = () => {
721
+ const calendarBodyRef = this.calendarBodyRef;
722
+ if (!calendarBodyRef) {
723
+ return;
724
+ }
725
+ /**
726
+ * For performance reasons, we only render 3
727
+ * months at a time: The current month, the previous
728
+ * month, and the next month. We have a scroll listener
729
+ * on the calendar body to append/prepend new months.
730
+ *
731
+ * We can do this because Stencil is smart enough to not
732
+ * re-create the .calendar-month containers, but rather
733
+ * update the content within those containers.
734
+ *
735
+ * As an added bonus, WebKit has some troubles with
736
+ * scroll-snap-stop: always, so not rendering all of
737
+ * the months in a row allows us to mostly sidestep
738
+ * that issue.
739
+ */
740
+ const months = calendarBodyRef.querySelectorAll('.calendar-month');
741
+ const startMonth = months[0];
742
+ const workingMonth = months[1];
743
+ const endMonth = months[2];
744
+ const mode = getIonMode(this);
745
+ const needsiOSRubberBandFix = mode === 'ios' && typeof navigator !== 'undefined' && navigator.maxTouchPoints > 1;
746
+ /**
747
+ * Before setting up the scroll listener,
748
+ * scroll the middle month into view.
749
+ * scrollIntoView() will scroll entire page
750
+ * if element is not in viewport. Use scrollLeft instead.
751
+ */
752
+ writeTask(() => {
753
+ calendarBodyRef.scrollLeft = startMonth.clientWidth * (isRTL(this.el) ? -1 : 1);
754
+ const getChangedMonth = (parts) => {
755
+ const box = calendarBodyRef.getBoundingClientRect();
756
+ /**
757
+ * If the current scroll position is all the way to the left
758
+ * then we have scrolled to the previous month.
759
+ * Otherwise, assume that we have scrolled to the next
760
+ * month. We have a tolerance of 2px to account for
761
+ * sub pixel rendering.
762
+ *
763
+ * Check below the next line ensures that we did not
764
+ * swipe and abort (i.e. we swiped but we are still on the current month).
765
+ */
766
+ const condition = isRTL(this.el) ? calendarBodyRef.scrollLeft >= -2 : calendarBodyRef.scrollLeft <= 2;
767
+ const month = condition ? startMonth : endMonth;
768
+ /**
769
+ * The edge of the month must be lined up with
770
+ * the edge of the calendar body in order for
771
+ * the component to update. Otherwise, it
772
+ * may be the case that the user has paused their
773
+ * swipe or the browser has not finished snapping yet.
774
+ * Rather than check if the x values are equal,
775
+ * we give it a tolerance of 2px to account for
776
+ * sub pixel rendering.
777
+ */
778
+ const monthBox = month.getBoundingClientRect();
779
+ if (Math.abs(monthBox.x - box.x) > 2)
780
+ return;
781
+ /**
782
+ * If we're force-rendering a month, assume we've
783
+ * scrolled to that and return it.
784
+ *
785
+ * If forceRenderDate is ever used in a context where the
786
+ * forced month is not immediately auto-scrolled to, this
787
+ * should be updated to also check whether `month` has the
788
+ * same month and year as the forced date.
789
+ */
790
+ const { forceRenderDate } = this;
791
+ if (forceRenderDate !== undefined) {
792
+ return { month: forceRenderDate.month, year: forceRenderDate.year, day: forceRenderDate.day };
793
+ }
794
+ /**
795
+ * From here, we can determine if the start
796
+ * month or the end month was scrolled into view.
797
+ * If no month was changed, then we can return from
798
+ * the scroll callback early.
799
+ */
800
+ if (month === startMonth) {
801
+ return getPreviousMonth(parts);
802
+ }
803
+ else if (month === endMonth) {
804
+ return getNextMonth(parts);
805
+ }
806
+ else {
807
+ return;
808
+ }
809
+ };
810
+ const updateActiveMonth = () => {
811
+ if (needsiOSRubberBandFix) {
812
+ calendarBodyRef.style.removeProperty('pointer-events');
813
+ appliediOSRubberBandFix = false;
814
+ }
815
+ /**
816
+ * If the month did not change
817
+ * then we can return early.
818
+ */
819
+ const newDate = getChangedMonth(this.workingParts);
820
+ if (!newDate)
821
+ return;
822
+ const { month, day, year } = newDate;
823
+ if (isMonthDisabled({ month, year, day: null }, {
824
+ minParts: { ...this.minParts, day: null },
825
+ maxParts: { ...this.maxParts, day: null },
826
+ })) {
827
+ return;
828
+ }
829
+ /**
830
+ * Prevent scrolling for other browsers
831
+ * to give the DOM time to update and the container
832
+ * time to properly snap.
833
+ */
834
+ calendarBodyRef.style.setProperty('overflow', 'hidden');
835
+ /**
836
+ * Use a writeTask here to ensure
837
+ * that the state is updated and the
838
+ * correct month is scrolled into view
839
+ * in the same frame. This is not
840
+ * typically a problem on newer devices
841
+ * but older/slower device may have a flicker
842
+ * if we did not do this.
843
+ */
844
+ writeTask(() => {
845
+ this.setWorkingParts({
846
+ ...this.workingParts,
847
+ month,
848
+ day: day,
849
+ year,
850
+ });
851
+ calendarBodyRef.scrollLeft = workingMonth.clientWidth * (isRTL(this.el) ? -1 : 1);
852
+ calendarBodyRef.style.removeProperty('overflow');
853
+ if (this.resolveForceDateScrolling) {
854
+ this.resolveForceDateScrolling();
855
+ }
856
+ const activeEl = this.el.shadowRoot.activeElement;
857
+ if (activeEl && activeEl.classList.contains('calendar-day')) {
858
+ activeEl.closest('.calendar-body')?.focus();
859
+ }
860
+ });
861
+ };
862
+ /**
863
+ * When the container finishes scrolling we
864
+ * need to update the DOM with the selected month.
865
+ */
866
+ let scrollTimeout;
867
+ /**
868
+ * We do not want to attempt to set pointer-events
869
+ * multiple times within a single swipe gesture as
870
+ * that adds unnecessary work to the main thread.
871
+ */
872
+ let appliediOSRubberBandFix = false;
873
+ const scrollCallback = () => {
874
+ if (scrollTimeout) {
875
+ clearTimeout(scrollTimeout);
876
+ }
877
+ /**
878
+ * On iOS it is possible to quickly rubber band
879
+ * the scroll area before the scroll timeout has fired.
880
+ * This results in users reaching the end of the scrollable
881
+ * container before the DOM has updated.
882
+ * By setting `pointer-events: none` we can ensure that
883
+ * subsequent swipes do not happen while the container
884
+ * is snapping.
885
+ */
886
+ if (!appliediOSRubberBandFix && needsiOSRubberBandFix) {
887
+ calendarBodyRef.style.setProperty('pointer-events', 'none');
888
+ appliediOSRubberBandFix = true;
889
+ }
890
+ // Wait ~3 frames
891
+ scrollTimeout = setTimeout(updateActiveMonth, 50);
892
+ };
893
+ calendarBodyRef.addEventListener('scroll', scrollCallback);
894
+ this.destroyCalendarListener = () => {
895
+ calendarBodyRef.removeEventListener('scroll', scrollCallback);
896
+ };
897
+ });
898
+ };
934
899
  connectedCallback() {
935
900
  this.clearFocusVisible = startFocusVisible(this.el).destroy;
936
901
  this.loadTimeout = setTimeout(() => {
@@ -945,10 +910,66 @@ export class Datetime {
945
910
  this.loadTimeoutCleanup();
946
911
  this.hasBeenIntersecting = false;
947
912
  }
913
+ /**
914
+ * Clean up all listeners except for the overlay
915
+ * listener. This is so that we can re-create the listeners
916
+ * if the datetime has been hidden/presented by a modal or popover.
917
+ */
918
+ destroyInteractionListeners = () => {
919
+ const { destroyCalendarListener, destroyKeyboardMO } = this;
920
+ if (destroyCalendarListener !== undefined) {
921
+ destroyCalendarListener();
922
+ }
923
+ if (destroyKeyboardMO !== undefined) {
924
+ destroyKeyboardMO();
925
+ }
926
+ };
948
927
  initializeListeners() {
949
928
  this.initializeCalendarListener();
950
929
  this.initializeKeyboardListeners();
951
930
  }
931
+ /**
932
+ * TODO(FW-6931): Remove this fallback upon solving the root cause
933
+ * Fallback to ensure the datetime becomes ready even if
934
+ * IntersectionObserver never reports it as intersecting.
935
+ *
936
+ * This is primarily used in environments where the observer
937
+ * might not fire as expected, such as when running under
938
+ * synthetic tests that stub IntersectionObserver.
939
+ */
940
+ ensureReadyIfVisible = () => {
941
+ if (this.el.classList.contains('datetime-ready')) {
942
+ return;
943
+ }
944
+ const rect = this.el.getBoundingClientRect();
945
+ if (rect.width === 0 || rect.height === 0) {
946
+ return;
947
+ }
948
+ this.markReady();
949
+ };
950
+ markReady = () => {
951
+ if (this.el.classList.contains('datetime-ready')) {
952
+ return;
953
+ }
954
+ this.initializeListeners();
955
+ /**
956
+ * TODO FW-2793: Datetime needs a frame to ensure that it
957
+ * can properly scroll contents into view. As a result
958
+ * we hide the scrollable content until after that frame
959
+ * so users do not see the content quickly shifting. The downside
960
+ * is that the content will pop into view a frame after. Maybe there
961
+ * is a better way to handle this?
962
+ */
963
+ writeTask(() => {
964
+ this.el.classList.add('datetime-ready');
965
+ });
966
+ };
967
+ loadTimeoutCleanup = () => {
968
+ if (this.loadTimeout) {
969
+ clearTimeout(this.loadTimeout);
970
+ this.loadTimeout = undefined;
971
+ }
972
+ };
952
973
  componentDidLoad() {
953
974
  const { el, intersectionTrackerRef } = this;
954
975
  /**
@@ -973,7 +994,7 @@ export class Datetime {
973
994
  * could cause the datetime to start at a visibility of 0, erroneously
974
995
  * triggering the `hiddenIO` observer below.
975
996
  */
976
- raf(() => visibleIO === null || visibleIO === void 0 ? void 0 : visibleIO.observe(intersectionTrackerRef));
997
+ raf(() => visibleIO?.observe(intersectionTrackerRef));
977
998
  /**
978
999
  * TODO(FW-6931): Remove this fallback upon solving the root cause
979
1000
  * Fallback: If IntersectionObserver never reports that the
@@ -1019,7 +1040,7 @@ export class Datetime {
1019
1040
  });
1020
1041
  };
1021
1042
  const hiddenIO = new IntersectionObserver(hiddenCallback, { threshold: 0, root: el });
1022
- raf(() => hiddenIO === null || hiddenIO === void 0 ? void 0 : hiddenIO.observe(intersectionTrackerRef));
1043
+ raf(() => hiddenIO?.observe(intersectionTrackerRef));
1023
1044
  /**
1024
1045
  * Datetime uses Ionic components that emit
1025
1046
  * ionFocus and ionBlur. These events are
@@ -1092,6 +1113,119 @@ export class Datetime {
1092
1113
  this.ionRender.emit();
1093
1114
  });
1094
1115
  }
1116
+ processValue = (value) => {
1117
+ const hasValue = value !== null && value !== undefined && value !== '' && (!Array.isArray(value) || value.length > 0);
1118
+ const valueToProcess = hasValue ? parseDate(value) : this.defaultParts;
1119
+ const { minParts, maxParts, workingParts, el } = this;
1120
+ this.warnIfIncorrectValueUsage();
1121
+ /**
1122
+ * Return early if the value wasn't parsed correctly, such as
1123
+ * if an improperly formatted date string was provided.
1124
+ */
1125
+ if (!valueToProcess) {
1126
+ return;
1127
+ }
1128
+ /**
1129
+ * Datetime should only warn of out of bounds values
1130
+ * if set by the user. If the `value` is undefined,
1131
+ * we will default to today's date which may be out
1132
+ * of bounds. In this case, the warning makes it look
1133
+ * like the developer did something wrong which is
1134
+ * not true.
1135
+ */
1136
+ if (hasValue) {
1137
+ warnIfValueOutOfBounds(valueToProcess, minParts, maxParts);
1138
+ }
1139
+ /**
1140
+ * If there are multiple values, clamp to the last one.
1141
+ * This is because the last value is the one that the user
1142
+ * has most recently interacted with.
1143
+ */
1144
+ const singleValue = Array.isArray(valueToProcess) ? valueToProcess[valueToProcess.length - 1] : valueToProcess;
1145
+ const targetValue = clampDate(singleValue, minParts, maxParts);
1146
+ const { month, day, year, hour, minute } = targetValue;
1147
+ const ampm = parseAmPm(hour);
1148
+ /**
1149
+ * Since `activeParts` indicates a value that been explicitly selected
1150
+ * either by the user or the app, only update `activeParts` if the
1151
+ * `value` property is set.
1152
+ */
1153
+ if (hasValue) {
1154
+ if (Array.isArray(valueToProcess)) {
1155
+ this.activeParts = [...valueToProcess];
1156
+ }
1157
+ else {
1158
+ this.activeParts = {
1159
+ month,
1160
+ day,
1161
+ year,
1162
+ hour,
1163
+ minute,
1164
+ ampm,
1165
+ };
1166
+ }
1167
+ }
1168
+ else {
1169
+ /**
1170
+ * Reset the active parts if the value is not set.
1171
+ * This will clear the selected calendar day when
1172
+ * performing a clear action or using the reset() method.
1173
+ */
1174
+ this.activeParts = [];
1175
+ }
1176
+ const didChangeMonth = (month !== undefined && month !== workingParts.month) || (year !== undefined && year !== workingParts.year);
1177
+ const bodyIsVisible = el.classList.contains('datetime-ready');
1178
+ const { isGridStyle, showMonthAndYear } = this;
1179
+ if (isGridStyle && didChangeMonth && bodyIsVisible && !showMonthAndYear) {
1180
+ /**
1181
+ * Only animate if:
1182
+ * 1. We're using grid style (wheel style pickers should just jump to new value)
1183
+ * 2. The month and/or year actually changed, and both are defined (otherwise there's nothing to animate to)
1184
+ * 3. The calendar body is visible (prevents animation when in collapsed datetime-button, for example)
1185
+ * 4. The month/year picker is not open (since you wouldn't see the animation anyway)
1186
+ */
1187
+ this.animateToDate(targetValue);
1188
+ }
1189
+ else {
1190
+ this.setWorkingParts({
1191
+ month,
1192
+ day,
1193
+ year,
1194
+ hour,
1195
+ minute,
1196
+ ampm,
1197
+ });
1198
+ }
1199
+ };
1200
+ animateToDate = async (targetValue) => {
1201
+ const { workingParts } = this;
1202
+ /**
1203
+ * Tell other render functions that we need to force the
1204
+ * target month to appear in place of the actual next/prev month.
1205
+ * Because this is a State variable, a rerender will be triggered
1206
+ * automatically, updating the rendered months.
1207
+ */
1208
+ this.forceRenderDate = targetValue;
1209
+ /**
1210
+ * Flag that we've started scrolling to the forced date.
1211
+ * The resolve function will be called by the datetime's
1212
+ * scroll listener when it's done updating everything.
1213
+ * This is a replacement for making prev/nextMonth async,
1214
+ * since the logic we're waiting on is in a listener.
1215
+ */
1216
+ const forceDateScrollingPromise = new Promise((resolve) => {
1217
+ this.resolveForceDateScrolling = resolve;
1218
+ });
1219
+ /**
1220
+ * Animate smoothly to the forced month. This will also update
1221
+ * workingParts and correct the surrounding months for us.
1222
+ */
1223
+ const targetMonthIsBefore = isBefore(targetValue, workingParts);
1224
+ targetMonthIsBefore ? this.prevMonth() : this.nextMonth();
1225
+ await forceDateScrollingPromise;
1226
+ this.resolveForceDateScrolling = undefined;
1227
+ this.forceRenderDate = undefined;
1228
+ };
1095
1229
  componentWillLoad() {
1096
1230
  const { el, formatOptions, highlightedDates, multiple, presentation, preferWheel } = this;
1097
1231
  if (multiple) {
@@ -1142,6 +1276,52 @@ export class Datetime {
1142
1276
  'interactive-disabled': this.disabled,
1143
1277
  });
1144
1278
  }
1279
+ onFocus = () => {
1280
+ this.ionFocus.emit();
1281
+ };
1282
+ onBlur = () => {
1283
+ this.ionBlur.emit();
1284
+ };
1285
+ hasValue = () => {
1286
+ return this.value != null;
1287
+ };
1288
+ nextMonth = () => {
1289
+ const calendarBodyRef = this.calendarBodyRef;
1290
+ if (!calendarBodyRef) {
1291
+ return;
1292
+ }
1293
+ const nextMonth = calendarBodyRef.querySelector('.calendar-month:last-of-type');
1294
+ if (!nextMonth) {
1295
+ return;
1296
+ }
1297
+ const left = nextMonth.offsetWidth * 2;
1298
+ const scrollMode = config.getBoolean('animated', true) ? 'smooth' : 'instant';
1299
+ calendarBodyRef.scrollTo({
1300
+ top: 0,
1301
+ left: left * (isRTL(this.el) ? -1 : 1),
1302
+ behavior: scrollMode,
1303
+ });
1304
+ };
1305
+ prevMonth = () => {
1306
+ const calendarBodyRef = this.calendarBodyRef;
1307
+ if (!calendarBodyRef) {
1308
+ return;
1309
+ }
1310
+ const prevMonth = calendarBodyRef.querySelector('.calendar-month:first-of-type');
1311
+ if (!prevMonth) {
1312
+ return;
1313
+ }
1314
+ const left = prevMonth.offsetWidth * 2;
1315
+ const scrollMode = config.getBoolean('animated', true) ? 'smooth' : 'instant';
1316
+ calendarBodyRef.scrollTo({
1317
+ top: 0,
1318
+ left: left * (isRTL(this.el) ? 1 : -1),
1319
+ behavior: scrollMode,
1320
+ });
1321
+ };
1322
+ toggleMonthAndYearView = () => {
1323
+ this.showMonthAndYear = !this.showMonthAndYear;
1324
+ };
1145
1325
  /**
1146
1326
  * Universal render methods
1147
1327
  * These are pieces of datetime that
@@ -1240,7 +1420,10 @@ export class Datetime {
1240
1420
  catch (e) {
1241
1421
  printIonError('[ion-datetime] - Exception thrown from provided `isDateEnabled` function. Please check your function and try again.', e);
1242
1422
  }
1243
- return Object.assign(Object.assign({}, itemObject), { disabled });
1423
+ return {
1424
+ ...itemObject,
1425
+ disabled,
1426
+ };
1244
1427
  });
1245
1428
  }
1246
1429
  /**
@@ -1253,10 +1436,16 @@ export class Datetime {
1253
1436
  return (h("ion-picker-column", { part: WHEEL_PART, "aria-label": "Select a date", class: "date-column", color: this.color, disabled: disabled, value: todayString, onIonChange: (ev) => {
1254
1437
  const { value } = ev.detail;
1255
1438
  const findPart = parts.find(({ month, day, year }) => value === `${year}-${month}-${day}`);
1256
- this.setWorkingParts(Object.assign(Object.assign({}, workingParts), findPart));
1257
- this.setActiveParts(Object.assign(Object.assign({}, activePart), findPart));
1439
+ this.setWorkingParts({
1440
+ ...workingParts,
1441
+ ...findPart,
1442
+ });
1443
+ this.setActiveParts({
1444
+ ...activePart,
1445
+ ...findPart,
1446
+ });
1258
1447
  ev.stopPropagation();
1259
- } }, items.map((item) => (h("ion-picker-column-option", { part: item.value === todayString ? `${WHEEL_ITEM_PART} ${WHEEL_ITEM_ACTIVE_PART}` : WHEEL_ITEM_PART, key: item.value, disabled: item.disabled, value: item.value }, item.text)))));
1448
+ } }, items.map((item) => (h("ion-picker-column-option", { color: this.color, part: item.value === todayString ? `${WHEEL_ITEM_PART} ${WHEEL_ITEM_ACTIVE_PART}` : WHEEL_ITEM_PART, key: item.value, disabled: item.disabled, value: item.value }, item.text)))));
1260
1449
  }
1261
1450
  renderIndividualDatePickerColumns(forcePresentation) {
1262
1451
  const { workingParts, isDateEnabled } = this;
@@ -1289,7 +1478,10 @@ export class Datetime {
1289
1478
  catch (e) {
1290
1479
  printIonError('[ion-datetime] - Exception thrown from provided `isDateEnabled` function. Please check your function and try again.', e);
1291
1480
  }
1292
- return Object.assign(Object.assign({}, dayObject), { disabled });
1481
+ return {
1482
+ ...dayObject,
1483
+ disabled,
1484
+ };
1293
1485
  });
1294
1486
  }
1295
1487
  const shouldRenderYears = forcePresentation !== 'month' && forcePresentation !== 'time';
@@ -1318,18 +1510,23 @@ export class Datetime {
1318
1510
  return renderArray;
1319
1511
  }
1320
1512
  renderDayPickerColumn(days) {
1321
- var _a;
1322
1513
  if (days.length === 0) {
1323
1514
  return [];
1324
1515
  }
1325
1516
  const { disabled, workingParts } = this;
1326
1517
  const activePart = this.getActivePartsWithFallback();
1327
- const pickerColumnValue = (_a = (workingParts.day !== null ? workingParts.day : this.defaultParts.day)) !== null && _a !== void 0 ? _a : undefined;
1518
+ const pickerColumnValue = (workingParts.day !== null ? workingParts.day : this.defaultParts.day) ?? undefined;
1328
1519
  return (h("ion-picker-column", { part: WHEEL_PART, "aria-label": "Select a day", class: "day-column", color: this.color, disabled: disabled, value: pickerColumnValue, onIonChange: (ev) => {
1329
- this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { day: ev.detail.value }));
1330
- this.setActiveParts(Object.assign(Object.assign({}, activePart), { day: ev.detail.value }));
1520
+ this.setWorkingParts({
1521
+ ...workingParts,
1522
+ day: ev.detail.value,
1523
+ });
1524
+ this.setActiveParts({
1525
+ ...activePart,
1526
+ day: ev.detail.value,
1527
+ });
1331
1528
  ev.stopPropagation();
1332
- } }, days.map((day) => (h("ion-picker-column-option", { part: day.value === pickerColumnValue ? `${WHEEL_ITEM_PART} ${WHEEL_ITEM_ACTIVE_PART}` : WHEEL_ITEM_PART, key: day.value, disabled: day.disabled, value: day.value }, day.text)))));
1529
+ } }, days.map((day) => (h("ion-picker-column-option", { color: this.color, part: day.value === pickerColumnValue ? `${WHEEL_ITEM_PART} ${WHEEL_ITEM_ACTIVE_PART}` : WHEEL_ITEM_PART, key: day.value, disabled: day.disabled, value: day.value }, day.text)))));
1333
1530
  }
1334
1531
  renderMonthPickerColumn(months) {
1335
1532
  if (months.length === 0) {
@@ -1338,13 +1535,19 @@ export class Datetime {
1338
1535
  const { disabled, workingParts } = this;
1339
1536
  const activePart = this.getActivePartsWithFallback();
1340
1537
  return (h("ion-picker-column", { part: WHEEL_PART, "aria-label": "Select a month", class: "month-column", color: this.color, disabled: disabled, value: workingParts.month, onIonChange: (ev) => {
1341
- this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { month: ev.detail.value }));
1538
+ this.setWorkingParts({
1539
+ ...workingParts,
1540
+ month: ev.detail.value,
1541
+ });
1342
1542
  // Month wheel is navigation-only in multi-select mode as a fix for https://github.com/ionic-team/ionic-framework/issues/29673
1343
1543
  if (!this.multiple) {
1344
- this.setActiveParts(Object.assign(Object.assign({}, activePart), { month: ev.detail.value }));
1544
+ this.setActiveParts({
1545
+ ...activePart,
1546
+ month: ev.detail.value,
1547
+ });
1345
1548
  }
1346
1549
  ev.stopPropagation();
1347
- } }, months.map((month) => (h("ion-picker-column-option", { part: month.value === workingParts.month ? `${WHEEL_ITEM_PART} ${WHEEL_ITEM_ACTIVE_PART}` : WHEEL_ITEM_PART, key: month.value, disabled: month.disabled, value: month.value }, month.text)))));
1550
+ } }, months.map((month) => (h("ion-picker-column-option", { color: this.color, part: month.value === workingParts.month ? `${WHEEL_ITEM_PART} ${WHEEL_ITEM_ACTIVE_PART}` : WHEEL_ITEM_PART, key: month.value, disabled: month.disabled, value: month.value }, month.text)))));
1348
1551
  }
1349
1552
  renderYearPickerColumn(years) {
1350
1553
  if (years.length === 0) {
@@ -1353,13 +1556,19 @@ export class Datetime {
1353
1556
  const { disabled, workingParts } = this;
1354
1557
  const activePart = this.getActivePartsWithFallback();
1355
1558
  return (h("ion-picker-column", { part: WHEEL_PART, "aria-label": "Select a year", class: "year-column", color: this.color, disabled: disabled, value: workingParts.year, onIonChange: (ev) => {
1356
- this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { year: ev.detail.value }));
1559
+ this.setWorkingParts({
1560
+ ...workingParts,
1561
+ year: ev.detail.value,
1562
+ });
1357
1563
  // Year wheel is navigation-only in multi-select mode as a fix for https://github.com/ionic-team/ionic-framework/issues/29673
1358
1564
  if (!this.multiple) {
1359
- this.setActiveParts(Object.assign(Object.assign({}, activePart), { year: ev.detail.value }));
1565
+ this.setActiveParts({
1566
+ ...activePart,
1567
+ year: ev.detail.value,
1568
+ });
1360
1569
  }
1361
1570
  ev.stopPropagation();
1362
- } }, years.map((year) => (h("ion-picker-column-option", { part: year.value === workingParts.year ? `${WHEEL_ITEM_PART} ${WHEEL_ITEM_ACTIVE_PART}` : WHEEL_ITEM_PART, key: year.value, disabled: year.disabled, value: year.value }, year.text)))));
1571
+ } }, years.map((year) => (h("ion-picker-column-option", { color: this.color, part: year.value === workingParts.year ? `${WHEEL_ITEM_PART} ${WHEEL_ITEM_ACTIVE_PART}` : WHEEL_ITEM_PART, key: year.value, disabled: year.disabled, value: year.value }, year.text)))));
1363
1572
  }
1364
1573
  renderTimePickerColumns(forcePresentation) {
1365
1574
  if (['date', 'month', 'month-year', 'year'].includes(forcePresentation)) {
@@ -1389,10 +1598,16 @@ export class Datetime {
1389
1598
  return [];
1390
1599
  const activePart = this.getActivePartsWithFallback();
1391
1600
  return (h("ion-picker-column", { part: WHEEL_PART, "aria-label": "Select an hour", color: this.color, disabled: disabled, value: activePart.hour, numericInput: true, onIonChange: (ev) => {
1392
- this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { hour: ev.detail.value }));
1393
- this.setActiveParts(Object.assign(Object.assign({}, this.getActivePartsWithFallback()), { hour: ev.detail.value }));
1601
+ this.setWorkingParts({
1602
+ ...workingParts,
1603
+ hour: ev.detail.value,
1604
+ });
1605
+ this.setActiveParts({
1606
+ ...this.getActivePartsWithFallback(),
1607
+ hour: ev.detail.value,
1608
+ });
1394
1609
  ev.stopPropagation();
1395
- } }, hoursData.map((hour) => (h("ion-picker-column-option", { part: hour.value === activePart.hour ? `${WHEEL_ITEM_PART} ${WHEEL_ITEM_ACTIVE_PART}` : WHEEL_ITEM_PART, key: hour.value, disabled: hour.disabled, value: hour.value }, hour.text)))));
1610
+ } }, hoursData.map((hour) => (h("ion-picker-column-option", { color: this.color, part: hour.value === activePart.hour ? `${WHEEL_ITEM_PART} ${WHEEL_ITEM_ACTIVE_PART}` : WHEEL_ITEM_PART, key: hour.value, disabled: hour.disabled, value: hour.value }, hour.text)))));
1396
1611
  }
1397
1612
  renderMinutePickerColumn(minutesData) {
1398
1613
  const { disabled, workingParts } = this;
@@ -1400,10 +1615,16 @@ export class Datetime {
1400
1615
  return [];
1401
1616
  const activePart = this.getActivePartsWithFallback();
1402
1617
  return (h("ion-picker-column", { part: WHEEL_PART, "aria-label": "Select a minute", color: this.color, disabled: disabled, value: activePart.minute, numericInput: true, onIonChange: (ev) => {
1403
- this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { minute: ev.detail.value }));
1404
- this.setActiveParts(Object.assign(Object.assign({}, this.getActivePartsWithFallback()), { minute: ev.detail.value }));
1618
+ this.setWorkingParts({
1619
+ ...workingParts,
1620
+ minute: ev.detail.value,
1621
+ });
1622
+ this.setActiveParts({
1623
+ ...this.getActivePartsWithFallback(),
1624
+ minute: ev.detail.value,
1625
+ });
1405
1626
  ev.stopPropagation();
1406
- } }, minutesData.map((minute) => (h("ion-picker-column-option", { part: minute.value === activePart.minute ? `${WHEEL_ITEM_PART} ${WHEEL_ITEM_ACTIVE_PART}` : WHEEL_ITEM_PART, key: minute.value, disabled: minute.disabled, value: minute.value }, minute.text)))));
1627
+ } }, minutesData.map((minute) => (h("ion-picker-column-option", { color: this.color, part: minute.value === activePart.minute ? `${WHEEL_ITEM_PART} ${WHEEL_ITEM_ACTIVE_PART}` : WHEEL_ITEM_PART, key: minute.value, disabled: minute.disabled, value: minute.value }, minute.text)))));
1407
1628
  }
1408
1629
  renderDayPeriodPickerColumn(dayPeriodData) {
1409
1630
  const { disabled, workingParts } = this;
@@ -1414,10 +1635,18 @@ export class Datetime {
1414
1635
  const isDayPeriodRTL = isLocaleDayPeriodRTL(this.locale);
1415
1636
  return (h("ion-picker-column", { part: WHEEL_PART, "aria-label": "Select a day period", style: isDayPeriodRTL ? { order: '-1' } : {}, color: this.color, disabled: disabled, value: activePart.ampm, onIonChange: (ev) => {
1416
1637
  const hour = calculateHourFromAMPM(workingParts, ev.detail.value);
1417
- this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { ampm: ev.detail.value, hour }));
1418
- this.setActiveParts(Object.assign(Object.assign({}, this.getActivePartsWithFallback()), { ampm: ev.detail.value, hour }));
1638
+ this.setWorkingParts({
1639
+ ...workingParts,
1640
+ ampm: ev.detail.value,
1641
+ hour,
1642
+ });
1643
+ this.setActiveParts({
1644
+ ...this.getActivePartsWithFallback(),
1645
+ ampm: ev.detail.value,
1646
+ hour,
1647
+ });
1419
1648
  ev.stopPropagation();
1420
- } }, dayPeriodData.map((dayPeriod) => (h("ion-picker-column-option", { part: dayPeriod.value === activePart.ampm ? `${WHEEL_ITEM_PART} ${WHEEL_ITEM_ACTIVE_PART}` : WHEEL_ITEM_PART, key: dayPeriod.value, disabled: dayPeriod.disabled, value: dayPeriod.value }, dayPeriod.text)))));
1649
+ } }, dayPeriodData.map((dayPeriod) => (h("ion-picker-column-option", { color: this.color, part: dayPeriod.value === activePart.ampm ? `${WHEEL_ITEM_PART} ${WHEEL_ITEM_ACTIVE_PART}` : WHEEL_ITEM_PART, key: dayPeriod.value, disabled: dayPeriod.disabled, value: dayPeriod.value }, dayPeriod.text)))));
1421
1650
  }
1422
1651
  renderWheelView(forcePresentation) {
1423
1652
  const { locale } = this;
@@ -1461,8 +1690,8 @@ export class Datetime {
1461
1690
  // The day is not used when checking if a month is disabled.
1462
1691
  // Users should be able to access the min or max month, even if the
1463
1692
  // min/max date is out of bounds (e.g. min is set to Feb 15, Feb should not be disabled).
1464
- minParts: Object.assign(Object.assign({}, this.minParts), { day: null }),
1465
- maxParts: Object.assign(Object.assign({}, this.maxParts), { day: null }),
1693
+ minParts: { ...this.minParts, day: null },
1694
+ maxParts: { ...this.maxParts, day: null },
1466
1695
  });
1467
1696
  // The working month should never have swipe disabled.
1468
1697
  // Otherwise the CSS scroll snap will not work and the user
@@ -1571,18 +1800,24 @@ export class Datetime {
1571
1800
  if (isAdjacentDay) {
1572
1801
  // The user selected a day outside the current month. Ignore this button, as the month will be re-rendered.
1573
1802
  this.el.blur();
1574
- this.activeParts = Object.assign(Object.assign({}, activePart), referenceParts);
1803
+ this.activeParts = { ...activePart, ...referenceParts };
1575
1804
  this.animateToDate(referenceParts);
1576
1805
  this.confirm();
1577
1806
  }
1578
1807
  else {
1579
- this.setWorkingParts(Object.assign(Object.assign({}, this.workingParts), referenceParts));
1808
+ this.setWorkingParts({
1809
+ ...this.workingParts,
1810
+ ...referenceParts,
1811
+ });
1580
1812
  // Multiple only needs date info so we can wipe out other fields like time.
1581
1813
  if (multiple) {
1582
1814
  this.setActiveParts(referenceParts, isActive);
1583
1815
  }
1584
1816
  else {
1585
- this.setActiveParts(Object.assign(Object.assign({}, activePart), referenceParts));
1817
+ this.setActiveParts({
1818
+ ...activePart,
1819
+ ...referenceParts,
1820
+ });
1586
1821
  }
1587
1822
  }
1588
1823
  }
@@ -1625,7 +1860,7 @@ export class Datetime {
1625
1860
  await popoverRef.onWillDismiss();
1626
1861
  this.isTimePopoverOpen = false;
1627
1862
  }
1628
- } }, getLocalizedTime(locale, activePart, computedHourCycle, formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time)),
1863
+ } }, getLocalizedTime(locale, activePart, computedHourCycle, formatOptions?.time)),
1629
1864
  h("ion-popover", { alignment: "center", translucent: true, overlayIndex: 1, arrow: false, onWillPresent: (ev) => {
1630
1865
  /**
1631
1866
  * Intersection Observers do not consistently fire between Blink and Webkit
@@ -1648,7 +1883,6 @@ export class Datetime {
1648
1883
  ];
1649
1884
  }
1650
1885
  getHeaderSelectedDateText() {
1651
- var _a;
1652
1886
  const { activeParts, formatOptions, multiple, titleSelectedDatesFormatter } = this;
1653
1887
  const isArray = Array.isArray(activeParts);
1654
1888
  let headerText;
@@ -1665,7 +1899,7 @@ export class Datetime {
1665
1899
  }
1666
1900
  else {
1667
1901
  // for exactly 1 day selected (multiple set or not), show a formatted version of that
1668
- headerText = getLocalizedDateTime(this.locale, this.getActivePartsWithFallback(), (_a = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.date) !== null && _a !== void 0 ? _a : { weekday: 'short', month: 'short', day: 'numeric' });
1902
+ headerText = getLocalizedDateTime(this.locale, this.getActivePartsWithFallback(), formatOptions?.date ?? { weekday: 'short', month: 'short', day: 'numeric' });
1669
1903
  }
1670
1904
  return headerText;
1671
1905
  }
@@ -1754,17 +1988,19 @@ export class Datetime {
1754
1988
  const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
1755
1989
  const hasWheelVariant = hasDatePresentation && preferWheel;
1756
1990
  renderHiddenInput(true, el, name, formatValue(value), disabled);
1757
- return (h(Host, { key: '5e0b83cb88a87945eaae2f9402751819b75452ee', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, createColorClasses(color, {
1758
- [mode]: true,
1759
- ['datetime-readonly']: readonly,
1760
- ['datetime-disabled']: disabled,
1761
- 'show-month-and-year': shouldShowMonthAndYear,
1762
- 'month-year-picker-open': monthYearPickerOpen,
1763
- [`datetime-presentation-${presentation}`]: true,
1764
- [`datetime-size-${size}`]: true,
1765
- [`datetime-prefer-wheel`]: hasWheelVariant,
1766
- [`datetime-grid`]: isGridStyle,
1767
- })) }, h("div", { key: '9f9ba72e9879525961b00abe342a7891492ca0ff', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
1991
+ return (h(Host, { key: '79b906669d3e0d9ff356421a5f571d5cf12b6793', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: {
1992
+ ...createColorClasses(color, {
1993
+ [mode]: true,
1994
+ ['datetime-readonly']: readonly,
1995
+ ['datetime-disabled']: disabled,
1996
+ 'show-month-and-year': shouldShowMonthAndYear,
1997
+ 'month-year-picker-open': monthYearPickerOpen,
1998
+ [`datetime-presentation-${presentation}`]: true,
1999
+ [`datetime-size-${size}`]: true,
2000
+ [`datetime-prefer-wheel`]: hasWheelVariant,
2001
+ [`datetime-grid`]: isGridStyle,
2002
+ }),
2003
+ } }, h("div", { key: 'e29ce6edd79f3efb8f7cc4a81bb543d580e5f4c6', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
1768
2004
  }
1769
2005
  static get is() { return "ion-datetime"; }
1770
2006
  static get encapsulation() { return "shadow"; }
@@ -1806,8 +2042,7 @@ export class Datetime {
1806
2042
  "getter": false,
1807
2043
  "setter": false,
1808
2044
  "reflect": false,
1809
- "attribute": "color",
1810
- "defaultValue": "'primary'"
2045
+ "attribute": "color"
1811
2046
  },
1812
2047
  "name": {
1813
2048
  "type": "string",