@sparkle-learning/core 0.0.32 → 0.0.35

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 (611) hide show
  1. package/dist/cjs/PrivateRoute-4abc9d29.js +35 -0
  2. package/dist/cjs/{active-router-eedb3bfe.js → active-router-f9e18bd8.js} +1 -1
  3. package/dist/cjs/{animation-6132e37f.js → animation-ee586546.js} +83 -78
  4. package/dist/cjs/{app-globals-9869bf67.js → app-globals-33c9f31b.js} +1 -1
  5. package/dist/cjs/{PrivateRoute-043bb7d3.js → auth.service-4b584cd7.js} +4 -33
  6. package/dist/cjs/{auth.store-ff3fda09.js → auth.store-1e630a7d.js} +48 -725
  7. package/dist/cjs/compass-svg.cjs.entry.js +1 -1
  8. package/dist/cjs/context-consumer.cjs.entry.js +1 -1
  9. package/dist/cjs/course-select.cjs.entry.js +1 -1
  10. package/dist/cjs/{cubic-bezier-293f4663.js → cubic-bezier-53d26d05.js} +10 -11
  11. package/dist/cjs/dom-utils-b8befdd5.js +63 -0
  12. package/dist/cjs/{facilitator.service-faac5c0c.js → facilitator.service-9e990274.js} +8 -7
  13. package/dist/cjs/{feed.service-66405969.js → feed.service-b4f09441.js} +8 -7
  14. package/dist/cjs/{focus-visible-ad3828a7.js → focus-visible-b0b07ba6.js} +19 -6
  15. package/dist/cjs/{framework-delegate-2470a246.js → framework-delegate-59a98abd.js} +11 -13
  16. package/dist/cjs/{gesture-controller-07c31f70.js → gesture-controller-0eb5579e.js} +1 -1
  17. package/dist/cjs/{haptic-91e86eb7.js → haptic-780f33c4.js} +3 -2
  18. package/dist/cjs/{hardware-back-button-f7b5d99e.js → hardware-back-button-92d97ff8.js} +8 -8
  19. package/dist/cjs/header-mobile-collapse_2.cjs.entry.js +112 -0
  20. package/dist/cjs/{helpers-7e28976c.js → helpers-c2496722.js} +81 -14
  21. package/dist/cjs/httpService-7211d93b.js +685 -0
  22. package/dist/cjs/{icons-80d477f6.js → icons-c61db785.js} +1 -1
  23. package/dist/cjs/{index-43642662.js → index-12082cba.js} +21 -18
  24. package/dist/cjs/{index-459a5fa9.js → index-15ea05f5.js} +19 -28
  25. package/dist/cjs/{index-bae2a754.js → index-51e8292e.js} +18 -11
  26. package/dist/cjs/index-70e63f5b.js +3071 -0
  27. package/dist/cjs/{index-b12edb26.js → index-787d4498.js} +17 -25
  28. package/dist/cjs/{tap-click-1caf1780.js → index-8b5629a6.js} +30 -20
  29. package/dist/cjs/{index-8540d72e.js → index-975586fd.js} +7 -1
  30. package/dist/cjs/index-9c7b27e4.js +140 -0
  31. package/dist/cjs/{index-185f9c5a.js → index-af080b50.js} +9 -8
  32. package/dist/cjs/index-e56e09b8.js +38 -0
  33. package/dist/cjs/index.cjs.js +13 -11
  34. package/dist/cjs/{index.es-ef3efdfb.js → index.es-38cbcdbe.js} +2 -7
  35. package/dist/cjs/injectHistory-7206bbb9.js +9 -0
  36. package/dist/cjs/{input-shims-6c442c9f.js → input-shims-eff63b88.js} +21 -24
  37. package/dist/cjs/ion-accordion-group.cjs.entry.js +17 -9
  38. package/dist/cjs/ion-accordion.cjs.entry.js +19 -23
  39. package/dist/cjs/ion-action-sheet_4.cjs.entry.js +216 -212
  40. package/dist/cjs/ion-app.cjs.entry.js +8 -8
  41. package/dist/cjs/ion-avatar_16.cjs.entry.js +1907 -0
  42. package/dist/cjs/ion-back-button.cjs.entry.js +11 -11
  43. package/dist/cjs/ion-backdrop.cjs.entry.js +4 -4
  44. package/dist/cjs/ion-badge.cjs.entry.js +3 -3
  45. package/dist/cjs/ion-breadcrumb.cjs.entry.js +13 -21
  46. package/dist/cjs/ion-breadcrumbs.cjs.entry.js +12 -14
  47. package/dist/cjs/ion-buttons_3.cjs.entry.js +13 -13
  48. package/dist/cjs/ion-card-header.cjs.entry.js +4 -4
  49. package/dist/cjs/ion-card-subtitle.cjs.entry.js +4 -4
  50. package/dist/cjs/ion-checkbox_4.cjs.entry.js +360 -0
  51. package/dist/cjs/ion-chip.cjs.entry.js +3 -3
  52. package/dist/cjs/ion-col_3.cjs.entry.js +159 -0
  53. package/dist/cjs/ion-content_2.cjs.entry.js +59 -52
  54. package/dist/cjs/ion-datetime-button.cjs.entry.js +312 -0
  55. package/dist/cjs/ion-datetime.cjs.entry.js +752 -1245
  56. package/dist/cjs/ion-fab-button.cjs.entry.js +25 -9
  57. package/dist/cjs/ion-fab-list.cjs.entry.js +4 -4
  58. package/dist/cjs/ion-fab.cjs.entry.js +15 -13
  59. package/dist/cjs/ion-footer.cjs.entry.js +16 -14
  60. package/dist/cjs/ion-img.cjs.entry.js +4 -4
  61. package/dist/cjs/ion-infinite-scroll-content.cjs.entry.js +5 -5
  62. package/dist/cjs/ion-infinite-scroll.cjs.entry.js +13 -15
  63. package/dist/cjs/ion-item-divider.cjs.entry.js +4 -4
  64. package/dist/cjs/ion-item-group.cjs.entry.js +3 -3
  65. package/dist/cjs/ion-item-option.cjs.entry.js +8 -8
  66. package/dist/cjs/ion-item-options.cjs.entry.js +5 -5
  67. package/dist/cjs/ion-item-sliding.cjs.entry.js +41 -46
  68. package/dist/cjs/ion-loading.cjs.entry.js +23 -35
  69. package/dist/cjs/ion-menu-button.cjs.entry.js +13 -13
  70. package/dist/cjs/ion-menu-toggle.cjs.entry.js +7 -7
  71. package/dist/cjs/ion-menu.cjs.entry.js +47 -40
  72. package/dist/cjs/ion-modal.cjs.entry.js +935 -282
  73. package/dist/cjs/ion-nav-link.cjs.entry.js +2 -2
  74. package/dist/cjs/ion-nav.cjs.entry.js +45 -35
  75. package/dist/cjs/ion-picker-column-internal_2.cjs.entry.js +151 -43
  76. package/dist/cjs/ion-picker-column.cjs.entry.js +23 -25
  77. package/dist/cjs/ion-picker.cjs.entry.js +15 -17
  78. package/dist/cjs/ion-progress-bar.cjs.entry.js +6 -8
  79. package/dist/cjs/ion-range.cjs.entry.js +515 -0
  80. package/dist/cjs/ion-refresher-content.cjs.entry.js +6 -12
  81. package/dist/cjs/ion-refresher.cjs.entry.js +68 -50
  82. package/dist/cjs/ion-reorder-group.cjs.entry.js +15 -16
  83. package/dist/cjs/ion-reorder.cjs.entry.js +3 -3
  84. package/dist/cjs/ion-route-redirect.cjs.entry.js +1 -1
  85. package/dist/cjs/ion-route.cjs.entry.js +1 -1
  86. package/dist/cjs/ion-router-link.cjs.entry.js +5 -5
  87. package/dist/cjs/ion-router-outlet.cjs.entry.js +22 -20
  88. package/dist/cjs/ion-router.cjs.entry.js +32 -31
  89. package/dist/cjs/ion-searchbar.cjs.entry.js +14 -16
  90. package/dist/cjs/ion-segment-button.cjs.entry.js +8 -8
  91. package/dist/cjs/ion-segment.cjs.entry.js +24 -26
  92. package/dist/cjs/ion-select_2.cjs.entry.js +59 -56
  93. package/dist/cjs/ion-skeleton-text.cjs.entry.js +4 -4
  94. package/dist/cjs/ion-slide.cjs.entry.js +3 -3
  95. package/dist/cjs/ion-slides.cjs.entry.js +23 -23
  96. package/dist/cjs/ion-split-pane.cjs.entry.js +10 -11
  97. package/dist/cjs/ion-tab-bar.cjs.entry.js +5 -5
  98. package/dist/cjs/ion-tab-button.cjs.entry.js +6 -6
  99. package/dist/cjs/ion-tab.cjs.entry.js +4 -4
  100. package/dist/cjs/ion-tabs.cjs.entry.js +4 -5
  101. package/dist/cjs/ion-text.cjs.entry.js +24 -0
  102. package/dist/cjs/ion-thumbnail.cjs.entry.js +2 -2
  103. package/dist/cjs/ion-toast.cjs.entry.js +23 -43
  104. package/dist/cjs/ion-virtual-scroll.cjs.entry.js +29 -28
  105. package/dist/cjs/{ionic-global-878073d1.js → ionic-global-2cde9d3a.js} +27 -31
  106. package/dist/cjs/{ios.transition-c3bfb096.js → ios.transition-da235483.js} +71 -51
  107. package/dist/cjs/{keyboard-dfd76ac3.js → keyboard-91096619.js} +3 -3
  108. package/dist/cjs/loader.cjs.js +5 -5
  109. package/dist/cjs/match-path-84c9f7ca.js +511 -0
  110. package/dist/cjs/{md.transition-7eb9a1a7.js → md.transition-be429e07.js} +9 -16
  111. package/dist/cjs/{menu-toggle-util-cb549c2c.js → menu-toggle-util-7a01448c.js} +2 -2
  112. package/dist/cjs/{overlays-0a748609.js → overlays-32df265a.js} +29 -29
  113. package/dist/cjs/parse-d0071120.js +1237 -0
  114. package/dist/cjs/{purify-d0ad2883.js → purify-fb9c107e.js} +1 -1
  115. package/dist/cjs/sparkle-animation-player.cjs.entry.js +1 -1
  116. package/dist/cjs/sparkle-card_3.cjs.entry.js +91 -0
  117. package/dist/cjs/sparkle-character-intro.cjs.entry.js +1 -1
  118. package/dist/cjs/sparkle-code.cjs.entry.js +2 -2
  119. package/dist/cjs/sparkle-compass-post.cjs.entry.js +1 -1
  120. package/dist/cjs/sparkle-compass.cjs.entry.js +1 -1
  121. package/dist/cjs/sparkle-core.cjs.js +5 -5
  122. package/dist/cjs/sparkle-course-root.cjs.entry.js +146 -0
  123. package/dist/cjs/sparkle-dropdown.cjs.entry.js +61 -0
  124. package/dist/cjs/sparkle-emoji.cjs.entry.js +1 -1
  125. package/dist/cjs/{header-mobile-collapse_61.cjs.entry.js → sparkle-export-lessons_6.cjs.entry.js} +8865 -17663
  126. package/dist/cjs/sparkle-facilitator-header_19.cjs.entry.js +2130 -0
  127. package/dist/cjs/sparkle-facilitator-notes-form.cjs.entry.js +8 -7
  128. package/dist/cjs/sparkle-feedback.cjs.entry.js +9 -7
  129. package/dist/cjs/sparkle-goal-form.cjs.entry.js +8 -7
  130. package/dist/cjs/sparkle-goal-progress.cjs.entry.js +19 -0
  131. package/dist/cjs/sparkle-gww-comment-list.cjs.entry.js +1 -1
  132. package/dist/cjs/sparkle-gww-graph.cjs.entry.js +1 -1
  133. package/dist/cjs/sparkle-gww-item.cjs.entry.js +74 -0
  134. package/dist/cjs/sparkle-intro.cjs.entry.js +26 -0
  135. package/dist/cjs/sparkle-lower-content-nav.cjs.entry.js +1 -1
  136. package/dist/cjs/sparkle-menu-collapsible.cjs.entry.js +2 -2
  137. package/dist/cjs/sparkle-menu-toggle_3.cjs.entry.js +236 -0
  138. package/dist/cjs/sparkle-modal-image.cjs.entry.js +1 -1
  139. package/dist/cjs/sparkle-notfound-page.cjs.entry.js +1 -1
  140. package/dist/cjs/sparkle-overlay.cjs.entry.js +1 -1
  141. package/dist/cjs/sparkle-poll.cjs.entry.js +1 -1
  142. package/dist/cjs/sparkle-quiz-container.cjs.entry.js +1 -1
  143. package/dist/cjs/sparkle-quiz-feedback_5.cjs.entry.js +1 -1
  144. package/dist/cjs/sparkle-quiz.cjs.entry.js +1 -1
  145. package/dist/cjs/sparkle-select.cjs.entry.js +1 -1
  146. package/dist/cjs/sparkle-sidebar.cjs.entry.js +1 -1
  147. package/dist/cjs/sparkle-tab.cjs.entry.js +1 -1
  148. package/dist/cjs/sparkle-table-of-contents.cjs.entry.js +1 -1
  149. package/dist/cjs/sparkle-tabs.cjs.entry.js +1 -1
  150. package/dist/cjs/sparkle-validation-error.cjs.entry.js +21 -0
  151. package/dist/cjs/sparkle-youtube.cjs.entry.js +1 -1
  152. package/dist/cjs/{spinner-configs-6f6b7ef0.js → spinner-configs-0ac05f2d.js} +43 -43
  153. package/dist/cjs/{status-tap-8697433c.js → status-tap-033befa2.js} +7 -5
  154. package/dist/cjs/stencil-async-content.cjs.entry.js +1 -1
  155. package/dist/cjs/stencil-route-link.cjs.entry.js +77 -0
  156. package/dist/cjs/stencil-route-title.cjs.entry.js +2 -2
  157. package/dist/cjs/stencil-router-prompt.cjs.entry.js +2 -2
  158. package/dist/cjs/stencil-router-redirect.cjs.entry.js +32 -0
  159. package/dist/cjs/student.service-d48f1c99.js +61 -0
  160. package/dist/cjs/{swipe-back-7e08b5e0.js → swipe-back-4a826f9b.js} +5 -5
  161. package/dist/cjs/{theme-4252ac15.js → theme-b0b295c1.js} +6 -5
  162. package/dist/cjs/user.store-8a049c4e.js +21 -0
  163. package/dist/collection/collection-manifest.json +3 -1
  164. package/dist/collection/components/sparkle-feed-post/sparkle-feed-post.css +16 -0
  165. package/dist/collection/components/sparkle-feed-post/sparkle-feed-post.js +197 -3
  166. package/dist/collection/components/sparkle-intro/sparkle-intro.css +15 -0
  167. package/dist/collection/components/sparkle-intro/sparkle-intro.js +35 -0
  168. package/dist/esm/PrivateRoute-530ef873.js +33 -0
  169. package/dist/esm/{active-router-909088d6.js → active-router-9843e205.js} +1 -1
  170. package/dist/esm/{animation-b306f6c2.js → animation-d98d3e81.js} +83 -78
  171. package/dist/esm/{app-globals-5c736ae5.js → app-globals-08edc964.js} +1 -1
  172. package/dist/esm/{PrivateRoute-b9937c45.js → auth.service-79389d86.js} +4 -32
  173. package/dist/esm/{auth.store-3ed2389e.js → auth.store-b812b34b.js} +45 -725
  174. package/dist/esm/compass-svg.entry.js +1 -1
  175. package/dist/esm/context-consumer.entry.js +1 -1
  176. package/dist/esm/course-select.entry.js +1 -1
  177. package/dist/esm/{cubic-bezier-a7ad9c8e.js → cubic-bezier-4c0db14f.js} +10 -11
  178. package/dist/esm/dom-utils-8e73e88b.js +55 -0
  179. package/dist/esm/{facilitator.service-ec0a9739.js → facilitator.service-7babc526.js} +2 -1
  180. package/dist/esm/{feed.service-33b83cb7.js → feed.service-80fbe79d.js} +3 -2
  181. package/dist/esm/{focus-visible-40cda868.js → focus-visible-4e9a0764.js} +19 -6
  182. package/dist/esm/{framework-delegate-3bc58c27.js → framework-delegate-9b329182.js} +11 -13
  183. package/dist/esm/{gesture-controller-686622ba.js → gesture-controller-7be18351.js} +1 -1
  184. package/dist/esm/{haptic-99c9e346.js → haptic-3a76a65c.js} +4 -3
  185. package/dist/esm/{hardware-back-button-b6ccf74a.js → hardware-back-button-fa04d6e9.js} +8 -8
  186. package/dist/esm/header-mobile-collapse_2.entry.js +107 -0
  187. package/dist/esm/{helpers-39367fe1.js → helpers-94a5855b.js} +81 -15
  188. package/dist/esm/httpService-b2b7a1ad.js +683 -0
  189. package/dist/esm/{icons-61dec176.js → icons-16f1a80b.js} +2 -2
  190. package/dist/esm/{index-a12c14bd.js → index-21661af2.js} +22 -19
  191. package/dist/esm/{tap-click-13f1fb0d.js → index-230a26c9.js} +30 -20
  192. package/dist/esm/{index-c26d8655.js → index-478745be.js} +17 -25
  193. package/dist/esm/{index-dc61f152.js → index-4ec6b9c2.js} +5 -2
  194. package/dist/esm/{index-9594837e.js → index-95307148.js} +19 -28
  195. package/dist/esm/{index-5568e3fa.js → index-9db08224.js} +19 -12
  196. package/dist/esm/index-ab1c6a9f.js +3067 -0
  197. package/dist/esm/{index-435af8e6.js → index-be6112f8.js} +9 -8
  198. package/dist/esm/index-c23a1826.js +128 -0
  199. package/dist/esm/index-dad75b83.js +34 -0
  200. package/dist/esm/{index.es-97dd8174.js → index.es-1c3b1ef3.js} +2 -7
  201. package/dist/esm/index.js +9 -7
  202. package/dist/esm/injectHistory-4bfff188.js +7 -0
  203. package/dist/esm/{input-shims-cc98ea92.js → input-shims-ce5c01df.js} +21 -24
  204. package/dist/esm/ion-accordion-group.entry.js +17 -9
  205. package/dist/esm/ion-accordion.entry.js +19 -23
  206. package/dist/esm/ion-action-sheet_4.entry.js +216 -212
  207. package/dist/esm/ion-app.entry.js +8 -8
  208. package/dist/esm/ion-avatar_16.entry.js +1888 -0
  209. package/dist/esm/ion-back-button.entry.js +11 -11
  210. package/dist/esm/ion-backdrop.entry.js +4 -4
  211. package/dist/esm/ion-badge.entry.js +3 -3
  212. package/dist/esm/ion-breadcrumb.entry.js +13 -21
  213. package/dist/esm/ion-breadcrumbs.entry.js +12 -14
  214. package/dist/esm/ion-buttons_3.entry.js +13 -13
  215. package/dist/esm/ion-card-header.entry.js +4 -4
  216. package/dist/esm/ion-card-subtitle.entry.js +4 -4
  217. package/dist/esm/ion-checkbox_4.entry.js +353 -0
  218. package/dist/esm/ion-chip.entry.js +3 -3
  219. package/dist/esm/ion-col_3.entry.js +153 -0
  220. package/dist/esm/ion-content_2.entry.js +59 -52
  221. package/dist/esm/ion-datetime-button.entry.js +308 -0
  222. package/dist/esm/ion-datetime.entry.js +723 -1216
  223. package/dist/esm/ion-fab-button.entry.js +25 -9
  224. package/dist/esm/ion-fab-list.entry.js +4 -4
  225. package/dist/esm/ion-fab.entry.js +15 -13
  226. package/dist/esm/ion-footer.entry.js +16 -14
  227. package/dist/esm/ion-img.entry.js +4 -4
  228. package/dist/esm/ion-infinite-scroll-content.entry.js +5 -5
  229. package/dist/esm/ion-infinite-scroll.entry.js +13 -15
  230. package/dist/esm/ion-item-divider.entry.js +4 -4
  231. package/dist/esm/ion-item-group.entry.js +3 -3
  232. package/dist/esm/ion-item-option.entry.js +8 -8
  233. package/dist/esm/ion-item-options.entry.js +5 -5
  234. package/dist/esm/ion-item-sliding.entry.js +41 -46
  235. package/dist/esm/ion-loading.entry.js +23 -35
  236. package/dist/esm/ion-menu-button.entry.js +13 -13
  237. package/dist/esm/ion-menu-toggle.entry.js +7 -7
  238. package/dist/esm/ion-menu.entry.js +47 -40
  239. package/dist/esm/ion-modal.entry.js +921 -268
  240. package/dist/esm/ion-nav-link.entry.js +2 -2
  241. package/dist/esm/ion-nav.entry.js +45 -35
  242. package/dist/esm/ion-picker-column-internal_2.entry.js +151 -43
  243. package/dist/esm/ion-picker-column.entry.js +23 -25
  244. package/dist/esm/ion-picker.entry.js +15 -17
  245. package/dist/esm/ion-progress-bar.entry.js +6 -8
  246. package/dist/esm/ion-range.entry.js +511 -0
  247. package/dist/esm/ion-refresher-content.entry.js +6 -12
  248. package/dist/esm/ion-refresher.entry.js +68 -50
  249. package/dist/esm/ion-reorder-group.entry.js +15 -16
  250. package/dist/esm/ion-reorder.entry.js +3 -3
  251. package/dist/esm/ion-route-redirect.entry.js +1 -1
  252. package/dist/esm/ion-route.entry.js +1 -1
  253. package/dist/esm/ion-router-link.entry.js +5 -5
  254. package/dist/esm/ion-router-outlet.entry.js +22 -20
  255. package/dist/esm/ion-router.entry.js +32 -31
  256. package/dist/esm/ion-searchbar.entry.js +14 -16
  257. package/dist/esm/ion-segment-button.entry.js +8 -8
  258. package/dist/esm/ion-segment.entry.js +24 -26
  259. package/dist/esm/ion-select_2.entry.js +59 -56
  260. package/dist/esm/ion-skeleton-text.entry.js +4 -4
  261. package/dist/esm/ion-slide.entry.js +3 -3
  262. package/dist/esm/ion-slides.entry.js +23 -23
  263. package/dist/esm/ion-split-pane.entry.js +10 -11
  264. package/dist/esm/ion-tab-bar.entry.js +5 -5
  265. package/dist/esm/ion-tab-button.entry.js +6 -6
  266. package/dist/esm/ion-tab.entry.js +4 -4
  267. package/dist/esm/ion-tabs.entry.js +4 -5
  268. package/dist/esm/ion-text.entry.js +20 -0
  269. package/dist/esm/ion-thumbnail.entry.js +2 -2
  270. package/dist/esm/ion-toast.entry.js +23 -43
  271. package/dist/esm/ion-virtual-scroll.entry.js +29 -28
  272. package/dist/esm/{ionic-global-0939c477.js → ionic-global-293e882b.js} +27 -31
  273. package/dist/esm/{ios.transition-b4ca8a33.js → ios.transition-7cd34deb.js} +71 -51
  274. package/dist/esm/{keyboard-2503e874.js → keyboard-7e8329b3.js} +3 -3
  275. package/dist/esm/loader.js +5 -5
  276. package/dist/esm/match-path-36fdf5c7.js +499 -0
  277. package/dist/esm/{md.transition-ca5e0322.js → md.transition-2589a5b1.js} +9 -16
  278. package/dist/esm/{menu-toggle-util-7fa22c2f.js → menu-toggle-util-f92ba2f0.js} +2 -2
  279. package/dist/esm/{overlays-34cfa9e0.js → overlays-dfa730c8.js} +30 -30
  280. package/dist/esm/parse-1ae3a9bb.js +1196 -0
  281. package/dist/esm/polyfills/css-shim.js +1 -1
  282. package/dist/esm/{purify-ffce2b4c.js → purify-79af871f.js} +1 -1
  283. package/dist/esm/sparkle-animation-player.entry.js +2 -2
  284. package/dist/esm/sparkle-card_3.entry.js +85 -0
  285. package/dist/esm/sparkle-character-intro.entry.js +1 -1
  286. package/dist/esm/sparkle-code.entry.js +2 -2
  287. package/dist/esm/sparkle-compass-post.entry.js +1 -1
  288. package/dist/esm/sparkle-compass.entry.js +1 -1
  289. package/dist/esm/sparkle-core.js +5 -5
  290. package/dist/esm/sparkle-course-root.entry.js +142 -0
  291. package/dist/esm/sparkle-dropdown.entry.js +57 -0
  292. package/dist/esm/sparkle-emoji.entry.js +1 -1
  293. package/dist/esm/{header-mobile-collapse_61.entry.js → sparkle-export-lessons_6.entry.js} +8860 -17603
  294. package/dist/esm/sparkle-facilitator-header_19.entry.js +2108 -0
  295. package/dist/esm/sparkle-facilitator-notes-form.entry.js +8 -7
  296. package/dist/esm/sparkle-feedback.entry.js +9 -7
  297. package/dist/esm/sparkle-goal-form.entry.js +9 -8
  298. package/dist/esm/sparkle-goal-progress.entry.js +15 -0
  299. package/dist/esm/sparkle-gww-comment-list.entry.js +1 -1
  300. package/dist/esm/sparkle-gww-graph.entry.js +1 -1
  301. package/dist/esm/sparkle-gww-item.entry.js +70 -0
  302. package/dist/esm/sparkle-intro.entry.js +22 -0
  303. package/dist/esm/sparkle-lower-content-nav.entry.js +1 -1
  304. package/dist/esm/sparkle-menu-collapsible.entry.js +2 -2
  305. package/dist/esm/sparkle-menu-toggle_3.entry.js +230 -0
  306. package/dist/esm/sparkle-modal-image.entry.js +1 -1
  307. package/dist/esm/sparkle-notfound-page.entry.js +1 -1
  308. package/dist/esm/sparkle-overlay.entry.js +1 -1
  309. package/dist/esm/sparkle-poll.entry.js +1 -1
  310. package/dist/esm/sparkle-quiz-container.entry.js +1 -1
  311. package/dist/esm/sparkle-quiz-feedback_5.entry.js +1 -1
  312. package/dist/esm/sparkle-quiz.entry.js +1 -1
  313. package/dist/esm/sparkle-select.entry.js +1 -1
  314. package/dist/esm/sparkle-sidebar.entry.js +1 -1
  315. package/dist/esm/sparkle-tab.entry.js +1 -1
  316. package/dist/esm/sparkle-table-of-contents.entry.js +1 -1
  317. package/dist/esm/sparkle-tabs.entry.js +1 -1
  318. package/dist/esm/sparkle-validation-error.entry.js +17 -0
  319. package/dist/esm/sparkle-youtube.entry.js +1 -1
  320. package/dist/esm/{spinner-configs-f609a655.js → spinner-configs-a37e628a.js} +43 -43
  321. package/dist/esm/{status-tap-6351a0cb.js → status-tap-79b6199d.js} +7 -5
  322. package/dist/esm/stencil-async-content.entry.js +1 -1
  323. package/dist/esm/stencil-route-link.entry.js +73 -0
  324. package/dist/esm/stencil-route-title.entry.js +2 -2
  325. package/dist/esm/stencil-router-prompt.entry.js +2 -2
  326. package/dist/esm/stencil-router-redirect.entry.js +28 -0
  327. package/dist/esm/{student.service-29b688ba.js → student.service-0caed0f4.js} +3 -18
  328. package/dist/esm/{swipe-back-34251834.js → swipe-back-ad7a0361.js} +5 -5
  329. package/dist/esm/{theme-c336c9d9.js → theme-7ef00c83.js} +6 -5
  330. package/dist/esm/user.store-8477642a.js +19 -0
  331. package/dist/esm/{util-6ef753e9.js → util-a831d09d.js} +1 -1
  332. package/dist/node_modules/@ionic/core/dist/collection/components/content/content.css +8 -1
  333. package/dist/node_modules/@ionic/core/dist/collection/components/datetime/datetime.ios.css +46 -22
  334. package/dist/node_modules/@ionic/core/dist/collection/components/datetime/datetime.md.css +43 -19
  335. package/dist/node_modules/@ionic/core/dist/collection/components/datetime-button/datetime-button.css +60 -0
  336. package/dist/node_modules/@ionic/core/dist/collection/components/item/item.ios.css +2 -1
  337. package/dist/node_modules/@ionic/core/dist/collection/components/item/item.md.css +2 -2
  338. package/dist/node_modules/@ionic/core/dist/collection/components/item-option/item-option.ios.css +6 -6
  339. package/dist/node_modules/@ionic/core/dist/collection/components/item-option/item-option.md.css +6 -6
  340. package/dist/node_modules/@ionic/core/dist/collection/components/label/label.ios.css +3 -3
  341. package/dist/node_modules/@ionic/core/dist/collection/components/loading/loading.ios.css +1 -6
  342. package/dist/node_modules/@ionic/core/dist/collection/components/loading/loading.md.css +1 -6
  343. package/dist/node_modules/@ionic/core/dist/collection/components/menu/menu.ios.css +1 -5
  344. package/dist/node_modules/@ionic/core/dist/collection/components/menu/menu.md.css +1 -5
  345. package/dist/node_modules/@ionic/core/dist/collection/components/modal/modal.ios.css +31 -3
  346. package/dist/node_modules/@ionic/core/dist/collection/components/modal/modal.md.css +29 -1
  347. package/dist/node_modules/@ionic/core/dist/collection/components/picker-column-internal/picker-column-internal.ios.css +24 -1
  348. package/dist/node_modules/@ionic/core/dist/collection/components/picker-column-internal/picker-column-internal.md.css +24 -1
  349. package/dist/node_modules/@ionic/core/dist/collection/components/picker-internal/picker-internal.ios.css +4 -0
  350. package/dist/node_modules/@ionic/core/dist/collection/components/picker-internal/picker-internal.md.css +4 -0
  351. package/dist/node_modules/@ionic/core/dist/collection/components/range/range.ios.css +2 -2
  352. package/dist/node_modules/@ionic/core/dist/collection/components/range/range.md.css +2 -2
  353. package/dist/node_modules/@ionic/core/dist/collection/components/spinner/spinner.css +8 -8
  354. package/dist/node_modules/@ionic/core/dist/collection/components/textarea/textarea.ios.css +34 -17
  355. package/dist/node_modules/@ionic/core/dist/collection/components/textarea/textarea.md.css +34 -17
  356. package/dist/node_modules/@ionic/core/dist/collection/components/toggle/toggle.ios.css +50 -1
  357. package/dist/node_modules/@ionic/core/dist/collection/components/toggle/toggle.md.css +27 -0
  358. package/dist/sparkle-core/index.esm.js +1 -1
  359. package/dist/sparkle-core/p-0127a61a.entry.js +1 -0
  360. package/dist/sparkle-core/p-01743e3e.js +4 -0
  361. package/dist/sparkle-core/p-06af1bc8.entry.js +1 -0
  362. package/dist/sparkle-core/{p-703ca87c.js → p-076f0239.js} +0 -0
  363. package/dist/sparkle-core/p-0798d46a.entry.js +1 -0
  364. package/dist/sparkle-core/p-085eb951.entry.js +4 -0
  365. package/dist/sparkle-core/{p-39e5a90f.entry.js → p-0b92326d.entry.js} +1 -1
  366. package/dist/sparkle-core/{p-5ff6416d.entry.js → p-0c603495.entry.js} +2 -2
  367. package/dist/sparkle-core/{p-6bbabb80.entry.js → p-0d7cceaa.entry.js} +1 -1
  368. package/dist/sparkle-core/p-0d813026.entry.js +1 -0
  369. package/dist/sparkle-core/{p-69e7783d.js → p-0e4de1d0.js} +0 -0
  370. package/dist/sparkle-core/p-11ed6b7f.entry.js +1 -0
  371. package/dist/sparkle-core/p-122427b7.entry.js +1 -0
  372. package/dist/sparkle-core/p-12c4f45c.entry.js +1 -0
  373. package/dist/sparkle-core/p-136b93d5.entry.js +4 -0
  374. package/dist/sparkle-core/{p-e225581a.js → p-1394cbb8.js} +2 -2
  375. package/dist/sparkle-core/{p-c48bbc7c.entry.js → p-14340143.entry.js} +1 -1
  376. package/dist/sparkle-core/p-14a06a91.entry.js +1 -0
  377. package/dist/sparkle-core/{p-a9ee3f6d.entry.js → p-16b7974e.entry.js} +1 -1
  378. package/dist/sparkle-core/p-16c81890.entry.js +1 -0
  379. package/dist/sparkle-core/{p-5c9aa1f9.entry.js → p-1701723e.entry.js} +1 -1
  380. package/dist/sparkle-core/p-1728ead7.js +1 -0
  381. package/dist/sparkle-core/p-17aef6f9.js +1 -0
  382. package/dist/sparkle-core/p-180857a2.entry.js +1 -0
  383. package/dist/sparkle-core/p-1acc7870.entry.js +1 -0
  384. package/dist/sparkle-core/{p-513794b0.js → p-1c2aee9c.js} +1 -1
  385. package/dist/sparkle-core/p-1cd4c3cc.entry.js +1 -0
  386. package/dist/sparkle-core/p-21d9833d.js +1 -0
  387. package/dist/sparkle-core/p-23d713e2.js +1 -0
  388. package/dist/sparkle-core/p-25c13612.entry.js +1 -0
  389. package/dist/sparkle-core/p-2699868a.entry.js +1 -0
  390. package/dist/sparkle-core/p-27075abe.js +4 -0
  391. package/dist/sparkle-core/{p-713590fc.js → p-280e938d.js} +1 -1
  392. package/dist/sparkle-core/p-2bd4c60e.js +1 -0
  393. package/dist/sparkle-core/p-2c89a6c2.entry.js +1 -0
  394. package/dist/sparkle-core/p-308517b3.js +4 -0
  395. package/dist/sparkle-core/p-3227afcb.entry.js +1 -0
  396. package/dist/sparkle-core/{p-173d5461.entry.js → p-34d93a39.entry.js} +1 -1
  397. package/dist/sparkle-core/p-34ebfc8a.entry.js +1 -0
  398. package/dist/sparkle-core/p-351b82a8.entry.js +1 -0
  399. package/dist/sparkle-core/p-363a2d6d.js +4 -0
  400. package/dist/sparkle-core/p-36c48760.entry.js +1 -0
  401. package/dist/sparkle-core/p-3810777d.js +4 -0
  402. package/dist/sparkle-core/p-384911d7.entry.js +1 -0
  403. package/dist/sparkle-core/p-3b618eda.entry.js +1 -0
  404. package/dist/sparkle-core/p-3c752205.entry.js +1 -0
  405. package/dist/sparkle-core/{p-50aac721.entry.js → p-3d2c0e24.entry.js} +2 -2
  406. package/dist/sparkle-core/{p-350adbaa.entry.js → p-3eb56165.entry.js} +1 -1
  407. package/dist/sparkle-core/{p-ed0e9d29.entry.js → p-3ef53ebf.entry.js} +1 -1
  408. package/dist/sparkle-core/{p-fbd7eeca.entry.js → p-3fd92216.entry.js} +1 -1
  409. package/dist/sparkle-core/{p-1df05176.js → p-4338e1e3.js} +2 -2
  410. package/dist/sparkle-core/p-442eadcf.entry.js +1 -0
  411. package/dist/sparkle-core/{p-5f45d206.entry.js → p-4af496a8.entry.js} +1 -1
  412. package/dist/sparkle-core/{p-935e7cfc.js → p-4bd4dab2.js} +1 -1
  413. package/dist/sparkle-core/{p-18e62133.entry.js → p-4c9e010d.entry.js} +1 -1
  414. package/dist/sparkle-core/p-4d0dfbc9.js +1 -0
  415. package/dist/sparkle-core/{p-8c6b6038.js → p-4d4077ea.js} +0 -0
  416. package/dist/sparkle-core/p-4e0502b8.entry.js +4 -0
  417. package/dist/sparkle-core/p-506f3c5f.js +4 -0
  418. package/dist/sparkle-core/p-524a6174.entry.js +1 -0
  419. package/dist/sparkle-core/p-53aac9d7.entry.js +1 -0
  420. package/dist/sparkle-core/{p-0580419b.entry.js → p-56700a40.entry.js} +1 -1
  421. package/dist/sparkle-core/p-5722be24.entry.js +1 -0
  422. package/dist/sparkle-core/p-58389020.entry.js +348 -0
  423. package/dist/sparkle-core/{p-11cf398a.entry.js → p-58f74119.entry.js} +1 -1
  424. package/dist/sparkle-core/p-5979f253.entry.js +1 -0
  425. package/dist/sparkle-core/p-5a3de051.entry.js +4 -0
  426. package/dist/sparkle-core/p-5a850731.entry.js +1 -0
  427. package/dist/sparkle-core/{p-950effe7.entry.js → p-5dcf33fb.entry.js} +1 -1
  428. package/dist/sparkle-core/p-5e8fa1ac.entry.js +1 -0
  429. package/dist/sparkle-core/p-5ef50959.js +1 -0
  430. package/dist/sparkle-core/p-615b8f64.entry.js +1 -0
  431. package/dist/sparkle-core/{p-90389886.entry.js → p-63d8a5b7.entry.js} +1 -1
  432. package/dist/sparkle-core/p-6a337ad1.entry.js +1 -0
  433. package/dist/sparkle-core/p-6a5ace01.js +2 -0
  434. package/dist/sparkle-core/{p-d7baf31e.entry.js → p-6ae9c743.entry.js} +1 -1
  435. package/dist/sparkle-core/p-76206f80.entry.js +1 -0
  436. package/dist/sparkle-core/{p-99b43ee1.entry.js → p-767c9db8.entry.js} +1 -1
  437. package/dist/sparkle-core/p-76a6e202.entry.js +1 -0
  438. package/dist/sparkle-core/{p-ee0d7f19.entry.js → p-785f1879.entry.js} +1 -1
  439. package/dist/sparkle-core/p-788735b9.entry.js +1 -0
  440. package/dist/sparkle-core/{p-057f6a23.entry.js → p-7b21bd70.entry.js} +1 -1
  441. package/dist/sparkle-core/p-7b3d1457.js +1 -0
  442. package/dist/sparkle-core/p-7d8427eb.js +4 -0
  443. package/dist/sparkle-core/{p-5264da79.js → p-7e7ce516.js} +0 -0
  444. package/dist/sparkle-core/{p-838fa86d.entry.js → p-8cbe019a.entry.js} +5 -5
  445. package/dist/sparkle-core/{p-9c1772c3.js → p-8d630960.js} +1 -1
  446. package/dist/sparkle-core/{p-7052c43a.entry.js → p-8e42e634.entry.js} +1 -1
  447. package/dist/sparkle-core/p-8e56f9ee.entry.js +1 -0
  448. package/dist/sparkle-core/p-8ed0cefb.entry.js +1 -0
  449. package/dist/sparkle-core/{p-d4c07aca.js → p-924b2917.js} +0 -0
  450. package/dist/sparkle-core/p-9484e34b.entry.js +1 -0
  451. package/dist/sparkle-core/p-966817ec.js +1 -0
  452. package/dist/sparkle-core/p-969e98e5.entry.js +1 -0
  453. package/dist/sparkle-core/p-98f3925b.js +4 -0
  454. package/dist/sparkle-core/{p-a1cab0f3.js → p-99231c00.js} +2 -2
  455. package/dist/sparkle-core/p-9a383065.entry.js +7 -0
  456. package/dist/sparkle-core/p-9b4979b5.entry.js +4 -0
  457. package/dist/sparkle-core/{p-c69b0a7a.entry.js → p-9cd95e7e.entry.js} +1 -1
  458. package/dist/sparkle-core/p-9dc42d70.entry.js +1 -0
  459. package/dist/sparkle-core/p-9eea81f2.js +1 -0
  460. package/dist/sparkle-core/{p-797c23ed.entry.js → p-9ef14088.entry.js} +1 -1
  461. package/dist/sparkle-core/p-a05871e6.js +1 -0
  462. package/dist/sparkle-core/p-a111c567.entry.js +1 -0
  463. package/dist/sparkle-core/{p-1af044f7.js → p-a19b42f0.js} +1 -1
  464. package/dist/sparkle-core/p-a208ab2d.js +4 -0
  465. package/dist/sparkle-core/p-a2f7c751.entry.js +1 -0
  466. package/dist/sparkle-core/p-a458b415.entry.js +1 -0
  467. package/dist/sparkle-core/p-a6c1a55a.entry.js +5 -0
  468. package/dist/sparkle-core/{p-145e40f5.entry.js → p-ab3a8f5e.entry.js} +1 -1
  469. package/dist/sparkle-core/p-ac0e4d8c.entry.js +1 -0
  470. package/dist/sparkle-core/p-add30d46.js +4 -0
  471. package/dist/sparkle-core/{p-5b40aae5.entry.js → p-b00d0a47.entry.js} +1 -1
  472. package/dist/sparkle-core/p-b2827978.entry.js +1 -0
  473. package/dist/sparkle-core/p-b8ba8164.entry.js +1 -0
  474. package/dist/sparkle-core/{p-6823e6c1.entry.js → p-ba775d8e.entry.js} +1 -1
  475. package/dist/sparkle-core/{p-37c00e39.entry.js → p-bae8cd7d.entry.js} +1 -1
  476. package/dist/sparkle-core/p-bb3e3482.entry.js +1 -0
  477. package/dist/sparkle-core/p-bb575dba.entry.js +1 -0
  478. package/dist/sparkle-core/p-bd2c8e30.entry.js +10 -0
  479. package/dist/sparkle-core/p-c48352cf.js +4 -0
  480. package/dist/sparkle-core/{p-667accac.entry.js → p-c5eb4404.entry.js} +1 -1
  481. package/dist/sparkle-core/p-c8ad5a5b.entry.js +4 -0
  482. package/dist/sparkle-core/p-c9f474d0.js +4 -0
  483. package/dist/sparkle-core/p-ca0edc9b.entry.js +1 -0
  484. package/dist/sparkle-core/{p-680663a2.entry.js → p-cb04b18a.entry.js} +1 -1
  485. package/dist/sparkle-core/{p-b3909012.entry.js → p-d0d0e5e5.entry.js} +1 -1
  486. package/dist/sparkle-core/{p-7d61177b.entry.js → p-d220a642.entry.js} +1 -1
  487. package/dist/sparkle-core/p-d38a2511.entry.js +1 -0
  488. package/dist/sparkle-core/{p-b07a2cf2.entry.js → p-d5b8302f.entry.js} +1 -1
  489. package/dist/sparkle-core/p-d5ba8e80.entry.js +1 -0
  490. package/dist/sparkle-core/{p-3a202a38.entry.js → p-d6637b48.entry.js} +1 -1
  491. package/dist/sparkle-core/p-d6788642.entry.js +1 -0
  492. package/dist/sparkle-core/p-d6a3a639.entry.js +1 -0
  493. package/dist/sparkle-core/p-d86f8633.entry.js +1 -0
  494. package/dist/sparkle-core/{p-9cfdeb18.entry.js → p-defeaa5c.entry.js} +1 -1
  495. package/dist/sparkle-core/p-df5cfa7f.entry.js +1 -0
  496. package/dist/sparkle-core/p-df5efe0d.entry.js +1 -0
  497. package/dist/sparkle-core/p-dff8325e.js +4 -0
  498. package/dist/sparkle-core/p-e09de7ac.js +1 -0
  499. package/dist/sparkle-core/{p-016a7aaf.entry.js → p-e1743d82.entry.js} +1 -1
  500. package/dist/sparkle-core/p-e28a106d.entry.js +1 -0
  501. package/dist/sparkle-core/p-e566c0b3.entry.js +1 -0
  502. package/dist/sparkle-core/{p-bca0e465.entry.js → p-e6d39f6e.entry.js} +1 -1
  503. package/dist/sparkle-core/p-e9431eeb.js +7 -0
  504. package/dist/sparkle-core/p-ea4a9f0d.entry.js +1 -0
  505. package/dist/sparkle-core/p-ea7d7a3b.js +1 -0
  506. package/dist/sparkle-core/p-eaa8bbee.js +4 -0
  507. package/dist/sparkle-core/p-ed3dfd89.js +4 -0
  508. package/dist/sparkle-core/{p-3defe550.entry.js → p-efe37368.entry.js} +1 -1
  509. package/dist/sparkle-core/p-f187d129.entry.js +1 -0
  510. package/dist/sparkle-core/{p-a9ccb0df.js → p-f3cba72a.js} +0 -0
  511. package/dist/sparkle-core/{p-052caa63.js → p-f5e7bfa5.js} +1 -1
  512. package/dist/sparkle-core/{p-ecd39170.entry.js → p-f63a13d8.entry.js} +1 -1
  513. package/dist/sparkle-core/{p-1726da2f.entry.js → p-fdb9a613.entry.js} +1 -1
  514. package/dist/sparkle-core/p-fde96f7c.js +4 -0
  515. package/dist/sparkle-core/{p-aa87c7f0.entry.js → p-fe214d79.entry.js} +1 -1
  516. package/dist/sparkle-core/p-fe3a7bca.js +1 -0
  517. package/dist/sparkle-core/{p-aa9ebc39.entry.js → p-fea20ec2.entry.js} +1 -1
  518. package/dist/sparkle-core/p-ff26d891.entry.js +1 -0
  519. package/dist/sparkle-core/sparkle-core.css +1 -1
  520. package/dist/sparkle-core/sparkle-core.esm.js +1 -1
  521. package/dist/types/components/sparkle-feed-post/sparkle-feed-post.d.ts +16 -0
  522. package/dist/types/components/sparkle-intro/sparkle-intro.d.ts +7 -0
  523. package/dist/types/components.d.ts +73 -11
  524. package/package.json +3 -3
  525. package/dist/cjs/ion-card-title.cjs.entry.js +0 -30
  526. package/dist/cjs/ion-textarea.cjs.entry.js +0 -247
  527. package/dist/cjs/ion-toggle.cjs.entry.js +0 -160
  528. package/dist/cjs/sparkle-feed-post.cjs.entry.js +0 -19
  529. package/dist/cjs/student.service-744c3155.js +0 -77
  530. package/dist/esm/ion-card-title.entry.js +0 -26
  531. package/dist/esm/ion-textarea.entry.js +0 -243
  532. package/dist/esm/ion-toggle.entry.js +0 -156
  533. package/dist/esm/sparkle-feed-post.entry.js +0 -15
  534. package/dist/sparkle-core/p-0187adef.entry.js +0 -1
  535. package/dist/sparkle-core/p-03189863.js +0 -1
  536. package/dist/sparkle-core/p-03ec54a8.entry.js +0 -1
  537. package/dist/sparkle-core/p-04583c51.entry.js +0 -1
  538. package/dist/sparkle-core/p-063cd168.js +0 -4
  539. package/dist/sparkle-core/p-081968cc.entry.js +0 -1
  540. package/dist/sparkle-core/p-0934f5dd.entry.js +0 -1
  541. package/dist/sparkle-core/p-0f899097.entry.js +0 -352
  542. package/dist/sparkle-core/p-1339830f.entry.js +0 -1
  543. package/dist/sparkle-core/p-1b78dea1.entry.js +0 -1
  544. package/dist/sparkle-core/p-1cef8572.js +0 -4
  545. package/dist/sparkle-core/p-21bf4ca0.entry.js +0 -1
  546. package/dist/sparkle-core/p-21db4e8e.entry.js +0 -1
  547. package/dist/sparkle-core/p-23a9f7d1.entry.js +0 -1
  548. package/dist/sparkle-core/p-289a35ed.entry.js +0 -1
  549. package/dist/sparkle-core/p-2ee6a5f9.entry.js +0 -1
  550. package/dist/sparkle-core/p-35a7bd6c.entry.js +0 -1
  551. package/dist/sparkle-core/p-389500fd.js +0 -4
  552. package/dist/sparkle-core/p-45e6db62.entry.js +0 -1
  553. package/dist/sparkle-core/p-48f9b960.entry.js +0 -1
  554. package/dist/sparkle-core/p-4dc3ef96.entry.js +0 -1
  555. package/dist/sparkle-core/p-547b70c6.entry.js +0 -1
  556. package/dist/sparkle-core/p-5598650a.entry.js +0 -1
  557. package/dist/sparkle-core/p-55ae49e1.js +0 -4
  558. package/dist/sparkle-core/p-58e98f89.entry.js +0 -1
  559. package/dist/sparkle-core/p-59f7bf6e.entry.js +0 -1
  560. package/dist/sparkle-core/p-5a3d0e6b.js +0 -4
  561. package/dist/sparkle-core/p-5d2e54ee.entry.js +0 -1
  562. package/dist/sparkle-core/p-62a6c96f.entry.js +0 -1
  563. package/dist/sparkle-core/p-64e72f8f.js +0 -4
  564. package/dist/sparkle-core/p-660e0742.js +0 -1
  565. package/dist/sparkle-core/p-6bf07a28.js +0 -1
  566. package/dist/sparkle-core/p-6c6145cd.js +0 -4
  567. package/dist/sparkle-core/p-6c90bde6.entry.js +0 -5
  568. package/dist/sparkle-core/p-6e88764b.entry.js +0 -4
  569. package/dist/sparkle-core/p-6ee40949.js +0 -1
  570. package/dist/sparkle-core/p-6fbe3ca3.entry.js +0 -1
  571. package/dist/sparkle-core/p-6fd4985d.js +0 -4
  572. package/dist/sparkle-core/p-70b2452c.js +0 -4
  573. package/dist/sparkle-core/p-7493ee15.entry.js +0 -1
  574. package/dist/sparkle-core/p-75572037.js +0 -1
  575. package/dist/sparkle-core/p-768bcc9e.entry.js +0 -1
  576. package/dist/sparkle-core/p-7e61973d.entry.js +0 -7
  577. package/dist/sparkle-core/p-855ca600.js +0 -1
  578. package/dist/sparkle-core/p-857f3696.entry.js +0 -1
  579. package/dist/sparkle-core/p-8fe2e51f.entry.js +0 -4
  580. package/dist/sparkle-core/p-932bfb69.entry.js +0 -1
  581. package/dist/sparkle-core/p-941eaa3a.entry.js +0 -1
  582. package/dist/sparkle-core/p-95004267.entry.js +0 -1
  583. package/dist/sparkle-core/p-996361f9.entry.js +0 -1
  584. package/dist/sparkle-core/p-9a17f2ad.js +0 -4
  585. package/dist/sparkle-core/p-9babd345.js +0 -1
  586. package/dist/sparkle-core/p-a080e768.entry.js +0 -1
  587. package/dist/sparkle-core/p-a7cc0052.entry.js +0 -4
  588. package/dist/sparkle-core/p-ae1f145d.entry.js +0 -1
  589. package/dist/sparkle-core/p-b3e6427d.js +0 -7
  590. package/dist/sparkle-core/p-b49ca0ea.entry.js +0 -1
  591. package/dist/sparkle-core/p-b81e20fe.entry.js +0 -4
  592. package/dist/sparkle-core/p-c1279cc9.entry.js +0 -1
  593. package/dist/sparkle-core/p-c1376096.entry.js +0 -1
  594. package/dist/sparkle-core/p-c3986a52.entry.js +0 -1
  595. package/dist/sparkle-core/p-c3d3d5c4.entry.js +0 -1
  596. package/dist/sparkle-core/p-c5b9bdd6.entry.js +0 -1
  597. package/dist/sparkle-core/p-cbbeed67.entry.js +0 -1
  598. package/dist/sparkle-core/p-d4a435f8.entry.js +0 -1
  599. package/dist/sparkle-core/p-d5b05ece.entry.js +0 -5
  600. package/dist/sparkle-core/p-d8d3524a.js +0 -1
  601. package/dist/sparkle-core/p-e0fced48.entry.js +0 -1
  602. package/dist/sparkle-core/p-e1cba44b.entry.js +0 -4
  603. package/dist/sparkle-core/p-e3fdd0a8.entry.js +0 -1
  604. package/dist/sparkle-core/p-e6b66cef.entry.js +0 -1
  605. package/dist/sparkle-core/p-e72d4450.js +0 -4
  606. package/dist/sparkle-core/p-eb70a23c.entry.js +0 -1
  607. package/dist/sparkle-core/p-f4001fdf.js +0 -4
  608. package/dist/sparkle-core/p-f9b73032.entry.js +0 -1
  609. package/dist/sparkle-core/p-faa912d7.entry.js +0 -1
  610. package/dist/sparkle-core/p-fc933591.entry.js +0 -1
  611. package/dist/sparkle-core/p-fef04ab5.js +0 -4
@@ -1,875 +1,12 @@
1
- import { r as registerInstance, i as createEvent, w as writeTask, h, H as Host, e as getElement } from './index-5568e3fa.js';
2
- import { d as chevronBack, c as chevronForward, a as chevronDown, f as caretUpSharp, g as caretDownSharp } from './index-dc61f152.js';
3
- import { g as getIonMode } from './ionic-global-0939c477.js';
4
- import { startFocusVisible } from './focus-visible-40cda868.js';
5
- import { k as raf, d as renderHiddenInput, g as getElementRoot } from './helpers-39367fe1.js';
1
+ import { r as registerInstance, e as createEvent, w as writeTask, h, H as Host, i as getElement } from './index-9db08224.js';
2
+ import { g as chevronBack, c as chevronForward, b as chevronDown, h as caretUpSharp, i as caretDownSharp } from './index-4ec6b9c2.js';
3
+ import { g as getIonMode } from './ionic-global-293e882b.js';
4
+ import { startFocusVisible } from './focus-visible-4e9a0764.js';
5
+ import { j as raf, l as renderHiddenInput, g as getElementRoot } from './helpers-94a5855b.js';
6
+ import { a as printIonWarning, p as printIonError } from './index-dad75b83.js';
6
7
  import { i as isRTL } from './dir-03012648.js';
7
- import { c as createColorClasses } from './theme-c336c9d9.js';
8
-
9
- /*!
10
- * (C) Ionic http://ionicframework.com - MIT License
11
- */
12
- /**
13
- * Returns true if the selected day is equal to the reference day
14
- */
15
- const isSameDay = (baseParts, compareParts) => {
16
- return (baseParts.month === compareParts.month &&
17
- baseParts.day === compareParts.day &&
18
- baseParts.year === compareParts.year);
19
- };
20
- /**
21
- * Returns true is the selected day is before the reference day.
22
- */
23
- const isBefore = (baseParts, compareParts) => {
24
- return (baseParts.year < compareParts.year ||
25
- baseParts.year === compareParts.year && baseParts.month < compareParts.month ||
26
- baseParts.year === compareParts.year && baseParts.month === compareParts.month && baseParts.day < compareParts.day);
27
- };
28
- /**
29
- * Returns true is the selected day is after the reference day.
30
- */
31
- const isAfter = (baseParts, compareParts) => {
32
- return (baseParts.year > compareParts.year ||
33
- baseParts.year === compareParts.year && baseParts.month > compareParts.month ||
34
- baseParts.year === compareParts.year && baseParts.month === compareParts.month && baseParts.day > compareParts.day);
35
- };
36
-
37
- /*!
38
- * (C) Ionic http://ionicframework.com - MIT License
39
- */
40
- /**
41
- * Determines if given year is a
42
- * leap year. Returns `true` if year
43
- * is a leap year. Returns `false`
44
- * otherwise.
45
- */
46
- const isLeapYear = (year) => {
47
- return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);
48
- };
49
- const is24Hour = (locale, hourCycle) => {
50
- /**
51
- * If developer has explicitly enabled h23 time
52
- * then return early and do not look at the system default.
53
- */
54
- if (hourCycle !== undefined) {
55
- return hourCycle === 'h23';
56
- }
57
- /**
58
- * If hourCycle was not specified, check the locale
59
- * that is set on the user's device. We first check the
60
- * Intl.DateTimeFormat hourCycle option as developers can encode this
61
- * option into the locale string. Example: `en-US-u-hc-h23`
62
- */
63
- const formatted = new Intl.DateTimeFormat(locale, { hour: 'numeric' });
64
- const options = formatted.resolvedOptions();
65
- if (options.hourCycle !== undefined) {
66
- return options.hourCycle === 'h23';
67
- }
68
- /**
69
- * If hourCycle is not specified (either through lack
70
- * of browser support or locale information) then fall
71
- * back to this slower hourCycle check.
72
- */
73
- const date = new Date('5/18/2021 00:00');
74
- const parts = formatted.formatToParts(date);
75
- const hour = parts.find(p => p.type === 'hour');
76
- if (!hour) {
77
- throw new Error('Hour value not found from DateTimeFormat');
78
- }
79
- return hour.value === '00';
80
- };
81
- /**
82
- * Given a date object, returns the number
83
- * of days in that month.
84
- * Month value begin at 1, not 0.
85
- * i.e. January = month 1.
86
- */
87
- const getNumDaysInMonth = (month, year) => {
88
- return (month === 4 || month === 6 || month === 9 || month === 11) ? 30 : (month === 2) ? isLeapYear(year) ? 29 : 28 : 31;
89
- };
90
- /**
91
- * Certain locales display month then year while
92
- * others display year then month.
93
- * We can use Intl.DateTimeFormat to determine
94
- * the ordering for each locale.
95
- */
96
- const isMonthFirstLocale = (locale) => {
97
- /**
98
- * By setting month and year we guarantee that only
99
- * month, year, and literal (slashes '/', for example)
100
- * values are included in the formatToParts results.
101
- *
102
- * The ordering of the parts will be determined by
103
- * the locale. So if the month is the first value,
104
- * then we know month should be shown first. If the
105
- * year is the first value, then we know year should be shown first.
106
- *
107
- * This ordering can be controlled by customizing the locale property.
108
- */
109
- const parts = new Intl.DateTimeFormat(locale, { month: 'numeric', year: 'numeric' }).formatToParts(new Date());
110
- return parts[0].type === 'month';
111
- };
112
-
113
- /*!
114
- * (C) Ionic http://ionicframework.com - MIT License
115
- */
116
- const twoDigit = (val) => {
117
- return ('0' + (val !== undefined ? Math.abs(val) : '0')).slice(-2);
118
- };
119
- const fourDigit = (val) => {
120
- return ('000' + (val !== undefined ? Math.abs(val) : '0')).slice(-4);
121
- };
122
- const convertDataToISO = (data) => {
123
- // https://www.w3.org/TR/NOTE-datetime
124
- let rtn = '';
125
- if (data.year !== undefined) {
126
- // YYYY
127
- rtn = fourDigit(data.year);
128
- if (data.month !== undefined) {
129
- // YYYY-MM
130
- rtn += '-' + twoDigit(data.month);
131
- if (data.day !== undefined) {
132
- // YYYY-MM-DD
133
- rtn += '-' + twoDigit(data.day);
134
- if (data.hour !== undefined) {
135
- // YYYY-MM-DDTHH:mm:SS
136
- rtn += `T${twoDigit(data.hour)}:${twoDigit(data.minute)}:00`;
137
- if (data.tzOffset === undefined) {
138
- // YYYY-MM-DDTHH:mm:SSZ
139
- rtn += 'Z';
140
- }
141
- else {
142
- // YYYY-MM-DDTHH:mm:SS+/-HH:mm
143
- rtn += (data.tzOffset > 0 ? '+' : '-') + twoDigit(Math.floor(Math.abs(data.tzOffset / 60))) + ':' + twoDigit(data.tzOffset % 60);
144
- }
145
- }
146
- }
147
- }
148
- }
149
- else if (data.hour !== undefined) {
150
- // HH:mm
151
- rtn = twoDigit(data.hour) + ':' + twoDigit(data.minute);
152
- }
153
- return rtn;
154
- };
155
- /**
156
- * Converts an 12 hour value to 24 hours.
157
- */
158
- const convert12HourTo24Hour = (hour, ampm) => {
159
- if (ampm === undefined) {
160
- return hour;
161
- }
162
- /**
163
- * If AM and 12am
164
- * then return 00:00.
165
- * Otherwise just return
166
- * the hour since it is
167
- * already in 24 hour format.
168
- */
169
- if (ampm === 'am') {
170
- if (hour === 12) {
171
- return 0;
172
- }
173
- return hour;
174
- }
175
- /**
176
- * If PM and 12pm
177
- * just return 12:00
178
- * since it is already
179
- * in 24 hour format.
180
- * Otherwise add 12 hours
181
- * to the time.
182
- */
183
- if (hour === 12) {
184
- return 12;
185
- }
186
- return hour + 12;
187
- };
188
- const getStartOfWeek = (refParts) => {
189
- const { dayOfWeek } = refParts;
190
- if (dayOfWeek === null || dayOfWeek === undefined) {
191
- throw new Error('No day of week provided');
192
- }
193
- return subtractDays(refParts, dayOfWeek);
194
- };
195
- const getEndOfWeek = (refParts) => {
196
- const { dayOfWeek } = refParts;
197
- if (dayOfWeek === null || dayOfWeek === undefined) {
198
- throw new Error('No day of week provided');
199
- }
200
- return addDays(refParts, 6 - dayOfWeek);
201
- };
202
- const getNextDay = (refParts) => {
203
- return addDays(refParts, 1);
204
- };
205
- const getPreviousDay = (refParts) => {
206
- return subtractDays(refParts, 1);
207
- };
208
- const getPreviousWeek = (refParts) => {
209
- return subtractDays(refParts, 7);
210
- };
211
- const getNextWeek = (refParts) => {
212
- return addDays(refParts, 7);
213
- };
214
- /**
215
- * Given datetime parts, subtract
216
- * numDays from the date.
217
- * Returns a new DatetimeParts object
218
- * Currently can only go backward at most 1 month.
219
- */
220
- const subtractDays = (refParts, numDays) => {
221
- const { month, day, year } = refParts;
222
- if (day === null) {
223
- throw new Error('No day provided');
224
- }
225
- const workingParts = {
226
- month,
227
- day,
228
- year
229
- };
230
- workingParts.day = day - numDays;
231
- /**
232
- * If wrapping to previous month
233
- * update days and decrement month
234
- */
235
- if (workingParts.day < 1) {
236
- workingParts.month -= 1;
237
- }
238
- /**
239
- * If moving to previous year, reset
240
- * month to December and decrement year
241
- */
242
- if (workingParts.month < 1) {
243
- workingParts.month = 12;
244
- workingParts.year -= 1;
245
- }
246
- /**
247
- * Determine how many days are in the current
248
- * month
249
- */
250
- if (workingParts.day < 1) {
251
- const daysInMonth = getNumDaysInMonth(workingParts.month, workingParts.year);
252
- /**
253
- * Take num days in month and add the
254
- * number of underflow days. This number will
255
- * be negative.
256
- * Example: 1 week before Jan 2, 2021 is
257
- * December 26, 2021 so:
258
- * 2 - 7 = -5
259
- * 31 + (-5) = 26
260
- */
261
- workingParts.day = daysInMonth + workingParts.day;
262
- }
263
- return workingParts;
264
- };
265
- /**
266
- * Given datetime parts, add
267
- * numDays to the date.
268
- * Returns a new DatetimeParts object
269
- * Currently can only go forward at most 1 month.
270
- */
271
- const addDays = (refParts, numDays) => {
272
- const { month, day, year } = refParts;
273
- if (day === null) {
274
- throw new Error('No day provided');
275
- }
276
- const workingParts = {
277
- month,
278
- day,
279
- year
280
- };
281
- const daysInMonth = getNumDaysInMonth(month, year);
282
- workingParts.day = day + numDays;
283
- /**
284
- * If wrapping to next month
285
- * update days and increment month
286
- */
287
- if (workingParts.day > daysInMonth) {
288
- workingParts.day -= daysInMonth;
289
- workingParts.month += 1;
290
- }
291
- /**
292
- * If moving to next year, reset
293
- * month to January and increment year
294
- */
295
- if (workingParts.month > 12) {
296
- workingParts.month = 1;
297
- workingParts.year += 1;
298
- }
299
- return workingParts;
300
- };
301
- /**
302
- * Given DatetimeParts, generate the previous month.
303
- */
304
- const getPreviousMonth = (refParts) => {
305
- /**
306
- * If current month is January, wrap backwards
307
- * to December of the previous year.
308
- */
309
- const month = (refParts.month === 1) ? 12 : refParts.month - 1;
310
- const year = (refParts.month === 1) ? refParts.year - 1 : refParts.year;
311
- const numDaysInMonth = getNumDaysInMonth(month, year);
312
- const day = (numDaysInMonth < refParts.day) ? numDaysInMonth : refParts.day;
313
- return { month, year, day };
314
- };
315
- /**
316
- * Given DatetimeParts, generate the next month.
317
- */
318
- const getNextMonth = (refParts) => {
319
- /**
320
- * If current month is December, wrap forwards
321
- * to January of the next year.
322
- */
323
- const month = (refParts.month === 12) ? 1 : refParts.month + 1;
324
- const year = (refParts.month === 12) ? refParts.year + 1 : refParts.year;
325
- const numDaysInMonth = getNumDaysInMonth(month, year);
326
- const day = (numDaysInMonth < refParts.day) ? numDaysInMonth : refParts.day;
327
- return { month, year, day };
328
- };
329
- const changeYear = (refParts, yearDelta) => {
330
- const month = refParts.month;
331
- const year = refParts.year + yearDelta;
332
- const numDaysInMonth = getNumDaysInMonth(month, year);
333
- const day = (numDaysInMonth < refParts.day) ? numDaysInMonth : refParts.day;
334
- return { month, year, day };
335
- };
336
- /**
337
- * Given DatetimeParts, generate the previous year.
338
- */
339
- const getPreviousYear = (refParts) => {
340
- return changeYear(refParts, -1);
341
- };
342
- /**
343
- * Given DatetimeParts, generate the next year.
344
- */
345
- const getNextYear = (refParts) => {
346
- return changeYear(refParts, 1);
347
- };
348
- /**
349
- * If PM, then internal value should
350
- * be converted to 24-hr time.
351
- * Does not apply when public
352
- * values are already 24-hr time.
353
- */
354
- const getInternalHourValue = (hour, use24Hour, ampm) => {
355
- if (use24Hour) {
356
- return hour;
357
- }
358
- return convert12HourTo24Hour(hour, ampm);
359
- };
360
- /**
361
- * Unless otherwise stated, all month values are
362
- * 1 indexed instead of the typical 0 index in JS Date.
363
- * Example:
364
- * January = Month 0 when using JS Date
365
- * January = Month 1 when using this datetime util
366
- */
367
- /**
368
- * Given the current datetime parts and a new AM/PM value
369
- * calculate what the hour should be in 24-hour time format.
370
- * Used when toggling the AM/PM segment since we store our hours
371
- * in 24-hour time format internally.
372
- */
373
- const calculateHourFromAMPM = (currentParts, newAMPM) => {
374
- const { ampm: currentAMPM, hour } = currentParts;
375
- let newHour = hour;
376
- /**
377
- * If going from AM --> PM, need to update the
378
- *
379
- */
380
- if (currentAMPM === 'am' && newAMPM === 'pm') {
381
- newHour = convert12HourTo24Hour(newHour, 'pm');
382
- /**
383
- * If going from PM --> AM
384
- */
385
- }
386
- else if (currentAMPM === 'pm' && newAMPM === 'am') {
387
- newHour = Math.abs(newHour - 12);
388
- }
389
- return newHour;
390
- };
391
-
392
- /*!
393
- * (C) Ionic http://ionicframework.com - MIT License
394
- */
395
- /**
396
- * Returns the current date as
397
- * an ISO string in the user's
398
- * timezone.
399
- */
400
- const getToday = () => {
401
- /**
402
- * Grab the current date object
403
- * as well as the timezone offset
404
- */
405
- const date = new Date();
406
- const tzOffset = date.getTimezoneOffset();
407
- /**
408
- * When converting to ISO string, everything is
409
- * set to UTC. Since we want to show these dates
410
- * relative to the user's timezone, we need to
411
- * subtract the timezone offset from the date
412
- * so that when `toISOString()` adds it back
413
- * there was a net change of zero hours from the
414
- * local date.
415
- */
416
- date.setHours(date.getHours() - (tzOffset / 60));
417
- return date.toISOString();
418
- };
419
- const minutes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59];
420
- const hour12 = [12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
421
- const hour23 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23];
422
- /**
423
- * Given a locale and a mode,
424
- * return an array with formatted days
425
- * of the week. iOS should display days
426
- * such as "Mon" or "Tue".
427
- * MD should display days such as "M"
428
- * or "T".
429
- */
430
- const getDaysOfWeek = (locale, mode, firstDayOfWeek = 0) => {
431
- /**
432
- * Nov 1st, 2020 starts on a Sunday.
433
- * ion-datetime assumes weeks start on Sunday,
434
- * but is configurable via `firstDayOfWeek`.
435
- */
436
- const weekdayFormat = mode === 'ios' ? 'short' : 'narrow';
437
- const intl = new Intl.DateTimeFormat(locale, { weekday: weekdayFormat });
438
- const startDate = new Date('11/01/2020');
439
- const daysOfWeek = [];
440
- /**
441
- * For each day of the week,
442
- * get the day name.
443
- */
444
- for (let i = firstDayOfWeek; i < firstDayOfWeek + 7; i++) {
445
- const currentDate = new Date(startDate);
446
- currentDate.setDate(currentDate.getDate() + i);
447
- daysOfWeek.push(intl.format(currentDate));
448
- }
449
- return daysOfWeek;
450
- };
451
- /**
452
- * Returns an array containing all of the
453
- * days in a month for a given year. Values are
454
- * aligned with a week calendar starting on
455
- * the firstDayOfWeek value (Sunday by default)
456
- * using null values.
457
- */
458
- const getDaysOfMonth = (month, year, firstDayOfWeek) => {
459
- const numDays = getNumDaysInMonth(month, year);
460
- const firstOfMonth = new Date(`${month}/1/${year}`).getDay();
461
- /**
462
- * To get the first day of the month aligned on the correct
463
- * day of the week, we need to determine how many "filler" days
464
- * to generate. These filler days as empty/disabled buttons
465
- * that fill the space of the days of the week before the first
466
- * of the month.
467
- *
468
- * There are two cases here:
469
- *
470
- * 1. If firstOfMonth = 4, firstDayOfWeek = 0 then the offset
471
- * is (4 - (0 + 1)) = 3. Since the offset loop goes from 0 to 3 inclusive,
472
- * this will generate 4 filler days (0, 1, 2, 3), and then day of week 4 will have
473
- * the first day of the month.
474
- *
475
- * 2. If firstOfMonth = 2, firstDayOfWeek = 4 then the offset
476
- * is (6 - (4 - 2)) = 4. Since the offset loop goes from 0 to 4 inclusive,
477
- * this will generate 5 filler days (0, 1, 2, 3, 4), and then day of week 5 will have
478
- * the first day of the month.
479
- */
480
- const offset = firstOfMonth >= firstDayOfWeek ? firstOfMonth - (firstDayOfWeek + 1) : 6 - (firstDayOfWeek - firstOfMonth);
481
- let days = [];
482
- for (let i = 1; i <= numDays; i++) {
483
- days.push({ day: i, dayOfWeek: (offset + i) % 7 });
484
- }
485
- for (let i = 0; i <= offset; i++) {
486
- days = [
487
- { day: null, dayOfWeek: null },
488
- ...days
489
- ];
490
- }
491
- return days;
492
- };
493
- /**
494
- * Given a local, reference datetime parts and option
495
- * max/min bound datetime parts, calculate the acceptable
496
- * hour and minute values according to the bounds and locale.
497
- */
498
- const generateTime = (refParts, hourCycle = 'h12', minParts, maxParts, hourValues, minuteValues) => {
499
- const use24Hour = hourCycle === 'h23';
500
- let processedHours = use24Hour ? hour23 : hour12;
501
- let processedMinutes = minutes;
502
- let isAMAllowed = true;
503
- let isPMAllowed = true;
504
- if (hourValues) {
505
- processedHours = processedHours.filter(hour => hourValues.includes(hour));
506
- }
507
- if (minuteValues) {
508
- processedMinutes = processedMinutes.filter(minute => minuteValues.includes(minute));
509
- }
510
- if (minParts) {
511
- /**
512
- * If ref day is the same as the
513
- * minimum allowed day, filter hour/minute
514
- * values according to min hour and minute.
515
- */
516
- if (isSameDay(refParts, minParts)) {
517
- /**
518
- * Users may not always set the hour/minute for
519
- * min value (i.e. 2021-06-02) so we should allow
520
- * all hours/minutes in that case.
521
- */
522
- if (minParts.hour !== undefined) {
523
- processedHours = processedHours.filter(hour => {
524
- const convertedHour = refParts.ampm === 'pm' ? (hour + 12) % 24 : hour;
525
- return (use24Hour ? hour : convertedHour) >= minParts.hour;
526
- });
527
- isAMAllowed = minParts.hour < 13;
528
- }
529
- if (minParts.minute !== undefined) {
530
- /**
531
- * The minimum minute range should not be enforced when
532
- * the hour is greater than the min hour.
533
- *
534
- * For example with a minimum range of 09:30, users
535
- * should be able to select 10:00-10:29 and beyond.
536
- */
537
- let isPastMinHour = false;
538
- if (minParts.hour !== undefined && refParts.hour !== undefined) {
539
- if (refParts.hour > minParts.hour) {
540
- isPastMinHour = true;
541
- }
542
- }
543
- processedMinutes = processedMinutes.filter(minute => {
544
- if (isPastMinHour) {
545
- return true;
546
- }
547
- return minute >= minParts.minute;
548
- });
549
- }
550
- /**
551
- * If ref day is before minimum
552
- * day do not render any hours/minute values
553
- */
554
- }
555
- else if (isBefore(refParts, minParts)) {
556
- processedHours = [];
557
- processedMinutes = [];
558
- isAMAllowed = isPMAllowed = false;
559
- }
560
- }
561
- if (maxParts) {
562
- /**
563
- * If ref day is the same as the
564
- * maximum allowed day, filter hour/minute
565
- * values according to max hour and minute.
566
- */
567
- if (isSameDay(refParts, maxParts)) {
568
- /**
569
- * Users may not always set the hour/minute for
570
- * max value (i.e. 2021-06-02) so we should allow
571
- * all hours/minutes in that case.
572
- */
573
- if (maxParts.hour !== undefined) {
574
- processedHours = processedHours.filter(hour => {
575
- const convertedHour = refParts.ampm === 'pm' ? (hour + 12) % 24 : hour;
576
- return (use24Hour ? hour : convertedHour) <= maxParts.hour;
577
- });
578
- isPMAllowed = maxParts.hour >= 13;
579
- }
580
- if (maxParts.minute !== undefined && refParts.hour === maxParts.hour) {
581
- // The available minutes should only be filtered when the hour is the same as the max hour.
582
- // For example if the max hour is 10:30 and the current hour is 10:00,
583
- // users should be able to select 00-30 minutes.
584
- // If the current hour is 09:00, users should be able to select 00-60 minutes.
585
- processedMinutes = processedMinutes.filter(minute => minute <= maxParts.minute);
586
- }
587
- /**
588
- * If ref day is after minimum
589
- * day do not render any hours/minute values
590
- */
591
- }
592
- else if (isAfter(refParts, maxParts)) {
593
- processedHours = [];
594
- processedMinutes = [];
595
- isAMAllowed = isPMAllowed = false;
596
- }
597
- }
598
- return {
599
- hours: processedHours,
600
- minutes: processedMinutes,
601
- am: isAMAllowed,
602
- pm: isPMAllowed
603
- };
604
- };
605
- /**
606
- * Given DatetimeParts, generate the previous,
607
- * current, and and next months.
608
- */
609
- const generateMonths = (refParts) => {
610
- return [
611
- getPreviousMonth(refParts),
612
- { month: refParts.month, year: refParts.year, day: refParts.day },
613
- getNextMonth(refParts)
614
- ];
615
- };
616
- const getPickerMonths = (locale, refParts, minParts, maxParts, monthValues) => {
617
- const { year } = refParts;
618
- const months = [];
619
- if (monthValues !== undefined) {
620
- let processedMonths = monthValues;
621
- if ((maxParts === null || maxParts === void 0 ? void 0 : maxParts.month) !== undefined) {
622
- processedMonths = processedMonths.filter(month => month <= maxParts.month);
623
- }
624
- if ((minParts === null || minParts === void 0 ? void 0 : minParts.month) !== undefined) {
625
- processedMonths = processedMonths.filter(month => month >= minParts.month);
626
- }
627
- processedMonths.forEach(processedMonth => {
628
- const date = new Date(`${processedMonth}/1/${year} GMT+0000`);
629
- const monthString = new Intl.DateTimeFormat(locale, { month: 'long', timeZone: 'UTC' }).format(date);
630
- months.push({ text: monthString, value: processedMonth });
631
- });
632
- }
633
- else {
634
- const maxMonth = maxParts && maxParts.year === year ? maxParts.month : 12;
635
- const minMonth = minParts && minParts.year === year ? minParts.month : 1;
636
- for (let i = minMonth; i <= maxMonth; i++) {
637
- /**
638
- *
639
- * There is a bug on iOS 14 where
640
- * Intl.DateTimeFormat takes into account
641
- * the local timezone offset when formatting dates.
642
- *
643
- * Forcing the timezone to 'UTC' fixes the issue. However,
644
- * we should keep this workaround as it is safer. In the event
645
- * this breaks in another browser, we will not be impacted
646
- * because all dates will be interpreted in UTC.
647
- *
648
- * Example:
649
- * new Intl.DateTimeFormat('en-US', { month: 'long' }).format(new Date('Sat Apr 01 2006 00:00:00 GMT-0400 (EDT)')) // "March"
650
- * new Intl.DateTimeFormat('en-US', { month: 'long', timeZone: 'UTC' }).format(new Date('Sat Apr 01 2006 00:00:00 GMT-0400 (EDT)')) // "April"
651
- *
652
- * In certain timezones, iOS 14 shows the wrong
653
- * date for .toUTCString(). To combat this, we
654
- * force all of the timezones to GMT+0000 (UTC).
655
- *
656
- * Example:
657
- * Time Zone: Central European Standard Time
658
- * new Date('1/1/1992').toUTCString() // "Tue, 31 Dec 1991 23:00:00 GMT"
659
- * new Date('1/1/1992 GMT+0000').toUTCString() // "Wed, 01 Jan 1992 00:00:00 GMT"
660
- */
661
- const date = new Date(`${i}/1/${year} GMT+0000`);
662
- const monthString = new Intl.DateTimeFormat(locale, { month: 'long', timeZone: 'UTC' }).format(date);
663
- months.push({ text: monthString, value: i });
664
- }
665
- }
666
- return months;
667
- };
668
- const getCalendarYears = (refParts, minParts, maxParts, yearValues) => {
669
- if (yearValues !== undefined) {
670
- let processedYears = yearValues;
671
- if ((maxParts === null || maxParts === void 0 ? void 0 : maxParts.year) !== undefined) {
672
- processedYears = processedYears.filter(year => year <= maxParts.year);
673
- }
674
- if ((minParts === null || minParts === void 0 ? void 0 : minParts.year) !== undefined) {
675
- processedYears = processedYears.filter(year => year >= minParts.year);
676
- }
677
- return processedYears;
678
- }
679
- else {
680
- const { year } = refParts;
681
- const maxYear = ((maxParts === null || maxParts === void 0 ? void 0 : maxParts.year) || year);
682
- const minYear = ((minParts === null || minParts === void 0 ? void 0 : minParts.year) || year - 100);
683
- const years = [];
684
- for (let i = maxYear; i >= minYear; i--) {
685
- years.push(i);
686
- }
687
- return years;
688
- }
689
- };
690
-
691
- /*!
692
- * (C) Ionic http://ionicframework.com - MIT License
693
- */
694
- const get12HourTime = (hour) => {
695
- return hour % 12 || 12;
696
- };
697
- const getFormattedAMPM = (ampm) => {
698
- if (ampm === undefined) {
699
- return '';
700
- }
701
- return ampm.toUpperCase();
702
- };
703
- const getFormattedTime = (refParts, use24Hour) => {
704
- if (refParts.hour === undefined || refParts.minute === undefined) {
705
- return 'Invalid Time';
706
- }
707
- const hour = use24Hour ? getFormattedHour(refParts.hour, use24Hour) : get12HourTime(refParts.hour);
708
- const minute = addTimePadding(refParts.minute);
709
- if (use24Hour) {
710
- return `${hour}:${minute}`;
711
- }
712
- return `${hour}:${minute} ${getFormattedAMPM(refParts.ampm)}`;
713
- };
714
- /**
715
- * Adds padding to a time value so
716
- * that it is always 2 digits.
717
- */
718
- const addTimePadding = (value) => {
719
- const valueToString = value.toString();
720
- if (valueToString.length > 1) {
721
- return valueToString;
722
- }
723
- return `0${valueToString}`;
724
- };
725
- /**
726
- * Formats the hour value so that it
727
- * is always 2 digits. Only applies
728
- * if using 12 hour format.
729
- */
730
- const getFormattedHour = (hour, use24Hour) => {
731
- if (!use24Hour) {
732
- return hour.toString();
733
- }
734
- return addTimePadding(hour);
735
- };
736
- /**
737
- * Generates an aria-label to be read by screen readers
738
- * given a local, a date, and whether or not that date is
739
- * today's date.
740
- */
741
- const generateDayAriaLabel = (locale, today, refParts) => {
742
- if (refParts.day === null) {
743
- return null;
744
- }
745
- /**
746
- * MM/DD/YYYY will return midnight in the user's timezone.
747
- */
748
- const date = new Date(`${refParts.month}/${refParts.day}/${refParts.year} GMT+0000`);
749
- const labelString = new Intl.DateTimeFormat(locale, { weekday: 'long', month: 'long', day: 'numeric', timeZone: 'UTC' }).format(date);
750
- /**
751
- * If date is today, prepend "Today" so screen readers indicate
752
- * that the date is today.
753
- */
754
- return (today) ? `Today, ${labelString}` : labelString;
755
- };
756
- /**
757
- * Gets the day of the week, month, and day
758
- * Used for the header in MD mode.
759
- */
760
- const getMonthAndDay = (locale, refParts) => {
761
- const date = new Date(`${refParts.month}/${refParts.day}/${refParts.year} GMT+0000`);
762
- return new Intl.DateTimeFormat(locale, { weekday: 'short', month: 'short', day: 'numeric', timeZone: 'UTC' }).format(date);
763
- };
764
- /**
765
- * Given a locale and a date object,
766
- * return a formatted string that includes
767
- * the month name and full year.
768
- * Example: May 2021
769
- */
770
- const getMonthAndYear = (locale, refParts) => {
771
- const date = new Date(`${refParts.month}/${refParts.day}/${refParts.year} GMT+0000`);
772
- return new Intl.DateTimeFormat(locale, { month: 'long', year: 'numeric', timeZone: 'UTC' }).format(date);
773
- };
774
-
775
- /*!
776
- * (C) Ionic http://ionicframework.com - MIT License
777
- */
778
- const ISO_8601_REGEXP = /^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/;
779
- const TIME_REGEXP = /^((\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/;
780
- /**
781
- * Use to convert a string of comma separated numbers or
782
- * an array of numbers, and clean up any user input
783
- */
784
- const convertToArrayOfNumbers = (input) => {
785
- if (input === undefined) {
786
- return;
787
- }
788
- let processedInput = input;
789
- if (typeof input === 'string') {
790
- // convert the string to an array of strings
791
- // auto remove any whitespace and [] characters
792
- processedInput = input.replace(/\[|\]|\s/g, '').split(',');
793
- }
794
- let values;
795
- if (Array.isArray(processedInput)) {
796
- // ensure each value is an actual number in the returned array
797
- values = processedInput
798
- .map((num) => parseInt(num, 10))
799
- .filter(isFinite);
800
- }
801
- else {
802
- values = [processedInput];
803
- }
804
- return values;
805
- };
806
- /**
807
- * Extracts date information
808
- * from a .calendar-day element
809
- * into DatetimeParts.
810
- */
811
- const getPartsFromCalendarDay = (el) => {
812
- return {
813
- month: parseInt(el.getAttribute('data-month'), 10),
814
- day: parseInt(el.getAttribute('data-day'), 10),
815
- year: parseInt(el.getAttribute('data-year'), 10),
816
- dayOfWeek: parseInt(el.getAttribute('data-day-of-week'), 10)
817
- };
818
- };
819
- /**
820
- * Given an ISO-8601 string, format out the parts
821
- * We do not use the JS Date object here because
822
- * it adjusts the date for the current timezone.
823
- */
824
- const parseDate = (val) => {
825
- // manually parse IS0 cuz Date.parse cannot be trusted
826
- // ISO 8601 format: 1994-12-15T13:47:20Z
827
- let parse = null;
828
- if (val != null && val !== '') {
829
- // try parsing for just time first, HH:MM
830
- parse = TIME_REGEXP.exec(val);
831
- if (parse) {
832
- // adjust the array so it fits nicely with the datetime parse
833
- parse.unshift(undefined, undefined);
834
- parse[2] = parse[3] = undefined;
835
- }
836
- else {
837
- // try parsing for full ISO datetime
838
- parse = ISO_8601_REGEXP.exec(val);
839
- }
840
- }
841
- if (parse === null) {
842
- // wasn't able to parse the ISO datetime
843
- return undefined;
844
- }
845
- // ensure all the parse values exist with at least 0
846
- for (let i = 1; i < 8; i++) {
847
- parse[i] = parse[i] !== undefined ? parseInt(parse[i], 10) : undefined;
848
- }
849
- let tzOffset = 0;
850
- if (parse[9] && parse[10]) {
851
- // hours
852
- tzOffset = parseInt(parse[10], 10) * 60;
853
- if (parse[11]) {
854
- // minutes
855
- tzOffset += parseInt(parse[11], 10);
856
- }
857
- if (parse[9] === '-') {
858
- // + or -
859
- tzOffset *= -1;
860
- }
861
- }
862
- return {
863
- year: parse[1],
864
- month: parse[2],
865
- day: parse[3],
866
- hour: parse[4],
867
- minute: parse[5],
868
- second: parse[6],
869
- millisecond: parse[7],
870
- tzOffset,
871
- };
872
- };
8
+ import { c as createColorClasses } from './theme-7ef00c83.js';
9
+ import { g as generateDayAriaLabel, i as isBefore, a as isAfter, b as isSameDay, c as getPreviousMonth, d as getNextMonth, p as parseDate, e as getToday, f as getPartsFromCalendarDay, h as getEndOfWeek, j as getStartOfWeek, k as getPreviousDay, l as getNextDay, m as getPreviousWeek, n as getNextWeek, w as warnIfValueOutOfBounds, o as convertToArrayOfNumbers, q as convertDataToISO, r as getCombinedDateColumnData, s as getMonthColumnData, t as getDayColumnData, u as getYearColumnData, v as isMonthFirstLocale, x as getTimeColumnsData, y as isLocaleDayPeriodRTL, z as getDaysOfWeek, A as getMonthAndYear, B as getDaysOfMonth, C as generateMonths, D as is24Hour, E as getLocalizedTime, F as getMonthAndDay, G as formatValue, H as getNextYear, I as getPreviousYear, J as clampDate, K as parseAmPm, L as calculateHourFromAMPM } from './parse-1ae3a9bb.js';
873
10
 
874
11
  /*!
875
12
  * (C) Ionic http://ionicframework.com - MIT License
@@ -940,33 +77,49 @@ const isDayDisabled = (refParts, minParts, maxParts, dayValues) => {
940
77
  return false;
941
78
  };
942
79
  /**
943
- * Given a locale, a date, the selected date, and today's date,
80
+ * Given a locale, a date, the selected date(s), and today's date,
944
81
  * generate the state for a given calendar day button.
945
82
  */
946
83
  const getCalendarDayState = (locale, refParts, activeParts, todayParts, minParts, maxParts, dayValues) => {
947
- const isActive = isSameDay(refParts, activeParts);
84
+ /**
85
+ * activeParts signals what day(s) are currently selected in the datetime.
86
+ * If multiple="true", this will be an array, but the logic in this util
87
+ * is the same whether we have one selected day or many because we're only
88
+ * calculating the state for one button. So, we treat a single activeParts value
89
+ * the same as an array of length one.
90
+ */
91
+ const activePartsArray = Array.isArray(activeParts) ? activeParts : [activeParts];
92
+ /**
93
+ * The day button is active if it is selected, or in other words, if refParts
94
+ * matches at least one selected date.
95
+ */
96
+ const isActive = activePartsArray.find((parts) => isSameDay(refParts, parts)) !== undefined;
948
97
  const isToday = isSameDay(refParts, todayParts);
949
98
  const disabled = isDayDisabled(refParts, minParts, maxParts, dayValues);
99
+ /**
100
+ * Note that we always return one object regardless of whether activeParts
101
+ * was an array, since we pare down to one value for isActive.
102
+ */
950
103
  return {
951
104
  disabled,
952
105
  isActive,
953
106
  isToday,
954
107
  ariaSelected: isActive ? 'true' : null,
955
- ariaLabel: generateDayAriaLabel(locale, isToday, refParts)
108
+ ariaLabel: generateDayAriaLabel(locale, isToday, refParts),
956
109
  };
957
110
  };
958
111
  /**
959
112
  * Returns `true` if the month is disabled given the
960
113
  * current date value and min/max date constraints.
961
114
  */
962
- const isMonthDisabled = (refParts, { minParts, maxParts }) => {
115
+ const isMonthDisabled = (refParts, { minParts, maxParts, }) => {
963
116
  // If the year is disabled then the month is disabled.
964
117
  if (isYearDisabled(refParts.year, minParts, maxParts)) {
965
118
  return true;
966
119
  }
967
120
  // If the date value is before the min date, then the month is disabled.
968
121
  // If the date value is after the max date, then the month is disabled.
969
- if (minParts && isBefore(refParts, minParts) || maxParts && isAfter(refParts, maxParts)) {
122
+ if ((minParts && isBefore(refParts, minParts)) || (maxParts && isAfter(refParts, maxParts))) {
970
123
  return true;
971
124
  }
972
125
  return false;
@@ -977,10 +130,10 @@ const isMonthDisabled = (refParts, { minParts, maxParts }) => {
977
130
  * previous navigation button is disabled.
978
131
  */
979
132
  const isPrevMonthDisabled = (refParts, minParts, maxParts) => {
980
- const prevMonth = getPreviousMonth(refParts);
133
+ const prevMonth = Object.assign(Object.assign({}, getPreviousMonth(refParts)), { day: null });
981
134
  return isMonthDisabled(prevMonth, {
982
135
  minParts,
983
- maxParts
136
+ maxParts,
984
137
  });
985
138
  };
986
139
  /**
@@ -988,15 +141,15 @@ const isPrevMonthDisabled = (refParts, minParts, maxParts) => {
988
141
  * determine if the next navigation button is disabled.
989
142
  */
990
143
  const isNextMonthDisabled = (refParts, maxParts) => {
991
- const nextMonth = getNextMonth(refParts);
144
+ const nextMonth = Object.assign(Object.assign({}, getNextMonth(refParts)), { day: null });
992
145
  return isMonthDisabled(nextMonth, {
993
- maxParts
146
+ maxParts,
994
147
  });
995
148
  };
996
149
 
997
- const datetimeIosCss = ":host{display:flex;flex-flow:column;background:var(--background);overflow:hidden}:host(.datetime-size-fixed){width:auto;max-width:350px;height:auto}:host(.datetime-size-cover){width:100%}:host .calendar-body,:host .datetime-year{opacity:0}:host(:not(.datetime-ready)) .datetime-year{position:absolute;pointer-events:none}:host(.datetime-ready) .calendar-body{opacity:1}:host(.datetime-ready) .datetime-year{display:none;opacity:1}:host .datetime-year .order-month-first .month-column{order:1}:host .datetime-year .order-month-first .year-column{order:2}:host .datetime-year .order-year-first .month-column{order:2;text-align:end}:host .datetime-year .order-year-first .year-column{order:1;text-align:start}:host .datetime-calendar,:host .datetime-year{display:flex;flex:1 1 auto;flex-flow:column}:host(.show-month-and-year) .datetime-year{display:flex}@supports (background: -webkit-named-image(apple-pay-logo-black)) and (not (aspect-ratio: 1/1)){:host(.show-month-and-year) .calendar-next-prev,:host(.show-month-and-year) .calendar-days-of-week,:host(.show-month-and-year) .calendar-body,:host(.show-month-and-year) .datetime-time{left:-99999px;position:absolute;visibility:hidden;pointer-events:none}:host-context([dir=rtl]):host(.show-month-and-year) .calendar-next-prev,:host-context([dir=rtl]).show-month-and-year .calendar-next-prev,:host-context([dir=rtl]):host(.show-month-and-year) .calendar-days-of-week,:host-context([dir=rtl]).show-month-and-year .calendar-days-of-week,:host-context([dir=rtl]):host(.show-month-and-year) .calendar-body,:host-context([dir=rtl]).show-month-and-year .calendar-body,:host-context([dir=rtl]):host(.show-month-and-year) .datetime-time,:host-context([dir=rtl]).show-month-and-year .datetime-time{left:unset;right:unset;right:-99999px}}@supports (not (background: -webkit-named-image(apple-pay-logo-black))) or ((background: -webkit-named-image(apple-pay-logo-black)) and (aspect-ratio: 1/1)){:host(.show-month-and-year) .calendar-next-prev,:host(.show-month-and-year) .calendar-days-of-week,:host(.show-month-and-year) .calendar-body,:host(.show-month-and-year) .datetime-time{display:none}}:host(.datetime-readonly),:host(.datetime-disabled){pointer-events:none}:host(.datetime-disabled){opacity:0.4}:host .datetime-header .datetime-title{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}:host .datetime-action-buttons.has-clear-button{width:100%}:host .datetime-action-buttons ion-buttons{display:flex;justify-content:space-between}:host .calendar-action-buttons{display:flex;justify-content:space-between}:host .calendar-action-buttons ion-item,:host .calendar-action-buttons ion-button{--background:translucent}:host .calendar-action-buttons ion-item ion-label{display:flex;align-items:center}:host .calendar-action-buttons ion-item ion-icon{padding-left:4px;padding-right:0;padding-top:0;padding-bottom:0}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .calendar-action-buttons ion-item ion-icon{padding-left:unset;padding-right:unset;-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:0;padding-inline-end:0}}:host .calendar-days-of-week{display:grid;grid-template-columns:repeat(7, 1fr);text-align:center}:host .calendar-body{display:flex;flex-grow:1;scroll-snap-type:x mandatory;overflow-x:scroll;overflow-y:hidden;scrollbar-width:none;outline:none}:host .calendar-body .calendar-month{scroll-snap-align:start;scroll-snap-stop:always;flex-shrink:0;width:100%}:host .calendar-body .calendar-month-disabled{scroll-snap-align:none}:host .calendar-body::-webkit-scrollbar{display:none}:host .calendar-body .calendar-month-grid{display:grid;grid-template-columns:repeat(7, 1fr);height:100%}:host .calendar-day{padding-left:0px;padding-right:0px;padding-top:0px;padding-bottom:0px;margin-left:0px;margin-right:0px;margin-top:0px;margin-bottom:0px;display:flex;position:relative;align-items:center;justify-content:center;border:none;outline:none;background:none;color:currentColor;cursor:pointer;appearance:none;z-index:0}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .calendar-day{padding-left:unset;padding-right:unset;-webkit-padding-start:0px;padding-inline-start:0px;-webkit-padding-end:0px;padding-inline-end:0px}}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .calendar-day{margin-left:unset;margin-right:unset;-webkit-margin-start:0px;margin-inline-start:0px;-webkit-margin-end:0px;margin-inline-end:0px}}:host .calendar-day[disabled]{pointer-events:none;opacity:0.4}:host .calendar-day:after{border-radius:32px;padding-left:4px;padding-right:4px;padding-top:4px;padding-bottom:4px;left:50%;top:50%;position:absolute;width:32px;height:32px;transform:translate(-50%, -50%);content:\" \";z-index:-1}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .calendar-day:after{padding-left:unset;padding-right:unset;-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px}}:host-context([dir=rtl]){left:unset;right:unset;right:50%}:host .datetime-time{display:flex;justify-content:space-between}:host(.datetime-presentation-time) .datetime-time{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0}:host ion-popover{--height:200px}:host .time-header{display:flex;align-items:center}:host .time-body{border-radius:8px;padding-left:12px;padding-right:12px;padding-top:6px;padding-bottom:6px;display:flex;border:none;background:var(--ion-color-step-300, #edeef0);color:var(--ion-text-color, #000);font-family:inherit;font-size:inherit;cursor:pointer;appearance:none}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .time-body{padding-left:unset;padding-right:unset;-webkit-padding-start:12px;padding-inline-start:12px;-webkit-padding-end:12px;padding-inline-end:12px}}:host .time-body-active{color:var(--ion-color-base)}:host(.in-item){position:static}:host(.show-month-and-year) .calendar-action-buttons ion-item{--color:var(--ion-color-base)}:host{--background:var(--ion-color-light, #ffffff);--background-rgb:var(--ion-color-light-rgb);--title-color:var(--ion-color-step-600, #666666)}:host(.datetime-presentation-date-time),:host(.datetime-presentation-time-date),:host(.datetime-presentation-date){min-height:350px}:host .datetime-header{padding-left:16px;padding-right:16px;padding-top:16px;padding-bottom:16px;border-bottom:0.55px solid var(--ion-color-step-200, #cccccc)}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .datetime-header{padding-left:unset;padding-right:unset;-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px}}:host .datetime-header .datetime-title{color:var(--title-color);font-size:14px}:host .calendar-action-buttons ion-item{--padding-start:16px;--background-hover:transparent;--background-activated:transparent;font-size:16px;font-weight:600}:host .calendar-action-buttons ion-item ion-icon,:host .calendar-action-buttons ion-buttons ion-button{color:var(--ion-color-base)}:host .calendar-action-buttons ion-buttons{padding-left:0;padding-right:0;padding-top:8px;padding-bottom:0}:host .calendar-action-buttons ion-buttons ion-button{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0}:host .calendar-days-of-week{padding-left:8px;padding-right:8px;padding-top:0;padding-bottom:0;color:var(--ion-color-step-300, #b3b3b3);font-size:12px;font-weight:600;line-height:24px;text-transform:uppercase}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .calendar-days-of-week{padding-left:unset;padding-right:unset;-webkit-padding-start:8px;padding-inline-start:8px;-webkit-padding-end:8px;padding-inline-end:8px}}:host .calendar-body .calendar-month .calendar-month-grid{padding-left:8px;padding-right:8px;padding-top:8px;padding-bottom:8px;height:calc(100% - 16px)}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .calendar-body .calendar-month .calendar-month-grid{padding-left:unset;padding-right:unset;-webkit-padding-start:8px;padding-inline-start:8px;-webkit-padding-end:8px;padding-inline-end:8px}}:host .calendar-day{font-size:20px}:host .calendar-day:after{opacity:0.2}:host .calendar-day:focus:after{background:var(--ion-color-base)}:host .calendar-day.calendar-day-today{color:var(--ion-color-base)}:host .calendar-day.calendar-day-active{color:var(--ion-color-base);font-weight:600}:host .calendar-day.calendar-day-active:after{background:var(--ion-color-base)}:host .calendar-day.calendar-day-today.calendar-day-active{color:var(--ion-color-contrast)}:host .calendar-day.calendar-day-today.calendar-day-active:after{background:var(--ion-color-base);opacity:1}:host .datetime-time{padding-left:16px;padding-right:16px;padding-top:8px;padding-bottom:16px;font-size:16px}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .datetime-time{padding-left:unset;padding-right:unset;-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px}}:host .datetime-time .time-header{font-weight:600}:host .datetime-buttons{padding-left:8px;padding-right:8px;padding-top:8px;padding-bottom:8px;border-top:0.55px solid var(--ion-color-step-200, #cccccc)}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .datetime-buttons{padding-left:unset;padding-right:unset;-webkit-padding-start:8px;padding-inline-start:8px;-webkit-padding-end:8px;padding-inline-end:8px}}:host .datetime-buttons ::slotted(ion-buttons),:host .datetime-buttons ion-buttons{display:flex;align-items:center;justify-content:space-between}:host .datetime-action-buttons{width:100%}";
150
+ const datetimeIosCss = ":host{display:flex;flex-flow:column;background:var(--background);overflow:hidden}ion-picker-column-internal{min-width:26px}:host(.datetime-size-fixed){width:auto;height:auto}:host(.datetime-size-fixed:not(.datetime-prefer-wheel)){max-width:350px}:host(.datetime-size-fixed.datetime-prefer-wheel){min-width:350px;max-width:max-content}:host(.datetime-size-cover){width:100%}:host .calendar-body,:host .datetime-year{opacity:0}:host(:not(.datetime-ready)) .datetime-year{position:absolute;pointer-events:none}:host(.datetime-ready) .calendar-body{opacity:1}:host(.datetime-ready) .datetime-year{display:none;opacity:1}:host .wheel-order-year-first .day-column{order:3;text-align:end}:host .wheel-order-year-first .month-column{order:2;text-align:end}:host .wheel-order-year-first .year-column{order:1;text-align:start}:host .datetime-calendar,:host .datetime-year{display:flex;flex:1 1 auto;flex-flow:column}:host(.show-month-and-year) .datetime-year{display:flex}@supports (background: -webkit-named-image(apple-pay-logo-black)) and (not (aspect-ratio: 1/1)){:host(.show-month-and-year) .calendar-next-prev,:host(.show-month-and-year) .calendar-days-of-week,:host(.show-month-and-year) .calendar-body,:host(.show-month-and-year) .datetime-time{left:-99999px;position:absolute;visibility:hidden;pointer-events:none}:host-context([dir=rtl]):host(.show-month-and-year) .calendar-next-prev,:host-context([dir=rtl]).show-month-and-year .calendar-next-prev,:host-context([dir=rtl]):host(.show-month-and-year) .calendar-days-of-week,:host-context([dir=rtl]).show-month-and-year .calendar-days-of-week,:host-context([dir=rtl]):host(.show-month-and-year) .calendar-body,:host-context([dir=rtl]).show-month-and-year .calendar-body,:host-context([dir=rtl]):host(.show-month-and-year) .datetime-time,:host-context([dir=rtl]).show-month-and-year .datetime-time{left:unset;right:unset;right:-99999px}}@supports (not (background: -webkit-named-image(apple-pay-logo-black))) or ((background: -webkit-named-image(apple-pay-logo-black)) and (aspect-ratio: 1/1)){:host(.show-month-and-year) .calendar-next-prev,:host(.show-month-and-year) .calendar-days-of-week,:host(.show-month-and-year) .calendar-body,:host(.show-month-and-year) .datetime-time{display:none}}:host(.month-year-picker-open) .datetime-footer{display:none}:host(.datetime-readonly),:host(.datetime-disabled){pointer-events:none}:host(.datetime-disabled){opacity:0.4}:host .datetime-header .datetime-title{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}:host .datetime-action-buttons.has-clear-button{width:100%}:host .datetime-action-buttons ion-buttons{display:flex;justify-content:space-between}:host .calendar-action-buttons{display:flex;justify-content:space-between}:host .calendar-action-buttons ion-item,:host .calendar-action-buttons ion-button{--background:translucent}:host .calendar-action-buttons ion-item ion-label{display:flex;align-items:center}:host .calendar-action-buttons ion-item ion-icon{padding-left:4px;padding-right:0;padding-top:0;padding-bottom:0}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .calendar-action-buttons ion-item ion-icon{padding-left:unset;padding-right:unset;-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:0;padding-inline-end:0}}:host .calendar-days-of-week{display:grid;grid-template-columns:repeat(7, 1fr);text-align:center}:host .calendar-body{display:flex;flex-grow:1;scroll-snap-type:x mandatory;overflow-x:scroll;overflow-y:hidden;scrollbar-width:none;outline:none}:host .calendar-body .calendar-month{scroll-snap-align:start;scroll-snap-stop:always;flex-shrink:0;width:100%}:host .calendar-body .calendar-month-disabled{scroll-snap-align:none}:host .calendar-body::-webkit-scrollbar{display:none}:host .calendar-body .calendar-month-grid{display:grid;grid-template-columns:repeat(7, 1fr);height:100%}:host .calendar-day{padding-left:0px;padding-right:0px;padding-top:0px;padding-bottom:0px;margin-left:0px;margin-right:0px;margin-top:0px;margin-bottom:0px;display:flex;position:relative;align-items:center;justify-content:center;border:none;outline:none;background:none;color:currentColor;cursor:pointer;appearance:none;z-index:0}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .calendar-day{padding-left:unset;padding-right:unset;-webkit-padding-start:0px;padding-inline-start:0px;-webkit-padding-end:0px;padding-inline-end:0px}}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .calendar-day{margin-left:unset;margin-right:unset;-webkit-margin-start:0px;margin-inline-start:0px;-webkit-margin-end:0px;margin-inline-end:0px}}:host .calendar-day[disabled]{pointer-events:none;opacity:0.4}:host .calendar-day:after{border-radius:32px;padding-left:4px;padding-right:4px;padding-top:4px;padding-bottom:4px;position:absolute;top:50%;left:50%;width:32px;height:32px;transform:translate(-50%, -50%);content:\" \";z-index:-1}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .calendar-day:after{padding-left:unset;padding-right:unset;-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px}}:host .datetime-time{display:flex;justify-content:space-between}:host(.datetime-presentation-time) .datetime-time{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0}:host ion-popover{--height:200px}:host .time-header{display:flex;align-items:center}:host .time-body{border-radius:8px;padding-left:12px;padding-right:12px;padding-top:6px;padding-bottom:6px;display:flex;border:none;background:var(--ion-color-step-300, #edeef0);color:var(--ion-text-color, #000);font-family:inherit;font-size:inherit;cursor:pointer;appearance:none}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .time-body{padding-left:unset;padding-right:unset;-webkit-padding-start:12px;padding-inline-start:12px;-webkit-padding-end:12px;padding-inline-end:12px}}:host .time-body-active{color:var(--ion-color-base)}:host(.in-item){position:static}:host(.show-month-and-year) .calendar-action-buttons ion-item{--color:var(--ion-color-base)}:host{--background:var(--ion-color-light, #ffffff);--background-rgb:var(--ion-color-light-rgb);--title-color:var(--ion-color-step-600, #666666)}:host(.datetime-presentation-date-time:not(.datetime-prefer-wheel)),:host(.datetime-presentation-time-date:not(.datetime-prefer-wheel)),:host(.datetime-presentation-date:not(.datetime-prefer-wheel)){min-height:350px}:host .datetime-header{padding-left:16px;padding-right:16px;padding-top:16px;padding-bottom:16px;border-bottom:0.55px solid var(--ion-color-step-200, #cccccc)}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .datetime-header{padding-left:unset;padding-right:unset;-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px}}:host .datetime-header .datetime-title{color:var(--title-color);font-size:14px}:host .calendar-action-buttons ion-item{--padding-start:16px;--background-hover:transparent;--background-activated:transparent;font-size:16px;font-weight:600}:host .calendar-action-buttons ion-item ion-icon,:host .calendar-action-buttons ion-buttons ion-button{color:var(--ion-color-base)}:host .calendar-action-buttons ion-buttons{padding-left:0;padding-right:0;padding-top:8px;padding-bottom:0}:host .calendar-action-buttons ion-buttons ion-button{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0}:host .calendar-days-of-week{padding-left:8px;padding-right:8px;padding-top:0;padding-bottom:0;color:var(--ion-color-step-300, #b3b3b3);font-size:12px;font-weight:600;line-height:24px;text-transform:uppercase}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .calendar-days-of-week{padding-left:unset;padding-right:unset;-webkit-padding-start:8px;padding-inline-start:8px;-webkit-padding-end:8px;padding-inline-end:8px}}:host .calendar-body .calendar-month .calendar-month-grid{padding-left:8px;padding-right:8px;padding-top:8px;padding-bottom:8px;height:calc(100% - 16px)}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .calendar-body .calendar-month .calendar-month-grid{padding-left:unset;padding-right:unset;-webkit-padding-start:8px;padding-inline-start:8px;-webkit-padding-end:8px;padding-inline-end:8px}}:host .calendar-day{font-size:20px}:host .calendar-day:after{opacity:0.2}:host .calendar-day:focus:after{background:var(--ion-color-base)}:host .calendar-day.calendar-day-today{color:var(--ion-color-base)}:host .calendar-day.calendar-day-active{color:var(--ion-color-base);font-weight:600}:host .calendar-day.calendar-day-active:after{background:var(--ion-color-base)}:host .calendar-day.calendar-day-today.calendar-day-active{color:var(--ion-color-contrast)}:host .calendar-day.calendar-day-today.calendar-day-active:after{background:var(--ion-color-base);opacity:1}:host .datetime-time{padding-left:16px;padding-right:16px;padding-top:8px;padding-bottom:16px;font-size:16px}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .datetime-time{padding-left:unset;padding-right:unset;-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px}}:host .datetime-time .time-header{font-weight:600}:host .datetime-buttons{padding-left:8px;padding-right:8px;padding-top:8px;padding-bottom:8px;border-top:0.55px solid var(--ion-color-step-200, #cccccc)}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .datetime-buttons{padding-left:unset;padding-right:unset;-webkit-padding-start:8px;padding-inline-start:8px;-webkit-padding-end:8px;padding-inline-end:8px}}:host .datetime-buttons ::slotted(ion-buttons),:host .datetime-buttons ion-buttons{display:flex;align-items:center;justify-content:space-between}:host .datetime-action-buttons{width:100%}";
998
151
 
999
- const datetimeMdCss = ":host{display:flex;flex-flow:column;background:var(--background);overflow:hidden}:host(.datetime-size-fixed){width:auto;max-width:350px;height:auto}:host(.datetime-size-cover){width:100%}:host .calendar-body,:host .datetime-year{opacity:0}:host(:not(.datetime-ready)) .datetime-year{position:absolute;pointer-events:none}:host(.datetime-ready) .calendar-body{opacity:1}:host(.datetime-ready) .datetime-year{display:none;opacity:1}:host .datetime-year .order-month-first .month-column{order:1}:host .datetime-year .order-month-first .year-column{order:2}:host .datetime-year .order-year-first .month-column{order:2;text-align:end}:host .datetime-year .order-year-first .year-column{order:1;text-align:start}:host .datetime-calendar,:host .datetime-year{display:flex;flex:1 1 auto;flex-flow:column}:host(.show-month-and-year) .datetime-year{display:flex}@supports (background: -webkit-named-image(apple-pay-logo-black)) and (not (aspect-ratio: 1/1)){:host(.show-month-and-year) .calendar-next-prev,:host(.show-month-and-year) .calendar-days-of-week,:host(.show-month-and-year) .calendar-body,:host(.show-month-and-year) .datetime-time{left:-99999px;position:absolute;visibility:hidden;pointer-events:none}:host-context([dir=rtl]):host(.show-month-and-year) .calendar-next-prev,:host-context([dir=rtl]).show-month-and-year .calendar-next-prev,:host-context([dir=rtl]):host(.show-month-and-year) .calendar-days-of-week,:host-context([dir=rtl]).show-month-and-year .calendar-days-of-week,:host-context([dir=rtl]):host(.show-month-and-year) .calendar-body,:host-context([dir=rtl]).show-month-and-year .calendar-body,:host-context([dir=rtl]):host(.show-month-and-year) .datetime-time,:host-context([dir=rtl]).show-month-and-year .datetime-time{left:unset;right:unset;right:-99999px}}@supports (not (background: -webkit-named-image(apple-pay-logo-black))) or ((background: -webkit-named-image(apple-pay-logo-black)) and (aspect-ratio: 1/1)){:host(.show-month-and-year) .calendar-next-prev,:host(.show-month-and-year) .calendar-days-of-week,:host(.show-month-and-year) .calendar-body,:host(.show-month-and-year) .datetime-time{display:none}}:host(.datetime-readonly),:host(.datetime-disabled){pointer-events:none}:host(.datetime-disabled){opacity:0.4}:host .datetime-header .datetime-title{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}:host .datetime-action-buttons.has-clear-button{width:100%}:host .datetime-action-buttons ion-buttons{display:flex;justify-content:space-between}:host .calendar-action-buttons{display:flex;justify-content:space-between}:host .calendar-action-buttons ion-item,:host .calendar-action-buttons ion-button{--background:translucent}:host .calendar-action-buttons ion-item ion-label{display:flex;align-items:center}:host .calendar-action-buttons ion-item ion-icon{padding-left:4px;padding-right:0;padding-top:0;padding-bottom:0}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .calendar-action-buttons ion-item ion-icon{padding-left:unset;padding-right:unset;-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:0;padding-inline-end:0}}:host .calendar-days-of-week{display:grid;grid-template-columns:repeat(7, 1fr);text-align:center}:host .calendar-body{display:flex;flex-grow:1;scroll-snap-type:x mandatory;overflow-x:scroll;overflow-y:hidden;scrollbar-width:none;outline:none}:host .calendar-body .calendar-month{scroll-snap-align:start;scroll-snap-stop:always;flex-shrink:0;width:100%}:host .calendar-body .calendar-month-disabled{scroll-snap-align:none}:host .calendar-body::-webkit-scrollbar{display:none}:host .calendar-body .calendar-month-grid{display:grid;grid-template-columns:repeat(7, 1fr);height:100%}:host .calendar-day{padding-left:0px;padding-right:0px;padding-top:0px;padding-bottom:0px;margin-left:0px;margin-right:0px;margin-top:0px;margin-bottom:0px;display:flex;position:relative;align-items:center;justify-content:center;border:none;outline:none;background:none;color:currentColor;cursor:pointer;appearance:none;z-index:0}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .calendar-day{padding-left:unset;padding-right:unset;-webkit-padding-start:0px;padding-inline-start:0px;-webkit-padding-end:0px;padding-inline-end:0px}}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .calendar-day{margin-left:unset;margin-right:unset;-webkit-margin-start:0px;margin-inline-start:0px;-webkit-margin-end:0px;margin-inline-end:0px}}:host .calendar-day[disabled]{pointer-events:none;opacity:0.4}:host .calendar-day:after{border-radius:32px;padding-left:4px;padding-right:4px;padding-top:4px;padding-bottom:4px;left:50%;top:50%;position:absolute;width:32px;height:32px;transform:translate(-50%, -50%);content:\" \";z-index:-1}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .calendar-day:after{padding-left:unset;padding-right:unset;-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px}}:host-context([dir=rtl]){left:unset;right:unset;right:50%}:host .datetime-time{display:flex;justify-content:space-between}:host(.datetime-presentation-time) .datetime-time{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0}:host ion-popover{--height:200px}:host .time-header{display:flex;align-items:center}:host .time-body{border-radius:8px;padding-left:12px;padding-right:12px;padding-top:6px;padding-bottom:6px;display:flex;border:none;background:var(--ion-color-step-300, #edeef0);color:var(--ion-text-color, #000);font-family:inherit;font-size:inherit;cursor:pointer;appearance:none}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .time-body{padding-left:unset;padding-right:unset;-webkit-padding-start:12px;padding-inline-start:12px;-webkit-padding-end:12px;padding-inline-end:12px}}:host .time-body-active{color:var(--ion-color-base)}:host(.in-item){position:static}:host(.show-month-and-year) .calendar-action-buttons ion-item{--color:var(--ion-color-base)}:host{--background:var(--ion-color-step-100, #ffffff);--title-color:var(--ion-color-contrast)}:host .datetime-header{padding-left:20px;padding-right:20px;padding-top:20px;padding-bottom:20px;background:var(--ion-color-base);color:var(--title-color)}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .datetime-header{padding-left:unset;padding-right:unset;-webkit-padding-start:20px;padding-inline-start:20px;-webkit-padding-end:20px;padding-inline-end:20px}}:host .datetime-header .datetime-title{font-size:12px;text-transform:uppercase}:host .datetime-header .datetime-selected-date{margin-top:30px;font-size:34px}:host .datetime-calendar .calendar-action-buttons ion-item{--padding-start:20px}:host .calendar-action-buttons ion-item,:host .calendar-action-buttons ion-button{color:var(--ion-color-step-650, #595959)}:host .calendar-days-of-week{padding-left:10px;padding-right:10px;padding-top:0px;padding-bottom:0px;color:var(--ion-color-step-500, gray);font-size:14px;line-height:36px}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .calendar-days-of-week{padding-left:unset;padding-right:unset;-webkit-padding-start:10px;padding-inline-start:10px;-webkit-padding-end:10px;padding-inline-end:10px}}:host .calendar-body .calendar-month .calendar-month-grid{padding-left:10px;padding-right:10px;padding-top:3px;padding-bottom:0px;grid-template-rows:repeat(6, 1fr)}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .calendar-body .calendar-month .calendar-month-grid{padding-left:unset;padding-right:unset;-webkit-padding-start:10px;padding-inline-start:10px;-webkit-padding-end:10px;padding-inline-end:10px}}:host .calendar-day{padding-left:0px;padding-right:0;padding-top:13px;padding-bottom:13px;font-size:14px}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .calendar-day{padding-left:unset;padding-right:unset;-webkit-padding-start:0px;padding-inline-start:0px;-webkit-padding-end:0;padding-inline-end:0}}:host .calendar-day:focus:after{background:rgba(var(--ion-color-base-rgb), 0.2);box-shadow:0px 0px 0px 4px rgba(var(--ion-color-base-rgb), 0.2)}:host .calendar-day.calendar-day-today{color:var(--ion-color-base)}:host .calendar-day.calendar-day-today:after{border:1px solid var(--ion-color-base)}:host .calendar-day.calendar-day-active{color:var(--ion-color-contrast)}:host .calendar-day.calendar-day-active:after{border:1px solid var(--ion-color-base);background:var(--ion-color-base)}:host .datetime-time{padding-left:16px;padding-right:16px;padding-top:8px;padding-bottom:8px}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .datetime-time{padding-left:unset;padding-right:unset;-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px}}:host .time-header{color:var(--ion-color-step-650, #595959)}:host(.datetime-presentation-month) .datetime-year,:host(.datetime-presentation-year) .datetime-year,:host(.datetime-presentation-month-year) .datetime-year{margin-top:20px;margin-bottom:20px}:host .datetime-buttons{padding-left:10px;padding-right:10px;padding-top:10px;padding-bottom:10px;display:flex;align-items:center;justify-content:flex-end}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .datetime-buttons{padding-left:unset;padding-right:unset;-webkit-padding-start:10px;padding-inline-start:10px;-webkit-padding-end:10px;padding-inline-end:10px}}:host .datetime-view-buttons ion-button{color:var(--ion-color-step-800, #333333)}";
152
+ const datetimeMdCss = ":host{display:flex;flex-flow:column;background:var(--background);overflow:hidden}ion-picker-column-internal{min-width:26px}:host(.datetime-size-fixed){width:auto;height:auto}:host(.datetime-size-fixed:not(.datetime-prefer-wheel)){max-width:350px}:host(.datetime-size-fixed.datetime-prefer-wheel){min-width:350px;max-width:max-content}:host(.datetime-size-cover){width:100%}:host .calendar-body,:host .datetime-year{opacity:0}:host(:not(.datetime-ready)) .datetime-year{position:absolute;pointer-events:none}:host(.datetime-ready) .calendar-body{opacity:1}:host(.datetime-ready) .datetime-year{display:none;opacity:1}:host .wheel-order-year-first .day-column{order:3;text-align:end}:host .wheel-order-year-first .month-column{order:2;text-align:end}:host .wheel-order-year-first .year-column{order:1;text-align:start}:host .datetime-calendar,:host .datetime-year{display:flex;flex:1 1 auto;flex-flow:column}:host(.show-month-and-year) .datetime-year{display:flex}@supports (background: -webkit-named-image(apple-pay-logo-black)) and (not (aspect-ratio: 1/1)){:host(.show-month-and-year) .calendar-next-prev,:host(.show-month-and-year) .calendar-days-of-week,:host(.show-month-and-year) .calendar-body,:host(.show-month-and-year) .datetime-time{left:-99999px;position:absolute;visibility:hidden;pointer-events:none}:host-context([dir=rtl]):host(.show-month-and-year) .calendar-next-prev,:host-context([dir=rtl]).show-month-and-year .calendar-next-prev,:host-context([dir=rtl]):host(.show-month-and-year) .calendar-days-of-week,:host-context([dir=rtl]).show-month-and-year .calendar-days-of-week,:host-context([dir=rtl]):host(.show-month-and-year) .calendar-body,:host-context([dir=rtl]).show-month-and-year .calendar-body,:host-context([dir=rtl]):host(.show-month-and-year) .datetime-time,:host-context([dir=rtl]).show-month-and-year .datetime-time{left:unset;right:unset;right:-99999px}}@supports (not (background: -webkit-named-image(apple-pay-logo-black))) or ((background: -webkit-named-image(apple-pay-logo-black)) and (aspect-ratio: 1/1)){:host(.show-month-and-year) .calendar-next-prev,:host(.show-month-and-year) .calendar-days-of-week,:host(.show-month-and-year) .calendar-body,:host(.show-month-and-year) .datetime-time{display:none}}:host(.month-year-picker-open) .datetime-footer{display:none}:host(.datetime-readonly),:host(.datetime-disabled){pointer-events:none}:host(.datetime-disabled){opacity:0.4}:host .datetime-header .datetime-title{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}:host .datetime-action-buttons.has-clear-button{width:100%}:host .datetime-action-buttons ion-buttons{display:flex;justify-content:space-between}:host .calendar-action-buttons{display:flex;justify-content:space-between}:host .calendar-action-buttons ion-item,:host .calendar-action-buttons ion-button{--background:translucent}:host .calendar-action-buttons ion-item ion-label{display:flex;align-items:center}:host .calendar-action-buttons ion-item ion-icon{padding-left:4px;padding-right:0;padding-top:0;padding-bottom:0}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .calendar-action-buttons ion-item ion-icon{padding-left:unset;padding-right:unset;-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:0;padding-inline-end:0}}:host .calendar-days-of-week{display:grid;grid-template-columns:repeat(7, 1fr);text-align:center}:host .calendar-body{display:flex;flex-grow:1;scroll-snap-type:x mandatory;overflow-x:scroll;overflow-y:hidden;scrollbar-width:none;outline:none}:host .calendar-body .calendar-month{scroll-snap-align:start;scroll-snap-stop:always;flex-shrink:0;width:100%}:host .calendar-body .calendar-month-disabled{scroll-snap-align:none}:host .calendar-body::-webkit-scrollbar{display:none}:host .calendar-body .calendar-month-grid{display:grid;grid-template-columns:repeat(7, 1fr);height:100%}:host .calendar-day{padding-left:0px;padding-right:0px;padding-top:0px;padding-bottom:0px;margin-left:0px;margin-right:0px;margin-top:0px;margin-bottom:0px;display:flex;position:relative;align-items:center;justify-content:center;border:none;outline:none;background:none;color:currentColor;cursor:pointer;appearance:none;z-index:0}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .calendar-day{padding-left:unset;padding-right:unset;-webkit-padding-start:0px;padding-inline-start:0px;-webkit-padding-end:0px;padding-inline-end:0px}}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .calendar-day{margin-left:unset;margin-right:unset;-webkit-margin-start:0px;margin-inline-start:0px;-webkit-margin-end:0px;margin-inline-end:0px}}:host .calendar-day[disabled]{pointer-events:none;opacity:0.4}:host .calendar-day:after{border-radius:32px;padding-left:4px;padding-right:4px;padding-top:4px;padding-bottom:4px;position:absolute;top:50%;left:50%;width:32px;height:32px;transform:translate(-50%, -50%);content:\" \";z-index:-1}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .calendar-day:after{padding-left:unset;padding-right:unset;-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px}}:host .datetime-time{display:flex;justify-content:space-between}:host(.datetime-presentation-time) .datetime-time{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0}:host ion-popover{--height:200px}:host .time-header{display:flex;align-items:center}:host .time-body{border-radius:8px;padding-left:12px;padding-right:12px;padding-top:6px;padding-bottom:6px;display:flex;border:none;background:var(--ion-color-step-300, #edeef0);color:var(--ion-text-color, #000);font-family:inherit;font-size:inherit;cursor:pointer;appearance:none}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .time-body{padding-left:unset;padding-right:unset;-webkit-padding-start:12px;padding-inline-start:12px;-webkit-padding-end:12px;padding-inline-end:12px}}:host .time-body-active{color:var(--ion-color-base)}:host(.in-item){position:static}:host(.show-month-and-year) .calendar-action-buttons ion-item{--color:var(--ion-color-base)}:host{--background:var(--ion-color-step-100, #ffffff);--title-color:var(--ion-color-contrast)}:host .datetime-header{padding-left:20px;padding-right:20px;padding-top:20px;padding-bottom:20px;background:var(--ion-color-base);color:var(--title-color)}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .datetime-header{padding-left:unset;padding-right:unset;-webkit-padding-start:20px;padding-inline-start:20px;-webkit-padding-end:20px;padding-inline-end:20px}}:host .datetime-header .datetime-title{font-size:12px;text-transform:uppercase}:host .datetime-header .datetime-selected-date{margin-top:30px;font-size:34px}:host .datetime-calendar .calendar-action-buttons ion-item{--padding-start:20px}:host .calendar-action-buttons ion-item,:host .calendar-action-buttons ion-button{color:var(--ion-color-step-650, #595959)}:host .calendar-days-of-week{padding-left:10px;padding-right:10px;padding-top:0px;padding-bottom:0px;color:var(--ion-color-step-500, gray);font-size:14px;line-height:36px}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .calendar-days-of-week{padding-left:unset;padding-right:unset;-webkit-padding-start:10px;padding-inline-start:10px;-webkit-padding-end:10px;padding-inline-end:10px}}:host .calendar-body .calendar-month .calendar-month-grid{padding-left:10px;padding-right:10px;padding-top:3px;padding-bottom:0px;grid-template-rows:repeat(6, 1fr)}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .calendar-body .calendar-month .calendar-month-grid{padding-left:unset;padding-right:unset;-webkit-padding-start:10px;padding-inline-start:10px;-webkit-padding-end:10px;padding-inline-end:10px}}:host .calendar-day{padding-left:0px;padding-right:0;padding-top:13px;padding-bottom:13px;font-size:14px}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .calendar-day{padding-left:unset;padding-right:unset;-webkit-padding-start:0px;padding-inline-start:0px;-webkit-padding-end:0;padding-inline-end:0}}:host .calendar-day:focus:after{background:rgba(var(--ion-color-base-rgb), 0.2);box-shadow:0px 0px 0px 4px rgba(var(--ion-color-base-rgb), 0.2)}:host .calendar-day.calendar-day-today{color:var(--ion-color-base)}:host .calendar-day.calendar-day-today:after{border:1px solid var(--ion-color-base)}:host .calendar-day.calendar-day-active{color:var(--ion-color-contrast)}:host .calendar-day.calendar-day-active:after{border:1px solid var(--ion-color-base);background:var(--ion-color-base)}:host .datetime-time{padding-left:16px;padding-right:16px;padding-top:8px;padding-bottom:8px}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .datetime-time{padding-left:unset;padding-right:unset;-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px}}:host .time-header{color:var(--ion-color-step-650, #595959)}:host(.datetime-presentation-month) .datetime-year,:host(.datetime-presentation-year) .datetime-year,:host(.datetime-presentation-month-year) .datetime-year{margin-top:20px;margin-bottom:20px}:host .datetime-buttons{padding-left:10px;padding-right:10px;padding-top:10px;padding-bottom:10px;display:flex;align-items:center;justify-content:flex-end}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){:host .datetime-buttons{padding-left:unset;padding-right:unset;-webkit-padding-start:10px;padding-inline-start:10px;-webkit-padding-end:10px;padding-inline-end:10px}}:host .datetime-view-buttons ion-button{color:var(--ion-color-step-800, #333333)}";
1000
153
 
1001
154
  const Datetime = class {
1002
155
  constructor(hostRef) {
@@ -1006,8 +159,17 @@ const Datetime = class {
1006
159
  this.ionFocus = createEvent(this, "ionFocus", 7);
1007
160
  this.ionBlur = createEvent(this, "ionBlur", 7);
1008
161
  this.ionStyle = createEvent(this, "ionStyle", 7);
162
+ this.ionRender = createEvent(this, "ionRender", 7);
1009
163
  this.inputId = `ion-dt-${datetimeIds++}`;
1010
- this.overlayIsPresenting = false;
164
+ /**
165
+ * Whether to highlight the active day with a solid circle (as opposed
166
+ * to the outline circle around today). If you don't specify an initial
167
+ * value for the datetime, it doesn't automatically init to a default to
168
+ * avoid unwanted change events firing. If the solid circle were still
169
+ * shown then, it would look like a date had already been selected, which
170
+ * is misleading UX.
171
+ */
172
+ this.highlightActiveParts = false;
1011
173
  this.todayParts = parseDate(getToday());
1012
174
  this.prevPresentation = null;
1013
175
  this.showMonthAndYear = false;
@@ -1017,7 +179,7 @@ const Datetime = class {
1017
179
  year: 2021,
1018
180
  hour: 13,
1019
181
  minute: 52,
1020
- ampm: 'pm'
182
+ ampm: 'pm',
1021
183
  };
1022
184
  this.workingParts = {
1023
185
  month: 5,
@@ -1025,7 +187,7 @@ const Datetime = class {
1025
187
  year: 2021,
1026
188
  hour: 13,
1027
189
  minute: 52,
1028
- ampm: 'pm'
190
+ ampm: 'pm',
1029
191
  };
1030
192
  this.isPresented = false;
1031
193
  this.isTimePopoverOpen = false;
@@ -1079,6 +241,11 @@ const Datetime = class {
1079
241
  * default value is `0` and represents Sunday.
1080
242
  */
1081
243
  this.firstDayOfWeek = 0;
244
+ /**
245
+ * If `true`, multiple dates can be selected at once. Only
246
+ * applies to `presentation="date"` and `preferWheel="false"`.
247
+ */
248
+ this.multiple = false;
1082
249
  /**
1083
250
  * If `true`, a header will be shown above the calendar
1084
251
  * picker. On `ios` mode this will include the
@@ -1118,6 +285,19 @@ const Datetime = class {
1118
285
  * If `fixed`, the `ion-datetime` will have a fixed width.
1119
286
  */
1120
287
  this.size = 'fixed';
288
+ /**
289
+ * If `true`, a wheel picker will be rendered instead of a calendar grid
290
+ * where possible. If `false`, a calendar grid will be rendered instead of
291
+ * a wheel picker where possible.
292
+ *
293
+ * A wheel picker can be rendered instead of a grid when `presentation` is
294
+ * one of the following values: `'date'`, `'date-time'`, or `'time-date'`.
295
+ *
296
+ * A wheel picker will always be rendered regardless of
297
+ * the `preferWheel` value when `presentation` is one of the following values:
298
+ * `'time'`, `'month'`, `'month-year'`, or `'year'`.
299
+ */
300
+ this.preferWheel = false;
1121
301
  this.closeParentOverlay = () => {
1122
302
  const popoverOrModal = this.el.closest('ion-modal, ion-popover');
1123
303
  if (popoverOrModal) {
@@ -1127,8 +307,48 @@ const Datetime = class {
1127
307
  this.setWorkingParts = (parts) => {
1128
308
  this.workingParts = Object.assign({}, parts);
1129
309
  };
1130
- this.setActiveParts = (parts) => {
1131
- this.activeParts = Object.assign({}, parts);
310
+ this.setActiveParts = (parts, removeDate = false) => {
311
+ const { multiple, activePartsClone, highlightActiveParts } = this;
312
+ if (multiple) {
313
+ /**
314
+ * We read from activePartsClone here because valueChanged() only updates that,
315
+ * so it's the more reliable source of truth. If we read from activeParts, then
316
+ * if you click July 1, manually set the value to July 2, and then click July 3,
317
+ * the new value would be [July 1, July 3], ignoring the value set.
318
+ *
319
+ * We can then pass the new value to activeParts (rather than activePartsClone)
320
+ * since the clone will be updated automatically by activePartsChanged().
321
+ */
322
+ const activePartsArray = Array.isArray(activePartsClone) ? activePartsClone : [activePartsClone];
323
+ if (removeDate) {
324
+ this.activeParts = activePartsArray.filter((p) => !isSameDay(p, parts));
325
+ }
326
+ else if (highlightActiveParts) {
327
+ this.activeParts = [...activePartsArray, parts];
328
+ }
329
+ else {
330
+ /**
331
+ * If highlightActiveParts is false, that means we just have a
332
+ * default value of today in activeParts; we need to replace that
333
+ * rather than adding to it since it's just a placeholder.
334
+ */
335
+ this.activeParts = [parts];
336
+ }
337
+ }
338
+ else {
339
+ this.activeParts = Object.assign({}, parts);
340
+ }
341
+ /**
342
+ * Now that the user has interacted somehow to select something, we can
343
+ * show the solid highlight. This needs to be done after checking it above,
344
+ * but before the confirm call below.
345
+ *
346
+ * Note that for datetimes with confirm/cancel buttons, the value
347
+ * isn't updated until you call confirm(). We need to bring the
348
+ * solid circle back on day click for UX reasons, rather than only
349
+ * show the circle if `value` is truthy.
350
+ */
351
+ this.highlightActiveParts = true;
1132
352
  const hasSlottedButtons = this.el.querySelector('[slot="buttons"]') !== null;
1133
353
  if (hasSlottedButtons || this.showDefaultButtons) {
1134
354
  return;
@@ -1171,8 +391,7 @@ const Datetime = class {
1171
391
  * if not currently focused, we should not re-focus
1172
392
  * the inner day.
1173
393
  */
1174
- if (((_a = record.oldValue) === null || _a === void 0 ? void 0 : _a.includes('ion-focused')) ||
1175
- !calendarBodyRef.classList.contains('ion-focused')) {
394
+ if (((_a = record.oldValue) === null || _a === void 0 ? void 0 : _a.includes('ion-focused')) || !calendarBodyRef.classList.contains('ion-focused')) {
1176
395
  return;
1177
396
  }
1178
397
  this.focusWorkingDay(currentMonth);
@@ -1281,7 +500,7 @@ const Datetime = class {
1281
500
  day,
1282
501
  year,
1283
502
  hour,
1284
- minute
503
+ minute,
1285
504
  };
1286
505
  };
1287
506
  this.processMaxParts = () => {
@@ -1295,21 +514,19 @@ const Datetime = class {
1295
514
  day,
1296
515
  year,
1297
516
  hour,
1298
- minute
517
+ minute,
1299
518
  };
1300
519
  };
1301
- this.initializeCalendarIOListeners = () => {
520
+ this.initializeCalendarListener = () => {
1302
521
  const calendarBodyRef = this.getCalendarBodyEl();
1303
522
  if (!calendarBodyRef) {
1304
523
  return;
1305
524
  }
1306
- const mode = getIonMode(this);
1307
525
  /**
1308
526
  * For performance reasons, we only render 3
1309
527
  * months at a time: The current month, the previous
1310
- * month, and the next month. We have IntersectionObservers
1311
- * on the previous and next month elements to append/prepend
1312
- * new months.
528
+ * month, and the next month. We have a scroll listener
529
+ * on the calendar body to append/prepend new months.
1313
530
  *
1314
531
  * We can do this because Stencil is smart enough to not
1315
532
  * re-create the .calendar-month containers, but rather
@@ -1324,61 +541,80 @@ const Datetime = class {
1324
541
  const startMonth = months[0];
1325
542
  const workingMonth = months[1];
1326
543
  const endMonth = months[2];
544
+ const mode = getIonMode(this);
545
+ const needsiOSRubberBandFix = mode === 'ios' && typeof navigator !== 'undefined' && navigator.maxTouchPoints > 1;
1327
546
  /**
1328
- * Before setting up the IntersectionObserver,
547
+ * Before setting up the scroll listener,
1329
548
  * scroll the middle month into view.
1330
549
  * scrollIntoView() will scroll entire page
1331
550
  * if element is not in viewport. Use scrollLeft instead.
1332
551
  */
1333
552
  writeTask(() => {
1334
553
  calendarBodyRef.scrollLeft = startMonth.clientWidth * (isRTL(this.el) ? -1 : 1);
1335
- let endIO;
1336
- let startIO;
1337
- const ioCallback = (callbackType, entries) => {
1338
- const refIO = (callbackType === 'start') ? startIO : endIO;
1339
- const refMonth = (callbackType === 'start') ? startMonth : endMonth;
1340
- const refMonthFn = (callbackType === 'start') ? getPreviousMonth : getNextMonth;
554
+ const getChangedMonth = (parts) => {
555
+ const box = calendarBodyRef.getBoundingClientRect();
556
+ const root = this.el.shadowRoot;
557
+ /**
558
+ * Get the element that is in the center of the calendar body.
559
+ * This will be an element inside of the active month.
560
+ */
561
+ const elementAtCenter = root.elementFromPoint(box.x + box.width / 2, box.y + box.height / 2);
1341
562
  /**
1342
- * If the month is not fully in view, do not do anything
563
+ * If there is no element then the
564
+ * component may be re-rendering on a slow device.
1343
565
  */
1344
- const ev = entries[0];
1345
- if (!ev.isIntersecting) {
566
+ if (!elementAtCenter)
567
+ return;
568
+ const month = elementAtCenter.closest('.calendar-month');
569
+ if (!month)
1346
570
  return;
1347
- }
1348
571
  /**
1349
- * When presenting an inline overlay,
1350
- * subsequent presentations will cause
1351
- * the IO to fire again (since the overlay
1352
- * is now visible and therefore the calendar
1353
- * months are intersecting).
572
+ * The edge of the month must be lined up with
573
+ * the edge of the calendar body in order for
574
+ * the component to update. Otherwise, it
575
+ * may be the case that the user has paused their
576
+ * swipe or the browser has not finished snapping yet.
577
+ * Rather than check if the x values are equal,
578
+ * we give it a tolerance of 2px to account for
579
+ * sub pixel rendering.
1354
580
  */
1355
- if (this.overlayIsPresenting) {
1356
- this.overlayIsPresenting = false;
581
+ const monthBox = month.getBoundingClientRect();
582
+ if (Math.abs(monthBox.x - box.x) > 2)
1357
583
  return;
584
+ /**
585
+ * From here, we can determine if the start
586
+ * month or the end month was scrolled into view.
587
+ * If no month was changed, then we can return from
588
+ * the scroll callback early.
589
+ */
590
+ if (month === startMonth) {
591
+ return getPreviousMonth(parts);
1358
592
  }
1359
- const { month, year, day } = refMonthFn(this.workingParts);
1360
- if (isMonthDisabled({ month, year, day: null }, {
1361
- minParts: Object.assign(Object.assign({}, this.minParts), { day: null }),
1362
- maxParts: Object.assign(Object.assign({}, this.maxParts), { day: null })
1363
- })) {
593
+ else if (month === endMonth) {
594
+ return getNextMonth(parts);
595
+ }
596
+ else {
1364
597
  return;
1365
598
  }
599
+ };
600
+ const updateActiveMonth = () => {
601
+ if (needsiOSRubberBandFix) {
602
+ calendarBodyRef.style.removeProperty('pointer-events');
603
+ appliediOSRubberBandFix = false;
604
+ }
1366
605
  /**
1367
- * On iOS, we need to set pointer-events: none
1368
- * when the user is almost done with the gesture
1369
- * so that they cannot quickly swipe while
1370
- * the scrollable container is snapping.
1371
- * Updating the container while snapping
1372
- * causes WebKit to snap incorrectly.
606
+ * If the month did not change
607
+ * then we can return early.
1373
608
  */
1374
- if (mode === 'ios') {
1375
- const ratio = ev.intersectionRatio;
1376
- // `maxTouchPoints` will be 1 in device preview, but > 1 on device
1377
- const shouldDisable = Math.abs(ratio - 0.7) <= 0.1 && navigator.maxTouchPoints > 1;
1378
- if (shouldDisable) {
1379
- calendarBodyRef.style.setProperty('pointer-events', 'none');
1380
- return;
1381
- }
609
+ const newDate = getChangedMonth(this.workingParts);
610
+ if (!newDate)
611
+ return;
612
+ const { month, day, year } = newDate;
613
+ if (isMonthDisabled({ month, year, day: null }, {
614
+ minParts: Object.assign(Object.assign({}, this.minParts), { day: null }),
615
+ maxParts: Object.assign(Object.assign({}, this.maxParts), { day: null }),
616
+ })) {
617
+ return;
1382
618
  }
1383
619
  /**
1384
620
  * Prevent scrolling for other browsers
@@ -1386,15 +622,6 @@ const Datetime = class {
1386
622
  * time to properly snap.
1387
623
  */
1388
624
  calendarBodyRef.style.setProperty('overflow', 'hidden');
1389
- /**
1390
- * Remove the IO temporarily
1391
- * otherwise you can sometimes get duplicate
1392
- * events when rubber banding.
1393
- */
1394
- if (refIO === undefined) {
1395
- return;
1396
- }
1397
- refIO.disconnect();
1398
625
  /**
1399
626
  * Use a writeTask here to ensure
1400
627
  * that the state is updated and the
@@ -1405,74 +632,45 @@ const Datetime = class {
1405
632
  * if we did not do this.
1406
633
  */
1407
634
  writeTask(() => {
1408
- // Disconnect all active intersection observers
1409
- // to avoid a re-render causing a duplicate event.
1410
- if (this.destroyCalendarIO) {
1411
- this.destroyCalendarIO();
1412
- }
1413
- raf(() => {
1414
- this.setWorkingParts(Object.assign(Object.assign({}, this.workingParts), { month, day: day, year }));
1415
- calendarBodyRef.scrollLeft = workingMonth.clientWidth * (isRTL(this.el) ? -1 : 1);
1416
- calendarBodyRef.style.removeProperty('overflow');
1417
- calendarBodyRef.style.removeProperty('pointer-events');
1418
- endIO === null || endIO === void 0 ? void 0 : endIO.observe(endMonth);
1419
- startIO === null || startIO === void 0 ? void 0 : startIO.observe(startMonth);
1420
- });
1421
- /**
1422
- * Now that state has been updated
1423
- * and the correct month is in view,
1424
- * we can resume the IO.
1425
- */
1426
- // tslint:disable-next-line
1427
- if (refIO === undefined) {
1428
- return;
1429
- }
1430
- refIO.observe(refMonth);
635
+ this.setWorkingParts(Object.assign(Object.assign({}, this.workingParts), { month, day: day, year }));
636
+ calendarBodyRef.scrollLeft = workingMonth.clientWidth * (isRTL(this.el) ? -1 : 1);
637
+ calendarBodyRef.style.removeProperty('overflow');
1431
638
  });
1432
639
  };
1433
- const threshold = mode === 'ios' &&
1434
- // tslint:disable-next-line
1435
- typeof navigator !== 'undefined' &&
1436
- navigator.maxTouchPoints > 1 ?
1437
- [0.7, 1] : 1;
1438
- // Intersection observers cannot accurately detect the
1439
- // intersection with a threshold of 1, when the observed
1440
- // element width is a sub-pixel value (i.e. 334.05px).
1441
- // Setting a root margin to 1px solves the issue.
1442
- const rootMargin = '1px';
1443
640
  /**
1444
- * Listen on the first month to
1445
- * prepend a new month and on the last
1446
- * month to append a new month.
1447
- * The 0.7 threshold is required on ios
1448
- * so that we can remove pointer-events
1449
- * when adding new months.
1450
- * Adding to a scroll snapping container
1451
- * while the container is snapping does not
1452
- * completely work as expected in WebKit.
1453
- * Adding pointer-events: none allows us to
1454
- * avoid these issues.
1455
- *
1456
- * This should be fine on Chromium, but
1457
- * when you set pointer-events: none
1458
- * it applies to active gestures which is not
1459
- * something WebKit does.
641
+ * When the container finishes scrolling we
642
+ * need to update the DOM with the selected month.
643
+ */
644
+ let scrollTimeout;
645
+ /**
646
+ * We do not want to attempt to set pointer-events
647
+ * multiple times within a single swipe gesture as
648
+ * that adds unnecessary work to the main thread.
1460
649
  */
1461
- endIO = new IntersectionObserver(ev => ioCallback('end', ev), {
1462
- threshold,
1463
- root: calendarBodyRef,
1464
- rootMargin
1465
- });
1466
- endIO.observe(endMonth);
1467
- startIO = new IntersectionObserver(ev => ioCallback('start', ev), {
1468
- threshold,
1469
- root: calendarBodyRef,
1470
- rootMargin
1471
- });
1472
- startIO.observe(startMonth);
1473
- this.destroyCalendarIO = () => {
1474
- endIO === null || endIO === void 0 ? void 0 : endIO.disconnect();
1475
- startIO === null || startIO === void 0 ? void 0 : startIO.disconnect();
650
+ let appliediOSRubberBandFix = false;
651
+ const scrollCallback = () => {
652
+ if (scrollTimeout) {
653
+ clearTimeout(scrollTimeout);
654
+ }
655
+ /**
656
+ * On iOS it is possible to quickly rubber band
657
+ * the scroll area before the scroll timeout has fired.
658
+ * This results in users reaching the end of the scrollable
659
+ * container before the DOM has updated.
660
+ * By setting `pointer-events: none` we can ensure that
661
+ * subsequent swipes do not happen while the container
662
+ * is snapping.
663
+ */
664
+ if (!appliediOSRubberBandFix && needsiOSRubberBandFix) {
665
+ calendarBodyRef.style.setProperty('pointer-events', 'none');
666
+ appliediOSRubberBandFix = true;
667
+ }
668
+ // Wait ~3 frames
669
+ scrollTimeout = setTimeout(updateActiveMonth, 50);
670
+ };
671
+ calendarBodyRef.addEventListener('scroll', scrollCallback);
672
+ this.destroyCalendarListener = () => {
673
+ calendarBodyRef.removeEventListener('scroll', scrollCallback);
1476
674
  };
1477
675
  });
1478
676
  };
@@ -1482,55 +680,54 @@ const Datetime = class {
1482
680
  * if the datetime has been hidden/presented by a modal or popover.
1483
681
  */
1484
682
  this.destroyInteractionListeners = () => {
1485
- const { destroyCalendarIO, destroyKeyboardMO } = this;
1486
- if (destroyCalendarIO !== undefined) {
1487
- destroyCalendarIO();
683
+ const { destroyCalendarListener, destroyKeyboardMO } = this;
684
+ if (destroyCalendarListener !== undefined) {
685
+ destroyCalendarListener();
1488
686
  }
1489
687
  if (destroyKeyboardMO !== undefined) {
1490
688
  destroyKeyboardMO();
1491
689
  }
1492
690
  };
1493
- /**
1494
- * When doing subsequent presentations of an inline
1495
- * overlay, the IO callback will fire again causing
1496
- * the calendar to go back one month. We need to listen
1497
- * for the presentation of the overlay so we can properly
1498
- * cancel that IO callback.
1499
- */
1500
- this.initializeOverlayListener = () => {
1501
- const overlay = this.el.closest('ion-popover, ion-modal');
1502
- if (overlay === null) {
1503
- return;
1504
- }
1505
- const overlayListener = () => {
1506
- this.overlayIsPresenting = true;
1507
- };
1508
- overlay.addEventListener('willPresent', overlayListener);
1509
- this.destroyOverlayListener = () => {
1510
- overlay.removeEventListener('willPresent', overlayListener);
1511
- };
1512
- };
1513
691
  this.processValue = (value) => {
1514
- const valueToProcess = value || getToday();
1515
- const { month, day, year, hour, minute, tzOffset } = parseDate(valueToProcess);
1516
- this.workingParts = {
1517
- month,
1518
- day,
1519
- year,
1520
- hour,
1521
- minute,
1522
- tzOffset,
1523
- ampm: hour >= 12 ? 'pm' : 'am'
1524
- };
1525
- this.activeParts = {
692
+ this.highlightActiveParts = !!value;
693
+ let valueToProcess = parseDate(value || getToday());
694
+ const { minParts, maxParts, multiple } = this;
695
+ if (!multiple && Array.isArray(value)) {
696
+ this.value = value[0];
697
+ valueToProcess = valueToProcess[0];
698
+ }
699
+ warnIfValueOutOfBounds(valueToProcess, minParts, maxParts);
700
+ /**
701
+ * If there are multiple values, pick an arbitrary one to clamp to. This way,
702
+ * if the values are across months, we always show at least one of them. Note
703
+ * that the values don't necessarily have to be in order.
704
+ */
705
+ const singleValue = Array.isArray(valueToProcess) ? valueToProcess[0] : valueToProcess;
706
+ const { month, day, year, hour, minute, tzOffset } = clampDate(singleValue, minParts, maxParts);
707
+ const ampm = parseAmPm(hour);
708
+ this.setWorkingParts({
1526
709
  month,
1527
710
  day,
1528
711
  year,
1529
712
  hour,
1530
713
  minute,
1531
714
  tzOffset,
1532
- ampm: hour >= 12 ? 'pm' : 'am'
1533
- };
715
+ ampm,
716
+ });
717
+ if (Array.isArray(valueToProcess)) {
718
+ this.activeParts = [...valueToProcess];
719
+ }
720
+ else {
721
+ this.activeParts = {
722
+ month,
723
+ day,
724
+ year,
725
+ hour,
726
+ minute,
727
+ tzOffset,
728
+ ampm,
729
+ };
730
+ }
1534
731
  };
1535
732
  this.onFocus = () => {
1536
733
  this.ionFocus.emit();
@@ -1554,7 +751,7 @@ const Datetime = class {
1554
751
  calendarBodyRef.scrollTo({
1555
752
  top: 0,
1556
753
  left: left * (isRTL(this.el) ? -1 : 1),
1557
- behavior: 'smooth'
754
+ behavior: 'smooth',
1558
755
  });
1559
756
  };
1560
757
  this.prevMonth = () => {
@@ -1569,7 +766,7 @@ const Datetime = class {
1569
766
  calendarBodyRef.scrollTo({
1570
767
  top: 0,
1571
768
  left: 0,
1572
- behavior: 'smooth'
769
+ behavior: 'smooth',
1573
770
  });
1574
771
  };
1575
772
  this.toggleMonthAndYearView = () => {
@@ -1607,7 +804,12 @@ const Datetime = class {
1607
804
  * Update the datetime value when the value changes
1608
805
  */
1609
806
  valueChanged() {
807
+ const { value, minParts, maxParts, workingParts, multiple } = this;
1610
808
  if (this.hasValue()) {
809
+ if (!multiple && Array.isArray(value)) {
810
+ this.value = value[0];
811
+ return; // setting this.value will trigger re-run of this function
812
+ }
1611
813
  /**
1612
814
  * Clones the value of the `activeParts` to the private clone, to update
1613
815
  * the date display on the current render cycle without causing another render.
@@ -1615,17 +817,37 @@ const Datetime = class {
1615
817
  * This allows us to update the current value's date/time display without
1616
818
  * refocusing or shifting the user's display (leaves the user in place).
1617
819
  */
1618
- const { month, day, year, hour, minute } = parseDate(this.value);
1619
- this.activePartsClone = Object.assign(Object.assign({}, this.activeParts), { month,
1620
- day,
1621
- year,
1622
- hour,
1623
- minute });
820
+ const valueDateParts = parseDate(value);
821
+ if (valueDateParts) {
822
+ warnIfValueOutOfBounds(valueDateParts, minParts, maxParts);
823
+ if (Array.isArray(valueDateParts)) {
824
+ this.activePartsClone = [...valueDateParts];
825
+ }
826
+ else {
827
+ const { month, day, year, hour, minute } = valueDateParts;
828
+ const ampm = hour != null ? (hour >= 12 ? 'pm' : 'am') : undefined;
829
+ this.activePartsClone = Object.assign(Object.assign({}, this.activeParts), { month,
830
+ day,
831
+ year,
832
+ hour,
833
+ minute,
834
+ ampm });
835
+ /**
836
+ * The working parts am/pm value must be updated when the value changes, to
837
+ * ensure the time picker hour column values are generated correctly.
838
+ *
839
+ * Note that we don't need to do this if valueDateParts is an array, since
840
+ * multiple="true" does not apply to time pickers.
841
+ */
842
+ this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { ampm }));
843
+ }
844
+ }
845
+ else {
846
+ printIonWarning(`Unable to parse date string: ${value}. Please provide a valid ISO 8601 datetime string.`);
847
+ }
1624
848
  }
1625
849
  this.emitStyle();
1626
- this.ionChange.emit({
1627
- value: this.value
1628
- });
850
+ this.ionChange.emit({ value });
1629
851
  }
1630
852
  /**
1631
853
  * Confirms the selected datetime value, updates the
@@ -1633,18 +855,42 @@ const Datetime = class {
1633
855
  * or modal that the datetime was presented in.
1634
856
  */
1635
857
  async confirm(closeOverlay = false) {
858
+ const { highlightActiveParts, isCalendarPicker, activeParts } = this;
1636
859
  /**
1637
- * Prevent convertDataToISO from doing any
1638
- * kind of transformation based on timezone
1639
- * This cancels out any change it attempts to make
860
+ * We only update the value if the presentation is not a calendar picker,
861
+ * or if `highlightActiveParts` is true; indicating that the user
862
+ * has selected a date from the calendar picker.
1640
863
  *
1641
- * Important: Take the timezone offset based on
1642
- * the date that is currently selected, otherwise
1643
- * there can be 1 hr difference when dealing w/ DST
864
+ * Otherwise "today" would accidentally be set as the value.
1644
865
  */
1645
- const date = new Date(convertDataToISO(this.activeParts));
1646
- this.activeParts.tzOffset = date.getTimezoneOffset() * -1;
1647
- this.value = convertDataToISO(this.activeParts);
866
+ if (highlightActiveParts || !isCalendarPicker) {
867
+ const activePartsIsArray = Array.isArray(activeParts);
868
+ if (activePartsIsArray && activeParts.length === 0) {
869
+ this.value = undefined;
870
+ }
871
+ else {
872
+ /**
873
+ * Prevent convertDataToISO from doing any
874
+ * kind of transformation based on timezone
875
+ * This cancels out any change it attempts to make
876
+ *
877
+ * Important: Take the timezone offset based on
878
+ * the date that is currently selected, otherwise
879
+ * there can be 1 hr difference when dealing w/ DST
880
+ */
881
+ if (activePartsIsArray) {
882
+ const dates = convertDataToISO(activeParts).map((str) => new Date(str));
883
+ for (let i = 0; i < dates.length; i++) {
884
+ activeParts[i].tzOffset = dates[i].getTimezoneOffset() * -1;
885
+ }
886
+ }
887
+ else {
888
+ const date = new Date(convertDataToISO(activeParts));
889
+ activeParts.tzOffset = date.getTimezoneOffset() * -1;
890
+ }
891
+ this.value = convertDataToISO(activeParts);
892
+ }
893
+ }
1648
894
  if (closeOverlay) {
1649
895
  this.closeParentOverlay();
1650
896
  }
@@ -1652,7 +898,7 @@ const Datetime = class {
1652
898
  /**
1653
899
  * Resets the internal state of the datetime but does not update the value.
1654
900
  * Passing a valid ISO-8601 string will reset the state of the component to the provided date.
1655
- * If no value is provided, the internal state will be reset to today.
901
+ * If no value is provided, the internal state will be reset to the clamped value of the min, max and today.
1656
902
  */
1657
903
  async reset(startDate) {
1658
904
  this.processValue(startDate);
@@ -1669,6 +915,10 @@ const Datetime = class {
1669
915
  this.closeParentOverlay();
1670
916
  }
1671
917
  }
918
+ get isCalendarPicker() {
919
+ const { presentation } = this;
920
+ return presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
921
+ }
1672
922
  connectedCallback() {
1673
923
  this.clearFocusVisible = startFocusVisible(this.el).destroy;
1674
924
  }
@@ -1679,9 +929,8 @@ const Datetime = class {
1679
929
  }
1680
930
  }
1681
931
  initializeListeners() {
1682
- this.initializeCalendarIOListeners();
932
+ this.initializeCalendarListener();
1683
933
  this.initializeKeyboardListeners();
1684
- this.initializeOverlayListener();
1685
934
  }
1686
935
  componentDidLoad() {
1687
936
  /**
@@ -1691,7 +940,6 @@ const Datetime = class {
1691
940
  * visible if used inside of a modal or a popover otherwise the scrollable
1692
941
  * areas will not have the correct values snapped into place.
1693
942
  */
1694
- let visibleIO;
1695
943
  const visibleCallback = (entries) => {
1696
944
  const ev = entries[0];
1697
945
  if (!ev.isIntersecting) {
@@ -1710,7 +958,7 @@ const Datetime = class {
1710
958
  this.el.classList.add('datetime-ready');
1711
959
  });
1712
960
  };
1713
- visibleIO = new IntersectionObserver(visibleCallback, { threshold: 0.01 });
961
+ const visibleIO = new IntersectionObserver(visibleCallback, { threshold: 0.01 });
1714
962
  /**
1715
963
  * Use raf to avoid a race condition between the component loading and
1716
964
  * its display animation starting (such as when shown in a modal). This
@@ -1725,7 +973,6 @@ const Datetime = class {
1725
973
  * the scroll areas have scroll widths/heights of 0px, so any snapping
1726
974
  * we did originally has been lost.
1727
975
  */
1728
- let hiddenIO;
1729
976
  const hiddenCallback = (entries) => {
1730
977
  const ev = entries[0];
1731
978
  if (ev.isIntersecting) {
@@ -1736,7 +983,7 @@ const Datetime = class {
1736
983
  this.el.classList.remove('datetime-ready');
1737
984
  });
1738
985
  };
1739
- hiddenIO = new IntersectionObserver(hiddenCallback, { threshold: 0 });
986
+ const hiddenIO = new IntersectionObserver(hiddenCallback, { threshold: 0 });
1740
987
  raf(() => hiddenIO === null || hiddenIO === void 0 ? void 0 : hiddenIO.observe(this.el));
1741
988
  /**
1742
989
  * Datetime uses Ionic components that emit
@@ -1766,12 +1013,27 @@ const Datetime = class {
1766
1013
  }
1767
1014
  this.prevPresentation = presentation;
1768
1015
  this.destroyInteractionListeners();
1769
- if (this.destroyOverlayListener !== undefined) {
1770
- this.destroyOverlayListener();
1771
- }
1772
1016
  this.initializeListeners();
1017
+ /**
1018
+ * The month/year picker from the date interface
1019
+ * should be closed as it is not available in non-date
1020
+ * interfaces.
1021
+ */
1022
+ this.showMonthAndYear = false;
1023
+ raf(() => {
1024
+ this.ionRender.emit();
1025
+ });
1773
1026
  }
1774
1027
  componentWillLoad() {
1028
+ const { el, multiple, presentation, preferWheel } = this;
1029
+ if (multiple) {
1030
+ if (presentation !== 'date') {
1031
+ printIonWarning('Multiple date selection is only supported for presentation="date".', el);
1032
+ }
1033
+ if (preferWheel) {
1034
+ printIonWarning('Multiple date selection is not supported with preferWheel="true".', el);
1035
+ }
1036
+ }
1775
1037
  this.processMinParts();
1776
1038
  this.processMaxParts();
1777
1039
  this.processValue(this.value);
@@ -1784,11 +1046,16 @@ const Datetime = class {
1784
1046
  }
1785
1047
  emitStyle() {
1786
1048
  this.ionStyle.emit({
1787
- 'interactive': true,
1788
- 'datetime': true,
1049
+ interactive: true,
1050
+ datetime: true,
1789
1051
  'interactive-disabled': this.disabled,
1790
1052
  });
1791
1053
  }
1054
+ /**
1055
+ * Universal render methods
1056
+ * These are pieces of datetime that
1057
+ * are rendered independently of presentation.
1058
+ */
1792
1059
  renderFooter() {
1793
1060
  const { showDefaultButtons, showClearButton } = this;
1794
1061
  const hasSlottedButtons = this.el.querySelector('[slot="buttons"]') !== null;
@@ -1808,83 +1075,316 @@ const Datetime = class {
1808
1075
  */
1809
1076
  return (h("div", { class: "datetime-footer" }, h("div", { class: "datetime-buttons" }, h("div", { class: {
1810
1077
  ['datetime-action-buttons']: true,
1811
- ['has-clear-button']: this.showClearButton
1812
- } }, h("slot", { name: "buttons" }, h("ion-buttons", null, showDefaultButtons && h("ion-button", { id: "cancel-button", color: this.color, onClick: () => this.cancel(true) }, this.cancelText), h("div", null, showClearButton && h("ion-button", { id: "clear-button", color: this.color, onClick: () => clearButtonClick() }, this.clearText), showDefaultButtons && h("ion-button", { id: "confirm-button", color: this.color, onClick: () => this.confirm(true) }, this.doneText))))))));
1078
+ ['has-clear-button']: this.showClearButton,
1079
+ } }, h("slot", { name: "buttons" }, h("ion-buttons", null, showDefaultButtons && (h("ion-button", { id: "cancel-button", color: this.color, onClick: () => this.cancel(true) }, this.cancelText)), h("div", null, showClearButton && (h("ion-button", { id: "clear-button", color: this.color, onClick: () => clearButtonClick() }, this.clearText)), showDefaultButtons && (h("ion-button", { id: "confirm-button", color: this.color, onClick: () => this.confirm(true) }, this.doneText)))))))));
1813
1080
  }
1814
- renderYearView() {
1815
- const { presentation, workingParts, locale } = this;
1816
- const calendarYears = getCalendarYears(this.todayParts, this.minParts, this.maxParts, this.parsedYearValues);
1817
- const showMonth = presentation !== 'year';
1818
- const showYear = presentation !== 'month';
1819
- const months = getPickerMonths(locale, workingParts, this.minParts, this.maxParts, this.parsedMonthValues);
1820
- const years = calendarYears.map(year => {
1821
- return {
1822
- text: `${year}`,
1823
- value: year
1824
- };
1825
- });
1081
+ /**
1082
+ * Wheel picker render methods
1083
+ */
1084
+ renderWheelPicker(forcePresentation = this.presentation) {
1085
+ /**
1086
+ * If presentation="time-date" we switch the
1087
+ * order of the render array here instead of
1088
+ * manually reordering each date/time picker
1089
+ * column with CSS. This allows for additional
1090
+ * flexibility if we need to render subsets
1091
+ * of the date/time data or do additional ordering
1092
+ * within the child render functions.
1093
+ */
1094
+ const renderArray = forcePresentation === 'time-date'
1095
+ ? [this.renderTimePickerColumns(forcePresentation), this.renderDatePickerColumns(forcePresentation)]
1096
+ : [this.renderDatePickerColumns(forcePresentation), this.renderTimePickerColumns(forcePresentation)];
1097
+ return h("ion-picker-internal", null, renderArray);
1098
+ }
1099
+ renderDatePickerColumns(forcePresentation) {
1100
+ return forcePresentation === 'date-time' || forcePresentation === 'time-date'
1101
+ ? this.renderCombinedDatePickerColumn()
1102
+ : this.renderIndividualDatePickerColumns(forcePresentation);
1103
+ }
1104
+ renderCombinedDatePickerColumn() {
1105
+ const { activeParts, workingParts, locale, minParts, maxParts, todayParts, isDateEnabled } = this;
1106
+ /**
1107
+ * By default, generate a range of 3 months:
1108
+ * Previous month, current month, and next month
1109
+ */
1110
+ const monthsToRender = generateMonths(workingParts);
1111
+ /**
1112
+ * generateMonths returns the day data as well,
1113
+ * but we do not want the day value to act as a max/min
1114
+ * on the data we are going to generate.
1115
+ */
1116
+ for (let i = 0; i <= monthsToRender.length - 1; i++) {
1117
+ monthsToRender[i].day = null;
1118
+ }
1119
+ /**
1120
+ * If developers have provided their own
1121
+ * min/max values, use that instead. Otherwise,
1122
+ * fallback to the default range of 3 months.
1123
+ */
1124
+ const min = minParts || monthsToRender[0];
1125
+ const max = maxParts || monthsToRender[monthsToRender.length - 1];
1126
+ const result = getCombinedDateColumnData(locale, workingParts, todayParts, min, max, this.parsedDayValues, this.parsedMonthValues);
1127
+ let items = result.items;
1128
+ const parts = result.parts;
1129
+ if (isDateEnabled) {
1130
+ items = items.map((itemObject, index) => {
1131
+ const referenceParts = parts[index];
1132
+ let disabled;
1133
+ try {
1134
+ /**
1135
+ * The `isDateEnabled` implementation is try-catch wrapped
1136
+ * to prevent exceptions in the user's function from
1137
+ * interrupting the calendar rendering.
1138
+ */
1139
+ disabled = !isDateEnabled(convertDataToISO(referenceParts));
1140
+ }
1141
+ catch (e) {
1142
+ printIonError('Exception thrown from provided `isDateEnabled` function. Please check your function and try again.', e);
1143
+ }
1144
+ return Object.assign(Object.assign({}, itemObject), { disabled });
1145
+ });
1146
+ }
1147
+ /**
1148
+ * If we have selected a day already, then default the column
1149
+ * to that value. Otherwise, default it to today.
1150
+ */
1151
+ const todayString = workingParts.day
1152
+ ? `${workingParts.year}-${workingParts.month}-${workingParts.day}`
1153
+ : `${todayParts.year}-${todayParts.month}-${todayParts.day}`;
1154
+ return (h("ion-picker-column-internal", { class: "date-column", color: this.color, items: items, value: todayString, onIonChange: (ev) => {
1155
+ // TODO(FW-1823) Remove this when iOS 14 support is dropped.
1156
+ // Due to a Safari 14 issue we need to destroy
1157
+ // the scroll listener before we update state
1158
+ // and trigger a re-render.
1159
+ if (this.destroyCalendarListener) {
1160
+ this.destroyCalendarListener();
1161
+ }
1162
+ const { value } = ev.detail;
1163
+ const findPart = parts.find(({ month, day, year }) => value === `${year}-${month}-${day}`);
1164
+ this.setWorkingParts(Object.assign(Object.assign({}, workingParts), findPart));
1165
+ if (!Array.isArray(activeParts)) {
1166
+ this.setActiveParts(Object.assign(Object.assign({}, activeParts), findPart));
1167
+ }
1168
+ // We can re-attach the scroll listener after
1169
+ // the working parts have been updated.
1170
+ this.initializeCalendarListener();
1171
+ ev.stopPropagation();
1172
+ } }));
1173
+ }
1174
+ renderIndividualDatePickerColumns(forcePresentation) {
1175
+ const { workingParts, isDateEnabled } = this;
1176
+ const shouldRenderMonths = forcePresentation !== 'year' && forcePresentation !== 'time';
1177
+ const months = shouldRenderMonths
1178
+ ? getMonthColumnData(this.locale, workingParts, this.minParts, this.maxParts, this.parsedMonthValues)
1179
+ : [];
1180
+ const shouldRenderDays = forcePresentation === 'date';
1181
+ let days = shouldRenderDays
1182
+ ? getDayColumnData(this.locale, workingParts, this.minParts, this.maxParts, this.parsedDayValues)
1183
+ : [];
1184
+ if (isDateEnabled) {
1185
+ days = days.map((dayObject) => {
1186
+ const { value } = dayObject;
1187
+ const valueNum = typeof value === 'string' ? parseInt(value) : value;
1188
+ const referenceParts = {
1189
+ month: workingParts.month,
1190
+ day: valueNum,
1191
+ year: workingParts.year,
1192
+ };
1193
+ let disabled;
1194
+ try {
1195
+ /**
1196
+ * The `isDateEnabled` implementation is try-catch wrapped
1197
+ * to prevent exceptions in the user's function from
1198
+ * interrupting the calendar rendering.
1199
+ */
1200
+ disabled = !isDateEnabled(convertDataToISO(referenceParts));
1201
+ }
1202
+ catch (e) {
1203
+ printIonError('Exception thrown from provided `isDateEnabled` function. Please check your function and try again.', e);
1204
+ }
1205
+ return Object.assign(Object.assign({}, dayObject), { disabled });
1206
+ });
1207
+ }
1208
+ const shouldRenderYears = forcePresentation !== 'month' && forcePresentation !== 'time';
1209
+ const years = shouldRenderYears
1210
+ ? getYearColumnData(this.todayParts, this.minParts, this.maxParts, this.parsedYearValues)
1211
+ : [];
1212
+ /**
1213
+ * Certain locales show the day before the month.
1214
+ */
1215
+ const showMonthFirst = isMonthFirstLocale(this.locale, { month: 'numeric', day: 'numeric' });
1216
+ let renderArray = [];
1217
+ if (showMonthFirst) {
1218
+ renderArray = [
1219
+ this.renderMonthPickerColumn(months),
1220
+ this.renderDayPickerColumn(days),
1221
+ this.renderYearPickerColumn(years),
1222
+ ];
1223
+ }
1224
+ else {
1225
+ renderArray = [
1226
+ this.renderDayPickerColumn(days),
1227
+ this.renderMonthPickerColumn(months),
1228
+ this.renderYearPickerColumn(years),
1229
+ ];
1230
+ }
1231
+ return renderArray;
1232
+ }
1233
+ renderDayPickerColumn(days) {
1234
+ var _a;
1235
+ if (days.length === 0) {
1236
+ return [];
1237
+ }
1238
+ const { activeParts, workingParts } = this;
1239
+ return (h("ion-picker-column-internal", { class: "day-column", color: this.color, items: days, value: (_a = (workingParts.day || this.todayParts.day)) !== null && _a !== void 0 ? _a : undefined, onIonChange: (ev) => {
1240
+ // TODO(FW-1823) Remove this when iOS 14 support is dropped.
1241
+ // Due to a Safari 14 issue we need to destroy
1242
+ // the scroll listener before we update state
1243
+ // and trigger a re-render.
1244
+ if (this.destroyCalendarListener) {
1245
+ this.destroyCalendarListener();
1246
+ }
1247
+ this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { day: ev.detail.value }));
1248
+ if (!Array.isArray(activeParts)) {
1249
+ this.setActiveParts(Object.assign(Object.assign({}, activeParts), { day: ev.detail.value }));
1250
+ }
1251
+ // We can re-attach the scroll listener after
1252
+ // the working parts have been updated.
1253
+ this.initializeCalendarListener();
1254
+ ev.stopPropagation();
1255
+ } }));
1256
+ }
1257
+ renderMonthPickerColumn(months) {
1258
+ if (months.length === 0) {
1259
+ return [];
1260
+ }
1261
+ const { activeParts, workingParts } = this;
1262
+ return (h("ion-picker-column-internal", { class: "month-column", color: this.color, items: months, value: workingParts.month, onIonChange: (ev) => {
1263
+ // TODO(FW-1823) Remove this when iOS 14 support is dropped.
1264
+ // Due to a Safari 14 issue we need to destroy
1265
+ // the scroll listener before we update state
1266
+ // and trigger a re-render.
1267
+ if (this.destroyCalendarListener) {
1268
+ this.destroyCalendarListener();
1269
+ }
1270
+ this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { month: ev.detail.value }));
1271
+ if (!Array.isArray(activeParts)) {
1272
+ this.setActiveParts(Object.assign(Object.assign({}, activeParts), { month: ev.detail.value }));
1273
+ }
1274
+ // We can re-attach the scroll listener after
1275
+ // the working parts have been updated.
1276
+ this.initializeCalendarListener();
1277
+ ev.stopPropagation();
1278
+ } }));
1279
+ }
1280
+ renderYearPickerColumn(years) {
1281
+ if (years.length === 0) {
1282
+ return [];
1283
+ }
1284
+ const { activeParts, workingParts } = this;
1285
+ return (h("ion-picker-column-internal", { class: "year-column", color: this.color, items: years, value: workingParts.year, onIonChange: (ev) => {
1286
+ // TODO(FW-1823) Remove this when iOS 14 support is dropped.
1287
+ // Due to a Safari 14 issue we need to destroy
1288
+ // the scroll listener before we update state
1289
+ // and trigger a re-render.
1290
+ if (this.destroyCalendarListener) {
1291
+ this.destroyCalendarListener();
1292
+ }
1293
+ this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { year: ev.detail.value }));
1294
+ if (!Array.isArray(activeParts)) {
1295
+ this.setActiveParts(Object.assign(Object.assign({}, activeParts), { year: ev.detail.value }));
1296
+ }
1297
+ // We can re-attach the scroll listener after
1298
+ // the working parts have been updated.
1299
+ this.initializeCalendarListener();
1300
+ ev.stopPropagation();
1301
+ } }));
1302
+ }
1303
+ renderTimePickerColumns(forcePresentation) {
1304
+ if (['date', 'month', 'month-year', 'year'].includes(forcePresentation)) {
1305
+ return [];
1306
+ }
1307
+ const { hoursData, minutesData, dayPeriodData } = getTimeColumnsData(this.locale, this.workingParts, this.hourCycle, this.value ? this.minParts : undefined, this.value ? this.maxParts : undefined, this.parsedHourValues, this.parsedMinuteValues);
1308
+ return [
1309
+ this.renderHourPickerColumn(hoursData),
1310
+ this.renderMinutePickerColumn(minutesData),
1311
+ this.renderDayPeriodPickerColumn(dayPeriodData),
1312
+ ];
1313
+ }
1314
+ renderHourPickerColumn(hoursData) {
1315
+ const { workingParts, activePartsClone } = this;
1316
+ if (hoursData.length === 0)
1317
+ return [];
1318
+ return (h("ion-picker-column-internal", { color: this.color, value: activePartsClone.hour, items: hoursData, numericInput: true, onIonChange: (ev) => {
1319
+ this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { hour: ev.detail.value }));
1320
+ if (!Array.isArray(activePartsClone)) {
1321
+ this.setActiveParts(Object.assign(Object.assign({}, activePartsClone), { hour: ev.detail.value }));
1322
+ }
1323
+ ev.stopPropagation();
1324
+ } }));
1325
+ }
1326
+ renderMinutePickerColumn(minutesData) {
1327
+ const { workingParts, activePartsClone } = this;
1328
+ if (minutesData.length === 0)
1329
+ return [];
1330
+ return (h("ion-picker-column-internal", { color: this.color, value: activePartsClone.minute, items: minutesData, numericInput: true, onIonChange: (ev) => {
1331
+ this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { minute: ev.detail.value }));
1332
+ if (!Array.isArray(activePartsClone)) {
1333
+ this.setActiveParts(Object.assign(Object.assign({}, activePartsClone), { minute: ev.detail.value }));
1334
+ }
1335
+ ev.stopPropagation();
1336
+ } }));
1337
+ }
1338
+ renderDayPeriodPickerColumn(dayPeriodData) {
1339
+ const { workingParts, activePartsClone } = this;
1340
+ if (dayPeriodData.length === 0) {
1341
+ return [];
1342
+ }
1343
+ const isDayPeriodRTL = isLocaleDayPeriodRTL(this.locale);
1344
+ return (h("ion-picker-column-internal", { style: isDayPeriodRTL ? { order: '-1' } : {}, color: this.color, value: activePartsClone.ampm, items: dayPeriodData, onIonChange: (ev) => {
1345
+ const hour = calculateHourFromAMPM(workingParts, ev.detail.value);
1346
+ this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { ampm: ev.detail.value, hour }));
1347
+ if (!Array.isArray(activePartsClone)) {
1348
+ this.setActiveParts(Object.assign(Object.assign({}, activePartsClone), { ampm: ev.detail.value, hour }));
1349
+ }
1350
+ ev.stopPropagation();
1351
+ } }));
1352
+ }
1353
+ renderWheelView(forcePresentation) {
1354
+ const { locale } = this;
1826
1355
  const showMonthFirst = isMonthFirstLocale(locale);
1827
1356
  const columnOrder = showMonthFirst ? 'month-first' : 'year-first';
1828
- return (h("div", { class: "datetime-year" }, h("div", { class: {
1829
- 'datetime-year-body': true,
1830
- [`order-${columnOrder}`]: true
1831
- } }, h("ion-picker-internal", null, showMonth &&
1832
- h("ion-picker-column-internal", { class: "month-column", color: this.color, items: months, value: workingParts.month, onIonChange: (ev) => {
1833
- // Due to a Safari 14 issue we need to destroy
1834
- // the intersection observer before we update state
1835
- // and trigger a re-render.
1836
- if (this.destroyCalendarIO) {
1837
- this.destroyCalendarIO();
1838
- }
1839
- this.setWorkingParts(Object.assign(Object.assign({}, this.workingParts), { month: ev.detail.value }));
1840
- if (presentation === 'month' || presentation === 'month-year') {
1841
- this.setActiveParts(Object.assign(Object.assign({}, this.activeParts), { month: ev.detail.value }));
1842
- }
1843
- // We can re-attach the intersection observer after
1844
- // the working parts have been updated.
1845
- this.initializeCalendarIOListeners();
1846
- ev.stopPropagation();
1847
- } }), showYear &&
1848
- h("ion-picker-column-internal", { class: "year-column", color: this.color, items: years, value: workingParts.year, onIonChange: (ev) => {
1849
- // Due to a Safari 14 issue we need to destroy
1850
- // the intersection observer before we update state
1851
- // and trigger a re-render.
1852
- if (this.destroyCalendarIO) {
1853
- this.destroyCalendarIO();
1854
- }
1855
- this.setWorkingParts(Object.assign(Object.assign({}, this.workingParts), { year: ev.detail.value }));
1856
- if (presentation === 'year' || presentation === 'month-year') {
1857
- this.setActiveParts(Object.assign(Object.assign({}, this.activeParts), { year: ev.detail.value }));
1858
- }
1859
- // We can re-attach the intersection observer after
1860
- // the working parts have been updated.
1861
- this.initializeCalendarIOListeners();
1862
- ev.stopPropagation();
1863
- } })))));
1357
+ return (h("div", { class: {
1358
+ [`wheel-order-${columnOrder}`]: true,
1359
+ } }, this.renderWheelPicker(forcePresentation)));
1864
1360
  }
1361
+ /**
1362
+ * Grid Render Methods
1363
+ */
1865
1364
  renderCalendarHeader(mode) {
1866
1365
  const expandedIcon = mode === 'ios' ? chevronDown : caretUpSharp;
1867
1366
  const collapsedIcon = mode === 'ios' ? chevronForward : caretDownSharp;
1868
1367
  const prevMonthDisabled = isPrevMonthDisabled(this.workingParts, this.minParts, this.maxParts);
1869
1368
  const nextMonthDisabled = isNextMonthDisabled(this.workingParts, this.maxParts);
1870
- return (h("div", { class: "calendar-header" }, h("div", { class: "calendar-action-buttons" }, h("div", { class: "calendar-month-year" }, h("ion-item", { button: true, detail: false, lines: "none", onClick: () => this.toggleMonthAndYearView() }, h("ion-label", null, getMonthAndYear(this.locale, this.workingParts), " ", h("ion-icon", { icon: this.showMonthAndYear ? expandedIcon : collapsedIcon, lazy: false })))), h("div", { class: "calendar-next-prev" }, h("ion-buttons", null, h("ion-button", { disabled: prevMonthDisabled, onClick: () => this.prevMonth() }, h("ion-icon", { slot: "icon-only", icon: chevronBack, lazy: false, flipRtl: true })), h("ion-button", { disabled: nextMonthDisabled, onClick: () => this.nextMonth() }, h("ion-icon", { slot: "icon-only", icon: chevronForward, lazy: false, flipRtl: true }))))), h("div", { class: "calendar-days-of-week" }, getDaysOfWeek(this.locale, mode, this.firstDayOfWeek % 7).map(d => {
1369
+ return (h("div", { class: "calendar-header" }, h("div", { class: "calendar-action-buttons" }, h("div", { class: "calendar-month-year" }, h("ion-item", { button: true, detail: false, lines: "none", onClick: () => this.toggleMonthAndYearView() }, h("ion-label", null, getMonthAndYear(this.locale, this.workingParts), ' ', h("ion-icon", { icon: this.showMonthAndYear ? expandedIcon : collapsedIcon, lazy: false })))), h("div", { class: "calendar-next-prev" }, h("ion-buttons", null, h("ion-button", { disabled: prevMonthDisabled, onClick: () => this.prevMonth() }, h("ion-icon", { slot: "icon-only", icon: chevronBack, lazy: false, flipRtl: true })), h("ion-button", { disabled: nextMonthDisabled, onClick: () => this.nextMonth() }, h("ion-icon", { slot: "icon-only", icon: chevronForward, lazy: false, flipRtl: true }))))), h("div", { class: "calendar-days-of-week" }, getDaysOfWeek(this.locale, mode, this.firstDayOfWeek % 7).map((d) => {
1871
1370
  return h("div", { class: "day-of-week" }, d);
1872
1371
  }))));
1873
1372
  }
1874
1373
  renderMonth(month, year) {
1374
+ const { highlightActiveParts } = this;
1875
1375
  const yearAllowed = this.parsedYearValues === undefined || this.parsedYearValues.includes(year);
1876
1376
  const monthAllowed = this.parsedMonthValues === undefined || this.parsedMonthValues.includes(month);
1877
1377
  const isCalMonthDisabled = !yearAllowed || !monthAllowed;
1878
1378
  const swipeDisabled = isMonthDisabled({
1879
1379
  month,
1880
1380
  year,
1881
- day: null
1381
+ day: null,
1882
1382
  }, {
1883
1383
  // The day is not used when checking if a month is disabled.
1884
1384
  // Users should be able to access the min or max month, even if the
1885
1385
  // min/max date is out of bounds (e.g. min is set to Feb 15, Feb should not be disabled).
1886
1386
  minParts: Object.assign(Object.assign({}, this.minParts), { day: null }),
1887
- maxParts: Object.assign(Object.assign({}, this.maxParts), { day: null })
1387
+ maxParts: Object.assign(Object.assign({}, this.maxParts), { day: null }),
1888
1388
  });
1889
1389
  // The working month should never have swipe disabled.
1890
1390
  // Otherwise the CSS scroll snap will not work and the user
@@ -1893,16 +1393,31 @@ const Datetime = class {
1893
1393
  return (h("div", { class: {
1894
1394
  'calendar-month': true,
1895
1395
  // Prevents scroll snap swipe gestures for months outside of the min/max bounds
1896
- 'calendar-month-disabled': !isWorkingMonth && swipeDisabled
1396
+ 'calendar-month-disabled': !isWorkingMonth && swipeDisabled,
1897
1397
  } }, h("div", { class: "calendar-month-grid" }, getDaysOfMonth(month, year, this.firstDayOfWeek % 7).map((dateObject, index) => {
1898
1398
  const { day, dayOfWeek } = dateObject;
1399
+ const { isDateEnabled, multiple } = this;
1899
1400
  const referenceParts = { month, day, year };
1900
1401
  const { isActive, isToday, ariaLabel, ariaSelected, disabled } = getCalendarDayState(this.locale, referenceParts, this.activePartsClone, this.todayParts, this.minParts, this.maxParts, this.parsedDayValues);
1901
- return (h("button", { tabindex: "-1", "data-day": day, "data-month": month, "data-year": year, "data-index": index, "data-day-of-week": dayOfWeek, disabled: isCalMonthDisabled || disabled, class: {
1402
+ let isCalDayDisabled = isCalMonthDisabled || disabled;
1403
+ if (!isCalDayDisabled && isDateEnabled !== undefined) {
1404
+ try {
1405
+ /**
1406
+ * The `isDateEnabled` implementation is try-catch wrapped
1407
+ * to prevent exceptions in the user's function from
1408
+ * interrupting the calendar rendering.
1409
+ */
1410
+ isCalDayDisabled = !isDateEnabled(convertDataToISO(referenceParts));
1411
+ }
1412
+ catch (e) {
1413
+ printIonError('Exception thrown from provided `isDateEnabled` function. Please check your function and try again.', e);
1414
+ }
1415
+ }
1416
+ return (h("button", { tabindex: "-1", "data-day": day, "data-month": month, "data-year": year, "data-index": index, "data-day-of-week": dayOfWeek, disabled: isCalDayDisabled, class: {
1902
1417
  'calendar-day-padding': day === null,
1903
1418
  'calendar-day': true,
1904
- 'calendar-day-active': isActive,
1905
- 'calendar-day-today': isToday
1419
+ 'calendar-day-active': isActive && highlightActiveParts,
1420
+ 'calendar-day-today': isToday,
1906
1421
  }, "aria-selected": ariaSelected, "aria-label": ariaLabel, onClick: () => {
1907
1422
  if (day === null) {
1908
1423
  return;
@@ -1910,14 +1425,24 @@ const Datetime = class {
1910
1425
  this.setWorkingParts(Object.assign(Object.assign({}, this.workingParts), { month,
1911
1426
  day,
1912
1427
  year }));
1913
- this.setActiveParts(Object.assign(Object.assign({}, this.activeParts), { month,
1914
- day,
1915
- year }));
1428
+ // multiple only needs date info, so we can wipe out other fields like time
1429
+ if (multiple) {
1430
+ this.setActiveParts({
1431
+ month,
1432
+ day,
1433
+ year,
1434
+ }, isActive && highlightActiveParts);
1435
+ }
1436
+ else {
1437
+ this.setActiveParts(Object.assign(Object.assign({}, this.activeParts), { month,
1438
+ day,
1439
+ year }));
1440
+ }
1916
1441
  } }, day));
1917
1442
  }))));
1918
1443
  }
1919
1444
  renderCalendarBody() {
1920
- return (h("div", { class: "calendar-body ion-focusable", ref: el => this.calendarBodyRef = el, tabindex: "0" }, generateMonths(this.workingParts).map(({ month, year }) => {
1445
+ return (h("div", { class: "calendar-body ion-focusable", ref: (el) => (this.calendarBodyRef = el), tabindex: "0" }, generateMonths(this.workingParts).map(({ month, year }) => {
1921
1446
  return this.renderMonth(month, year);
1922
1447
  })));
1923
1448
  }
@@ -1929,45 +1454,29 @@ const Datetime = class {
1929
1454
  if (!hasSlottedTimeLabel && !this.showDefaultTimeLabel) {
1930
1455
  return;
1931
1456
  }
1932
- return (h("slot", { name: "time-label" }, "Time"));
1457
+ return h("slot", { name: "time-label" }, "Time");
1933
1458
  }
1934
- renderTimePicker(hoursItems, minutesItems, ampmItems, use24Hour) {
1935
- const { color, activePartsClone, workingParts } = this;
1936
- return (h("ion-picker-internal", null, h("ion-picker-column-internal", { color: color, value: activePartsClone.hour, items: hoursItems, numericInput: true, onIonChange: (ev) => {
1937
- this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { hour: ev.detail.value }));
1938
- this.setActiveParts(Object.assign(Object.assign({}, activePartsClone), { hour: ev.detail.value }));
1939
- ev.stopPropagation();
1940
- } }), h("ion-picker-column-internal", { color: color, value: activePartsClone.minute, items: minutesItems, numericInput: true, onIonChange: (ev) => {
1941
- this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { minute: ev.detail.value }));
1942
- this.setActiveParts(Object.assign(Object.assign({}, activePartsClone), { minute: ev.detail.value }));
1943
- ev.stopPropagation();
1944
- } }), !use24Hour && h("ion-picker-column-internal", { color: color, value: activePartsClone.ampm, items: ampmItems, onIonChange: (ev) => {
1945
- const hour = calculateHourFromAMPM(workingParts, ev.detail.value);
1946
- this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { ampm: ev.detail.value, hour }));
1947
- this.setActiveParts(Object.assign(Object.assign({}, activePartsClone), { ampm: ev.detail.value, hour }));
1948
- ev.stopPropagation();
1949
- } })));
1950
- }
1951
- renderTimeOverlay(hoursItems, minutesItems, ampmItems, use24Hour) {
1459
+ renderTimeOverlay() {
1460
+ const use24Hour = is24Hour(this.locale, this.hourCycle);
1952
1461
  return [
1953
1462
  h("div", { class: "time-header" }, this.renderTimeLabel()),
1954
1463
  h("button", { class: {
1955
1464
  'time-body': true,
1956
- 'time-body-active': this.isTimePopoverOpen
1465
+ 'time-body-active': this.isTimePopoverOpen,
1957
1466
  }, "aria-expanded": "false", "aria-haspopup": "true", onClick: async (ev) => {
1958
1467
  const { popoverRef } = this;
1959
1468
  if (popoverRef) {
1960
1469
  this.isTimePopoverOpen = true;
1961
1470
  popoverRef.present(new CustomEvent('ionShadowTarget', {
1962
1471
  detail: {
1963
- ionShadowTarget: ev.target
1964
- }
1472
+ ionShadowTarget: ev.target,
1473
+ },
1965
1474
  }));
1966
1475
  await popoverRef.onWillDismiss();
1967
1476
  this.isTimePopoverOpen = false;
1968
1477
  }
1969
- } }, getFormattedTime(this.activePartsClone, use24Hour)),
1970
- h("ion-popover", { alignment: "center", translucent: true, overlayIndex: 1, arrow: false, onWillPresent: ev => {
1478
+ } }, getLocalizedTime(this.locale, this.activePartsClone, use24Hour)),
1479
+ h("ion-popover", { alignment: "center", translucent: true, overlayIndex: 1, arrow: false, onWillPresent: (ev) => {
1971
1480
  /**
1972
1481
  * Intersection Observers do not consistently fire between Blink and Webkit
1973
1482
  * when toggling the visibility of the popover and trying to scroll the picker
@@ -1978,15 +1487,23 @@ const Datetime = class {
1978
1487
  */
1979
1488
  const cols = ev.target.querySelectorAll('ion-picker-column-internal');
1980
1489
  // TODO (FW-615): Potentially remove this when intersection observers are fixed in picker column
1981
- cols.forEach(col => col.scrollActiveItemIntoView());
1490
+ cols.forEach((col) => col.scrollActiveItemIntoView());
1982
1491
  }, style: {
1983
- '--offset-y': '-10px'
1492
+ '--offset-y': '-10px',
1493
+ '--min-width': 'fit-content',
1984
1494
  },
1985
1495
  // Allow native browser keyboard events to support up/down/home/end key
1986
1496
  // navigation within the time picker.
1987
- keyboardEvents: true, ref: el => this.popoverRef = el }, this.renderTimePicker(hoursItems, minutesItems, ampmItems, use24Hour))
1497
+ keyboardEvents: true, ref: (el) => (this.popoverRef = el) }, this.renderWheelPicker('time')),
1988
1498
  ];
1989
1499
  }
1500
+ renderCalendarViewHeader(mode) {
1501
+ const hasSlottedTitle = this.el.querySelector('[slot="title"]') !== null;
1502
+ if (!hasSlottedTitle && !this.showDefaultTitle) {
1503
+ return;
1504
+ }
1505
+ return (h("div", { class: "datetime-header" }, h("div", { class: "datetime-title" }, h("slot", { name: "title" }, "Select Date")), mode === 'md' && !this.multiple && (h("div", { class: "datetime-selected-date" }, getMonthAndDay(this.locale, this.activeParts)))));
1506
+ }
1990
1507
  /**
1991
1508
  * Render time picker inside of datetime.
1992
1509
  * Do not pass color prop to segment on
@@ -1995,98 +1512,88 @@ const Datetime = class {
1995
1512
  * should just be the default segment.
1996
1513
  */
1997
1514
  renderTime() {
1998
- const { workingParts, presentation } = this;
1515
+ const { presentation } = this;
1999
1516
  const timeOnlyPresentation = presentation === 'time';
2000
- const use24Hour = is24Hour(this.locale, this.hourCycle);
2001
- const { hours, minutes, am, pm } = generateTime(this.workingParts, use24Hour ? 'h23' : 'h12', this.minParts, this.maxParts, this.parsedHourValues, this.parsedMinuteValues);
2002
- const hoursItems = hours.map(hour => {
2003
- return {
2004
- text: getFormattedHour(hour, use24Hour),
2005
- value: getInternalHourValue(hour, use24Hour, workingParts.ampm)
2006
- };
2007
- });
2008
- const minutesItems = minutes.map(minute => {
2009
- return {
2010
- text: addTimePadding(minute),
2011
- value: minute
2012
- };
2013
- });
2014
- const ampmItems = [];
2015
- if (am) {
2016
- ampmItems.push({
2017
- text: 'AM',
2018
- value: 'am'
2019
- });
2020
- }
2021
- if (pm) {
2022
- ampmItems.push({
2023
- text: 'PM',
2024
- value: 'pm'
2025
- });
2026
- }
2027
- return (h("div", { class: "datetime-time" }, timeOnlyPresentation ? this.renderTimePicker(hoursItems, minutesItems, ampmItems, use24Hour) : this.renderTimeOverlay(hoursItems, minutesItems, ampmItems, use24Hour)));
1517
+ return (h("div", { class: "datetime-time" }, timeOnlyPresentation ? this.renderWheelPicker() : this.renderTimeOverlay()));
2028
1518
  }
2029
- renderCalendarViewHeader(mode) {
2030
- const hasSlottedTitle = this.el.querySelector('[slot="title"]') !== null;
2031
- if (!hasSlottedTitle && !this.showDefaultTitle) {
2032
- return;
2033
- }
2034
- return (h("div", { class: "datetime-header" }, h("div", { class: "datetime-title" }, h("slot", { name: "title" }, "Select Date")), mode === 'md' && h("div", { class: "datetime-selected-date" }, getMonthAndDay(this.locale, this.activeParts))));
1519
+ /**
1520
+ * Renders the month/year picker that is
1521
+ * displayed on the calendar grid.
1522
+ * The .datetime-year class has additional
1523
+ * styles that let us show/hide the
1524
+ * picker when the user clicks on the
1525
+ * toggle in the calendar header.
1526
+ */
1527
+ renderCalendarViewMonthYearPicker() {
1528
+ return h("div", { class: "datetime-year" }, this.renderWheelView('month-year'));
2035
1529
  }
1530
+ /**
1531
+ * Render entry point
1532
+ * All presentation types are rendered from here.
1533
+ */
2036
1534
  renderDatetime(mode) {
2037
- const { presentation } = this;
1535
+ const { presentation, preferWheel } = this;
1536
+ /**
1537
+ * Certain presentation types have separate grid and wheel displays.
1538
+ * If preferWheel is true then we should show a wheel picker instead.
1539
+ */
1540
+ const hasWheelVariant = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
1541
+ if (preferWheel && hasWheelVariant) {
1542
+ return [this.renderWheelView(), this.renderFooter()];
1543
+ }
2038
1544
  switch (presentation) {
2039
1545
  case 'date-time':
2040
1546
  return [
2041
1547
  this.renderCalendarViewHeader(mode),
2042
1548
  this.renderCalendar(mode),
2043
- this.renderYearView(),
1549
+ this.renderCalendarViewMonthYearPicker(),
2044
1550
  this.renderTime(),
2045
- this.renderFooter()
1551
+ this.renderFooter(),
2046
1552
  ];
2047
1553
  case 'time-date':
2048
1554
  return [
2049
1555
  this.renderCalendarViewHeader(mode),
2050
1556
  this.renderTime(),
2051
1557
  this.renderCalendar(mode),
2052
- this.renderYearView(),
2053
- this.renderFooter()
1558
+ this.renderCalendarViewMonthYearPicker(),
1559
+ this.renderFooter(),
2054
1560
  ];
2055
1561
  case 'time':
2056
- return [
2057
- this.renderTime(),
2058
- this.renderFooter()
2059
- ];
1562
+ return [this.renderTime(), this.renderFooter()];
2060
1563
  case 'month':
2061
1564
  case 'month-year':
2062
1565
  case 'year':
2063
- return [
2064
- this.renderYearView(),
2065
- this.renderFooter()
2066
- ];
1566
+ return [this.renderWheelView(), this.renderFooter()];
2067
1567
  default:
2068
1568
  return [
2069
1569
  this.renderCalendarViewHeader(mode),
2070
1570
  this.renderCalendar(mode),
2071
- this.renderYearView(),
2072
- this.renderFooter()
1571
+ this.renderCalendarViewMonthYearPicker(),
1572
+ this.renderFooter(),
2073
1573
  ];
2074
1574
  }
2075
1575
  }
2076
1576
  render() {
2077
- const { name, value, disabled, el, color, isPresented, readonly, showMonthAndYear, presentation, size } = this;
1577
+ const { name, value, disabled, el, color, isPresented, readonly, showMonthAndYear, preferWheel, presentation, size, } = this;
2078
1578
  const mode = getIonMode(this);
2079
1579
  const isMonthAndYearPresentation = presentation === 'year' || presentation === 'month' || presentation === 'month-year';
2080
1580
  const shouldShowMonthAndYear = showMonthAndYear || isMonthAndYearPresentation;
2081
- renderHiddenInput(true, el, name, value, disabled);
1581
+ const monthYearPickerOpen = showMonthAndYear && !isMonthAndYearPresentation;
1582
+ const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
1583
+ const hasWheelVariant = hasDatePresentation && preferWheel;
1584
+ const hasGrid = hasDatePresentation && !preferWheel;
1585
+ renderHiddenInput(true, el, name, formatValue(value), disabled);
2082
1586
  return (h(Host, { "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, createColorClasses(color, {
2083
1587
  [mode]: true,
2084
1588
  ['datetime-presented']: isPresented,
2085
1589
  ['datetime-readonly']: readonly,
2086
1590
  ['datetime-disabled']: disabled,
2087
1591
  'show-month-and-year': shouldShowMonthAndYear,
1592
+ 'month-year-picker-open': monthYearPickerOpen,
2088
1593
  [`datetime-presentation-${presentation}`]: true,
2089
- [`datetime-size-${size}`]: true
1594
+ [`datetime-size-${size}`]: true,
1595
+ [`datetime-prefer-wheel`]: hasWheelVariant,
1596
+ [`datetime-grid`]: hasGrid,
2090
1597
  })) }, this.renderDatetime(mode)));
2091
1598
  }
2092
1599
  get el() { return getElement(this); }