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