@nova-design-system/nova-webcomponents 3.0.0 → 3.2.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 (532) 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 → index-108ddff0.js} +22 -6
  4. package/dist/cjs/index-108ddff0.js.map +1 -0
  5. package/dist/cjs/index.cjs.js +5 -471
  6. package/dist/cjs/index.cjs.js.map +1 -1
  7. package/dist/cjs/loader.cjs.js +2 -2
  8. package/dist/cjs/native.cjs.js +2 -2
  9. package/dist/cjs/nv-alert.cjs.entry.js +6 -6
  10. package/dist/cjs/nv-alert.cjs.entry.js.map +1 -1
  11. package/dist/cjs/nv-avatar.cjs.entry.js +2 -2
  12. package/dist/cjs/nv-badge_2.cjs.entry.js +18 -9
  13. package/dist/cjs/nv-badge_2.cjs.entry.js.map +1 -1
  14. package/dist/cjs/nv-breadcrumb.cjs.entry.js +1 -1
  15. package/dist/cjs/nv-breadcrumbs.cjs.entry.js +1 -1
  16. package/dist/cjs/nv-button.cjs.entry.js +2 -2
  17. package/dist/cjs/nv-calendar.cjs.entry.js +821 -843
  18. package/dist/cjs/nv-calendar.cjs.entry.js.map +1 -1
  19. package/dist/cjs/nv-col.cjs.entry.js +1 -1
  20. package/dist/cjs/nv-datagrid.cjs.entry.js +423 -94
  21. package/dist/cjs/nv-datagrid.cjs.entry.js.map +1 -1
  22. package/dist/cjs/nv-datagridcolumn.cjs.entry.js +2 -2
  23. package/dist/cjs/nv-datagridcolumn.cjs.entry.js.map +1 -1
  24. package/dist/cjs/nv-dialog.cjs.entry.js +19 -13
  25. package/dist/cjs/nv-dialog.cjs.entry.js.map +1 -1
  26. package/dist/cjs/nv-dialogfooter_2.cjs.entry.js +2 -2
  27. package/dist/cjs/nv-fieldcheckbox.cjs.entry.js +1 -1
  28. package/dist/cjs/nv-fielddate.cjs.entry.js +9 -18
  29. package/dist/cjs/nv-fielddate.cjs.entry.js.map +1 -1
  30. package/dist/cjs/nv-fielddaterange.cjs.entry.js +85 -32
  31. package/dist/cjs/nv-fielddaterange.cjs.entry.js.map +1 -1
  32. package/dist/cjs/nv-fielddropdown.cjs.entry.js +88 -57
  33. package/dist/cjs/nv-fielddropdown.cjs.entry.js.map +1 -1
  34. package/dist/cjs/nv-fielddropdownitem.cjs.entry.js +2 -2
  35. package/dist/cjs/nv-fieldmultiselect.cjs.entry.js +122 -104
  36. package/dist/cjs/nv-fieldmultiselect.cjs.entry.js.map +1 -1
  37. package/dist/cjs/nv-fieldnumber.cjs.entry.js +9 -5
  38. package/dist/cjs/nv-fieldnumber.cjs.entry.js.map +1 -1
  39. package/dist/cjs/nv-fieldpassword.cjs.entry.js +9 -5
  40. package/dist/cjs/nv-fieldpassword.cjs.entry.js.map +1 -1
  41. package/dist/cjs/nv-fieldradio.cjs.entry.js +4 -4
  42. package/dist/cjs/nv-fieldselect.cjs.entry.js +11 -7
  43. package/dist/cjs/nv-fieldselect.cjs.entry.js.map +1 -1
  44. package/dist/cjs/nv-fieldslider.cjs.entry.js +663 -0
  45. package/dist/cjs/nv-fieldslider.cjs.entry.js.map +1 -0
  46. package/dist/cjs/nv-fieldtext.cjs.entry.js +9 -5
  47. package/dist/cjs/nv-fieldtext.cjs.entry.js.map +1 -1
  48. package/dist/cjs/nv-fieldtextarea.cjs.entry.js +9 -5
  49. package/dist/cjs/nv-fieldtextarea.cjs.entry.js.map +1 -1
  50. package/dist/cjs/nv-fieldtime.cjs.entry.js +16 -13
  51. package/dist/cjs/nv-fieldtime.cjs.entry.js.map +1 -1
  52. package/dist/cjs/nv-icon.cjs.entry.js +4 -4
  53. package/dist/cjs/nv-icon.cjs.entry.js.map +1 -1
  54. package/dist/cjs/nv-iconbutton_2.cjs.entry.js +3 -3
  55. package/dist/cjs/nv-menu.cjs.entry.js +4 -2
  56. package/dist/cjs/nv-menu.cjs.entry.js.map +1 -1
  57. package/dist/cjs/nv-menuitem.cjs.entry.js +2 -2
  58. package/dist/cjs/nv-popover.cjs.entry.js +2 -2
  59. package/dist/cjs/nv-row.cjs.entry.js +2 -2
  60. package/dist/cjs/nv-stack.cjs.entry.js +2 -2
  61. package/dist/cjs/nv-table.cjs.entry.js +3 -3
  62. package/dist/cjs/nv-table.cjs.entry.js.map +1 -1
  63. package/dist/cjs/nv-tablecolumn.cjs.entry.js +1 -1
  64. package/dist/cjs/nv-toggle.cjs.entry.js +3 -3
  65. package/dist/cjs/nv-tooltip.cjs.entry.js +3 -3
  66. package/dist/cjs/nv-tooltip.cjs.entry.js.map +1 -1
  67. package/dist/collection/collection-manifest.json +1 -0
  68. package/dist/collection/components/nv-alert/nv-alert.css +3 -0
  69. package/dist/collection/components/nv-alert/nv-alert.js +6 -11
  70. package/dist/collection/components/nv-alert/nv-alert.js.map +1 -1
  71. package/dist/collection/components/nv-badge/nv-badge.css +181 -1
  72. package/dist/collection/components/nv-badge/nv-badge.docs.js +20 -1
  73. package/dist/collection/components/nv-badge/nv-badge.docs.js.map +1 -1
  74. package/dist/collection/components/nv-badge/nv-badge.js +39 -15
  75. package/dist/collection/components/nv-badge/nv-badge.js.map +1 -1
  76. package/dist/collection/components/nv-breadcrumbs/nv-breadcrumbs.docs.js +0 -1
  77. package/dist/collection/components/nv-breadcrumbs/nv-breadcrumbs.docs.js.map +1 -1
  78. package/dist/collection/components/nv-calendar/nv-calendar.css +25 -2
  79. package/dist/collection/components/nv-calendar/nv-calendar.docs.js +33 -38
  80. package/dist/collection/components/nv-calendar/nv-calendar.docs.js.map +1 -1
  81. package/dist/collection/components/nv-calendar/nv-calendar.js +659 -897
  82. package/dist/collection/components/nv-calendar/nv-calendar.js.map +1 -1
  83. package/dist/collection/components/nv-calendar/nv-calendar.utils.js +202 -0
  84. package/dist/collection/components/nv-calendar/nv-calendar.utils.js.map +1 -0
  85. package/dist/collection/components/nv-calendar/test/nv-calendar.utils.test.js +667 -0
  86. package/dist/collection/components/nv-calendar/test/nv-calendar.utils.test.js.map +1 -0
  87. package/dist/collection/components/nv-datagrid/nv-datagrid.css +98 -0
  88. package/dist/collection/components/nv-datagrid/nv-datagrid.docs.js +232 -51
  89. package/dist/collection/components/nv-datagrid/nv-datagrid.docs.js.map +1 -1
  90. package/dist/collection/components/nv-datagrid/nv-datagrid.js +437 -160
  91. package/dist/collection/components/nv-datagrid/nv-datagrid.js.map +1 -1
  92. package/dist/collection/components/nv-datagridcolumn/nv-datagridcolumn.js +20 -1
  93. package/dist/collection/components/nv-datagridcolumn/nv-datagridcolumn.js.map +1 -1
  94. package/dist/collection/components/nv-dialog/nv-dialog.css +29 -5
  95. package/dist/collection/components/nv-dialog/nv-dialog.docs.js +0 -1
  96. package/dist/collection/components/nv-dialog/nv-dialog.docs.js.map +1 -1
  97. package/dist/collection/components/nv-dialog/nv-dialog.js +16 -10
  98. package/dist/collection/components/nv-dialog/nv-dialog.js.map +1 -1
  99. package/dist/collection/components/nv-fielddate/nv-fielddate.docs.js +16 -8
  100. package/dist/collection/components/nv-fielddate/nv-fielddate.docs.js.map +1 -1
  101. package/dist/collection/components/nv-fielddate/nv-fielddate.js +48 -39
  102. package/dist/collection/components/nv-fielddate/nv-fielddate.js.map +1 -1
  103. package/dist/collection/components/nv-fielddate/styles/nv-fielddate.css +14 -1
  104. package/dist/collection/components/nv-fielddaterange/nv-fielddaterange.docs.js +12 -15
  105. package/dist/collection/components/nv-fielddaterange/nv-fielddaterange.docs.js.map +1 -1
  106. package/dist/collection/components/nv-fielddaterange/nv-fielddaterange.js +147 -68
  107. package/dist/collection/components/nv-fielddaterange/nv-fielddaterange.js.map +1 -1
  108. package/dist/collection/components/nv-fielddaterange/styles/nv-fielddaterange.css +20 -12
  109. package/dist/collection/components/nv-fielddropdown/nv-fielddropdown.docs.js +16 -0
  110. package/dist/collection/components/nv-fielddropdown/nv-fielddropdown.docs.js.map +1 -1
  111. package/dist/collection/components/nv-fielddropdown/nv-fielddropdown.js +197 -103
  112. package/dist/collection/components/nv-fielddropdown/nv-fielddropdown.js.map +1 -1
  113. package/dist/collection/components/nv-fielddropdown/styles/nv-fielddropdown.css +36 -1
  114. package/dist/collection/components/nv-fielddropdownitem/nv-fielddropdownitem.js +1 -1
  115. package/dist/collection/components/nv-fielddropdownitemcheck/nv-fielddropdownitemcheck.js +1 -1
  116. package/dist/collection/components/nv-fieldmultiselect/nv-fieldmultiselect.docs.js +8 -1
  117. package/dist/collection/components/nv-fieldmultiselect/nv-fieldmultiselect.docs.js.map +1 -1
  118. package/dist/collection/components/nv-fieldmultiselect/nv-fieldmultiselect.js +228 -190
  119. package/dist/collection/components/nv-fieldmultiselect/nv-fieldmultiselect.js.map +1 -1
  120. package/dist/collection/components/nv-fieldmultiselect/{nv-fieldmultiselect.css → styles/nv-fieldmultiselect.css} +36 -1
  121. package/dist/collection/components/nv-fieldnumber/nv-fieldnumber.css +12 -1
  122. package/dist/collection/components/nv-fieldnumber/nv-fieldnumber.docs.js +8 -0
  123. package/dist/collection/components/nv-fieldnumber/nv-fieldnumber.docs.js.map +1 -1
  124. package/dist/collection/components/nv-fieldnumber/nv-fieldnumber.js +27 -3
  125. package/dist/collection/components/nv-fieldnumber/nv-fieldnumber.js.map +1 -1
  126. package/dist/collection/components/nv-fieldpassword/nv-fieldpassword.css +12 -1
  127. package/dist/collection/components/nv-fieldpassword/nv-fieldpassword.docs.js +8 -0
  128. package/dist/collection/components/nv-fieldpassword/nv-fieldpassword.docs.js.map +1 -1
  129. package/dist/collection/components/nv-fieldpassword/nv-fieldpassword.js +27 -3
  130. package/dist/collection/components/nv-fieldpassword/nv-fieldpassword.js.map +1 -1
  131. package/dist/collection/components/nv-fieldradio/nv-fieldradio.js +3 -3
  132. package/dist/collection/components/nv-fieldselect/nv-fieldselect.css +12 -1
  133. package/dist/collection/components/nv-fieldselect/nv-fieldselect.docs.js +8 -0
  134. package/dist/collection/components/nv-fieldselect/nv-fieldselect.docs.js.map +1 -1
  135. package/dist/collection/components/nv-fieldselect/nv-fieldselect.js +29 -5
  136. package/dist/collection/components/nv-fieldselect/nv-fieldselect.js.map +1 -1
  137. package/dist/collection/components/nv-fieldslider/nv-fieldslider.docs.js +264 -0
  138. package/dist/collection/components/nv-fieldslider/nv-fieldslider.docs.js.map +1 -0
  139. package/dist/collection/components/nv-fieldslider/nv-fieldslider.js +1035 -0
  140. package/dist/collection/components/nv-fieldslider/nv-fieldslider.js.map +1 -0
  141. package/dist/collection/components/nv-fieldslider/nv-fieldslider.utils.js +77 -0
  142. package/dist/collection/components/nv-fieldslider/nv-fieldslider.utils.js.map +1 -0
  143. package/dist/collection/components/nv-fieldslider/partials/field-input.js +33 -0
  144. package/dist/collection/components/nv-fieldslider/partials/field-input.js.map +1 -0
  145. package/dist/collection/components/nv-fieldslider/partials/range-thumb.js +34 -0
  146. package/dist/collection/components/nv-fieldslider/partials/range-thumb.js.map +1 -0
  147. package/dist/collection/components/nv-fieldslider/partials/single-thumb.js +18 -0
  148. package/dist/collection/components/nv-fieldslider/partials/single-thumb.js.map +1 -0
  149. package/dist/collection/components/nv-fieldslider/partials/tick-marks.js +18 -0
  150. package/dist/collection/components/nv-fieldslider/partials/tick-marks.js.map +1 -0
  151. package/dist/collection/components/nv-fieldslider/styles/nv-fieldslider.css +267 -0
  152. package/dist/collection/components/nv-fieldslider/test/nv-fieldslider.utils.test.js +159 -0
  153. package/dist/collection/components/nv-fieldslider/test/nv-fieldslider.utils.test.js.map +1 -0
  154. package/dist/collection/components/nv-fieldtext/nv-fieldtext.css +20 -1
  155. package/dist/collection/components/nv-fieldtext/nv-fieldtext.docs.js +17 -1
  156. package/dist/collection/components/nv-fieldtext/nv-fieldtext.docs.js.map +1 -1
  157. package/dist/collection/components/nv-fieldtext/nv-fieldtext.js +28 -3
  158. package/dist/collection/components/nv-fieldtext/nv-fieldtext.js.map +1 -1
  159. package/dist/collection/components/nv-fieldtextarea/nv-fieldtextarea.css +30 -1
  160. package/dist/collection/components/nv-fieldtextarea/nv-fieldtextarea.docs.js +8 -0
  161. package/dist/collection/components/nv-fieldtextarea/nv-fieldtextarea.docs.js.map +1 -1
  162. package/dist/collection/components/nv-fieldtextarea/nv-fieldtextarea.js +27 -3
  163. package/dist/collection/components/nv-fieldtextarea/nv-fieldtextarea.js.map +1 -1
  164. package/dist/collection/components/nv-fieldtime/nv-fieldtime.js +13 -10
  165. package/dist/collection/components/nv-fieldtime/nv-fieldtime.js.map +1 -1
  166. package/dist/collection/components/nv-fieldtime/styles/nv-fieldtime.css +26 -3
  167. package/dist/collection/components/nv-icon/nv-icon.js +1 -1
  168. package/dist/collection/components/nv-icon/nv-icons.js +4 -470
  169. package/dist/collection/components/nv-icon/nv-icons.js.map +1 -1
  170. package/dist/collection/components/nv-iconbutton/nv-iconbutton.js +1 -1
  171. package/dist/collection/components/nv-loader/nv-loader.js +1 -1
  172. package/dist/collection/components/nv-menu/nv-menu.js +3 -1
  173. package/dist/collection/components/nv-menu/nv-menu.js.map +1 -1
  174. package/dist/collection/components/nv-menuitem/nv-menuitem.js +2 -2
  175. package/dist/collection/components/nv-popover/nv-popover.js +1 -1
  176. package/dist/collection/components/nv-row/nv-row.js +1 -1
  177. package/dist/collection/components/nv-stack/nv-stack.js +1 -1
  178. package/dist/collection/components/nv-table/nv-table.js +8 -11
  179. package/dist/collection/components/nv-table/nv-table.js.map +1 -1
  180. package/dist/collection/components/nv-toggle/nv-toggle.js +2 -2
  181. package/dist/collection/components/nv-tooltip/nv-tooltip.css +1 -0
  182. package/dist/collection/components/nv-tooltip/nv-tooltip.js +1 -1
  183. package/dist/collection/index.js.map +1 -1
  184. package/dist/collection/interfaces/Column.js.map +1 -1
  185. package/dist/collection/templates/navigation.docs.js +0 -1
  186. package/dist/collection/templates/navigation.docs.js.map +1 -1
  187. package/dist/collection/utils/constants.js +11 -0
  188. package/dist/collection/utils/constants.js.map +1 -1
  189. package/dist/components/index.js +6 -472
  190. package/dist/components/index.js.map +1 -1
  191. package/dist/components/nv-alert.js +7 -7
  192. package/dist/components/nv-alert.js.map +1 -1
  193. package/dist/components/nv-avatar.js +3 -3
  194. package/dist/components/nv-badge.js +1 -1
  195. package/dist/components/nv-breadcrumb.js +3 -3
  196. package/dist/components/nv-breadcrumbs.js +1 -1
  197. package/dist/components/nv-button.js +1 -1
  198. package/dist/components/nv-calendar.js +1 -1
  199. package/dist/components/nv-col.js +1 -1
  200. package/dist/components/nv-datagrid.js +447 -102
  201. package/dist/components/nv-datagrid.js.map +1 -1
  202. package/dist/components/nv-datagridcolumn.js +4 -3
  203. package/dist/components/nv-datagridcolumn.js.map +1 -1
  204. package/dist/components/nv-dialog.js +24 -18
  205. package/dist/components/nv-dialog.js.map +1 -1
  206. package/dist/components/nv-dialogfooter.js +1 -1
  207. package/dist/components/nv-dialogheader.js +1 -1
  208. package/dist/components/nv-fieldcheckbox.js +1 -1
  209. package/dist/components/nv-fielddate.js +19 -27
  210. package/dist/components/nv-fielddate.js.map +1 -1
  211. package/dist/components/nv-fielddaterange.js +99 -44
  212. package/dist/components/nv-fielddaterange.js.map +1 -1
  213. package/dist/components/nv-fielddropdown.js +103 -69
  214. package/dist/components/nv-fielddropdown.js.map +1 -1
  215. package/dist/components/nv-fielddropdownitem.js +1 -1
  216. package/dist/components/nv-fielddropdownitemcheck.js +1 -1
  217. package/dist/components/nv-fieldmultiselect.js +139 -120
  218. package/dist/components/nv-fieldmultiselect.js.map +1 -1
  219. package/dist/components/nv-fieldnumber.js +14 -9
  220. package/dist/components/nv-fieldnumber.js.map +1 -1
  221. package/dist/components/nv-fieldpassword.js +13 -8
  222. package/dist/components/nv-fieldpassword.js.map +1 -1
  223. package/dist/components/nv-fieldradio.js +4 -4
  224. package/dist/components/nv-fieldselect.js +15 -10
  225. package/dist/components/nv-fieldselect.js.map +1 -1
  226. package/dist/components/nv-fieldslider.d.ts +11 -0
  227. package/dist/components/nv-fieldslider.js +726 -0
  228. package/dist/components/nv-fieldslider.js.map +1 -0
  229. package/dist/components/nv-fieldtext.js +1 -158
  230. package/dist/components/nv-fieldtext.js.map +1 -1
  231. package/dist/components/nv-fieldtextarea.js +11 -6
  232. package/dist/components/nv-fieldtextarea.js.map +1 -1
  233. package/dist/components/nv-fieldtime.js +20 -17
  234. package/dist/components/nv-fieldtime.js.map +1 -1
  235. package/dist/components/nv-icon.js +1 -1
  236. package/dist/components/nv-iconbutton.js +1 -1
  237. package/dist/components/nv-loader.js +1 -1
  238. package/dist/components/nv-menu.js +7 -5
  239. package/dist/components/nv-menu.js.map +1 -1
  240. package/dist/components/nv-menuitem.js +1 -1
  241. package/dist/components/nv-popover.js +1 -1
  242. package/dist/components/nv-row.js +2 -2
  243. package/dist/components/nv-stack.js +2 -2
  244. package/dist/components/nv-table.js +3 -3
  245. package/dist/components/nv-table.js.map +1 -1
  246. package/dist/components/nv-tablecolumn.js +1 -1
  247. package/dist/components/nv-toggle.js +3 -3
  248. package/dist/components/nv-tooltip.js +1 -1
  249. package/dist/components/{p-dc3faba3.js → p-04cb3a6f.js} +5 -5
  250. package/dist/components/{p-dc3faba3.js.map → p-04cb3a6f.js.map} +1 -1
  251. package/dist/components/p-07a89754.js +187 -0
  252. package/dist/components/p-07a89754.js.map +1 -0
  253. package/dist/components/{p-b7b78e64.js → p-0ab80d95.js} +3 -3
  254. package/dist/components/{p-b7b78e64.js.map → p-0ab80d95.js.map} +1 -1
  255. package/dist/components/{p-8348db09.js → p-1f505531.js} +15 -2
  256. package/dist/components/p-1f505531.js.map +1 -0
  257. package/dist/components/{p-02752770.js → p-33e231f4.js} +2 -2
  258. package/dist/components/{p-02752770.js.map → p-33e231f4.js.map} +1 -1
  259. package/dist/components/p-4656efae.js +1111 -0
  260. package/dist/components/p-4656efae.js.map +1 -0
  261. package/dist/components/{p-2012b8ba.js → p-581e67cc.js} +4 -4
  262. package/dist/components/{p-2012b8ba.js.map → p-581e67cc.js.map} +1 -1
  263. package/dist/components/{p-1c45c0f2.js → p-679e0fa9.js} +16 -4
  264. package/dist/components/p-679e0fa9.js.map +1 -0
  265. package/dist/components/p-76a30bf1.js +88 -0
  266. package/dist/components/p-76a30bf1.js.map +1 -0
  267. package/dist/components/{p-150daf68.js → p-83c8873a.js} +3 -3
  268. package/dist/components/{p-150daf68.js.map → p-83c8873a.js.map} +1 -1
  269. package/dist/components/{p-c14f6b8e.js → p-c0a91091.js} +5 -5
  270. package/dist/components/p-c0a91091.js.map +1 -0
  271. package/dist/components/{p-6c364a23.js → p-cbdc2c8b.js} +6 -6
  272. package/dist/components/{p-6c364a23.js.map → p-cbdc2c8b.js.map} +1 -1
  273. package/dist/components/{p-2d9ba7d3.js → p-cbe9521f.js} +4 -4
  274. package/dist/components/{p-2d9ba7d3.js.map → p-cbe9521f.js.map} +1 -1
  275. package/dist/components/{p-a30b55fc.js → p-d19b41d2.js} +2 -2
  276. package/dist/components/{p-a30b55fc.js.map → p-d19b41d2.js.map} +1 -1
  277. package/dist/components/{p-4d3ec142.js → p-d63f1cbe.js} +4 -4
  278. package/dist/components/{p-4d3ec142.js.map → p-d63f1cbe.js.map} +1 -1
  279. package/dist/components/{p-e00cbb8a.js → p-dd2273a3.js} +2 -2
  280. package/dist/components/{p-e00cbb8a.js.map → p-dd2273a3.js.map} +1 -1
  281. package/dist/components/p-f0a5e7e4.js +167 -0
  282. package/dist/components/p-f0a5e7e4.js.map +1 -0
  283. package/dist/components/{p-f4d86795.js → p-f1859ddc.js} +4 -4
  284. package/dist/components/{p-f4d86795.js.map → p-f1859ddc.js.map} +1 -1
  285. package/dist/esm/{constants-98e2dcc2.js → constants-b97e736d.js} +15 -2
  286. package/dist/esm/constants-b97e736d.js.map +1 -0
  287. package/dist/esm/{index-1fb7a9a6.js → index-8f0e5f19.js} +22 -6
  288. package/dist/esm/index-8f0e5f19.js.map +1 -0
  289. package/dist/esm/index.js +5 -471
  290. package/dist/esm/index.js.map +1 -1
  291. package/dist/esm/loader.js +3 -3
  292. package/dist/esm/native.js +3 -3
  293. package/dist/esm/nv-alert.entry.js +6 -6
  294. package/dist/esm/nv-alert.entry.js.map +1 -1
  295. package/dist/esm/nv-avatar.entry.js +2 -2
  296. package/dist/esm/nv-badge_2.entry.js +18 -9
  297. package/dist/esm/nv-badge_2.entry.js.map +1 -1
  298. package/dist/esm/nv-breadcrumb.entry.js +1 -1
  299. package/dist/esm/nv-breadcrumbs.entry.js +1 -1
  300. package/dist/esm/nv-button.entry.js +2 -2
  301. package/dist/esm/nv-calendar.entry.js +821 -843
  302. package/dist/esm/nv-calendar.entry.js.map +1 -1
  303. package/dist/esm/nv-col.entry.js +1 -1
  304. package/dist/esm/nv-datagrid.entry.js +423 -94
  305. package/dist/esm/nv-datagrid.entry.js.map +1 -1
  306. package/dist/esm/nv-datagridcolumn.entry.js +2 -2
  307. package/dist/esm/nv-datagridcolumn.entry.js.map +1 -1
  308. package/dist/esm/nv-dialog.entry.js +19 -13
  309. package/dist/esm/nv-dialog.entry.js.map +1 -1
  310. package/dist/esm/nv-dialogfooter_2.entry.js +2 -2
  311. package/dist/esm/nv-fieldcheckbox.entry.js +1 -1
  312. package/dist/esm/nv-fielddate.entry.js +9 -18
  313. package/dist/esm/nv-fielddate.entry.js.map +1 -1
  314. package/dist/esm/nv-fielddaterange.entry.js +85 -32
  315. package/dist/esm/nv-fielddaterange.entry.js.map +1 -1
  316. package/dist/esm/nv-fielddropdown.entry.js +88 -57
  317. package/dist/esm/nv-fielddropdown.entry.js.map +1 -1
  318. package/dist/esm/nv-fielddropdownitem.entry.js +2 -2
  319. package/dist/esm/nv-fieldmultiselect.entry.js +122 -104
  320. package/dist/esm/nv-fieldmultiselect.entry.js.map +1 -1
  321. package/dist/esm/nv-fieldnumber.entry.js +9 -5
  322. package/dist/esm/nv-fieldnumber.entry.js.map +1 -1
  323. package/dist/esm/nv-fieldpassword.entry.js +9 -5
  324. package/dist/esm/nv-fieldpassword.entry.js.map +1 -1
  325. package/dist/esm/nv-fieldradio.entry.js +4 -4
  326. package/dist/esm/nv-fieldselect.entry.js +11 -7
  327. package/dist/esm/nv-fieldselect.entry.js.map +1 -1
  328. package/dist/esm/nv-fieldslider.entry.js +659 -0
  329. package/dist/esm/nv-fieldslider.entry.js.map +1 -0
  330. package/dist/esm/nv-fieldtext.entry.js +9 -5
  331. package/dist/esm/nv-fieldtext.entry.js.map +1 -1
  332. package/dist/esm/nv-fieldtextarea.entry.js +9 -5
  333. package/dist/esm/nv-fieldtextarea.entry.js.map +1 -1
  334. package/dist/esm/nv-fieldtime.entry.js +16 -13
  335. package/dist/esm/nv-fieldtime.entry.js.map +1 -1
  336. package/dist/esm/nv-icon.entry.js +4 -4
  337. package/dist/esm/nv-icon.entry.js.map +1 -1
  338. package/dist/esm/nv-iconbutton_2.entry.js +3 -3
  339. package/dist/esm/nv-menu.entry.js +4 -2
  340. package/dist/esm/nv-menu.entry.js.map +1 -1
  341. package/dist/esm/nv-menuitem.entry.js +2 -2
  342. package/dist/esm/nv-popover.entry.js +2 -2
  343. package/dist/esm/nv-row.entry.js +2 -2
  344. package/dist/esm/nv-stack.entry.js +2 -2
  345. package/dist/esm/nv-table.entry.js +3 -3
  346. package/dist/esm/nv-table.entry.js.map +1 -1
  347. package/dist/esm/nv-tablecolumn.entry.js +1 -1
  348. package/dist/esm/nv-toggle.entry.js +3 -3
  349. package/dist/esm/nv-tooltip.entry.js +3 -3
  350. package/dist/esm/nv-tooltip.entry.js.map +1 -1
  351. package/dist/native/index.esm.js +1 -1
  352. package/dist/native/index.esm.js.map +1 -1
  353. package/dist/native/native.css +1 -1
  354. package/dist/native/native.esm.js +1 -1
  355. package/dist/native/native.esm.js.map +1 -1
  356. package/dist/native/{p-6b348684.entry.js → p-0323daf6.entry.js} +2 -2
  357. package/dist/native/{p-d5cbf5c8.entry.js → p-05d95d4d.entry.js} +2 -2
  358. package/dist/native/{p-fb5bddba.entry.js → p-0ec1e2e3.entry.js} +2 -2
  359. package/dist/native/{p-c7b201cd.entry.js → p-16a4cdf3.entry.js} +2 -2
  360. package/dist/native/p-19fb0fd0.entry.js +2 -0
  361. package/dist/native/p-19fb0fd0.entry.js.map +1 -0
  362. package/dist/native/p-1e3d3374.entry.js +2 -0
  363. package/dist/native/{p-9135fdf5.entry.js.map → p-1e3d3374.entry.js.map} +1 -1
  364. package/dist/native/p-21e7132f.entry.js +2 -0
  365. package/dist/native/p-21e7132f.entry.js.map +1 -0
  366. package/dist/native/p-221b8f72.entry.js +2 -0
  367. package/dist/native/p-221b8f72.entry.js.map +1 -0
  368. package/dist/native/p-2805f9f2.entry.js +2 -0
  369. package/dist/native/p-2805f9f2.entry.js.map +1 -0
  370. package/dist/native/p-3f2b6a22.entry.js +2 -0
  371. package/dist/native/p-3f2b6a22.entry.js.map +1 -0
  372. package/dist/native/{p-0245863d.entry.js → p-407fc32d.entry.js} +2 -2
  373. package/dist/native/{p-63e6aed3.entry.js → p-4c0d81b0.entry.js} +2 -2
  374. package/dist/native/p-4c0d81b0.entry.js.map +1 -0
  375. package/dist/native/{p-39bb95ff.entry.js → p-519b4819.entry.js} +2 -2
  376. package/dist/native/{p-fa77a591.entry.js → p-5382eab2.entry.js} +2 -2
  377. package/dist/native/p-5ba3fc3c.entry.js +2 -0
  378. package/dist/native/p-5ba3fc3c.entry.js.map +1 -0
  379. package/dist/native/{p-bad11367.entry.js → p-60b204ac.entry.js} +2 -2
  380. package/dist/native/p-60b204ac.entry.js.map +1 -0
  381. package/dist/native/p-7092a675.entry.js +2 -0
  382. package/dist/native/p-711a7778.js +3 -0
  383. package/dist/native/p-711a7778.js.map +1 -0
  384. package/dist/native/p-759c9ce4.entry.js +2 -0
  385. package/dist/native/p-759c9ce4.entry.js.map +1 -0
  386. package/dist/native/{p-d7a76400.entry.js → p-7c676f2c.entry.js} +2 -2
  387. package/dist/native/p-7c6edd1c.entry.js +2 -0
  388. package/dist/native/p-7c6edd1c.entry.js.map +1 -0
  389. package/dist/native/p-987c79d8.entry.js +2 -0
  390. package/dist/native/p-987c79d8.entry.js.map +1 -0
  391. package/dist/native/{p-f85aca27.entry.js → p-9fba8663.entry.js} +2 -2
  392. package/dist/native/{p-b094296d.entry.js → p-a2c0f1a7.entry.js} +2 -2
  393. package/dist/native/p-aa86af25.entry.js +2 -0
  394. package/dist/native/p-aa86af25.entry.js.map +1 -0
  395. package/dist/native/p-adc96c3a.entry.js +2 -0
  396. package/dist/native/p-adc96c3a.entry.js.map +1 -0
  397. package/dist/native/p-b0fc08e7.entry.js +2 -0
  398. package/dist/native/p-b0fc08e7.entry.js.map +1 -0
  399. package/dist/native/{p-6ff228da.entry.js → p-c930adb7.entry.js} +2 -2
  400. package/dist/native/{p-701b5557.entry.js → p-cfe0a6c6.entry.js} +2 -2
  401. package/dist/native/p-d07ab618.entry.js +2 -0
  402. package/dist/native/p-dac0089b.entry.js +2 -0
  403. package/dist/native/p-dac0089b.entry.js.map +1 -0
  404. package/dist/native/p-de2c07a6.entry.js +13 -0
  405. package/dist/native/p-de2c07a6.entry.js.map +1 -0
  406. package/dist/native/p-ed488498.entry.js +7 -0
  407. package/dist/native/p-ed488498.entry.js.map +1 -0
  408. package/dist/native/p-ef76178b.entry.js +2 -0
  409. package/dist/native/p-ef76178b.entry.js.map +1 -0
  410. package/dist/native/{p-e5de64d5.entry.js → p-f0ddf60b.entry.js} +2 -2
  411. package/dist/native/p-f39803d9.entry.js +2 -0
  412. package/dist/native/p-f39803d9.entry.js.map +1 -0
  413. package/dist/native/{p-59768ee5.js → p-f85c08f1.js} +2 -2
  414. package/dist/native/p-f85c08f1.js.map +1 -0
  415. package/dist/native/p-fb897f7d.entry.js +2 -0
  416. package/dist/native/p-fb897f7d.entry.js.map +1 -0
  417. package/dist/native/{p-244f56ac.entry.js → p-fc3bea07.entry.js} +2 -2
  418. package/dist/types/components/nv-alert/nv-alert.d.ts +1 -1
  419. package/dist/types/components/nv-badge/nv-badge.d.ts +11 -3
  420. package/dist/types/components/nv-calendar/nv-calendar.d.ts +70 -112
  421. package/dist/types/components/nv-calendar/nv-calendar.utils.d.ts +60 -0
  422. package/dist/types/components/nv-calendar/test/nv-calendar.utils.test.d.ts +1 -0
  423. package/dist/types/components/nv-datagrid/nv-datagrid.d.ts +47 -26
  424. package/dist/types/components/nv-datagridcolumn/nv-datagridcolumn.d.ts +4 -0
  425. package/dist/types/components/nv-dialog/nv-dialog.d.ts +4 -0
  426. package/dist/types/components/nv-fielddate/nv-fielddate.d.ts +6 -7
  427. package/dist/types/components/nv-fielddaterange/nv-fielddaterange.d.ts +23 -12
  428. package/dist/types/components/nv-fielddropdown/nv-fielddropdown.d.ts +51 -26
  429. package/dist/types/components/nv-fieldmultiselect/nv-fieldmultiselect.d.ts +65 -55
  430. package/dist/types/components/nv-fieldnumber/nv-fieldnumber.d.ts +4 -0
  431. package/dist/types/components/nv-fieldpassword/nv-fieldpassword.d.ts +4 -0
  432. package/dist/types/components/nv-fieldselect/nv-fieldselect.d.ts +4 -0
  433. package/dist/types/components/nv-fieldslider/nv-fieldslider.d.ts +230 -0
  434. package/dist/types/components/nv-fieldslider/nv-fieldslider.docs.d.ts +4 -0
  435. package/dist/types/components/nv-fieldslider/nv-fieldslider.utils.d.ts +46 -0
  436. package/dist/types/components/nv-fieldslider/partials/field-input.d.ts +45 -0
  437. package/dist/types/components/nv-fieldslider/partials/range-thumb.d.ts +37 -0
  438. package/dist/types/components/nv-fieldslider/partials/single-thumb.d.ts +35 -0
  439. package/dist/types/components/nv-fieldslider/partials/tick-marks.d.ts +28 -0
  440. package/dist/types/components/nv-fieldslider/test/nv-fieldslider.utils.test.d.ts +1 -0
  441. package/dist/types/components/nv-fieldtext/nv-fieldtext.d.ts +5 -0
  442. package/dist/types/components/nv-fieldtextarea/nv-fieldtextarea.d.ts +4 -0
  443. package/dist/types/components/nv-icon/nv-icons.d.ts +1 -1
  444. package/dist/types/components/nv-table/nv-table.d.ts +13 -2
  445. package/dist/types/components.d.ts +656 -154
  446. package/dist/types/index.d.ts +0 -2
  447. package/dist/types/interfaces/Column.d.ts +5 -1
  448. package/dist/types/utils/constants.d.ts +9 -0
  449. package/dist/vscode-data.json +292 -1546
  450. package/hydrate/index.js +2715 -1533
  451. package/hydrate/index.mjs +2715 -1533
  452. package/package.json +6 -2
  453. package/dist/cjs/constants-bcd6b2e2.js.map +0 -1
  454. package/dist/cjs/index-9bda5507.js.map +0 -1
  455. package/dist/collection/interfaces/actionEvent.js +0 -2
  456. package/dist/collection/interfaces/actionEvent.js.map +0 -1
  457. package/dist/collection/interfaces/calendarShortcut.js +0 -2
  458. package/dist/collection/interfaces/calendarShortcut.js.map +0 -1
  459. package/dist/collection/interfaces/dateRange.js +0 -2
  460. package/dist/collection/interfaces/dateRange.js.map +0 -1
  461. package/dist/components/p-1c45c0f2.js.map +0 -1
  462. package/dist/components/p-373926aa.js +0 -177
  463. package/dist/components/p-373926aa.js.map +0 -1
  464. package/dist/components/p-591730e7.js +0 -88
  465. package/dist/components/p-591730e7.js.map +0 -1
  466. package/dist/components/p-8348db09.js.map +0 -1
  467. package/dist/components/p-c14f6b8e.js.map +0 -1
  468. package/dist/components/p-f331117c.js +0 -1133
  469. package/dist/components/p-f331117c.js.map +0 -1
  470. package/dist/esm/constants-98e2dcc2.js.map +0 -1
  471. package/dist/esm/index-1fb7a9a6.js.map +0 -1
  472. package/dist/native/p-0ee428d5.entry.js +0 -2
  473. package/dist/native/p-0ee428d5.entry.js.map +0 -1
  474. package/dist/native/p-2691e02d.entry.js +0 -2
  475. package/dist/native/p-37f0210e.entry.js +0 -2
  476. package/dist/native/p-37f0210e.entry.js.map +0 -1
  477. package/dist/native/p-4a440970.entry.js +0 -2
  478. package/dist/native/p-4a440970.entry.js.map +0 -1
  479. package/dist/native/p-4ae26462.entry.js +0 -7
  480. package/dist/native/p-4ae26462.entry.js.map +0 -1
  481. package/dist/native/p-4d9c4618.entry.js +0 -2
  482. package/dist/native/p-4d9c4618.entry.js.map +0 -1
  483. package/dist/native/p-4dc1d036.entry.js +0 -2
  484. package/dist/native/p-59768ee5.js.map +0 -1
  485. package/dist/native/p-59e0bd2b.entry.js +0 -2
  486. package/dist/native/p-59e0bd2b.entry.js.map +0 -1
  487. package/dist/native/p-5c00f092.entry.js +0 -2
  488. package/dist/native/p-5c00f092.entry.js.map +0 -1
  489. package/dist/native/p-63e6aed3.entry.js.map +0 -1
  490. package/dist/native/p-7f5eb2ac.entry.js +0 -2
  491. package/dist/native/p-7f5eb2ac.entry.js.map +0 -1
  492. package/dist/native/p-84a73e2a.entry.js +0 -2
  493. package/dist/native/p-84a73e2a.entry.js.map +0 -1
  494. package/dist/native/p-9135fdf5.entry.js +0 -2
  495. package/dist/native/p-93dc2f47.entry.js +0 -2
  496. package/dist/native/p-93dc2f47.entry.js.map +0 -1
  497. package/dist/native/p-9a267f16.entry.js +0 -13
  498. package/dist/native/p-9a267f16.entry.js.map +0 -1
  499. package/dist/native/p-9d6431c7.entry.js +0 -2
  500. package/dist/native/p-9d6431c7.entry.js.map +0 -1
  501. package/dist/native/p-ab002252.js +0 -3
  502. package/dist/native/p-ab002252.js.map +0 -1
  503. package/dist/native/p-b2ce83ad.entry.js +0 -2
  504. package/dist/native/p-b2ce83ad.entry.js.map +0 -1
  505. package/dist/native/p-bad11367.entry.js.map +0 -1
  506. package/dist/native/p-e1a4f776.entry.js +0 -2
  507. package/dist/native/p-e1a4f776.entry.js.map +0 -1
  508. package/dist/native/p-e49bbd02.entry.js +0 -2
  509. package/dist/native/p-e49bbd02.entry.js.map +0 -1
  510. package/dist/native/p-eee01062.entry.js +0 -2
  511. package/dist/native/p-eee01062.entry.js.map +0 -1
  512. package/dist/native/p-f6bdc270.entry.js +0 -2
  513. package/dist/native/p-f6bdc270.entry.js.map +0 -1
  514. package/dist/types/interfaces/actionEvent.d.ts +0 -13
  515. package/dist/types/interfaces/calendarShortcut.d.ts +0 -17
  516. package/dist/types/interfaces/dateRange.d.ts +0 -13
  517. /package/dist/native/{p-6b348684.entry.js.map → p-0323daf6.entry.js.map} +0 -0
  518. /package/dist/native/{p-d5cbf5c8.entry.js.map → p-05d95d4d.entry.js.map} +0 -0
  519. /package/dist/native/{p-fb5bddba.entry.js.map → p-0ec1e2e3.entry.js.map} +0 -0
  520. /package/dist/native/{p-c7b201cd.entry.js.map → p-16a4cdf3.entry.js.map} +0 -0
  521. /package/dist/native/{p-0245863d.entry.js.map → p-407fc32d.entry.js.map} +0 -0
  522. /package/dist/native/{p-39bb95ff.entry.js.map → p-519b4819.entry.js.map} +0 -0
  523. /package/dist/native/{p-fa77a591.entry.js.map → p-5382eab2.entry.js.map} +0 -0
  524. /package/dist/native/{p-2691e02d.entry.js.map → p-7092a675.entry.js.map} +0 -0
  525. /package/dist/native/{p-d7a76400.entry.js.map → p-7c676f2c.entry.js.map} +0 -0
  526. /package/dist/native/{p-f85aca27.entry.js.map → p-9fba8663.entry.js.map} +0 -0
  527. /package/dist/native/{p-b094296d.entry.js.map → p-a2c0f1a7.entry.js.map} +0 -0
  528. /package/dist/native/{p-6ff228da.entry.js.map → p-c930adb7.entry.js.map} +0 -0
  529. /package/dist/native/{p-701b5557.entry.js.map → p-cfe0a6c6.entry.js.map} +0 -0
  530. /package/dist/native/{p-4dc1d036.entry.js.map → p-d07ab618.entry.js.map} +0 -0
  531. /package/dist/native/{p-e5de64d5.entry.js.map → p-f0ddf60b.entry.js.map} +0 -0
  532. /package/dist/native/{p-244f56ac.entry.js.map → p-fc3bea07.entry.js.map} +0 -0
@@ -1,13 +1,6 @@
1
1
  import { Host, h, } from "@stencil/core";
2
- import dayjs from "dayjs";
3
- import customParseFormat from "dayjs/plugin/customParseFormat";
4
- import utc from "dayjs/plugin/utc";
5
- import weekOfYear from "dayjs/plugin/weekOfYear";
6
2
  import { WEEK_ABBREVIATIONS, CUSTOM_DAY_NAMES, CUSTOM_MONTH_NAMES, } from "../../utils/constants";
7
- // Extend dayjs with plugins
8
- dayjs.extend(customParseFormat);
9
- dayjs.extend(utc);
10
- dayjs.extend(weekOfYear);
3
+ import { getWeekNumber, parseDate, isSameDate, formatDate, isSameOrAfter, isSameOrBefore, } from "./nv-calendar.utils";
11
4
  /**
12
5
  * @slot default - Child content of the component.
13
6
  * @slot actions - Child content of the component.
@@ -27,33 +20,12 @@ export class NvCalendar {
27
20
  */
28
21
  this.numberOfCalendars = 1;
29
22
  /**
30
- * Selected date (ISO string format)
31
- * ex: "2025-03-15"
32
- */
33
- this.singleValue = '';
34
- /**
35
- * Selected date range
36
- * format: { start: ISO string, end: ISO string }
37
- * ex: { start: "2025-03-15", end: "2025-03-20" }
38
- */
39
- this.rangeValue = '';
40
- /**
41
- * Minimum date for selection (ISO string format, ex: "2025-01-01")
42
- */
43
- this.min = '';
44
- /**
45
- * Maximum date for selection (ISO string format, ex: "2025-12-31")
46
- */
47
- this.max = '';
48
- /** Disabled dates (ISO string array)
49
- * @default '[]'
50
- */
51
- this.disabledDates = '';
52
- /** Locale for date formatting
23
+ * Locale for date formatting
53
24
  * @default 'en-BE'
54
25
  */
55
26
  this.locale = 'en-BE';
56
- /** Date format (ex: 'YYYY-MM-DD', 'DD-MM-YYYY', etc.)
27
+ /**
28
+ * Date format (ex: 'YYYY-MM-DD', 'DD-MM-YYYY', etc.)
57
29
  * @default 'YYYY-MM-DD'
58
30
  * @note If the date format is in UTC mode, the date will be displayed in UTC time.
59
31
  * @note If the date format is not in UTC mode, the date will be displayed in the local time.
@@ -71,40 +43,454 @@ export class NvCalendar {
71
43
  this.selectionType = 'single';
72
44
  /**
73
45
  * Show action buttons
74
- * @default false
75
46
  */
76
47
  this.showActions = false;
77
- /**
78
- * Custom actions to display in the footer
79
- * JSON array of objects with the following properties:
80
- * - label: string
81
- * - onClick: function
82
- * @default '[]'
83
- */
84
- this.shortcuts = '[]';
85
48
  /** Cache for parsed disabled dates */
86
49
  this.parsedDisabledDates = [];
87
- /** Selected date */
50
+ //#endregion PROPERTIES
51
+ /****************************************************************************/
52
+ //#region STATE
53
+ this.currentDate = null;
88
54
  this.selectedDate = null;
89
- /** Start date */
90
55
  this.startDate = null;
91
- /** End date */
92
56
  this.endDate = null;
93
57
  /** List of formatted months for the selector */
94
58
  this.months = [];
59
+ /**
60
+ * Change the displayed month
61
+ * @param {number} offset - Month offset (-1 for previous, 1 for next)
62
+ */
63
+ this.changeMonth = (offset) => {
64
+ const newDate = new Date(this.currentDate);
65
+ // Ensure we only move by one month at a time
66
+ newDate.setUTCMonth(newDate.getUTCMonth() + offset);
67
+ // Add the appropriate animation class
68
+ const containers = this.el.querySelectorAll('.calendar-grid');
69
+ containers.forEach(container => {
70
+ // Remove existing animation classes
71
+ container.classList.remove('slide-left', 'slide-right');
72
+ // Add the new animation class
73
+ const animationClass = offset > 0 ? 'slide-left' : 'slide-right';
74
+ container.classList.add(animationClass);
75
+ // Remove the class after the animation
76
+ setTimeout(() => {
77
+ container.classList.remove(animationClass);
78
+ }, 300); // 300ms corresponds to $slide-duration in the SCSS
79
+ });
80
+ this.currentDate = newDate;
81
+ };
82
+ /**
83
+ * Handles date selection based on the mode
84
+ * @param {Date} date - Selected date
85
+ */
86
+ this.handleDateSelection = (date) => {
87
+ if (this.isDateDisabled(date)) {
88
+ return;
89
+ }
90
+ if (this.selectionType === 'single') {
91
+ this.handleSingleSelection(date);
92
+ }
93
+ else {
94
+ this.handleRangeSelection(date);
95
+ }
96
+ };
97
+ /**
98
+ * Handles single date selection
99
+ * @param {Date} date - Selected date
100
+ */
101
+ this.handleSingleSelection = (date) => {
102
+ if (!date)
103
+ return;
104
+ const formattedDate = formatDate(date, { dateFormat: this.dateFormat });
105
+ this.selectedDate = date;
106
+ this.singleDateChange.emit(formattedDate);
107
+ };
108
+ /**
109
+ * Handles range date selection
110
+ * @param {Date} date - Selected date
111
+ */
112
+ this.handleRangeSelection = (date) => {
113
+ if (!this.startDate || (this.startDate && this.endDate)) {
114
+ this.startDate = date;
115
+ this.endDate = null;
116
+ }
117
+ else {
118
+ this.endDate = date;
119
+ if (this.startDate > this.endDate) {
120
+ [this.startDate, this.endDate] = [this.endDate, this.startDate];
121
+ }
122
+ this.rangeDateChange.emit({
123
+ start: formatDate(this.startDate, { dateFormat: this.dateFormat }),
124
+ end: formatDate(this.endDate, { dateFormat: this.dateFormat }),
125
+ });
126
+ }
127
+ };
128
+ /**
129
+ * Checks if a date is disabled.
130
+ * Disabled if:
131
+ * - The date is before min (if defined)
132
+ * - The date is after max (if defined)
133
+ * - The date is in the disabledDates array
134
+ * @param {Date} date - Date to check
135
+ * @returns {boolean} true if the date is disabled
136
+ */
137
+ this.isDateDisabled = (date) => {
138
+ if (!date)
139
+ return true;
140
+ // Minimum bound check
141
+ if (this.min) {
142
+ const minDate = parseDate(this.min, this.dateFormat);
143
+ if (minDate && date < minDate) {
144
+ return true;
145
+ }
146
+ }
147
+ // Maximum bound check
148
+ if (this.max) {
149
+ const maxDate = parseDate(this.max, this.dateFormat);
150
+ if (maxDate && date > maxDate) {
151
+ return true;
152
+ }
153
+ }
154
+ // Check disabled dates
155
+ return this.parsedDisabledDates.some(disabledDate => isSameDate(date, disabledDate, { isUTCMode: this.isUTCMode }));
156
+ };
157
+ /**
158
+ * Checks if a date is in the selected range
159
+ * @param {Date} date - Date to check
160
+ * @returns {boolean} true if the date is in the range
161
+ */
162
+ this.isDateInRange = (date) => {
163
+ if (!date || !this.startDate || !this.endDate)
164
+ return false;
165
+ const checkDate = parseDate(date, this.dateFormat);
166
+ const startDate = parseDate(this.startDate, this.dateFormat);
167
+ const endDate = parseDate(this.endDate, this.dateFormat);
168
+ // Verify if startDate and endDate are valid
169
+ if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {
170
+ return false;
171
+ }
172
+ // Verify that startDate is before endDate (additional security)
173
+ if (startDate > endDate)
174
+ return false;
175
+ // Comparison based only on the date (year, month, day)
176
+ return (isSameOrAfter(checkDate, startDate, { isUTCMode: this.isUTCMode }) &&
177
+ isSameOrBefore(checkDate, endDate, { isUTCMode: this.isUTCMode }));
178
+ };
179
+ /**
180
+ * Retrieves the localized day names
181
+ * @returns {string[]} Array of short day names
182
+ */
183
+ this.getDayNames = () => {
184
+ // If we have custom day names for this locale
185
+ if (CUSTOM_DAY_NAMES[this.locale]) {
186
+ const days = [...CUSTOM_DAY_NAMES[this.locale]];
187
+ // Reorganize the days based on the first day of the week
188
+ const firstDays = days.slice(0, this.firstDayOfWeek);
189
+ const remainingDays = days.slice(this.firstDayOfWeek);
190
+ return [...remainingDays, ...firstDays];
191
+ }
192
+ // Otherwise, use the default behavior
193
+ const formatter = new Intl.DateTimeFormat(this.locale, {
194
+ weekday: 'short',
195
+ });
196
+ const days = [...Array(7)].map((_, i) => formatter.format(new Date(2023, 0, i + 1)).toUpperCase());
197
+ // Reorganize the days based on the first day of the week
198
+ const firstDays = days.slice(0, this.firstDayOfWeek);
199
+ const remainingDays = days.slice(this.firstDayOfWeek);
200
+ return [...remainingDays, ...firstDays];
201
+ };
202
+ /**
203
+ * Generates the days of the current month
204
+ * @param {number} offset - Month offset (0 by default)
205
+ * @param {number} totalCalendars - Number of calendars to display (1 by default)
206
+ * @returns {Array<{ dayOfMonth: number | null, date: Date | null, isSelected: boolean, isDisabled: boolean }>} Array of formatted days
207
+ */
208
+ this.getDaysInMonth = (offset = 0, totalCalendars = 1) => {
209
+ const year = this.currentDate.getUTCFullYear();
210
+ const month = this.currentDate.getUTCMonth() + offset;
211
+ const firstDay = new Date(Date.UTC(year, month, 1));
212
+ const lastDay = new Date(Date.UTC(year, month + 1, 0));
213
+ const days = [];
214
+ // Correct calculation of offset for previous month days
215
+ // Use getUTCDay to stay consistent with UTC timezone
216
+ const dayOfWeekIndex = firstDay.getUTCDay(); // 0 = Sunday, 1 = Monday, etc.
217
+ // Adjust based on firstDayOfWeek (if week starts on Monday, offset is different)
218
+ const offsetDays = (dayOfWeekIndex - this.firstDayOfWeek + 7) % 7;
219
+ // Add the days of the previous month for the first calendar
220
+ if (offset === 0 && offsetDays > 0) {
221
+ const prevMonthLastDay = new Date(Date.UTC(year, month, 0)).getUTCDate();
222
+ for (let i = offsetDays; i > 0; i--) {
223
+ const date = new Date(Date.UTC(year, month - 1, prevMonthLastDay - i + 1));
224
+ days.push({
225
+ dayOfMonth: date.getUTCDate(),
226
+ date,
227
+ isCurrentMonth: false,
228
+ isDisabled: this.isDateDisabled(date),
229
+ });
230
+ }
231
+ }
232
+ // Add the days of the current month
233
+ for (let i = 1; i <= lastDay.getUTCDate(); i++) {
234
+ const date = new Date(Date.UTC(year, month, i));
235
+ days.push({
236
+ dayOfMonth: i,
237
+ date,
238
+ isCurrentMonth: true,
239
+ isDisabled: this.isDateDisabled(date),
240
+ });
241
+ }
242
+ // Add the days of the next month only for the last calendar
243
+ if (offset === totalCalendars - 1) {
244
+ const nextMonthDaysNeeded = 7 - (days.length % 7 || 7);
245
+ for (let i = 1; i <= nextMonthDaysNeeded; i++) {
246
+ const date = new Date(Date.UTC(year, month + 1, i));
247
+ days.push({
248
+ dayOfMonth: i,
249
+ date,
250
+ isCurrentMonth: false,
251
+ isDisabled: this.isDateDisabled(date),
252
+ });
253
+ }
254
+ }
255
+ return days;
256
+ };
257
+ /** Initializes the list of formatted months according to the locale */
258
+ this.initializeMonths = () => {
259
+ // If we have custom month names for this locale
260
+ if (CUSTOM_MONTH_NAMES[this.locale]) {
261
+ this.months = CUSTOM_MONTH_NAMES[this.locale].map((label, value) => ({
262
+ value,
263
+ label,
264
+ }));
265
+ return;
266
+ }
267
+ // Otherwise, use the default behavior
268
+ const formatter = new Intl.DateTimeFormat(this.locale, { month: 'short' });
269
+ this.months = Array.from({ length: 12 }, (_, i) => ({
270
+ value: i,
271
+ label: formatter.format(new Date(2000, i, 1)).toUpperCase(),
272
+ }));
273
+ };
274
+ /**
275
+ * Retrieves the localized abbreviation for "week"
276
+ * @returns {string} Localized abbreviation for "week"
277
+ */
278
+ this.getLocalizedWeekText = () => {
279
+ return WEEK_ABBREVIATIONS[this.locale] || 'W';
280
+ };
281
+ /**
282
+ * Handles month change in the selector
283
+ * @param {Event} event - Month change event
284
+ * @param {number} calendarOffset - Calendar offset (0 by default)
285
+ */
286
+ this.handleMonthChange = (event, calendarOffset = 0) => {
287
+ const select = event.target;
288
+ const selectedMonth = parseInt(select.value, 10);
289
+ const currentMonth = this.currentDate.getUTCMonth();
290
+ // Calculate the difference considering the calendar offset
291
+ const monthDiff = selectedMonth - ((currentMonth + calendarOffset) % 12);
292
+ const newDate = new Date(this.currentDate);
293
+ newDate.setUTCMonth(newDate.getUTCMonth() + monthDiff);
294
+ this.currentDate = newDate;
295
+ };
296
+ /**
297
+ * Handles year change in the numeric entry
298
+ * @param {Event} event - Year change event
299
+ * @param {number} calendarOffset - Calendar offset (0 by default)
300
+ */
301
+ this.handleYearChange = (event, calendarOffset = 0) => {
302
+ const input = event.target;
303
+ const year = parseInt(input.value, 10);
304
+ if (!isNaN(year) && year >= 1900 && year <= 2100) {
305
+ const newDate = new Date(this.currentDate);
306
+ newDate.setUTCFullYear(year);
307
+ newDate.setUTCMonth(newDate.getUTCMonth() + calendarOffset);
308
+ this.currentDate = newDate;
309
+ }
310
+ };
311
+ /**
312
+ * Handles week selection
313
+ * @param {Date[]} weekDays - Selected week days
314
+ * @param {number} calendarIndex - Calendar index from which the selection is made
315
+ */
316
+ this.handleWeekSelection = (weekDays, calendarIndex) => {
317
+ if (this.selectionType !== 'range')
318
+ return;
319
+ const allDays = this.getDaysInMonth(calendarIndex, this.numberOfCalendars);
320
+ const weekStart = weekDays[0];
321
+ const weekEnd = weekDays[weekDays.length - 1];
322
+ if (!weekStart || !weekEnd)
323
+ return;
324
+ const selectedWeekDays = allDays.filter(day => day.date && day.date >= weekStart && day.date <= weekEnd);
325
+ const validDays = selectedWeekDays.filter(day => !this.isDateDisabled(day.date));
326
+ if (validDays.length > 0) {
327
+ this.startDate = validDays[0].date;
328
+ this.endDate = validDays[validDays.length - 1].date;
329
+ this.rangeDateChange.emit({
330
+ start: formatDate(this.startDate, { dateFormat: this.dateFormat }),
331
+ end: formatDate(this.endDate, { dateFormat: this.dateFormat }),
332
+ });
333
+ }
334
+ };
335
+ /**
336
+ * Checks if a date corresponds to today
337
+ * @param {Date} date - Date to check
338
+ * @returns {boolean} true if the date is today
339
+ */
340
+ this.isToday = (date) => {
341
+ const today = new Date();
342
+ return (date.getDate() === today.getDate() &&
343
+ date.getMonth() === today.getMonth() &&
344
+ date.getFullYear() === today.getFullYear());
345
+ };
346
+ /**
347
+ * Parse and cache the disabled dates
348
+ * @description Parse and cache the disabled dates
349
+ */
350
+ this.parseDisabledDates = () => {
351
+ if (!this.disabledDates) {
352
+ this.parsedDisabledDates = [];
353
+ return;
354
+ }
355
+ try {
356
+ this.parsedDisabledDates = this.disabledDates
357
+ .map(date => parseDate(date, this.dateFormat))
358
+ .filter(date => date !== null);
359
+ }
360
+ catch (error) {
361
+ console.error('Error parsing disabled dates:', error);
362
+ this.parsedDisabledDates = [];
363
+ }
364
+ };
365
+ /**
366
+ * Applies a shortcut selection
367
+ * @param {Object} shortcut - Shortcut to apply
368
+ * @param {string | Date} shortcut.singleValue - Selected date value
369
+ * @param {Object} shortcut.rangeValue - Start and end date values
370
+ * @param {string | Date} shortcut.rangeValue.start - Start date value
371
+ * @param {string | Date} shortcut.rangeValue.end - End date value
372
+ * @param {string} shortcut.label - Label
373
+ */
374
+ this.applyShortcut = (shortcut) => {
375
+ this.selectedDate = null;
376
+ this.startDate = null;
377
+ this.endDate = null;
378
+ if (shortcut.singleValue) {
379
+ const newDate = parseDate(shortcut.singleValue, this.dateFormat);
380
+ this.selectedDate = newDate;
381
+ this.singleDateChange.emit(formatDate(newDate, { dateFormat: this.dateFormat }));
382
+ this.singleValue = formatDate(newDate, { dateFormat: this.dateFormat });
383
+ if (!this.showActions) {
384
+ const event = new CustomEvent('closePopover', {
385
+ bubbles: true,
386
+ composed: true,
387
+ });
388
+ this.el.dispatchEvent(event);
389
+ }
390
+ this.forceCalendarUpdate(newDate);
391
+ }
392
+ else {
393
+ const start = parseDate(shortcut.rangeValue.start, this.dateFormat);
394
+ const end = parseDate(shortcut.rangeValue.end, this.dateFormat);
395
+ this.startDate = start;
396
+ this.endDate = end;
397
+ this.rangeDateChange.emit({
398
+ start: formatDate(start, { dateFormat: this.dateFormat }),
399
+ end: formatDate(end, { dateFormat: this.dateFormat }),
400
+ });
401
+ this.rangeValue = {
402
+ start: formatDate(start, { dateFormat: this.dateFormat }),
403
+ end: formatDate(end, { dateFormat: this.dateFormat }),
404
+ };
405
+ if (!this.showActions) {
406
+ const event = new CustomEvent('closePopover', {
407
+ bubbles: true,
408
+ composed: true,
409
+ });
410
+ this.el.dispatchEvent(event);
411
+ }
412
+ this.currentDate = start;
413
+ }
414
+ };
415
+ /**
416
+ * Method to force the complete calendar update
417
+ * @param {Date} newDate - Date to force
418
+ */
419
+ this.forceCalendarUpdate = newDate => {
420
+ this.currentDate = new Date(newDate);
421
+ };
422
+ /**
423
+ * Handles month change with an offset
424
+ * @param {number} direction - Direction (-1 for previous, 1 for next)
425
+ * @returns {Function} Change month handler
426
+ */
427
+ this.getChangeMonthHandler = (direction) => {
428
+ return () => this.changeMonth(direction);
429
+ };
430
+ /**
431
+ * Handles month change from an event (ex: dropdown)
432
+ * @param {number} offset - Month offset (0 by default)
433
+ * @returns {Function} Change month handler
434
+ */
435
+ this.getHandleMonthChange = (offset) => {
436
+ return (event) => this.handleMonthChange(event, offset);
437
+ };
438
+ /**
439
+ * Handles year change from an event (ex: dropdown)
440
+ * @param {number} offset - Year offset (0 by default)
441
+ * @returns {Function} Change year handler
442
+ */
443
+ this.getHandleYearChange = (offset) => {
444
+ return (event) => this.handleYearChange(event, offset);
445
+ };
446
+ /**
447
+ * Handles day click
448
+ * @param {Date} date - Date to handle
449
+ * @param {boolean} isDisabled - Whether the date is disabled
450
+ * @returns {Function} Day click handler
451
+ */
452
+ this.getDayClickHandler = (date, isDisabled) => {
453
+ return isDisabled ? undefined : () => this.handleDateSelection(date);
454
+ };
455
+ /**
456
+ * Handles shortcut selection
457
+ * @param {Object} shortcut - Shortcut to handle
458
+ * @param {string | Date} shortcut.singleValue - Selected date value
459
+ * @param {Object} shortcut.rangeValue - Start and end date values
460
+ * @param {string | Date} shortcut.rangeValue.start - Start date value
461
+ * @param {string | Date} shortcut.rangeValue.end - End date value
462
+ * @param {string} shortcut.label - Label
463
+ * @returns {Function} Shortcut selection handler
464
+ */
465
+ this.getShortcutHandler = (shortcut) => {
466
+ return () => this.applyShortcut(shortcut);
467
+ };
468
+ /**
469
+ * Handles week selection
470
+ * @param {Date[]} dates - Dates to handle
471
+ * @param {number} index - Calendar index
472
+ * @returns {Function} Week selection handler
473
+ */
474
+ this.getWeekSelectionHandler = (dates, index) => {
475
+ return () => {
476
+ if (this.selectionType === 'range') {
477
+ this.handleWeekSelection(dates, index);
478
+ }
479
+ };
480
+ };
95
481
  /**
96
482
  * Resets the current selection
97
483
  */
98
484
  this.resetSelection = () => {
99
485
  if (this.selectionType === 'single') {
100
486
  this.selectedDate = null;
101
- this.singleValue = '';
487
+ this.singleValue = null;
102
488
  this.singleDateChange.emit('');
103
489
  }
104
490
  else {
105
491
  this.startDate = null;
106
492
  this.endDate = null;
107
- this.rangeValue = '';
493
+ this.rangeValue = null;
108
494
  this.rangeDateChange.emit({ start: '', end: '' });
109
495
  }
110
496
  };
@@ -113,7 +499,9 @@ export class NvCalendar {
113
499
  */
114
500
  this.confirmSelection = () => {
115
501
  if (this.selectionType === 'single' && this.selectedDate) {
116
- const dateStr = this.formatDate(this.selectedDate);
502
+ const dateStr = formatDate(this.selectedDate, {
503
+ dateFormat: this.dateFormat,
504
+ });
117
505
  this.singleDateChange.emit(dateStr);
118
506
  this.singleValue = dateStr;
119
507
  const event = new CustomEvent('closePopover', {
@@ -126,13 +514,13 @@ export class NvCalendar {
126
514
  this.startDate &&
127
515
  this.endDate) {
128
516
  this.rangeDateChange.emit({
129
- start: this.formatDate(this.startDate),
130
- end: this.formatDate(this.endDate),
131
- });
132
- this.rangeValue = JSON.stringify({
133
- start: this.formatDate(this.startDate),
134
- end: this.formatDate(this.endDate),
517
+ start: formatDate(this.startDate, { dateFormat: this.dateFormat }),
518
+ end: formatDate(this.endDate, { dateFormat: this.dateFormat }),
135
519
  });
520
+ this.rangeValue = {
521
+ start: formatDate(this.startDate, { dateFormat: this.dateFormat }),
522
+ end: formatDate(this.endDate, { dateFormat: this.dateFormat }),
523
+ };
136
524
  const event = new CustomEvent('closePopover', {
137
525
  bubbles: true,
138
526
  composed: true,
@@ -140,353 +528,114 @@ export class NvCalendar {
140
528
  this.el.dispatchEvent(event);
141
529
  }
142
530
  };
143
- }
144
- //#endregion EVENTS
145
- /****************************************************************************/
146
- //#region LIFECYCLE
147
- componentWillLoad() {
148
- this.parseDisabledDates();
149
- if (this.selectionType === 'single' && this.singleValue) {
150
- this.selectedDate = this.parseDate(this.singleValue);
151
- this.currentDate = this.selectedDate;
152
- }
153
- else if (this.selectionType === 'range' && this.rangeValue) {
154
- try {
155
- let parsed;
156
- if (typeof this.rangeValue === 'string') {
157
- parsed = JSON.parse(this.rangeValue);
158
- }
159
- else {
160
- parsed = this.rangeValue;
161
- }
162
- if (parsed.start && parsed.end) {
163
- this.startDate = this.parseDate(parsed.start);
164
- this.endDate = this.parseDate(parsed.end);
165
- this.currentDate = this.startDate;
166
- if (this.startDate && this.endDate && this.startDate > this.endDate) {
167
- console.warn(`Warning: startDate (${this.formatDate(this.startDate)}) is after endDate (${this.formatDate(this.endDate)})`);
168
- // [this.startDate, this.endDate] = [this.endDate, this.startDate];
169
- throw new Error('startDate cannot be after endDate');
170
- }
171
- }
172
- }
173
- catch (error) {
174
- console.error('Invalid JSON for rangeValue:', error);
175
- }
176
- }
177
- else {
178
- this.currentDate = new Date();
179
- }
180
- this.initializeMonths();
181
- }
182
- // componentDidLoad() {
183
- // if (this.rangeValue) {
184
- // this.onRangeValueChange(this.rangeValue);
185
- // }
186
- // }
187
- //#endregion LIFECYCLE
188
- /****************************************************************************/
189
- //#region METHODS
190
- /**
191
- * Change the displayed month
192
- * @param {number} offset - Month offset (-1 for previous, 1 for next)
193
- */
194
- changeMonth(offset) {
195
- const newDate = new Date(this.currentDate);
196
- // Ensure we only move by one month at a time
197
- newDate.setUTCMonth(newDate.getUTCMonth() + offset);
198
- // Add the appropriate animation class
199
- const containers = this.el.querySelectorAll('.calendar-grid');
200
- containers.forEach(container => {
201
- // Remove existing animation classes
202
- container.classList.remove('slide-left', 'slide-right');
203
- // Add the new animation class
204
- const animationClass = offset > 0 ? 'slide-left' : 'slide-right';
205
- container.classList.add(animationClass);
206
- // Remove the class after the animation
207
- setTimeout(() => {
208
- container.classList.remove(animationClass);
209
- }, 300); // 300ms corresponds to $slide-duration in the SCSS
210
- });
211
- this.currentDate = newDate;
212
- }
213
- /**
214
- * Handles date selection based on the mode
215
- * @param {Date} date - Selected date
216
- */
217
- handleDateSelection(date) {
218
- if (this.isDateDisabled(date)) {
219
- return;
220
- }
221
- if (this.selectionType === 'single') {
222
- this.handleSingleSelection(date);
223
- }
224
- else {
225
- this.handleRangeSelection(date);
226
- }
227
- }
228
- /**
229
- * Handles single date selection
230
- * @param {Date} date - Selected date
231
- */
232
- handleSingleSelection(date) {
233
- if (!date)
234
- return;
235
- const formattedDate = this.formatDate(date);
236
- this.selectedDate = date;
237
- this.singleDateChange.emit(formattedDate);
238
- }
239
- /**
240
- * Handles range date selection
241
- * @param {Date} date - Selected date
242
- */
243
- handleRangeSelection(date) {
244
- if (!this.startDate || (this.startDate && this.endDate)) {
245
- this.startDate = date;
246
- this.endDate = null;
247
- }
248
- else {
249
- this.endDate = date;
250
- if (this.startDate > this.endDate) {
251
- [this.startDate, this.endDate] = [this.endDate, this.startDate];
252
- }
253
- this.rangeDateChange.emit({
254
- start: this.formatDate(this.startDate),
255
- end: this.formatDate(this.endDate),
256
- });
257
- }
258
- }
259
- /**
260
- * Calculates the ISO week number
261
- * @param {Date} date - Date to calculate
262
- * @returns {number} Week number
263
- */
264
- getWeekNumber(date) {
265
- const startOfYear = new Date(date.getFullYear(), 0, 1);
266
- const pastDaysOfYear = (date.getTime() - startOfYear.getTime()) / 86400000;
267
- return Math.ceil((pastDaysOfYear + startOfYear.getDay() + 1) / 7);
268
- }
269
- /**
270
- * Checks if a date is disabled.
271
- * Disabled if:
272
- * - The date is before min (if defined)
273
- * - The date is after max (if defined)
274
- * - The date is in the disabledDates array
275
- * @param {Date} date - Date to check
276
- * @returns {boolean} true if the date is disabled
277
- */
278
- isDateDisabled(date) {
279
- if (!date)
280
- return true;
281
- // Minimum bound check
282
- if (this.min) {
283
- const minDate = this.parseDate(this.min);
284
- if (minDate && date < minDate) {
285
- return true;
286
- }
287
- }
288
- // Maximum bound check
289
- if (this.max) {
290
- const maxDate = this.parseDate(this.max);
291
- if (maxDate && date > maxDate) {
292
- return true;
293
- }
294
- }
295
- // Check disabled dates
296
- return this.parsedDisabledDates.some(disabledDate => this.isSameDate(date, disabledDate));
297
- }
298
- /**
299
- * Checks if a date is in the selected range
300
- * @param {Date} date - Date to check
301
- * @returns {boolean} true if the date is in the range
302
- */
303
- isDateInRange(date) {
304
- if (!date || !this.startDate || !this.endDate)
305
- return false;
306
- const checkDate = this.parseDate(date);
307
- const startDate = this.parseDate(this.startDate);
308
- const endDate = this.parseDate(this.endDate);
309
- // Verify if startDate and endDate are valid
310
- if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {
311
- return false;
312
- }
313
- // Verify that startDate is before endDate (additional security)
314
- if (startDate > endDate)
315
- return false;
316
- // Comparison based only on the date (year, month, day)
317
- return (this.isSameOrAfter(checkDate, startDate) &&
318
- this.isSameOrBefore(checkDate, endDate));
319
- }
320
- /**
321
- * Retrieves the localized day names
322
- * @returns {string[]} Array of short day names
323
- */
324
- getDayNames() {
325
- // If we have custom day names for this locale
326
- if (CUSTOM_DAY_NAMES[this.locale]) {
327
- const days = [...CUSTOM_DAY_NAMES[this.locale]];
328
- // Reorganize the days based on the first day of the week
329
- const firstDays = days.slice(0, this.firstDayOfWeek);
330
- const remainingDays = days.slice(this.firstDayOfWeek);
331
- return [...remainingDays, ...firstDays];
332
- }
333
- // Otherwise, use the default behavior
334
- const formatter = new Intl.DateTimeFormat(this.locale, {
335
- weekday: 'short',
336
- });
337
- const days = [...Array(7)].map((_, i) => formatter.format(new Date(2023, 0, i + 1)).toUpperCase());
338
- // Reorganize the days based on the first day of the week
339
- const firstDays = days.slice(0, this.firstDayOfWeek);
340
- const remainingDays = days.slice(this.firstDayOfWeek);
341
- return [...remainingDays, ...firstDays];
342
- }
343
- /**
344
- * Generates the days of the current month
345
- * @param {number} offset - Month offset (0 by default)
346
- * @param {number} totalCalendars - Number of calendars to display (1 by default)
347
- * @returns {Array<{ dayOfMonth: number | null, date: Date | null, isSelected: boolean, isDisabled: boolean }>} Array of formatted days
348
- */
349
- getDaysInMonth(offset = 0, totalCalendars = 1) {
350
- const year = this.currentDate.getUTCFullYear();
351
- const month = this.currentDate.getUTCMonth() + offset;
352
- const firstDay = new Date(Date.UTC(year, month, 1));
353
- const lastDay = new Date(Date.UTC(year, month + 1, 0));
354
- const days = [];
355
- // Correct calculation of offset for previous month days
356
- // Use getUTCDay to stay consistent with UTC timezone
357
- const dayOfWeekIndex = firstDay.getUTCDay(); // 0 = Sunday, 1 = Monday, etc.
358
- // Adjust based on firstDayOfWeek (if week starts on Monday, offset is different)
359
- const offsetDays = (dayOfWeekIndex - this.firstDayOfWeek + 7) % 7;
360
- // Add the days of the previous month for the first calendar
361
- if (offset === 0 && offsetDays > 0) {
362
- const prevMonthLastDay = new Date(Date.UTC(year, month, 0)).getUTCDate();
363
- for (let i = offsetDays; i > 0; i--) {
364
- const date = new Date(Date.UTC(year, month - 1, prevMonthLastDay - i + 1));
365
- days.push({
366
- dayOfMonth: date.getUTCDate(),
367
- date,
368
- isCurrentMonth: false,
369
- isDisabled: this.isDateDisabled(date),
531
+ //#endregion METHODS
532
+ /****************************************************************************/
533
+ //#region RENDER
534
+ /**
535
+ * Renders the header
536
+ * @param {number} offset - Month offset
537
+ * @param {number} index - Calendar index
538
+ * @returns {JSX.Element} Header
539
+ * @description Renders the header of the calendar
540
+ */
541
+ this.renderHeader = (offset, index) => {
542
+ return (h("div", { class: "header" }, this.numberOfCalendars > 1 && index === 0 && (h("nv-iconbutton", { class: "nav-left", emphasis: "lower", name: "chevron-left", onClick: this.getChangeMonthHandler(-1) })), h("div", { class: "date-controls" }, h("select", { class: "month-select mr-4", onChange: this.getHandleMonthChange(offset) }, this.months.map(month => (h("option", { key: month.value, value: month.value, selected: month.value === (this.currentDate.getUTCMonth() + offset) % 12 }, month.label)))), h("input", { type: "number", class: "year-input", min: "1950", max: "2100", value: this.currentDate.getUTCFullYear() +
543
+ Math.floor((this.currentDate.getUTCMonth() + offset) / 12), onChange: this.getHandleYearChange(offset) })), this.numberOfCalendars === 1 && (h("div", { class: "nav-buttons" }, h("nv-iconbutton", { emphasis: "lower", name: "chevron-left", onClick: this.getChangeMonthHandler(-1) }), h("nv-iconbutton", { emphasis: "lower", name: "chevron-right", onClick: this.getChangeMonthHandler(1) }))), this.numberOfCalendars > 1 && index === this.numberOfCalendars - 1 && (h("nv-iconbutton", { emphasis: "lower", name: "chevron-right", onClick: this.getChangeMonthHandler(1), class: "nav-right" }))));
544
+ };
545
+ /**
546
+ * Renders the week numbers
547
+ * @param {Array<{date: Date}>} weeks - Weeks to render
548
+ * @param {number} index - Calendar index
549
+ * @returns {JSX.Element} Week numbers
550
+ * @description Renders the week numbers of the calendar
551
+ */
552
+ this.renderWeekNumbers = (
553
+ /** Weeks to render */
554
+ weeks,
555
+ /** Calendar index */
556
+ index) => {
557
+ return (h("div", { class: "week-numbers" }, h("div", { class: "week-header" }, this.getLocalizedWeekText()), weeks.map((week, weekIndex) => {
558
+ var _a;
559
+ const dates = week.map(d => d.date);
560
+ return (h("div", { class: `week-number ${this.selectionType === 'range' ? 'clickable' : ''}`, onClick: this.getWeekSelectionHandler(dates, index), key: `week-${weekIndex}` }, getWeekNumber(((_a = week.find(d => d.date)) === null || _a === void 0 ? void 0 : _a.date) || new Date())));
561
+ })));
562
+ };
563
+ this.renderDaysGrid = (
564
+ /** Days to render */
565
+ days) => {
566
+ return (h("div", { class: "days-grid" }, days.map(day => {
567
+ const date = day.date;
568
+ if (!date)
569
+ return null;
570
+ const isSelected = this.selectionType === 'single' &&
571
+ isSameDate(date, this.selectedDate, { isUTCMode: this.isUTCMode });
572
+ const isInRange = this.isDateInRange(date);
573
+ const isStart = isSameDate(date, this.startDate, {
574
+ isUTCMode: this.isUTCMode,
370
575
  });
371
- }
372
- }
373
- // Add the days of the current month
374
- for (let i = 1; i <= lastDay.getUTCDate(); i++) {
375
- const date = new Date(Date.UTC(year, month, i));
376
- days.push({
377
- dayOfMonth: i,
378
- date,
379
- isCurrentMonth: true,
380
- isDisabled: this.isDateDisabled(date),
381
- });
382
- }
383
- // Add the days of the next month only for the last calendar
384
- if (offset === totalCalendars - 1) {
385
- const nextMonthDaysNeeded = 7 - (days.length % 7 || 7);
386
- for (let i = 1; i <= nextMonthDaysNeeded; i++) {
387
- const date = new Date(Date.UTC(year, month + 1, i));
388
- days.push({
389
- dayOfMonth: i,
390
- date,
391
- isCurrentMonth: false,
392
- isDisabled: this.isDateDisabled(date),
576
+ const isEnd = isSameDate(date, this.endDate, {
577
+ isUTCMode: this.isUTCMode,
393
578
  });
579
+ const isToday = this.isToday(date);
580
+ const isOutsideMonth = !day.isCurrentMonth;
581
+ const dayClasses = [
582
+ 'day',
583
+ isSelected ? 'selected' : '',
584
+ isStart ? 'range-start' : '',
585
+ isEnd ? 'range-end' : '',
586
+ isInRange ? 'in-range' : '',
587
+ day.isDisabled ? 'disabled' : '',
588
+ isOutsideMonth ? 'outside-month' : '',
589
+ isToday ? 'is-today' : '',
590
+ ];
591
+ return (h("div", { class: dayClasses.filter(Boolean).join(' '), onClick: this.getDayClickHandler(date, day.isDisabled), "aria-disabled": day.isDisabled, key: `day-${date.toISOString()}` }, day.dayOfMonth));
592
+ })));
593
+ };
594
+ /**
595
+ * Renders the calendar
596
+ * @param {number} index - Calendar index
597
+ * @param {number} offset - Month offset
598
+ * @returns {JSX.Element} Calendar
599
+ * @description Renders the calendar of the calendar
600
+ */
601
+ this.renderCalendar = (
602
+ /** Calendar index */
603
+ index,
604
+ /** Month offset */
605
+ offset) => {
606
+ const days = this.getDaysInMonth(offset, this.numberOfCalendars);
607
+ const weeks = [];
608
+ for (let i = 0; i < days.length; i += 7) {
609
+ weeks.push(days.slice(i, i + 7));
394
610
  }
395
- }
396
- return days;
397
- }
398
- /** Initializes the list of formatted months according to the locale */
399
- initializeMonths() {
400
- // If we have custom month names for this locale
401
- if (CUSTOM_MONTH_NAMES[this.locale]) {
402
- this.months = CUSTOM_MONTH_NAMES[this.locale].map((label, value) => ({
403
- value,
404
- label,
405
- }));
406
- return;
407
- }
408
- // Otherwise, use the default behavior
409
- const formatter = new Intl.DateTimeFormat(this.locale, { month: 'short' });
410
- this.months = Array.from({ length: 12 }, (_, i) => ({
411
- value: i,
412
- label: formatter.format(new Date(2000, i, 1)).toUpperCase(),
413
- }));
414
- }
415
- /**
416
- * Retrieves the localized abbreviation for "week"
417
- * @returns {string} Localized abbreviation for "week"
418
- */
419
- getLocalizedWeekText() {
420
- return WEEK_ABBREVIATIONS[this.locale] || 'W';
421
- }
422
- /**
423
- * Handles month change in the selector
424
- * @param {Event} event - Month change event
425
- * @param {number} calendarOffset - Calendar offset (0 by default)
426
- */
427
- handleMonthChange(event, calendarOffset = 0) {
428
- const select = event.target;
429
- const selectedMonth = parseInt(select.value, 10);
430
- const currentMonth = this.currentDate.getUTCMonth();
431
- // Calculate the difference considering the calendar offset
432
- const monthDiff = selectedMonth - ((currentMonth + calendarOffset) % 12);
433
- const newDate = new Date(this.currentDate);
434
- newDate.setUTCMonth(newDate.getUTCMonth() + monthDiff);
435
- this.currentDate = newDate;
436
- }
437
- /**
438
- * Handles year change in the numeric entry
439
- * @param {Event} event - Year change event
440
- * @param {number} calendarOffset - Calendar offset (0 by default)
441
- */
442
- handleYearChange(event, calendarOffset = 0) {
443
- const input = event.target;
444
- const year = parseInt(input.value, 10);
445
- if (!isNaN(year) && year >= 1900 && year <= 2100) {
446
- const newDate = new Date(this.currentDate);
447
- newDate.setUTCFullYear(year);
448
- newDate.setUTCMonth(newDate.getUTCMonth() + calendarOffset);
449
- this.currentDate = newDate;
450
- }
451
- }
452
- /**
453
- * Handles week selection
454
- * @param {Date[]} weekDays - Selected week days
455
- * @param {number} calendarIndex - Calendar index from which the selection is made
456
- */
457
- handleWeekSelection(weekDays, calendarIndex) {
458
- if (this.selectionType !== 'range')
459
- return;
460
- const allDays = this.getDaysInMonth(calendarIndex, this.numberOfCalendars);
461
- const weekStart = weekDays[0];
462
- const weekEnd = weekDays[weekDays.length - 1];
463
- if (!weekStart || !weekEnd)
464
- return;
465
- const selectedWeekDays = allDays.filter(day => day.date && day.date >= weekStart && day.date <= weekEnd);
466
- const validDays = selectedWeekDays.filter(day => !this.isDateDisabled(day.date));
467
- if (validDays.length > 0) {
468
- this.startDate = validDays[0].date;
469
- this.endDate = validDays[validDays.length - 1].date;
470
- this.rangeDateChange.emit({
471
- start: this.formatDate(this.startDate),
472
- end: this.formatDate(this.endDate),
473
- });
474
- }
475
- }
476
- /**
477
- * Checks if a date corresponds to today
478
- * @param {Date} date - Date to check
479
- * @returns {boolean} true if the date is today
480
- */
481
- isToday(date) {
482
- const today = new Date();
483
- return (date.getDate() === today.getDate() &&
484
- date.getMonth() === today.getMonth() &&
485
- date.getFullYear() === today.getFullYear());
611
+ return (h("div", { class: "calendar-wrapper" }, h("div", { class: "calendar-container", key: `calendar-${index}` }, this.renderHeader(offset, index), h("div", { class: "calendar-grid" }, this.showWeekNumbers && this.renderWeekNumbers(weeks, index), h("div", { class: "days-container" }, h("div", { class: "days-header" }, this.getDayNames().map(day => (h("div", { class: "day-header" }, day)))), this.renderDaysGrid(days)))), index < this.numberOfCalendars - 1 && (h("div", { class: "calendar-separator" }))));
612
+ };
613
+ /**
614
+ * Renders the shortcuts
615
+ * @returns {JSX.Element} Shortcuts
616
+ * @description Renders the shortcuts of the calendar
617
+ */
618
+ this.renderShortcuts = () => {
619
+ if (!this.hasShortcuts) {
620
+ return null;
621
+ }
622
+ return (h("div", { class: `shortcuts-container shortcuts-placement-${this.shortcutsPlacement}` }, this.shortcuts.map(shortcut => (h("nv-button", { emphasis: "lower", size: "xs", "aria-label": shortcut.label, onClick: this.getShortcutHandler(shortcut) }, shortcut.label)))));
623
+ };
624
+ /**
625
+ * Renders the actions
626
+ * @returns {JSX.Element} Actions
627
+ * @description Renders the actions of the calendar
628
+ * @slot actions - Child content of the component.
629
+ */
630
+ this.renderActions = () => {
631
+ return (h("div", { class: "datepicker-actions" }, h("slot", { name: "actions" }, h("nv-button", { emphasis: "low", size: "xs", onClick: this.resetSelection }, "Cancel"), h("nv-button", { size: "xs", onClick: this.confirmSelection }, "OK"))));
632
+ };
486
633
  }
634
+ //#endregion EVENTS
635
+ /****************************************************************************/
636
+ //#region WATCHERS
487
637
  /**
488
638
  * Watches the changes of the number of calendars
489
- * @watch numberOfCalendars
490
639
  * @param {number} newValue - New number of calendars
491
640
  */
492
641
  validateNumberOfCalendars(newValue) {
@@ -497,29 +646,29 @@ export class NvCalendar {
497
646
  }
498
647
  /**
499
648
  * Watches the changes of the selected date range
500
- * @watch rangeValue
501
649
  * @param {Object} newValue - New rangeValue value
502
650
  * @param {string} newValue.start - Start date
503
651
  * @param {string} newValue.end - End date
504
652
  */
505
653
  onRangeValueChange(newValue) {
506
- if (newValue) {
654
+ if (newValue && newValue.start && newValue.end) {
507
655
  try {
508
- const parsed = JSON.parse(newValue);
509
- if (parsed.start && parsed.end) {
510
- this.startDate = this.parseDate(parsed.start);
511
- this.endDate = this.parseDate(parsed.end);
512
- this.currentDate = this.parseDate(parsed.start);
656
+ const { startDate, endDate } = this.validateDateRange(newValue.start, newValue.end);
657
+ this.startDate = startDate;
658
+ this.endDate = endDate;
659
+ // Do not navigate to the start date if data-prevent-navigation attribute is present
660
+ const preventNavigation = this.el.getAttribute('data-prevent-navigation') === 'true';
661
+ if (!preventNavigation) {
662
+ this.currentDate = startDate;
513
663
  }
514
664
  }
515
665
  catch (error) {
516
- console.error('Invalid JSON for rangeValue:', error);
666
+ console.error('Invalid rangeValue:', error);
517
667
  }
518
668
  }
519
669
  }
520
670
  /**
521
671
  * Watches the changes of the disabled dates
522
- * @watch disabledDates
523
672
  * @description Watches the changes of the disabled dates
524
673
  */
525
674
  handleDisabledDatesChange() {
@@ -527,381 +676,65 @@ export class NvCalendar {
527
676
  }
528
677
  /**
529
678
  * Watches the changes of the single value
530
- * @watch singleValue
531
679
  * @param {string} newValue - New single value
532
680
  * @param {string} oldValue - Old single value
533
681
  */
534
682
  onSingleValueChange(newValue, oldValue) {
535
683
  if (this.selectionType === 'single' && newValue !== oldValue && newValue) {
536
- const parsedDate = this.parseDate(newValue);
684
+ const parsedDate = parseDate(newValue, this.dateFormat);
537
685
  if (parsedDate) {
538
686
  this.selectedDate = parsedDate;
539
- this.currentDate = parsedDate;
687
+ // Do not navigate to the selected date if data-prevent-navigation attribute is present
688
+ const preventNavigation = this.el.getAttribute('data-prevent-navigation') === 'true';
689
+ if (!preventNavigation) {
690
+ this.currentDate = parsedDate;
691
+ }
540
692
  }
541
693
  }
542
694
  }
543
- /**
544
- * Convert a date string/Date to a Date without timezone offset
545
- * @param {string | Date} dateInput - Date under string or Date object form
546
- * @returns {Date} Date in Date form without timezone offset
547
- */
548
- parseDate(dateInput) {
549
- if (dateInput instanceof Date)
550
- return dateInput;
551
- // Attempt to automatically detect ISO 8601 format (generated by toISOString())
552
- // The regex checks the standard ISO format: YYYY-MM-DDTHH:mm:ss.sssZ
553
- if (typeof dateInput === 'string' &&
554
- /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$/.test(dateInput)) {
695
+ //#endregion WATCHERS
696
+ /****************************************************************************/
697
+ //#region LIFECYCLE
698
+ componentWillLoad() {
699
+ this.parseDisabledDates();
700
+ if (this.selectionType === 'single' && this.singleValue) {
701
+ this.selectedDate = parseDate(this.singleValue, this.dateFormat);
702
+ this.currentDate = this.selectedDate;
703
+ }
704
+ else if (this.selectionType === 'range' && this.rangeValue) {
555
705
  try {
556
- const parsedDate = new Date(dateInput);
557
- if (!isNaN(parsedDate.getTime())) {
558
- return parsedDate;
706
+ if (this.rangeValue.start && this.rangeValue.end) {
707
+ const { startDate, endDate, swapped } = this.validateDateRange(this.rangeValue.start, this.rangeValue.end);
708
+ this.startDate = startDate;
709
+ this.endDate = endDate;
710
+ this.currentDate = startDate;
711
+ if (swapped) {
712
+ // If dates were swapped, update the rangeValue property
713
+ this.rangeValue = {
714
+ start: formatDate(startDate, { dateFormat: this.dateFormat }),
715
+ end: formatDate(endDate, { dateFormat: this.dateFormat }),
716
+ };
717
+ }
559
718
  }
560
719
  }
561
720
  catch (error) {
562
- // If it fails, continue with other methods
563
- console.error('Error parsing ISO date:', error);
564
- }
565
- }
566
- // Handling Unix Seconds ("X") formats
567
- if (this.dateFormat === 'X') {
568
- const unixSeconds = Number(dateInput);
569
- if (isNaN(unixSeconds))
570
- return null;
571
- return this.isUTCMode
572
- ? dayjs.unix(unixSeconds).utc().toDate()
573
- : dayjs.unix(unixSeconds).toDate();
574
- }
575
- // Handling Unix Milliseconds ("x") formats
576
- if (this.dateFormat === 'x') {
577
- const unixMilliseconds = Number(dateInput);
578
- if (isNaN(unixMilliseconds))
579
- return null;
580
- return this.isUTCMode
581
- ? dayjs(unixMilliseconds).utc().toDate()
582
- : dayjs(unixMilliseconds).toDate();
583
- }
584
- // Handling C# Ticks format
585
- if (this.dateFormat === 'Ticks') {
586
- const ticks = Number(dateInput);
587
- if (isNaN(ticks))
588
- return null;
589
- // Conversion of .NET ticks to milliseconds since Unix epoch
590
- const unixMilliseconds = (ticks - 621355968000000000) / 10000;
591
- return this.isUTCMode
592
- ? dayjs(unixMilliseconds).utc().toDate()
593
- : dayjs(unixMilliseconds).toDate();
594
- }
595
- // For all other formats, use customParseFormat in strict mode
596
- let parsed;
597
- if (this.isUTCMode) {
598
- parsed = dayjs.utc(dateInput, this.dateFormat, true);
599
- }
600
- else {
601
- parsed = dayjs(dateInput, this.dateFormat, true);
602
- }
603
- if (!parsed.isValid()) {
604
- console.error(`Parsing error:`, {
605
- dateInput,
606
- dateFormat: this.dateFormat,
607
- });
608
- return null;
609
- }
610
- return parsed.toDate();
611
- }
612
- /**
613
- * Checks if the date format is in UTC mode
614
- * @returns {boolean} true if the date format is in UTC mode
615
- */
616
- get isUTCMode() {
617
- return this.dateFormat.includes('Z');
618
- }
619
- /**
620
- * Checks if the date format is ISO 8601
621
- * @returns {boolean} true if the format is ISO 8601
622
- */
623
- get isISO8601Format() {
624
- return this.dateFormat === 'YYYY-MM-DD[T]HH:mm:ss[Z]';
625
- }
626
- /**
627
- * Formats a date to a string according to the format
628
- * @param {Date} date - Date to format
629
- * @returns {string} Formatted date
630
- */
631
- formatDate(date) {
632
- if (!date)
633
- return '';
634
- // Special case for ISO 8601
635
- if (this.isISO8601Format) {
636
- // For the ISO 8601 format, use directly toISOString() which is standard
637
- return date.toISOString();
638
- }
639
- // If the format is "Ticks", convert the time to C# ticks
640
- if (this.dateFormat === 'Ticks') {
641
- const ticks = date.getTime() * 10000 + 621355968000000000;
642
- return ticks.toString();
643
- }
644
- // If the format is "X" (Unix Seconds)
645
- if (this.dateFormat === 'X') {
646
- return dayjs(date).unix().toString();
647
- }
648
- // If the format is "x" (Unix Milliseconds)
649
- if (this.dateFormat === 'x') {
650
- return date.getTime().toString();
651
- }
652
- // Otherwise, format according to the mode (UTC or local)
653
- return this.isUTCMode
654
- ? dayjs(date).utc().format(this.dateFormat)
655
- : dayjs(date).format(this.dateFormat);
656
- }
657
- /**
658
- * Parse and cache the disabled dates
659
- * @description Parse and cache the disabled dates
660
- */
661
- parseDisabledDates() {
662
- if (!this.disabledDates) {
663
- this.parsedDisabledDates = [];
664
- return;
665
- }
666
- try {
667
- const disabledDatesArray = JSON.parse(this.disabledDates);
668
- this.parsedDisabledDates = disabledDatesArray
669
- .map(date => this.parseDate(date))
670
- .filter(date => date !== null);
671
- }
672
- catch (error) {
673
- console.error('Error parsing disabled dates:', error);
674
- this.parsedDisabledDates = [];
675
- }
676
- }
677
- /**
678
- * Checks if two dates are identical
679
- * @param {Date | null} date1 - First date
680
- * @param {Date | null} date2 - Second date
681
- * @returns {boolean} true if the dates are identical
682
- */
683
- isSameDate(date1, date2) {
684
- if (!date1 || !date2)
685
- return false;
686
- if (this.isUTCMode) {
687
- return (date1.getUTCFullYear() === date2.getUTCFullYear() &&
688
- date1.getUTCMonth() === date2.getUTCMonth() &&
689
- date1.getUTCDate() === date2.getUTCDate());
690
- }
691
- else {
692
- return (date1.getFullYear() === date2.getFullYear() &&
693
- date1.getMonth() === date2.getMonth() &&
694
- date1.getDate() === date2.getDate());
695
- }
696
- }
697
- /**
698
- * Checks if a date is identical or after another date
699
- * @param {Date} date - Date to check
700
- * @param {Date} compareDate - Reference date
701
- * @returns {boolean} true if `date` >= `compareDate`
702
- */
703
- isSameOrAfter(date, compareDate) {
704
- if (this.isUTCMode) {
705
- return (date.getUTCFullYear() > compareDate.getUTCFullYear() ||
706
- (date.getUTCFullYear() === compareDate.getUTCFullYear() &&
707
- date.getUTCMonth() > compareDate.getUTCMonth()) ||
708
- (date.getUTCFullYear() === compareDate.getUTCFullYear() &&
709
- date.getUTCMonth() === compareDate.getUTCMonth() &&
710
- date.getUTCDate() >= compareDate.getUTCDate()));
711
- }
712
- else {
713
- return (date.getFullYear() > compareDate.getFullYear() ||
714
- (date.getFullYear() === compareDate.getFullYear() &&
715
- date.getMonth() > compareDate.getMonth()) ||
716
- (date.getFullYear() === compareDate.getFullYear() &&
717
- date.getMonth() === compareDate.getMonth() &&
718
- date.getDate() >= compareDate.getDate()));
719
- }
720
- }
721
- /**
722
- * Checks if a date is identical or before another date
723
- * @param {Date} date - Date to check
724
- * @param {Date} compareDate - Reference date
725
- * @returns {boolean} true if `date` <= `compareDate`
726
- */
727
- isSameOrBefore(date, compareDate) {
728
- if (this.isUTCMode) {
729
- return (date.getUTCFullYear() < compareDate.getUTCFullYear() ||
730
- (date.getUTCFullYear() === compareDate.getUTCFullYear() &&
731
- date.getUTCMonth() < compareDate.getUTCMonth()) ||
732
- (date.getUTCFullYear() === compareDate.getUTCFullYear() &&
733
- date.getUTCMonth() === compareDate.getUTCMonth() &&
734
- date.getUTCDate() <= compareDate.getUTCDate()));
735
- }
736
- else {
737
- return (date.getFullYear() < compareDate.getFullYear() ||
738
- (date.getFullYear() === compareDate.getFullYear() &&
739
- date.getMonth() < compareDate.getMonth()) ||
740
- (date.getFullYear() === compareDate.getFullYear() &&
741
- date.getMonth() === compareDate.getMonth() &&
742
- date.getDate() <= compareDate.getDate()));
743
- }
744
- }
745
- /**
746
- * Applies a shortcut selection
747
- * @param {Object} shortcut - Shortcut to apply
748
- * @param {string | Date} shortcut.singleValue - Selected date value
749
- * @param {Object} shortcut.rangeValue - Start and end date values
750
- * @param {string | Date} shortcut.rangeValue.start - Start date value
751
- * @param {string | Date} shortcut.rangeValue.end - End date value
752
- * @param {string} shortcut.label - Label
753
- */
754
- applyShortcut(shortcut) {
755
- this.selectedDate = null;
756
- this.startDate = null;
757
- this.endDate = null;
758
- if (shortcut.singleValue) {
759
- const newDate = this.parseDate(shortcut.singleValue);
760
- this.selectedDate = newDate;
761
- this.singleDateChange.emit(this.formatDate(newDate));
762
- this.singleValue = this.formatDate(newDate);
763
- if (!this.showActions) {
764
- const event = new CustomEvent('closePopover', {
765
- bubbles: true,
766
- composed: true,
767
- });
768
- this.el.dispatchEvent(event);
721
+ console.error('Invalid rangeValue:', error);
769
722
  }
770
- this.forceCalendarUpdate(newDate);
771
723
  }
772
724
  else {
773
- const start = this.parseDate(shortcut.rangeValue.start);
774
- const end = this.parseDate(shortcut.rangeValue.end);
775
- this.startDate = start;
776
- this.endDate = end;
777
- this.rangeDateChange.emit({
778
- start: this.formatDate(start),
779
- end: this.formatDate(end),
780
- });
781
- this.rangeValue = JSON.stringify({
782
- start: this.formatDate(start),
783
- end: this.formatDate(end),
784
- });
785
- if (!this.showActions) {
786
- const event = new CustomEvent('closePopover', {
787
- bubbles: true,
788
- composed: true,
789
- });
790
- this.el.dispatchEvent(event);
791
- }
792
- this.forceCalendarUpdate(end);
793
- }
794
- }
795
- /**
796
- * Method to force the complete calendar update (and fix the persistent hover problem)
797
- * @param {Date} newDate - Date to force
798
- */
799
- forceCalendarUpdate(newDate) {
800
- this.currentDate = new Date(newDate);
801
- this.currentDate = new Date(this.currentDate); // Force a re-render
802
- // Reset visually the hover/touch effect
803
- requestAnimationFrame(() => {
804
- const days = document.querySelectorAll('.day');
805
- days.forEach(el => {
806
- el.classList.remove('hover', 'active', 'touched');
807
- el.style.pointerEvents = 'none';
808
- });
809
- // Add specific touch handling (for mobile)
810
- document.body.addEventListener('touchstart', this.clearTouchState, {
811
- passive: true,
812
- });
813
- // Reset the touch state after 50ms
814
- setTimeout(() => {
815
- days.forEach(el => {
816
- el.style.pointerEvents = '';
817
- });
818
- }, 50);
819
- });
820
- }
821
- /**
822
- * Function to reset the touch effect (Mobile fix)
823
- */
824
- clearTouchState() {
825
- document.querySelectorAll('.day').forEach(el => {
826
- el.classList.remove('touched');
827
- });
828
- // Remove the listener after the first interaction
829
- document.body.removeEventListener('touchstart', this.clearTouchState);
830
- }
831
- /**
832
- * Handles month change with an offset
833
- * @param {number} direction - Direction (-1 for previous, 1 for next)
834
- * @returns {Function} Change month handler
835
- */
836
- getChangeMonthHandler(direction) {
837
- return () => this.changeMonth(direction);
838
- }
839
- /**
840
- * Handles month change from an event (ex: dropdown)
841
- * @param {number} offset - Month offset (0 by default)
842
- * @returns {Function} Change month handler
843
- */
844
- getHandleMonthChange(offset) {
845
- return (event) => this.handleMonthChange(event, offset);
846
- }
847
- /**
848
- * Handles year change from an event (ex: dropdown)
849
- * @param {number} offset - Year offset (0 by default)
850
- * @returns {Function} Change year handler
851
- */
852
- getHandleYearChange(offset) {
853
- return (event) => this.handleYearChange(event, offset);
854
- }
855
- /**
856
- * Handles day click
857
- * @param {Date} date - Date to handle
858
- * @param {boolean} isDisabled - Whether the date is disabled
859
- * @returns {Function} Day click handler
860
- */
861
- getDayClickHandler(date, isDisabled) {
862
- return isDisabled ? undefined : () => this.handleDateSelection(date);
863
- }
864
- /**
865
- * Handles shortcut selection
866
- * @param {Object} shortcut - Shortcut to handle
867
- * @param {string | Date} shortcut.singleValue - Selected date value
868
- * @param {Object} shortcut.rangeValue - Start and end date values
869
- * @param {string | Date} shortcut.rangeValue.start - Start date value
870
- * @param {string | Date} shortcut.rangeValue.end - End date value
871
- * @param {string} shortcut.label - Label
872
- * @returns {Function} Shortcut selection handler
873
- */
874
- getShortcutHandler(shortcut) {
875
- return () => this.applyShortcut(shortcut);
876
- }
877
- /**
878
- * Handles week selection
879
- * @param {Date[]} dates - Dates to handle
880
- * @param {number} index - Calendar index
881
- * @returns {Function} Week selection handler
882
- */
883
- getWeekSelectionHandler(dates, index) {
884
- return () => {
885
- if (this.selectionType === 'range') {
886
- this.handleWeekSelection(dates, index);
887
- }
888
- };
889
- }
890
- parsedShortcuts() {
891
- try {
892
- return this.shortcuts ? JSON.parse(this.shortcuts) : [];
893
- }
894
- catch (error) {
895
- console.error('Invalid JSON for shortcuts:', error);
896
- return [];
725
+ this.currentDate = new Date();
897
726
  }
727
+ this.initializeMonths();
898
728
  }
729
+ //#endregion LIFECYCLE
730
+ /****************************************************************************/
731
+ //#region METHODS
899
732
  /**
900
733
  * Checks if shortcuts are visible
901
734
  * @returns {boolean} true if shortcuts are visible
902
735
  */
903
736
  get hasShortcuts() {
904
- return (this.shortcutsPlacement === 'bottom' && this.parsedShortcuts().length > 0);
737
+ return Boolean(this.shortcutsPlacement && this.shortcuts);
905
738
  }
906
739
  /**
907
740
  * Checks if actions are visible
@@ -910,103 +743,46 @@ export class NvCalendar {
910
743
  get hasActions() {
911
744
  return this.showActions;
912
745
  }
913
- //#endregion METHODS
914
- /****************************************************************************/
915
- //#region RENDER
916
- /**
917
- * Renders the header
918
- * @param {number} offset - Month offset
919
- * @param {number} index - Calendar index
920
- * @returns {JSX.Element} Header
921
- * @description Renders the header of the calendar
922
- */
923
- renderHeader(offset, index) {
924
- return (h("div", { class: "header" }, this.numberOfCalendars > 1 && index === 0 && (h("nv-iconbutton", { class: "nav-left", emphasis: "lower", name: "chevron-left", onClick: this.getChangeMonthHandler(-1) })), h("div", { class: "date-controls" }, h("select", { class: "month-select mr-4", onChange: this.getHandleMonthChange(offset) }, this.months.map(month => (h("option", { key: month.value, value: month.value, selected: month.value === (this.currentDate.getUTCMonth() + offset) % 12 }, month.label)))), h("input", { type: "number", class: "year-input", min: "1950", max: "2100", value: this.currentDate.getUTCFullYear() +
925
- Math.floor((this.currentDate.getUTCMonth() + offset) / 12), onChange: this.getHandleYearChange(offset) })), this.numberOfCalendars === 1 && (h("div", { class: "nav-buttons" }, h("nv-iconbutton", { emphasis: "lower", name: "chevron-left", onClick: this.getChangeMonthHandler(-1) }), h("nv-iconbutton", { emphasis: "lower", name: "chevron-right", onClick: this.getChangeMonthHandler(1) }))), this.numberOfCalendars > 1 && index === this.numberOfCalendars - 1 && (h("nv-iconbutton", { emphasis: "lower", name: "chevron-right", onClick: this.getChangeMonthHandler(1), class: "nav-right" }))));
926
- }
927
746
  /**
928
- * Renders the week numbers
929
- * @param {Array<{date: Date}>} weeks - Weeks to render
930
- * @param {number} index - Calendar index
931
- * @returns {JSX.Element} Week numbers
932
- * @description Renders the week numbers of the calendar
747
+ * Checks if the date format is in UTC mode
748
+ * @returns {boolean} true if the date format is in UTC mode
933
749
  */
934
- renderWeekNumbers(
935
- /** Weeks to render */
936
- weeks,
937
- /** Calendar index */
938
- index) {
939
- return (h("div", { class: "week-numbers" }, h("div", { class: "week-header" }, this.getLocalizedWeekText()), weeks.map((week, weekIndex) => {
940
- var _a;
941
- const dates = week.map(d => d.date);
942
- return (h("div", { class: `week-number ${this.selectionType === 'range' ? 'clickable' : ''}`, onClick: this.getWeekSelectionHandler(dates, index), key: `week-${weekIndex}` }, this.getWeekNumber(((_a = week.find(d => d.date)) === null || _a === void 0 ? void 0 : _a.date) || new Date())));
943
- })));
944
- }
945
- renderDaysGrid(
946
- /** Days to render */
947
- days) {
948
- return (h("div", { class: "days-grid" }, days.map(day => {
949
- const date = day.date;
950
- if (!date)
951
- return null;
952
- const isSelected = this.selectionType === 'single' &&
953
- this.isSameDate(date, this.selectedDate);
954
- const isInRange = this.isDateInRange(date);
955
- const isStart = this.isSameDate(date, this.startDate);
956
- const isEnd = this.isSameDate(date, this.endDate);
957
- const isToday = this.isToday(date);
958
- const isOutsideMonth = !day.isCurrentMonth;
959
- const dayClasses = [
960
- 'day',
961
- isSelected ? 'selected' : '',
962
- isStart ? 'range-start' : '',
963
- isEnd ? 'range-end' : '',
964
- isInRange ? 'in-range' : '',
965
- day.isDisabled ? 'disabled' : '',
966
- isOutsideMonth ? 'outside-month' : '',
967
- isToday ? 'is-today' : '',
968
- ];
969
- return (h("div", { class: dayClasses.filter(Boolean).join(' '), onClick: this.getDayClickHandler(date, day.isDisabled), "aria-disabled": day.isDisabled, key: `day-${date.toISOString()}` }, day.dayOfMonth));
970
- })));
750
+ get isUTCMode() {
751
+ return this.dateFormat.includes('Z');
971
752
  }
972
753
  /**
973
- * Renders the calendar
974
- * @param {number} index - Calendar index
975
- * @param {number} offset - Month offset
976
- * @returns {JSX.Element} Calendar
977
- * @description Renders the calendar of the calendar
754
+ * Validates and processes a date range, warning if start is after end
755
+ * @param {string} startDateStr - Start date in ISO string format
756
+ * @param {string} endDateStr - End date in ISO string format
757
+ * @returns {object} Object containing the validated start and end dates
978
758
  */
979
- renderCalendar(
980
- /** Calendar index */
981
- index,
982
- /** Month offset */
983
- offset) {
984
- const days = this.getDaysInMonth(offset, this.numberOfCalendars);
985
- const weeks = [];
986
- for (let i = 0; i < days.length; i += 7) {
987
- weeks.push(days.slice(i, i + 7));
759
+ validateDateRange(startDateStr, endDateStr) {
760
+ try {
761
+ const startDate = parseDate(startDateStr, this.dateFormat);
762
+ const endDate = parseDate(endDateStr, this.dateFormat);
763
+ if (startDate && endDate && startDate > endDate) {
764
+ console.warn(`Warning: startDate (${formatDate(startDate, {
765
+ dateFormat: this.dateFormat,
766
+ })}) is after endDate (${formatDate(endDate, {
767
+ dateFormat: this.dateFormat,
768
+ })})`);
769
+ // Return dates in correct order, with swapped flag
770
+ return {
771
+ startDate: endDate,
772
+ endDate: startDate,
773
+ swapped: true,
774
+ };
775
+ }
776
+ return {
777
+ startDate,
778
+ endDate,
779
+ swapped: false,
780
+ };
988
781
  }
989
- return (h("div", { class: "calendar-wrapper" }, h("div", { class: "calendar-container", key: `calendar-${index}` }, this.renderHeader(offset, index), h("div", { class: "calendar-grid" }, this.showWeekNumbers && this.renderWeekNumbers(weeks, index), h("div", { class: "days-container" }, h("div", { class: "days-header" }, this.getDayNames().map(day => (h("div", { class: "day-header" }, day)))), this.renderDaysGrid(days)))), index < this.numberOfCalendars - 1 && (h("div", { class: "calendar-separator" }))));
990
- }
991
- /**
992
- * Renders the shortcuts
993
- * @returns {JSX.Element} Shortcuts
994
- * @description Renders the shortcuts of the calendar
995
- */
996
- renderShortcuts() {
997
- if (!this.parsedShortcuts().length) {
998
- return null;
782
+ catch (error) {
783
+ console.error('Invalid date range:', error);
784
+ throw error; // Re-throw to let the caller handle it
999
785
  }
1000
- return (h("div", { class: `shortcuts-container shortcuts-placement-${this.shortcutsPlacement}` }, this.parsedShortcuts().map(shortcut => (h("nv-button", { emphasis: "lower", size: "xs", "aria-label": shortcut.label, onClick: this.getShortcutHandler(shortcut) }, shortcut.label)))));
1001
- }
1002
- /**
1003
- * Renders the actions
1004
- * @returns {JSX.Element} Actions
1005
- * @description Renders the actions of the calendar
1006
- * @slot actions - Child content of the component.
1007
- */
1008
- renderActions() {
1009
- return (h("div", { class: "datepicker-actions" }, h("slot", { name: "actions" }, h("nv-button", { emphasis: "low", size: "xs", onClick: this.resetSelection }, "Cancel"), h("nv-button", { size: "xs", onClick: this.confirmSelection }, "OK"))));
1010
786
  }
1011
787
  /**
1012
788
  * Renders the datepicker
@@ -1015,7 +791,8 @@ export class NvCalendar {
1015
791
  * @slot default - Child content of the component.
1016
792
  */
1017
793
  render() {
1018
- return (h(Host, { key: '89300da9f694aa926855452414e7e036f75f2de6' }, h("div", { key: '467ef9fc9d6523eec3712bf779d49fdf50c55617', class: "datepicker-root" }, h("div", { key: '990f2cb18dcad96cab0f8dfb62e6c57049475440', class: `datepicker-container ${this.numberOfCalendars === 1 ? 'datepicker-container-single' : ''}` }, h("div", { key: 'c0dedf1007cbc6a87bd591925c9994474c876afc', class: `datepicker-wrapper ${this.numberOfCalendars === 1 ? 'single' : ''}` }, this.shortcutsPlacement === 'left' && this.renderShortcuts(), Array.from({ length: this.numberOfCalendars }, (_, index) => this.renderCalendar(index, index)), this.shortcutsPlacement === 'right' && this.renderShortcuts()), (this.hasShortcuts || this.hasActions) && (h("div", { key: 'ef81eaf952fbe569be7e1d3ee6cb59de0e137fe4', class: "datepicker-controls" }, this.hasShortcuts && this.renderShortcuts(), this.hasActions && this.renderActions())))), h("slot", { key: 'e1281217950b5cb02952a69b081d4fcce5863b4d' })));
794
+ return (h(Host, { key: '9804c486acf32e12f2d88f932a54ca6260365887' }, h("div", { key: '8503f585401191b904f2de248ed0c24b1fed1505', class: "datepicker-root" }, h("div", { key: '9da71618bd2031b44f5a3fd889d40b2580fcca58', class: `datepicker-container ${this.numberOfCalendars === 1 ? 'datepicker-container-single' : ''}` }, h("div", { key: 'fbf71a34b520ca48f1440d8caeec442773b1e57a', 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') ||
795
+ this.hasActions) && (h("div", { key: '4431e3f1221e9d47807d58af380dcaa91bf05c48', class: "datepicker-controls" }, this.shortcutsPlacement === 'bottom' && this.renderShortcuts(), this.hasActions && this.renderActions())))), h("slot", { key: '30386356bda72f4f12a28351084ab498ec95f5b9' })));
1019
796
  }
1020
797
  static get is() { return "nv-calendar"; }
1021
798
  static get originalStyleUrls() {
@@ -1093,15 +870,14 @@ export class NvCalendar {
1093
870
  "getter": false,
1094
871
  "setter": false,
1095
872
  "attribute": "single-value",
1096
- "reflect": true,
1097
- "defaultValue": "''"
873
+ "reflect": true
1098
874
  },
1099
875
  "rangeValue": {
1100
- "type": "string",
876
+ "type": "unknown",
1101
877
  "mutable": true,
1102
878
  "complexType": {
1103
- "original": "string",
1104
- "resolved": "string",
879
+ "original": "{\n /** ISO string for start date */\n start: string;\n /** ISO string for end date */\n end: string;\n }",
880
+ "resolved": "{ start: string; end: string; }",
1105
881
  "references": {}
1106
882
  },
1107
883
  "required": false,
@@ -1111,10 +887,7 @@ export class NvCalendar {
1111
887
  "text": "Selected date range\nformat: { start: ISO string, end: ISO string }\nex: { start: \"2025-03-15\", end: \"2025-03-20\" }"
1112
888
  },
1113
889
  "getter": false,
1114
- "setter": false,
1115
- "attribute": "range-value",
1116
- "reflect": true,
1117
- "defaultValue": "''"
890
+ "setter": false
1118
891
  },
1119
892
  "min": {
1120
893
  "type": "string",
@@ -1133,8 +906,7 @@ export class NvCalendar {
1133
906
  "getter": false,
1134
907
  "setter": false,
1135
908
  "attribute": "min",
1136
- "reflect": true,
1137
- "defaultValue": "''"
909
+ "reflect": true
1138
910
  },
1139
911
  "max": {
1140
912
  "type": "string",
@@ -1153,31 +925,29 @@ export class NvCalendar {
1153
925
  "getter": false,
1154
926
  "setter": false,
1155
927
  "attribute": "max",
1156
- "reflect": true,
1157
- "defaultValue": "''"
928
+ "reflect": true
1158
929
  },
1159
930
  "disabledDates": {
1160
- "type": "string",
931
+ "type": "unknown",
1161
932
  "mutable": false,
1162
933
  "complexType": {
1163
- "original": "string",
1164
- "resolved": "string",
1165
- "references": {}
934
+ "original": "Array<string>",
935
+ "resolved": "string[]",
936
+ "references": {
937
+ "Array": {
938
+ "location": "global",
939
+ "id": "global::Array"
940
+ }
941
+ }
1166
942
  },
1167
943
  "required": false,
1168
944
  "optional": false,
1169
945
  "docs": {
1170
- "tags": [{
1171
- "name": "default",
1172
- "text": "'[]'"
1173
- }],
946
+ "tags": [],
1174
947
  "text": "Disabled dates (ISO string array)"
1175
948
  },
1176
949
  "getter": false,
1177
- "setter": false,
1178
- "attribute": "disabled-dates",
1179
- "reflect": true,
1180
- "defaultValue": "''"
950
+ "setter": false
1181
951
  },
1182
952
  "locale": {
1183
953
  "type": "string",
@@ -1288,10 +1058,7 @@ export class NvCalendar {
1288
1058
  "required": false,
1289
1059
  "optional": false,
1290
1060
  "docs": {
1291
- "tags": [{
1292
- "name": "default",
1293
- "text": "false"
1294
- }],
1061
+ "tags": [],
1295
1062
  "text": "Show action buttons"
1296
1063
  },
1297
1064
  "getter": false,
@@ -1301,27 +1068,26 @@ export class NvCalendar {
1301
1068
  "defaultValue": "false"
1302
1069
  },
1303
1070
  "shortcuts": {
1304
- "type": "string",
1071
+ "type": "unknown",
1305
1072
  "mutable": false,
1306
1073
  "complexType": {
1307
- "original": "string",
1308
- "resolved": "string",
1309
- "references": {}
1074
+ "original": "{\n /** Label of the shortcut */\n label: string;\n /** Selected date value for single selection mode */\n singleValue?: string;\n /** Date range values for range selection mode */\n rangeValue?: HTMLNvCalendarElement['rangeValue'];\n }[]",
1075
+ "resolved": "{ label: string; singleValue?: string; rangeValue?: { start: string; end: string; }; }[]",
1076
+ "references": {
1077
+ "HTMLNvCalendarElement": {
1078
+ "location": "global",
1079
+ "id": "global::HTMLNvCalendarElement"
1080
+ }
1081
+ }
1310
1082
  },
1311
1083
  "required": false,
1312
1084
  "optional": false,
1313
1085
  "docs": {
1314
- "tags": [{
1315
- "name": "default",
1316
- "text": "'[]'"
1317
- }],
1318
- "text": "Custom actions to display in the footer\nJSON array of objects with the following properties:\n- label: string\n- onClick: function"
1086
+ "tags": [],
1087
+ "text": "Custom actions to display in the footer"
1319
1088
  },
1320
1089
  "getter": false,
1321
- "setter": false,
1322
- "attribute": "shortcuts",
1323
- "reflect": true,
1324
- "defaultValue": "'[]'"
1090
+ "setter": false
1325
1091
  },
1326
1092
  "showWeekNumbers": {
1327
1093
  "type": "boolean",
@@ -1334,10 +1100,7 @@ export class NvCalendar {
1334
1100
  "required": false,
1335
1101
  "optional": false,
1336
1102
  "docs": {
1337
- "tags": [{
1338
- "name": "default",
1339
- "text": "true"
1340
- }],
1103
+ "tags": [],
1341
1104
  "text": "Show week numbers"
1342
1105
  },
1343
1106
  "getter": false,
@@ -1383,13 +1146,12 @@ export class NvCalendar {
1383
1146
  "text": "Emitted when a date range is selected"
1384
1147
  },
1385
1148
  "complexType": {
1386
- "original": "DateRange",
1387
- "resolved": "DateRange",
1149
+ "original": "HTMLNvCalendarElement['rangeValue']",
1150
+ "resolved": "{ start: string; end: string; }",
1388
1151
  "references": {
1389
- "DateRange": {
1390
- "location": "import",
1391
- "path": "../../interfaces/dateRange",
1392
- "id": "src/interfaces/dateRange.tsx::DateRange"
1152
+ "HTMLNvCalendarElement": {
1153
+ "location": "global",
1154
+ "id": "global::HTMLNvCalendarElement"
1393
1155
  }
1394
1156
  }
1395
1157
  }