uikit-react-public 0.11.20 → 0.14.21

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 (295) hide show
  1. package/dist/components/Badge/Badge.d.ts +6 -0
  2. package/dist/components/Badge/Badge.stories.d.ts +15 -0
  3. package/dist/components/Badge/index.d.ts +2 -0
  4. package/dist/components/Button/Button.d.ts +2 -1
  5. package/dist/components/Calendar/Calendar.d.ts +3 -0
  6. package/dist/components/Calendar/Calendar.stories.d.ts +42 -0
  7. package/dist/components/Calendar/Calendar.types.d.ts +18 -0
  8. package/dist/components/Calendar/index.d.ts +2 -0
  9. package/dist/components/Calendar/subcomponents/AcademicWeeks.d.ts +7 -0
  10. package/dist/components/Calendar/subcomponents/ColumnHeading.d.ts +7 -0
  11. package/dist/components/Calendar/subcomponents/Controls.d.ts +6 -0
  12. package/dist/components/{Datepicker/subcomponents/Day → Calendar/subcomponents}/Day.d.ts +3 -3
  13. package/dist/components/{Datepicker → Calendar}/subcomponents/EventDot.d.ts +2 -2
  14. package/dist/components/Calendar/subcomponents/Grid.d.ts +11 -0
  15. package/dist/components/Calendar/subcomponents/index.d.ts +7 -0
  16. package/dist/components/{Datepicker → Calendar}/utils/getAcademicWeekNumbers/getAcademicWeekNumbers.d.ts +1 -1
  17. package/dist/components/Calendar/utils/index.d.ts +4 -0
  18. package/dist/components/Calendar/utils/normaliseMonth/normaliseMonth.d.ts +9 -0
  19. package/dist/components/Calendar/utils/parseDateFromString/parseDateFromString.d.ts +9 -0
  20. package/dist/components/Calendar/utils/parseDateFromString/parseDateFromString.test.d.ts +1 -0
  21. package/dist/components/CookieNotice/CookieNotice.d.ts +16 -0
  22. package/dist/components/CookieNotice/index.d.ts +2 -0
  23. package/dist/components/Datepicker/Datepicker.d.ts +3 -16
  24. package/dist/components/Datepicker/Datepicker.stories.d.ts +9 -3
  25. package/dist/components/Datepicker/Datepicker.types.d.ts +23 -7
  26. package/dist/components/Datepicker/index.d.ts +1 -2
  27. package/dist/components/Datepicker/subcomponents/CustomDatepicker.d.ts +17 -0
  28. package/dist/components/Datepicker/subcomponents/DatepickerInput.d.ts +10 -0
  29. package/dist/components/Datepicker/subcomponents/NativeDatepicker.d.ts +6 -0
  30. package/dist/components/Datepicker/subcomponents/Panel.d.ts +6 -0
  31. package/dist/components/Datepicker/subcomponents/VisibleField.d.ts +12 -0
  32. package/dist/components/Datepicker/subcomponents/index.d.ts +5 -7
  33. package/dist/components/Datepicker/utils/dateToLocaleISOString/dateToLocaleISOString.d.ts +17 -0
  34. package/dist/components/Datepicker/utils/dateToLocaleISOString/dateToLocaleISOString.test.d.ts +1 -0
  35. package/dist/components/Datepicker/utils/index.d.ts +2 -3
  36. package/dist/components/Datepicker/utils/parseInputValue/parseInputValue.d.ts +11 -0
  37. package/dist/components/Datepicker/utils/parseInputValue/parseInputValue.test.d.ts +1 -0
  38. package/dist/components/Dialog/BaseDialog.d.ts +7 -2
  39. package/dist/components/FileInput/FileInput.d.ts +8 -0
  40. package/dist/components/FileInput/FileInput.stories.d.ts +16 -0
  41. package/dist/components/FileInput/__tests__/FileInput.test.d.ts +1 -0
  42. package/dist/components/FileInput/index.d.ts +2 -0
  43. package/dist/components/Footer/Footer.d.ts +1 -1
  44. package/dist/components/Header/Header.d.ts +4 -1
  45. package/dist/components/Heading/Heading.d.ts +1 -1
  46. package/dist/components/Link/BaseLink.d.ts +10 -0
  47. package/dist/components/Link/Link.d.ts +5 -10
  48. package/dist/components/Link/Link.stories.d.ts +1 -1
  49. package/dist/components/Link/index.d.ts +1 -1
  50. package/dist/components/Menu/Menu.d.ts +2 -1
  51. package/dist/components/Menu/MenuContent.d.ts +2 -1
  52. package/dist/components/Menu/MenuItem.d.ts +2 -0
  53. package/dist/components/Menu/MenuSection.d.ts +1 -1
  54. package/dist/components/Search/Search.d.ts +16 -0
  55. package/dist/components/Search/Search.stories.d.ts +34 -0
  56. package/dist/components/Search/__tests__/Search.test.d.ts +1 -0
  57. package/dist/components/Search/index.d.ts +2 -0
  58. package/dist/components/Select/Select.d.ts +1 -1
  59. package/dist/components/Select/Select.stories.d.ts +3 -7
  60. package/dist/components/Select/Select.types.d.ts +19 -14
  61. package/dist/components/Select/subcomponents/CustomOption.d.ts +1 -1
  62. package/dist/components/Select/subcomponents/CustomSelect.d.ts +1 -2
  63. package/dist/components/Select/subcomponents/Panel.d.ts +1 -1
  64. package/dist/components/Select/subcomponents/VisibleField.d.ts +4 -4
  65. package/dist/components/StandaloneLink/StandaloneLink.d.ts +12 -0
  66. package/dist/components/StandaloneLink/StandaloneLink.stories.d.ts +13 -0
  67. package/dist/components/StandaloneLink/__tests__/StandaloneLink.test.d.ts +1 -0
  68. package/dist/components/StandaloneLink/index.d.ts +2 -0
  69. package/dist/components/Table/Table.d.ts +10 -8
  70. package/dist/components/Table/Table.stories.d.ts +21 -0
  71. package/dist/components/Table/Table.types.d.ts +11 -0
  72. package/dist/components/Table/__tests__/Table.test.d.ts +1 -0
  73. package/dist/components/Table/index.d.ts +2 -1
  74. package/dist/components/Table/subcomponents/Body.d.ts +4 -0
  75. package/dist/components/Table/subcomponents/Cell/Cell.d.ts +12 -0
  76. package/dist/components/Table/subcomponents/Cell/Cell.stories.d.ts +313 -0
  77. package/dist/components/Table/subcomponents/Cell/CellContent.d.ts +10 -0
  78. package/dist/components/Table/subcomponents/Cell/__tests__/Cell.test.d.ts +1 -0
  79. package/dist/components/Table/subcomponents/Head.d.ts +4 -0
  80. package/dist/components/Table/subcomponents/HeadCell/HeadCell.d.ts +13 -0
  81. package/dist/components/Table/subcomponents/HeadCell/HeadCell.stories.d.ts +312 -0
  82. package/dist/components/Table/subcomponents/HeadCell/HeadCellContent.d.ts +10 -0
  83. package/dist/components/Table/subcomponents/HeadCell/__tests__/HeadCell.test.d.ts +1 -0
  84. package/dist/components/Table/subcomponents/Row.d.ts +5 -0
  85. package/dist/components/Table/subcomponents/SortIcon.d.ts +7 -0
  86. package/dist/components/Table/subcomponents/index.d.ts +10 -0
  87. package/dist/components/Tabs/Tab.d.ts +1 -1
  88. package/dist/components/Tabs/TabContext.d.ts +1 -0
  89. package/dist/components/Tabs/Tabs.d.ts +3 -1
  90. package/dist/components/Tabs/Tabs.stories.d.ts +3 -0
  91. package/dist/components/Timepicker/Timepicker.d.ts +10 -0
  92. package/dist/components/Timepicker/Timepicker.stories.d.ts +7 -0
  93. package/dist/components/Timepicker/__tests__/Timepicker.test.d.ts +1 -0
  94. package/dist/components/Timepicker/index.d.ts +2 -0
  95. package/dist/components/Timepicker/utils/convertDateToTimeString.d.ts +2 -0
  96. package/dist/components/Timepicker/utils/convertDateToTimeString.test.d.ts +1 -0
  97. package/dist/components/Timepicker/utils/index.d.ts +1 -0
  98. package/dist/components/WeekPicker/WeekPicker.d.ts +3 -0
  99. package/dist/components/WeekPicker/index.d.ts +1 -0
  100. package/dist/components/WeekPicker/subcomponents/CustomDatepicker.d.ts +17 -0
  101. package/dist/components/WeekPicker/subcomponents/DatepickerInput.d.ts +13 -0
  102. package/dist/components/WeekPicker/subcomponents/VisibleField.d.ts +15 -0
  103. package/dist/components/WeekPicker/subcomponents/index.d.ts +3 -0
  104. package/dist/components/index.d.ts +13 -0
  105. package/dist/hooks/index.d.ts +2 -0
  106. package/dist/hooks/useFocusTrap.d.ts +9 -0
  107. package/dist/index.d.ts +1 -0
  108. package/dist/index.js +6006 -4599
  109. package/dist/theme/defaultTheme.d.ts +7 -0
  110. package/dist/theme/useTheme.d.ts +14 -0
  111. package/dist/utils/__tests__/capitalise.test.d.ts +1 -0
  112. package/dist/utils/capitalise.d.ts +2 -0
  113. package/lib/components/Alert/Alert.tsx +7 -1
  114. package/lib/components/Alert/__tests__/__snapshots__/Alert.test.tsx.snap +4 -0
  115. package/lib/components/Badge/Badge.stories.tsx +19 -0
  116. package/lib/components/Badge/Badge.tsx +48 -0
  117. package/lib/components/Badge/index.ts +2 -0
  118. package/lib/components/Breadcrumbs/__tests__/__snapshots__/Breadcrumbs.test.tsx.snap +4 -4
  119. package/lib/components/Button/Button.tsx +5 -2
  120. package/lib/components/Calendar/Calendar.stories.tsx +209 -0
  121. package/lib/components/Calendar/Calendar.tsx +121 -0
  122. package/lib/components/Calendar/Calendar.types.ts +21 -0
  123. package/lib/components/Calendar/__tests__/Calendar.test.tsx +71 -0
  124. package/lib/components/Calendar/__tests__/__snapshots__/Calendar.test.tsx.snap +1218 -0
  125. package/lib/components/Calendar/index.ts +6 -0
  126. package/lib/components/{Datepicker → Calendar}/subcomponents/AcademicWeek.tsx +1 -1
  127. package/lib/components/{Datepicker → Calendar}/subcomponents/AcademicWeeks.tsx +9 -7
  128. package/lib/components/Calendar/subcomponents/ColumnHeading.tsx +40 -0
  129. package/lib/components/{Datepicker/subcomponents/MonthSelector/MonthSelector.tsx → Calendar/subcomponents/Controls.tsx} +17 -17
  130. package/lib/components/{Datepicker/subcomponents/Day → Calendar/subcomponents}/Day.stories.tsx +8 -8
  131. package/lib/components/{Datepicker/subcomponents/Day → Calendar/subcomponents}/Day.tsx +28 -16
  132. package/lib/components/{Datepicker → Calendar}/subcomponents/EventDot.tsx +3 -3
  133. package/lib/components/Calendar/subcomponents/Grid.tsx +116 -0
  134. package/lib/components/Calendar/subcomponents/index.ts +7 -0
  135. package/lib/components/{Datepicker → Calendar}/utils/getAcademicWeekNumbers/getAcademicWeekNumbers.test.ts +1 -1
  136. package/lib/components/{Datepicker → Calendar}/utils/getAcademicWeekNumbers/getAcademicWeekNumbers.ts +1 -1
  137. package/lib/components/{Datepicker → Calendar}/utils/getDatesForCalendarGrid/getDatesForCalendarGrid.test.ts +29 -65
  138. package/lib/components/{Datepicker → Calendar}/utils/getDatesForCalendarGrid/getDatesForCalendarGrid.ts +11 -43
  139. package/lib/components/Calendar/utils/index.ts +4 -0
  140. package/lib/components/Calendar/utils/normaliseMonth/normaliseMonth.test.ts +40 -0
  141. package/lib/components/Calendar/utils/normaliseMonth/normaliseMonth.ts +16 -0
  142. package/lib/components/Calendar/utils/parseDateFromString/parseDateFromString.test.ts +15 -0
  143. package/lib/components/Calendar/utils/parseDateFromString/parseDateFromString.ts +19 -0
  144. package/lib/components/CookieNotice/CookieNotice.tsx +114 -0
  145. package/lib/components/CookieNotice/index.ts +2 -0
  146. package/lib/components/Datepicker/Datepicker.stories.tsx +128 -64
  147. package/lib/components/Datepicker/Datepicker.tsx +34 -114
  148. package/lib/components/Datepicker/Datepicker.types.ts +38 -9
  149. package/lib/components/Datepicker/__tests__/Datepicker.test.tsx +53 -112
  150. package/lib/components/Datepicker/__tests__/__snapshots__/Datepicker.test.tsx.snap +92 -747
  151. package/lib/components/Datepicker/index.ts +1 -2
  152. package/lib/components/Datepicker/subcomponents/CustomDatepicker.tsx +209 -0
  153. package/lib/components/Datepicker/subcomponents/DatepickerInput.tsx +74 -0
  154. package/lib/components/Datepicker/subcomponents/NativeDatepicker.tsx +70 -0
  155. package/lib/components/Datepicker/subcomponents/Panel.tsx +32 -0
  156. package/lib/components/Datepicker/subcomponents/VisibleField.tsx +104 -0
  157. package/lib/components/Datepicker/subcomponents/index.ts +5 -7
  158. package/lib/components/Datepicker/utils/dateToLocaleISOString/dateToLocaleISOString.test.ts +32 -0
  159. package/lib/components/Datepicker/utils/dateToLocaleISOString/dateToLocaleISOString.ts +23 -0
  160. package/lib/components/Datepicker/utils/index.ts +2 -3
  161. package/lib/components/Datepicker/utils/parseInputValue/parseInputValue.test.ts +110 -0
  162. package/lib/components/Datepicker/utils/parseInputValue/parseInputValue.ts +57 -0
  163. package/lib/components/Dialog/BaseDialog.tsx +44 -4
  164. package/lib/components/Field/__tests__/Field.test.tsx +148 -148
  165. package/lib/components/FileInput/FileInput.stories.tsx +70 -0
  166. package/lib/components/FileInput/FileInput.tsx +68 -0
  167. package/lib/components/FileInput/__tests__/FileInput.test.tsx +99 -0
  168. package/lib/components/FileInput/__tests__/__snapshots__/FileInput.test.tsx.snap +91 -0
  169. package/lib/components/FileInput/index.ts +2 -0
  170. package/lib/components/Footer/Footer.tsx +3 -3
  171. package/lib/components/Footer/__tests__/__snapshots__/Footer.test.tsx.snap +31 -31
  172. package/lib/components/Header/Header.tsx +19 -2
  173. package/lib/components/Header/__tests__/__snapshots__/Header.test.tsx.snap +4 -4
  174. package/lib/components/Heading/Documentation.mdx +1 -1
  175. package/lib/components/Heading/Heading.tsx +1 -1
  176. package/lib/components/Heading/__tests__/Heading.test.tsx +7 -19
  177. package/lib/components/Heading/__tests__/__snapshots__/Heading.test.tsx.snap +7 -7
  178. package/lib/components/Label/Label.tsx +0 -2
  179. package/lib/components/Label/__tests__/__snapshots__/Label.test.tsx.snap +7 -7
  180. package/lib/components/Link/BaseLink.tsx +84 -0
  181. package/lib/components/Link/Link.tsx +72 -32
  182. package/lib/components/Link/__tests__/__snapshots__/link.test.tsx.snap +3 -3
  183. package/lib/components/Link/__tests__/link.test.tsx +6 -13
  184. package/lib/components/Link/index.ts +1 -1
  185. package/lib/components/Menu/Menu.context.tsx +3 -1
  186. package/lib/components/Menu/Menu.tsx +5 -2
  187. package/lib/components/Menu/MenuContent.tsx +9 -6
  188. package/lib/components/Menu/MenuItem.tsx +20 -3
  189. package/lib/components/Menu/MenuSection.tsx +4 -3
  190. package/lib/components/Pagination/PaginationControls.tsx +1 -3
  191. package/lib/components/Search/Search.stories.tsx +41 -0
  192. package/lib/components/Search/Search.tsx +167 -0
  193. package/lib/components/Search/__tests__/Search.test.tsx +94 -0
  194. package/lib/components/Search/__tests__/__snapshots__/Search.test.tsx.snap +179 -0
  195. package/lib/components/Search/index.ts +2 -0
  196. package/lib/components/Select/Select.stories.tsx +8 -35
  197. package/lib/components/Select/Select.tsx +2 -2
  198. package/lib/components/Select/Select.types.ts +20 -15
  199. package/lib/components/Select/__tests__/__snapshots__/Select.test.tsx.snap +3 -3
  200. package/lib/components/Select/subcomponents/CustomOption.tsx +22 -9
  201. package/lib/components/Select/subcomponents/CustomSelect.tsx +31 -20
  202. package/lib/components/Select/subcomponents/Panel.tsx +4 -5
  203. package/lib/components/Select/subcomponents/VisibleField.tsx +26 -22
  204. package/lib/components/StandaloneLink/StandaloneLink.stories.tsx +32 -0
  205. package/lib/components/StandaloneLink/StandaloneLink.tsx +183 -0
  206. package/lib/components/StandaloneLink/__tests__/StandaloneLink.test.tsx +57 -0
  207. package/lib/components/StandaloneLink/__tests__/__snapshots__/StandaloneLink.test.tsx.snap +19 -0
  208. package/lib/components/StandaloneLink/index.ts +2 -0
  209. package/lib/components/Table/Table.stories.tsx +337 -0
  210. package/lib/components/Table/Table.tsx +42 -67
  211. package/lib/components/Table/Table.types.ts +14 -0
  212. package/lib/components/Table/__tests__/Table.test.tsx +121 -0
  213. package/lib/components/Table/__tests__/__snapshots__/Table.test.tsx.snap +210 -0
  214. package/lib/components/Table/index.ts +8 -1
  215. package/lib/components/Table/subcomponents/Body.tsx +18 -0
  216. package/lib/components/Table/subcomponents/Cell/Cell.stories.tsx +151 -0
  217. package/lib/components/Table/subcomponents/Cell/Cell.tsx +72 -0
  218. package/lib/components/Table/subcomponents/Cell/CellContent.tsx +91 -0
  219. package/lib/components/Table/subcomponents/Cell/__tests__/Cell.test.tsx +115 -0
  220. package/lib/components/Table/subcomponents/Cell/__tests__/__snapshots__/Cell.test.tsx.snap +107 -0
  221. package/lib/components/Table/subcomponents/Head.tsx +34 -0
  222. package/lib/components/Table/subcomponents/HeadCell/HeadCell.stories.tsx +85 -0
  223. package/lib/components/Table/subcomponents/HeadCell/HeadCell.tsx +99 -0
  224. package/lib/components/Table/subcomponents/HeadCell/HeadCellContent.tsx +61 -0
  225. package/lib/components/Table/subcomponents/HeadCell/__tests__/HeadCell.test.tsx +137 -0
  226. package/lib/components/Table/subcomponents/HeadCell/__tests__/__snapshots__/HeadCell.test.tsx.snap +110 -0
  227. package/lib/components/Table/subcomponents/Row.tsx +49 -0
  228. package/lib/components/Table/subcomponents/SortIcon.tsx +63 -0
  229. package/lib/components/Table/subcomponents/index.ts +14 -0
  230. package/lib/components/Tabs/Tab.tsx +3 -3
  231. package/lib/components/Tabs/TabContext.tsx +1 -0
  232. package/lib/components/Tabs/Tabs.stories.tsx +9 -3
  233. package/lib/components/Tabs/Tabs.tsx +10 -32
  234. package/lib/components/Tabs/__tests__/Tabs.test.tsx +10 -4
  235. package/lib/components/Tabs/__tests__/__snapshots__/Tabs.test.tsx.snap +32 -32
  236. package/lib/components/Timepicker/Timepicker.stories.tsx +43 -0
  237. package/lib/components/Timepicker/Timepicker.tsx +96 -0
  238. package/lib/components/Timepicker/__tests__/Timepicker.test.tsx +55 -0
  239. package/lib/components/Timepicker/__tests__/__snapshots__/Timepicker.test.tsx.snap +19 -0
  240. package/lib/components/Timepicker/index.tsx +2 -0
  241. package/lib/components/Timepicker/utils/convertDateToTimeString.test.ts +54 -0
  242. package/lib/components/Timepicker/utils/convertDateToTimeString.ts +10 -0
  243. package/lib/components/Timepicker/utils/index.ts +1 -0
  244. package/lib/components/WeekPicker/WeekPicker.tsx +26 -0
  245. package/lib/components/WeekPicker/index.ts +1 -0
  246. package/lib/components/WeekPicker/subcomponents/CustomDatepicker.tsx +298 -0
  247. package/lib/components/WeekPicker/subcomponents/DatepickerInput.tsx +111 -0
  248. package/lib/components/WeekPicker/subcomponents/VisibleField.tsx +126 -0
  249. package/lib/components/WeekPicker/subcomponents/index.ts +3 -0
  250. package/lib/components/index.ts +20 -0
  251. package/lib/hooks/index.ts +2 -0
  252. package/lib/hooks/useFocusTrap.ts +123 -0
  253. package/lib/index.ts +1 -0
  254. package/lib/theme/defaultTheme.ts +7 -0
  255. package/lib/utils/__tests__/capitalise.test.ts +40 -0
  256. package/lib/utils/capitalise.ts +4 -0
  257. package/package.json +2 -2
  258. package/dist/components/Datepicker/subcomponents/AcademicWeeks.d.ts +0 -7
  259. package/dist/components/Datepicker/subcomponents/CalendarGrid/CalendarGrid.d.ts +0 -8
  260. package/dist/components/Datepicker/subcomponents/CalendarGrid/index.d.ts +0 -1
  261. package/dist/components/Datepicker/subcomponents/CalendarMenu/CalendarMenu.d.ts +0 -12
  262. package/dist/components/Datepicker/subcomponents/CalendarMenu/index.d.ts +0 -1
  263. package/dist/components/Datepicker/subcomponents/ColumnHeadings/ColumnHeadings.d.ts +0 -2
  264. package/dist/components/Datepicker/subcomponents/ColumnHeadings/index.d.ts +0 -1
  265. package/dist/components/Datepicker/subcomponents/DateField/DateField.d.ts +0 -7
  266. package/dist/components/Datepicker/subcomponents/DateField/index.d.ts +0 -1
  267. package/dist/components/Datepicker/subcomponents/Day/index.d.ts +0 -1
  268. package/dist/components/Datepicker/subcomponents/MonthSelector/MonthSelector.d.ts +0 -6
  269. package/dist/components/Datepicker/subcomponents/MonthSelector/index.d.ts +0 -1
  270. package/dist/components/Datepicker/subcomponents/Native/Native.d.ts +0 -9
  271. package/dist/components/Datepicker/subcomponents/Native/index.d.ts +0 -1
  272. package/dist/components/Datepicker/utils/parseDateForDateField/parseDateForDateField.d.ts +0 -20
  273. package/lib/components/Datepicker/subcomponents/CalendarGrid/CalendarGrid.tsx +0 -54
  274. package/lib/components/Datepicker/subcomponents/CalendarGrid/index.ts +0 -1
  275. package/lib/components/Datepicker/subcomponents/CalendarMenu/CalendarMenu.tsx +0 -90
  276. package/lib/components/Datepicker/subcomponents/CalendarMenu/index.ts +0 -1
  277. package/lib/components/Datepicker/subcomponents/ColumnHeadings/ColumnHeadings.tsx +0 -35
  278. package/lib/components/Datepicker/subcomponents/ColumnHeadings/index.ts +0 -1
  279. package/lib/components/Datepicker/subcomponents/DateField/DateField.tsx +0 -155
  280. package/lib/components/Datepicker/subcomponents/DateField/__tests__/DateField.test.tsx +0 -191
  281. package/lib/components/Datepicker/subcomponents/DateField/index.ts +0 -1
  282. package/lib/components/Datepicker/subcomponents/Day/index.ts +0 -1
  283. package/lib/components/Datepicker/subcomponents/MonthSelector/index.ts +0 -1
  284. package/lib/components/Datepicker/subcomponents/Native/Native.tsx +0 -59
  285. package/lib/components/Datepicker/subcomponents/Native/index.ts +0 -1
  286. package/lib/components/Datepicker/utils/parseDateForDateField/parseDateForDateField.test.ts +0 -41
  287. package/lib/components/Datepicker/utils/parseDateForDateField/parseDateForDateField.ts +0 -48
  288. package/lib/components/Field/__tests__/__snapshots__/Field.test.tsx.snap +0 -300
  289. /package/dist/components/{Datepicker/subcomponents/DateField/__tests__/DateField.test.d.ts → Calendar/__tests__/Calendar.test.d.ts} +0 -0
  290. /package/dist/components/{Datepicker → Calendar}/subcomponents/AcademicWeek.d.ts +0 -0
  291. /package/dist/components/{Datepicker/subcomponents/Day → Calendar/subcomponents}/Day.stories.d.ts +0 -0
  292. /package/dist/components/{Datepicker → Calendar}/utils/getAcademicWeekNumbers/getAcademicWeekNumbers.test.d.ts +0 -0
  293. /package/dist/components/{Datepicker → Calendar}/utils/getDatesForCalendarGrid/getDatesForCalendarGrid.d.ts +0 -0
  294. /package/dist/components/{Datepicker → Calendar}/utils/getDatesForCalendarGrid/getDatesForCalendarGrid.test.d.ts +0 -0
  295. /package/dist/components/{Datepicker/utils/parseDateForDateField/parseDateForDateField.test.d.ts → Calendar/utils/normaliseMonth/normaliseMonth.test.d.ts} +0 -0
@@ -1,3 +1,2 @@
1
1
  export { default } from './Datepicker';
2
- export type { DatepickerProps } from './Datepicker';
3
- export type { CalendarEvent, AcademicWeek } from './Datepicker.types';
2
+ export type { DatepickerProps } from './Datepicker.types';
@@ -0,0 +1,209 @@
1
+ import { useRef, useEffect, useState, useCallback } from 'react';
2
+ import { css, cx } from '@emotion/css';
3
+ import { VisibleField, Panel } from '.';
4
+ import { Calendar } from '../..';
5
+ import { parseInputValue } from '../utils';
6
+ import type { DatepickerValue } from '../Datepicker.types';
7
+ import type { CalendarEvent, AcademicWeek } from '../../Calendar';
8
+
9
+ interface CustomDatepickerProps extends React.HTMLAttributes<HTMLDivElement> {
10
+ value?: DatepickerValue;
11
+ onValueChange?: (
12
+ value: DatepickerValue,
13
+ event?: React.SyntheticEvent
14
+ ) => void;
15
+ minDate?: string | null; // ISO date string: YYYY-MM-DD
16
+ maxDate?: string | null; // ISO date string: YYYY-MM-DD
17
+ disabled?: boolean;
18
+ events?: CalendarEvent[];
19
+ showAcademicWeeks?: boolean;
20
+ academicWeeks?: AcademicWeek[];
21
+ testId?: string;
22
+ ref?: React.RefObject<HTMLDivElement>;
23
+ inputRef?: React.RefObject<HTMLInputElement>;
24
+ }
25
+
26
+ const NAME = 'ucl-uikit-datepicker';
27
+
28
+ const CustomDatepicker = ({
29
+ value = null,
30
+ onValueChange = () => {},
31
+ minDate,
32
+ maxDate,
33
+ disabled = false,
34
+ events,
35
+ showAcademicWeeks,
36
+ academicWeeks = [],
37
+ testId = NAME,
38
+ className,
39
+ ref,
40
+ inputRef,
41
+ ...props
42
+ }: CustomDatepickerProps) => {
43
+ if (value && isNaN(value.getTime())) {
44
+ console.warn('CustomDatepicker: value is invalid, defaulting to null');
45
+ value = null;
46
+ }
47
+
48
+ const internalRef = useRef<HTMLDivElement>(null);
49
+ const effectiveRef = ref || internalRef;
50
+ const internalInputRef = useRef<HTMLInputElement>(null);
51
+ const effectiveInputRef = inputRef || internalInputRef;
52
+
53
+ const [panelOpen, setPanelOpen] = useState(false);
54
+
55
+ // Derived props (tidier than using `date?.getDate()`, etc, everywhere.)
56
+ const day = value?.getDate().toString().padStart(2, '0') ?? '';
57
+ const month = value ? (value.getMonth() + 1).toString().padStart(2, '0') : '';
58
+ const year = value?.getFullYear().toString() ?? '';
59
+ const formattedDateString = value ? `${day}/${month}/${year}` : '';
60
+
61
+ const [inputValue, setInputValue] = useState(formattedDateString);
62
+
63
+ const resetField = useCallback(() => {
64
+ setInputValue(formattedDateString);
65
+ }, [setInputValue, formattedDateString]);
66
+
67
+ useEffect(() => {
68
+ // Reset the input field when the value changes.
69
+ resetField();
70
+ }, [value, resetField]);
71
+
72
+ const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
73
+ setInputValue(event.target.value);
74
+ };
75
+
76
+ const handleParseInput = (event: React.SyntheticEvent) => {
77
+ // `parseInputValue` checks the date is valid and within min/max range.
78
+ const parseDate = parseInputValue(inputValue, minDate, maxDate);
79
+ if (parseDate) {
80
+ onValueChange(parseDate, event);
81
+ } else {
82
+ resetField();
83
+ }
84
+ };
85
+
86
+ const handleInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
87
+ if (event.key === 'Enter') {
88
+ handleParseInput(event);
89
+ } else if (event.key === 'Escape') {
90
+ resetField();
91
+ effectiveInputRef.current?.blur();
92
+ setPanelOpen(false);
93
+ } else if (event.key === 'Tab') {
94
+ resetField();
95
+ setPanelOpen(false);
96
+ }
97
+ };
98
+
99
+ // If `value` is out of range, automatically set it to null.
100
+ // This is validation to prevent parent components passing invalid dates.
101
+ useEffect(() => {
102
+ const isDateOutOfRange = (date: Date | null): boolean => {
103
+ if (!date) return false;
104
+
105
+ const normaliseDate = (date: Date) => {
106
+ date.setHours(0, 0, 0, 0); // Normalize to UTC midnight to avoid time zone issues
107
+ return date;
108
+ };
109
+
110
+ const parsedMinDate = minDate ? normaliseDate(new Date(minDate)) : null;
111
+ const parsedMaxDate = maxDate ? normaliseDate(new Date(maxDate)) : null;
112
+ const normalisedDate = normaliseDate(date);
113
+
114
+ if (parsedMinDate && normalisedDate < parsedMinDate) return true;
115
+ if (parsedMaxDate && normalisedDate > parsedMaxDate) return true;
116
+ return false;
117
+ };
118
+
119
+ if (value && isDateOutOfRange(value)) {
120
+ console.warn('CustomDatepicker: value is out of range, setting to null');
121
+ onValueChange(null);
122
+ }
123
+ }, [value, minDate, maxDate, onValueChange]);
124
+
125
+ // Close the panel & reset the input field if we click away.
126
+ useEffect(() => {
127
+ const handleClickOutside = (event: MouseEvent) => {
128
+ if (
129
+ effectiveRef.current &&
130
+ !effectiveRef.current.contains(event.target as Node)
131
+ ) {
132
+ setPanelOpen(false);
133
+ resetField();
134
+ }
135
+ };
136
+ document.addEventListener('mousedown', handleClickOutside);
137
+ return () => {
138
+ document.removeEventListener('mousedown', handleClickOutside);
139
+ };
140
+ }, [effectiveRef, setPanelOpen, resetField]);
141
+
142
+ useEffect(() => {
143
+ // Close the panel if the <Datepicker> becomes disabled
144
+ if (disabled && panelOpen) setPanelOpen(false);
145
+ }, [disabled, panelOpen]);
146
+
147
+ const handlePickCalendarDate = (
148
+ date: Date | null,
149
+ event?: React.SyntheticEvent
150
+ ) => {
151
+ if (onValueChange) {
152
+ onValueChange(date, event);
153
+ }
154
+ setPanelOpen(false);
155
+ };
156
+
157
+ const handleShowPanel = () => {
158
+ if (disabled) return;
159
+ setPanelOpen(true);
160
+ };
161
+
162
+ const handleTogglePanel = () => {
163
+ if (disabled) return;
164
+ setPanelOpen((prev) => !prev);
165
+ };
166
+
167
+ const baseStyle = css`
168
+ width: 196px;
169
+ height: 48px;
170
+ box-sizing: border-box;
171
+ position: relative;
172
+ `;
173
+
174
+ const style = cx(NAME, className, baseStyle);
175
+
176
+ return (
177
+ <div
178
+ className={style}
179
+ data-testid={testId}
180
+ ref={effectiveRef}
181
+ {...props}
182
+ >
183
+ <VisibleField
184
+ inputValue={inputValue}
185
+ onInputChange={handleInputChange}
186
+ onInputKeyDown={handleInputKeyDown}
187
+ onInputFocus={handleShowPanel}
188
+ onButtonClick={handleTogglePanel}
189
+ disabled={disabled}
190
+ inputRef={effectiveInputRef}
191
+ />
192
+ {panelOpen && (
193
+ <Panel>
194
+ <Calendar
195
+ pickedDate={value}
196
+ onDatePick={handlePickCalendarDate}
197
+ minDate={minDate}
198
+ maxDate={maxDate}
199
+ events={events}
200
+ showAcademicWeeks={showAcademicWeeks}
201
+ academicWeeks={academicWeeks}
202
+ />
203
+ </Panel>
204
+ )}
205
+ </div>
206
+ );
207
+ };
208
+
209
+ export default CustomDatepicker;
@@ -0,0 +1,74 @@
1
+ import { css, cx } from '@emotion/css';
2
+ import { useTheme } from '../../../theme';
3
+
4
+ interface DatepickerInputProps {
5
+ value: string;
6
+ onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
7
+ onKeyDown: (event: React.KeyboardEvent<HTMLInputElement>) => void;
8
+ onFocus: () => void;
9
+ disabled: boolean;
10
+ ref: React.RefObject<HTMLInputElement | null>;
11
+ }
12
+
13
+ const NAME = 'ucl-uikit-datepicker__input';
14
+
15
+ const DatepickerInput = ({
16
+ value,
17
+ onChange,
18
+ onKeyDown,
19
+ onFocus,
20
+ disabled,
21
+ ref,
22
+ }: DatepickerInputProps) => {
23
+ const [theme] = useTheme();
24
+
25
+ const baseStyle = css`
26
+ width: 100%;
27
+ height: 100%;
28
+ padding: 0 0 0 16px;
29
+ border: none;
30
+ color: ${theme.color.text.primary};
31
+ font-family: ${theme.font.family.primary};
32
+ font-size: ${theme.font.size.f16};
33
+ letter-spacing: 1px;
34
+ caret-color: ${theme.color.text.primary};
35
+
36
+ &:focus {
37
+ outline: none;
38
+ }
39
+
40
+ &::placeholder {
41
+ color: #8c8c8c; // TODO: Needs a design token -- Figma says 'color/text/tertiary'
42
+ }
43
+ `;
44
+
45
+ const disabledStyle = css`
46
+ color: ${theme.color.text.disabled};
47
+ background-color: ${theme.color.neutral.white};
48
+
49
+ &::placeholder {
50
+ color: ${theme.color.text.disabled};
51
+ }
52
+ `;
53
+
54
+ const style = cx(NAME, baseStyle, disabled && disabledStyle);
55
+
56
+ return (
57
+ <input
58
+ value={value}
59
+ onChange={onChange}
60
+ onKeyDown={onKeyDown}
61
+ onFocus={onFocus}
62
+ disabled={disabled}
63
+ type='text'
64
+ inputMode='numeric'
65
+ placeholder='DD/MM/YYYY'
66
+ className={style}
67
+ data-testid={NAME}
68
+ ref={ref}
69
+ aria-label={`Currently selected date: ${value}`}
70
+ />
71
+ );
72
+ };
73
+
74
+ export default DatepickerInput;
@@ -0,0 +1,70 @@
1
+ import { css, cx } from '@emotion/css';
2
+ import { theme } from '../../../theme';
3
+
4
+ interface NativeDatepickerProps
5
+ extends React.InputHTMLAttributes<HTMLInputElement> {
6
+ testId?: string;
7
+ ref?: React.RefObject<HTMLInputElement>;
8
+ }
9
+
10
+ const NAME = 'ucl-uikit-datepicker--native';
11
+
12
+ const NativeDatepicker = ({
13
+ value,
14
+ onChange,
15
+ min,
16
+ max,
17
+ className,
18
+ disabled,
19
+ testId = NAME,
20
+ ref,
21
+ ...props
22
+ }: NativeDatepickerProps) => {
23
+ const baseStyle = css`
24
+ width: 196px;
25
+ height: 48px;
26
+ box-sizing: border-box;
27
+ padding: 0 16px;
28
+ border: 1px solid ${theme.color.neutral.grey60};
29
+ color: #1a1a1a;
30
+ font-size: 16px;
31
+ font-family: sans-serif;
32
+ text-transform: uppercase;
33
+ cursor: pointer;
34
+
35
+ &:focus-visible {
36
+ outline: none;
37
+ box-shadow: ${theme.boxShadow.focus};
38
+ }
39
+
40
+ &::placeholder {
41
+ color: #8c8c8c; // TODO: Needs a design token -- Figma says 'color/text/tertiary'
42
+ }
43
+ `;
44
+
45
+ const disabledStyle = css`
46
+ color: ${theme.color.text.disabled};
47
+ background-color: ${theme.color.neutral.white};
48
+ border-color: ${theme.color.neutral.grey20};
49
+ cursor: not-allowed;
50
+ `;
51
+
52
+ const style = cx(NAME, baseStyle, disabled && disabledStyle, className);
53
+
54
+ return (
55
+ <input
56
+ type='date'
57
+ value={value}
58
+ onChange={onChange}
59
+ min={min}
60
+ max={max}
61
+ disabled={disabled}
62
+ className={style}
63
+ data-testid={testId}
64
+ ref={ref}
65
+ {...props}
66
+ />
67
+ );
68
+ };
69
+
70
+ export default NativeDatepicker;
@@ -0,0 +1,32 @@
1
+ import { css, cx } from '@emotion/css';
2
+
3
+ interface PanelProps {
4
+ zIndex?: number;
5
+ children: React.ReactNode;
6
+ }
7
+
8
+ const NAME = 'ucl-uikit-datepicker__panel';
9
+
10
+ const Panel = ({ zIndex = 10, children }: PanelProps) => {
11
+ const datepickerHeight = 48;
12
+ const gapFromDatepicker = 8;
13
+
14
+ const baseStyle = css`
15
+ position: absolute;
16
+ top: ${datepickerHeight + gapFromDatepicker}px;
17
+ z-index: ${zIndex};
18
+ `;
19
+
20
+ const style = cx(NAME, baseStyle);
21
+
22
+ return (
23
+ <div
24
+ data-testid={NAME}
25
+ className={style}
26
+ >
27
+ {children}
28
+ </div>
29
+ );
30
+ };
31
+
32
+ export default Panel;
@@ -0,0 +1,104 @@
1
+ import { css, cx } from '@emotion/css';
2
+ import { DatepickerInput } from './';
3
+ import { Icon } from '../../..';
4
+ import { useTheme } from '../../../theme';
5
+ import React from 'react';
6
+
7
+ interface VisibleFieldProps {
8
+ inputValue: string;
9
+ onInputChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
10
+ onInputKeyDown: (event: React.KeyboardEvent<HTMLInputElement>) => void;
11
+ onInputFocus: () => void;
12
+ onButtonClick: () => void;
13
+ disabled: boolean;
14
+ inputRef: React.RefObject<HTMLInputElement | null>;
15
+ }
16
+
17
+ const NAME = 'ucl-uikit-datepicker__visible-field';
18
+
19
+ const VisibleField = ({
20
+ inputValue,
21
+ onInputChange,
22
+ onInputKeyDown,
23
+ onInputFocus,
24
+ onButtonClick,
25
+ disabled,
26
+ inputRef,
27
+ }: VisibleFieldProps) => {
28
+ const [theme] = useTheme();
29
+
30
+ const baseStyle = css`
31
+ display: flex;
32
+ align-items: center;
33
+ justify-content: space-between;
34
+ width: 100%;
35
+ height: 100%;
36
+ box-sizing: border-box;
37
+ border: 1px solid ${theme.color.neutral.grey60};
38
+ background-color: ${theme.color.neutral.white};
39
+
40
+ &:focus-within {
41
+ box-shadow: ${theme.boxShadow.focus};
42
+ }
43
+ `;
44
+
45
+ const disabledStyle = css`
46
+ color: ${theme.color.text.disabled};
47
+ background-color: ${theme.color.neutral.white};
48
+ border-color: ${theme.color.neutral.grey20};
49
+
50
+ cursor: not-allowed;
51
+ // And child elements
52
+ & * {
53
+ cursor: not-allowed;
54
+ }
55
+ `;
56
+
57
+ // The container for the <Icon.Calendar> is a <div> not an <IconButton>,
58
+ // so that the orange border only appears when the input has focus and the user can type.
59
+ // The container increases the clickable area of the icon.
60
+ const iconButtonStyle = css`
61
+ display: flex;
62
+ align-items: center;
63
+ justify-content: center;
64
+ padding: 0 16px 0 4px;
65
+ height: 100%;
66
+ cursor: pointer;
67
+ `;
68
+
69
+ // `min-width` here accounts for a recurring problem,
70
+ // in which icons shrink when horizontal space is limited.
71
+ // TODO: This ought to be fixed in the <Icon> component itself.
72
+ const iconStyle = css`
73
+ min-width: 24px;
74
+ color: ${disabled
75
+ ? theme.color.text.disabled
76
+ : '#8C8C8C'}; // TODO: Needs a design token
77
+ `;
78
+
79
+ const style = cx(NAME, baseStyle, disabled && disabledStyle);
80
+
81
+ return (
82
+ <div
83
+ className={style}
84
+ data-testid={NAME}
85
+ >
86
+ <DatepickerInput
87
+ value={inputValue}
88
+ onChange={onInputChange}
89
+ onKeyDown={onInputKeyDown}
90
+ onFocus={onInputFocus}
91
+ disabled={disabled}
92
+ ref={inputRef}
93
+ />
94
+ <div
95
+ onClick={onButtonClick}
96
+ className={iconButtonStyle}
97
+ >
98
+ <Icon.Calendar className={iconStyle} />
99
+ </div>
100
+ </div>
101
+ );
102
+ };
103
+
104
+ export default VisibleField;
@@ -1,7 +1,5 @@
1
- export { default as CalendarGrid } from './CalendarGrid';
2
- export { default as CalendarMenu } from './CalendarMenu';
3
- export { default as ColumnHeadings } from './ColumnHeadings';
4
- export { default as DateField } from './DateField';
5
- export { default as Day } from './Day';
6
- export { default as Native } from './Native';
7
- export { default as MonthSelector } from './MonthSelector';
1
+ export { default as CustomDatepicker } from './CustomDatepicker';
2
+ export { default as NativeDatepicker } from './NativeDatepicker';
3
+ export { default as VisibleField } from './VisibleField';
4
+ export { default as DatepickerInput } from './DatepickerInput';
5
+ export { default as Panel } from './Panel';
@@ -0,0 +1,32 @@
1
+ import { describe, expect, test } from 'vitest';
2
+ import dateToLocaleISOString from './dateToLocaleISOString';
3
+
4
+ describe('dateToLocaleISOString', () => {
5
+ test('Should return null if the date is null', () => {
6
+ expect(dateToLocaleISOString(null)).toBeNull();
7
+ });
8
+
9
+ test('Should return null if the date is undefined', () => {
10
+ expect(dateToLocaleISOString(undefined)).toBeNull();
11
+ });
12
+
13
+ test('Should return a YYYY-MM-DD string for a valid date', () => {
14
+ const date = new Date('2025-06-28');
15
+ expect(dateToLocaleISOString(date)).toBe('2025-06-28');
16
+ });
17
+
18
+ test('Should handle dates explicitly set to midnight', () => {
19
+ const date = new Date('2025-01-01T00:00:00');
20
+ expect(dateToLocaleISOString(date)).toBe('2025-01-01');
21
+ });
22
+
23
+ test('Should handle dates explicitly set just before the end of the day', () => {
24
+ const date = new Date('2025-12-31T23:59:59');
25
+ expect(dateToLocaleISOString(date)).toBe('2025-12-31');
26
+ });
27
+
28
+ test('Should correctly format a leap day', () => {
29
+ const date = new Date('2024-02-29');
30
+ expect(dateToLocaleISOString(date)).toBe('2024-02-29');
31
+ });
32
+ });
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Converts a Date object to a `YYYY-MM-DD` string based on the user's local timezone.
3
+ *
4
+ * Used for passing dates to <NativeDatepicker> in `Datepicker.tsx`
5
+ *
6
+ * This function uses the Swedish (`sv-SE`) locale with `toLocaleDateString`
7
+ * as it conveniently defaults to the ISO 8601 `YYYY-MM-DD` format, while respecting
8
+ * the local date. This avoids timezone conversion issues that can arise from
9
+ * using `toISOString()`.
10
+ *
11
+ * This implementation should handle daylight saving time, etc, correctly.
12
+ *
13
+ * @param date The date to convert.
14
+ * @returns A string in `YYYY-MM-DD` format, or `null` if the input is `null`.
15
+ */
16
+ const dateToLocaleISOString = (
17
+ date: Date | null | undefined
18
+ ): string | null => {
19
+ if (!date) return null;
20
+ return date.toLocaleDateString('sv-SE');
21
+ };
22
+
23
+ export default dateToLocaleISOString;
@@ -1,3 +1,2 @@
1
- export { default as getDatesForCalendarGrid } from './getDatesForCalendarGrid/getDatesForCalendarGrid';
2
- export { default as parseDate } from './parseDateForDateField/parseDateForDateField';
3
- export { default as getAcademicWeekNumbers } from './getAcademicWeekNumbers/getAcademicWeekNumbers';
1
+ export { default as dateToLocaleISOString } from './dateToLocaleISOString/dateToLocaleISOString';
2
+ export { default as parseInputValue } from './parseInputValue/parseInputValue';
@@ -0,0 +1,110 @@
1
+ import { describe, expect, test } from 'vitest';
2
+ import parseInputValue from './parseInputValue';
3
+
4
+ describe('parseInputValue', () => {
5
+ test('Returns a date from an expected string format', () => {
6
+ const dateWithSlashes = parseInputValue('01/03/2025') as Date;
7
+ expect(dateWithSlashes).toBeInstanceOf(Date);
8
+ expect(dateWithSlashes.getFullYear()).toBe(2025);
9
+ expect(dateWithSlashes.getMonth()).toBe(2); // March is month 2 (0-indexed)
10
+ expect(dateWithSlashes.getDate()).toBe(1);
11
+
12
+ const dateWithDashes = parseInputValue('11-06-2026') as Date;
13
+ expect(dateWithDashes).toBeInstanceOf(Date);
14
+ expect(dateWithDashes.getFullYear()).toBe(2026);
15
+ expect(dateWithDashes.getMonth()).toBe(5); // June is month 5 (0-indexed)
16
+ expect(dateWithDashes.getDate()).toBe(11);
17
+
18
+ const dateWithSpaces = parseInputValue('12 10 2027') as Date;
19
+ expect(dateWithSpaces).toBeInstanceOf(Date);
20
+ expect(dateWithSpaces.getFullYear()).toBe(2027);
21
+ expect(dateWithSpaces.getMonth()).toBe(9); // October is month 9 (0-indexed)
22
+ expect(dateWithSpaces.getDate()).toBe(12);
23
+ });
24
+
25
+ test('Returns null for invalid date strings', () => {
26
+ expect(parseInputValue('invalid-date')).toBeNull();
27
+ expect(parseInputValue('')).toBeNull(); // Empty string
28
+ expect(parseInputValue(' ')).toBeNull(); // Just white space
29
+ });
30
+
31
+ test('Handles single-digit days and months correctly', () => {
32
+ const dateWithSingleDigit = parseInputValue('1/2/2023') as Date;
33
+ expect(dateWithSingleDigit).toBeInstanceOf(Date);
34
+ expect(dateWithSingleDigit.getFullYear()).toBe(2023);
35
+ expect(dateWithSingleDigit.getMonth()).toBe(1); // February is month 1 (0-indexed)
36
+ expect(dateWithSingleDigit.getDate()).toBe(1);
37
+ });
38
+
39
+ test('Rejects dates before minDate', () => {
40
+ const minDate1 = '2020-01-01';
41
+ const dateBeforeMin1 = parseInputValue('31/12/2019', minDate1) as Date;
42
+ expect(dateBeforeMin1).toBeNull();
43
+
44
+ const minDate2 = '2020-06-15';
45
+ const dateBeforeMin2 = parseInputValue('14/06/2020', minDate2) as Date;
46
+ expect(dateBeforeMin2).toBeNull();
47
+ });
48
+
49
+ test('Rejects dates after maxDate', () => {
50
+ const maxDate = '2025-12-31';
51
+ const dateAfterMax = parseInputValue(
52
+ '01/01/2026',
53
+ undefined,
54
+ maxDate
55
+ ) as Date;
56
+ expect(dateAfterMax).toBeNull();
57
+
58
+ const maxDate2 = '2023-06-15';
59
+ const dateAfterMax2 = parseInputValue(
60
+ '16/06/2023',
61
+ undefined,
62
+ maxDate2
63
+ ) as Date;
64
+ expect(dateAfterMax2).toBeNull();
65
+ });
66
+
67
+ test('Accepts dates within minDate and maxDate range', () => {
68
+ const minDate1 = '2020-01-01';
69
+ const maxDate1 = '2025-12-31';
70
+ const validDate1 = parseInputValue(
71
+ '15/06/2023',
72
+ minDate1,
73
+ maxDate1
74
+ ) as Date;
75
+ expect(validDate1).toBeInstanceOf(Date);
76
+ expect(validDate1.getFullYear()).toBe(2023);
77
+ expect(validDate1.getMonth()).toBe(5); // June is month 5 (0-indexed)
78
+ expect(validDate1.getDate()).toBe(15);
79
+
80
+ const minDate2 = '2025-06-01';
81
+ const maxDate2 = '2025-06-30';
82
+ const validDate2 = parseInputValue(
83
+ '15/06/2025',
84
+ minDate2,
85
+ maxDate2
86
+ ) as Date;
87
+ expect(validDate2).toBeInstanceOf(Date);
88
+ expect(validDate2.getFullYear()).toBe(2025);
89
+ expect(validDate2.getMonth()).toBe(5); // June is month 5 (0-indexed)
90
+ expect(validDate2.getDate()).toBe(15);
91
+ });
92
+
93
+ test('Accepts dates after minDate without maxDate', () => {
94
+ const minDate = '2020-01-01';
95
+ const validDate = parseInputValue('15/06/2023', minDate) as Date;
96
+ expect(validDate).toBeInstanceOf(Date);
97
+ expect(validDate.getFullYear()).toBe(2023);
98
+ expect(validDate.getMonth()).toBe(5); // June is month 5 (0-indexed)
99
+ expect(validDate.getDate()).toBe(15);
100
+ });
101
+
102
+ test('Accepts dates before maxDate without minDate', () => {
103
+ const maxDate = '2025-12-31';
104
+ const validDate = parseInputValue('15/06/2025', undefined, maxDate) as Date;
105
+ expect(validDate).toBeInstanceOf(Date);
106
+ expect(validDate.getFullYear()).toBe(2025);
107
+ expect(validDate.getMonth()).toBe(5); // June is month 5 (0-indexed)
108
+ expect(validDate.getDate()).toBe(15);
109
+ });
110
+ });