@ionic/core 7.7.2-dev.11707840956.16e27b4c → 7.7.2-dev.11707926434.1affaed4

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 (366) hide show
  1. package/components/action-sheet.js +3 -7
  2. package/components/alert.js +2 -6
  3. package/components/data.js +28 -38
  4. package/components/ion-datetime-button.js +11 -10
  5. package/components/ion-datetime.js +68 -7
  6. package/components/ion-loading.js +2 -6
  7. package/components/ion-modal.js +3 -7
  8. package/components/ion-picker.js +2 -6
  9. package/components/ion-toast.js +2 -6
  10. package/components/label.js +2 -2
  11. package/components/overlays.js +4 -54
  12. package/components/popover.js +2 -6
  13. package/dist/cjs/{app-globals-92ad1b3d.js → app-globals-5a17c5e1.js} +1 -1
  14. package/dist/cjs/{button-active-2d6520ec.js → button-active-b8c3f603.js} +1 -1
  15. package/dist/cjs/{data-a5109f09.js → data-6246812e.js} +27 -39
  16. package/dist/cjs/{hardware-back-button-2696acaf.js → hardware-back-button-d23873bb.js} +2 -2
  17. package/dist/cjs/{index-0ffe376d.js → index-5a471146.js} +22 -25
  18. package/dist/cjs/{index-c3580a90.js → index-84351d21.js} +3 -3
  19. package/dist/cjs/{index-a43f7a0f.js → index-8c679cbf.js} +2 -2
  20. package/dist/cjs/index.cjs.js +8 -8
  21. package/dist/cjs/ion-accordion_2.cjs.entry.js +2 -2
  22. package/dist/cjs/ion-action-sheet.cjs.entry.js +8 -12
  23. package/dist/cjs/ion-alert.cjs.entry.js +7 -11
  24. package/dist/cjs/ion-app_8.cjs.entry.js +6 -6
  25. package/dist/cjs/ion-avatar_3.cjs.entry.js +2 -2
  26. package/dist/cjs/ion-back-button.cjs.entry.js +2 -2
  27. package/dist/cjs/ion-backdrop.cjs.entry.js +2 -2
  28. package/dist/cjs/ion-breadcrumb_2.cjs.entry.js +2 -2
  29. package/dist/cjs/ion-button_2.cjs.entry.js +2 -2
  30. package/dist/cjs/ion-card_5.cjs.entry.js +2 -2
  31. package/dist/cjs/ion-checkbox.cjs.entry.js +2 -2
  32. package/dist/cjs/ion-chip.cjs.entry.js +2 -2
  33. package/dist/cjs/ion-col_3.cjs.entry.js +2 -2
  34. package/dist/cjs/ion-datetime-button.cjs.entry.js +13 -12
  35. package/dist/cjs/ion-datetime_3.cjs.entry.js +71 -17
  36. package/dist/cjs/ion-fab_3.cjs.entry.js +2 -2
  37. package/dist/cjs/ion-img.cjs.entry.js +2 -2
  38. package/dist/cjs/ion-infinite-scroll_2.cjs.entry.js +2 -2
  39. package/dist/cjs/ion-input.cjs.entry.js +2 -2
  40. package/dist/cjs/ion-item-option_3.cjs.entry.js +2 -2
  41. package/dist/cjs/ion-item_8.cjs.entry.js +4 -4
  42. package/dist/cjs/ion-loading.cjs.entry.js +6 -10
  43. package/dist/cjs/ion-menu_3.cjs.entry.js +5 -5
  44. package/dist/cjs/ion-modal.cjs.entry.js +8 -12
  45. package/dist/cjs/ion-nav_2.cjs.entry.js +3 -3
  46. package/dist/cjs/ion-picker-column-internal.cjs.entry.js +2 -2
  47. package/dist/cjs/ion-picker-internal.cjs.entry.js +1 -1
  48. package/dist/cjs/ion-popover.cjs.entry.js +7 -11
  49. package/dist/cjs/ion-progress-bar.cjs.entry.js +2 -2
  50. package/dist/cjs/ion-radio_2.cjs.entry.js +2 -2
  51. package/dist/cjs/ion-range.cjs.entry.js +2 -2
  52. package/dist/cjs/ion-refresher_2.cjs.entry.js +2 -2
  53. package/dist/cjs/ion-reorder_2.cjs.entry.js +2 -2
  54. package/dist/cjs/ion-ripple-effect.cjs.entry.js +2 -2
  55. package/dist/cjs/ion-route_4.cjs.entry.js +2 -2
  56. package/dist/cjs/ion-searchbar.cjs.entry.js +2 -2
  57. package/dist/cjs/ion-segment_2.cjs.entry.js +2 -2
  58. package/dist/cjs/ion-select_3.cjs.entry.js +4 -4
  59. package/dist/cjs/ion-spinner.cjs.entry.js +2 -2
  60. package/dist/cjs/ion-split-pane.cjs.entry.js +2 -2
  61. package/dist/cjs/ion-tab-bar_2.cjs.entry.js +2 -2
  62. package/dist/cjs/ion-tab_2.cjs.entry.js +1 -1
  63. package/dist/cjs/ion-text.cjs.entry.js +2 -2
  64. package/dist/cjs/ion-textarea.cjs.entry.js +2 -2
  65. package/dist/cjs/ion-toast.cjs.entry.js +6 -10
  66. package/dist/cjs/ion-toggle.cjs.entry.js +2 -2
  67. package/dist/cjs/{ionic-global-59a10130.js → ionic-global-7358c23e.js} +1 -1
  68. package/dist/cjs/ionic.cjs.js +7 -7
  69. package/dist/cjs/{ios.transition-c3b11cc3.js → ios.transition-8e40c54e.js} +2 -2
  70. package/dist/cjs/loader.cjs.js +6 -6
  71. package/dist/cjs/{md.transition-82a8c649.js → md.transition-597a2479.js} +2 -2
  72. package/dist/cjs/{overlays-fb7ca451.js → overlays-330df245.js} +6 -56
  73. package/dist/cjs/{status-tap-692f6d32.js → status-tap-b0bfea34.js} +1 -1
  74. package/dist/collection/collection-manifest.json +1 -1
  75. package/dist/collection/components/action-sheet/action-sheet.js +5 -9
  76. package/dist/collection/components/alert/alert.js +4 -8
  77. package/dist/collection/components/datetime/datetime.js +90 -7
  78. package/dist/collection/components/datetime/test/basic/datetime.e2e.js +79 -0
  79. package/dist/collection/components/datetime/test/format.spec.js +65 -1
  80. package/dist/collection/components/datetime/utils/format.js +28 -20
  81. package/dist/collection/components/datetime-button/datetime-button.js +11 -10
  82. package/dist/collection/components/datetime-button/test/basic/datetime-button.e2e.js +66 -0
  83. package/dist/collection/components/label/label.ios.css +4 -0
  84. package/dist/collection/components/label/label.md.css +4 -0
  85. package/dist/collection/components/loading/loading.js +4 -8
  86. package/dist/collection/components/modal/modal.js +5 -9
  87. package/dist/collection/components/picker/picker.js +4 -8
  88. package/dist/collection/components/popover/popover.js +4 -8
  89. package/dist/collection/components/toast/test/toast.spec.js +0 -12
  90. package/dist/collection/components/toast/toast.js +4 -8
  91. package/dist/collection/utils/overlays.js +4 -54
  92. package/dist/collection/utils/test/overlays/overlays.e2e.js +0 -33
  93. package/dist/collection/utils/test/overlays/overlays.spec.js +0 -51
  94. package/dist/docs.json +66 -23
  95. package/dist/esm/{app-globals-5cf6195b.js → app-globals-47226a12.js} +1 -1
  96. package/dist/esm/{button-active-47ac8092.js → button-active-4bee452c.js} +1 -1
  97. package/dist/esm/{data-0f3ab200.js → data-25d50209.js} +28 -38
  98. package/dist/esm/{hardware-back-button-b410a047.js → hardware-back-button-f42b9c80.js} +2 -2
  99. package/dist/esm/{index-47b2066d.js → index-48209844.js} +2 -2
  100. package/dist/esm/{index-0b4beb69.js → index-4b98143d.js} +3 -3
  101. package/dist/esm/{index-4c30cddd.js → index-73881b51.js} +22 -25
  102. package/dist/esm/index.js +8 -8
  103. package/dist/esm/ion-accordion_2.entry.js +2 -2
  104. package/dist/esm/ion-action-sheet.entry.js +8 -12
  105. package/dist/esm/ion-alert.entry.js +7 -11
  106. package/dist/esm/ion-app_8.entry.js +6 -6
  107. package/dist/esm/ion-avatar_3.entry.js +2 -2
  108. package/dist/esm/ion-back-button.entry.js +2 -2
  109. package/dist/esm/ion-backdrop.entry.js +2 -2
  110. package/dist/esm/ion-breadcrumb_2.entry.js +2 -2
  111. package/dist/esm/ion-button_2.entry.js +2 -2
  112. package/dist/esm/ion-card_5.entry.js +2 -2
  113. package/dist/esm/ion-checkbox.entry.js +2 -2
  114. package/dist/esm/ion-chip.entry.js +2 -2
  115. package/dist/esm/ion-col_3.entry.js +2 -2
  116. package/dist/esm/ion-datetime-button.entry.js +13 -12
  117. package/dist/esm/ion-datetime_3.entry.js +71 -17
  118. package/dist/esm/ion-fab_3.entry.js +2 -2
  119. package/dist/esm/ion-img.entry.js +2 -2
  120. package/dist/esm/ion-infinite-scroll_2.entry.js +2 -2
  121. package/dist/esm/ion-input.entry.js +2 -2
  122. package/dist/esm/ion-item-option_3.entry.js +2 -2
  123. package/dist/esm/ion-item_8.entry.js +4 -4
  124. package/dist/esm/ion-loading.entry.js +6 -10
  125. package/dist/esm/ion-menu_3.entry.js +5 -5
  126. package/dist/esm/ion-modal.entry.js +8 -12
  127. package/dist/esm/ion-nav_2.entry.js +3 -3
  128. package/dist/esm/ion-picker-column-internal.entry.js +2 -2
  129. package/dist/esm/ion-picker-internal.entry.js +1 -1
  130. package/dist/esm/ion-popover.entry.js +7 -11
  131. package/dist/esm/ion-progress-bar.entry.js +2 -2
  132. package/dist/esm/ion-radio_2.entry.js +2 -2
  133. package/dist/esm/ion-range.entry.js +2 -2
  134. package/dist/esm/ion-refresher_2.entry.js +2 -2
  135. package/dist/esm/ion-reorder_2.entry.js +2 -2
  136. package/dist/esm/ion-ripple-effect.entry.js +2 -2
  137. package/dist/esm/ion-route_4.entry.js +2 -2
  138. package/dist/esm/ion-searchbar.entry.js +2 -2
  139. package/dist/esm/ion-segment_2.entry.js +2 -2
  140. package/dist/esm/ion-select_3.entry.js +4 -4
  141. package/dist/esm/ion-spinner.entry.js +2 -2
  142. package/dist/esm/ion-split-pane.entry.js +2 -2
  143. package/dist/esm/ion-tab-bar_2.entry.js +2 -2
  144. package/dist/esm/ion-tab_2.entry.js +1 -1
  145. package/dist/esm/ion-text.entry.js +2 -2
  146. package/dist/esm/ion-textarea.entry.js +2 -2
  147. package/dist/esm/ion-toast.entry.js +6 -10
  148. package/dist/esm/ion-toggle.entry.js +2 -2
  149. package/dist/esm/{ionic-global-ad9a1810.js → ionic-global-778b7863.js} +1 -1
  150. package/dist/esm/ionic.js +8 -8
  151. package/dist/esm/{ios.transition-b76c7020.js → ios.transition-7ff7381d.js} +2 -2
  152. package/dist/esm/loader.js +7 -7
  153. package/dist/esm/{md.transition-564937a7.js → md.transition-28a9a26b.js} +2 -2
  154. package/dist/esm/{overlays-04a9a43f.js → overlays-33ae3ea0.js} +6 -56
  155. package/dist/esm/{status-tap-5a95077d.js → status-tap-2b335fb7.js} +1 -1
  156. package/dist/esm-es5/app-globals-47226a12.js +4 -0
  157. package/dist/esm-es5/{button-active-47ac8092.js → button-active-4bee452c.js} +1 -1
  158. package/dist/esm-es5/data-25d50209.js +4 -0
  159. package/dist/esm-es5/{hardware-back-button-b410a047.js → hardware-back-button-f42b9c80.js} +1 -1
  160. package/dist/esm-es5/{index-47b2066d.js → index-48209844.js} +1 -1
  161. package/dist/esm-es5/{index-0b4beb69.js → index-4b98143d.js} +1 -1
  162. package/dist/esm-es5/{index-4c30cddd.js → index-73881b51.js} +1 -1
  163. package/dist/esm-es5/index.js +1 -1
  164. package/dist/esm-es5/ion-accordion_2.entry.js +1 -1
  165. package/dist/esm-es5/ion-action-sheet.entry.js +1 -1
  166. package/dist/esm-es5/ion-alert.entry.js +1 -1
  167. package/dist/esm-es5/ion-app_8.entry.js +1 -1
  168. package/dist/esm-es5/ion-avatar_3.entry.js +1 -1
  169. package/dist/esm-es5/ion-back-button.entry.js +1 -1
  170. package/dist/esm-es5/ion-backdrop.entry.js +1 -1
  171. package/dist/esm-es5/ion-breadcrumb_2.entry.js +1 -1
  172. package/dist/esm-es5/ion-button_2.entry.js +1 -1
  173. package/dist/esm-es5/ion-card_5.entry.js +1 -1
  174. package/dist/esm-es5/ion-checkbox.entry.js +1 -1
  175. package/dist/esm-es5/ion-chip.entry.js +1 -1
  176. package/dist/esm-es5/ion-col_3.entry.js +1 -1
  177. package/dist/esm-es5/ion-datetime-button.entry.js +1 -1
  178. package/dist/esm-es5/ion-datetime_3.entry.js +1 -1
  179. package/dist/esm-es5/ion-fab_3.entry.js +1 -1
  180. package/dist/esm-es5/ion-img.entry.js +1 -1
  181. package/dist/esm-es5/ion-infinite-scroll_2.entry.js +1 -1
  182. package/dist/esm-es5/ion-input.entry.js +1 -1
  183. package/dist/esm-es5/ion-item-option_3.entry.js +1 -1
  184. package/dist/esm-es5/ion-item_8.entry.js +1 -1
  185. package/dist/esm-es5/ion-loading.entry.js +1 -1
  186. package/dist/esm-es5/ion-menu_3.entry.js +1 -1
  187. package/dist/esm-es5/ion-modal.entry.js +1 -1
  188. package/dist/esm-es5/ion-nav_2.entry.js +1 -1
  189. package/dist/esm-es5/ion-picker-column-internal.entry.js +1 -1
  190. package/dist/esm-es5/ion-picker-internal.entry.js +1 -1
  191. package/dist/esm-es5/ion-popover.entry.js +1 -1
  192. package/dist/esm-es5/ion-progress-bar.entry.js +1 -1
  193. package/dist/esm-es5/ion-radio_2.entry.js +1 -1
  194. package/dist/esm-es5/ion-range.entry.js +1 -1
  195. package/dist/esm-es5/ion-refresher_2.entry.js +1 -1
  196. package/dist/esm-es5/ion-reorder_2.entry.js +1 -1
  197. package/dist/esm-es5/ion-ripple-effect.entry.js +1 -1
  198. package/dist/esm-es5/ion-route_4.entry.js +1 -1
  199. package/dist/esm-es5/ion-searchbar.entry.js +1 -1
  200. package/dist/esm-es5/ion-segment_2.entry.js +1 -1
  201. package/dist/esm-es5/ion-select_3.entry.js +1 -1
  202. package/dist/esm-es5/ion-spinner.entry.js +1 -1
  203. package/dist/esm-es5/ion-split-pane.entry.js +1 -1
  204. package/dist/esm-es5/ion-tab-bar_2.entry.js +1 -1
  205. package/dist/esm-es5/ion-tab_2.entry.js +1 -1
  206. package/dist/esm-es5/ion-text.entry.js +1 -1
  207. package/dist/esm-es5/ion-textarea.entry.js +1 -1
  208. package/dist/esm-es5/ion-toast.entry.js +1 -1
  209. package/dist/esm-es5/ion-toggle.entry.js +1 -1
  210. package/dist/esm-es5/{ionic-global-ad9a1810.js → ionic-global-778b7863.js} +1 -1
  211. package/dist/esm-es5/ionic.js +2 -2
  212. package/dist/esm-es5/{ios.transition-b76c7020.js → ios.transition-7ff7381d.js} +1 -1
  213. package/dist/esm-es5/loader.js +2 -2
  214. package/dist/esm-es5/md.transition-28a9a26b.js +4 -0
  215. package/dist/esm-es5/{overlays-04a9a43f.js → overlays-33ae3ea0.js} +1 -1
  216. package/dist/esm-es5/{status-tap-5a95077d.js → status-tap-2b335fb7.js} +1 -1
  217. package/dist/ionic/index.esm.js +1 -1
  218. package/dist/ionic/ionic.esm.js +1 -1
  219. package/dist/ionic/ionic.js +1 -1
  220. package/dist/ionic/{p-df504a37.system.js → p-001010b6.system.js} +1 -1
  221. package/dist/ionic/{p-1924f2e0.system.entry.js → p-016976a7.system.entry.js} +2 -2
  222. package/dist/ionic/{p-a0b28c69.system.entry.js → p-078fd095.system.entry.js} +1 -1
  223. package/dist/ionic/{p-ae35294f.system.entry.js → p-0ae25399.system.entry.js} +1 -1
  224. package/dist/ionic/p-0b955124.system.js +4 -0
  225. package/dist/ionic/{p-3481d54e.system.entry.js → p-0e29919c.system.entry.js} +1 -1
  226. package/dist/ionic/{p-8794fa00.system.entry.js → p-0eef8b34.system.entry.js} +1 -1
  227. package/dist/ionic/{p-fb9f8495.system.entry.js → p-0fd295ef.system.entry.js} +1 -1
  228. package/dist/ionic/{p-508a4c87.entry.js → p-108f730a.entry.js} +1 -1
  229. package/dist/ionic/{p-5d7e32ce.js → p-1aa7c019.js} +1 -1
  230. package/dist/ionic/{p-601e17b4.entry.js → p-1c531ca2.entry.js} +1 -1
  231. package/dist/ionic/{p-91cb3f9a.entry.js → p-1f583f73.entry.js} +1 -1
  232. package/dist/ionic/{p-ea25b4c8.system.entry.js → p-1f6cdf2c.system.entry.js} +1 -1
  233. package/dist/ionic/{p-717e2526.system.entry.js → p-20a6513f.system.entry.js} +1 -1
  234. package/dist/ionic/{p-cde3ac34.system.entry.js → p-20f7a91e.system.entry.js} +1 -1
  235. package/dist/ionic/{p-74deb358.system.js → p-25b08bc4.system.js} +1 -1
  236. package/dist/ionic/p-26138fed.js +4 -0
  237. package/dist/ionic/{p-bf05cbc7.entry.js → p-2da0a76c.entry.js} +1 -1
  238. package/dist/ionic/{p-70e34286.system.entry.js → p-2f66e177.system.entry.js} +1 -1
  239. package/dist/ionic/{p-5cb5f63d.system.entry.js → p-30c9e049.system.entry.js} +1 -1
  240. package/dist/ionic/{p-16a61810.entry.js → p-333f06ed.entry.js} +1 -1
  241. package/dist/ionic/{p-de55ec45.js → p-341b4519.js} +1 -1
  242. package/dist/ionic/{p-bd314f1e.system.entry.js → p-389ff4d2.system.entry.js} +1 -1
  243. package/dist/ionic/{p-1f16d040.entry.js → p-396c1a55.entry.js} +1 -1
  244. package/dist/ionic/{p-5e23bea8.system.entry.js → p-3a54c070.system.entry.js} +1 -1
  245. package/dist/ionic/{p-275705e5.entry.js → p-3a98f8db.entry.js} +1 -1
  246. package/dist/ionic/{p-502780e4.entry.js → p-3cdbaa49.entry.js} +1 -1
  247. package/dist/ionic/{p-49aba878.js → p-3eb2da31.js} +1 -1
  248. package/dist/ionic/{p-6525a8cd.system.js → p-3f028207.system.js} +1 -1
  249. package/dist/ionic/{p-43a5edee.entry.js → p-400574bf.entry.js} +1 -1
  250. package/dist/ionic/{p-18beebdf.system.entry.js → p-48af4316.system.entry.js} +2 -2
  251. package/dist/ionic/{p-ceceac26.js → p-4b2d5b9c.js} +1 -1
  252. package/dist/ionic/{p-a022b684.system.entry.js → p-4c256bc2.system.entry.js} +1 -1
  253. package/dist/ionic/{p-b7efc743.system.entry.js → p-4dfc27eb.system.entry.js} +1 -1
  254. package/dist/ionic/{p-396083cc.entry.js → p-51f08a9f.entry.js} +1 -1
  255. package/dist/ionic/{p-86813176.system.entry.js → p-58e3ae88.system.entry.js} +1 -1
  256. package/dist/ionic/{p-31450f73.entry.js → p-5b6aa59a.entry.js} +1 -1
  257. package/dist/ionic/{p-4fda5c35.entry.js → p-5e60dbc8.entry.js} +1 -1
  258. package/dist/ionic/{p-1636923f.system.js → p-5eea8b4c.system.js} +1 -1
  259. package/dist/ionic/{p-cd9a7017.system.entry.js → p-5f456b3c.system.entry.js} +1 -1
  260. package/dist/ionic/{p-2e1f014a.system.entry.js → p-61c0f8bf.system.entry.js} +1 -1
  261. package/dist/ionic/{p-a5951821.system.js → p-62a3c609.system.js} +1 -1
  262. package/dist/ionic/{p-f53d074d.system.entry.js → p-680f96e8.system.entry.js} +1 -1
  263. package/dist/ionic/p-68ae6719.system.entry.js +4 -0
  264. package/dist/ionic/{p-5b40d967.entry.js → p-6a34980d.entry.js} +1 -1
  265. package/dist/ionic/p-6b02edd6.js +4 -0
  266. package/dist/ionic/{p-afd6d696.system.entry.js → p-6f38d0c5.system.entry.js} +1 -1
  267. package/dist/ionic/{p-42a9f663.system.entry.js → p-70026e8f.system.entry.js} +1 -1
  268. package/dist/ionic/{p-72fa96bf.system.js → p-76893257.system.js} +1 -1
  269. package/dist/ionic/{p-c1797ec5.system.entry.js → p-78edc0cd.system.entry.js} +1 -1
  270. package/dist/ionic/{p-f0194418.system.entry.js → p-7c32fb95.system.entry.js} +1 -1
  271. package/dist/ionic/p-7c5e8706.entry.js +4 -0
  272. package/dist/ionic/{p-05d560ec.entry.js → p-7dc7514a.entry.js} +1 -1
  273. package/dist/ionic/{p-bd4787eb.entry.js → p-84513dfb.entry.js} +1 -1
  274. package/dist/ionic/{p-e04b9647.system.entry.js → p-84879f61.system.entry.js} +1 -1
  275. package/dist/ionic/{p-1131946f.system.entry.js → p-8569d759.system.entry.js} +1 -1
  276. package/dist/ionic/p-87ae4f6c.system.entry.js +4 -0
  277. package/dist/ionic/{p-eb07b88f.entry.js → p-8a671f16.entry.js} +1 -1
  278. package/dist/ionic/{p-123b4809.js → p-8ddc00f7.js} +1 -1
  279. package/dist/ionic/p-8e16390d.system.js +4 -0
  280. package/dist/ionic/{p-a8a56449.entry.js → p-8ebd9951.entry.js} +1 -1
  281. package/dist/ionic/p-8f1ce253.js +4 -0
  282. package/dist/ionic/{p-c747f89b.system.entry.js → p-92c2178e.system.entry.js} +1 -1
  283. package/dist/ionic/{p-9cd7ba27.system.js → p-95c44e02.system.js} +1 -1
  284. package/dist/ionic/{p-95d5a097.entry.js → p-97eca294.entry.js} +1 -1
  285. package/dist/ionic/{p-a85d9047.system.entry.js → p-9a6ab80a.system.entry.js} +1 -1
  286. package/dist/ionic/{p-e9f9388e.system.js → p-9beb5039.system.js} +1 -1
  287. package/dist/ionic/{p-5928fac9.system.entry.js → p-9f5b40c0.system.entry.js} +1 -1
  288. package/dist/ionic/{p-3d961d93.entry.js → p-9f6397ce.entry.js} +1 -1
  289. package/dist/ionic/{p-5c6a04bd.entry.js → p-a02b2d75.entry.js} +1 -1
  290. package/dist/ionic/{p-88e9052d.entry.js → p-a051c371.entry.js} +1 -1
  291. package/dist/ionic/{p-cb9e71e0.entry.js → p-a19f5ae1.entry.js} +1 -1
  292. package/dist/ionic/{p-7b1ed642.system.entry.js → p-a1bfaa5c.system.entry.js} +1 -1
  293. package/dist/ionic/{p-5c580e89.entry.js → p-a2ad515b.entry.js} +1 -1
  294. package/dist/ionic/{p-3079950e.entry.js → p-aa7ae6aa.entry.js} +1 -1
  295. package/dist/ionic/{p-69973389.system.entry.js → p-aaa4ffb3.system.entry.js} +1 -1
  296. package/dist/ionic/{p-abcedc15.system.entry.js → p-ac20160b.system.entry.js} +1 -1
  297. package/dist/ionic/{p-ba97a133.system.entry.js → p-ac979ebf.system.entry.js} +1 -1
  298. package/dist/ionic/{p-dbd70d97.system.entry.js → p-b37e4ee5.system.entry.js} +1 -1
  299. package/dist/ionic/{p-c771a6ef.entry.js → p-b498de69.entry.js} +1 -1
  300. package/dist/ionic/{p-30cd5e7b.js → p-b4d8fe47.js} +1 -1
  301. package/dist/ionic/{p-337ac0f5.entry.js → p-b8c4df21.entry.js} +1 -1
  302. package/dist/ionic/{p-89ca4c4b.system.js → p-b94882a9.system.js} +1 -1
  303. package/dist/ionic/{p-edcada2b.system.entry.js → p-b96699d3.system.entry.js} +1 -1
  304. package/dist/ionic/{p-64856c3c.system.entry.js → p-bc2c03d7.system.entry.js} +1 -1
  305. package/dist/ionic/{p-8f872991.entry.js → p-c3790581.entry.js} +1 -1
  306. package/dist/ionic/p-c5c3710c.js +4 -0
  307. package/dist/ionic/{p-2e14c533.system.js → p-c6fef62b.system.js} +1 -1
  308. package/dist/ionic/{p-aaaa615c.system.entry.js → p-c851b204.system.entry.js} +1 -1
  309. package/dist/ionic/{p-d39ab63d.entry.js → p-ccd419ae.entry.js} +1 -1
  310. package/dist/ionic/{p-68ba8e77.system.entry.js → p-cd055d60.system.entry.js} +1 -1
  311. package/dist/ionic/{p-027f3674.entry.js → p-ce2eabd5.entry.js} +1 -1
  312. package/dist/ionic/{p-b0ff8075.entry.js → p-d7260b87.entry.js} +1 -1
  313. package/dist/ionic/{p-f840d817.entry.js → p-d74ca358.entry.js} +1 -1
  314. package/dist/ionic/{p-657ccdd6.entry.js → p-d8607ede.entry.js} +1 -1
  315. package/dist/ionic/{p-c308f773.entry.js → p-d95c8e90.entry.js} +1 -1
  316. package/dist/ionic/{p-c11bab7e.entry.js → p-dbb4c012.entry.js} +1 -1
  317. package/dist/ionic/{p-0457213c.entry.js → p-dce9bc53.entry.js} +1 -1
  318. package/dist/ionic/{p-7173ba59.system.entry.js → p-df281664.system.entry.js} +1 -1
  319. package/dist/ionic/{p-2327064c.entry.js → p-df468a8f.entry.js} +1 -1
  320. package/dist/ionic/p-e1271366.js +5 -0
  321. package/dist/ionic/{p-b2595011.system.entry.js → p-e68980ff.system.entry.js} +1 -1
  322. package/dist/ionic/{p-1f19958f.system.entry.js → p-e6aaff14.system.entry.js} +1 -1
  323. package/dist/ionic/{p-dcb5711d.entry.js → p-ea8fbf09.entry.js} +1 -1
  324. package/dist/ionic/{p-a3df16b9.system.entry.js → p-eda7a1db.system.entry.js} +1 -1
  325. package/dist/ionic/{p-64db1331.entry.js → p-efe9180b.entry.js} +1 -1
  326. package/dist/ionic/{p-64761c90.entry.js → p-f1ad3b3d.entry.js} +1 -1
  327. package/dist/ionic/{p-45841d37.entry.js → p-f1cc690e.entry.js} +1 -1
  328. package/dist/ionic/{p-8e651c29.entry.js → p-f46775e4.entry.js} +1 -1
  329. package/dist/ionic/p-f74afe3b.entry.js +4 -0
  330. package/dist/ionic/{p-c39cc96d.system.entry.js → p-f7b43141.system.entry.js} +1 -1
  331. package/dist/ionic/{p-3a7de59c.entry.js → p-f88dd429.entry.js} +1 -1
  332. package/dist/ionic/p-f89ae259.js +4 -0
  333. package/dist/ionic/{p-9056778e.system.entry.js → p-f97b9cdd.system.entry.js} +1 -1
  334. package/dist/ionic/{p-9ec7208d.system.js → p-fd36799d.system.js} +1 -1
  335. package/dist/ionic/{p-7ce40e7b.entry.js → p-fd3f475f.entry.js} +1 -1
  336. package/dist/ionic/{p-d4cadd34.system.js → p-fd9a9db3.system.js} +1 -1
  337. package/dist/ionic/{p-b6279412.entry.js → p-fe92da17.entry.js} +1 -1
  338. package/dist/types/components/action-sheet/action-sheet.d.ts +0 -4
  339. package/dist/types/components/alert/alert.d.ts +0 -4
  340. package/dist/types/components/datetime/datetime-interface.d.ts +10 -0
  341. package/dist/types/components/datetime/datetime.d.ts +16 -1
  342. package/dist/types/components/datetime/utils/format.d.ts +7 -1
  343. package/dist/types/components/loading/loading.d.ts +0 -4
  344. package/dist/types/components/modal/modal.d.ts +0 -4
  345. package/dist/types/components/picker/picker.d.ts +0 -4
  346. package/dist/types/components/popover/popover.d.ts +0 -4
  347. package/dist/types/components/toast/toast.d.ts +0 -4
  348. package/dist/types/components.d.ts +17 -9
  349. package/hydrate/index.d.ts +1 -1
  350. package/hydrate/index.js +136 -271
  351. package/package.json +3 -3
  352. package/dist/esm-es5/app-globals-5cf6195b.js +0 -4
  353. package/dist/esm-es5/data-0f3ab200.js +0 -4
  354. package/dist/esm-es5/md.transition-564937a7.js +0 -4
  355. package/dist/ionic/p-0b34d3a7.system.js +0 -4
  356. package/dist/ionic/p-0e23c289.system.entry.js +0 -4
  357. package/dist/ionic/p-21ca1f1c.js +0 -4
  358. package/dist/ionic/p-23c73017.entry.js +0 -4
  359. package/dist/ionic/p-5c2ae448.js +0 -4
  360. package/dist/ionic/p-7330c044.system.js +0 -4
  361. package/dist/ionic/p-a6e465f5.entry.js +0 -4
  362. package/dist/ionic/p-bdca4784.js +0 -4
  363. package/dist/ionic/p-dbcba5a2.js +0 -4
  364. package/dist/ionic/p-e81bf09e.system.entry.js +0 -4
  365. package/dist/ionic/p-ed7a529f.js +0 -5
  366. package/dist/ionic/p-f7dce541.js +0 -4
@@ -11,7 +11,7 @@ import { caretDownSharp, caretUpSharp, chevronBack, chevronDown, chevronForward
11
11
  import { getIonMode } from "../../global/ionic-global";
12
12
  import { isSameDay, warnIfValueOutOfBounds, isBefore, isAfter } from "./utils/comparison";
13
13
  import { generateMonths, getDaysOfMonth, getDaysOfWeek, getToday, getMonthColumnData, getDayColumnData, getYearColumnData, getTimeColumnsData, getCombinedDateColumnData, } from "./utils/data";
14
- import { formatValue, getLocalizedTime, getMonthAndDay, getMonthAndYear } from "./utils/format";
14
+ import { formatValue, getLocalizedDateTime, getLocalizedTime, getMonthAndYear } from "./utils/format";
15
15
  import { isLocaleDayPeriodRTL, isMonthFirstLocale, getNumDaysInMonth, getHourCycle } from "./utils/helpers";
16
16
  import { calculateHourFromAMPM, convertDataToISO, getClosestValidDate, getEndOfWeek, getNextDay, getNextMonth, getNextWeek, getNextYear, getPreviousDay, getPreviousMonth, getPreviousWeek, getPreviousYear, getStartOfWeek, validateParts, } from "./utils/manipulation";
17
17
  import { clampDate, convertToArrayOfNumbers, getPartsFromCalendarDay, parseAmPm, parseDate, parseMaxParts, parseMinParts, } from "./utils/parse";
@@ -592,6 +592,34 @@ export class Datetime {
592
592
  this.resolveForceDateScrolling = undefined;
593
593
  this.forceRenderDate = undefined;
594
594
  };
595
+ this.checkForPresentationFormatMismatch = () => {
596
+ const { formatOptions, presentation } = this;
597
+ // formatOptions is not required
598
+ if (!formatOptions)
599
+ return;
600
+ // If formatOptions is provided, the date and/or time objects are required, depending on the presentation
601
+ switch (presentation) {
602
+ case 'date':
603
+ case 'month-year':
604
+ case 'month':
605
+ case 'year':
606
+ if (formatOptions.date === undefined) {
607
+ printIonWarning(`Datetime: The '${presentation}' presentation requires a date object in formatOptions.`, this.el);
608
+ }
609
+ break;
610
+ case 'time':
611
+ if (formatOptions.time === undefined) {
612
+ printIonWarning(`Datetime: The 'time' presentation requires a time object in formatOptions.`, this.el);
613
+ }
614
+ break;
615
+ case 'date-time':
616
+ case 'time-date':
617
+ if (formatOptions.date === undefined || formatOptions.time === undefined) {
618
+ printIonWarning(`Datetime: The '${presentation}' presentation requires both a date and time object in formatOptions.`, this.el);
619
+ }
620
+ break;
621
+ }
622
+ };
595
623
  this.onFocus = () => {
596
624
  this.ionFocus.emit();
597
625
  };
@@ -650,6 +678,7 @@ export class Datetime {
650
678
  this.color = 'primary';
651
679
  this.name = this.inputId;
652
680
  this.disabled = false;
681
+ this.formatOptions = undefined;
653
682
  this.readonly = false;
654
683
  this.isDateEnabled = undefined;
655
684
  this.min = undefined;
@@ -677,6 +706,10 @@ export class Datetime {
677
706
  this.size = 'fixed';
678
707
  this.preferWheel = false;
679
708
  }
709
+ formatOptionsChanged() {
710
+ this.checkForPresentationFormatMismatch();
711
+ this.errorIfTimeZoneProvided();
712
+ }
680
713
  disabledChanged() {
681
714
  this.emitStyle();
682
715
  }
@@ -686,6 +719,9 @@ export class Datetime {
686
719
  maxChanged() {
687
720
  this.processMaxParts();
688
721
  }
722
+ presentationChanged() {
723
+ this.checkForPresentationFormatMismatch();
724
+ }
689
725
  get isGridStyle() {
690
726
  const { presentation, preferWheel } = this;
691
727
  const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
@@ -921,7 +957,7 @@ export class Datetime {
921
957
  });
922
958
  }
923
959
  componentWillLoad() {
924
- const { el, highlightedDates, multiple, presentation, preferWheel } = this;
960
+ const { el, formatOptions, highlightedDates, multiple, presentation, preferWheel } = this;
925
961
  if (multiple) {
926
962
  if (presentation !== 'date') {
927
963
  printIonWarning('Multiple date selection is only supported for presentation="date".', el);
@@ -938,6 +974,10 @@ export class Datetime {
938
974
  printIonWarning('The highlightedDates property is not supported with preferWheel="true".', el);
939
975
  }
940
976
  }
977
+ if (formatOptions) {
978
+ this.checkForPresentationFormatMismatch();
979
+ this.errorIfTimeZoneProvided();
980
+ }
941
981
  const hourValues = (this.parsedHourValues = convertToArrayOfNumbers(this.hourValues));
942
982
  const minuteValues = (this.parsedMinuteValues = convertToArrayOfNumbers(this.minuteValues));
943
983
  const monthValues = (this.parsedMonthValues = convertToArrayOfNumbers(this.monthValues));
@@ -959,6 +999,21 @@ export class Datetime {
959
999
  this.processValue(this.value);
960
1000
  this.emitStyle();
961
1001
  }
1002
+ /**
1003
+ * If a time zone is provided in the format options, the rendered text could
1004
+ * differ from what was selected in the Datetime, which could cause
1005
+ * confusion.
1006
+ */
1007
+ errorIfTimeZoneProvided() {
1008
+ var _a, _b, _c, _d;
1009
+ const { formatOptions } = this;
1010
+ if (((_a = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.date) === null || _a === void 0 ? void 0 : _a.timeZone) ||
1011
+ ((_b = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.date) === null || _b === void 0 ? void 0 : _b.timeZoneName) ||
1012
+ ((_c = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time) === null || _c === void 0 ? void 0 : _c.timeZone) ||
1013
+ ((_d = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time) === null || _d === void 0 ? void 0 : _d.timeZoneName)) {
1014
+ printIonWarning('Datetime: "timeZone" and "timeZoneName" are not supported in "formatOptions".');
1015
+ }
1016
+ }
962
1017
  emitStyle() {
963
1018
  this.ionStyle.emit({
964
1019
  interactive: true,
@@ -1445,7 +1500,7 @@ export class Datetime {
1445
1500
  return h("slot", { name: "time-label" }, "Time");
1446
1501
  }
1447
1502
  renderTimeOverlay() {
1448
- const { disabled, hourCycle, isTimePopoverOpen, locale } = this;
1503
+ const { disabled, hourCycle, isTimePopoverOpen, locale, formatOptions } = this;
1449
1504
  const computedHourCycle = getHourCycle(locale, hourCycle);
1450
1505
  const activePart = this.getActivePartsWithFallback();
1451
1506
  return [
@@ -1465,7 +1520,7 @@ export class Datetime {
1465
1520
  await popoverRef.onWillDismiss();
1466
1521
  this.isTimePopoverOpen = false;
1467
1522
  }
1468
- } }, getLocalizedTime(locale, activePart, computedHourCycle)),
1523
+ } }, getLocalizedTime(locale, activePart, computedHourCycle, formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time)),
1469
1524
  h("ion-popover", { alignment: "center", translucent: true, overlayIndex: 1, arrow: false, onWillPresent: (ev) => {
1470
1525
  /**
1471
1526
  * Intersection Observers do not consistently fire between Blink and Webkit
@@ -1488,7 +1543,8 @@ export class Datetime {
1488
1543
  ];
1489
1544
  }
1490
1545
  getHeaderSelectedDateText() {
1491
- const { activeParts, multiple, titleSelectedDatesFormatter } = this;
1546
+ var _a;
1547
+ const { activeParts, formatOptions, multiple, titleSelectedDatesFormatter } = this;
1492
1548
  const isArray = Array.isArray(activeParts);
1493
1549
  let headerText;
1494
1550
  if (multiple && isArray && activeParts.length !== 1) {
@@ -1504,7 +1560,7 @@ export class Datetime {
1504
1560
  }
1505
1561
  else {
1506
1562
  // for exactly 1 day selected (multiple set or not), show a formatted version of that
1507
- headerText = getMonthAndDay(this.locale, this.getActivePartsWithFallback());
1563
+ 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' });
1508
1564
  }
1509
1565
  return headerText;
1510
1566
  }
@@ -1593,7 +1649,7 @@ export class Datetime {
1593
1649
  const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
1594
1650
  const hasWheelVariant = hasDatePresentation && preferWheel;
1595
1651
  renderHiddenInput(true, el, name, formatValue(value), disabled);
1596
- return (h(Host, { key: 'b00545b7bbba3ccf35d53c1eec4f1614fb830c11', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, createColorClasses(color, {
1652
+ return (h(Host, { key: 'ff50a7d344831b3af2e7f5cfe52b0a71c8c4b8d1', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, createColorClasses(color, {
1597
1653
  [mode]: true,
1598
1654
  ['datetime-readonly']: readonly,
1599
1655
  ['datetime-disabled']: disabled,
@@ -1681,6 +1737,27 @@ export class Datetime {
1681
1737
  "reflect": false,
1682
1738
  "defaultValue": "false"
1683
1739
  },
1740
+ "formatOptions": {
1741
+ "type": "unknown",
1742
+ "mutable": false,
1743
+ "complexType": {
1744
+ "original": "FormatOptions",
1745
+ "resolved": "undefined | { date: DateTimeFormatOptions; time?: DateTimeFormatOptions | undefined; } | { date?: DateTimeFormatOptions | undefined; time: DateTimeFormatOptions; }",
1746
+ "references": {
1747
+ "FormatOptions": {
1748
+ "location": "import",
1749
+ "path": "./datetime-interface",
1750
+ "id": "src/components/datetime/datetime-interface.ts::FormatOptions"
1751
+ }
1752
+ }
1753
+ },
1754
+ "required": false,
1755
+ "optional": true,
1756
+ "docs": {
1757
+ "tags": [],
1758
+ "text": "Formatting options for dates and times.\nShould 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)."
1759
+ }
1760
+ },
1684
1761
  "readonly": {
1685
1762
  "type": "boolean",
1686
1763
  "mutable": false,
@@ -2376,6 +2453,9 @@ export class Datetime {
2376
2453
  static get elementRef() { return "el"; }
2377
2454
  static get watchers() {
2378
2455
  return [{
2456
+ "propName": "formatOptions",
2457
+ "methodName": "formatOptionsChanged"
2458
+ }, {
2379
2459
  "propName": "disabled",
2380
2460
  "methodName": "disabledChanged"
2381
2461
  }, {
@@ -2384,6 +2464,9 @@ export class Datetime {
2384
2464
  }, {
2385
2465
  "propName": "max",
2386
2466
  "methodName": "maxChanged"
2467
+ }, {
2468
+ "propName": "presentation",
2469
+ "methodName": "presentationChanged"
2387
2470
  }, {
2388
2471
  "propName": "yearValues",
2389
2472
  "methodName": "yearValuesChanged"
@@ -402,3 +402,82 @@ configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
402
402
  });
403
403
  });
404
404
  });
405
+ /**
406
+ * This behavior does not differ across
407
+ * directions.
408
+ */
409
+ configs({ directions: ['ltr'] }).forEach(({ title, config }) => {
410
+ test.describe(title('datetime: formatOptions'), () => {
411
+ test('should format header and time button', async ({ page }) => {
412
+ await page.setContent(`
413
+ <ion-datetime value="2022-02-01T16:30:00">
414
+ <span slot="title">Select Date</span>
415
+ </ion-datetime>
416
+ <script>
417
+ const datetime = document.querySelector('ion-datetime');
418
+ datetime.formatOptions = {
419
+ time: { hour: '2-digit', minute: '2-digit' },
420
+ date: { day: '2-digit', month: 'long', era: 'short' },
421
+ }
422
+ </script>
423
+ `, config);
424
+ await page.locator('.datetime-ready').waitFor();
425
+ const headerDate = page.locator('ion-datetime .datetime-selected-date');
426
+ await expect(headerDate).toHaveText('February 01 AD');
427
+ const timeBody = page.locator('ion-datetime .time-body');
428
+ await expect(timeBody).toHaveText('04:30 PM');
429
+ });
430
+ });
431
+ });
432
+ /**
433
+ * This behavior does not differ across
434
+ * modes/directions.
435
+ */
436
+ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
437
+ test.describe(title('datetime: formatOptions misconfiguration errors'), () => {
438
+ test('should log a warning if time zone is provided', async ({ page }) => {
439
+ const logs = [];
440
+ page.on('console', (msg) => {
441
+ if (msg.type() === 'warning') {
442
+ logs.push(msg.text());
443
+ }
444
+ });
445
+ await page.setContent(`
446
+ <ion-datetime value="2022-02-01T16:30:00" presentation="date">
447
+ <span slot="title">Select Date</span>
448
+ </ion-datetime>
449
+ <script>
450
+ const datetime = document.querySelector('ion-datetime');
451
+ datetime.formatOptions = {
452
+ date: { timeZone: 'UTC' },
453
+ }
454
+ </script>
455
+ `, config);
456
+ await page.locator('.datetime-ready').waitFor();
457
+ expect(logs.length).toBe(1);
458
+ expect(logs[0]).toContain('[Ionic Warning]: Datetime: "timeZone" and "timeZoneName" are not supported in "formatOptions".');
459
+ });
460
+ test('should log a warning if the required formatOptions are not provided for a presentation', async ({ page }) => {
461
+ const logs = [];
462
+ page.on('console', (msg) => {
463
+ if (msg.type() === 'warning') {
464
+ logs.push(msg.text());
465
+ }
466
+ });
467
+ await page.setContent(`
468
+ <ion-datetime value="2022-02-01T16:30:00">
469
+ <span slot="title">Select Date</span>
470
+ </ion-datetime>
471
+ <script>
472
+ const datetime = document.querySelector('ion-datetime');
473
+ datetime.formatOptions = {
474
+ time: { hour: '2-digit', minute: '2-digit' },
475
+ }
476
+ </script>
477
+ `, config);
478
+ await page.locator('.datetime-ready').waitFor();
479
+ expect(logs.length).toBe(1);
480
+ expect(logs[0]).toContain("[Ionic Warning]: Datetime: The 'date-time' presentation requires both a date and time object in formatOptions.");
481
+ });
482
+ });
483
+ });
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
- import { generateDayAriaLabel, getMonthAndDay, getFormattedHour, addTimePadding, getMonthAndYear, getLocalizedDayPeriod, getLocalizedTime, } from "../utils/format";
4
+ import { generateDayAriaLabel, getMonthAndDay, getFormattedHour, addTimePadding, getMonthAndYear, getLocalizedDayPeriod, getLocalizedTime, stripTimeZone, } from "../utils/format";
5
5
  describe('generateDayAriaLabel()', () => {
6
6
  it('should return Wednesday, May 12', () => {
7
7
  const reference = { month: 5, day: 12, year: 2021 };
@@ -121,4 +121,68 @@ describe('getLocalizedTime', () => {
121
121
  expect(getLocalizedTime('en-US', datetimeParts, 'h12')).toEqual('10:40 PM');
122
122
  expect(getLocalizedTime('en-US', datetimeParts, 'h23')).toEqual('22:40');
123
123
  });
124
+ it('should use formatOptions', () => {
125
+ const datetimeParts = {
126
+ day: 1,
127
+ month: 1,
128
+ year: 2022,
129
+ hour: 9,
130
+ minute: 40,
131
+ };
132
+ const formatOptions = {
133
+ hour: '2-digit',
134
+ minute: '2-digit',
135
+ dayPeriod: 'short',
136
+ day: '2-digit',
137
+ };
138
+ // Even though this method is intended to be used for time, the date may be displayed as well when passing formatOptions
139
+ expect(getLocalizedTime('en-US', datetimeParts, 'h12', formatOptions)).toEqual('01, 09:40 in the morning');
140
+ });
141
+ it('should override provided time zone with UTC', () => {
142
+ const datetimeParts = {
143
+ day: 1,
144
+ month: 1,
145
+ year: 2022,
146
+ hour: 9,
147
+ minute: 40,
148
+ };
149
+ const formatOptions = {
150
+ timeZone: 'Australia/Sydney',
151
+ timeZoneName: 'long',
152
+ hour: 'numeric',
153
+ minute: 'numeric',
154
+ };
155
+ expect(getLocalizedTime('en-US', datetimeParts, 'h12', formatOptions)).toEqual('9:40 AM');
156
+ });
157
+ it('should not include time zone name', () => {
158
+ const datetimeParts = {
159
+ day: 1,
160
+ month: 1,
161
+ year: 2022,
162
+ hour: 9,
163
+ minute: 40,
164
+ };
165
+ const formatOptions = {
166
+ timeZone: 'America/Los_Angeles',
167
+ timeZoneName: 'long',
168
+ hour: 'numeric',
169
+ minute: 'numeric',
170
+ };
171
+ expect(getLocalizedTime('en-US', datetimeParts, 'h12', formatOptions)).toEqual('9:40 AM');
172
+ });
173
+ });
174
+ describe('stripTimeZone', () => {
175
+ it('should remove the time zone name from the options and set the time zone to UTC', () => {
176
+ const formatOptions = {
177
+ timeZone: 'America/Los_Angeles',
178
+ timeZoneName: 'long',
179
+ hour: 'numeric',
180
+ minute: 'numeric',
181
+ };
182
+ expect(stripTimeZone(formatOptions)).toEqual({
183
+ timeZone: 'UTC',
184
+ hour: 'numeric',
185
+ minute: 'numeric',
186
+ });
187
+ });
124
188
  });
@@ -9,7 +9,25 @@ const getFormattedDayPeriod = (dayPeriod) => {
9
9
  }
10
10
  return dayPeriod.toUpperCase();
11
11
  };
12
- export const getLocalizedTime = (locale, refParts, hourCycle) => {
12
+ /**
13
+ * Including time zone options may lead to the rendered text showing a
14
+ * different time from what was selected in the Datetime, which could cause
15
+ * confusion.
16
+ */
17
+ export const stripTimeZone = (formatOptions) => {
18
+ /**
19
+ * We do not want to display the time zone name
20
+ */
21
+ delete formatOptions.timeZoneName;
22
+ /**
23
+ * Setting the time zone to UTC ensures that the value shown is always the
24
+ * same as what was selected and safeguards against older Safari bugs with
25
+ * Intl.DateTimeFormat.
26
+ */
27
+ formatOptions.timeZone = 'UTC';
28
+ return formatOptions;
29
+ };
30
+ export const getLocalizedTime = (locale, refParts, hourCycle, formatOptions) => {
13
31
  const timeParts = {
14
32
  hour: refParts.hour,
15
33
  minute: refParts.minute,
@@ -17,28 +35,18 @@ export const getLocalizedTime = (locale, refParts, hourCycle) => {
17
35
  if (timeParts.hour === undefined || timeParts.minute === undefined) {
18
36
  return 'Invalid Time';
19
37
  }
20
- return new Intl.DateTimeFormat(locale, {
21
- hour: 'numeric',
22
- minute: 'numeric',
23
- /**
24
- * Setting the timeZone to UTC prevents
25
- * new Intl.DatetimeFormat from subtracting
26
- * the user's current timezone offset
27
- * when formatting the time.
28
- */
29
- timeZone: 'UTC',
38
+ const defaultFormatOptions = { hour: 'numeric', minute: 'numeric' };
39
+ /**
40
+ * If any options are provided, don't use any of the defaults.
41
+ */
42
+ const options = stripTimeZone(formatOptions !== null && formatOptions !== void 0 ? formatOptions : defaultFormatOptions);
43
+ return new Intl.DateTimeFormat(locale, Object.assign(Object.assign({}, options), {
30
44
  /**
31
45
  * We use hourCycle here instead of hour12 due to:
32
46
  * https://bugs.chromium.org/p/chromium/issues/detail?id=1347316&q=hour12&can=2
33
47
  */
34
- hourCycle,
35
- /**
36
- * Setting Z at the end indicates that this
37
- * date string is in the UTC time zone. This
38
- * prevents new Date from adding the time zone
39
- * offset when getting the ISO string.
40
- */
41
- }).format(new Date(convertDataToISO(Object.assign({
48
+ hourCycle
49
+ })).format(new Date(convertDataToISO(Object.assign({
42
50
  /**
43
51
  * JS uses a simplified ISO 8601 format which allows for
44
52
  * date-only formats and date-time formats, but not
@@ -201,7 +209,7 @@ export const getNormalizedDate = (refParts) => {
201
209
  */
202
210
  export const getLocalizedDateTime = (locale, refParts, options) => {
203
211
  const date = getNormalizedDate(refParts);
204
- return getDateTimeFormat(locale, options).format(date);
212
+ return getDateTimeFormat(locale, stripTimeZone(options)).format(date);
205
213
  };
206
214
  /**
207
215
  * Given a locale, DatetimeParts, and options
@@ -7,7 +7,7 @@ import { printIonError } from "../../utils/logging/index";
7
7
  import { createColorClasses } from "../../utils/theme";
8
8
  import { getIonMode } from "../../global/ionic-global";
9
9
  import { getToday } from "../datetime/utils/data";
10
- import { getMonthAndYear, getMonthDayAndYear, getLocalizedDateTime, getLocalizedTime } from "../datetime/utils/format";
10
+ import { getLocalizedDateTime, getLocalizedTime } from "../datetime/utils/format";
11
11
  import { getHourCycle } from "../datetime/utils/helpers";
12
12
  import { parseDate } from "../datetime/utils/parse";
13
13
  /**
@@ -43,11 +43,12 @@ export class DatetimeButton {
43
43
  * to the locale specified on ion-datetime.
44
44
  */
45
45
  this.setDateTimeText = () => {
46
+ var _a, _b, _c, _d, _e;
46
47
  const { datetimeEl, datetimePresentation } = this;
47
48
  if (!datetimeEl) {
48
49
  return;
49
50
  }
50
- const { value, locale, hourCycle, preferWheel, multiple, titleSelectedDatesFormatter } = datetimeEl;
51
+ const { value, locale, formatOptions, hourCycle, preferWheel, multiple, titleSelectedDatesFormatter } = datetimeEl;
51
52
  const parsedValues = this.getParsedDateValues(value);
52
53
  /**
53
54
  * Both ion-datetime and ion-datetime-button default
@@ -70,8 +71,8 @@ export class DatetimeButton {
70
71
  switch (datetimePresentation) {
71
72
  case 'date-time':
72
73
  case 'time-date':
73
- const dateText = getMonthDayAndYear(locale, firstParsedDatetime);
74
- const timeText = getLocalizedTime(locale, firstParsedDatetime, computedHourCycle);
74
+ const dateText = getLocalizedDateTime(locale, firstParsedDatetime, (_a = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.date) !== null && _a !== void 0 ? _a : { month: 'short', day: 'numeric', year: 'numeric' });
75
+ const timeText = getLocalizedTime(locale, firstParsedDatetime, computedHourCycle, formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time);
75
76
  if (preferWheel) {
76
77
  this.dateText = `${dateText} ${timeText}`;
77
78
  }
@@ -94,20 +95,20 @@ export class DatetimeButton {
94
95
  this.dateText = headerText;
95
96
  }
96
97
  else {
97
- this.dateText = getMonthDayAndYear(locale, firstParsedDatetime);
98
+ this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, (_b = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.date) !== null && _b !== void 0 ? _b : { month: 'short', day: 'numeric', year: 'numeric' });
98
99
  }
99
100
  break;
100
101
  case 'time':
101
- this.timeText = getLocalizedTime(locale, firstParsedDatetime, computedHourCycle);
102
+ this.timeText = getLocalizedTime(locale, firstParsedDatetime, computedHourCycle, formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time);
102
103
  break;
103
104
  case 'month-year':
104
- this.dateText = getMonthAndYear(locale, firstParsedDatetime);
105
+ this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, (_c = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.date) !== null && _c !== void 0 ? _c : { month: 'long', year: 'numeric' });
105
106
  break;
106
107
  case 'month':
107
- this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, { month: 'long' });
108
+ this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, (_d = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time) !== null && _d !== void 0 ? _d : { month: 'long' });
108
109
  break;
109
110
  case 'year':
110
- this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, { year: 'numeric' });
111
+ this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, (_e = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time) !== null && _e !== void 0 ? _e : { year: 'numeric' });
111
112
  break;
112
113
  }
113
114
  };
@@ -336,7 +337,7 @@ export class DatetimeButton {
336
337
  render() {
337
338
  const { color, dateText, timeText, selectedButton, datetimeActive, disabled } = this;
338
339
  const mode = getIonMode(this);
339
- return (h(Host, { key: '36fe34d4225940611d74bdef5b954d54749d2dca', class: createColorClasses(color, {
340
+ return (h(Host, { key: '861a08f4a239de771875aee9b505e06ac7064b32', class: createColorClasses(color, {
340
341
  [mode]: true,
341
342
  [`${selectedButton}-active`]: datetimeActive,
342
343
  ['datetime-button-disabled']: disabled,
@@ -174,4 +174,70 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
174
174
  await expect(page.locator('#time-button')).not.toBeVisible();
175
175
  });
176
176
  });
177
+ test.describe(title('datetime-button: formatOptions'), () => {
178
+ test('should include date and time for presentation date-time', async ({ page }) => {
179
+ await page.setContent(`
180
+ <ion-datetime-button datetime="datetime"></ion-datetime-button>
181
+ <ion-datetime id="datetime" presentation="date-time" value="2023-11-02T01:22:00" locale="en-US"></ion-datetime>
182
+ <script>
183
+ const datetime = document.querySelector('ion-datetime');
184
+ datetime.formatOptions = {
185
+ date: {
186
+ weekday: "short",
187
+ month: "long",
188
+ day: "2-digit"
189
+ },
190
+ time: {
191
+ hour: "2-digit",
192
+ minute: "2-digit"
193
+ }
194
+ }
195
+ </script>
196
+ `, config);
197
+ await page.locator('.datetime-ready').waitFor();
198
+ await expect(page.locator('#date-button')).toContainText('Thu, November 02');
199
+ await expect(page.locator('#time-button')).toContainText('01:22 AM');
200
+ });
201
+ test('should include date for presentation date', async ({ page }) => {
202
+ await page.setContent(`
203
+ <ion-datetime-button datetime="datetime"></ion-datetime-button>
204
+ <ion-datetime id="datetime" presentation="date" value="2023-11-02" locale="en-US"></ion-datetime>
205
+ <script>
206
+ const datetime = document.querySelector('ion-datetime');
207
+ datetime.formatOptions = {
208
+ date: {
209
+ weekday: "short",
210
+ month: "long",
211
+ day: "2-digit"
212
+ }
213
+ }
214
+ </script>
215
+ `, config);
216
+ await page.locator('.datetime-ready').waitFor();
217
+ await expect(page.locator('#date-button')).toContainText('Thu, November 02');
218
+ });
219
+ test('should include date and time in same button for preferWheel', async ({ page }) => {
220
+ await page.setContent(`
221
+ <ion-datetime-button datetime="datetime"></ion-datetime-button>
222
+ <ion-datetime id="datetime" presentation="date-time" value="2023-11-02T01:22:00" locale="en-US" prefer-wheel="true"></ion-datetime>
223
+ <script>
224
+ const datetime = document.querySelector('ion-datetime');
225
+ datetime.formatOptions = {
226
+ date: {
227
+ weekday: "short",
228
+ month: "long",
229
+ day: "2-digit"
230
+ },
231
+ time: {
232
+ hour: "2-digit",
233
+ minute: "2-digit"
234
+ }
235
+ }
236
+ </script>
237
+ `, config);
238
+ await page.locator('.datetime-ready').waitFor();
239
+ await page.pause();
240
+ await expect(page.locator('ion-datetime-button')).toContainText('Thu, November 02 01:22 AM');
241
+ });
242
+ });
177
243
  });
@@ -71,6 +71,10 @@
71
71
  overflow: hidden;
72
72
  }
73
73
 
74
+ :host-context(.item:not(.item-input):not(.item-legacy)) {
75
+ flex-grow: 1;
76
+ }
77
+
74
78
  :host(.ion-color) {
75
79
  color: var(--ion-color-base);
76
80
  }
@@ -71,6 +71,10 @@
71
71
  overflow: hidden;
72
72
  }
73
73
 
74
+ :host-context(.item:not(.item-input):not(.item-legacy)) {
75
+ flex-grow: 1;
76
+ }
77
+
74
78
  :host(.ion-color) {
75
79
  color: var(--ion-color-base);
76
80
  }
@@ -113,10 +113,6 @@ export class Loading {
113
113
  * This can be useful in a button handler for determining which button was
114
114
  * clicked to dismiss the loading.
115
115
  * Some examples include: ``"cancel"`, `"destructive"`, "selected"`, and `"backdrop"`.
116
- *
117
- * This is a no-op if the overlay has not been presented yet. If you want
118
- * to remove an overlay from the DOM that was never presented, use the
119
- * [remove](https://developer.mozilla.org/en-US/docs/Web/API/Element/remove) method.
120
116
  */
121
117
  async dismiss(data, role) {
122
118
  const unlock = await this.lockController.lock();
@@ -158,9 +154,9 @@ export class Loading {
158
154
  * Otherwise, don't set aria-labelledby.
159
155
  */
160
156
  const ariaLabelledBy = message !== undefined ? msgId : null;
161
- return (h(Host, Object.assign({ key: '95123f54ba1db5e59563d79db075315b43ed20f7', role: "dialog", "aria-modal": "true", "aria-labelledby": ariaLabelledBy, tabindex: "-1" }, htmlAttributes, { style: {
157
+ return (h(Host, Object.assign({ key: '81295894ca6e047124918420f2483c092ebf91b9', role: "dialog", "aria-modal": "true", "aria-labelledby": ariaLabelledBy, tabindex: "-1" }, htmlAttributes, { style: {
162
158
  zIndex: `${40000 + this.overlayIndex}`,
163
- }, onIonBackdropTap: this.onBackdropTap, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'overlay-hidden': true, 'loading-translucent': this.translucent }) }), h("ion-backdrop", { key: 'e113bf123eaad38f2dafce8ea5d2ebef409d0c0f', visible: this.showBackdrop, tappable: this.backdropDismiss }), h("div", { key: '1268c9480854383c7883a79d597350540ade93c2', tabindex: "0" }), h("div", { key: 'e86fc71504ebd578117dea2232d9740a087d1249', class: "loading-wrapper ion-overlay-wrapper" }, spinner && (h("div", { class: "loading-spinner" }, h("ion-spinner", { name: spinner, "aria-hidden": "true" }))), message !== undefined && this.renderLoadingMessage(msgId)), h("div", { key: '3b91e2492e06aa65ebe77ed2b6ffb9d2f84bdd9c', tabindex: "0" })));
159
+ }, onIonBackdropTap: this.onBackdropTap, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'overlay-hidden': true, 'loading-translucent': this.translucent }) }), h("ion-backdrop", { key: 'db9fbd946cf3eb03c3a70f2e71c49ab233df1879', visible: this.showBackdrop, tappable: this.backdropDismiss }), h("div", { key: 'd27b03de0b450c0668d4b4077d76bc5b283f03cf', tabindex: "0" }), h("div", { key: '7112719ddd487365c1e36fc4dec32aac888dbb52', class: "loading-wrapper ion-overlay-wrapper" }, spinner && (h("div", { class: "loading-spinner" }, h("ion-spinner", { name: spinner, "aria-hidden": "true" }))), message !== undefined && this.renderLoadingMessage(msgId)), h("div", { key: '5715dd7dae209ae58e5557cb60f3ae514752b822', tabindex: "0" })));
164
160
  }
165
161
  static get is() { return "ion-loading"; }
166
162
  static get encapsulation() { return "scoped"; }
@@ -684,7 +680,7 @@ export class Loading {
684
680
  }, {
685
681
  "name": "role",
686
682
  "type": "string | undefined",
687
- "docs": "The role of the element that is dismissing the loading.\nThis can be useful in a button handler for determining which button was\nclicked to dismiss the loading.\nSome examples include: ``\"cancel\"`, `\"destructive\"`, \"selected\"`, and `\"backdrop\"`.\n\nThis is a no-op if the overlay has not been presented yet. If you want\nto remove an overlay from the DOM that was never presented, use the\n[remove](https://developer.mozilla.org/en-US/docs/Web/API/Element/remove) method."
683
+ "docs": "The role of the element that is dismissing the loading.\nThis can be useful in a button handler for determining which button was\nclicked to dismiss the loading.\nSome examples include: ``\"cancel\"`, `\"destructive\"`, \"selected\"`, and `\"backdrop\"`."
688
684
  }],
689
685
  "references": {
690
686
  "Promise": {
@@ -701,7 +697,7 @@ export class Loading {
701
697
  "text": "data Any data to emit in the dismiss events."
702
698
  }, {
703
699
  "name": "param",
704
- "text": "role The role of the element that is dismissing the loading.\nThis can be useful in a button handler for determining which button was\nclicked to dismiss the loading.\nSome examples include: ``\"cancel\"`, `\"destructive\"`, \"selected\"`, and `\"backdrop\"`.\n\nThis is a no-op if the overlay has not been presented yet. If you want\nto remove an overlay from the DOM that was never presented, use the\n[remove](https://developer.mozilla.org/en-US/docs/Web/API/Element/remove) method."
700
+ "text": "role The role of the element that is dismissing the loading.\nThis can be useful in a button handler for determining which button was\nclicked to dismiss the loading.\nSome examples include: ``\"cancel\"`, `\"destructive\"`, \"selected\"`, and `\"backdrop\"`."
705
701
  }]
706
702
  }
707
703
  },