@nova-design-system/nova-webcomponents 3.0.0 → 3.1.0

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 (436) hide show
  1. package/dist/cjs/{constants-bcd6b2e2.js → constants-8fb8ccc0.js} +14 -1
  2. package/dist/cjs/constants-8fb8ccc0.js.map +1 -0
  3. package/dist/cjs/index-9bda5507.js +4 -4
  4. package/dist/cjs/index.cjs.js +4 -471
  5. package/dist/cjs/index.cjs.js.map +1 -1
  6. package/dist/cjs/loader.cjs.js +1 -1
  7. package/dist/cjs/native.cjs.js +1 -1
  8. package/dist/cjs/nv-alert.cjs.entry.js +5 -5
  9. package/dist/cjs/nv-alert.cjs.entry.js.map +1 -1
  10. package/dist/cjs/nv-avatar.cjs.entry.js +1 -1
  11. package/dist/cjs/nv-badge_2.cjs.entry.js +17 -8
  12. package/dist/cjs/nv-badge_2.cjs.entry.js.map +1 -1
  13. package/dist/cjs/nv-button.cjs.entry.js +1 -1
  14. package/dist/cjs/nv-calendar.cjs.entry.js +841 -842
  15. package/dist/cjs/nv-calendar.cjs.entry.js.map +1 -1
  16. package/dist/cjs/nv-datagrid.cjs.entry.js +376 -39
  17. package/dist/cjs/nv-datagrid.cjs.entry.js.map +1 -1
  18. package/dist/cjs/nv-dialog.cjs.entry.js +18 -12
  19. package/dist/cjs/nv-dialog.cjs.entry.js.map +1 -1
  20. package/dist/cjs/nv-dialogfooter_2.cjs.entry.js +1 -1
  21. package/dist/cjs/nv-fielddate.cjs.entry.js +8 -17
  22. package/dist/cjs/nv-fielddate.cjs.entry.js.map +1 -1
  23. package/dist/cjs/nv-fielddaterange.cjs.entry.js +26 -28
  24. package/dist/cjs/nv-fielddaterange.cjs.entry.js.map +1 -1
  25. package/dist/cjs/nv-fielddropdown.cjs.entry.js +12 -5
  26. package/dist/cjs/nv-fielddropdown.cjs.entry.js.map +1 -1
  27. package/dist/cjs/nv-fielddropdownitem.cjs.entry.js +1 -1
  28. package/dist/cjs/nv-fieldmultiselect.cjs.entry.js +10 -4
  29. package/dist/cjs/nv-fieldmultiselect.cjs.entry.js.map +1 -1
  30. package/dist/cjs/nv-fieldnumber.cjs.entry.js +8 -4
  31. package/dist/cjs/nv-fieldnumber.cjs.entry.js.map +1 -1
  32. package/dist/cjs/nv-fieldpassword.cjs.entry.js +8 -4
  33. package/dist/cjs/nv-fieldpassword.cjs.entry.js.map +1 -1
  34. package/dist/cjs/nv-fieldradio.cjs.entry.js +3 -3
  35. package/dist/cjs/nv-fieldselect.cjs.entry.js +10 -6
  36. package/dist/cjs/nv-fieldselect.cjs.entry.js.map +1 -1
  37. package/dist/cjs/nv-fieldtext.cjs.entry.js +8 -4
  38. package/dist/cjs/nv-fieldtext.cjs.entry.js.map +1 -1
  39. package/dist/cjs/nv-fieldtextarea.cjs.entry.js +8 -4
  40. package/dist/cjs/nv-fieldtextarea.cjs.entry.js.map +1 -1
  41. package/dist/cjs/nv-fieldtime.cjs.entry.js +15 -12
  42. package/dist/cjs/nv-fieldtime.cjs.entry.js.map +1 -1
  43. package/dist/cjs/nv-icon.cjs.entry.js +3 -3
  44. package/dist/cjs/nv-icon.cjs.entry.js.map +1 -1
  45. package/dist/cjs/nv-iconbutton_2.cjs.entry.js +2 -2
  46. package/dist/cjs/nv-menu.cjs.entry.js +3 -1
  47. package/dist/cjs/nv-menu.cjs.entry.js.map +1 -1
  48. package/dist/cjs/nv-menuitem.cjs.entry.js +1 -1
  49. package/dist/cjs/nv-popover.cjs.entry.js +1 -1
  50. package/dist/cjs/nv-row.cjs.entry.js +1 -1
  51. package/dist/cjs/nv-stack.cjs.entry.js +1 -1
  52. package/dist/cjs/nv-table.cjs.entry.js +2 -2
  53. package/dist/cjs/nv-table.cjs.entry.js.map +1 -1
  54. package/dist/cjs/nv-toggle.cjs.entry.js +2 -2
  55. package/dist/cjs/nv-tooltip.cjs.entry.js +1 -1
  56. package/dist/collection/components/nv-alert/nv-alert.css +3 -0
  57. package/dist/collection/components/nv-alert/nv-alert.js +6 -11
  58. package/dist/collection/components/nv-alert/nv-alert.js.map +1 -1
  59. package/dist/collection/components/nv-badge/nv-badge.css +181 -1
  60. package/dist/collection/components/nv-badge/nv-badge.docs.js +20 -1
  61. package/dist/collection/components/nv-badge/nv-badge.docs.js.map +1 -1
  62. package/dist/collection/components/nv-badge/nv-badge.js +39 -15
  63. package/dist/collection/components/nv-badge/nv-badge.js.map +1 -1
  64. package/dist/collection/components/nv-breadcrumbs/nv-breadcrumbs.docs.js +0 -1
  65. package/dist/collection/components/nv-breadcrumbs/nv-breadcrumbs.docs.js.map +1 -1
  66. package/dist/collection/components/nv-calendar/nv-calendar.css +19 -0
  67. package/dist/collection/components/nv-calendar/nv-calendar.docs.js +33 -38
  68. package/dist/collection/components/nv-calendar/nv-calendar.docs.js.map +1 -1
  69. package/dist/collection/components/nv-calendar/nv-calendar.js +680 -897
  70. package/dist/collection/components/nv-calendar/nv-calendar.js.map +1 -1
  71. package/dist/collection/components/nv-calendar/nv-calendar.utils.js +202 -0
  72. package/dist/collection/components/nv-calendar/nv-calendar.utils.js.map +1 -0
  73. package/dist/collection/components/nv-calendar/test/nv-calendar.utils.test.js +667 -0
  74. package/dist/collection/components/nv-calendar/test/nv-calendar.utils.test.js.map +1 -0
  75. package/dist/collection/components/nv-datagrid/nv-datagrid.css +98 -0
  76. package/dist/collection/components/nv-datagrid/nv-datagrid.docs.js +103 -5
  77. package/dist/collection/components/nv-datagrid/nv-datagrid.docs.js.map +1 -1
  78. package/dist/collection/components/nv-datagrid/nv-datagrid.js +391 -56
  79. package/dist/collection/components/nv-datagrid/nv-datagrid.js.map +1 -1
  80. package/dist/collection/components/nv-dialog/nv-dialog.css +29 -5
  81. package/dist/collection/components/nv-dialog/nv-dialog.docs.js +0 -1
  82. package/dist/collection/components/nv-dialog/nv-dialog.docs.js.map +1 -1
  83. package/dist/collection/components/nv-dialog/nv-dialog.js +16 -10
  84. package/dist/collection/components/nv-dialog/nv-dialog.js.map +1 -1
  85. package/dist/collection/components/nv-fielddate/nv-fielddate.docs.js +16 -8
  86. package/dist/collection/components/nv-fielddate/nv-fielddate.docs.js.map +1 -1
  87. package/dist/collection/components/nv-fielddate/nv-fielddate.js +48 -39
  88. package/dist/collection/components/nv-fielddate/nv-fielddate.js.map +1 -1
  89. package/dist/collection/components/nv-fielddate/styles/nv-fielddate.css +7 -0
  90. package/dist/collection/components/nv-fielddaterange/nv-fielddaterange.docs.js +12 -15
  91. package/dist/collection/components/nv-fielddaterange/nv-fielddaterange.docs.js.map +1 -1
  92. package/dist/collection/components/nv-fielddaterange/nv-fielddaterange.js +75 -64
  93. package/dist/collection/components/nv-fielddaterange/nv-fielddaterange.js.map +1 -1
  94. package/dist/collection/components/nv-fielddaterange/styles/nv-fielddaterange.css +13 -11
  95. package/dist/collection/components/nv-fielddropdown/nv-fielddropdown.docs.js +8 -0
  96. package/dist/collection/components/nv-fielddropdown/nv-fielddropdown.docs.js.map +1 -1
  97. package/dist/collection/components/nv-fielddropdown/nv-fielddropdown.js +31 -4
  98. package/dist/collection/components/nv-fielddropdown/nv-fielddropdown.js.map +1 -1
  99. package/dist/collection/components/nv-fielddropdown/styles/nv-fielddropdown.css +5 -0
  100. package/dist/collection/components/nv-fielddropdownitem/nv-fielddropdownitem.js +1 -1
  101. package/dist/collection/components/nv-fielddropdownitemcheck/nv-fielddropdownitemcheck.js +1 -1
  102. package/dist/collection/components/nv-fieldmultiselect/nv-fieldmultiselect.css +24 -0
  103. package/dist/collection/components/nv-fieldmultiselect/nv-fieldmultiselect.docs.js +8 -1
  104. package/dist/collection/components/nv-fieldmultiselect/nv-fieldmultiselect.docs.js.map +1 -1
  105. package/dist/collection/components/nv-fieldmultiselect/nv-fieldmultiselect.js +29 -3
  106. package/dist/collection/components/nv-fieldmultiselect/nv-fieldmultiselect.js.map +1 -1
  107. package/dist/collection/components/nv-fieldnumber/nv-fieldnumber.css +5 -0
  108. package/dist/collection/components/nv-fieldnumber/nv-fieldnumber.docs.js +8 -0
  109. package/dist/collection/components/nv-fieldnumber/nv-fieldnumber.docs.js.map +1 -1
  110. package/dist/collection/components/nv-fieldnumber/nv-fieldnumber.js +27 -3
  111. package/dist/collection/components/nv-fieldnumber/nv-fieldnumber.js.map +1 -1
  112. package/dist/collection/components/nv-fieldpassword/nv-fieldpassword.css +5 -0
  113. package/dist/collection/components/nv-fieldpassword/nv-fieldpassword.docs.js +8 -0
  114. package/dist/collection/components/nv-fieldpassword/nv-fieldpassword.docs.js.map +1 -1
  115. package/dist/collection/components/nv-fieldpassword/nv-fieldpassword.js +27 -3
  116. package/dist/collection/components/nv-fieldpassword/nv-fieldpassword.js.map +1 -1
  117. package/dist/collection/components/nv-fieldradio/nv-fieldradio.js +3 -3
  118. package/dist/collection/components/nv-fieldselect/nv-fieldselect.css +5 -0
  119. package/dist/collection/components/nv-fieldselect/nv-fieldselect.docs.js +8 -0
  120. package/dist/collection/components/nv-fieldselect/nv-fieldselect.docs.js.map +1 -1
  121. package/dist/collection/components/nv-fieldselect/nv-fieldselect.js +29 -5
  122. package/dist/collection/components/nv-fieldselect/nv-fieldselect.js.map +1 -1
  123. package/dist/collection/components/nv-fieldtext/nv-fieldtext.css +5 -0
  124. package/dist/collection/components/nv-fieldtext/nv-fieldtext.docs.js +8 -0
  125. package/dist/collection/components/nv-fieldtext/nv-fieldtext.docs.js.map +1 -1
  126. package/dist/collection/components/nv-fieldtext/nv-fieldtext.js +27 -3
  127. package/dist/collection/components/nv-fieldtext/nv-fieldtext.js.map +1 -1
  128. package/dist/collection/components/nv-fieldtextarea/nv-fieldtextarea.css +23 -0
  129. package/dist/collection/components/nv-fieldtextarea/nv-fieldtextarea.docs.js +8 -0
  130. package/dist/collection/components/nv-fieldtextarea/nv-fieldtextarea.docs.js.map +1 -1
  131. package/dist/collection/components/nv-fieldtextarea/nv-fieldtextarea.js +27 -3
  132. package/dist/collection/components/nv-fieldtextarea/nv-fieldtextarea.js.map +1 -1
  133. package/dist/collection/components/nv-fieldtime/nv-fieldtime.js +13 -10
  134. package/dist/collection/components/nv-fieldtime/nv-fieldtime.js.map +1 -1
  135. package/dist/collection/components/nv-fieldtime/styles/nv-fieldtime.css +19 -2
  136. package/dist/collection/components/nv-icon/nv-icon.js +1 -1
  137. package/dist/collection/components/nv-icon/nv-icons.js +3 -470
  138. package/dist/collection/components/nv-icon/nv-icons.js.map +1 -1
  139. package/dist/collection/components/nv-iconbutton/nv-iconbutton.js +1 -1
  140. package/dist/collection/components/nv-loader/nv-loader.js +1 -1
  141. package/dist/collection/components/nv-menu/nv-menu.js +3 -1
  142. package/dist/collection/components/nv-menu/nv-menu.js.map +1 -1
  143. package/dist/collection/components/nv-menuitem/nv-menuitem.js +2 -2
  144. package/dist/collection/components/nv-popover/nv-popover.js +1 -1
  145. package/dist/collection/components/nv-row/nv-row.js +1 -1
  146. package/dist/collection/components/nv-stack/nv-stack.js +1 -1
  147. package/dist/collection/components/nv-table/nv-table.js +8 -11
  148. package/dist/collection/components/nv-table/nv-table.js.map +1 -1
  149. package/dist/collection/components/nv-toggle/nv-toggle.js +2 -2
  150. package/dist/collection/components/nv-tooltip/nv-tooltip.js +1 -1
  151. package/dist/collection/index.js.map +1 -1
  152. package/dist/collection/templates/navigation.docs.js +0 -1
  153. package/dist/collection/templates/navigation.docs.js.map +1 -1
  154. package/dist/collection/utils/constants.js +11 -0
  155. package/dist/collection/utils/constants.js.map +1 -1
  156. package/dist/components/index.js +4 -471
  157. package/dist/components/index.js.map +1 -1
  158. package/dist/components/nv-alert.js +6 -6
  159. package/dist/components/nv-alert.js.map +1 -1
  160. package/dist/components/nv-avatar.js +2 -2
  161. package/dist/components/nv-badge.js +1 -1
  162. package/dist/components/nv-breadcrumb.js +2 -2
  163. package/dist/components/nv-button.js +1 -1
  164. package/dist/components/nv-calendar.js +1 -1
  165. package/dist/components/nv-datagrid.js +400 -43
  166. package/dist/components/nv-datagrid.js.map +1 -1
  167. package/dist/components/nv-dialog.js +22 -16
  168. package/dist/components/nv-dialog.js.map +1 -1
  169. package/dist/components/nv-dialogfooter.js +1 -1
  170. package/dist/components/nv-fielddate.js +18 -26
  171. package/dist/components/nv-fielddate.js.map +1 -1
  172. package/dist/components/nv-fielddaterange.js +37 -38
  173. package/dist/components/nv-fielddaterange.js.map +1 -1
  174. package/dist/components/nv-fielddropdown.js +18 -10
  175. package/dist/components/nv-fielddropdown.js.map +1 -1
  176. package/dist/components/nv-fielddropdownitem.js +1 -1
  177. package/dist/components/nv-fielddropdownitemcheck.js +1 -1
  178. package/dist/components/nv-fieldmultiselect.js +17 -10
  179. package/dist/components/nv-fieldmultiselect.js.map +1 -1
  180. package/dist/components/nv-fieldnumber.js +13 -8
  181. package/dist/components/nv-fieldnumber.js.map +1 -1
  182. package/dist/components/nv-fieldpassword.js +12 -7
  183. package/dist/components/nv-fieldpassword.js.map +1 -1
  184. package/dist/components/nv-fieldradio.js +3 -3
  185. package/dist/components/nv-fieldselect.js +14 -9
  186. package/dist/components/nv-fieldselect.js.map +1 -1
  187. package/dist/components/nv-fieldtext.js +1 -158
  188. package/dist/components/nv-fieldtext.js.map +1 -1
  189. package/dist/components/nv-fieldtextarea.js +10 -5
  190. package/dist/components/nv-fieldtextarea.js.map +1 -1
  191. package/dist/components/nv-fieldtime.js +19 -16
  192. package/dist/components/nv-fieldtime.js.map +1 -1
  193. package/dist/components/nv-icon.js +1 -1
  194. package/dist/components/nv-iconbutton.js +1 -1
  195. package/dist/components/nv-loader.js +1 -1
  196. package/dist/components/nv-menu.js +6 -4
  197. package/dist/components/nv-menu.js.map +1 -1
  198. package/dist/components/nv-menuitem.js +1 -1
  199. package/dist/components/nv-popover.js +1 -1
  200. package/dist/components/nv-row.js +1 -1
  201. package/dist/components/nv-stack.js +1 -1
  202. package/dist/components/nv-table.js +2 -2
  203. package/dist/components/nv-table.js.map +1 -1
  204. package/dist/components/nv-toggle.js +2 -2
  205. package/dist/components/nv-tooltip.js +1 -1
  206. package/dist/components/p-0a0f6daf.js +187 -0
  207. package/dist/components/p-0a0f6daf.js.map +1 -0
  208. package/dist/components/{p-b7b78e64.js → p-10b37876.js} +2 -2
  209. package/dist/components/{p-b7b78e64.js.map → p-10b37876.js.map} +1 -1
  210. package/dist/components/{p-dc3faba3.js → p-10faa938.js} +4 -4
  211. package/dist/components/{p-dc3faba3.js.map → p-10faa938.js.map} +1 -1
  212. package/dist/{esm/constants-98e2dcc2.js → components/p-1f505531.js} +15 -2
  213. package/dist/components/p-1f505531.js.map +1 -0
  214. package/dist/components/{p-2012b8ba.js → p-35a70c5e.js} +2 -2
  215. package/dist/components/{p-2012b8ba.js.map → p-35a70c5e.js.map} +1 -1
  216. package/dist/components/{p-6c364a23.js → p-41c56ddc.js} +5 -5
  217. package/dist/components/{p-6c364a23.js.map → p-41c56ddc.js.map} +1 -1
  218. package/dist/components/{p-a30b55fc.js → p-608eb9da.js} +2 -2
  219. package/dist/components/{p-a30b55fc.js.map → p-608eb9da.js.map} +1 -1
  220. package/dist/components/p-76646ce9.js +88 -0
  221. package/dist/components/p-76646ce9.js.map +1 -0
  222. package/dist/components/p-854c32dc.js +1132 -0
  223. package/dist/components/p-854c32dc.js.map +1 -0
  224. package/dist/components/p-9decffb6.js +167 -0
  225. package/dist/components/p-9decffb6.js.map +1 -0
  226. package/dist/components/{p-2d9ba7d3.js → p-a2527411.js} +3 -3
  227. package/dist/components/{p-2d9ba7d3.js.map → p-a2527411.js.map} +1 -1
  228. package/dist/components/{p-f4d86795.js → p-b48d5a94.js} +3 -3
  229. package/dist/components/{p-f4d86795.js.map → p-b48d5a94.js.map} +1 -1
  230. package/dist/components/{p-4d3ec142.js → p-eb632278.js} +3 -3
  231. package/dist/components/{p-4d3ec142.js.map → p-eb632278.js.map} +1 -1
  232. package/dist/components/{p-150daf68.js → p-f5cb0a63.js} +2 -2
  233. package/dist/components/{p-150daf68.js.map → p-f5cb0a63.js.map} +1 -1
  234. package/dist/components/{p-c14f6b8e.js → p-f76bb0c3.js} +3 -3
  235. package/dist/components/{p-c14f6b8e.js.map → p-f76bb0c3.js.map} +1 -1
  236. package/dist/{components/p-8348db09.js → esm/constants-b97e736d.js} +15 -2
  237. package/dist/esm/constants-b97e736d.js.map +1 -0
  238. package/dist/esm/index-1fb7a9a6.js +4 -4
  239. package/dist/esm/index.js +4 -471
  240. package/dist/esm/index.js.map +1 -1
  241. package/dist/esm/loader.js +1 -1
  242. package/dist/esm/native.js +1 -1
  243. package/dist/esm/nv-alert.entry.js +5 -5
  244. package/dist/esm/nv-alert.entry.js.map +1 -1
  245. package/dist/esm/nv-avatar.entry.js +1 -1
  246. package/dist/esm/nv-badge_2.entry.js +17 -8
  247. package/dist/esm/nv-badge_2.entry.js.map +1 -1
  248. package/dist/esm/nv-button.entry.js +1 -1
  249. package/dist/esm/nv-calendar.entry.js +841 -842
  250. package/dist/esm/nv-calendar.entry.js.map +1 -1
  251. package/dist/esm/nv-datagrid.entry.js +376 -39
  252. package/dist/esm/nv-datagrid.entry.js.map +1 -1
  253. package/dist/esm/nv-dialog.entry.js +18 -12
  254. package/dist/esm/nv-dialog.entry.js.map +1 -1
  255. package/dist/esm/nv-dialogfooter_2.entry.js +1 -1
  256. package/dist/esm/nv-fielddate.entry.js +8 -17
  257. package/dist/esm/nv-fielddate.entry.js.map +1 -1
  258. package/dist/esm/nv-fielddaterange.entry.js +26 -28
  259. package/dist/esm/nv-fielddaterange.entry.js.map +1 -1
  260. package/dist/esm/nv-fielddropdown.entry.js +12 -5
  261. package/dist/esm/nv-fielddropdown.entry.js.map +1 -1
  262. package/dist/esm/nv-fielddropdownitem.entry.js +1 -1
  263. package/dist/esm/nv-fieldmultiselect.entry.js +10 -4
  264. package/dist/esm/nv-fieldmultiselect.entry.js.map +1 -1
  265. package/dist/esm/nv-fieldnumber.entry.js +8 -4
  266. package/dist/esm/nv-fieldnumber.entry.js.map +1 -1
  267. package/dist/esm/nv-fieldpassword.entry.js +8 -4
  268. package/dist/esm/nv-fieldpassword.entry.js.map +1 -1
  269. package/dist/esm/nv-fieldradio.entry.js +3 -3
  270. package/dist/esm/nv-fieldselect.entry.js +10 -6
  271. package/dist/esm/nv-fieldselect.entry.js.map +1 -1
  272. package/dist/esm/nv-fieldtext.entry.js +8 -4
  273. package/dist/esm/nv-fieldtext.entry.js.map +1 -1
  274. package/dist/esm/nv-fieldtextarea.entry.js +8 -4
  275. package/dist/esm/nv-fieldtextarea.entry.js.map +1 -1
  276. package/dist/esm/nv-fieldtime.entry.js +15 -12
  277. package/dist/esm/nv-fieldtime.entry.js.map +1 -1
  278. package/dist/esm/nv-icon.entry.js +3 -3
  279. package/dist/esm/nv-icon.entry.js.map +1 -1
  280. package/dist/esm/nv-iconbutton_2.entry.js +2 -2
  281. package/dist/esm/nv-menu.entry.js +3 -1
  282. package/dist/esm/nv-menu.entry.js.map +1 -1
  283. package/dist/esm/nv-menuitem.entry.js +1 -1
  284. package/dist/esm/nv-popover.entry.js +1 -1
  285. package/dist/esm/nv-row.entry.js +1 -1
  286. package/dist/esm/nv-stack.entry.js +1 -1
  287. package/dist/esm/nv-table.entry.js +2 -2
  288. package/dist/esm/nv-table.entry.js.map +1 -1
  289. package/dist/esm/nv-toggle.entry.js +2 -2
  290. package/dist/esm/nv-tooltip.entry.js +1 -1
  291. package/dist/native/index.esm.js +1 -1
  292. package/dist/native/index.esm.js.map +1 -1
  293. package/dist/native/native.css +1 -1
  294. package/dist/native/native.esm.js +1 -1
  295. package/dist/native/native.esm.js.map +1 -1
  296. package/dist/native/{p-b094296d.entry.js → p-08a75cfa.entry.js} +2 -2
  297. package/dist/native/{p-d5cbf5c8.entry.js → p-14c07207.entry.js} +2 -2
  298. package/dist/native/p-1da72182.entry.js +2 -0
  299. package/dist/native/p-1da72182.entry.js.map +1 -0
  300. package/dist/native/p-2523eead.entry.js +2 -0
  301. package/dist/native/p-2523eead.entry.js.map +1 -0
  302. package/dist/native/p-3953464e.entry.js +7 -0
  303. package/dist/native/p-3953464e.entry.js.map +1 -0
  304. package/dist/native/{p-701b5557.entry.js → p-3b7ef609.entry.js} +2 -2
  305. package/dist/native/{p-63e6aed3.entry.js → p-3cd77d82.entry.js} +2 -2
  306. package/dist/native/p-3cd77d82.entry.js.map +1 -0
  307. package/dist/native/p-470588c2.entry.js +13 -0
  308. package/dist/native/p-470588c2.entry.js.map +1 -0
  309. package/dist/native/p-49cac014.entry.js +2 -0
  310. package/dist/native/p-49cac014.entry.js.map +1 -0
  311. package/dist/native/p-4d164ed6.entry.js +2 -0
  312. package/dist/native/p-4d164ed6.entry.js.map +1 -0
  313. package/dist/native/p-4e635fa7.entry.js +2 -0
  314. package/dist/native/p-4e635fa7.entry.js.map +1 -0
  315. package/dist/native/p-5d21532a.entry.js +2 -0
  316. package/dist/native/p-5d21532a.entry.js.map +1 -0
  317. package/dist/native/{p-39bb95ff.entry.js → p-615947e7.entry.js} +2 -2
  318. package/dist/native/{p-bad11367.entry.js → p-656c56f0.entry.js} +2 -2
  319. package/dist/native/p-656c56f0.entry.js.map +1 -0
  320. package/dist/native/{p-fa77a591.entry.js → p-7042ba8a.entry.js} +2 -2
  321. package/dist/native/p-7e154bfd.entry.js +2 -0
  322. package/dist/native/p-7e154bfd.entry.js.map +1 -0
  323. package/dist/native/p-7eba904e.entry.js +2 -0
  324. package/dist/native/p-7eba904e.entry.js.map +1 -0
  325. package/dist/native/{p-6b348684.entry.js → p-7fd4d13d.entry.js} +2 -2
  326. package/dist/native/{p-fb5bddba.entry.js → p-90e6d9dd.entry.js} +2 -2
  327. package/dist/native/p-ae7ab110.entry.js +2 -0
  328. package/dist/native/p-ae7ab110.entry.js.map +1 -0
  329. package/dist/native/{p-f85aca27.entry.js → p-b8b6875d.entry.js} +2 -2
  330. package/dist/native/p-b94d9f0b.entry.js +2 -0
  331. package/dist/native/p-b94d9f0b.entry.js.map +1 -0
  332. package/dist/native/p-c0f79bac.entry.js +2 -0
  333. package/dist/native/p-c0f79bac.entry.js.map +1 -0
  334. package/dist/native/{p-6ff228da.entry.js → p-c67186f8.entry.js} +2 -2
  335. package/dist/native/{p-eee01062.entry.js → p-c71c6f23.entry.js} +2 -2
  336. package/dist/native/p-d9a52884.entry.js +2 -0
  337. package/dist/native/p-d9a52884.entry.js.map +1 -0
  338. package/dist/native/{p-d7a76400.entry.js → p-efe6a46c.entry.js} +2 -2
  339. package/dist/native/p-f2ef6771.entry.js +2 -0
  340. package/dist/native/p-f5f68992.entry.js +2 -0
  341. package/dist/native/p-f5f68992.entry.js.map +1 -0
  342. package/dist/native/{p-59768ee5.js → p-f85c08f1.js} +2 -2
  343. package/dist/native/p-f85c08f1.js.map +1 -0
  344. package/dist/native/p-fc97f071.entry.js +2 -0
  345. package/dist/native/p-fc97f071.entry.js.map +1 -0
  346. package/dist/types/components/nv-alert/nv-alert.d.ts +1 -1
  347. package/dist/types/components/nv-badge/nv-badge.d.ts +11 -3
  348. package/dist/types/components/nv-calendar/nv-calendar.d.ts +69 -107
  349. package/dist/types/components/nv-calendar/nv-calendar.utils.d.ts +60 -0
  350. package/dist/types/components/nv-calendar/test/nv-calendar.utils.test.d.ts +1 -0
  351. package/dist/types/components/nv-datagrid/nv-datagrid.d.ts +47 -10
  352. package/dist/types/components/nv-dialog/nv-dialog.d.ts +4 -0
  353. package/dist/types/components/nv-fielddate/nv-fielddate.d.ts +6 -7
  354. package/dist/types/components/nv-fielddaterange/nv-fielddaterange.d.ts +13 -12
  355. package/dist/types/components/nv-fielddropdown/nv-fielddropdown.d.ts +4 -0
  356. package/dist/types/components/nv-fieldmultiselect/nv-fieldmultiselect.d.ts +4 -0
  357. package/dist/types/components/nv-fieldnumber/nv-fieldnumber.d.ts +4 -0
  358. package/dist/types/components/nv-fieldpassword/nv-fieldpassword.d.ts +4 -0
  359. package/dist/types/components/nv-fieldselect/nv-fieldselect.d.ts +4 -0
  360. package/dist/types/components/nv-fieldtext/nv-fieldtext.d.ts +4 -0
  361. package/dist/types/components/nv-fieldtextarea/nv-fieldtextarea.d.ts +4 -0
  362. package/dist/types/components/nv-icon/nv-icons.d.ts +1 -1
  363. package/dist/types/components/nv-table/nv-table.d.ts +13 -2
  364. package/dist/types/components.d.ts +269 -116
  365. package/dist/types/index.d.ts +0 -2
  366. package/dist/types/utils/constants.d.ts +9 -0
  367. package/dist/vscode-data.json +221 -1587
  368. package/hydrate/index.js +1466 -1063
  369. package/hydrate/index.mjs +1466 -1063
  370. package/package.json +1 -1
  371. package/dist/cjs/constants-bcd6b2e2.js.map +0 -1
  372. package/dist/collection/interfaces/actionEvent.js +0 -2
  373. package/dist/collection/interfaces/actionEvent.js.map +0 -1
  374. package/dist/collection/interfaces/calendarShortcut.js +0 -2
  375. package/dist/collection/interfaces/calendarShortcut.js.map +0 -1
  376. package/dist/collection/interfaces/dateRange.js +0 -2
  377. package/dist/collection/interfaces/dateRange.js.map +0 -1
  378. package/dist/components/p-373926aa.js +0 -177
  379. package/dist/components/p-373926aa.js.map +0 -1
  380. package/dist/components/p-591730e7.js +0 -88
  381. package/dist/components/p-591730e7.js.map +0 -1
  382. package/dist/components/p-8348db09.js.map +0 -1
  383. package/dist/components/p-f331117c.js +0 -1133
  384. package/dist/components/p-f331117c.js.map +0 -1
  385. package/dist/esm/constants-98e2dcc2.js.map +0 -1
  386. package/dist/native/p-0ee428d5.entry.js +0 -2
  387. package/dist/native/p-0ee428d5.entry.js.map +0 -1
  388. package/dist/native/p-2691e02d.entry.js +0 -2
  389. package/dist/native/p-37f0210e.entry.js +0 -2
  390. package/dist/native/p-37f0210e.entry.js.map +0 -1
  391. package/dist/native/p-4a440970.entry.js +0 -2
  392. package/dist/native/p-4a440970.entry.js.map +0 -1
  393. package/dist/native/p-4ae26462.entry.js +0 -7
  394. package/dist/native/p-4ae26462.entry.js.map +0 -1
  395. package/dist/native/p-4d9c4618.entry.js +0 -2
  396. package/dist/native/p-4d9c4618.entry.js.map +0 -1
  397. package/dist/native/p-59768ee5.js.map +0 -1
  398. package/dist/native/p-59e0bd2b.entry.js +0 -2
  399. package/dist/native/p-59e0bd2b.entry.js.map +0 -1
  400. package/dist/native/p-5c00f092.entry.js +0 -2
  401. package/dist/native/p-5c00f092.entry.js.map +0 -1
  402. package/dist/native/p-63e6aed3.entry.js.map +0 -1
  403. package/dist/native/p-7f5eb2ac.entry.js +0 -2
  404. package/dist/native/p-7f5eb2ac.entry.js.map +0 -1
  405. package/dist/native/p-84a73e2a.entry.js +0 -2
  406. package/dist/native/p-84a73e2a.entry.js.map +0 -1
  407. package/dist/native/p-93dc2f47.entry.js +0 -2
  408. package/dist/native/p-93dc2f47.entry.js.map +0 -1
  409. package/dist/native/p-9a267f16.entry.js +0 -13
  410. package/dist/native/p-9a267f16.entry.js.map +0 -1
  411. package/dist/native/p-9d6431c7.entry.js +0 -2
  412. package/dist/native/p-9d6431c7.entry.js.map +0 -1
  413. package/dist/native/p-b2ce83ad.entry.js +0 -2
  414. package/dist/native/p-b2ce83ad.entry.js.map +0 -1
  415. package/dist/native/p-bad11367.entry.js.map +0 -1
  416. package/dist/native/p-e1a4f776.entry.js +0 -2
  417. package/dist/native/p-e1a4f776.entry.js.map +0 -1
  418. package/dist/native/p-e49bbd02.entry.js +0 -2
  419. package/dist/native/p-e49bbd02.entry.js.map +0 -1
  420. package/dist/native/p-f6bdc270.entry.js +0 -2
  421. package/dist/native/p-f6bdc270.entry.js.map +0 -1
  422. package/dist/types/interfaces/actionEvent.d.ts +0 -13
  423. package/dist/types/interfaces/calendarShortcut.d.ts +0 -17
  424. package/dist/types/interfaces/dateRange.d.ts +0 -13
  425. /package/dist/native/{p-b094296d.entry.js.map → p-08a75cfa.entry.js.map} +0 -0
  426. /package/dist/native/{p-d5cbf5c8.entry.js.map → p-14c07207.entry.js.map} +0 -0
  427. /package/dist/native/{p-701b5557.entry.js.map → p-3b7ef609.entry.js.map} +0 -0
  428. /package/dist/native/{p-39bb95ff.entry.js.map → p-615947e7.entry.js.map} +0 -0
  429. /package/dist/native/{p-fa77a591.entry.js.map → p-7042ba8a.entry.js.map} +0 -0
  430. /package/dist/native/{p-6b348684.entry.js.map → p-7fd4d13d.entry.js.map} +0 -0
  431. /package/dist/native/{p-fb5bddba.entry.js.map → p-90e6d9dd.entry.js.map} +0 -0
  432. /package/dist/native/{p-f85aca27.entry.js.map → p-b8b6875d.entry.js.map} +0 -0
  433. /package/dist/native/{p-6ff228da.entry.js.map → p-c67186f8.entry.js.map} +0 -0
  434. /package/dist/native/{p-eee01062.entry.js.map → p-c71c6f23.entry.js.map} +0 -0
  435. /package/dist/native/{p-d7a76400.entry.js.map → p-efe6a46c.entry.js.map} +0 -0
  436. /package/dist/native/{p-2691e02d.entry.js.map → p-f2ef6771.entry.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import { r as registerInstance, c as createEvent, h, a as Host, g as getElement } from './index-1fb7a9a6.js';
2
+ import { C as CUSTOM_DAY_NAMES, b as CUSTOM_MONTH_NAMES, W as WEEK_ABBREVIATIONS } from './constants-b97e736d.js';
2
3
  import { c as commonjsGlobal } from './_commonjsHelpers-1789f0cf.js';
3
- import { C as CUSTOM_DAY_NAMES, a as CUSTOM_MONTH_NAMES, W as WEEK_ABBREVIATIONS } from './constants-98e2dcc2.js';
4
4
 
5
5
  var dayjs_min = {exports: {}};
6
6
 
@@ -34,13 +34,207 @@ var weekOfYear$1 = {exports: {}};
34
34
 
35
35
  const weekOfYear = weekOfYear$1.exports;
36
36
 
37
- const nvCalendarCss = "nv-calendar{display:block}.datepicker-root{display:flex;justify-content:center;align-items:flex-start;width:auto}.datepicker-container{font-family:system-ui, sans-serif;display:flex;flex-direction:column;align-items:stretch;background:var(--components-calendar-background);border-radius:var(--calendar-radius);padding:var(--calendar-padding);box-shadow:0px var(--shadow-y-axis-md-1) var(--shadow-blur-md-1) var(--shadow-spread-md, 0) var(--shadow-color-opacity-0), 0px var(--shadow-y-axis-md-2) var(--shadow-blur-md-2) var(--shadow-spread-md, 0) var(--shadow-color-opacity-2);border:1px solid var(--components-calendar-border);width:auto;max-width:100%}.datepicker-container-single{max-width:300px}.datepicker-container-single .datepicker-wrapper:has(.shortcuts-placement-left),.datepicker-container-single .datepicker-wrapper:has(.shortcuts-placement-right){max-width:410px !important}.datepicker-container-single:has(.shortcuts-placement-left),.datepicker-container-single:has(.shortcuts-placement-right){max-width:410px !important}.datepicker-wrapper{display:flex;justify-content:center;align-items:flex-start;gap:var(--calendar-gap-x);width:auto;overflow-x:hidden}.datepicker-wrapper.single{justify-content:center}.calendar-container{display:flex;flex-direction:column;align-items:center;padding:var(--calendar-padding);width:auto;position:relative}.calendar-separator{width:1px;background:var(--components-calendar-border);height:auto;min-height:100%;margin:0 10px}.header{display:flex;justify-content:start;align-items:center;margin-bottom:var(--calendar-header-margin-bottom);width:100%}.header nv-iconbutton{width:var(--calendar-header-button-size);height:var(--calendar-header-button-size)}.nav-buttons{display:flex;gap:var(--spacing-0);margin-left:auto}.nav-left{order:-1}.date-controls{display:flex;gap:var(--spacing-1);align-items:center;min-height:34px;justify-content:center}.datepicker-container-single .date-controls{justify-content:flex-start}.datepicker-container:not(.datepicker-container-single) .date-controls{justify-content:start;flex-grow:1}.date-controls .month-select,.date-controls .year-input{background:transparent !important}.calendar-wrapper:nth-child(n+2) .datepicker-container{margin-left:42px}.calendar-grid{display:grid;grid-template-columns:auto 1fr;column-gap:var(--calendar-weeks-calendar-gap-x);position:relative}.calendar-grid.slide-left{animation:slideLeft 0.3s ease-out}.calendar-grid.slide-right{animation:slideRight 0.3s ease-out}.week-numbers{display:grid;grid-template-rows:var(--calendar-cell-size) repeat(6, var(--calendar-cell-size));background:var(--components-calendar-weeks-background);color:var(--components-calendar-weeks-text);border-radius:var(--calendar-weeks-radius);width:var(--calendar-weeks-size);row-gap:var(--calendar-grid-gap-y)}.week-numbers .clickable{cursor:pointer}.week-numbers .clickable:hover{background-color:var(--components-calendar-weeks-background-hover);color:var(--components-calendar-weeks-text-hover);border-radius:var(--calendar-radius)}.week-header,.week-number{display:grid;place-items:center;font-size:var(--calendar-cell-font-size)}.week-header{font-weight:700;color:var(--components-calendar-weeks-text)}.week-number{color:var(--components-calendar-cell-text)}.days-container{display:grid;grid-template-rows:auto 1fr;row-gap:var(--calendar-grid-gap-y)}.days-header{display:grid;grid-template-columns:repeat(7, var(--calendar-cell-size));height:var(--calendar-cell-size)}.day-header{display:grid;place-items:center;font-size:var(--calendar-cell-font-size);color:var(--components-calendar-cell-text)}.days-grid{display:grid;grid-template-columns:repeat(7, var(--calendar-cell-size));grid-template-rows:repeat(6, var(--calendar-cell-size));animation:fadeIn 0.2s ease-in;row-gap:var(--calendar-grid-gap-y);z-index:0}.day{display:grid;place-items:center;width:var(--calendar-cell-size);height:var(--calendar-cell-size);font-size:var(--calendar-cell-font-size);border-radius:var(--calendar-cell-radius);cursor:pointer;border:none;background:transparent;transition:all 0.2s ease;text-align:center;animation:scaleIn 0.2s ease-out}.day:hover:not(.disabled,.empty,.selected){background:var(--components-calendar-cell-background-hover);color:var(--components-calendar-cell-text-hover)}.day.selected,.day.selected:hover .day.is-today.selected,.day.is-today.selected:hover{background:var(--components-calendar-cell-background-selected);color:var(--components-calendar-cell-text-selected) !important}.day.disabled{opacity:var(--opacity-disabled);cursor:not-allowed}.day.outside-month{color:var(--components-calendar-cell-text);opacity:var(--opacity-disabled)}.day.outside-month.selected{opacity:1 !important;color:var(--components-calendar-cell-text-selected)}.day.outside-month.in-range{opacity:1 !important;background-color:var(--components-calendar-cell-background-in-range);color:var(--components-calendar-cell-text-in-range)}.day.in-range{background:var(--components-calendar-cell-background-in-range);color:var(--components-calendar-cell-text-in-range);border-radius:0;position:relative}.day.range-start,.day.range-start:focus,.day.range-start:hover,.day.range-end,.day.range-end:focus,.day.range-end:hover{background-color:var(--components-calendar-cell-background-selected) !important;color:var(--components-calendar-cell-text-selected) !important}.day.range-start,.day.range-end,.day.range-start.is-today,.day.range-end.is-today{background:var(--components-calendar-cell-background-selected);color:var(--components-calendar-cell-text-selected);position:relative;border-radius:var(--radius-rounded-full)}.day.range-start:hover,.day.range-end:hover,.day.range-start.is-today:hover,.day.range-end.is-today:hover{color:var(--components-calendar-cell-text-today)}.day.range-start:before,.day.range-end:before,.day.range-start.is-today:before,.day.range-end.is-today:before{content:\"\";position:absolute;bottom:0;left:0;right:0;top:0;z-index:-1;background-color:var(--components-calendar-cell-background-in-range);border-radius:var(--radius-rounded-full);width:auto;height:auto}.day.range-start:has(~.range-end):before,.day.range-start:has(+.in-range):before{border-top-right-radius:0;border-bottom-right-radius:0}.day.range-end:before{border-top-left-radius:0 !important;border-bottom-left-radius:0 !important}.day.outside-month.range-start,.day.outside-month.range-end{background:var(--components-calendar-cell-background-selected) !important;color:var(--components-calendar-cell-text-selected);opacity:1 !important}.day.is-today{font-weight:700;position:relative;color:var(--components-calendar-cell-text-today)}.day.is-today.range-start,.day.is-today.range-end{color:var(--components-calendar-cell-text-selected)}.day.is-today.range-start:hover,.day.is-today.range-end:hover{color:var(--components-calendar-cell-text-today)}.day.is-today::after{content:\"\";position:absolute;bottom:var(--spacing-1);left:50%;transform:translateX(-50%);width:var(--calendar-cell-dot-size);height:var(--calendar-cell-dot-size);background-color:currentColor;border-radius:50%}.day.is-today.selected::after{color:var(--components-calendar-cell-text-selected)}.day.is-today.selected::after::after{background-color:var(--components-calendar-cell-dot-selected)}.calendar-footer{display:flex;gap:var(--spacing-1);justify-content:flex-start;width:100%;flex-wrap:wrap}.footer-placement-left{justify-content:flex-start}.footer-placement-right{justify-content:flex-end}.footer-placement-center{justify-content:center}.datepicker-controls{display:flex;flex-direction:column;border-top:1px solid var(--components-calendar-border);padding:var(--calendar-controls-padding-top) var(--calendar-padding) var(--calendar-padding);gap:var(--calendar-grid-gap-y);margin-top:var(--calendar-controls-margin-top)}.datepicker-actions{display:flex;justify-content:flex-end;gap:var(--spacing-1);width:100%}.datepicker-actions slot-fb{display:contents !important}.calendar-footer+.datepicker-actions{margin-top:0}.shortcuts-placement-left,.shortcuts-placement-right{display:flex;flex-direction:column;gap:var(--spacing-1);margin-top:var(--spacing-4)}.shortcuts-placement-left{align-items:flex-end}.shortcuts-placement-right{align-items:flex-start}@keyframes slideLeft{from{opacity:0;transform:translateX(20px)}to{opacity:1;transform:translateX(0)}}@keyframes slideRight{from{opacity:0;transform:translateX(-20px)}to{opacity:1;transform:translateX(0)}}@keyframes fadeIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes scaleIn{from{opacity:0;transform:scale(0.9)}to{opacity:1;transform:scale(1)}}";
38
- const NvCalendarStyle0 = nvCalendarCss;
39
-
40
- // Extend dayjs with plugins
41
37
  dayjs.extend(customParseFormat);
42
38
  dayjs.extend(utc);
43
39
  dayjs.extend(weekOfYear);
40
+ /**
41
+ * Formats a date to a string according to the format
42
+ * @param {Date} date - Date to format
43
+ * @returns {string} Formatted date
44
+ * @param {Object} options - Additional options
45
+ * @param {string} options.dateFormat - Date format (ex: 'YYYY-MM-DD', 'DD-MM-YYYY', etc.)
46
+ */
47
+ function formatDate(date, options) {
48
+ if (!date)
49
+ return '';
50
+ const isUTCMode = options.dateFormat.includes('Z');
51
+ const isISO8601Format = options.dateFormat === 'YYYY-MM-DD[T]HH:mm:ss[Z]';
52
+ // Special case for ISO 8601
53
+ if (isISO8601Format) {
54
+ // For the ISO 8601 format, use directly toISOString() which is standard
55
+ return date.toISOString();
56
+ }
57
+ // If the format is "Ticks", convert the time to C# ticks
58
+ if (options.dateFormat === 'Ticks') {
59
+ const ticks = date.getTime() * 10000 + 621355968000000000;
60
+ return ticks.toString();
61
+ }
62
+ // If the format is "X" (Unix Seconds)
63
+ if (options.dateFormat === 'X') {
64
+ return dayjs(date).unix().toString();
65
+ }
66
+ // If the format is "x" (Unix Milliseconds)
67
+ if (options.dateFormat === 'x') {
68
+ return date.getTime().toString();
69
+ }
70
+ // Otherwise, format according to the mode (UTC or local)
71
+ return isUTCMode
72
+ ? dayjs(date).utc().format(options.dateFormat)
73
+ : dayjs(date).format(options.dateFormat);
74
+ }
75
+ /**
76
+ * Checks if two dates are identical
77
+ * @param {Date | null} date - First date
78
+ * @param {Date | null} compareDate - Second date
79
+ * @param {Object} options - Additional options
80
+ * @param {boolean} options.isUTCMode - Whether the dates are in UTC mode
81
+ * @returns {boolean} true if the dates are identical
82
+ */
83
+ function isSameDate(date, compareDate, options) {
84
+ if (!date || !compareDate)
85
+ return false;
86
+ if (options.isUTCMode) {
87
+ return (date.getUTCFullYear() === compareDate.getUTCFullYear() &&
88
+ date.getUTCMonth() === compareDate.getUTCMonth() &&
89
+ date.getUTCDate() === compareDate.getUTCDate());
90
+ }
91
+ else {
92
+ return (date.getFullYear() === compareDate.getFullYear() &&
93
+ date.getMonth() === compareDate.getMonth() &&
94
+ date.getDate() === compareDate.getDate());
95
+ }
96
+ }
97
+ /**
98
+ * Checks if a date is identical or before another date
99
+ * @param {Date} date - Date to check
100
+ * @param {Date} compareDate - Reference date
101
+ * @param {Object} options - Additional options
102
+ * @param {boolean} options.isUTCMode - Whether the dates are in UTC mode
103
+ * @returns {boolean} true if `date` <= `compareDate`
104
+ */
105
+ function isSameOrBefore(date, compareDate, options) {
106
+ if (!date || !compareDate)
107
+ return false;
108
+ if (options.isUTCMode) {
109
+ return (date.getUTCFullYear() < compareDate.getUTCFullYear() ||
110
+ (date.getUTCFullYear() === compareDate.getUTCFullYear() &&
111
+ date.getUTCMonth() < compareDate.getUTCMonth()) ||
112
+ (date.getUTCFullYear() === compareDate.getUTCFullYear() &&
113
+ date.getUTCMonth() === compareDate.getUTCMonth() &&
114
+ date.getUTCDate() <= compareDate.getUTCDate()));
115
+ }
116
+ else {
117
+ return (date.getFullYear() < compareDate.getFullYear() ||
118
+ (date.getFullYear() === compareDate.getFullYear() &&
119
+ date.getMonth() < compareDate.getMonth()) ||
120
+ (date.getFullYear() === compareDate.getFullYear() &&
121
+ date.getMonth() === compareDate.getMonth() &&
122
+ date.getDate() <= compareDate.getDate()));
123
+ }
124
+ }
125
+ /**
126
+ * Checks if a date is identical or after another date
127
+ * @param {Date} date - Date to check
128
+ * @param {Date} compareDate - Reference date
129
+ * @param {Object} options - Additional options
130
+ * @param {boolean} options.isUTCMode - Whether the dates are in UTC mode
131
+ * @returns {boolean} true if `date` >= `compareDate`
132
+ */
133
+ function isSameOrAfter(date, compareDate, options) {
134
+ if (!date || !compareDate)
135
+ return false;
136
+ if (options.isUTCMode) {
137
+ return (date.getUTCFullYear() > compareDate.getUTCFullYear() ||
138
+ (date.getUTCFullYear() === compareDate.getUTCFullYear() &&
139
+ date.getUTCMonth() > compareDate.getUTCMonth()) ||
140
+ (date.getUTCFullYear() === compareDate.getUTCFullYear() &&
141
+ date.getUTCMonth() === compareDate.getUTCMonth() &&
142
+ date.getUTCDate() >= compareDate.getUTCDate()));
143
+ }
144
+ else {
145
+ return (date.getFullYear() > compareDate.getFullYear() ||
146
+ (date.getFullYear() === compareDate.getFullYear() &&
147
+ date.getMonth() > compareDate.getMonth()) ||
148
+ (date.getFullYear() === compareDate.getFullYear() &&
149
+ date.getMonth() === compareDate.getMonth() &&
150
+ date.getDate() >= compareDate.getDate()));
151
+ }
152
+ }
153
+ /**
154
+ * Calculates the ISO week number
155
+ * @param {Date} date - Date to calculate
156
+ * @returns {number} Week number
157
+ */
158
+ function getWeekNumber(date) {
159
+ const startOfYear = new Date(date.getFullYear(), 0, 1);
160
+ const pastDaysOfYear = (date.getTime() - startOfYear.getTime()) / 86400000;
161
+ return Math.ceil((pastDaysOfYear + startOfYear.getDay() + 1) / 7);
162
+ }
163
+ /**
164
+ * Convert a date string/Date to a Date without timezone offset
165
+ * @param {string | Date} dateInput - Date under string or Date object form
166
+ * @param {string} dateFormat - Date format (ex: 'YYYY-MM-DD', 'DD-MM-YYYY', etc.)
167
+ * @returns {Date} Date in Date form without timezone offset
168
+ */
169
+ function parseDate(dateInput, dateFormat) {
170
+ if (dateInput instanceof Date)
171
+ return dateInput;
172
+ const isUTCMode = dateFormat.includes('Z');
173
+ // Attempt to automatically detect ISO 8601 format (generated by toISOString())
174
+ // The regex checks the standard ISO format: YYYY-MM-DDTHH:mm:ss.sssZ
175
+ if (typeof dateInput === 'string' &&
176
+ /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$/.test(dateInput)) {
177
+ try {
178
+ const parsedDate = new Date(dateInput);
179
+ if (!isNaN(parsedDate.getTime())) {
180
+ return parsedDate;
181
+ }
182
+ }
183
+ catch (error) {
184
+ // If it fails, continue with other methods
185
+ console.error('Error parsing ISO date:', error);
186
+ }
187
+ }
188
+ // Handling Unix Seconds ("X") formats
189
+ if (dateFormat === 'X') {
190
+ const unixSeconds = Number(dateInput);
191
+ if (isNaN(unixSeconds))
192
+ return null;
193
+ return isUTCMode
194
+ ? dayjs.unix(unixSeconds).utc().toDate()
195
+ : dayjs.unix(unixSeconds).toDate();
196
+ }
197
+ // Handling Unix Milliseconds ("x") formats
198
+ if (dateFormat === 'x') {
199
+ const unixMilliseconds = Number(dateInput);
200
+ if (isNaN(unixMilliseconds))
201
+ return null;
202
+ return isUTCMode
203
+ ? dayjs(unixMilliseconds).utc().toDate()
204
+ : dayjs(unixMilliseconds).toDate();
205
+ }
206
+ // Handling C# Ticks format
207
+ if (dateFormat === 'Ticks') {
208
+ const ticks = Number(dateInput);
209
+ if (isNaN(ticks))
210
+ return null;
211
+ // Conversion of .NET ticks to milliseconds since Unix epoch
212
+ const unixMilliseconds = (ticks - 621355968000000000) / 10000;
213
+ return isUTCMode
214
+ ? dayjs(unixMilliseconds).utc().toDate()
215
+ : dayjs(unixMilliseconds).toDate();
216
+ }
217
+ // For all other formats, use customParseFormat in strict mode
218
+ let parsed;
219
+ if (isUTCMode) {
220
+ parsed = dayjs.utc(dateInput, dateFormat, true);
221
+ }
222
+ else {
223
+ parsed = dayjs(dateInput, dateFormat, true);
224
+ }
225
+ if (!parsed.isValid()) {
226
+ console.error(`Parsing error:`, {
227
+ dateInput,
228
+ dateFormat: dateFormat,
229
+ });
230
+ return null;
231
+ }
232
+ return parsed.toDate();
233
+ }
234
+
235
+ const nvCalendarCss = "nv-calendar{display:block}.datepicker-root{display:flex;justify-content:center;align-items:flex-start;width:auto}.datepicker-container{font-family:system-ui, sans-serif;display:flex;flex-direction:column;align-items:stretch;background:var(--components-calendar-background);border-radius:var(--calendar-radius);padding:var(--calendar-padding);box-shadow:0px var(--shadow-y-axis-md-1) var(--shadow-blur-md-1) var(--shadow-spread-md, 0) var(--shadow-color-opacity-0), 0px var(--shadow-y-axis-md-2) var(--shadow-blur-md-2) var(--shadow-spread-md, 0) var(--shadow-color-opacity-2);border:1px solid var(--components-calendar-border);width:auto;max-width:100%}.datepicker-container-single{max-width:300px}.datepicker-container-single .datepicker-wrapper:has(.shortcuts-placement-left),.datepicker-container-single .datepicker-wrapper:has(.shortcuts-placement-right){max-width:410px !important}.datepicker-container-single:has(.shortcuts-placement-left),.datepicker-container-single:has(.shortcuts-placement-right){max-width:410px !important}.datepicker-wrapper{display:flex;justify-content:center;align-items:flex-start;gap:var(--calendar-gap-x);width:auto;overflow-x:hidden}.datepicker-wrapper::-webkit-scrollbar{width:6px;height:6px}.datepicker-wrapper::-webkit-scrollbar-track{background-color:var(--color-level-10-background);border-radius:9999px}.datepicker-wrapper::-webkit-scrollbar-thumb{background-color:var(--color-gray-200);border-radius:9999px}.datepicker-wrapper.single{justify-content:center}.calendar-container{display:flex;flex-direction:column;align-items:center;padding:var(--calendar-padding);width:auto;position:relative}.calendar-separator{width:1px;background:var(--components-calendar-border);height:auto;min-height:100%;margin:0 10px}.header{display:flex;justify-content:start;align-items:center;margin-bottom:var(--calendar-header-margin-bottom);width:100%}.header nv-iconbutton{width:var(--calendar-header-button-size);height:var(--calendar-header-button-size)}.nav-buttons{display:flex;gap:var(--spacing-0);margin-left:auto}.nav-left{order:-1}.date-controls{display:flex;gap:var(--spacing-1);align-items:center;min-height:34px;justify-content:center}.datepicker-container-single .date-controls{justify-content:flex-start}.datepicker-container:not(.datepicker-container-single) .date-controls{justify-content:start;flex-grow:1}.date-controls .month-select,.date-controls .year-input{background:transparent !important}.calendar-wrapper:nth-child(n+2) .datepicker-container{margin-left:42px}.calendar-grid{display:grid;grid-template-columns:auto 1fr;column-gap:var(--calendar-weeks-calendar-gap-x);position:relative}.calendar-grid.slide-left{animation:slideLeft 0.3s ease-out}.calendar-grid.slide-right{animation:slideRight 0.3s ease-out}.week-numbers{display:grid;grid-template-rows:var(--calendar-cell-size) repeat(6, var(--calendar-cell-size));background:var(--components-calendar-weeks-background);color:var(--components-calendar-weeks-text);border-radius:var(--calendar-weeks-radius);width:var(--calendar-weeks-size);row-gap:var(--calendar-grid-gap-y)}.week-numbers .clickable{cursor:pointer}.week-numbers .clickable:hover{background-color:var(--components-calendar-weeks-background-hover);color:var(--components-calendar-weeks-text-hover);border-radius:var(--calendar-radius)}.week-header,.week-number{display:grid;place-items:center;font-size:var(--calendar-cell-font-size)}.week-header{font-weight:700;color:var(--components-calendar-weeks-text)}.week-number{color:var(--components-calendar-cell-text)}.days-container{display:grid;grid-template-rows:auto 1fr;row-gap:var(--calendar-grid-gap-y)}.days-header{display:grid;grid-template-columns:repeat(7, var(--calendar-cell-size));height:var(--calendar-cell-size)}.day-header{display:grid;place-items:center;font-size:var(--calendar-cell-font-size);color:var(--components-calendar-cell-text)}.days-grid{display:grid;grid-template-columns:repeat(7, var(--calendar-cell-size));grid-template-rows:repeat(6, var(--calendar-cell-size));animation:fadeIn 0.2s ease-in;row-gap:var(--calendar-grid-gap-y);z-index:0}.day{display:grid;place-items:center;width:var(--calendar-cell-size);height:var(--calendar-cell-size);font-size:var(--calendar-cell-font-size);border-radius:var(--calendar-cell-radius);cursor:pointer;border:none;background:transparent;transition:all 0.2s ease;text-align:center;animation:scaleIn 0.2s ease-out}.day:hover:not(.disabled,.empty,.selected){background:var(--components-calendar-cell-background-hover);color:var(--components-calendar-cell-text-hover)}.day.selected,.day.selected:hover .day.is-today.selected,.day.is-today.selected:hover{background:var(--components-calendar-cell-background-selected);color:var(--components-calendar-cell-text-selected) !important}.day.disabled{opacity:var(--opacity-disabled);cursor:not-allowed}.day.outside-month{color:var(--components-calendar-cell-text);opacity:var(--opacity-disabled)}.day.outside-month.selected{opacity:1 !important;color:var(--components-calendar-cell-text-selected)}.day.outside-month.in-range{opacity:1 !important;background-color:var(--components-calendar-cell-background-in-range);color:var(--components-calendar-cell-text-in-range)}.day.in-range{background:var(--components-calendar-cell-background-in-range);color:var(--components-calendar-cell-text-in-range);border-radius:0;position:relative}.day.range-start,.day.range-start:focus,.day.range-start:hover,.day.range-end,.day.range-end:focus,.day.range-end:hover{background-color:var(--components-calendar-cell-background-selected) !important;color:var(--components-calendar-cell-text-selected) !important}.day.range-start,.day.range-end,.day.range-start.is-today,.day.range-end.is-today{background:var(--components-calendar-cell-background-selected);color:var(--components-calendar-cell-text-selected);position:relative;border-radius:var(--radius-rounded-full)}.day.range-start:hover,.day.range-end:hover,.day.range-start.is-today:hover,.day.range-end.is-today:hover{color:var(--components-calendar-cell-text-today)}.day.range-start:before,.day.range-end:before,.day.range-start.is-today:before,.day.range-end.is-today:before{content:\"\";position:absolute;bottom:0;left:0;right:0;top:0;z-index:-1;background-color:var(--components-calendar-cell-background-in-range);border-radius:var(--radius-rounded-full);width:auto;height:auto}.day.range-start:has(~.range-end):before,.day.range-start:has(+.in-range):before{border-top-right-radius:0;border-bottom-right-radius:0}.day.range-end:before{border-top-left-radius:0 !important;border-bottom-left-radius:0 !important}.day.outside-month.range-start,.day.outside-month.range-end{background:var(--components-calendar-cell-background-selected) !important;color:var(--components-calendar-cell-text-selected);opacity:1 !important}.day.is-today{font-weight:700;position:relative;color:var(--components-calendar-cell-text-today)}.day.is-today.range-start,.day.is-today.range-end{color:var(--components-calendar-cell-text-selected)}.day.is-today.range-start:hover,.day.is-today.range-end:hover{color:var(--components-calendar-cell-text-today)}.day.is-today::after{content:\"\";position:absolute;bottom:var(--spacing-1);left:50%;transform:translateX(-50%);width:var(--calendar-cell-dot-size);height:var(--calendar-cell-dot-size);background-color:currentColor;border-radius:50%}.day.is-today.selected::after{color:var(--components-calendar-cell-text-selected)}.day.is-today.selected::after::after{background-color:var(--components-calendar-cell-dot-selected)}.calendar-footer{display:flex;gap:var(--spacing-1);justify-content:flex-start;width:100%;flex-wrap:wrap}.footer-placement-left{justify-content:flex-start}.footer-placement-right{justify-content:flex-end}.footer-placement-center{justify-content:center}.datepicker-controls{display:flex;flex-direction:column;border-top:1px solid var(--components-calendar-border);padding:var(--calendar-controls-padding-top) var(--calendar-padding) var(--calendar-padding);gap:var(--calendar-grid-gap-y);margin-top:var(--calendar-controls-margin-top)}.datepicker-actions{display:flex;justify-content:flex-end;gap:var(--spacing-1);width:100%}.datepicker-actions slot-fb{display:contents !important}.calendar-footer+.datepicker-actions{margin-top:0}.shortcuts-placement-left,.shortcuts-placement-right{display:flex;flex-direction:column;gap:var(--spacing-1);margin-top:var(--spacing-4)}.shortcuts-placement-left{align-items:flex-end}.shortcuts-placement-right{align-items:flex-start}@keyframes slideLeft{from{opacity:0;transform:translateX(20px)}to{opacity:1;transform:translateX(0)}}@keyframes slideRight{from{opacity:0;transform:translateX(-20px)}to{opacity:1;transform:translateX(0)}}@keyframes fadeIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes scaleIn{from{opacity:0;transform:scale(0.9)}to{opacity:1;transform:scale(1)}}";
236
+ const NvCalendarStyle0 = nvCalendarCss;
237
+
44
238
  const NvCalendar = class {
45
239
  constructor(hostRef) {
46
240
  registerInstance(this, hostRef);
@@ -59,33 +253,12 @@ const NvCalendar = class {
59
253
  */
60
254
  this.numberOfCalendars = 1;
61
255
  /**
62
- * Selected date (ISO string format)
63
- * ex: "2025-03-15"
64
- */
65
- this.singleValue = '';
66
- /**
67
- * Selected date range
68
- * format: { start: ISO string, end: ISO string }
69
- * ex: { start: "2025-03-15", end: "2025-03-20" }
70
- */
71
- this.rangeValue = '';
72
- /**
73
- * Minimum date for selection (ISO string format, ex: "2025-01-01")
74
- */
75
- this.min = '';
76
- /**
77
- * Maximum date for selection (ISO string format, ex: "2025-12-31")
78
- */
79
- this.max = '';
80
- /** Disabled dates (ISO string array)
81
- * @default '[]'
82
- */
83
- this.disabledDates = '';
84
- /** Locale for date formatting
256
+ * Locale for date formatting
85
257
  * @default 'en-BE'
86
258
  */
87
259
  this.locale = 'en-BE';
88
- /** Date format (ex: 'YYYY-MM-DD', 'DD-MM-YYYY', etc.)
260
+ /**
261
+ * Date format (ex: 'YYYY-MM-DD', 'DD-MM-YYYY', etc.)
89
262
  * @default 'YYYY-MM-DD'
90
263
  * @note If the date format is in UTC mode, the date will be displayed in UTC time.
91
264
  * @note If the date format is not in UTC mode, the date will be displayed in the local time.
@@ -103,40 +276,483 @@ const NvCalendar = class {
103
276
  this.selectionType = 'single';
104
277
  /**
105
278
  * Show action buttons
106
- * @default false
107
279
  */
108
280
  this.showActions = false;
109
- /**
110
- * Custom actions to display in the footer
111
- * JSON array of objects with the following properties:
112
- * - label: string
113
- * - onClick: function
114
- * @default '[]'
115
- */
116
- this.shortcuts = '[]';
117
281
  /** Cache for parsed disabled dates */
118
282
  this.parsedDisabledDates = [];
119
- /** Selected date */
283
+ //#endregion PROPERTIES
284
+ /****************************************************************************/
285
+ //#region STATE
286
+ this.currentDate = null;
120
287
  this.selectedDate = null;
121
- /** Start date */
122
288
  this.startDate = null;
123
- /** End date */
124
289
  this.endDate = null;
125
290
  /** List of formatted months for the selector */
126
291
  this.months = [];
292
+ /**
293
+ * Change the displayed month
294
+ * @param {number} offset - Month offset (-1 for previous, 1 for next)
295
+ */
296
+ this.changeMonth = (offset) => {
297
+ const newDate = new Date(this.currentDate);
298
+ // Ensure we only move by one month at a time
299
+ newDate.setUTCMonth(newDate.getUTCMonth() + offset);
300
+ // Add the appropriate animation class
301
+ const containers = this.el.querySelectorAll('.calendar-grid');
302
+ containers.forEach(container => {
303
+ // Remove existing animation classes
304
+ container.classList.remove('slide-left', 'slide-right');
305
+ // Add the new animation class
306
+ const animationClass = offset > 0 ? 'slide-left' : 'slide-right';
307
+ container.classList.add(animationClass);
308
+ // Remove the class after the animation
309
+ setTimeout(() => {
310
+ container.classList.remove(animationClass);
311
+ }, 300); // 300ms corresponds to $slide-duration in the SCSS
312
+ });
313
+ this.currentDate = newDate;
314
+ };
315
+ /**
316
+ * Handles date selection based on the mode
317
+ * @param {Date} date - Selected date
318
+ */
319
+ this.handleDateSelection = (date) => {
320
+ if (this.isDateDisabled(date)) {
321
+ return;
322
+ }
323
+ if (this.selectionType === 'single') {
324
+ this.handleSingleSelection(date);
325
+ }
326
+ else {
327
+ this.handleRangeSelection(date);
328
+ }
329
+ };
330
+ /**
331
+ * Handles single date selection
332
+ * @param {Date} date - Selected date
333
+ */
334
+ this.handleSingleSelection = (date) => {
335
+ if (!date)
336
+ return;
337
+ const formattedDate = formatDate(date, { dateFormat: this.dateFormat });
338
+ this.selectedDate = date;
339
+ this.singleDateChange.emit(formattedDate);
340
+ };
341
+ /**
342
+ * Handles range date selection
343
+ * @param {Date} date - Selected date
344
+ */
345
+ this.handleRangeSelection = (date) => {
346
+ if (!this.startDate || (this.startDate && this.endDate)) {
347
+ this.startDate = date;
348
+ this.endDate = null;
349
+ }
350
+ else {
351
+ this.endDate = date;
352
+ if (this.startDate > this.endDate) {
353
+ [this.startDate, this.endDate] = [this.endDate, this.startDate];
354
+ }
355
+ this.rangeDateChange.emit({
356
+ start: formatDate(this.startDate, { dateFormat: this.dateFormat }),
357
+ end: formatDate(this.endDate, { dateFormat: this.dateFormat }),
358
+ });
359
+ }
360
+ };
361
+ /**
362
+ * Checks if a date is disabled.
363
+ * Disabled if:
364
+ * - The date is before min (if defined)
365
+ * - The date is after max (if defined)
366
+ * - The date is in the disabledDates array
367
+ * @param {Date} date - Date to check
368
+ * @returns {boolean} true if the date is disabled
369
+ */
370
+ this.isDateDisabled = (date) => {
371
+ if (!date)
372
+ return true;
373
+ // Minimum bound check
374
+ if (this.min) {
375
+ const minDate = parseDate(this.min, this.dateFormat);
376
+ if (minDate && date < minDate) {
377
+ return true;
378
+ }
379
+ }
380
+ // Maximum bound check
381
+ if (this.max) {
382
+ const maxDate = parseDate(this.max, this.dateFormat);
383
+ if (maxDate && date > maxDate) {
384
+ return true;
385
+ }
386
+ }
387
+ // Check disabled dates
388
+ return this.parsedDisabledDates.some(disabledDate => isSameDate(date, disabledDate, { isUTCMode: this.isUTCMode }));
389
+ };
390
+ /**
391
+ * Checks if a date is in the selected range
392
+ * @param {Date} date - Date to check
393
+ * @returns {boolean} true if the date is in the range
394
+ */
395
+ this.isDateInRange = (date) => {
396
+ if (!date || !this.startDate || !this.endDate)
397
+ return false;
398
+ const checkDate = parseDate(date, this.dateFormat);
399
+ const startDate = parseDate(this.startDate, this.dateFormat);
400
+ const endDate = parseDate(this.endDate, this.dateFormat);
401
+ // Verify if startDate and endDate are valid
402
+ if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {
403
+ return false;
404
+ }
405
+ // Verify that startDate is before endDate (additional security)
406
+ if (startDate > endDate)
407
+ return false;
408
+ // Comparison based only on the date (year, month, day)
409
+ return (isSameOrAfter(checkDate, startDate, { isUTCMode: this.isUTCMode }) &&
410
+ isSameOrBefore(checkDate, endDate, { isUTCMode: this.isUTCMode }));
411
+ };
412
+ /**
413
+ * Retrieves the localized day names
414
+ * @returns {string[]} Array of short day names
415
+ */
416
+ this.getDayNames = () => {
417
+ // If we have custom day names for this locale
418
+ if (CUSTOM_DAY_NAMES[this.locale]) {
419
+ const days = [...CUSTOM_DAY_NAMES[this.locale]];
420
+ // Reorganize the days based on the first day of the week
421
+ const firstDays = days.slice(0, this.firstDayOfWeek);
422
+ const remainingDays = days.slice(this.firstDayOfWeek);
423
+ return [...remainingDays, ...firstDays];
424
+ }
425
+ // Otherwise, use the default behavior
426
+ const formatter = new Intl.DateTimeFormat(this.locale, {
427
+ weekday: 'short',
428
+ });
429
+ const days = [...Array(7)].map((_, i) => formatter.format(new Date(2023, 0, i + 1)).toUpperCase());
430
+ // Reorganize the days based on the first day of the week
431
+ const firstDays = days.slice(0, this.firstDayOfWeek);
432
+ const remainingDays = days.slice(this.firstDayOfWeek);
433
+ return [...remainingDays, ...firstDays];
434
+ };
435
+ /**
436
+ * Generates the days of the current month
437
+ * @param {number} offset - Month offset (0 by default)
438
+ * @param {number} totalCalendars - Number of calendars to display (1 by default)
439
+ * @returns {Array<{ dayOfMonth: number | null, date: Date | null, isSelected: boolean, isDisabled: boolean }>} Array of formatted days
440
+ */
441
+ this.getDaysInMonth = (offset = 0, totalCalendars = 1) => {
442
+ const year = this.currentDate.getUTCFullYear();
443
+ const month = this.currentDate.getUTCMonth() + offset;
444
+ const firstDay = new Date(Date.UTC(year, month, 1));
445
+ const lastDay = new Date(Date.UTC(year, month + 1, 0));
446
+ const days = [];
447
+ // Correct calculation of offset for previous month days
448
+ // Use getUTCDay to stay consistent with UTC timezone
449
+ const dayOfWeekIndex = firstDay.getUTCDay(); // 0 = Sunday, 1 = Monday, etc.
450
+ // Adjust based on firstDayOfWeek (if week starts on Monday, offset is different)
451
+ const offsetDays = (dayOfWeekIndex - this.firstDayOfWeek + 7) % 7;
452
+ // Add the days of the previous month for the first calendar
453
+ if (offset === 0 && offsetDays > 0) {
454
+ const prevMonthLastDay = new Date(Date.UTC(year, month, 0)).getUTCDate();
455
+ for (let i = offsetDays; i > 0; i--) {
456
+ const date = new Date(Date.UTC(year, month - 1, prevMonthLastDay - i + 1));
457
+ days.push({
458
+ dayOfMonth: date.getUTCDate(),
459
+ date,
460
+ isCurrentMonth: false,
461
+ isDisabled: this.isDateDisabled(date),
462
+ });
463
+ }
464
+ }
465
+ // Add the days of the current month
466
+ for (let i = 1; i <= lastDay.getUTCDate(); i++) {
467
+ const date = new Date(Date.UTC(year, month, i));
468
+ days.push({
469
+ dayOfMonth: i,
470
+ date,
471
+ isCurrentMonth: true,
472
+ isDisabled: this.isDateDisabled(date),
473
+ });
474
+ }
475
+ // Add the days of the next month only for the last calendar
476
+ if (offset === totalCalendars - 1) {
477
+ const nextMonthDaysNeeded = 7 - (days.length % 7 || 7);
478
+ for (let i = 1; i <= nextMonthDaysNeeded; i++) {
479
+ const date = new Date(Date.UTC(year, month + 1, i));
480
+ days.push({
481
+ dayOfMonth: i,
482
+ date,
483
+ isCurrentMonth: false,
484
+ isDisabled: this.isDateDisabled(date),
485
+ });
486
+ }
487
+ }
488
+ return days;
489
+ };
490
+ /** Initializes the list of formatted months according to the locale */
491
+ this.initializeMonths = () => {
492
+ // If we have custom month names for this locale
493
+ if (CUSTOM_MONTH_NAMES[this.locale]) {
494
+ this.months = CUSTOM_MONTH_NAMES[this.locale].map((label, value) => ({
495
+ value,
496
+ label,
497
+ }));
498
+ return;
499
+ }
500
+ // Otherwise, use the default behavior
501
+ const formatter = new Intl.DateTimeFormat(this.locale, { month: 'short' });
502
+ this.months = Array.from({ length: 12 }, (_, i) => ({
503
+ value: i,
504
+ label: formatter.format(new Date(2000, i, 1)).toUpperCase(),
505
+ }));
506
+ };
507
+ /**
508
+ * Retrieves the localized abbreviation for "week"
509
+ * @returns {string} Localized abbreviation for "week"
510
+ */
511
+ this.getLocalizedWeekText = () => {
512
+ return WEEK_ABBREVIATIONS[this.locale] || 'W';
513
+ };
514
+ /**
515
+ * Handles month change in the selector
516
+ * @param {Event} event - Month change event
517
+ * @param {number} calendarOffset - Calendar offset (0 by default)
518
+ */
519
+ this.handleMonthChange = (event, calendarOffset = 0) => {
520
+ const select = event.target;
521
+ const selectedMonth = parseInt(select.value, 10);
522
+ const currentMonth = this.currentDate.getUTCMonth();
523
+ // Calculate the difference considering the calendar offset
524
+ const monthDiff = selectedMonth - ((currentMonth + calendarOffset) % 12);
525
+ const newDate = new Date(this.currentDate);
526
+ newDate.setUTCMonth(newDate.getUTCMonth() + monthDiff);
527
+ this.currentDate = newDate;
528
+ };
529
+ /**
530
+ * Handles year change in the numeric entry
531
+ * @param {Event} event - Year change event
532
+ * @param {number} calendarOffset - Calendar offset (0 by default)
533
+ */
534
+ this.handleYearChange = (event, calendarOffset = 0) => {
535
+ const input = event.target;
536
+ const year = parseInt(input.value, 10);
537
+ if (!isNaN(year) && year >= 1900 && year <= 2100) {
538
+ const newDate = new Date(this.currentDate);
539
+ newDate.setUTCFullYear(year);
540
+ newDate.setUTCMonth(newDate.getUTCMonth() + calendarOffset);
541
+ this.currentDate = newDate;
542
+ }
543
+ };
544
+ /**
545
+ * Handles week selection
546
+ * @param {Date[]} weekDays - Selected week days
547
+ * @param {number} calendarIndex - Calendar index from which the selection is made
548
+ */
549
+ this.handleWeekSelection = (weekDays, calendarIndex) => {
550
+ if (this.selectionType !== 'range')
551
+ return;
552
+ const allDays = this.getDaysInMonth(calendarIndex, this.numberOfCalendars);
553
+ const weekStart = weekDays[0];
554
+ const weekEnd = weekDays[weekDays.length - 1];
555
+ if (!weekStart || !weekEnd)
556
+ return;
557
+ const selectedWeekDays = allDays.filter(day => day.date && day.date >= weekStart && day.date <= weekEnd);
558
+ const validDays = selectedWeekDays.filter(day => !this.isDateDisabled(day.date));
559
+ if (validDays.length > 0) {
560
+ this.startDate = validDays[0].date;
561
+ this.endDate = validDays[validDays.length - 1].date;
562
+ this.rangeDateChange.emit({
563
+ start: formatDate(this.startDate, { dateFormat: this.dateFormat }),
564
+ end: formatDate(this.endDate, { dateFormat: this.dateFormat }),
565
+ });
566
+ }
567
+ };
568
+ /**
569
+ * Checks if a date corresponds to today
570
+ * @param {Date} date - Date to check
571
+ * @returns {boolean} true if the date is today
572
+ */
573
+ this.isToday = (date) => {
574
+ const today = new Date();
575
+ return (date.getDate() === today.getDate() &&
576
+ date.getMonth() === today.getMonth() &&
577
+ date.getFullYear() === today.getFullYear());
578
+ };
579
+ /**
580
+ * Parse and cache the disabled dates
581
+ * @description Parse and cache the disabled dates
582
+ */
583
+ this.parseDisabledDates = () => {
584
+ if (!this.disabledDates) {
585
+ this.parsedDisabledDates = [];
586
+ return;
587
+ }
588
+ try {
589
+ this.parsedDisabledDates = this.disabledDates
590
+ .map(date => parseDate(date, this.dateFormat))
591
+ .filter(date => date !== null);
592
+ }
593
+ catch (error) {
594
+ console.error('Error parsing disabled dates:', error);
595
+ this.parsedDisabledDates = [];
596
+ }
597
+ };
598
+ /**
599
+ * Applies a shortcut selection
600
+ * @param {Object} shortcut - Shortcut to apply
601
+ * @param {string | Date} shortcut.singleValue - Selected date value
602
+ * @param {Object} shortcut.rangeValue - Start and end date values
603
+ * @param {string | Date} shortcut.rangeValue.start - Start date value
604
+ * @param {string | Date} shortcut.rangeValue.end - End date value
605
+ * @param {string} shortcut.label - Label
606
+ */
607
+ this.applyShortcut = (shortcut) => {
608
+ this.selectedDate = null;
609
+ this.startDate = null;
610
+ this.endDate = null;
611
+ if (shortcut.singleValue) {
612
+ const newDate = parseDate(shortcut.singleValue, this.dateFormat);
613
+ this.selectedDate = newDate;
614
+ this.singleDateChange.emit(formatDate(newDate, { dateFormat: this.dateFormat }));
615
+ this.singleValue = formatDate(newDate, { dateFormat: this.dateFormat });
616
+ if (!this.showActions) {
617
+ const event = new CustomEvent('closePopover', {
618
+ bubbles: true,
619
+ composed: true,
620
+ });
621
+ this.el.dispatchEvent(event);
622
+ }
623
+ this.forceCalendarUpdate(newDate);
624
+ }
625
+ else {
626
+ const start = parseDate(shortcut.rangeValue.start, this.dateFormat);
627
+ const end = parseDate(shortcut.rangeValue.end, this.dateFormat);
628
+ this.startDate = start;
629
+ this.endDate = end;
630
+ this.rangeDateChange.emit({
631
+ start: formatDate(start, { dateFormat: this.dateFormat }),
632
+ end: formatDate(end, { dateFormat: this.dateFormat }),
633
+ });
634
+ this.rangeValue = {
635
+ start: formatDate(start, { dateFormat: this.dateFormat }),
636
+ end: formatDate(end, { dateFormat: this.dateFormat }),
637
+ };
638
+ if (!this.showActions) {
639
+ const event = new CustomEvent('closePopover', {
640
+ bubbles: true,
641
+ composed: true,
642
+ });
643
+ this.el.dispatchEvent(event);
644
+ }
645
+ this.forceCalendarUpdate(end);
646
+ }
647
+ };
648
+ /**
649
+ * Method to force the complete calendar update (and fix the persistent hover problem)
650
+ * @param {Date} newDate - Date to force
651
+ */
652
+ this.forceCalendarUpdate = newDate => {
653
+ this.currentDate = new Date(newDate);
654
+ this.currentDate = new Date(this.currentDate); // Force a re-render
655
+ // Reset visually the hover/touch effect
656
+ requestAnimationFrame(() => {
657
+ const days = document.querySelectorAll('.day');
658
+ days.forEach(el => {
659
+ el.classList.remove('hover', 'active', 'touched');
660
+ el.style.pointerEvents = 'none';
661
+ });
662
+ // Add specific touch handling (for mobile)
663
+ document.body.addEventListener('touchstart', this.clearTouchState, {
664
+ passive: true,
665
+ });
666
+ // Reset the touch state after 50ms
667
+ setTimeout(() => {
668
+ days.forEach(el => {
669
+ el.style.pointerEvents = '';
670
+ });
671
+ }, 50);
672
+ });
673
+ };
674
+ /**
675
+ * Function to reset the touch effect (Mobile fix)
676
+ */
677
+ this.clearTouchState = () => {
678
+ document.querySelectorAll('.day').forEach(el => {
679
+ el.classList.remove('touched');
680
+ });
681
+ // Remove the listener after the first interaction
682
+ document.body.removeEventListener('touchstart', this.clearTouchState);
683
+ };
684
+ /**
685
+ * Handles month change with an offset
686
+ * @param {number} direction - Direction (-1 for previous, 1 for next)
687
+ * @returns {Function} Change month handler
688
+ */
689
+ this.getChangeMonthHandler = (direction) => {
690
+ return () => this.changeMonth(direction);
691
+ };
692
+ /**
693
+ * Handles month change from an event (ex: dropdown)
694
+ * @param {number} offset - Month offset (0 by default)
695
+ * @returns {Function} Change month handler
696
+ */
697
+ this.getHandleMonthChange = (offset) => {
698
+ return (event) => this.handleMonthChange(event, offset);
699
+ };
700
+ /**
701
+ * Handles year change from an event (ex: dropdown)
702
+ * @param {number} offset - Year offset (0 by default)
703
+ * @returns {Function} Change year handler
704
+ */
705
+ this.getHandleYearChange = (offset) => {
706
+ return (event) => this.handleYearChange(event, offset);
707
+ };
708
+ /**
709
+ * Handles day click
710
+ * @param {Date} date - Date to handle
711
+ * @param {boolean} isDisabled - Whether the date is disabled
712
+ * @returns {Function} Day click handler
713
+ */
714
+ this.getDayClickHandler = (date, isDisabled) => {
715
+ return isDisabled ? undefined : () => this.handleDateSelection(date);
716
+ };
717
+ /**
718
+ * Handles shortcut selection
719
+ * @param {Object} shortcut - Shortcut to handle
720
+ * @param {string | Date} shortcut.singleValue - Selected date value
721
+ * @param {Object} shortcut.rangeValue - Start and end date values
722
+ * @param {string | Date} shortcut.rangeValue.start - Start date value
723
+ * @param {string | Date} shortcut.rangeValue.end - End date value
724
+ * @param {string} shortcut.label - Label
725
+ * @returns {Function} Shortcut selection handler
726
+ */
727
+ this.getShortcutHandler = (shortcut) => {
728
+ return () => this.applyShortcut(shortcut);
729
+ };
730
+ /**
731
+ * Handles week selection
732
+ * @param {Date[]} dates - Dates to handle
733
+ * @param {number} index - Calendar index
734
+ * @returns {Function} Week selection handler
735
+ */
736
+ this.getWeekSelectionHandler = (dates, index) => {
737
+ return () => {
738
+ if (this.selectionType === 'range') {
739
+ this.handleWeekSelection(dates, index);
740
+ }
741
+ };
742
+ };
127
743
  /**
128
744
  * Resets the current selection
129
745
  */
130
746
  this.resetSelection = () => {
131
747
  if (this.selectionType === 'single') {
132
748
  this.selectedDate = null;
133
- this.singleValue = '';
749
+ this.singleValue = null;
134
750
  this.singleDateChange.emit('');
135
751
  }
136
752
  else {
137
753
  this.startDate = null;
138
754
  this.endDate = null;
139
- this.rangeValue = '';
755
+ this.rangeValue = null;
140
756
  this.rangeDateChange.emit({ start: '', end: '' });
141
757
  }
142
758
  };
@@ -145,7 +761,9 @@ const NvCalendar = class {
145
761
  */
146
762
  this.confirmSelection = () => {
147
763
  if (this.selectionType === 'single' && this.selectedDate) {
148
- const dateStr = this.formatDate(this.selectedDate);
764
+ const dateStr = formatDate(this.selectedDate, {
765
+ dateFormat: this.dateFormat,
766
+ });
149
767
  this.singleDateChange.emit(dateStr);
150
768
  this.singleValue = dateStr;
151
769
  const event = new CustomEvent('closePopover', {
@@ -158,13 +776,13 @@ const NvCalendar = class {
158
776
  this.startDate &&
159
777
  this.endDate) {
160
778
  this.rangeDateChange.emit({
161
- start: this.formatDate(this.startDate),
162
- end: this.formatDate(this.endDate),
163
- });
164
- this.rangeValue = JSON.stringify({
165
- start: this.formatDate(this.startDate),
166
- end: this.formatDate(this.endDate),
779
+ start: formatDate(this.startDate, { dateFormat: this.dateFormat }),
780
+ end: formatDate(this.endDate, { dateFormat: this.dateFormat }),
167
781
  });
782
+ this.rangeValue = {
783
+ start: formatDate(this.startDate, { dateFormat: this.dateFormat }),
784
+ end: formatDate(this.endDate, { dateFormat: this.dateFormat }),
785
+ };
168
786
  const event = new CustomEvent('closePopover', {
169
787
  bubbles: true,
170
788
  composed: true,
@@ -172,353 +790,114 @@ const NvCalendar = class {
172
790
  this.el.dispatchEvent(event);
173
791
  }
174
792
  };
175
- }
176
- //#endregion EVENTS
177
- /****************************************************************************/
178
- //#region LIFECYCLE
179
- componentWillLoad() {
180
- this.parseDisabledDates();
181
- if (this.selectionType === 'single' && this.singleValue) {
182
- this.selectedDate = this.parseDate(this.singleValue);
183
- this.currentDate = this.selectedDate;
184
- }
185
- else if (this.selectionType === 'range' && this.rangeValue) {
186
- try {
187
- let parsed;
188
- if (typeof this.rangeValue === 'string') {
189
- parsed = JSON.parse(this.rangeValue);
190
- }
191
- else {
192
- parsed = this.rangeValue;
193
- }
194
- if (parsed.start && parsed.end) {
195
- this.startDate = this.parseDate(parsed.start);
196
- this.endDate = this.parseDate(parsed.end);
197
- this.currentDate = this.startDate;
198
- if (this.startDate && this.endDate && this.startDate > this.endDate) {
199
- console.warn(`Warning: startDate (${this.formatDate(this.startDate)}) is after endDate (${this.formatDate(this.endDate)})`);
200
- // [this.startDate, this.endDate] = [this.endDate, this.startDate];
201
- throw new Error('startDate cannot be after endDate');
202
- }
203
- }
204
- }
205
- catch (error) {
206
- console.error('Invalid JSON for rangeValue:', error);
207
- }
208
- }
209
- else {
210
- this.currentDate = new Date();
211
- }
212
- this.initializeMonths();
213
- }
214
- // componentDidLoad() {
215
- // if (this.rangeValue) {
216
- // this.onRangeValueChange(this.rangeValue);
217
- // }
218
- // }
219
- //#endregion LIFECYCLE
220
- /****************************************************************************/
221
- //#region METHODS
222
- /**
223
- * Change the displayed month
224
- * @param {number} offset - Month offset (-1 for previous, 1 for next)
225
- */
226
- changeMonth(offset) {
227
- const newDate = new Date(this.currentDate);
228
- // Ensure we only move by one month at a time
229
- newDate.setUTCMonth(newDate.getUTCMonth() + offset);
230
- // Add the appropriate animation class
231
- const containers = this.el.querySelectorAll('.calendar-grid');
232
- containers.forEach(container => {
233
- // Remove existing animation classes
234
- container.classList.remove('slide-left', 'slide-right');
235
- // Add the new animation class
236
- const animationClass = offset > 0 ? 'slide-left' : 'slide-right';
237
- container.classList.add(animationClass);
238
- // Remove the class after the animation
239
- setTimeout(() => {
240
- container.classList.remove(animationClass);
241
- }, 300); // 300ms corresponds to $slide-duration in the SCSS
242
- });
243
- this.currentDate = newDate;
244
- }
245
- /**
246
- * Handles date selection based on the mode
247
- * @param {Date} date - Selected date
248
- */
249
- handleDateSelection(date) {
250
- if (this.isDateDisabled(date)) {
251
- return;
252
- }
253
- if (this.selectionType === 'single') {
254
- this.handleSingleSelection(date);
255
- }
256
- else {
257
- this.handleRangeSelection(date);
258
- }
259
- }
260
- /**
261
- * Handles single date selection
262
- * @param {Date} date - Selected date
263
- */
264
- handleSingleSelection(date) {
265
- if (!date)
266
- return;
267
- const formattedDate = this.formatDate(date);
268
- this.selectedDate = date;
269
- this.singleDateChange.emit(formattedDate);
270
- }
271
- /**
272
- * Handles range date selection
273
- * @param {Date} date - Selected date
274
- */
275
- handleRangeSelection(date) {
276
- if (!this.startDate || (this.startDate && this.endDate)) {
277
- this.startDate = date;
278
- this.endDate = null;
279
- }
280
- else {
281
- this.endDate = date;
282
- if (this.startDate > this.endDate) {
283
- [this.startDate, this.endDate] = [this.endDate, this.startDate];
284
- }
285
- this.rangeDateChange.emit({
286
- start: this.formatDate(this.startDate),
287
- end: this.formatDate(this.endDate),
288
- });
289
- }
290
- }
291
- /**
292
- * Calculates the ISO week number
293
- * @param {Date} date - Date to calculate
294
- * @returns {number} Week number
295
- */
296
- getWeekNumber(date) {
297
- const startOfYear = new Date(date.getFullYear(), 0, 1);
298
- const pastDaysOfYear = (date.getTime() - startOfYear.getTime()) / 86400000;
299
- return Math.ceil((pastDaysOfYear + startOfYear.getDay() + 1) / 7);
300
- }
301
- /**
302
- * Checks if a date is disabled.
303
- * Disabled if:
304
- * - The date is before min (if defined)
305
- * - The date is after max (if defined)
306
- * - The date is in the disabledDates array
307
- * @param {Date} date - Date to check
308
- * @returns {boolean} true if the date is disabled
309
- */
310
- isDateDisabled(date) {
311
- if (!date)
312
- return true;
313
- // Minimum bound check
314
- if (this.min) {
315
- const minDate = this.parseDate(this.min);
316
- if (minDate && date < minDate) {
317
- return true;
318
- }
319
- }
320
- // Maximum bound check
321
- if (this.max) {
322
- const maxDate = this.parseDate(this.max);
323
- if (maxDate && date > maxDate) {
324
- return true;
325
- }
326
- }
327
- // Check disabled dates
328
- return this.parsedDisabledDates.some(disabledDate => this.isSameDate(date, disabledDate));
329
- }
330
- /**
331
- * Checks if a date is in the selected range
332
- * @param {Date} date - Date to check
333
- * @returns {boolean} true if the date is in the range
334
- */
335
- isDateInRange(date) {
336
- if (!date || !this.startDate || !this.endDate)
337
- return false;
338
- const checkDate = this.parseDate(date);
339
- const startDate = this.parseDate(this.startDate);
340
- const endDate = this.parseDate(this.endDate);
341
- // Verify if startDate and endDate are valid
342
- if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {
343
- return false;
344
- }
345
- // Verify that startDate is before endDate (additional security)
346
- if (startDate > endDate)
347
- return false;
348
- // Comparison based only on the date (year, month, day)
349
- return (this.isSameOrAfter(checkDate, startDate) &&
350
- this.isSameOrBefore(checkDate, endDate));
351
- }
352
- /**
353
- * Retrieves the localized day names
354
- * @returns {string[]} Array of short day names
355
- */
356
- getDayNames() {
357
- // If we have custom day names for this locale
358
- if (CUSTOM_DAY_NAMES[this.locale]) {
359
- const days = [...CUSTOM_DAY_NAMES[this.locale]];
360
- // Reorganize the days based on the first day of the week
361
- const firstDays = days.slice(0, this.firstDayOfWeek);
362
- const remainingDays = days.slice(this.firstDayOfWeek);
363
- return [...remainingDays, ...firstDays];
364
- }
365
- // Otherwise, use the default behavior
366
- const formatter = new Intl.DateTimeFormat(this.locale, {
367
- weekday: 'short',
368
- });
369
- const days = [...Array(7)].map((_, i) => formatter.format(new Date(2023, 0, i + 1)).toUpperCase());
370
- // Reorganize the days based on the first day of the week
371
- const firstDays = days.slice(0, this.firstDayOfWeek);
372
- const remainingDays = days.slice(this.firstDayOfWeek);
373
- return [...remainingDays, ...firstDays];
374
- }
375
- /**
376
- * Generates the days of the current month
377
- * @param {number} offset - Month offset (0 by default)
378
- * @param {number} totalCalendars - Number of calendars to display (1 by default)
379
- * @returns {Array<{ dayOfMonth: number | null, date: Date | null, isSelected: boolean, isDisabled: boolean }>} Array of formatted days
380
- */
381
- getDaysInMonth(offset = 0, totalCalendars = 1) {
382
- const year = this.currentDate.getUTCFullYear();
383
- const month = this.currentDate.getUTCMonth() + offset;
384
- const firstDay = new Date(Date.UTC(year, month, 1));
385
- const lastDay = new Date(Date.UTC(year, month + 1, 0));
386
- const days = [];
387
- // Correct calculation of offset for previous month days
388
- // Use getUTCDay to stay consistent with UTC timezone
389
- const dayOfWeekIndex = firstDay.getUTCDay(); // 0 = Sunday, 1 = Monday, etc.
390
- // Adjust based on firstDayOfWeek (if week starts on Monday, offset is different)
391
- const offsetDays = (dayOfWeekIndex - this.firstDayOfWeek + 7) % 7;
392
- // Add the days of the previous month for the first calendar
393
- if (offset === 0 && offsetDays > 0) {
394
- const prevMonthLastDay = new Date(Date.UTC(year, month, 0)).getUTCDate();
395
- for (let i = offsetDays; i > 0; i--) {
396
- const date = new Date(Date.UTC(year, month - 1, prevMonthLastDay - i + 1));
397
- days.push({
398
- dayOfMonth: date.getUTCDate(),
399
- date,
400
- isCurrentMonth: false,
401
- isDisabled: this.isDateDisabled(date),
793
+ //#endregion METHODS
794
+ /****************************************************************************/
795
+ //#region RENDER
796
+ /**
797
+ * Renders the header
798
+ * @param {number} offset - Month offset
799
+ * @param {number} index - Calendar index
800
+ * @returns {JSX.Element} Header
801
+ * @description Renders the header of the calendar
802
+ */
803
+ this.renderHeader = (offset, index) => {
804
+ return (h("div", { class: "header" }, this.numberOfCalendars > 1 && index === 0 && (h("nv-iconbutton", { class: "nav-left", emphasis: "lower", name: "chevron-left", onClick: this.getChangeMonthHandler(-1) })), h("div", { class: "date-controls" }, h("select", { class: "month-select mr-4", onChange: this.getHandleMonthChange(offset) }, this.months.map(month => (h("option", { key: month.value, value: month.value, selected: month.value === (this.currentDate.getUTCMonth() + offset) % 12 }, month.label)))), h("input", { type: "number", class: "year-input", min: "1950", max: "2100", value: this.currentDate.getUTCFullYear() +
805
+ Math.floor((this.currentDate.getUTCMonth() + offset) / 12), onChange: this.getHandleYearChange(offset) })), this.numberOfCalendars === 1 && (h("div", { class: "nav-buttons" }, h("nv-iconbutton", { emphasis: "lower", name: "chevron-left", onClick: this.getChangeMonthHandler(-1) }), h("nv-iconbutton", { emphasis: "lower", name: "chevron-right", onClick: this.getChangeMonthHandler(1) }))), this.numberOfCalendars > 1 && index === this.numberOfCalendars - 1 && (h("nv-iconbutton", { emphasis: "lower", name: "chevron-right", onClick: this.getChangeMonthHandler(1), class: "nav-right" }))));
806
+ };
807
+ /**
808
+ * Renders the week numbers
809
+ * @param {Array<{date: Date}>} weeks - Weeks to render
810
+ * @param {number} index - Calendar index
811
+ * @returns {JSX.Element} Week numbers
812
+ * @description Renders the week numbers of the calendar
813
+ */
814
+ this.renderWeekNumbers = (
815
+ /** Weeks to render */
816
+ weeks,
817
+ /** Calendar index */
818
+ index) => {
819
+ return (h("div", { class: "week-numbers" }, h("div", { class: "week-header" }, this.getLocalizedWeekText()), weeks.map((week, weekIndex) => {
820
+ var _a;
821
+ const dates = week.map(d => d.date);
822
+ return (h("div", { class: `week-number ${this.selectionType === 'range' ? 'clickable' : ''}`, onClick: this.getWeekSelectionHandler(dates, index), key: `week-${weekIndex}` }, getWeekNumber(((_a = week.find(d => d.date)) === null || _a === void 0 ? void 0 : _a.date) || new Date())));
823
+ })));
824
+ };
825
+ this.renderDaysGrid = (
826
+ /** Days to render */
827
+ days) => {
828
+ return (h("div", { class: "days-grid" }, days.map(day => {
829
+ const date = day.date;
830
+ if (!date)
831
+ return null;
832
+ const isSelected = this.selectionType === 'single' &&
833
+ isSameDate(date, this.selectedDate, { isUTCMode: this.isUTCMode });
834
+ const isInRange = this.isDateInRange(date);
835
+ const isStart = isSameDate(date, this.startDate, {
836
+ isUTCMode: this.isUTCMode,
402
837
  });
403
- }
404
- }
405
- // Add the days of the current month
406
- for (let i = 1; i <= lastDay.getUTCDate(); i++) {
407
- const date = new Date(Date.UTC(year, month, i));
408
- days.push({
409
- dayOfMonth: i,
410
- date,
411
- isCurrentMonth: true,
412
- isDisabled: this.isDateDisabled(date),
413
- });
414
- }
415
- // Add the days of the next month only for the last calendar
416
- if (offset === totalCalendars - 1) {
417
- const nextMonthDaysNeeded = 7 - (days.length % 7 || 7);
418
- for (let i = 1; i <= nextMonthDaysNeeded; i++) {
419
- const date = new Date(Date.UTC(year, month + 1, i));
420
- days.push({
421
- dayOfMonth: i,
422
- date,
423
- isCurrentMonth: false,
424
- isDisabled: this.isDateDisabled(date),
838
+ const isEnd = isSameDate(date, this.endDate, {
839
+ isUTCMode: this.isUTCMode,
425
840
  });
841
+ const isToday = this.isToday(date);
842
+ const isOutsideMonth = !day.isCurrentMonth;
843
+ const dayClasses = [
844
+ 'day',
845
+ isSelected ? 'selected' : '',
846
+ isStart ? 'range-start' : '',
847
+ isEnd ? 'range-end' : '',
848
+ isInRange ? 'in-range' : '',
849
+ day.isDisabled ? 'disabled' : '',
850
+ isOutsideMonth ? 'outside-month' : '',
851
+ isToday ? 'is-today' : '',
852
+ ];
853
+ return (h("div", { class: dayClasses.filter(Boolean).join(' '), onClick: this.getDayClickHandler(date, day.isDisabled), "aria-disabled": day.isDisabled, key: `day-${date.toISOString()}` }, day.dayOfMonth));
854
+ })));
855
+ };
856
+ /**
857
+ * Renders the calendar
858
+ * @param {number} index - Calendar index
859
+ * @param {number} offset - Month offset
860
+ * @returns {JSX.Element} Calendar
861
+ * @description Renders the calendar of the calendar
862
+ */
863
+ this.renderCalendar = (
864
+ /** Calendar index */
865
+ index,
866
+ /** Month offset */
867
+ offset) => {
868
+ const days = this.getDaysInMonth(offset, this.numberOfCalendars);
869
+ const weeks = [];
870
+ for (let i = 0; i < days.length; i += 7) {
871
+ weeks.push(days.slice(i, i + 7));
426
872
  }
427
- }
428
- return days;
429
- }
430
- /** Initializes the list of formatted months according to the locale */
431
- initializeMonths() {
432
- // If we have custom month names for this locale
433
- if (CUSTOM_MONTH_NAMES[this.locale]) {
434
- this.months = CUSTOM_MONTH_NAMES[this.locale].map((label, value) => ({
435
- value,
436
- label,
437
- }));
438
- return;
439
- }
440
- // Otherwise, use the default behavior
441
- const formatter = new Intl.DateTimeFormat(this.locale, { month: 'short' });
442
- this.months = Array.from({ length: 12 }, (_, i) => ({
443
- value: i,
444
- label: formatter.format(new Date(2000, i, 1)).toUpperCase(),
445
- }));
446
- }
447
- /**
448
- * Retrieves the localized abbreviation for "week"
449
- * @returns {string} Localized abbreviation for "week"
450
- */
451
- getLocalizedWeekText() {
452
- return WEEK_ABBREVIATIONS[this.locale] || 'W';
453
- }
454
- /**
455
- * Handles month change in the selector
456
- * @param {Event} event - Month change event
457
- * @param {number} calendarOffset - Calendar offset (0 by default)
458
- */
459
- handleMonthChange(event, calendarOffset = 0) {
460
- const select = event.target;
461
- const selectedMonth = parseInt(select.value, 10);
462
- const currentMonth = this.currentDate.getUTCMonth();
463
- // Calculate the difference considering the calendar offset
464
- const monthDiff = selectedMonth - ((currentMonth + calendarOffset) % 12);
465
- const newDate = new Date(this.currentDate);
466
- newDate.setUTCMonth(newDate.getUTCMonth() + monthDiff);
467
- this.currentDate = newDate;
468
- }
469
- /**
470
- * Handles year change in the numeric entry
471
- * @param {Event} event - Year change event
472
- * @param {number} calendarOffset - Calendar offset (0 by default)
473
- */
474
- handleYearChange(event, calendarOffset = 0) {
475
- const input = event.target;
476
- const year = parseInt(input.value, 10);
477
- if (!isNaN(year) && year >= 1900 && year <= 2100) {
478
- const newDate = new Date(this.currentDate);
479
- newDate.setUTCFullYear(year);
480
- newDate.setUTCMonth(newDate.getUTCMonth() + calendarOffset);
481
- this.currentDate = newDate;
482
- }
483
- }
484
- /**
485
- * Handles week selection
486
- * @param {Date[]} weekDays - Selected week days
487
- * @param {number} calendarIndex - Calendar index from which the selection is made
488
- */
489
- handleWeekSelection(weekDays, calendarIndex) {
490
- if (this.selectionType !== 'range')
491
- return;
492
- const allDays = this.getDaysInMonth(calendarIndex, this.numberOfCalendars);
493
- const weekStart = weekDays[0];
494
- const weekEnd = weekDays[weekDays.length - 1];
495
- if (!weekStart || !weekEnd)
496
- return;
497
- const selectedWeekDays = allDays.filter(day => day.date && day.date >= weekStart && day.date <= weekEnd);
498
- const validDays = selectedWeekDays.filter(day => !this.isDateDisabled(day.date));
499
- if (validDays.length > 0) {
500
- this.startDate = validDays[0].date;
501
- this.endDate = validDays[validDays.length - 1].date;
502
- this.rangeDateChange.emit({
503
- start: this.formatDate(this.startDate),
504
- end: this.formatDate(this.endDate),
505
- });
506
- }
507
- }
508
- /**
509
- * Checks if a date corresponds to today
510
- * @param {Date} date - Date to check
511
- * @returns {boolean} true if the date is today
512
- */
513
- isToday(date) {
514
- const today = new Date();
515
- return (date.getDate() === today.getDate() &&
516
- date.getMonth() === today.getMonth() &&
517
- date.getFullYear() === today.getFullYear());
873
+ return (h("div", { class: "calendar-wrapper" }, h("div", { class: "calendar-container", key: `calendar-${index}` }, this.renderHeader(offset, index), h("div", { class: "calendar-grid" }, this.showWeekNumbers && this.renderWeekNumbers(weeks, index), h("div", { class: "days-container" }, h("div", { class: "days-header" }, this.getDayNames().map(day => (h("div", { class: "day-header" }, day)))), this.renderDaysGrid(days)))), index < this.numberOfCalendars - 1 && (h("div", { class: "calendar-separator" }))));
874
+ };
875
+ /**
876
+ * Renders the shortcuts
877
+ * @returns {JSX.Element} Shortcuts
878
+ * @description Renders the shortcuts of the calendar
879
+ */
880
+ this.renderShortcuts = () => {
881
+ if (!this.hasShortcuts) {
882
+ return null;
883
+ }
884
+ return (h("div", { class: `shortcuts-container shortcuts-placement-${this.shortcutsPlacement}` }, this.shortcuts.map(shortcut => (h("nv-button", { emphasis: "lower", size: "xs", "aria-label": shortcut.label, onClick: this.getShortcutHandler(shortcut) }, shortcut.label)))));
885
+ };
886
+ /**
887
+ * Renders the actions
888
+ * @returns {JSX.Element} Actions
889
+ * @description Renders the actions of the calendar
890
+ * @slot actions - Child content of the component.
891
+ */
892
+ this.renderActions = () => {
893
+ return (h("div", { class: "datepicker-actions" }, h("slot", { name: "actions" }, h("nv-button", { emphasis: "low", size: "xs", onClick: this.resetSelection }, "Cancel"), h("nv-button", { size: "xs", onClick: this.confirmSelection }, "OK"))));
894
+ };
518
895
  }
896
+ //#endregion EVENTS
897
+ /****************************************************************************/
898
+ //#region WATCHERS
519
899
  /**
520
900
  * Watches the changes of the number of calendars
521
- * @watch numberOfCalendars
522
901
  * @param {number} newValue - New number of calendars
523
902
  */
524
903
  validateNumberOfCalendars(newValue) {
@@ -529,29 +908,25 @@ const NvCalendar = class {
529
908
  }
530
909
  /**
531
910
  * Watches the changes of the selected date range
532
- * @watch rangeValue
533
911
  * @param {Object} newValue - New rangeValue value
534
912
  * @param {string} newValue.start - Start date
535
913
  * @param {string} newValue.end - End date
536
914
  */
537
915
  onRangeValueChange(newValue) {
538
- if (newValue) {
916
+ if (newValue && newValue.start && newValue.end) {
539
917
  try {
540
- const parsed = JSON.parse(newValue);
541
- if (parsed.start && parsed.end) {
542
- this.startDate = this.parseDate(parsed.start);
543
- this.endDate = this.parseDate(parsed.end);
544
- this.currentDate = this.parseDate(parsed.start);
545
- }
918
+ const { startDate, endDate } = this.validateDateRange(newValue.start, newValue.end);
919
+ this.startDate = startDate;
920
+ this.endDate = endDate;
921
+ this.currentDate = startDate;
546
922
  }
547
923
  catch (error) {
548
- console.error('Invalid JSON for rangeValue:', error);
924
+ console.error('Invalid rangeValue:', error);
549
925
  }
550
926
  }
551
927
  }
552
928
  /**
553
929
  * Watches the changes of the disabled dates
554
- * @watch disabledDates
555
930
  * @description Watches the changes of the disabled dates
556
931
  */
557
932
  handleDisabledDatesChange() {
@@ -559,381 +934,61 @@ const NvCalendar = class {
559
934
  }
560
935
  /**
561
936
  * Watches the changes of the single value
562
- * @watch singleValue
563
937
  * @param {string} newValue - New single value
564
938
  * @param {string} oldValue - Old single value
565
939
  */
566
940
  onSingleValueChange(newValue, oldValue) {
567
941
  if (this.selectionType === 'single' && newValue !== oldValue && newValue) {
568
- const parsedDate = this.parseDate(newValue);
942
+ const parsedDate = parseDate(newValue, this.dateFormat);
569
943
  if (parsedDate) {
570
944
  this.selectedDate = parsedDate;
571
945
  this.currentDate = parsedDate;
572
946
  }
573
947
  }
574
948
  }
575
- /**
576
- * Convert a date string/Date to a Date without timezone offset
577
- * @param {string | Date} dateInput - Date under string or Date object form
578
- * @returns {Date} Date in Date form without timezone offset
579
- */
580
- parseDate(dateInput) {
581
- if (dateInput instanceof Date)
582
- return dateInput;
583
- // Attempt to automatically detect ISO 8601 format (generated by toISOString())
584
- // The regex checks the standard ISO format: YYYY-MM-DDTHH:mm:ss.sssZ
585
- if (typeof dateInput === 'string' &&
586
- /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$/.test(dateInput)) {
949
+ //#endregion WATCHERS
950
+ /****************************************************************************/
951
+ //#region LIFECYCLE
952
+ componentWillLoad() {
953
+ this.parseDisabledDates();
954
+ if (this.selectionType === 'single' && this.singleValue) {
955
+ this.selectedDate = parseDate(this.singleValue, this.dateFormat);
956
+ this.currentDate = this.selectedDate;
957
+ }
958
+ else if (this.selectionType === 'range' && this.rangeValue) {
587
959
  try {
588
- const parsedDate = new Date(dateInput);
589
- if (!isNaN(parsedDate.getTime())) {
590
- return parsedDate;
960
+ if (this.rangeValue.start && this.rangeValue.end) {
961
+ const { startDate, endDate, swapped } = this.validateDateRange(this.rangeValue.start, this.rangeValue.end);
962
+ this.startDate = startDate;
963
+ this.endDate = endDate;
964
+ this.currentDate = startDate;
965
+ if (swapped) {
966
+ // If dates were swapped, update the rangeValue property
967
+ this.rangeValue = {
968
+ start: formatDate(startDate, { dateFormat: this.dateFormat }),
969
+ end: formatDate(endDate, { dateFormat: this.dateFormat }),
970
+ };
971
+ }
591
972
  }
592
973
  }
593
974
  catch (error) {
594
- // If it fails, continue with other methods
595
- console.error('Error parsing ISO date:', error);
596
- }
597
- }
598
- // Handling Unix Seconds ("X") formats
599
- if (this.dateFormat === 'X') {
600
- const unixSeconds = Number(dateInput);
601
- if (isNaN(unixSeconds))
602
- return null;
603
- return this.isUTCMode
604
- ? dayjs.unix(unixSeconds).utc().toDate()
605
- : dayjs.unix(unixSeconds).toDate();
606
- }
607
- // Handling Unix Milliseconds ("x") formats
608
- if (this.dateFormat === 'x') {
609
- const unixMilliseconds = Number(dateInput);
610
- if (isNaN(unixMilliseconds))
611
- return null;
612
- return this.isUTCMode
613
- ? dayjs(unixMilliseconds).utc().toDate()
614
- : dayjs(unixMilliseconds).toDate();
615
- }
616
- // Handling C# Ticks format
617
- if (this.dateFormat === 'Ticks') {
618
- const ticks = Number(dateInput);
619
- if (isNaN(ticks))
620
- return null;
621
- // Conversion of .NET ticks to milliseconds since Unix epoch
622
- const unixMilliseconds = (ticks - 621355968000000000) / 10000;
623
- return this.isUTCMode
624
- ? dayjs(unixMilliseconds).utc().toDate()
625
- : dayjs(unixMilliseconds).toDate();
626
- }
627
- // For all other formats, use customParseFormat in strict mode
628
- let parsed;
629
- if (this.isUTCMode) {
630
- parsed = dayjs.utc(dateInput, this.dateFormat, true);
631
- }
632
- else {
633
- parsed = dayjs(dateInput, this.dateFormat, true);
634
- }
635
- if (!parsed.isValid()) {
636
- console.error(`Parsing error:`, {
637
- dateInput,
638
- dateFormat: this.dateFormat,
639
- });
640
- return null;
641
- }
642
- return parsed.toDate();
643
- }
644
- /**
645
- * Checks if the date format is in UTC mode
646
- * @returns {boolean} true if the date format is in UTC mode
647
- */
648
- get isUTCMode() {
649
- return this.dateFormat.includes('Z');
650
- }
651
- /**
652
- * Checks if the date format is ISO 8601
653
- * @returns {boolean} true if the format is ISO 8601
654
- */
655
- get isISO8601Format() {
656
- return this.dateFormat === 'YYYY-MM-DD[T]HH:mm:ss[Z]';
657
- }
658
- /**
659
- * Formats a date to a string according to the format
660
- * @param {Date} date - Date to format
661
- * @returns {string} Formatted date
662
- */
663
- formatDate(date) {
664
- if (!date)
665
- return '';
666
- // Special case for ISO 8601
667
- if (this.isISO8601Format) {
668
- // For the ISO 8601 format, use directly toISOString() which is standard
669
- return date.toISOString();
670
- }
671
- // If the format is "Ticks", convert the time to C# ticks
672
- if (this.dateFormat === 'Ticks') {
673
- const ticks = date.getTime() * 10000 + 621355968000000000;
674
- return ticks.toString();
675
- }
676
- // If the format is "X" (Unix Seconds)
677
- if (this.dateFormat === 'X') {
678
- return dayjs(date).unix().toString();
679
- }
680
- // If the format is "x" (Unix Milliseconds)
681
- if (this.dateFormat === 'x') {
682
- return date.getTime().toString();
683
- }
684
- // Otherwise, format according to the mode (UTC or local)
685
- return this.isUTCMode
686
- ? dayjs(date).utc().format(this.dateFormat)
687
- : dayjs(date).format(this.dateFormat);
688
- }
689
- /**
690
- * Parse and cache the disabled dates
691
- * @description Parse and cache the disabled dates
692
- */
693
- parseDisabledDates() {
694
- if (!this.disabledDates) {
695
- this.parsedDisabledDates = [];
696
- return;
697
- }
698
- try {
699
- const disabledDatesArray = JSON.parse(this.disabledDates);
700
- this.parsedDisabledDates = disabledDatesArray
701
- .map(date => this.parseDate(date))
702
- .filter(date => date !== null);
703
- }
704
- catch (error) {
705
- console.error('Error parsing disabled dates:', error);
706
- this.parsedDisabledDates = [];
707
- }
708
- }
709
- /**
710
- * Checks if two dates are identical
711
- * @param {Date | null} date1 - First date
712
- * @param {Date | null} date2 - Second date
713
- * @returns {boolean} true if the dates are identical
714
- */
715
- isSameDate(date1, date2) {
716
- if (!date1 || !date2)
717
- return false;
718
- if (this.isUTCMode) {
719
- return (date1.getUTCFullYear() === date2.getUTCFullYear() &&
720
- date1.getUTCMonth() === date2.getUTCMonth() &&
721
- date1.getUTCDate() === date2.getUTCDate());
722
- }
723
- else {
724
- return (date1.getFullYear() === date2.getFullYear() &&
725
- date1.getMonth() === date2.getMonth() &&
726
- date1.getDate() === date2.getDate());
727
- }
728
- }
729
- /**
730
- * Checks if a date is identical or after another date
731
- * @param {Date} date - Date to check
732
- * @param {Date} compareDate - Reference date
733
- * @returns {boolean} true if `date` >= `compareDate`
734
- */
735
- isSameOrAfter(date, compareDate) {
736
- if (this.isUTCMode) {
737
- return (date.getUTCFullYear() > compareDate.getUTCFullYear() ||
738
- (date.getUTCFullYear() === compareDate.getUTCFullYear() &&
739
- date.getUTCMonth() > compareDate.getUTCMonth()) ||
740
- (date.getUTCFullYear() === compareDate.getUTCFullYear() &&
741
- date.getUTCMonth() === compareDate.getUTCMonth() &&
742
- date.getUTCDate() >= compareDate.getUTCDate()));
743
- }
744
- else {
745
- return (date.getFullYear() > compareDate.getFullYear() ||
746
- (date.getFullYear() === compareDate.getFullYear() &&
747
- date.getMonth() > compareDate.getMonth()) ||
748
- (date.getFullYear() === compareDate.getFullYear() &&
749
- date.getMonth() === compareDate.getMonth() &&
750
- date.getDate() >= compareDate.getDate()));
751
- }
752
- }
753
- /**
754
- * Checks if a date is identical or before another date
755
- * @param {Date} date - Date to check
756
- * @param {Date} compareDate - Reference date
757
- * @returns {boolean} true if `date` <= `compareDate`
758
- */
759
- isSameOrBefore(date, compareDate) {
760
- if (this.isUTCMode) {
761
- return (date.getUTCFullYear() < compareDate.getUTCFullYear() ||
762
- (date.getUTCFullYear() === compareDate.getUTCFullYear() &&
763
- date.getUTCMonth() < compareDate.getUTCMonth()) ||
764
- (date.getUTCFullYear() === compareDate.getUTCFullYear() &&
765
- date.getUTCMonth() === compareDate.getUTCMonth() &&
766
- date.getUTCDate() <= compareDate.getUTCDate()));
767
- }
768
- else {
769
- return (date.getFullYear() < compareDate.getFullYear() ||
770
- (date.getFullYear() === compareDate.getFullYear() &&
771
- date.getMonth() < compareDate.getMonth()) ||
772
- (date.getFullYear() === compareDate.getFullYear() &&
773
- date.getMonth() === compareDate.getMonth() &&
774
- date.getDate() <= compareDate.getDate()));
775
- }
776
- }
777
- /**
778
- * Applies a shortcut selection
779
- * @param {Object} shortcut - Shortcut to apply
780
- * @param {string | Date} shortcut.singleValue - Selected date value
781
- * @param {Object} shortcut.rangeValue - Start and end date values
782
- * @param {string | Date} shortcut.rangeValue.start - Start date value
783
- * @param {string | Date} shortcut.rangeValue.end - End date value
784
- * @param {string} shortcut.label - Label
785
- */
786
- applyShortcut(shortcut) {
787
- this.selectedDate = null;
788
- this.startDate = null;
789
- this.endDate = null;
790
- if (shortcut.singleValue) {
791
- const newDate = this.parseDate(shortcut.singleValue);
792
- this.selectedDate = newDate;
793
- this.singleDateChange.emit(this.formatDate(newDate));
794
- this.singleValue = this.formatDate(newDate);
795
- if (!this.showActions) {
796
- const event = new CustomEvent('closePopover', {
797
- bubbles: true,
798
- composed: true,
799
- });
800
- this.el.dispatchEvent(event);
975
+ console.error('Invalid rangeValue:', error);
801
976
  }
802
- this.forceCalendarUpdate(newDate);
803
977
  }
804
978
  else {
805
- const start = this.parseDate(shortcut.rangeValue.start);
806
- const end = this.parseDate(shortcut.rangeValue.end);
807
- this.startDate = start;
808
- this.endDate = end;
809
- this.rangeDateChange.emit({
810
- start: this.formatDate(start),
811
- end: this.formatDate(end),
812
- });
813
- this.rangeValue = JSON.stringify({
814
- start: this.formatDate(start),
815
- end: this.formatDate(end),
816
- });
817
- if (!this.showActions) {
818
- const event = new CustomEvent('closePopover', {
819
- bubbles: true,
820
- composed: true,
821
- });
822
- this.el.dispatchEvent(event);
823
- }
824
- this.forceCalendarUpdate(end);
825
- }
826
- }
827
- /**
828
- * Method to force the complete calendar update (and fix the persistent hover problem)
829
- * @param {Date} newDate - Date to force
830
- */
831
- forceCalendarUpdate(newDate) {
832
- this.currentDate = new Date(newDate);
833
- this.currentDate = new Date(this.currentDate); // Force a re-render
834
- // Reset visually the hover/touch effect
835
- requestAnimationFrame(() => {
836
- const days = document.querySelectorAll('.day');
837
- days.forEach(el => {
838
- el.classList.remove('hover', 'active', 'touched');
839
- el.style.pointerEvents = 'none';
840
- });
841
- // Add specific touch handling (for mobile)
842
- document.body.addEventListener('touchstart', this.clearTouchState, {
843
- passive: true,
844
- });
845
- // Reset the touch state after 50ms
846
- setTimeout(() => {
847
- days.forEach(el => {
848
- el.style.pointerEvents = '';
849
- });
850
- }, 50);
851
- });
852
- }
853
- /**
854
- * Function to reset the touch effect (Mobile fix)
855
- */
856
- clearTouchState() {
857
- document.querySelectorAll('.day').forEach(el => {
858
- el.classList.remove('touched');
859
- });
860
- // Remove the listener after the first interaction
861
- document.body.removeEventListener('touchstart', this.clearTouchState);
862
- }
863
- /**
864
- * Handles month change with an offset
865
- * @param {number} direction - Direction (-1 for previous, 1 for next)
866
- * @returns {Function} Change month handler
867
- */
868
- getChangeMonthHandler(direction) {
869
- return () => this.changeMonth(direction);
870
- }
871
- /**
872
- * Handles month change from an event (ex: dropdown)
873
- * @param {number} offset - Month offset (0 by default)
874
- * @returns {Function} Change month handler
875
- */
876
- getHandleMonthChange(offset) {
877
- return (event) => this.handleMonthChange(event, offset);
878
- }
879
- /**
880
- * Handles year change from an event (ex: dropdown)
881
- * @param {number} offset - Year offset (0 by default)
882
- * @returns {Function} Change year handler
883
- */
884
- getHandleYearChange(offset) {
885
- return (event) => this.handleYearChange(event, offset);
886
- }
887
- /**
888
- * Handles day click
889
- * @param {Date} date - Date to handle
890
- * @param {boolean} isDisabled - Whether the date is disabled
891
- * @returns {Function} Day click handler
892
- */
893
- getDayClickHandler(date, isDisabled) {
894
- return isDisabled ? undefined : () => this.handleDateSelection(date);
895
- }
896
- /**
897
- * Handles shortcut selection
898
- * @param {Object} shortcut - Shortcut to handle
899
- * @param {string | Date} shortcut.singleValue - Selected date value
900
- * @param {Object} shortcut.rangeValue - Start and end date values
901
- * @param {string | Date} shortcut.rangeValue.start - Start date value
902
- * @param {string | Date} shortcut.rangeValue.end - End date value
903
- * @param {string} shortcut.label - Label
904
- * @returns {Function} Shortcut selection handler
905
- */
906
- getShortcutHandler(shortcut) {
907
- return () => this.applyShortcut(shortcut);
908
- }
909
- /**
910
- * Handles week selection
911
- * @param {Date[]} dates - Dates to handle
912
- * @param {number} index - Calendar index
913
- * @returns {Function} Week selection handler
914
- */
915
- getWeekSelectionHandler(dates, index) {
916
- return () => {
917
- if (this.selectionType === 'range') {
918
- this.handleWeekSelection(dates, index);
919
- }
920
- };
921
- }
922
- parsedShortcuts() {
923
- try {
924
- return this.shortcuts ? JSON.parse(this.shortcuts) : [];
925
- }
926
- catch (error) {
927
- console.error('Invalid JSON for shortcuts:', error);
928
- return [];
979
+ this.currentDate = new Date();
929
980
  }
981
+ this.initializeMonths();
930
982
  }
983
+ //#endregion LIFECYCLE
984
+ /****************************************************************************/
985
+ //#region METHODS
931
986
  /**
932
987
  * Checks if shortcuts are visible
933
988
  * @returns {boolean} true if shortcuts are visible
934
989
  */
935
990
  get hasShortcuts() {
936
- return (this.shortcutsPlacement === 'bottom' && this.parsedShortcuts().length > 0);
991
+ return Boolean(this.shortcutsPlacement && this.shortcuts);
937
992
  }
938
993
  /**
939
994
  * Checks if actions are visible
@@ -942,103 +997,46 @@ const NvCalendar = class {
942
997
  get hasActions() {
943
998
  return this.showActions;
944
999
  }
945
- //#endregion METHODS
946
- /****************************************************************************/
947
- //#region RENDER
948
- /**
949
- * Renders the header
950
- * @param {number} offset - Month offset
951
- * @param {number} index - Calendar index
952
- * @returns {JSX.Element} Header
953
- * @description Renders the header of the calendar
954
- */
955
- renderHeader(offset, index) {
956
- return (h("div", { class: "header" }, this.numberOfCalendars > 1 && index === 0 && (h("nv-iconbutton", { class: "nav-left", emphasis: "lower", name: "chevron-left", onClick: this.getChangeMonthHandler(-1) })), h("div", { class: "date-controls" }, h("select", { class: "month-select mr-4", onChange: this.getHandleMonthChange(offset) }, this.months.map(month => (h("option", { key: month.value, value: month.value, selected: month.value === (this.currentDate.getUTCMonth() + offset) % 12 }, month.label)))), h("input", { type: "number", class: "year-input", min: "1950", max: "2100", value: this.currentDate.getUTCFullYear() +
957
- Math.floor((this.currentDate.getUTCMonth() + offset) / 12), onChange: this.getHandleYearChange(offset) })), this.numberOfCalendars === 1 && (h("div", { class: "nav-buttons" }, h("nv-iconbutton", { emphasis: "lower", name: "chevron-left", onClick: this.getChangeMonthHandler(-1) }), h("nv-iconbutton", { emphasis: "lower", name: "chevron-right", onClick: this.getChangeMonthHandler(1) }))), this.numberOfCalendars > 1 && index === this.numberOfCalendars - 1 && (h("nv-iconbutton", { emphasis: "lower", name: "chevron-right", onClick: this.getChangeMonthHandler(1), class: "nav-right" }))));
958
- }
959
1000
  /**
960
- * Renders the week numbers
961
- * @param {Array<{date: Date}>} weeks - Weeks to render
962
- * @param {number} index - Calendar index
963
- * @returns {JSX.Element} Week numbers
964
- * @description Renders the week numbers of the calendar
1001
+ * Checks if the date format is in UTC mode
1002
+ * @returns {boolean} true if the date format is in UTC mode
965
1003
  */
966
- renderWeekNumbers(
967
- /** Weeks to render */
968
- weeks,
969
- /** Calendar index */
970
- index) {
971
- return (h("div", { class: "week-numbers" }, h("div", { class: "week-header" }, this.getLocalizedWeekText()), weeks.map((week, weekIndex) => {
972
- var _a;
973
- const dates = week.map(d => d.date);
974
- return (h("div", { class: `week-number ${this.selectionType === 'range' ? 'clickable' : ''}`, onClick: this.getWeekSelectionHandler(dates, index), key: `week-${weekIndex}` }, this.getWeekNumber(((_a = week.find(d => d.date)) === null || _a === void 0 ? void 0 : _a.date) || new Date())));
975
- })));
976
- }
977
- renderDaysGrid(
978
- /** Days to render */
979
- days) {
980
- return (h("div", { class: "days-grid" }, days.map(day => {
981
- const date = day.date;
982
- if (!date)
983
- return null;
984
- const isSelected = this.selectionType === 'single' &&
985
- this.isSameDate(date, this.selectedDate);
986
- const isInRange = this.isDateInRange(date);
987
- const isStart = this.isSameDate(date, this.startDate);
988
- const isEnd = this.isSameDate(date, this.endDate);
989
- const isToday = this.isToday(date);
990
- const isOutsideMonth = !day.isCurrentMonth;
991
- const dayClasses = [
992
- 'day',
993
- isSelected ? 'selected' : '',
994
- isStart ? 'range-start' : '',
995
- isEnd ? 'range-end' : '',
996
- isInRange ? 'in-range' : '',
997
- day.isDisabled ? 'disabled' : '',
998
- isOutsideMonth ? 'outside-month' : '',
999
- isToday ? 'is-today' : '',
1000
- ];
1001
- return (h("div", { class: dayClasses.filter(Boolean).join(' '), onClick: this.getDayClickHandler(date, day.isDisabled), "aria-disabled": day.isDisabled, key: `day-${date.toISOString()}` }, day.dayOfMonth));
1002
- })));
1004
+ get isUTCMode() {
1005
+ return this.dateFormat.includes('Z');
1003
1006
  }
1004
1007
  /**
1005
- * Renders the calendar
1006
- * @param {number} index - Calendar index
1007
- * @param {number} offset - Month offset
1008
- * @returns {JSX.Element} Calendar
1009
- * @description Renders the calendar of the calendar
1008
+ * Validates and processes a date range, warning if start is after end
1009
+ * @param {string} startDateStr - Start date in ISO string format
1010
+ * @param {string} endDateStr - End date in ISO string format
1011
+ * @returns {object} Object containing the validated start and end dates
1010
1012
  */
1011
- renderCalendar(
1012
- /** Calendar index */
1013
- index,
1014
- /** Month offset */
1015
- offset) {
1016
- const days = this.getDaysInMonth(offset, this.numberOfCalendars);
1017
- const weeks = [];
1018
- for (let i = 0; i < days.length; i += 7) {
1019
- weeks.push(days.slice(i, i + 7));
1013
+ validateDateRange(startDateStr, endDateStr) {
1014
+ try {
1015
+ const startDate = parseDate(startDateStr, this.dateFormat);
1016
+ const endDate = parseDate(endDateStr, this.dateFormat);
1017
+ if (startDate && endDate && startDate > endDate) {
1018
+ console.warn(`Warning: startDate (${formatDate(startDate, {
1019
+ dateFormat: this.dateFormat,
1020
+ })}) is after endDate (${formatDate(endDate, {
1021
+ dateFormat: this.dateFormat,
1022
+ })})`);
1023
+ // Return dates in correct order, with swapped flag
1024
+ return {
1025
+ startDate: endDate,
1026
+ endDate: startDate,
1027
+ swapped: true,
1028
+ };
1029
+ }
1030
+ return {
1031
+ startDate,
1032
+ endDate,
1033
+ swapped: false,
1034
+ };
1020
1035
  }
1021
- return (h("div", { class: "calendar-wrapper" }, h("div", { class: "calendar-container", key: `calendar-${index}` }, this.renderHeader(offset, index), h("div", { class: "calendar-grid" }, this.showWeekNumbers && this.renderWeekNumbers(weeks, index), h("div", { class: "days-container" }, h("div", { class: "days-header" }, this.getDayNames().map(day => (h("div", { class: "day-header" }, day)))), this.renderDaysGrid(days)))), index < this.numberOfCalendars - 1 && (h("div", { class: "calendar-separator" }))));
1022
- }
1023
- /**
1024
- * Renders the shortcuts
1025
- * @returns {JSX.Element} Shortcuts
1026
- * @description Renders the shortcuts of the calendar
1027
- */
1028
- renderShortcuts() {
1029
- if (!this.parsedShortcuts().length) {
1030
- return null;
1036
+ catch (error) {
1037
+ console.error('Invalid date range:', error);
1038
+ throw error; // Re-throw to let the caller handle it
1031
1039
  }
1032
- return (h("div", { class: `shortcuts-container shortcuts-placement-${this.shortcutsPlacement}` }, this.parsedShortcuts().map(shortcut => (h("nv-button", { emphasis: "lower", size: "xs", "aria-label": shortcut.label, onClick: this.getShortcutHandler(shortcut) }, shortcut.label)))));
1033
- }
1034
- /**
1035
- * Renders the actions
1036
- * @returns {JSX.Element} Actions
1037
- * @description Renders the actions of the calendar
1038
- * @slot actions - Child content of the component.
1039
- */
1040
- renderActions() {
1041
- return (h("div", { class: "datepicker-actions" }, h("slot", { name: "actions" }, h("nv-button", { emphasis: "low", size: "xs", onClick: this.resetSelection }, "Cancel"), h("nv-button", { size: "xs", onClick: this.confirmSelection }, "OK"))));
1042
1040
  }
1043
1041
  /**
1044
1042
  * Renders the datepicker
@@ -1047,7 +1045,8 @@ const NvCalendar = class {
1047
1045
  * @slot default - Child content of the component.
1048
1046
  */
1049
1047
  render() {
1050
- return (h(Host, { key: '89300da9f694aa926855452414e7e036f75f2de6' }, h("div", { key: '467ef9fc9d6523eec3712bf779d49fdf50c55617', class: "datepicker-root" }, h("div", { key: '990f2cb18dcad96cab0f8dfb62e6c57049475440', class: `datepicker-container ${this.numberOfCalendars === 1 ? 'datepicker-container-single' : ''}` }, h("div", { key: 'c0dedf1007cbc6a87bd591925c9994474c876afc', class: `datepicker-wrapper ${this.numberOfCalendars === 1 ? 'single' : ''}` }, this.shortcutsPlacement === 'left' && this.renderShortcuts(), Array.from({ length: this.numberOfCalendars }, (_, index) => this.renderCalendar(index, index)), this.shortcutsPlacement === 'right' && this.renderShortcuts()), (this.hasShortcuts || this.hasActions) && (h("div", { key: 'ef81eaf952fbe569be7e1d3ee6cb59de0e137fe4', class: "datepicker-controls" }, this.hasShortcuts && this.renderShortcuts(), this.hasActions && this.renderActions())))), h("slot", { key: 'e1281217950b5cb02952a69b081d4fcce5863b4d' })));
1048
+ return (h(Host, { key: 'd265f105851253b5aa2a40e055f8e51b5cb6b553' }, h("div", { key: 'c6e1ea923b17f7684243598109e4cffc767248d7', class: "datepicker-root" }, h("div", { key: '5fc4cfbf3f6d823c500408d0f81f5f15d3e654d7', class: `datepicker-container ${this.numberOfCalendars === 1 ? 'datepicker-container-single' : ''}` }, h("div", { key: '035dac25c8b8090e1a3a0ac2493865907f665da9', class: `datepicker-wrapper ${this.numberOfCalendars === 1 ? 'single' : ''}` }, this.shortcutsPlacement === 'left' && this.renderShortcuts(), Array.from({ length: this.numberOfCalendars }, (_, index) => this.renderCalendar(index, index)), this.shortcutsPlacement === 'right' && this.renderShortcuts()), ((this.hasShortcuts && this.shortcutsPlacement === 'bottom') ||
1049
+ this.hasActions) && (h("div", { key: '91c21c945ab53acda631a8c50fb1437665fce030', class: "datepicker-controls" }, this.shortcutsPlacement === 'bottom' && this.renderShortcuts(), this.hasActions && this.renderActions())))), h("slot", { key: '3799c412c842e406715c235d3288022c2a734ed2' })));
1051
1050
  }
1052
1051
  get el() { return getElement(this); }
1053
1052
  static get watchers() { return {