@etus/ui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1075) hide show
  1. package/dist/chunk-HRNDJU7D.js +11 -0
  2. package/dist/chunk-HRNDJU7D.js.map +1 -0
  3. package/dist/index.d.ts +21250 -0
  4. package/dist/index.js +44886 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/lib/utils.d.ts +5 -0
  7. package/dist/lib/utils.js +7 -0
  8. package/dist/lib/utils.js.map +1 -0
  9. package/package.json +145 -0
  10. package/src/components/CLAUDE.md +66 -0
  11. package/src/components/advanced/AssetManager/AssetManager.test.tsx +624 -0
  12. package/src/components/advanced/AssetManager/AssetManager.tsx +928 -0
  13. package/src/components/advanced/AssetManager/AssetManager.types.ts +248 -0
  14. package/src/components/advanced/AssetManager/AssetManager.variants.ts +284 -0
  15. package/src/components/advanced/AssetManager/README.md +246 -0
  16. package/src/components/advanced/AssetManager/index.ts +4 -0
  17. package/src/components/advanced/CLAUDE.md +77 -0
  18. package/src/components/advanced/Calendar/Calendar.test.tsx +718 -0
  19. package/src/components/advanced/Calendar/Calendar.tsx +264 -0
  20. package/src/components/advanced/Calendar/Calendar.types.ts +62 -0
  21. package/src/components/advanced/Calendar/Calendar.variants.ts +154 -0
  22. package/src/components/advanced/Calendar/README.md +389 -0
  23. package/src/components/advanced/Calendar/index.ts +3 -0
  24. package/src/components/advanced/Command/Command.test.tsx +1014 -0
  25. package/src/components/advanced/Command/Command.tsx +330 -0
  26. package/src/components/advanced/Command/Command.types.ts +238 -0
  27. package/src/components/advanced/Command/Command.variants.ts +300 -0
  28. package/src/components/advanced/Command/README.md +1259 -0
  29. package/src/components/advanced/Command/index.ts +45 -0
  30. package/src/components/advanced/DragAndDrop/DragAndDrop.test.tsx +573 -0
  31. package/src/components/advanced/DragAndDrop/DragAndDrop.tsx +495 -0
  32. package/src/components/advanced/DragAndDrop/DragAndDrop.types.ts +237 -0
  33. package/src/components/advanced/DragAndDrop/DragAndDrop.variants.ts +156 -0
  34. package/src/components/advanced/DragAndDrop/README.md +284 -0
  35. package/src/components/advanced/DragAndDrop/index.ts +4 -0
  36. package/src/components/advanced/ErrorBoundary/ErrorBoundary.test.tsx +372 -0
  37. package/src/components/advanced/ErrorBoundary/ErrorBoundary.tsx +184 -0
  38. package/src/components/advanced/ErrorBoundary/ErrorBoundary.types.ts +73 -0
  39. package/src/components/advanced/ErrorBoundary/ErrorBoundary.variants.ts +153 -0
  40. package/src/components/advanced/ErrorBoundary/README.md +296 -0
  41. package/src/components/advanced/ErrorBoundary/index.ts +18 -0
  42. package/src/components/advanced/EventCalendar/EventCalendar.test.tsx +535 -0
  43. package/src/components/advanced/EventCalendar/EventCalendar.tsx +1066 -0
  44. package/src/components/advanced/EventCalendar/EventCalendar.types.ts +232 -0
  45. package/src/components/advanced/EventCalendar/EventCalendar.variants.ts +222 -0
  46. package/src/components/advanced/EventCalendar/README.md +330 -0
  47. package/src/components/advanced/EventCalendar/index.ts +35 -0
  48. package/src/components/advanced/FileDropzone/FileDropzone.test.tsx +344 -0
  49. package/src/components/advanced/FileDropzone/FileDropzone.tsx +188 -0
  50. package/src/components/advanced/FileDropzone/FileDropzone.types.ts +47 -0
  51. package/src/components/advanced/FileDropzone/FileDropzone.variants.ts +46 -0
  52. package/src/components/advanced/FileDropzone/README.md +359 -0
  53. package/src/components/advanced/FileDropzone/index.ts +7 -0
  54. package/src/components/advanced/FilePreview/FilePreview.test.tsx +503 -0
  55. package/src/components/advanced/FilePreview/FilePreview.tsx +385 -0
  56. package/src/components/advanced/FilePreview/FilePreview.types.ts +90 -0
  57. package/src/components/advanced/FilePreview/FilePreview.variants.ts +234 -0
  58. package/src/components/advanced/FilePreview/README.md +318 -0
  59. package/src/components/advanced/FilePreview/index.ts +25 -0
  60. package/src/components/advanced/FileUpload/FileUpload.test.tsx +676 -0
  61. package/src/components/advanced/FileUpload/FileUpload.tsx +845 -0
  62. package/src/components/advanced/FileUpload/FileUpload.types.ts +270 -0
  63. package/src/components/advanced/FileUpload/FileUpload.variants.ts +216 -0
  64. package/src/components/advanced/FileUpload/README.md +380 -0
  65. package/src/components/advanced/FileUpload/index.ts +39 -0
  66. package/src/components/advanced/FilterBuilder/FilterBuilder.test.tsx +644 -0
  67. package/src/components/advanced/FilterBuilder/FilterBuilder.tsx +881 -0
  68. package/src/components/advanced/FilterBuilder/FilterBuilder.types.ts +249 -0
  69. package/src/components/advanced/FilterBuilder/FilterBuilder.variants.ts +307 -0
  70. package/src/components/advanced/FilterBuilder/README.md +383 -0
  71. package/src/components/advanced/FilterBuilder/index.ts +48 -0
  72. package/src/components/advanced/MarkdownEditor/MarkdownEditor.test.tsx +468 -0
  73. package/src/components/advanced/MarkdownEditor/MarkdownEditor.tsx +556 -0
  74. package/src/components/advanced/MarkdownEditor/MarkdownEditor.types.ts +108 -0
  75. package/src/components/advanced/MarkdownEditor/MarkdownEditor.variants.ts +62 -0
  76. package/src/components/advanced/MarkdownEditor/README.md +352 -0
  77. package/src/components/advanced/MarkdownEditor/index.ts +15 -0
  78. package/src/components/advanced/Portal/Portal.test.tsx +406 -0
  79. package/src/components/advanced/Portal/Portal.tsx +77 -0
  80. package/src/components/advanced/Portal/Portal.types.ts +28 -0
  81. package/src/components/advanced/Portal/Portal.variants.ts +95 -0
  82. package/src/components/advanced/Portal/README.md +326 -0
  83. package/src/components/advanced/Portal/index.ts +9 -0
  84. package/src/components/advanced/RichTextEditor/README.md +383 -0
  85. package/src/components/advanced/RichTextEditor/RichTextEditor.test.tsx +394 -0
  86. package/src/components/advanced/RichTextEditor/RichTextEditor.tsx +651 -0
  87. package/src/components/advanced/RichTextEditor/RichTextEditor.types.ts +77 -0
  88. package/src/components/advanced/RichTextEditor/RichTextEditor.variants.ts +151 -0
  89. package/src/components/advanced/RichTextEditor/index.ts +24 -0
  90. package/src/components/advanced/Search/README.md +391 -0
  91. package/src/components/advanced/Search/Search.test.tsx +567 -0
  92. package/src/components/advanced/Search/Search.tsx +829 -0
  93. package/src/components/advanced/Search/Search.types.ts +243 -0
  94. package/src/components/advanced/Search/Search.variants.ts +358 -0
  95. package/src/components/advanced/Search/index.ts +52 -0
  96. package/src/components/advanced/SortableList/README.md +448 -0
  97. package/src/components/advanced/SortableList/SortableList.test.tsx +317 -0
  98. package/src/components/advanced/SortableList/SortableList.tsx +392 -0
  99. package/src/components/advanced/SortableList/SortableList.types.ts +122 -0
  100. package/src/components/advanced/SortableList/SortableList.variants.ts +141 -0
  101. package/src/components/advanced/SortableList/index.ts +33 -0
  102. package/src/components/advanced/VersionControl/README.md +440 -0
  103. package/src/components/advanced/VersionControl/VersionControl.test.tsx +517 -0
  104. package/src/components/advanced/VersionControl/VersionControl.tsx +758 -0
  105. package/src/components/advanced/VersionControl/VersionControl.types.ts +176 -0
  106. package/src/components/advanced/VersionControl/VersionControl.variants.ts +203 -0
  107. package/src/components/advanced/VersionControl/index.ts +33 -0
  108. package/src/components/advanced/index.ts +17 -0
  109. package/src/components/data-display/Accordion/Accordion.test.tsx +519 -0
  110. package/src/components/data-display/Accordion/Accordion.tsx +164 -0
  111. package/src/components/data-display/Accordion/Accordion.types.ts +37 -0
  112. package/src/components/data-display/Accordion/Accordion.variants.ts +112 -0
  113. package/src/components/data-display/Accordion/README.md +976 -0
  114. package/src/components/data-display/Accordion/index.ts +31 -0
  115. package/src/components/data-display/AreaChart/AreaChart.test.tsx +529 -0
  116. package/src/components/data-display/AreaChart/AreaChart.tsx +318 -0
  117. package/src/components/data-display/AreaChart/AreaChart.types.ts +169 -0
  118. package/src/components/data-display/AreaChart/AreaChart.variants.ts +45 -0
  119. package/src/components/data-display/AreaChart/README.md +229 -0
  120. package/src/components/data-display/AreaChart/index.ts +2 -0
  121. package/src/components/data-display/Banner/Banner.test.tsx +648 -0
  122. package/src/components/data-display/Banner/Banner.tsx +111 -0
  123. package/src/components/data-display/Banner/Banner.types.ts +51 -0
  124. package/src/components/data-display/Banner/Banner.variants.ts +37 -0
  125. package/src/components/data-display/Banner/README.md +351 -0
  126. package/src/components/data-display/Banner/index.ts +2 -0
  127. package/src/components/data-display/BarChart/BarChart.test.tsx +536 -0
  128. package/src/components/data-display/BarChart/BarChart.tsx +305 -0
  129. package/src/components/data-display/BarChart/BarChart.types.ts +145 -0
  130. package/src/components/data-display/BarChart/BarChart.variants.ts +61 -0
  131. package/src/components/data-display/BarChart/README.md +205 -0
  132. package/src/components/data-display/BarChart/index.ts +2 -0
  133. package/src/components/data-display/BarList/BarList.tsx +172 -0
  134. package/src/components/data-display/BarList/BarList.types.ts +69 -0
  135. package/src/components/data-display/BarList/BarList.variants.ts +63 -0
  136. package/src/components/data-display/BarList/index.ts +2 -0
  137. package/src/components/data-display/CLAUDE.md +90 -0
  138. package/src/components/data-display/Callout/Callout.test.tsx +516 -0
  139. package/src/components/data-display/Callout/Callout.tsx +112 -0
  140. package/src/components/data-display/Callout/Callout.types.ts +37 -0
  141. package/src/components/data-display/Callout/Callout.variants.ts +48 -0
  142. package/src/components/data-display/Callout/README.md +341 -0
  143. package/src/components/data-display/Callout/index.ts +2 -0
  144. package/src/components/data-display/Carousel/Carousel.test.tsx +386 -0
  145. package/src/components/data-display/Carousel/Carousel.tsx +241 -0
  146. package/src/components/data-display/Carousel/Carousel.types.ts +20 -0
  147. package/src/components/data-display/Carousel/Carousel.variants.ts +125 -0
  148. package/src/components/data-display/Carousel/README.md +711 -0
  149. package/src/components/data-display/Carousel/index.ts +1 -0
  150. package/src/components/data-display/CategoryBar/CategoryBar.tsx +220 -0
  151. package/src/components/data-display/CategoryBar/CategoryBar.types.ts +80 -0
  152. package/src/components/data-display/CategoryBar/CategoryBar.variants.ts +85 -0
  153. package/src/components/data-display/CategoryBar/index.ts +2 -0
  154. package/src/components/data-display/Chart/Chart.test.tsx +432 -0
  155. package/src/components/data-display/Chart/Chart.tsx +476 -0
  156. package/src/components/data-display/Chart/Chart.types.ts +24 -0
  157. package/src/components/data-display/Chart/Chart.variants.ts +106 -0
  158. package/src/components/data-display/Chart/README.md +674 -0
  159. package/src/components/data-display/Chart/index.ts +1 -0
  160. package/src/components/data-display/ChartCard/ChartCard.test.tsx +327 -0
  161. package/src/components/data-display/ChartCard/ChartCard.tsx +201 -0
  162. package/src/components/data-display/ChartCard/ChartCard.types.ts +68 -0
  163. package/src/components/data-display/ChartCard/ChartCard.variants.ts +63 -0
  164. package/src/components/data-display/ChartCard/index.ts +17 -0
  165. package/src/components/data-display/ChartLegend/ChartLegend.test.tsx +165 -0
  166. package/src/components/data-display/ChartLegend/ChartLegend.types.ts +88 -0
  167. package/src/components/data-display/ChartLegend/README.md +317 -0
  168. package/src/components/data-display/ChartLegend/index.ts +22 -0
  169. package/src/components/data-display/ComboChart/ComboChart.tsx +380 -0
  170. package/src/components/data-display/ComboChart/ComboChart.types.ts +224 -0
  171. package/src/components/data-display/ComboChart/index.ts +2 -0
  172. package/src/components/data-display/DashboardCard/DashboardCard.test.tsx +289 -0
  173. package/src/components/data-display/DashboardCard/DashboardCard.tsx +285 -0
  174. package/src/components/data-display/DashboardCard/DashboardCard.types.ts +74 -0
  175. package/src/components/data-display/DashboardCard/DashboardCard.variants.ts +67 -0
  176. package/src/components/data-display/DashboardCard/index.ts +25 -0
  177. package/src/components/data-display/DashboardFilterbar/DashboardFilterbar.tsx +151 -0
  178. package/src/components/data-display/DashboardFilterbar/DashboardFilterbar.types.ts +39 -0
  179. package/src/components/data-display/DashboardFilterbar/DashboardFilterbar.variants.ts +30 -0
  180. package/src/components/data-display/DashboardFilterbar/index.ts +10 -0
  181. package/src/components/data-display/DataTable/DataTable.test.tsx +654 -0
  182. package/src/components/data-display/DataTable/DataTable.tsx +529 -0
  183. package/src/components/data-display/DataTable/DataTable.types.ts +190 -0
  184. package/src/components/data-display/DataTable/DataTable.variants.ts +79 -0
  185. package/src/components/data-display/DataTable/README.md +447 -0
  186. package/src/components/data-display/DataTable/index.ts +2 -0
  187. package/src/components/data-display/DeltaBar/DeltaBar.tsx +100 -0
  188. package/src/components/data-display/DeltaBar/DeltaBar.types.ts +57 -0
  189. package/src/components/data-display/DeltaBar/DeltaBar.variants.ts +40 -0
  190. package/src/components/data-display/DeltaBar/index.ts +2 -0
  191. package/src/components/data-display/EmptyState/EmptyState.test.tsx +368 -0
  192. package/src/components/data-display/EmptyState/EmptyState.tsx +91 -0
  193. package/src/components/data-display/EmptyState/EmptyState.types.ts +9 -0
  194. package/src/components/data-display/EmptyState/EmptyState.variants.ts +28 -0
  195. package/src/components/data-display/EmptyState/README.md +746 -0
  196. package/src/components/data-display/EmptyState/index.ts +1 -0
  197. package/src/components/data-display/Feed/Feed.test.tsx +668 -0
  198. package/src/components/data-display/Feed/Feed.tsx +290 -0
  199. package/src/components/data-display/Feed/Feed.types.ts +104 -0
  200. package/src/components/data-display/Feed/Feed.variants.ts +64 -0
  201. package/src/components/data-display/Feed/README.md +326 -0
  202. package/src/components/data-display/Feed/index.ts +17 -0
  203. package/src/components/data-display/FunnelChart/FunnelChart.tsx +177 -0
  204. package/src/components/data-display/FunnelChart/FunnelChart.types.ts +145 -0
  205. package/src/components/data-display/FunnelChart/index.ts +2 -0
  206. package/src/components/data-display/GaugeChart/GaugeChart.test.tsx +129 -0
  207. package/src/components/data-display/GaugeChart/GaugeChart.tsx +332 -0
  208. package/src/components/data-display/GaugeChart/GaugeChart.types.ts +53 -0
  209. package/src/components/data-display/GaugeChart/GaugeChart.variants.ts +56 -0
  210. package/src/components/data-display/GaugeChart/README.md +305 -0
  211. package/src/components/data-display/GaugeChart/index.ts +3 -0
  212. package/src/components/data-display/Heatmap/Heatmap.test.tsx +630 -0
  213. package/src/components/data-display/Heatmap/Heatmap.tsx +569 -0
  214. package/src/components/data-display/Heatmap/Heatmap.types.ts +120 -0
  215. package/src/components/data-display/Heatmap/Heatmap.variants.ts +72 -0
  216. package/src/components/data-display/Heatmap/README.md +321 -0
  217. package/src/components/data-display/Heatmap/index.ts +2 -0
  218. package/src/components/data-display/HoverCard/HoverCard.test.tsx +314 -0
  219. package/src/components/data-display/HoverCard/HoverCard.tsx +40 -0
  220. package/src/components/data-display/HoverCard/HoverCard.types.ts +21 -0
  221. package/src/components/data-display/HoverCard/HoverCard.variants.ts +29 -0
  222. package/src/components/data-display/HoverCard/README.md +624 -0
  223. package/src/components/data-display/HoverCard/index.ts +1 -0
  224. package/src/components/data-display/ImageGallery/ImageGallery.test.tsx +519 -0
  225. package/src/components/data-display/ImageGallery/ImageGallery.tsx +733 -0
  226. package/src/components/data-display/ImageGallery/ImageGallery.types.ts +109 -0
  227. package/src/components/data-display/ImageGallery/ImageGallery.variants.ts +58 -0
  228. package/src/components/data-display/ImageGallery/README.md +352 -0
  229. package/src/components/data-display/ImageGallery/index.ts +9 -0
  230. package/src/components/data-display/Item/Item.test.tsx +476 -0
  231. package/src/components/data-display/Item/Item.tsx +195 -0
  232. package/src/components/data-display/Item/Item.types.ts +23 -0
  233. package/src/components/data-display/Item/Item.variants.ts +51 -0
  234. package/src/components/data-display/Item/README.md +759 -0
  235. package/src/components/data-display/Item/index.ts +1 -0
  236. package/src/components/data-display/KPICard/KPICard.test.tsx +445 -0
  237. package/src/components/data-display/KPICard/KPICard.tsx +203 -0
  238. package/src/components/data-display/KPICard/KPICard.types.ts +32 -0
  239. package/src/components/data-display/KPICard/KPICard.variants.ts +64 -0
  240. package/src/components/data-display/KPICard/README.md +380 -0
  241. package/src/components/data-display/KPICard/index.ts +7 -0
  242. package/src/components/data-display/Lightbox/Lightbox.test.tsx +574 -0
  243. package/src/components/data-display/Lightbox/Lightbox.tsx +466 -0
  244. package/src/components/data-display/Lightbox/Lightbox.types.ts +53 -0
  245. package/src/components/data-display/Lightbox/Lightbox.variants.ts +99 -0
  246. package/src/components/data-display/Lightbox/README.md +397 -0
  247. package/src/components/data-display/Lightbox/index.ts +2 -0
  248. package/src/components/data-display/LineChart/LineChart.test.tsx +654 -0
  249. package/src/components/data-display/LineChart/LineChart.tsx +295 -0
  250. package/src/components/data-display/LineChart/LineChart.types.ts +168 -0
  251. package/src/components/data-display/LineChart/LineChart.variants.ts +52 -0
  252. package/src/components/data-display/LineChart/README.md +242 -0
  253. package/src/components/data-display/LineChart/index.ts +8 -0
  254. package/src/components/data-display/List/List.test.tsx +756 -0
  255. package/src/components/data-display/List/List.tsx +455 -0
  256. package/src/components/data-display/List/List.types.ts +67 -0
  257. package/src/components/data-display/List/List.variants.ts +69 -0
  258. package/src/components/data-display/List/README.md +374 -0
  259. package/src/components/data-display/List/index.ts +9 -0
  260. package/src/components/data-display/MarkerBar/MarkerBar.tsx +130 -0
  261. package/src/components/data-display/MarkerBar/MarkerBar.types.ts +67 -0
  262. package/src/components/data-display/MarkerBar/MarkerBar.variants.ts +75 -0
  263. package/src/components/data-display/MarkerBar/index.ts +3 -0
  264. package/src/components/data-display/PieChart/PieChart.test.tsx +655 -0
  265. package/src/components/data-display/PieChart/PieChart.tsx +327 -0
  266. package/src/components/data-display/PieChart/PieChart.types.ts +134 -0
  267. package/src/components/data-display/PieChart/PieChart.variants.ts +49 -0
  268. package/src/components/data-display/PieChart/README.md +261 -0
  269. package/src/components/data-display/PieChart/index.ts +2 -0
  270. package/src/components/data-display/ScatterChart/ScatterChart.tsx +310 -0
  271. package/src/components/data-display/ScatterChart/ScatterChart.types.ts +272 -0
  272. package/src/components/data-display/ScatterChart/index.ts +2 -0
  273. package/src/components/data-display/SingleStat/README.md +363 -0
  274. package/src/components/data-display/SingleStat/SingleStat.test.tsx +223 -0
  275. package/src/components/data-display/SingleStat/SingleStat.tsx +251 -0
  276. package/src/components/data-display/SingleStat/SingleStat.types.ts +71 -0
  277. package/src/components/data-display/SingleStat/SingleStat.variants.ts +51 -0
  278. package/src/components/data-display/SingleStat/index.ts +6 -0
  279. package/src/components/data-display/Sparkline/README.md +321 -0
  280. package/src/components/data-display/Sparkline/Sparkline.test.tsx +276 -0
  281. package/src/components/data-display/Sparkline/Sparkline.tsx +971 -0
  282. package/src/components/data-display/Sparkline/Sparkline.types.ts +147 -0
  283. package/src/components/data-display/Sparkline/Sparkline.variants.ts +52 -0
  284. package/src/components/data-display/Sparkline/index.ts +9 -0
  285. package/src/components/data-display/Table/README.md +821 -0
  286. package/src/components/data-display/Table/Table.test.tsx +732 -0
  287. package/src/components/data-display/Table/Table.tsx +123 -0
  288. package/src/components/data-display/Table/Table.types.ts +20 -0
  289. package/src/components/data-display/Table/Table.variants.ts +123 -0
  290. package/src/components/data-display/Table/index.ts +1 -0
  291. package/src/components/data-display/Timeline/README.md +366 -0
  292. package/src/components/data-display/Timeline/Timeline.test.tsx +701 -0
  293. package/src/components/data-display/Timeline/Timeline.tsx +328 -0
  294. package/src/components/data-display/Timeline/Timeline.types.ts +59 -0
  295. package/src/components/data-display/Timeline/Timeline.variants.ts +152 -0
  296. package/src/components/data-display/Timeline/index.ts +15 -0
  297. package/src/components/data-display/Tracker/Tracker.tsx +105 -0
  298. package/src/components/data-display/Tracker/Tracker.types.ts +45 -0
  299. package/src/components/data-display/Tracker/Tracker.variants.ts +24 -0
  300. package/src/components/data-display/Tracker/index.ts +2 -0
  301. package/src/components/data-display/VirtualTable/README.md +383 -0
  302. package/src/components/data-display/VirtualTable/VirtualTable.test.tsx +295 -0
  303. package/src/components/data-display/VirtualTable/VirtualTable.tsx +354 -0
  304. package/src/components/data-display/VirtualTable/VirtualTable.types.ts +62 -0
  305. package/src/components/data-display/VirtualTable/VirtualTable.variants.ts +61 -0
  306. package/src/components/data-display/VirtualTable/index.ts +2 -0
  307. package/src/components/data-display/index.ts +35 -0
  308. package/src/components/feedback/Alert/Alert.test.tsx +614 -0
  309. package/src/components/feedback/Alert/Alert.tsx +48 -0
  310. package/src/components/feedback/Alert/Alert.types.ts +42 -0
  311. package/src/components/feedback/Alert/Alert.variants.ts +20 -0
  312. package/src/components/feedback/Alert/README.md +522 -0
  313. package/src/components/feedback/Alert/index.ts +3 -0
  314. package/src/components/feedback/AlertDialog/AlertDialog.test.tsx +1237 -0
  315. package/src/components/feedback/AlertDialog/AlertDialog.tsx +160 -0
  316. package/src/components/feedback/AlertDialog/AlertDialog.types.ts +139 -0
  317. package/src/components/feedback/AlertDialog/README.md +723 -0
  318. package/src/components/feedback/AlertDialog/index.ts +2 -0
  319. package/src/components/feedback/CLAUDE.md +87 -0
  320. package/src/components/feedback/ConfirmModal/ConfirmModal.test.tsx +404 -0
  321. package/src/components/feedback/ConfirmModal/ConfirmModal.tsx +139 -0
  322. package/src/components/feedback/ConfirmModal/ConfirmModal.types.ts +117 -0
  323. package/src/components/feedback/ConfirmModal/README.md +546 -0
  324. package/src/components/feedback/ConfirmModal/index.ts +2 -0
  325. package/src/components/feedback/Dialog/Dialog.test.tsx +1070 -0
  326. package/src/components/feedback/Dialog/Dialog.tsx +137 -0
  327. package/src/components/feedback/Dialog/Dialog.types.ts +119 -0
  328. package/src/components/feedback/Dialog/README.md +770 -0
  329. package/src/components/feedback/Dialog/index.ts +2 -0
  330. package/src/components/feedback/ErrorPage/ErrorPage.test.tsx +338 -0
  331. package/src/components/feedback/ErrorPage/ErrorPage.tsx +232 -0
  332. package/src/components/feedback/ErrorPage/ErrorPage.types.ts +95 -0
  333. package/src/components/feedback/ErrorPage/README.md +573 -0
  334. package/src/components/feedback/ErrorPage/index.ts +6 -0
  335. package/src/components/feedback/FocusTrap/FocusTrap.test.tsx +378 -0
  336. package/src/components/feedback/FocusTrap/FocusTrap.tsx +115 -0
  337. package/src/components/feedback/FocusTrap/FocusTrap.types.ts +119 -0
  338. package/src/components/feedback/FocusTrap/README.md +571 -0
  339. package/src/components/feedback/FocusTrap/index.ts +2 -0
  340. package/src/components/feedback/Message/Message.test.tsx +143 -0
  341. package/src/components/feedback/Message/Message.tsx +66 -0
  342. package/src/components/feedback/Message/Message.types.ts +44 -0
  343. package/src/components/feedback/Message/Message.variants.ts +24 -0
  344. package/src/components/feedback/Message/README.md +522 -0
  345. package/src/components/feedback/Message/index.ts +2 -0
  346. package/src/components/feedback/Modal/Modal.test.tsx +475 -0
  347. package/src/components/feedback/Modal/Modal.tsx +168 -0
  348. package/src/components/feedback/Modal/Modal.types.ts +91 -0
  349. package/src/components/feedback/Modal/README.md +517 -0
  350. package/src/components/feedback/Modal/index.ts +2 -0
  351. package/src/components/feedback/Notification/Notification.test.tsx +908 -0
  352. package/src/components/feedback/Notification/Notification.tsx +222 -0
  353. package/src/components/feedback/Notification/Notification.types.ts +90 -0
  354. package/src/components/feedback/Notification/Notification.variants.ts +54 -0
  355. package/src/components/feedback/Notification/README.md +602 -0
  356. package/src/components/feedback/Notification/index.ts +11 -0
  357. package/src/components/feedback/Popover/Popover.test.tsx +901 -0
  358. package/src/components/feedback/Popover/Popover.tsx +60 -0
  359. package/src/components/feedback/Popover/Popover.types.ts +158 -0
  360. package/src/components/feedback/Popover/Popover.variants.ts +27 -0
  361. package/src/components/feedback/Popover/README.md +700 -0
  362. package/src/components/feedback/Popover/index.ts +2 -0
  363. package/src/components/feedback/Toast/README.md +613 -0
  364. package/src/components/feedback/Toast/Toast.test.tsx +1116 -0
  365. package/src/components/feedback/Toast/Toast.tsx +44 -0
  366. package/src/components/feedback/Toast/Toast.types.ts +156 -0
  367. package/src/components/feedback/Toast/index.ts +1 -0
  368. package/src/components/feedback/Tooltip/README.md +671 -0
  369. package/src/components/feedback/Tooltip/Tooltip.test.tsx +413 -0
  370. package/src/components/feedback/Tooltip/Tooltip.tsx +110 -0
  371. package/src/components/feedback/Tooltip/Tooltip.types.ts +138 -0
  372. package/src/components/feedback/Tooltip/Tooltip.variants.ts +54 -0
  373. package/src/components/feedback/Tooltip/index.ts +3 -0
  374. package/src/components/feedback/index.ts +13 -0
  375. package/src/components/forms/Autocomplete/Autocomplete.test.tsx +2351 -0
  376. package/src/components/forms/Autocomplete/Autocomplete.tsx +696 -0
  377. package/src/components/forms/Autocomplete/Autocomplete.types.ts +211 -0
  378. package/src/components/forms/Autocomplete/Autocomplete.variants.ts +154 -0
  379. package/src/components/forms/Autocomplete/README.md +919 -0
  380. package/src/components/forms/Autocomplete/index.ts +7 -0
  381. package/src/components/forms/CLAUDE.md +124 -0
  382. package/src/components/forms/Checkbox/Checkbox.test.tsx +475 -0
  383. package/src/components/forms/Checkbox/Checkbox.tsx +35 -0
  384. package/src/components/forms/Checkbox/Checkbox.types.ts +24 -0
  385. package/src/components/forms/Checkbox/Checkbox.variants.ts +46 -0
  386. package/src/components/forms/Checkbox/README.md +861 -0
  387. package/src/components/forms/Checkbox/index.ts +3 -0
  388. package/src/components/forms/CheckboxGroup/CheckboxGroup.test.tsx +338 -0
  389. package/src/components/forms/CheckboxGroup/CheckboxGroup.tsx +212 -0
  390. package/src/components/forms/CheckboxGroup/CheckboxGroup.types.ts +150 -0
  391. package/src/components/forms/CheckboxGroup/CheckboxGroup.variants.ts +85 -0
  392. package/src/components/forms/CheckboxGroup/README.md +124 -0
  393. package/src/components/forms/CheckboxGroup/index.ts +21 -0
  394. package/src/components/forms/ColorPicker/ColorPicker.test.tsx +916 -0
  395. package/src/components/forms/ColorPicker/ColorPicker.tsx +282 -0
  396. package/src/components/forms/ColorPicker/ColorPicker.types.ts +99 -0
  397. package/src/components/forms/ColorPicker/ColorPicker.variants.ts +84 -0
  398. package/src/components/forms/ColorPicker/README.md +809 -0
  399. package/src/components/forms/ColorPicker/index.ts +14 -0
  400. package/src/components/forms/Combobox/Combobox.test.tsx +975 -0
  401. package/src/components/forms/Combobox/Combobox.tsx +194 -0
  402. package/src/components/forms/Combobox/Combobox.types.ts +113 -0
  403. package/src/components/forms/Combobox/Combobox.variants.ts +108 -0
  404. package/src/components/forms/Combobox/README.md +923 -0
  405. package/src/components/forms/Combobox/index.ts +7 -0
  406. package/src/components/forms/DatePicker/DatePicker.test.tsx +1181 -0
  407. package/src/components/forms/DatePicker/DatePicker.tsx +503 -0
  408. package/src/components/forms/DatePicker/DatePicker.types.ts +196 -0
  409. package/src/components/forms/DatePicker/DatePicker.variants.ts +38 -0
  410. package/src/components/forms/DatePicker/README.md +821 -0
  411. package/src/components/forms/DatePicker/index.ts +8 -0
  412. package/src/components/forms/DateRangePicker/DateRangeInput.tsx +139 -0
  413. package/src/components/forms/DateRangePicker/DateRangePicker.test.tsx +1684 -0
  414. package/src/components/forms/DateRangePicker/DateRangePicker.tsx +375 -0
  415. package/src/components/forms/DateRangePicker/DateRangePicker.types.ts +145 -0
  416. package/src/components/forms/DateRangePicker/DateRangePicker.variants.ts +133 -0
  417. package/src/components/forms/DateRangePicker/DateRangePresets.tsx +44 -0
  418. package/src/components/forms/DateRangePicker/index.ts +25 -0
  419. package/src/components/forms/DateRangePicker/presets.ts +104 -0
  420. package/src/components/forms/EmailInput/EmailInput.test.tsx +562 -0
  421. package/src/components/forms/EmailInput/EmailInput.tsx +59 -0
  422. package/src/components/forms/EmailInput/EmailInput.types.ts +46 -0
  423. package/src/components/forms/EmailInput/EmailInput.variants.ts +30 -0
  424. package/src/components/forms/EmailInput/README.md +708 -0
  425. package/src/components/forms/EmailInput/index.ts +6 -0
  426. package/src/components/forms/ErrorMessage/ErrorMessage.test.tsx +457 -0
  427. package/src/components/forms/ErrorMessage/ErrorMessage.tsx +128 -0
  428. package/src/components/forms/ErrorMessage/ErrorMessage.types.ts +54 -0
  429. package/src/components/forms/ErrorMessage/ErrorMessage.variants.ts +78 -0
  430. package/src/components/forms/ErrorMessage/README.md +855 -0
  431. package/src/components/forms/ErrorMessage/index.ts +4 -0
  432. package/src/components/forms/Field/Field.test.tsx +811 -0
  433. package/src/components/forms/Field/Field.tsx +195 -0
  434. package/src/components/forms/Field/Field.types.ts +94 -0
  435. package/src/components/forms/Field/Field.variants.ts +114 -0
  436. package/src/components/forms/Field/README.md +931 -0
  437. package/src/components/forms/Field/index.ts +3 -0
  438. package/src/components/forms/FloatLabel/FloatLabel.test.tsx +248 -0
  439. package/src/components/forms/FloatLabel/FloatLabel.tsx +110 -0
  440. package/src/components/forms/FloatLabel/FloatLabel.types.ts +37 -0
  441. package/src/components/forms/FloatLabel/index.ts +2 -0
  442. package/src/components/forms/Form/Form.test.tsx +1167 -0
  443. package/src/components/forms/Form/Form.tsx +170 -0
  444. package/src/components/forms/Form/Form.types.ts +126 -0
  445. package/src/components/forms/Form/Form.variants.ts +81 -0
  446. package/src/components/forms/Form/README.md +787 -0
  447. package/src/components/forms/Form/index.ts +3 -0
  448. package/src/components/forms/FormValidation/FormValidation.test.tsx +376 -0
  449. package/src/components/forms/FormValidation/FormValidation.tsx +99 -0
  450. package/src/components/forms/FormValidation/FormValidation.types.ts +37 -0
  451. package/src/components/forms/FormValidation/FormValidation.variants.ts +24 -0
  452. package/src/components/forms/FormValidation/README.md +592 -0
  453. package/src/components/forms/FormValidation/index.ts +4 -0
  454. package/src/components/forms/HelpText/HelpText.test.tsx +558 -0
  455. package/src/components/forms/HelpText/HelpText.tsx +111 -0
  456. package/src/components/forms/HelpText/HelpText.types.ts +51 -0
  457. package/src/components/forms/HelpText/HelpText.variants.ts +54 -0
  458. package/src/components/forms/HelpText/README.md +739 -0
  459. package/src/components/forms/HelpText/index.ts +4 -0
  460. package/src/components/forms/IftaLabel/IftaLabel.test.tsx +193 -0
  461. package/src/components/forms/IftaLabel/IftaLabel.tsx +72 -0
  462. package/src/components/forms/IftaLabel/IftaLabel.types.ts +18 -0
  463. package/src/components/forms/IftaLabel/index.ts +2 -0
  464. package/src/components/forms/InputGroup/InputGroup.test.tsx +782 -0
  465. package/src/components/forms/InputGroup/InputGroup.tsx +128 -0
  466. package/src/components/forms/InputGroup/InputGroup.types.ts +66 -0
  467. package/src/components/forms/InputGroup/InputGroup.variants.ts +102 -0
  468. package/src/components/forms/InputGroup/README.md +845 -0
  469. package/src/components/forms/InputGroup/index.ts +24 -0
  470. package/src/components/forms/InputOTP/InputOTP.test.tsx +793 -0
  471. package/src/components/forms/InputOTP/InputOTP.tsx +90 -0
  472. package/src/components/forms/InputOTP/InputOTP.types.ts +74 -0
  473. package/src/components/forms/InputOTP/InputOTP.variants.ts +64 -0
  474. package/src/components/forms/InputOTP/README.md +1149 -0
  475. package/src/components/forms/InputOTP/index.ts +18 -0
  476. package/src/components/forms/InputOTPField/InputOTPField.test.tsx +220 -0
  477. package/src/components/forms/InputOTPField/InputOTPField.tsx +148 -0
  478. package/src/components/forms/InputOTPField/InputOTPField.types.ts +91 -0
  479. package/src/components/forms/InputOTPField/InputOTPField.variants.ts +83 -0
  480. package/src/components/forms/InputOTPField/README.md +195 -0
  481. package/src/components/forms/InputOTPField/index.ts +12 -0
  482. package/src/components/forms/MultiSelect/MultiSelect.test.tsx +1036 -0
  483. package/src/components/forms/MultiSelect/MultiSelect.tsx +291 -0
  484. package/src/components/forms/MultiSelect/MultiSelect.types.ts +147 -0
  485. package/src/components/forms/MultiSelect/MultiSelect.variants.ts +132 -0
  486. package/src/components/forms/MultiSelect/README.md +897 -0
  487. package/src/components/forms/MultiSelect/index.ts +7 -0
  488. package/src/components/forms/NativeSelect/NativeSelect.test.tsx +856 -0
  489. package/src/components/forms/NativeSelect/NativeSelect.tsx +75 -0
  490. package/src/components/forms/NativeSelect/NativeSelect.types.ts +17 -0
  491. package/src/components/forms/NativeSelect/NativeSelect.variants.ts +106 -0
  492. package/src/components/forms/NativeSelect/README.md +1033 -0
  493. package/src/components/forms/NativeSelect/index.ts +3 -0
  494. package/src/components/forms/NumberInput/NumberInput.test.tsx +636 -0
  495. package/src/components/forms/NumberInput/NumberInput.tsx +131 -0
  496. package/src/components/forms/NumberInput/NumberInput.types.ts +45 -0
  497. package/src/components/forms/NumberInput/NumberInput.variants.ts +85 -0
  498. package/src/components/forms/NumberInput/README.md +766 -0
  499. package/src/components/forms/NumberInput/index.ts +9 -0
  500. package/src/components/forms/PasswordInput/PasswordInput.test.tsx +525 -0
  501. package/src/components/forms/PasswordInput/PasswordInput.tsx +67 -0
  502. package/src/components/forms/PasswordInput/PasswordInput.types.ts +35 -0
  503. package/src/components/forms/PasswordInput/PasswordInput.variants.ts +34 -0
  504. package/src/components/forms/PasswordInput/README.md +698 -0
  505. package/src/components/forms/PasswordInput/index.ts +6 -0
  506. package/src/components/forms/PaymentInput/PaymentInput.test.tsx +252 -0
  507. package/src/components/forms/PaymentInput/PaymentInput.tsx +178 -0
  508. package/src/components/forms/PaymentInput/PaymentInput.types.ts +69 -0
  509. package/src/components/forms/PaymentInput/PaymentInput.variants.ts +81 -0
  510. package/src/components/forms/PaymentInput/README.md +263 -0
  511. package/src/components/forms/PaymentInput/card-utils.ts +219 -0
  512. package/src/components/forms/PaymentInput/index.ts +23 -0
  513. package/src/components/forms/PhoneInput/PhoneInput.test.tsx +270 -0
  514. package/src/components/forms/PhoneInput/PhoneInput.tsx +215 -0
  515. package/src/components/forms/PhoneInput/PhoneInput.types.ts +74 -0
  516. package/src/components/forms/PhoneInput/PhoneInput.variants.ts +103 -0
  517. package/src/components/forms/PhoneInput/README.md +258 -0
  518. package/src/components/forms/PhoneInput/countries.ts +134 -0
  519. package/src/components/forms/PhoneInput/index.ts +22 -0
  520. package/src/components/forms/RadioButton/README.md +832 -0
  521. package/src/components/forms/RadioButton/RadioButton.test.tsx +583 -0
  522. package/src/components/forms/RadioButton/RadioButton.tsx +82 -0
  523. package/src/components/forms/RadioButton/RadioButton.types.ts +23 -0
  524. package/src/components/forms/RadioButton/RadioButton.variants.ts +80 -0
  525. package/src/components/forms/RadioButton/index.ts +15 -0
  526. package/src/components/forms/RadioCardGroup/RadioCardGroup.tsx +130 -0
  527. package/src/components/forms/RadioCardGroup/RadioCardGroup.types.ts +66 -0
  528. package/src/components/forms/RadioCardGroup/RadioCardGroup.variants.ts +131 -0
  529. package/src/components/forms/RadioCardGroup/index.ts +3 -0
  530. package/src/components/forms/RadioGroup/README.md +908 -0
  531. package/src/components/forms/RadioGroup/RadioGroup.test.tsx +764 -0
  532. package/src/components/forms/RadioGroup/RadioGroup.tsx +75 -0
  533. package/src/components/forms/RadioGroup/RadioGroup.types.ts +36 -0
  534. package/src/components/forms/RadioGroup/RadioGroup.variants.ts +58 -0
  535. package/src/components/forms/RadioGroup/index.ts +15 -0
  536. package/src/components/forms/Rating/README.md +729 -0
  537. package/src/components/forms/Rating/Rating.test.tsx +729 -0
  538. package/src/components/forms/Rating/Rating.tsx +258 -0
  539. package/src/components/forms/Rating/Rating.types.ts +89 -0
  540. package/src/components/forms/Rating/Rating.variants.ts +56 -0
  541. package/src/components/forms/Rating/index.ts +8 -0
  542. package/src/components/forms/SearchInput/README.md +729 -0
  543. package/src/components/forms/SearchInput/SearchInput.test.tsx +579 -0
  544. package/src/components/forms/SearchInput/SearchInput.tsx +103 -0
  545. package/src/components/forms/SearchInput/SearchInput.types.ts +40 -0
  546. package/src/components/forms/SearchInput/SearchInput.variants.ts +51 -0
  547. package/src/components/forms/SearchInput/index.ts +8 -0
  548. package/src/components/forms/Select/README.md +1286 -0
  549. package/src/components/forms/Select/Select.test.tsx +1136 -0
  550. package/src/components/forms/Select/Select.tsx +170 -0
  551. package/src/components/forms/Select/Select.types.ts +75 -0
  552. package/src/components/forms/Select/Select.variants.ts +133 -0
  553. package/src/components/forms/Select/index.ts +3 -0
  554. package/src/components/forms/Slider/README.md +1246 -0
  555. package/src/components/forms/Slider/Slider.test.tsx +731 -0
  556. package/src/components/forms/Slider/Slider.tsx +235 -0
  557. package/src/components/forms/Slider/Slider.types.ts +90 -0
  558. package/src/components/forms/Slider/Slider.variants.ts +239 -0
  559. package/src/components/forms/Slider/index.ts +34 -0
  560. package/src/components/forms/SuccessMessage/README.md +534 -0
  561. package/src/components/forms/SuccessMessage/SuccessMessage.test.tsx +257 -0
  562. package/src/components/forms/SuccessMessage/SuccessMessage.tsx +43 -0
  563. package/src/components/forms/SuccessMessage/SuccessMessage.types.ts +11 -0
  564. package/src/components/forms/SuccessMessage/SuccessMessage.variants.ts +15 -0
  565. package/src/components/forms/SuccessMessage/index.ts +4 -0
  566. package/src/components/forms/Switch/README.md +785 -0
  567. package/src/components/forms/Switch/Switch.test.tsx +636 -0
  568. package/src/components/forms/Switch/Switch.tsx +28 -0
  569. package/src/components/forms/Switch/Switch.types.ts +24 -0
  570. package/src/components/forms/Switch/Switch.variants.ts +49 -0
  571. package/src/components/forms/Switch/index.ts +3 -0
  572. package/src/components/forms/TagsInput/README.md +216 -0
  573. package/src/components/forms/TagsInput/TagsInput.test.tsx +308 -0
  574. package/src/components/forms/TagsInput/TagsInput.tsx +189 -0
  575. package/src/components/forms/TagsInput/TagsInput.types.ts +85 -0
  576. package/src/components/forms/TagsInput/TagsInput.variants.ts +58 -0
  577. package/src/components/forms/TagsInput/index.ts +12 -0
  578. package/src/components/forms/TextInput/README.md +871 -0
  579. package/src/components/forms/TextInput/TextInput.test.tsx +484 -0
  580. package/src/components/forms/TextInput/TextInput.tsx +76 -0
  581. package/src/components/forms/TextInput/TextInput.types.ts +61 -0
  582. package/src/components/forms/TextInput/TextInput.variants.ts +117 -0
  583. package/src/components/forms/TextInput/index.ts +14 -0
  584. package/src/components/forms/Textarea/README.md +905 -0
  585. package/src/components/forms/Textarea/Textarea.test.tsx +482 -0
  586. package/src/components/forms/Textarea/Textarea.tsx +24 -0
  587. package/src/components/forms/Textarea/Textarea.types.ts +39 -0
  588. package/src/components/forms/Textarea/Textarea.variants.ts +48 -0
  589. package/src/components/forms/Textarea/index.ts +3 -0
  590. package/src/components/forms/TextareaField/README.md +172 -0
  591. package/src/components/forms/TextareaField/TextareaField.test.tsx +260 -0
  592. package/src/components/forms/TextareaField/TextareaField.tsx +73 -0
  593. package/src/components/forms/TextareaField/TextareaField.types.ts +37 -0
  594. package/src/components/forms/TextareaField/TextareaField.variants.ts +83 -0
  595. package/src/components/forms/TextareaField/index.ts +12 -0
  596. package/src/components/forms/TimePicker/README.md +750 -0
  597. package/src/components/forms/TimePicker/TimePicker.test.tsx +780 -0
  598. package/src/components/forms/TimePicker/TimePicker.tsx +383 -0
  599. package/src/components/forms/TimePicker/TimePicker.types.ts +94 -0
  600. package/src/components/forms/TimePicker/TimePicker.variants.ts +83 -0
  601. package/src/components/forms/TimePicker/index.ts +14 -0
  602. package/src/components/forms/ToggleGroup/README.md +870 -0
  603. package/src/components/forms/ToggleGroup/ToggleGroup.test.tsx +941 -0
  604. package/src/components/forms/ToggleGroup/ToggleGroup.tsx +5 -0
  605. package/src/components/forms/ToggleGroup/ToggleGroup.types.ts +17 -0
  606. package/src/components/forms/ToggleGroup/ToggleGroup.variants.ts +42 -0
  607. package/src/components/forms/ToggleGroup/index.ts +9 -0
  608. package/src/components/forms/URLInput/README.md +701 -0
  609. package/src/components/forms/URLInput/URLInput.test.tsx +602 -0
  610. package/src/components/forms/URLInput/URLInput.tsx +71 -0
  611. package/src/components/forms/URLInput/URLInput.types.ts +51 -0
  612. package/src/components/forms/URLInput/URLInput.variants.ts +52 -0
  613. package/src/components/forms/URLInput/index.ts +8 -0
  614. package/src/components/forms/index.ts +44 -0
  615. package/src/components/index.ts +26 -0
  616. package/src/components/layout/AppContent/AppContent.test.tsx +34 -0
  617. package/src/components/layout/AppContent/AppContent.tsx +23 -0
  618. package/src/components/layout/AppContent/AppContent.variants.ts +23 -0
  619. package/src/components/layout/AppContent/index.ts +2 -0
  620. package/src/components/layout/AppHeader/AppHeader.test.tsx +26 -0
  621. package/src/components/layout/AppHeader/AppHeader.tsx +17 -0
  622. package/src/components/layout/AppHeader/AppHeader.variants.ts +21 -0
  623. package/src/components/layout/AppHeader/AppHeaderActions.tsx +13 -0
  624. package/src/components/layout/AppHeader/AppHeaderNav.tsx +13 -0
  625. package/src/components/layout/AppHeader/AppHeaderTitle.tsx +13 -0
  626. package/src/components/layout/AppHeader/index.ts +5 -0
  627. package/src/components/layout/AppRail/AppRail.test.tsx +50 -0
  628. package/src/components/layout/AppRail/AppRail.tsx +24 -0
  629. package/src/components/layout/AppRail/AppRail.variants.ts +31 -0
  630. package/src/components/layout/AppRail/AppRailFooter.tsx +13 -0
  631. package/src/components/layout/AppRail/AppRailGroup.tsx +13 -0
  632. package/src/components/layout/AppRail/AppRailHeader.tsx +13 -0
  633. package/src/components/layout/AppRail/AppRailItem.tsx +57 -0
  634. package/src/components/layout/AppRail/index.ts +5 -0
  635. package/src/components/layout/AppShell/AppShell.context.tsx +34 -0
  636. package/src/components/layout/AppShell/AppShell.test.tsx +61 -0
  637. package/src/components/layout/AppShell/AppShell.tsx +91 -0
  638. package/src/components/layout/AppShell/AppShell.variants.ts +21 -0
  639. package/src/components/layout/AppShell/index.ts +2 -0
  640. package/src/components/layout/AppSidebar/AppSidebar.test.tsx +69 -0
  641. package/src/components/layout/AppSidebar/AppSidebar.tsx +58 -0
  642. package/src/components/layout/AppSidebar/AppSidebar.variants.ts +41 -0
  643. package/src/components/layout/AppSidebar/AppSidebarContent.tsx +18 -0
  644. package/src/components/layout/AppSidebar/AppSidebarFooter.tsx +13 -0
  645. package/src/components/layout/AppSidebar/AppSidebarGroup.tsx +22 -0
  646. package/src/components/layout/AppSidebar/AppSidebarHeader.tsx +13 -0
  647. package/src/components/layout/AppSidebar/AppSidebarItem.tsx +54 -0
  648. package/src/components/layout/AppSidebar/AppSidebarTrigger.tsx +25 -0
  649. package/src/components/layout/AppSidebar/index.ts +7 -0
  650. package/src/components/layout/CLAUDE.md +112 -0
  651. package/src/components/layout/Card/Card.test.tsx +339 -0
  652. package/src/components/layout/Card/Card.tsx +102 -0
  653. package/src/components/layout/Card/Card.types.ts +52 -0
  654. package/src/components/layout/Card/Card.variants.ts +85 -0
  655. package/src/components/layout/Card/README.md +994 -0
  656. package/src/components/layout/Card/index.ts +3 -0
  657. package/src/components/layout/Collapsible/Collapsible.test.tsx +491 -0
  658. package/src/components/layout/Collapsible/Collapsible.tsx +50 -0
  659. package/src/components/layout/Collapsible/Collapsible.types.ts +26 -0
  660. package/src/components/layout/Collapsible/Collapsible.variants.ts +52 -0
  661. package/src/components/layout/Collapsible/README.md +885 -0
  662. package/src/components/layout/Collapsible/index.ts +3 -0
  663. package/src/components/layout/Container/Container.test.tsx +283 -0
  664. package/src/components/layout/Container/Container.tsx +25 -0
  665. package/src/components/layout/Container/Container.types.ts +36 -0
  666. package/src/components/layout/Container/Container.variants.ts +59 -0
  667. package/src/components/layout/Container/README.md +700 -0
  668. package/src/components/layout/Container/index.ts +3 -0
  669. package/src/components/layout/Flex/Flex.test.tsx +545 -0
  670. package/src/components/layout/Flex/Flex.tsx +52 -0
  671. package/src/components/layout/Flex/Flex.types.ts +61 -0
  672. package/src/components/layout/Flex/Flex.variants.ts +98 -0
  673. package/src/components/layout/Flex/README.md +812 -0
  674. package/src/components/layout/Flex/index.ts +3 -0
  675. package/src/components/layout/Grid/Grid.test.tsx +601 -0
  676. package/src/components/layout/Grid/Grid.tsx +61 -0
  677. package/src/components/layout/Grid/Grid.types.ts +47 -0
  678. package/src/components/layout/Grid/Grid.variants.ts +100 -0
  679. package/src/components/layout/Grid/README.md +762 -0
  680. package/src/components/layout/Grid/index.ts +3 -0
  681. package/src/components/layout/PageContent/PageContent.tsx +13 -0
  682. package/src/components/layout/PageContent/index.ts +1 -0
  683. package/src/components/layout/PageHeader/PageHeader.tsx +43 -0
  684. package/src/components/layout/PageHeader/index.ts +1 -0
  685. package/src/components/layout/PageSection/PageSection.tsx +28 -0
  686. package/src/components/layout/PageSection/index.ts +1 -0
  687. package/src/components/layout/Panel/Panel.test.tsx +427 -0
  688. package/src/components/layout/Panel/Panel.tsx +75 -0
  689. package/src/components/layout/Panel/Panel.types.ts +59 -0
  690. package/src/components/layout/Panel/Panel.variants.ts +94 -0
  691. package/src/components/layout/Panel/README.md +861 -0
  692. package/src/components/layout/Panel/index.ts +3 -0
  693. package/src/components/layout/ResizablePanels/README.md +369 -0
  694. package/src/components/layout/ResizablePanels/ResizablePanels.test.tsx +506 -0
  695. package/src/components/layout/ResizablePanels/ResizablePanels.tsx +64 -0
  696. package/src/components/layout/ResizablePanels/ResizablePanels.types.ts +41 -0
  697. package/src/components/layout/ResizablePanels/ResizablePanels.variants.ts +67 -0
  698. package/src/components/layout/ResizablePanels/index.ts +3 -0
  699. package/src/components/layout/ResponsiveContainer/README.md +267 -0
  700. package/src/components/layout/ResponsiveContainer/ResponsiveContainer.test.tsx +386 -0
  701. package/src/components/layout/ResponsiveContainer/ResponsiveContainer.tsx +54 -0
  702. package/src/components/layout/ResponsiveContainer/ResponsiveContainer.types.ts +43 -0
  703. package/src/components/layout/ResponsiveContainer/ResponsiveContainer.variants.ts +106 -0
  704. package/src/components/layout/ResponsiveContainer/index.ts +3 -0
  705. package/src/components/layout/ScrollArea/README.md +278 -0
  706. package/src/components/layout/ScrollArea/ScrollArea.test.tsx +352 -0
  707. package/src/components/layout/ScrollArea/ScrollArea.tsx +61 -0
  708. package/src/components/layout/ScrollArea/ScrollArea.types.ts +36 -0
  709. package/src/components/layout/ScrollArea/ScrollArea.variants.ts +85 -0
  710. package/src/components/layout/ScrollArea/index.ts +3 -0
  711. package/src/components/layout/Section/README.md +315 -0
  712. package/src/components/layout/Section/Section.test.tsx +293 -0
  713. package/src/components/layout/Section/Section.tsx +60 -0
  714. package/src/components/layout/Section/Section.types.ts +38 -0
  715. package/src/components/layout/Section/Section.variants.ts +45 -0
  716. package/src/components/layout/Section/index.ts +3 -0
  717. package/src/components/layout/Sheet/README.md +533 -0
  718. package/src/components/layout/Sheet/Sheet.test.tsx +702 -0
  719. package/src/components/layout/Sheet/Sheet.tsx +142 -0
  720. package/src/components/layout/Sheet/Sheet.types.ts +92 -0
  721. package/src/components/layout/Sheet/Sheet.variants.ts +98 -0
  722. package/src/components/layout/Sheet/index.ts +3 -0
  723. package/src/components/layout/Stack/README.md +346 -0
  724. package/src/components/layout/Stack/Stack.test.tsx +492 -0
  725. package/src/components/layout/Stack/Stack.tsx +58 -0
  726. package/src/components/layout/Stack/Stack.types.ts +58 -0
  727. package/src/components/layout/Stack/Stack.variants.ts +77 -0
  728. package/src/components/layout/Stack/index.ts +3 -0
  729. package/src/components/layout/index.ts +21 -0
  730. package/src/components/navigation/Breadcrumb/Breadcrumb.test.tsx +875 -0
  731. package/src/components/navigation/Breadcrumb/Breadcrumb.tsx +183 -0
  732. package/src/components/navigation/Breadcrumb/Breadcrumb.types.ts +49 -0
  733. package/src/components/navigation/Breadcrumb/Breadcrumb.variants.ts +63 -0
  734. package/src/components/navigation/Breadcrumb/README.md +608 -0
  735. package/src/components/navigation/Breadcrumb/index.ts +24 -0
  736. package/src/components/navigation/CLAUDE.md +118 -0
  737. package/src/components/navigation/ContextMenu/ContextMenu.test.tsx +881 -0
  738. package/src/components/navigation/ContextMenu/ContextMenu.tsx +304 -0
  739. package/src/components/navigation/ContextMenu/ContextMenu.types.ts +119 -0
  740. package/src/components/navigation/ContextMenu/ContextMenu.variants.ts +167 -0
  741. package/src/components/navigation/ContextMenu/README.md +660 -0
  742. package/src/components/navigation/ContextMenu/index.ts +34 -0
  743. package/src/components/navigation/Drawer/Drawer.test.tsx +721 -0
  744. package/src/components/navigation/Drawer/Drawer.tsx +178 -0
  745. package/src/components/navigation/Drawer/Drawer.types.ts +66 -0
  746. package/src/components/navigation/Drawer/Drawer.variants.ts +121 -0
  747. package/src/components/navigation/Drawer/README.md +723 -0
  748. package/src/components/navigation/Drawer/index.ts +24 -0
  749. package/src/components/navigation/DropdownMenu/DropdownMenu.test.tsx +881 -0
  750. package/src/components/navigation/DropdownMenu/DropdownMenu.tsx +305 -0
  751. package/src/components/navigation/DropdownMenu/DropdownMenu.types.ts +98 -0
  752. package/src/components/navigation/DropdownMenu/DropdownMenu.variants.ts +168 -0
  753. package/src/components/navigation/DropdownMenu/README.md +676 -0
  754. package/src/components/navigation/DropdownMenu/index.ts +33 -0
  755. package/src/components/navigation/Header/Header.test.tsx +418 -0
  756. package/src/components/navigation/Header/Header.tsx +133 -0
  757. package/src/components/navigation/Header/Header.types.ts +41 -0
  758. package/src/components/navigation/Header/Header.variants.ts +91 -0
  759. package/src/components/navigation/Header/README.md +567 -0
  760. package/src/components/navigation/Header/index.ts +14 -0
  761. package/src/components/navigation/Menu/Menu.test.tsx +658 -0
  762. package/src/components/navigation/Menu/Menu.tsx +247 -0
  763. package/src/components/navigation/Menu/Menu.types.ts +51 -0
  764. package/src/components/navigation/Menu/Menu.variants.ts +105 -0
  765. package/src/components/navigation/Menu/README.md +599 -0
  766. package/src/components/navigation/Menu/index.ts +17 -0
  767. package/src/components/navigation/Menubar/Menubar.test.tsx +1028 -0
  768. package/src/components/navigation/Menubar/Menubar.tsx +308 -0
  769. package/src/components/navigation/Menubar/Menubar.types.ts +104 -0
  770. package/src/components/navigation/Menubar/Menubar.variants.ts +182 -0
  771. package/src/components/navigation/Menubar/README.md +641 -0
  772. package/src/components/navigation/Menubar/index.ts +36 -0
  773. package/src/components/navigation/MobileSidebar/MobileSidebar.test.tsx +255 -0
  774. package/src/components/navigation/MobileSidebar/MobileSidebar.tsx +187 -0
  775. package/src/components/navigation/MobileSidebar/MobileSidebar.types.ts +62 -0
  776. package/src/components/navigation/MobileSidebar/MobileSidebar.variants.ts +79 -0
  777. package/src/components/navigation/MobileSidebar/index.ts +17 -0
  778. package/src/components/navigation/Navbar/Navbar.test.tsx +621 -0
  779. package/src/components/navigation/Navbar/Navbar.tsx +238 -0
  780. package/src/components/navigation/Navbar/Navbar.types.ts +69 -0
  781. package/src/components/navigation/Navbar/Navbar.variants.ts +176 -0
  782. package/src/components/navigation/Navbar/README.md +670 -0
  783. package/src/components/navigation/Navbar/index.ts +20 -0
  784. package/src/components/navigation/NavigationMenu/NavigationMenu.test.tsx +701 -0
  785. package/src/components/navigation/NavigationMenu/NavigationMenu.tsx +211 -0
  786. package/src/components/navigation/NavigationMenu/NavigationMenu.types.ts +52 -0
  787. package/src/components/navigation/NavigationMenu/NavigationMenu.variants.ts +122 -0
  788. package/src/components/navigation/NavigationMenu/README.md +697 -0
  789. package/src/components/navigation/NavigationMenu/index.ts +23 -0
  790. package/src/components/navigation/Pagination/Pagination.test.tsx +619 -0
  791. package/src/components/navigation/Pagination/Pagination.tsx +185 -0
  792. package/src/components/navigation/Pagination/Pagination.types.ts +42 -0
  793. package/src/components/navigation/Pagination/Pagination.variants.ts +36 -0
  794. package/src/components/navigation/Pagination/README.md +635 -0
  795. package/src/components/navigation/Pagination/index.ts +17 -0
  796. package/src/components/navigation/Sidebar/README.md +628 -0
  797. package/src/components/navigation/Sidebar/Sidebar.test.tsx +1169 -0
  798. package/src/components/navigation/Sidebar/Sidebar.tsx +761 -0
  799. package/src/components/navigation/Sidebar/Sidebar.types.ts +168 -0
  800. package/src/components/navigation/Sidebar/Sidebar.variants.ts +302 -0
  801. package/src/components/navigation/Sidebar/index.ts +59 -0
  802. package/src/components/navigation/SkipLinks/README.md +512 -0
  803. package/src/components/navigation/SkipLinks/SkipLinks.test.tsx +445 -0
  804. package/src/components/navigation/SkipLinks/SkipLinks.tsx +103 -0
  805. package/src/components/navigation/SkipLinks/SkipLinks.types.ts +39 -0
  806. package/src/components/navigation/SkipLinks/SkipLinks.variants.ts +102 -0
  807. package/src/components/navigation/SkipLinks/index.ts +12 -0
  808. package/src/components/navigation/TabNavigation/TabNavigation.tsx +196 -0
  809. package/src/components/navigation/TabNavigation/TabNavigation.types.ts +85 -0
  810. package/src/components/navigation/TabNavigation/TabNavigation.variants.ts +95 -0
  811. package/src/components/navigation/TabNavigation/index.ts +10 -0
  812. package/src/components/navigation/TabPanel/README.md +437 -0
  813. package/src/components/navigation/TabPanel/TabPanel.test.tsx +566 -0
  814. package/src/components/navigation/TabPanel/TabPanel.tsx +95 -0
  815. package/src/components/navigation/TabPanel/TabPanel.types.ts +29 -0
  816. package/src/components/navigation/TabPanel/TabPanel.variants.ts +61 -0
  817. package/src/components/navigation/TabPanel/index.ts +13 -0
  818. package/src/components/navigation/Tabs/README.md +669 -0
  819. package/src/components/navigation/Tabs/Tabs.test.tsx +500 -0
  820. package/src/components/navigation/Tabs/Tabs.tsx +112 -0
  821. package/src/components/navigation/Tabs/Tabs.types.ts +38 -0
  822. package/src/components/navigation/Tabs/Tabs.variants.ts +80 -0
  823. package/src/components/navigation/Tabs/index.ts +14 -0
  824. package/src/components/navigation/Toolbar/README.md +650 -0
  825. package/src/components/navigation/Toolbar/Toolbar.test.tsx +620 -0
  826. package/src/components/navigation/Toolbar/Toolbar.tsx +133 -0
  827. package/src/components/navigation/Toolbar/Toolbar.types.ts +42 -0
  828. package/src/components/navigation/Toolbar/Toolbar.variants.ts +95 -0
  829. package/src/components/navigation/Toolbar/index.ts +17 -0
  830. package/src/components/navigation/UserProfileDropdown/UserProfileDropdown.test.tsx +257 -0
  831. package/src/components/navigation/UserProfileDropdown/UserProfileDropdown.tsx +267 -0
  832. package/src/components/navigation/UserProfileDropdown/UserProfileDropdown.types.ts +84 -0
  833. package/src/components/navigation/UserProfileDropdown/UserProfileDropdown.variants.ts +77 -0
  834. package/src/components/navigation/UserProfileDropdown/index.ts +17 -0
  835. package/src/components/navigation/WorkspaceDropdown/WorkspaceDropdown.tsx +190 -0
  836. package/src/components/navigation/WorkspaceDropdown/WorkspaceDropdown.types.ts +56 -0
  837. package/src/components/navigation/WorkspaceDropdown/WorkspaceDropdown.variants.ts +82 -0
  838. package/src/components/navigation/WorkspaceDropdown/index.ts +20 -0
  839. package/src/components/navigation/index.ts +17 -0
  840. package/src/components/primitives/ArrowAnimated/ArrowAnimated.test.tsx +240 -0
  841. package/src/components/primitives/ArrowAnimated/ArrowAnimated.tsx +96 -0
  842. package/src/components/primitives/ArrowAnimated/ArrowAnimated.types.ts +16 -0
  843. package/src/components/primitives/ArrowAnimated/ArrowAnimated.variants.ts +43 -0
  844. package/src/components/primitives/ArrowAnimated/index.ts +9 -0
  845. package/src/components/primitives/AspectRatio/AspectRatio.test.tsx +306 -0
  846. package/src/components/primitives/AspectRatio/AspectRatio.tsx +11 -0
  847. package/src/components/primitives/AspectRatio/AspectRatio.types.ts +57 -0
  848. package/src/components/primitives/AspectRatio/AspectRatio.variants.ts +110 -0
  849. package/src/components/primitives/AspectRatio/README.md +914 -0
  850. package/src/components/primitives/AspectRatio/index.ts +7 -0
  851. package/src/components/primitives/Avatar/Avatar.test.tsx +1311 -0
  852. package/src/components/primitives/Avatar/Avatar.tsx +159 -0
  853. package/src/components/primitives/Avatar/Avatar.types.ts +70 -0
  854. package/src/components/primitives/Avatar/AvatarAddButton.tsx +59 -0
  855. package/src/components/primitives/Avatar/AvatarBadge.tsx +84 -0
  856. package/src/components/primitives/Avatar/AvatarGroup.test.tsx +1377 -0
  857. package/src/components/primitives/Avatar/AvatarGroup.tsx +101 -0
  858. package/src/components/primitives/Avatar/AvatarLabelGroup.tsx +160 -0
  859. package/src/components/primitives/Avatar/AvatarSkeleton.tsx +76 -0
  860. package/src/components/primitives/Avatar/AvatarStatus.tsx +71 -0
  861. package/src/components/primitives/Avatar/README.md +1174 -0
  862. package/src/components/primitives/Avatar/index.ts +8 -0
  863. package/src/components/primitives/Badge/Badge.test.tsx +1146 -0
  864. package/src/components/primitives/Badge/Badge.tsx +389 -0
  865. package/src/components/primitives/Badge/Badge.types.ts +102 -0
  866. package/src/components/primitives/Badge/README.md +814 -0
  867. package/src/components/primitives/Badge/index.ts +2 -0
  868. package/src/components/primitives/Button/Button.test.tsx +626 -0
  869. package/src/components/primitives/Button/Button.tsx +299 -0
  870. package/src/components/primitives/Button/Button.types.ts +137 -0
  871. package/src/components/primitives/Button/README.md +1112 -0
  872. package/src/components/primitives/Button/index.ts +8 -0
  873. package/src/components/primitives/ButtonGroup/ButtonGroup.test.tsx +945 -0
  874. package/src/components/primitives/ButtonGroup/ButtonGroup.tsx +224 -0
  875. package/src/components/primitives/ButtonGroup/ButtonGroup.types.ts +133 -0
  876. package/src/components/primitives/ButtonGroup/README.md +945 -0
  877. package/src/components/primitives/ButtonGroup/index.ts +12 -0
  878. package/src/components/primitives/CLAUDE.md +108 -0
  879. package/src/components/primitives/ConfirmButton/ConfirmButton.test.tsx +929 -0
  880. package/src/components/primitives/ConfirmButton/ConfirmButton.tsx +298 -0
  881. package/src/components/primitives/ConfirmButton/ConfirmButton.types.ts +116 -0
  882. package/src/components/primitives/ConfirmButton/README.md +1059 -0
  883. package/src/components/primitives/ConfirmButton/index.ts +6 -0
  884. package/src/components/primitives/Divider/Divider.test.tsx +304 -0
  885. package/src/components/primitives/Divider/Divider.tsx +209 -0
  886. package/src/components/primitives/Divider/Divider.types.ts +74 -0
  887. package/src/components/primitives/Divider/README.md +839 -0
  888. package/src/components/primitives/Divider/index.ts +8 -0
  889. package/src/components/primitives/Heading/Heading.test.tsx +611 -0
  890. package/src/components/primitives/Heading/Heading.tsx +120 -0
  891. package/src/components/primitives/Heading/Heading.types.ts +61 -0
  892. package/src/components/primitives/Heading/README.md +820 -0
  893. package/src/components/primitives/Heading/index.ts +2 -0
  894. package/src/components/primitives/Icon/Icon.test.tsx +466 -0
  895. package/src/components/primitives/Icon/Icon.tsx +74 -0
  896. package/src/components/primitives/Icon/Icon.types.ts +61 -0
  897. package/src/components/primitives/Icon/README.md +759 -0
  898. package/src/components/primitives/Icon/index.ts +8 -0
  899. package/src/components/primitives/Image/Image.test.tsx +734 -0
  900. package/src/components/primitives/Image/Image.tsx +239 -0
  901. package/src/components/primitives/Image/Image.types.ts +75 -0
  902. package/src/components/primitives/Image/README.md +863 -0
  903. package/src/components/primitives/Image/index.ts +8 -0
  904. package/src/components/primitives/Kbd/Kbd.test.tsx +432 -0
  905. package/src/components/primitives/Kbd/Kbd.tsx +53 -0
  906. package/src/components/primitives/Kbd/Kbd.types.ts +55 -0
  907. package/src/components/primitives/Kbd/Kbd.variants.ts +33 -0
  908. package/src/components/primitives/Kbd/README.md +659 -0
  909. package/src/components/primitives/Kbd/index.ts +3 -0
  910. package/src/components/primitives/Label/Label.test.tsx +311 -0
  911. package/src/components/primitives/Label/Label.tsx +46 -0
  912. package/src/components/primitives/Label/Label.types.ts +28 -0
  913. package/src/components/primitives/Label/README.md +816 -0
  914. package/src/components/primitives/Label/index.ts +2 -0
  915. package/src/components/primitives/Link/Link.test.tsx +764 -0
  916. package/src/components/primitives/Link/Link.tsx +143 -0
  917. package/src/components/primitives/Link/Link.types.ts +85 -0
  918. package/src/components/primitives/Link/README.md +954 -0
  919. package/src/components/primitives/Link/index.ts +8 -0
  920. package/src/components/primitives/Paragraph/Paragraph.test.tsx +463 -0
  921. package/src/components/primitives/Paragraph/Paragraph.tsx +119 -0
  922. package/src/components/primitives/Paragraph/Paragraph.types.ts +81 -0
  923. package/src/components/primitives/Paragraph/README.md +812 -0
  924. package/src/components/primitives/Paragraph/index.ts +2 -0
  925. package/src/components/primitives/ProgressBar/ProgressBar.test.tsx +598 -0
  926. package/src/components/primitives/ProgressBar/ProgressBar.tsx +268 -0
  927. package/src/components/primitives/ProgressBar/ProgressBar.types.ts +127 -0
  928. package/src/components/primitives/ProgressBar/ProgressBar.variants.ts +111 -0
  929. package/src/components/primitives/ProgressBar/README.md +772 -0
  930. package/src/components/primitives/ProgressBar/index.ts +3 -0
  931. package/src/components/primitives/ProgressCircle/ProgressCircle.test.tsx +219 -0
  932. package/src/components/primitives/ProgressCircle/ProgressCircle.tsx +264 -0
  933. package/src/components/primitives/ProgressCircle/ProgressCircle.types.ts +152 -0
  934. package/src/components/primitives/ProgressCircle/ProgressCircle.variants.ts +140 -0
  935. package/src/components/primitives/ProgressCircle/README.md +763 -0
  936. package/src/components/primitives/ProgressCircle/index.ts +3 -0
  937. package/src/components/primitives/SkeletonLoader/README.md +792 -0
  938. package/src/components/primitives/SkeletonLoader/SkeletonLoader.test.tsx +382 -0
  939. package/src/components/primitives/SkeletonLoader/SkeletonLoader.tsx +45 -0
  940. package/src/components/primitives/SkeletonLoader/SkeletonLoader.types.ts +56 -0
  941. package/src/components/primitives/SkeletonLoader/SkeletonLoader.variants.ts +87 -0
  942. package/src/components/primitives/SkeletonLoader/index.ts +3 -0
  943. package/src/components/primitives/Spacer/README.md +804 -0
  944. package/src/components/primitives/Spacer/Spacer.test.tsx +363 -0
  945. package/src/components/primitives/Spacer/Spacer.tsx +147 -0
  946. package/src/components/primitives/Spacer/Spacer.types.ts +72 -0
  947. package/src/components/primitives/Spacer/index.ts +9 -0
  948. package/src/components/primitives/Spinner/README.md +767 -0
  949. package/src/components/primitives/Spinner/Spinner.test.tsx +289 -0
  950. package/src/components/primitives/Spinner/Spinner.tsx +101 -0
  951. package/src/components/primitives/Spinner/Spinner.types.ts +62 -0
  952. package/src/components/primitives/Spinner/Spinner.variants.ts +50 -0
  953. package/src/components/primitives/Spinner/index.ts +3 -0
  954. package/src/components/primitives/SplitButton/README.md +1142 -0
  955. package/src/components/primitives/SplitButton/SplitButton.test.tsx +1020 -0
  956. package/src/components/primitives/SplitButton/SplitButton.tsx +215 -0
  957. package/src/components/primitives/SplitButton/SplitButton.types.ts +114 -0
  958. package/src/components/primitives/SplitButton/index.ts +8 -0
  959. package/src/components/primitives/StatusIndicator/README.md +730 -0
  960. package/src/components/primitives/StatusIndicator/StatusIndicator.test.tsx +446 -0
  961. package/src/components/primitives/StatusIndicator/StatusIndicator.tsx +100 -0
  962. package/src/components/primitives/StatusIndicator/StatusIndicator.types.ts +39 -0
  963. package/src/components/primitives/StatusIndicator/index.ts +2 -0
  964. package/src/components/primitives/Tag/README.md +793 -0
  965. package/src/components/primitives/Tag/Tag.test.tsx +410 -0
  966. package/src/components/primitives/Tag/Tag.tsx +302 -0
  967. package/src/components/primitives/Tag/Tag.types.ts +112 -0
  968. package/src/components/primitives/Tag/Tag.variants.ts +144 -0
  969. package/src/components/primitives/Tag/TagGroup.tsx +89 -0
  970. package/src/components/primitives/Tag/index.ts +15 -0
  971. package/src/components/primitives/Text/README.md +849 -0
  972. package/src/components/primitives/Text/Text.test.tsx +371 -0
  973. package/src/components/primitives/Text/Text.tsx +89 -0
  974. package/src/components/primitives/Text/Text.types.ts +21 -0
  975. package/src/components/primitives/Text/index.ts +2 -0
  976. package/src/components/primitives/Thumbnail/README.md +800 -0
  977. package/src/components/primitives/Thumbnail/Thumbnail.test.tsx +657 -0
  978. package/src/components/primitives/Thumbnail/Thumbnail.tsx +141 -0
  979. package/src/components/primitives/Thumbnail/Thumbnail.types.ts +102 -0
  980. package/src/components/primitives/Thumbnail/index.ts +9 -0
  981. package/src/components/primitives/Toggle/README.md +232 -0
  982. package/src/components/primitives/Toggle/Toggle.test.tsx +630 -0
  983. package/src/components/primitives/Toggle/Toggle.tsx +174 -0
  984. package/src/components/primitives/Toggle/Toggle.types.ts +161 -0
  985. package/src/components/primitives/Toggle/index.ts +2 -0
  986. package/src/components/primitives/index.ts +26 -0
  987. package/src/components/workflow/ApprovalFlow/ApprovalFlow.test.tsx +607 -0
  988. package/src/components/workflow/ApprovalFlow/ApprovalFlow.tsx +522 -0
  989. package/src/components/workflow/ApprovalFlow/ApprovalFlow.types.ts +233 -0
  990. package/src/components/workflow/ApprovalFlow/ApprovalFlow.variants.ts +207 -0
  991. package/src/components/workflow/ApprovalFlow/README.md +450 -0
  992. package/src/components/workflow/ApprovalFlow/index.ts +38 -0
  993. package/src/components/workflow/ApprovalStatus/ApprovalStatus.test.tsx +316 -0
  994. package/src/components/workflow/ApprovalStatus/ApprovalStatus.tsx +342 -0
  995. package/src/components/workflow/ApprovalStatus/ApprovalStatus.types.ts +68 -0
  996. package/src/components/workflow/ApprovalStatus/ApprovalStatus.variants.ts +60 -0
  997. package/src/components/workflow/ApprovalStatus/README.md +359 -0
  998. package/src/components/workflow/ApprovalStatus/index.ts +7 -0
  999. package/src/components/workflow/CLAUDE.md +118 -0
  1000. package/src/components/workflow/CommentSystem/CommentSystem.test.tsx +901 -0
  1001. package/src/components/workflow/CommentSystem/CommentSystem.tsx +1014 -0
  1002. package/src/components/workflow/CommentSystem/CommentSystem.types.ts +290 -0
  1003. package/src/components/workflow/CommentSystem/CommentSystem.variants.ts +307 -0
  1004. package/src/components/workflow/CommentSystem/README.md +478 -0
  1005. package/src/components/workflow/CommentSystem/index.ts +37 -0
  1006. package/src/components/workflow/Dashboard/Dashboard.test.tsx +586 -0
  1007. package/src/components/workflow/Dashboard/Dashboard.tsx +447 -0
  1008. package/src/components/workflow/Dashboard/Dashboard.types.ts +232 -0
  1009. package/src/components/workflow/Dashboard/Dashboard.variants.ts +241 -0
  1010. package/src/components/workflow/Dashboard/README.md +445 -0
  1011. package/src/components/workflow/Dashboard/index.ts +39 -0
  1012. package/src/components/workflow/DashboardBuilder/DashboardBuilder.test.tsx +460 -0
  1013. package/src/components/workflow/DashboardBuilder/DashboardBuilder.tsx +944 -0
  1014. package/src/components/workflow/DashboardBuilder/DashboardBuilder.types.ts +389 -0
  1015. package/src/components/workflow/DashboardBuilder/DashboardBuilder.variants.ts +264 -0
  1016. package/src/components/workflow/DashboardBuilder/README.md +489 -0
  1017. package/src/components/workflow/DashboardBuilder/index.ts +61 -0
  1018. package/src/components/workflow/KanbanBoard/KanbanBoard.test.tsx +445 -0
  1019. package/src/components/workflow/KanbanBoard/KanbanBoard.tsx +806 -0
  1020. package/src/components/workflow/KanbanBoard/KanbanBoard.types.ts +183 -0
  1021. package/src/components/workflow/KanbanBoard/KanbanBoard.variants.ts +311 -0
  1022. package/src/components/workflow/KanbanBoard/README.md +495 -0
  1023. package/src/components/workflow/KanbanBoard/index.ts +40 -0
  1024. package/src/components/workflow/ProgressSteps/ProgressSteps.test.tsx +318 -0
  1025. package/src/components/workflow/ProgressSteps/ProgressSteps.tsx +350 -0
  1026. package/src/components/workflow/ProgressSteps/ProgressSteps.types.ts +84 -0
  1027. package/src/components/workflow/ProgressSteps/ProgressSteps.variants.ts +315 -0
  1028. package/src/components/workflow/ProgressSteps/README.md +412 -0
  1029. package/src/components/workflow/ProgressSteps/index.ts +20 -0
  1030. package/src/components/workflow/ReportGenerator/README.md +530 -0
  1031. package/src/components/workflow/ReportGenerator/ReportGenerator.test.tsx +723 -0
  1032. package/src/components/workflow/ReportGenerator/ReportGenerator.tsx +889 -0
  1033. package/src/components/workflow/ReportGenerator/ReportGenerator.types.ts +321 -0
  1034. package/src/components/workflow/ReportGenerator/ReportGenerator.variants.ts +378 -0
  1035. package/src/components/workflow/ReportGenerator/index.ts +44 -0
  1036. package/src/components/workflow/Stepper/README.md +390 -0
  1037. package/src/components/workflow/Stepper/Stepper.test.tsx +376 -0
  1038. package/src/components/workflow/Stepper/Stepper.tsx +301 -0
  1039. package/src/components/workflow/Stepper/Stepper.types.ts +73 -0
  1040. package/src/components/workflow/Stepper/Stepper.variants.ts +194 -0
  1041. package/src/components/workflow/Stepper/index.ts +16 -0
  1042. package/src/components/workflow/TaskCard/README.md +343 -0
  1043. package/src/components/workflow/TaskCard/TaskCard.test.tsx +375 -0
  1044. package/src/components/workflow/TaskCard/TaskCard.tsx +312 -0
  1045. package/src/components/workflow/TaskCard/TaskCard.types.ts +55 -0
  1046. package/src/components/workflow/TaskCard/TaskCard.variants.ts +64 -0
  1047. package/src/components/workflow/TaskCard/index.ts +14 -0
  1048. package/src/components/workflow/TaskList/README.md +317 -0
  1049. package/src/components/workflow/TaskList/TaskList.test.tsx +318 -0
  1050. package/src/components/workflow/TaskList/TaskList.tsx +556 -0
  1051. package/src/components/workflow/TaskList/TaskList.types.ts +78 -0
  1052. package/src/components/workflow/TaskList/TaskList.variants.ts +143 -0
  1053. package/src/components/workflow/TaskList/index.ts +19 -0
  1054. package/src/components/workflow/TaskStatus/README.md +358 -0
  1055. package/src/components/workflow/TaskStatus/TaskStatus.test.tsx +299 -0
  1056. package/src/components/workflow/TaskStatus/TaskStatus.tsx +246 -0
  1057. package/src/components/workflow/TaskStatus/TaskStatus.types.ts +65 -0
  1058. package/src/components/workflow/TaskStatus/TaskStatus.variants.ts +145 -0
  1059. package/src/components/workflow/TaskStatus/index.ts +24 -0
  1060. package/src/components/workflow/Wizard/README.md +440 -0
  1061. package/src/components/workflow/Wizard/Wizard.test.tsx +432 -0
  1062. package/src/components/workflow/Wizard/Wizard.tsx +279 -0
  1063. package/src/components/workflow/Wizard/Wizard.types.ts +61 -0
  1064. package/src/components/workflow/Wizard/Wizard.variants.ts +105 -0
  1065. package/src/components/workflow/Wizard/index.ts +9 -0
  1066. package/src/components/workflow/index.ts +14 -0
  1067. package/src/hooks/index.ts +4 -0
  1068. package/src/hooks/use-media-query.ts +24 -0
  1069. package/src/hooks/use-mobile.ts +30 -0
  1070. package/src/hooks/use-on-window-resize.ts +27 -0
  1071. package/src/index.ts +22 -0
  1072. package/src/lib/chart-colors.ts +195 -0
  1073. package/src/lib/utils.ts +6 -0
  1074. package/src/test/setup.ts +125 -0
  1075. package/src/test/vitest.d.ts +13 -0
@@ -0,0 +1,1684 @@
1
+ import type { DateRange } from "../../advanced/Calendar"
2
+ import type { DateRangePreset } from "./DateRangePicker.types"
3
+
4
+ import { render, screen, waitFor, within } from "@testing-library/react"
5
+ import userEvent from "@testing-library/user-event"
6
+ import { axe, toHaveNoViolations } from "jest-axe"
7
+ // DateRangePicker/DateRangePicker.test.tsx
8
+ import * as React from "react"
9
+ import { beforeAll, describe, expect, it, vi } from "vitest"
10
+
11
+ import { DateRangePicker } from "./DateRangePicker"
12
+ import { DateRangePresets } from "./DateRangePresets"
13
+ import { defaultPresets } from "./presets"
14
+
15
+ expect.extend(toHaveNoViolations)
16
+
17
+ // Mock pointer capture methods for JSDOM (Radix Popover uses them)
18
+ beforeAll(() => {
19
+ Element.prototype.hasPointerCapture = vi.fn(() => false)
20
+ Element.prototype.setPointerCapture = vi.fn()
21
+ Element.prototype.releasePointerCapture = vi.fn()
22
+ })
23
+
24
+ // Helper to open the date range picker using click
25
+ async function openDateRangePicker(user: ReturnType<typeof userEvent.setup>) {
26
+ const trigger = screen.getByRole("combobox")
27
+ await user.click(trigger)
28
+ }
29
+
30
+ // Helper to find a day button in the calendar
31
+ function findDayButton(container: HTMLElement, day: number): HTMLElement | null {
32
+ const buttons = container.querySelectorAll('button[data-day]')
33
+ for (const button of buttons) {
34
+ const dateStr = button.getAttribute('data-day')
35
+ if (dateStr && new Date(dateStr).getDate() === day) {
36
+ return button as HTMLElement
37
+ }
38
+ }
39
+ return null
40
+ }
41
+
42
+ // Test dates
43
+ const testRange: DateRange = {
44
+ from: new Date(2024, 0, 10), // January 10, 2024
45
+ to: new Date(2024, 0, 20), // January 20, 2024
46
+ }
47
+ const minDate = new Date(2024, 0, 5) // January 5, 2024
48
+ const maxDate = new Date(2024, 0, 25) // January 25, 2024
49
+
50
+ // ============================================
51
+ // RENDERING TESTS
52
+ // ============================================
53
+ describe("DateRangePicker", () => {
54
+ describe("Rendering", () => {
55
+ it("renders correctly", () => {
56
+ render(<DateRangePicker aria-label="Select date range" />)
57
+ expect(screen.getByRole("combobox")).toBeInTheDocument()
58
+ })
59
+
60
+ it("renders with custom className", () => {
61
+ render(<DateRangePicker aria-label="Select date range" className="custom-class" />)
62
+ const wrapper = screen.getByRole("combobox").closest('[data-slot="date-range-picker"]')
63
+ expect(wrapper).toHaveClass("custom-class")
64
+ })
65
+
66
+ it("renders with placeholder", () => {
67
+ render(<DateRangePicker aria-label="Select date range" placeholder="Pick a range" />)
68
+ expect(screen.getByText("Pick a range")).toBeInTheDocument()
69
+ })
70
+
71
+ it("renders with default value", () => {
72
+ render(<DateRangePicker aria-label="Select date range" defaultValue={testRange} />)
73
+ expect(screen.getByRole("combobox")).toHaveTextContent("Jan 10, 2024")
74
+ expect(screen.getByRole("combobox")).toHaveTextContent("Jan 20, 2024")
75
+ })
76
+
77
+ it("renders with controlled value", () => {
78
+ render(<DateRangePicker aria-label="Select date range" value={testRange} onChange={() => {}} />)
79
+ expect(screen.getByRole("combobox")).toHaveTextContent("Jan 10, 2024")
80
+ })
81
+
82
+ it("has data-slot attribute on wrapper", () => {
83
+ render(<DateRangePicker aria-label="Select date range" />)
84
+ const wrapper = screen.getByRole("combobox").closest('[data-slot="date-range-picker"]')
85
+ expect(wrapper).toHaveAttribute("data-slot", "date-range-picker")
86
+ })
87
+
88
+ it("has data-slot attribute on trigger", () => {
89
+ render(<DateRangePicker aria-label="Select date range" />)
90
+ expect(screen.getByRole("combobox")).toHaveAttribute("data-slot", "date-range-picker-trigger")
91
+ })
92
+
93
+ it("renders calendar icon", () => {
94
+ render(<DateRangePicker aria-label="Select date range" />)
95
+ const trigger = screen.getByRole("combobox")
96
+ expect(trigger.querySelector("svg")).toBeInTheDocument()
97
+ })
98
+
99
+ it("renders with single calendar when numberOfMonths=1", async () => {
100
+ const user = userEvent.setup()
101
+ render(<DateRangePicker aria-label="Select date range" numberOfMonths={1} />)
102
+
103
+ await openDateRangePicker(user)
104
+
105
+ await waitFor(() => {
106
+ const calendar = document.querySelector('[data-slot="calendar"]')
107
+ expect(calendar).not.toHaveAttribute("data-multiple-months", "true")
108
+ })
109
+ })
110
+
111
+ it("renders with dual calendar by default", async () => {
112
+ const user = userEvent.setup()
113
+ render(<DateRangePicker aria-label="Select date range" />)
114
+
115
+ await openDateRangePicker(user)
116
+
117
+ await waitFor(() => {
118
+ const calendar = document.querySelector('[data-slot="calendar"]')
119
+ expect(calendar).toHaveAttribute("data-multiple-months", "true")
120
+ })
121
+ })
122
+
123
+ it("renders with custom format", () => {
124
+ render(<DateRangePicker aria-label="Select date range" defaultValue={testRange} format="MM/dd/yyyy" />)
125
+ expect(screen.getByRole("combobox")).toHaveTextContent("01/10/2024")
126
+ expect(screen.getByRole("combobox")).toHaveTextContent("01/20/2024")
127
+ })
128
+ })
129
+
130
+ // ============================================
131
+ // STATE TESTS
132
+ // ============================================
133
+ describe("States", () => {
134
+ it("handles disabled state", () => {
135
+ render(<DateRangePicker disabled aria-label="Select date range" />)
136
+ expect(screen.getByRole("combobox")).toBeDisabled()
137
+ })
138
+
139
+ it("applies disabled styling", () => {
140
+ render(<DateRangePicker disabled aria-label="Select date range" />)
141
+ expect(screen.getByRole("combobox")).toHaveClass("disabled:opacity-50")
142
+ })
143
+
144
+ it("handles aria-invalid state", () => {
145
+ render(<DateRangePicker invalid aria-label="Select date range" />)
146
+ expect(screen.getByRole("combobox")).toHaveAttribute("aria-invalid", "true")
147
+ })
148
+
149
+ it("handles required state", () => {
150
+ render(<DateRangePicker required aria-label="Select date range" />)
151
+ expect(screen.getByRole("combobox")).toHaveAttribute("aria-required", "true")
152
+ })
153
+
154
+ it("shows placeholder when no value selected", () => {
155
+ render(<DateRangePicker aria-label="Select date range" placeholder="Choose range" />)
156
+ expect(screen.getByText("Choose range")).toBeInTheDocument()
157
+ })
158
+
159
+ it("shows selected range instead of placeholder", () => {
160
+ render(<DateRangePicker aria-label="Select date range" defaultValue={testRange} placeholder="Choose range" />)
161
+ expect(screen.queryByText("Choose range")).not.toBeInTheDocument()
162
+ })
163
+
164
+ it("applies muted color when no range selected", () => {
165
+ render(<DateRangePicker aria-label="Select date range" />)
166
+ expect(screen.getByRole("combobox")).toHaveClass("text-muted-foreground")
167
+ })
168
+
169
+ it("removes muted color when range is selected", () => {
170
+ render(<DateRangePicker aria-label="Select date range" defaultValue={testRange} />)
171
+ expect(screen.getByRole("combobox")).not.toHaveClass("text-muted-foreground")
172
+ })
173
+ })
174
+
175
+ // ============================================
176
+ // RANGE SELECTION TESTS
177
+ // ============================================
178
+ describe("Range Selection", () => {
179
+ it("opens calendar when trigger is clicked", async () => {
180
+ const user = userEvent.setup()
181
+ render(<DateRangePicker aria-label="Select date range" />)
182
+
183
+ await openDateRangePicker(user)
184
+
185
+ await waitFor(() => {
186
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
187
+ })
188
+ })
189
+
190
+ it("shows calendar when opened", async () => {
191
+ const user = userEvent.setup()
192
+ render(<DateRangePicker aria-label="Select date range" defaultValue={testRange} />)
193
+
194
+ await openDateRangePicker(user)
195
+
196
+ await waitFor(() => {
197
+ const dialog = screen.getByRole("dialog")
198
+ expect(dialog.querySelector('[data-slot="calendar"]')).toBeInTheDocument()
199
+ })
200
+ })
201
+
202
+ it("selects start date on first click", async () => {
203
+ const user = userEvent.setup()
204
+ const handleChange = vi.fn()
205
+ render(<DateRangePicker aria-label="Select date range" onChange={handleChange} />)
206
+
207
+ await openDateRangePicker(user)
208
+
209
+ await waitFor(() => {
210
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
211
+ })
212
+
213
+ const dialog = screen.getByRole("dialog")
214
+ const day15Button = findDayButton(dialog, 15)
215
+ await user.click(day15Button as Element)
216
+
217
+ expect(handleChange).toHaveBeenCalled()
218
+ const range = handleChange.mock.calls[0]?.[0] as DateRange
219
+ expect(range.from).toBeInstanceOf(Date)
220
+ })
221
+
222
+ it("selects end date on second click", async () => {
223
+ const user = userEvent.setup()
224
+ const handleChange = vi.fn()
225
+ render(<DateRangePicker aria-label="Select date range" onChange={handleChange} />)
226
+
227
+ await openDateRangePicker(user)
228
+
229
+ await waitFor(() => {
230
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
231
+ })
232
+
233
+ const dialog = screen.getByRole("dialog")
234
+ const day10Button = findDayButton(dialog, 10)
235
+ await user.click(day10Button as Element)
236
+
237
+ const day20Button = findDayButton(dialog, 20)
238
+ await user.click(day20Button as Element)
239
+
240
+ expect(handleChange).toHaveBeenCalledTimes(2)
241
+ const range = handleChange.mock.calls[1]?.[0] as DateRange
242
+ expect(range.from).toBeInstanceOf(Date)
243
+ expect(range.to).toBeInstanceOf(Date)
244
+ })
245
+
246
+ it("handles selecting same day for start and end", async () => {
247
+ const user = userEvent.setup()
248
+ const handleChange = vi.fn()
249
+ render(<DateRangePicker aria-label="Select date range" onChange={handleChange} />)
250
+
251
+ await openDateRangePicker(user)
252
+
253
+ await waitFor(() => {
254
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
255
+ })
256
+
257
+ const dialog = screen.getByRole("dialog")
258
+ const day15Button = findDayButton(dialog, 15)
259
+ await user.click(day15Button as Element)
260
+ await user.click(day15Button as Element)
261
+
262
+ expect(handleChange).toHaveBeenCalled()
263
+ })
264
+
265
+ it("allows reverse selection (end before start)", async () => {
266
+ const user = userEvent.setup()
267
+ const handleChange = vi.fn()
268
+ render(<DateRangePicker aria-label="Select date range" onChange={handleChange} />)
269
+
270
+ await openDateRangePicker(user)
271
+
272
+ await waitFor(() => {
273
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
274
+ })
275
+
276
+ const dialog = screen.getByRole("dialog")
277
+ // Select day 20 first
278
+ const day20Button = findDayButton(dialog, 20)
279
+ await user.click(day20Button as Element)
280
+
281
+ // Then select day 10
282
+ const day10Button = findDayButton(dialog, 10)
283
+ await user.click(day10Button as Element)
284
+
285
+ expect(handleChange).toHaveBeenCalled()
286
+ })
287
+
288
+ it("displays partial range (only start date)", () => {
289
+ const partialRange: DateRange = { from: new Date(2024, 0, 15) }
290
+ render(<DateRangePicker aria-label="Select date range" defaultValue={partialRange} />)
291
+ expect(screen.getByRole("combobox")).toHaveTextContent("Jan 15, 2024")
292
+ })
293
+
294
+ it("clears selection when new start date is picked after complete range", async () => {
295
+ const user = userEvent.setup()
296
+ const handleChange = vi.fn()
297
+ render(<DateRangePicker aria-label="Select date range" defaultValue={testRange} onChange={handleChange} />)
298
+
299
+ await openDateRangePicker(user)
300
+
301
+ await waitFor(() => {
302
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
303
+ })
304
+
305
+ // Click a new day to start a new selection
306
+ const dialog = screen.getByRole("dialog")
307
+ const day5Button = findDayButton(dialog, 5)
308
+ await user.click(day5Button as Element)
309
+
310
+ expect(handleChange).toHaveBeenCalled()
311
+ })
312
+ })
313
+
314
+ // ============================================
315
+ // PRESETS TESTS
316
+ // ============================================
317
+ describe("Presets", () => {
318
+ it("shows presets sidebar by default", async () => {
319
+ const user = userEvent.setup()
320
+ render(<DateRangePicker aria-label="Select date range" />)
321
+
322
+ await openDateRangePicker(user)
323
+
324
+ await waitFor(() => {
325
+ const presets = document.querySelector('[data-slot="date-range-presets"]')
326
+ expect(presets).toBeInTheDocument()
327
+ })
328
+ })
329
+
330
+ it("hides presets when showPresets is false", async () => {
331
+ const user = userEvent.setup()
332
+ render(<DateRangePicker aria-label="Select date range" showPresets={false} />)
333
+
334
+ await openDateRangePicker(user)
335
+
336
+ await waitFor(() => {
337
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
338
+ })
339
+
340
+ const presets = document.querySelector('[data-slot="date-range-presets"]')
341
+ expect(presets).not.toBeInTheDocument()
342
+ })
343
+
344
+ it("displays all default presets", async () => {
345
+ const user = userEvent.setup()
346
+ render(<DateRangePicker aria-label="Select date range" />)
347
+
348
+ await openDateRangePicker(user)
349
+
350
+ await waitFor(() => {
351
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
352
+ })
353
+
354
+ // Check some default presets exist (role="option" because they're in a listbox)
355
+ expect(screen.getByRole("option", { name: "Today" })).toBeInTheDocument()
356
+ expect(screen.getByRole("option", { name: "Yesterday" })).toBeInTheDocument()
357
+ expect(screen.getByRole("option", { name: "Last 7 days" })).toBeInTheDocument()
358
+ })
359
+
360
+ it("accepts custom presets", async () => {
361
+ const user = userEvent.setup()
362
+ const customPresets: DateRangePreset[] = [
363
+ { label: "Custom Range", getValue: () => testRange },
364
+ ]
365
+ render(<DateRangePicker aria-label="Select date range" presets={customPresets} />)
366
+
367
+ await openDateRangePicker(user)
368
+
369
+ await waitFor(() => {
370
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
371
+ })
372
+
373
+ expect(screen.getByRole("option", { name: "Custom Range" })).toBeInTheDocument()
374
+ expect(screen.queryByRole("option", { name: "Today" })).not.toBeInTheDocument()
375
+ })
376
+
377
+ it("applies preset when clicked", async () => {
378
+ const user = userEvent.setup()
379
+ const handleChange = vi.fn()
380
+ render(<DateRangePicker aria-label="Select date range" onChange={handleChange} />)
381
+
382
+ await openDateRangePicker(user)
383
+
384
+ await waitFor(() => {
385
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
386
+ })
387
+
388
+ await user.click(screen.getByRole("option", { name: "Today" }))
389
+
390
+ expect(handleChange).toHaveBeenCalled()
391
+ const range = handleChange.mock.calls[0]?.[0] as DateRange
392
+ expect(range.from).toBeInstanceOf(Date)
393
+ expect(range.to).toBeInstanceOf(Date)
394
+ })
395
+
396
+ it("closes calendar after preset selection (no confirmation mode)", async () => {
397
+ const user = userEvent.setup()
398
+ render(<DateRangePicker aria-label="Select date range" />)
399
+
400
+ await openDateRangePicker(user)
401
+
402
+ await waitFor(() => {
403
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
404
+ })
405
+
406
+ await user.click(screen.getByRole("option", { name: "Today" }))
407
+
408
+ await waitFor(() => {
409
+ expect(screen.queryByRole("dialog")).not.toBeInTheDocument()
410
+ })
411
+ })
412
+
413
+ it("highlights selected preset", async () => {
414
+ const user = userEvent.setup()
415
+ render(<DateRangePicker requireConfirmation aria-label="Select date range" />)
416
+
417
+ await openDateRangePicker(user)
418
+
419
+ await waitFor(() => {
420
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
421
+ })
422
+
423
+ const todayPreset = screen.getByRole("option", { name: "Today" })
424
+ await user.click(todayPreset)
425
+
426
+ // Check that preset has data-selected attribute
427
+ expect(todayPreset).toHaveAttribute("data-selected")
428
+ })
429
+
430
+ it("hides presets when empty array provided", async () => {
431
+ const user = userEvent.setup()
432
+ render(<DateRangePicker aria-label="Select date range" presets={[]} />)
433
+
434
+ await openDateRangePicker(user)
435
+
436
+ await waitFor(() => {
437
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
438
+ })
439
+
440
+ const presets = document.querySelector('[data-slot="date-range-presets"]')
441
+ expect(presets).not.toBeInTheDocument()
442
+ })
443
+ })
444
+
445
+ // ============================================
446
+ // CONFIRMATION MODE TESTS
447
+ // ============================================
448
+ describe("Confirmation Mode", () => {
449
+ it("shows Apply and Cancel buttons when requireConfirmation is true", async () => {
450
+ const user = userEvent.setup()
451
+ render(<DateRangePicker requireConfirmation aria-label="Select date range" />)
452
+
453
+ await openDateRangePicker(user)
454
+
455
+ await waitFor(() => {
456
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
457
+ })
458
+
459
+ expect(screen.getByRole("button", { name: "Apply" })).toBeInTheDocument()
460
+ expect(screen.getByRole("button", { name: "Cancel" })).toBeInTheDocument()
461
+ })
462
+
463
+ it("does not show Apply/Cancel buttons by default", async () => {
464
+ const user = userEvent.setup()
465
+ render(<DateRangePicker aria-label="Select date range" />)
466
+
467
+ await openDateRangePicker(user)
468
+
469
+ await waitFor(() => {
470
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
471
+ })
472
+
473
+ expect(screen.queryByRole("button", { name: "Apply" })).not.toBeInTheDocument()
474
+ expect(screen.queryByRole("button", { name: "Cancel" })).not.toBeInTheDocument()
475
+ })
476
+
477
+ it("does not call onChange until Apply is clicked", async () => {
478
+ const user = userEvent.setup()
479
+ const handleChange = vi.fn()
480
+ render(<DateRangePicker requireConfirmation aria-label="Select date range" onChange={handleChange} />)
481
+
482
+ await openDateRangePicker(user)
483
+
484
+ await waitFor(() => {
485
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
486
+ })
487
+
488
+ // Select a preset
489
+ await user.click(screen.getByRole("option", { name: "Today" }))
490
+
491
+ // onChange should not have been called yet
492
+ expect(handleChange).not.toHaveBeenCalled()
493
+ })
494
+
495
+ it("calls onChange when Apply is clicked", async () => {
496
+ const user = userEvent.setup()
497
+ const handleChange = vi.fn()
498
+ render(<DateRangePicker requireConfirmation aria-label="Select date range" onChange={handleChange} />)
499
+
500
+ await openDateRangePicker(user)
501
+
502
+ await waitFor(() => {
503
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
504
+ })
505
+
506
+ await user.click(screen.getByRole("option", { name: "Today" }))
507
+ await user.click(screen.getByRole("button", { name: "Apply" }))
508
+
509
+ expect(handleChange).toHaveBeenCalled()
510
+ })
511
+
512
+ it("reverts changes when Cancel is clicked", async () => {
513
+ const user = userEvent.setup()
514
+ const handleChange = vi.fn()
515
+ render(<DateRangePicker requireConfirmation aria-label="Select date range" defaultValue={testRange} onChange={handleChange} />)
516
+
517
+ await openDateRangePicker(user)
518
+
519
+ await waitFor(() => {
520
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
521
+ })
522
+
523
+ await user.click(screen.getByRole("option", { name: "Today" }))
524
+ await user.click(screen.getByRole("button", { name: "Cancel" }))
525
+
526
+ // onChange should not have been called
527
+ expect(handleChange).not.toHaveBeenCalled()
528
+
529
+ // Dialog should be closed
530
+ await waitFor(() => {
531
+ expect(screen.queryByRole("dialog")).not.toBeInTheDocument()
532
+ })
533
+
534
+ // Original value should be preserved
535
+ expect(screen.getByRole("combobox")).toHaveTextContent("Jan 10, 2024")
536
+ })
537
+
538
+ it("closes calendar after Apply", async () => {
539
+ const user = userEvent.setup()
540
+ render(<DateRangePicker requireConfirmation aria-label="Select date range" />)
541
+
542
+ await openDateRangePicker(user)
543
+
544
+ await waitFor(() => {
545
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
546
+ })
547
+
548
+ await user.click(screen.getByRole("option", { name: "Today" }))
549
+ await user.click(screen.getByRole("button", { name: "Apply" }))
550
+
551
+ await waitFor(() => {
552
+ expect(screen.queryByRole("dialog")).not.toBeInTheDocument()
553
+ })
554
+ })
555
+
556
+ it("disables Apply button when no selection", async () => {
557
+ const user = userEvent.setup()
558
+ render(<DateRangePicker requireConfirmation aria-label="Select date range" />)
559
+
560
+ await openDateRangePicker(user)
561
+
562
+ await waitFor(() => {
563
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
564
+ })
565
+
566
+ expect(screen.getByRole("button", { name: "Apply" })).toBeDisabled()
567
+ })
568
+
569
+ it("reverts changes when closing without Apply", async () => {
570
+ const user = userEvent.setup()
571
+ const handleChange = vi.fn()
572
+ render(<DateRangePicker requireConfirmation aria-label="Select date range" defaultValue={testRange} onChange={handleChange} />)
573
+
574
+ await openDateRangePicker(user)
575
+
576
+ await waitFor(() => {
577
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
578
+ })
579
+
580
+ await user.click(screen.getByRole("option", { name: "Today" }))
581
+ await user.keyboard("{Escape}")
582
+
583
+ expect(handleChange).not.toHaveBeenCalled()
584
+ })
585
+
586
+ it("has data-slot on footer", async () => {
587
+ const user = userEvent.setup()
588
+ render(<DateRangePicker requireConfirmation aria-label="Select date range" />)
589
+
590
+ await openDateRangePicker(user)
591
+
592
+ await waitFor(() => {
593
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
594
+ })
595
+
596
+ const footer = document.querySelector('[data-slot="date-range-picker-footer"]')
597
+ expect(footer).toBeInTheDocument()
598
+ })
599
+ })
600
+
601
+ // ============================================
602
+ // CONSTRAINTS TESTS
603
+ // ============================================
604
+ describe("Constraints", () => {
605
+ it("disables dates before minDate", async () => {
606
+ const user = userEvent.setup()
607
+ render(<DateRangePicker aria-label="Select date range" defaultValue={testRange} minDate={minDate} />)
608
+
609
+ await openDateRangePicker(user)
610
+
611
+ await waitFor(() => {
612
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
613
+ })
614
+
615
+ const dialog = screen.getByRole("dialog")
616
+ const day3Button = findDayButton(dialog, 3)
617
+ expect(day3Button).toBeDisabled()
618
+ })
619
+
620
+ it("disables dates after maxDate", async () => {
621
+ const user = userEvent.setup()
622
+ render(<DateRangePicker aria-label="Select date range" defaultValue={testRange} maxDate={maxDate} />)
623
+
624
+ await openDateRangePicker(user)
625
+
626
+ await waitFor(() => {
627
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
628
+ })
629
+
630
+ const dialog = screen.getByRole("dialog")
631
+ const day30Button = findDayButton(dialog, 30)
632
+ expect(day30Button).toBeDisabled()
633
+ })
634
+
635
+ it("allows dates within range", async () => {
636
+ const user = userEvent.setup()
637
+ render(<DateRangePicker aria-label="Select date range" defaultValue={testRange} maxDate={maxDate} minDate={minDate} />)
638
+
639
+ await openDateRangePicker(user)
640
+
641
+ await waitFor(() => {
642
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
643
+ })
644
+
645
+ const dialog = screen.getByRole("dialog")
646
+ const day15Button = findDayButton(dialog, 15)
647
+ expect(day15Button).not.toBeDisabled()
648
+ })
649
+
650
+ it("respects disabledDates function", async () => {
651
+ const user = userEvent.setup()
652
+ render(
653
+ <DateRangePicker
654
+ aria-label="Select date range"
655
+ defaultValue={testRange}
656
+ disabledDates={(date) => date.getDay() === 0 || date.getDay() === 6}
657
+ />
658
+ )
659
+
660
+ await openDateRangePicker(user)
661
+
662
+ await waitFor(() => {
663
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
664
+ })
665
+
666
+ const dialog = screen.getByRole("dialog")
667
+ // January 13, 2024 is a Saturday
668
+ const saturdayButton = findDayButton(dialog, 13)
669
+ expect(saturdayButton).toBeDisabled()
670
+ })
671
+
672
+ it("combines minDate, maxDate, and disabledDates", async () => {
673
+ const user = userEvent.setup()
674
+ render(
675
+ <DateRangePicker
676
+ aria-label="Select date range"
677
+ defaultValue={testRange}
678
+ disabledDates={(date) => date.getDate() === 16}
679
+ maxDate={maxDate}
680
+ minDate={minDate}
681
+ />
682
+ )
683
+
684
+ await openDateRangePicker(user)
685
+
686
+ await waitFor(() => {
687
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
688
+ })
689
+
690
+ const dialog = screen.getByRole("dialog")
691
+
692
+ // Day 3 disabled by minDate
693
+ const day3Button = findDayButton(dialog, 3)
694
+ expect(day3Button).toBeDisabled()
695
+
696
+ // Day 16 disabled by function
697
+ const day16Button = findDayButton(dialog, 16)
698
+ expect(day16Button).toBeDisabled()
699
+
700
+ // Day 15 should be enabled
701
+ const day15Button = findDayButton(dialog, 15)
702
+ expect(day15Button).not.toBeDisabled()
703
+ })
704
+ })
705
+
706
+ // ============================================
707
+ // ACCESSIBILITY TESTS
708
+ // ============================================
709
+ describe("Accessibility", () => {
710
+ it("has no accessibility violations", async () => {
711
+ const { container } = render(
712
+ <label>
713
+ Date range
714
+ <DateRangePicker id="daterange" />
715
+ </label>
716
+ )
717
+ const results = await axe(container)
718
+ expect(results).toHaveNoViolations()
719
+ })
720
+
721
+ it("trigger has combobox role", () => {
722
+ render(<DateRangePicker aria-label="Select date range" />)
723
+ expect(screen.getByRole("combobox")).toBeInTheDocument()
724
+ })
725
+
726
+ it("trigger has aria-haspopup", () => {
727
+ render(<DateRangePicker aria-label="Select date range" />)
728
+ expect(screen.getByRole("combobox")).toHaveAttribute("aria-haspopup", "dialog")
729
+ })
730
+
731
+ it("trigger has aria-expanded=false when closed", () => {
732
+ render(<DateRangePicker aria-label="Select date range" />)
733
+ expect(screen.getByRole("combobox")).toHaveAttribute("aria-expanded", "false")
734
+ })
735
+
736
+ it("trigger has aria-expanded=true when open", async () => {
737
+ const user = userEvent.setup()
738
+ render(<DateRangePicker aria-label="Select date range" />)
739
+
740
+ await openDateRangePicker(user)
741
+
742
+ await waitFor(() => {
743
+ expect(screen.getByRole("combobox")).toHaveAttribute("aria-expanded", "true")
744
+ })
745
+ })
746
+
747
+ it("supports aria-label prop", () => {
748
+ render(<DateRangePicker aria-label="Select your dates" />)
749
+ expect(screen.getByRole("combobox")).toHaveAttribute("aria-label", "Select your dates")
750
+ })
751
+
752
+ it("supports aria-labelledby", () => {
753
+ render(
754
+ <>
755
+ <span id="my-label">Pick dates</span>
756
+ <DateRangePicker aria-labelledby="my-label" />
757
+ </>
758
+ )
759
+ expect(screen.getByRole("combobox")).toHaveAttribute("aria-labelledby", "my-label")
760
+ })
761
+
762
+ it("supports aria-describedby", () => {
763
+ render(
764
+ <>
765
+ <DateRangePicker aria-describedby="help" aria-label="Select date range" />
766
+ <span id="help">Select a start and end date</span>
767
+ </>
768
+ )
769
+ expect(screen.getByRole("combobox")).toHaveAttribute("aria-describedby", "help")
770
+ })
771
+
772
+ it("clear button has accessible label", () => {
773
+ render(<DateRangePicker clearable aria-label="Select date range" defaultValue={testRange} />)
774
+ expect(screen.getByLabelText("Clear date range")).toBeInTheDocument()
775
+ })
776
+
777
+ it("presets are keyboard accessible", async () => {
778
+ const user = userEvent.setup()
779
+ render(<DateRangePicker aria-label="Select date range" />)
780
+
781
+ await openDateRangePicker(user)
782
+
783
+ await waitFor(() => {
784
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
785
+ })
786
+
787
+ // Tab to presets
788
+ await user.tab()
789
+
790
+ const focusedPreset = document.activeElement
791
+ expect(focusedPreset).toHaveRole("option")
792
+ })
793
+ })
794
+
795
+ // ============================================
796
+ // KEYBOARD NAVIGATION TESTS
797
+ // ============================================
798
+ describe("Keyboard Navigation", () => {
799
+ it("opens calendar with Enter key", async () => {
800
+ const user = userEvent.setup()
801
+ render(<DateRangePicker aria-label="Select date range" />)
802
+
803
+ screen.getByRole("combobox").focus()
804
+ await user.keyboard("{Enter}")
805
+
806
+ await waitFor(() => {
807
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
808
+ })
809
+ })
810
+
811
+ it("opens calendar with Space key", async () => {
812
+ const user = userEvent.setup()
813
+ render(<DateRangePicker aria-label="Select date range" />)
814
+
815
+ screen.getByRole("combobox").focus()
816
+ await user.keyboard(" ")
817
+
818
+ await waitFor(() => {
819
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
820
+ })
821
+ })
822
+
823
+ it("closes calendar with Escape key", async () => {
824
+ const user = userEvent.setup()
825
+ render(<DateRangePicker aria-label="Select date range" />)
826
+
827
+ await openDateRangePicker(user)
828
+
829
+ await waitFor(() => {
830
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
831
+ })
832
+
833
+ await user.keyboard("{Escape}")
834
+
835
+ await waitFor(() => {
836
+ expect(screen.queryByRole("dialog")).not.toBeInTheDocument()
837
+ })
838
+ })
839
+ })
840
+
841
+ // ============================================
842
+ // CONTROLLED/UNCONTROLLED TESTS
843
+ // ============================================
844
+ describe("Controlled State", () => {
845
+ it("respects controlled value", () => {
846
+ const { rerender } = render(
847
+ <DateRangePicker aria-label="Select date range" value={testRange} onChange={() => {}} />
848
+ )
849
+
850
+ expect(screen.getByRole("combobox")).toHaveTextContent("Jan 10, 2024")
851
+
852
+ const newRange: DateRange = {
853
+ from: new Date(2024, 1, 1),
854
+ to: new Date(2024, 1, 14),
855
+ }
856
+ rerender(<DateRangePicker aria-label="Select date range" value={newRange} onChange={() => {}} />)
857
+ expect(screen.getByRole("combobox")).toHaveTextContent("Feb 1, 2024")
858
+ })
859
+
860
+ it("reports new value via onChange", async () => {
861
+ const user = userEvent.setup()
862
+ const handleChange = vi.fn()
863
+ render(<DateRangePicker aria-label="Select date range" value={testRange} onChange={handleChange} />)
864
+
865
+ await openDateRangePicker(user)
866
+
867
+ await waitFor(() => {
868
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
869
+ })
870
+
871
+ const dialog = screen.getByRole("dialog")
872
+ const day25Button = findDayButton(dialog, 25)
873
+ await user.click(day25Button as Element)
874
+
875
+ expect(handleChange).toHaveBeenCalled()
876
+ })
877
+
878
+ it("works in uncontrolled mode with defaultValue", () => {
879
+ render(<DateRangePicker aria-label="Select date range" defaultValue={testRange} />)
880
+ expect(screen.getByRole("combobox")).toHaveTextContent("Jan 10, 2024")
881
+ })
882
+
883
+ it("works in uncontrolled mode without defaultValue", () => {
884
+ render(<DateRangePicker aria-label="Select date range" placeholder="Select range" />)
885
+ expect(screen.getByText("Select range")).toBeInTheDocument()
886
+ })
887
+ })
888
+
889
+ // ============================================
890
+ // EVENTS TESTS
891
+ // ============================================
892
+ describe("Events", () => {
893
+ it("calls onChange when range changes", async () => {
894
+ const user = userEvent.setup()
895
+ const handleChange = vi.fn()
896
+ render(<DateRangePicker aria-label="Select date range" onChange={handleChange} />)
897
+
898
+ await openDateRangePicker(user)
899
+
900
+ await waitFor(() => {
901
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
902
+ })
903
+
904
+ await user.click(screen.getByRole("option", { name: "Today" }))
905
+
906
+ expect(handleChange).toHaveBeenCalled()
907
+ })
908
+
909
+ it("calls onOpenChange when calendar opens", async () => {
910
+ const user = userEvent.setup()
911
+ const handleOpenChange = vi.fn()
912
+ render(<DateRangePicker aria-label="Select date range" onOpenChange={handleOpenChange} />)
913
+
914
+ await openDateRangePicker(user)
915
+
916
+ await waitFor(() => {
917
+ expect(handleOpenChange).toHaveBeenCalledWith(true)
918
+ })
919
+ })
920
+
921
+ it("calls onOpenChange when calendar closes", async () => {
922
+ const user = userEvent.setup()
923
+ const handleOpenChange = vi.fn()
924
+ render(<DateRangePicker aria-label="Select date range" onOpenChange={handleOpenChange} />)
925
+
926
+ await openDateRangePicker(user)
927
+
928
+ await waitFor(() => {
929
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
930
+ })
931
+
932
+ await user.keyboard("{Escape}")
933
+
934
+ await waitFor(() => {
935
+ expect(handleOpenChange).toHaveBeenCalledWith(false)
936
+ })
937
+ })
938
+
939
+ it("calls onClear when cleared", async () => {
940
+ const user = userEvent.setup()
941
+ const handleClear = vi.fn()
942
+ render(<DateRangePicker clearable aria-label="Select date range" defaultValue={testRange} onClear={handleClear} />)
943
+
944
+ await user.click(screen.getByLabelText("Clear date range"))
945
+
946
+ expect(handleClear).toHaveBeenCalled()
947
+ })
948
+
949
+ it("does not open when disabled", async () => {
950
+ const user = userEvent.setup()
951
+ render(<DateRangePicker disabled aria-label="Select date range" />)
952
+
953
+ const trigger = screen.getByRole("combobox")
954
+ await user.click(trigger)
955
+
956
+ expect(screen.queryByRole("dialog")).not.toBeInTheDocument()
957
+ })
958
+ })
959
+
960
+ // ============================================
961
+ // SIZE VARIANTS
962
+ // ============================================
963
+ describe("Size Variants", () => {
964
+ it("applies default size (md)", () => {
965
+ render(<DateRangePicker aria-label="Select date range" />)
966
+ expect(screen.getByRole("combobox")).toHaveClass("h-[var(--date-picker-trigger-height-md)]")
967
+ })
968
+
969
+ it("applies sm size", () => {
970
+ render(<DateRangePicker aria-label="Select date range" size="sm" />)
971
+ expect(screen.getByRole("combobox")).toHaveClass("h-[var(--date-picker-trigger-height-sm)]")
972
+ })
973
+
974
+ it("applies lg size", () => {
975
+ render(<DateRangePicker aria-label="Select date range" size="lg" />)
976
+ expect(screen.getByRole("combobox")).toHaveClass("h-[var(--date-picker-trigger-height-lg)]")
977
+ })
978
+
979
+ it("has data-size attribute", () => {
980
+ render(<DateRangePicker aria-label="Select date range" size="sm" />)
981
+ expect(screen.getByRole("combobox")).toHaveAttribute("data-size", "sm")
982
+ })
983
+ })
984
+
985
+ // ============================================
986
+ // VISUAL VARIANT TESTS
987
+ // ============================================
988
+ describe("Visual Variants", () => {
989
+ it("applies default variant", () => {
990
+ render(<DateRangePicker aria-label="Select date range" />)
991
+ expect(screen.getByRole("combobox")).toHaveClass("border-input")
992
+ })
993
+
994
+ it("applies outline variant", () => {
995
+ render(<DateRangePicker aria-label="Select date range" variant="outline" />)
996
+ expect(screen.getByRole("combobox")).toHaveClass("border-input")
997
+ })
998
+
999
+ it("applies ghost variant", () => {
1000
+ render(<DateRangePicker aria-label="Select date range" variant="ghost" />)
1001
+ expect(screen.getByRole("combobox")).toHaveClass("border-transparent")
1002
+ })
1003
+
1004
+ it("has data-variant attribute", () => {
1005
+ render(<DateRangePicker aria-label="Select date range" variant="ghost" />)
1006
+ expect(screen.getByRole("combobox")).toHaveAttribute("data-variant", "ghost")
1007
+ })
1008
+ })
1009
+
1010
+ // ============================================
1011
+ // CLEARABLE TESTS
1012
+ // ============================================
1013
+ describe("Clearable", () => {
1014
+ it("does not show clear button by default", () => {
1015
+ render(<DateRangePicker aria-label="Select date range" defaultValue={testRange} />)
1016
+ expect(screen.queryByLabelText("Clear date range")).not.toBeInTheDocument()
1017
+ })
1018
+
1019
+ it("shows clear button when clearable and has value", () => {
1020
+ render(<DateRangePicker clearable aria-label="Select date range" defaultValue={testRange} />)
1021
+ expect(screen.getByLabelText("Clear date range")).toBeInTheDocument()
1022
+ })
1023
+
1024
+ it("does not show clear button when clearable but no value", () => {
1025
+ render(<DateRangePicker clearable aria-label="Select date range" />)
1026
+ expect(screen.queryByLabelText("Clear date range")).not.toBeInTheDocument()
1027
+ })
1028
+
1029
+ it("does not show clear button when disabled", () => {
1030
+ render(<DateRangePicker clearable disabled aria-label="Select date range" defaultValue={testRange} />)
1031
+ expect(screen.queryByLabelText("Clear date range")).not.toBeInTheDocument()
1032
+ })
1033
+
1034
+ it("does not show clear button when readOnly", () => {
1035
+ render(<DateRangePicker clearable readOnly aria-label="Select date range" defaultValue={testRange} />)
1036
+ expect(screen.queryByLabelText("Clear date range")).not.toBeInTheDocument()
1037
+ })
1038
+
1039
+ it("clears range when clear button is clicked", async () => {
1040
+ const user = userEvent.setup()
1041
+ const handleChange = vi.fn()
1042
+ render(<DateRangePicker clearable aria-label="Select date range" defaultValue={testRange} onChange={handleChange} />)
1043
+
1044
+ await user.click(screen.getByLabelText("Clear date range"))
1045
+
1046
+ expect(handleChange).toHaveBeenCalledTimes(1)
1047
+ expect(handleChange.mock.calls[0]).toHaveLength(0)
1048
+ })
1049
+
1050
+ it("clears range with keyboard (Enter)", async () => {
1051
+ const user = userEvent.setup()
1052
+ const handleChange = vi.fn()
1053
+ render(<DateRangePicker clearable aria-label="Select date range" defaultValue={testRange} onChange={handleChange} />)
1054
+
1055
+ const clearButton = screen.getByLabelText("Clear date range")
1056
+ clearButton.focus()
1057
+ await user.keyboard("{Enter}")
1058
+
1059
+ expect(handleChange).toHaveBeenCalledTimes(1)
1060
+ expect(handleChange.mock.calls[0]).toHaveLength(0)
1061
+ })
1062
+
1063
+ it("has data-slot on clear button", () => {
1064
+ render(<DateRangePicker clearable aria-label="Select date range" defaultValue={testRange} />)
1065
+ expect(screen.getByLabelText("Clear date range")).toHaveAttribute("data-slot", "date-range-picker-clear")
1066
+ })
1067
+ })
1068
+
1069
+ // ============================================
1070
+ // READ-ONLY TESTS
1071
+ // ============================================
1072
+ describe("ReadOnly", () => {
1073
+ it("applies aria-readonly when readOnly", () => {
1074
+ render(<DateRangePicker readOnly aria-label="Select date range" />)
1075
+ expect(screen.getByRole("combobox")).toHaveAttribute("aria-readonly", "true")
1076
+ })
1077
+
1078
+ it("applies data-readonly when readOnly", () => {
1079
+ render(<DateRangePicker readOnly aria-label="Select date range" />)
1080
+ expect(screen.getByRole("combobox")).toHaveAttribute("data-readonly")
1081
+ })
1082
+
1083
+ it("does not open calendar when readOnly", async () => {
1084
+ const user = userEvent.setup()
1085
+ render(<DateRangePicker readOnly aria-label="Select date range" />)
1086
+
1087
+ await user.click(screen.getByRole("combobox"))
1088
+
1089
+ expect(screen.queryByRole("dialog")).not.toBeInTheDocument()
1090
+ })
1091
+
1092
+ it("is still focusable when readOnly", () => {
1093
+ render(<DateRangePicker readOnly aria-label="Select date range" />)
1094
+ const trigger = screen.getByRole("combobox")
1095
+ trigger.focus()
1096
+ expect(trigger).toHaveFocus()
1097
+ })
1098
+
1099
+ it("displays value when readOnly", () => {
1100
+ render(<DateRangePicker readOnly aria-label="Select date range" defaultValue={testRange} />)
1101
+ expect(screen.getByRole("combobox")).toHaveTextContent("Jan 10, 2024")
1102
+ })
1103
+ })
1104
+
1105
+ // ============================================
1106
+ // FORM INTEGRATION TESTS
1107
+ // ============================================
1108
+ describe("Form Integration", () => {
1109
+ it("renders hidden inputs with name", () => {
1110
+ const { container } = render(<DateRangePicker aria-label="Select date range" name="daterange" />)
1111
+ const fromInput = container.querySelector('input[type="hidden"][name="daterange-from"]')
1112
+ const toInput = container.querySelector('input[type="hidden"][name="daterange-to"]')
1113
+ expect(fromInput).toBeInTheDocument()
1114
+ expect(toInput).toBeInTheDocument()
1115
+ })
1116
+
1117
+ it("hidden inputs have ISO date values", () => {
1118
+ const { container } = render(<DateRangePicker aria-label="Select date range" defaultValue={testRange} name="daterange" />)
1119
+ const fromInput = container.querySelector<HTMLInputElement>('input[name="daterange-from"]')
1120
+ const toInput = container.querySelector<HTMLInputElement>('input[name="daterange-to"]')
1121
+ expect(fromInput).toBeInTheDocument()
1122
+ expect(toInput).toBeInTheDocument()
1123
+ expect(fromInput?.value).toBe(testRange.from?.toISOString())
1124
+ expect(toInput?.value).toBe(testRange.to?.toISOString())
1125
+ })
1126
+
1127
+ it("hidden inputs are empty when no range selected", () => {
1128
+ const { container } = render(<DateRangePicker aria-label="Select date range" name="daterange" />)
1129
+ const fromInput = container.querySelector<HTMLInputElement>('input[name="daterange-from"]')
1130
+ const toInput = container.querySelector<HTMLInputElement>('input[name="daterange-to"]')
1131
+ expect(fromInput).toBeInTheDocument()
1132
+ expect(toInput).toBeInTheDocument()
1133
+ expect(fromInput?.value).toBe("")
1134
+ expect(toInput?.value).toBe("")
1135
+ })
1136
+
1137
+ it("supports id for label association", () => {
1138
+ render(<DateRangePicker aria-label="Select date range" id="daterange-input" />)
1139
+ expect(screen.getByRole("combobox")).toHaveAttribute("id", "daterange-input")
1140
+ })
1141
+ })
1142
+
1143
+ // ============================================
1144
+ // REF FORWARDING TESTS
1145
+ // ============================================
1146
+ describe("Ref Forwarding", () => {
1147
+ it("forwards ref to trigger button", () => {
1148
+ const ref = React.createRef<HTMLButtonElement>()
1149
+ render(<DateRangePicker ref={ref} aria-label="Select date range" />)
1150
+
1151
+ expect(ref.current).toBeInstanceOf(HTMLButtonElement)
1152
+ expect(ref.current).toBe(screen.getByRole("combobox"))
1153
+ })
1154
+
1155
+ it("allows programmatic focus via ref", () => {
1156
+ const ref = React.createRef<HTMLButtonElement>()
1157
+ render(<DateRangePicker ref={ref} aria-label="Select date range" />)
1158
+
1159
+ ref.current?.focus()
1160
+ expect(screen.getByRole("combobox")).toHaveFocus()
1161
+ })
1162
+ })
1163
+
1164
+ // ============================================
1165
+ // DATA ATTRIBUTE TESTS
1166
+ // ============================================
1167
+ describe("Data Attributes", () => {
1168
+ it("has data-slot on wrapper", () => {
1169
+ render(<DateRangePicker aria-label="Select date range" />)
1170
+ const wrapper = screen.getByRole("combobox").closest('[data-slot="date-range-picker"]')
1171
+ expect(wrapper).toBeInTheDocument()
1172
+ })
1173
+
1174
+ it("has data-slot on trigger", () => {
1175
+ render(<DateRangePicker aria-label="Select date range" />)
1176
+ expect(screen.getByRole("combobox")).toHaveAttribute("data-slot", "date-range-picker-trigger")
1177
+ })
1178
+
1179
+ it("has data-state on trigger", () => {
1180
+ render(<DateRangePicker aria-label="Select date range" />)
1181
+ expect(screen.getByRole("combobox")).toHaveAttribute("data-state", "closed")
1182
+ })
1183
+
1184
+ it("has data-state=open when opened", async () => {
1185
+ const user = userEvent.setup()
1186
+ render(<DateRangePicker aria-label="Select date range" />)
1187
+
1188
+ await openDateRangePicker(user)
1189
+
1190
+ await waitFor(() => {
1191
+ expect(screen.getByRole("combobox")).toHaveAttribute("data-state", "open")
1192
+ })
1193
+ })
1194
+
1195
+ it("has data-slot on content when opened", async () => {
1196
+ const user = userEvent.setup()
1197
+ render(<DateRangePicker aria-label="Select date range" />)
1198
+
1199
+ await openDateRangePicker(user)
1200
+
1201
+ await waitFor(() => {
1202
+ const content = document.querySelector('[data-slot="date-range-picker-content"]')
1203
+ expect(content).toBeInTheDocument()
1204
+ })
1205
+ })
1206
+ })
1207
+
1208
+ // ============================================
1209
+ // EDGE CASES TESTS
1210
+ // ============================================
1211
+ describe("Edge Cases", () => {
1212
+ it("handles empty className", () => {
1213
+ render(<DateRangePicker aria-label="Select date range" className="" />)
1214
+ expect(screen.getByRole("combobox")).toBeInTheDocument()
1215
+ })
1216
+
1217
+ it("handles rapid open/close correctly", async () => {
1218
+ const user = userEvent.setup()
1219
+ render(<DateRangePicker aria-label="Select date range" />)
1220
+
1221
+ const trigger = screen.getByRole("combobox")
1222
+ await user.click(trigger)
1223
+ await user.keyboard("{Escape}")
1224
+ await user.click(trigger)
1225
+ await user.keyboard("{Escape}")
1226
+ await user.click(trigger)
1227
+
1228
+ await waitFor(() => {
1229
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
1230
+ })
1231
+ })
1232
+
1233
+ it("maintains state through re-renders", () => {
1234
+ const { rerender } = render(<DateRangePicker aria-label="Select date range" defaultValue={testRange} />)
1235
+
1236
+ expect(screen.getByRole("combobox")).toHaveTextContent("Jan 10, 2024")
1237
+
1238
+ rerender(<DateRangePicker aria-label="Select date range" defaultValue={testRange} />)
1239
+ expect(screen.getByRole("combobox")).toHaveTextContent("Jan 10, 2024")
1240
+ })
1241
+
1242
+ it("handles undefined range gracefully", () => {
1243
+ render(<DateRangePicker aria-label="Select date range" value={undefined} onChange={() => {}} />)
1244
+ expect(screen.getByRole("combobox")).toBeInTheDocument()
1245
+ })
1246
+ })
1247
+
1248
+ // ============================================
1249
+ // TYPE SAFETY TESTS
1250
+ // ============================================
1251
+ describe("Type Safety", () => {
1252
+ it("accepts valid size prop values", () => {
1253
+ const sizes = ["sm", "md", "lg"] as const
1254
+ sizes.forEach((size) => {
1255
+ const { unmount } = render(<DateRangePicker aria-label="Select date range" size={size} />)
1256
+ expect(screen.getByRole("combobox")).toBeInTheDocument()
1257
+ unmount()
1258
+ })
1259
+ })
1260
+
1261
+ it("accepts valid variant prop values", () => {
1262
+ const variants = ["default", "outline", "ghost"] as const
1263
+ variants.forEach((variant) => {
1264
+ const { unmount } = render(<DateRangePicker aria-label="Select date range" variant={variant} />)
1265
+ expect(screen.getByRole("combobox")).toBeInTheDocument()
1266
+ unmount()
1267
+ })
1268
+ })
1269
+ })
1270
+ })
1271
+
1272
+ // ============================================
1273
+ // DATERANGEPRESETS TESTS
1274
+ // ============================================
1275
+ describe("DateRangePresets", () => {
1276
+ const mockPresets: DateRangePreset[] = [
1277
+ { label: "Today", getValue: () => ({ from: new Date(), to: new Date() }) },
1278
+ { label: "Yesterday", getValue: () => ({ from: new Date(), to: new Date() }) },
1279
+ ]
1280
+
1281
+ it("renders all presets", () => {
1282
+ const handleSelect = vi.fn()
1283
+ render(<DateRangePresets presets={mockPresets} onSelect={handleSelect} />)
1284
+
1285
+ expect(screen.getByRole("option", { name: "Today" })).toBeInTheDocument()
1286
+ expect(screen.getByRole("option", { name: "Yesterday" })).toBeInTheDocument()
1287
+ })
1288
+
1289
+ it("calls onSelect with range and label when preset clicked", async () => {
1290
+ const user = userEvent.setup()
1291
+ const handleSelect = vi.fn()
1292
+ render(<DateRangePresets presets={mockPresets} onSelect={handleSelect} />)
1293
+
1294
+ await user.click(screen.getByRole("option", { name: "Today" }))
1295
+
1296
+ expect(handleSelect).toHaveBeenCalled()
1297
+ expect(handleSelect.mock.calls[0]?.[1]).toBe("Today")
1298
+ })
1299
+
1300
+ it("highlights selected preset", () => {
1301
+ const handleSelect = vi.fn()
1302
+ render(<DateRangePresets presets={mockPresets} selectedPreset="Today" onSelect={handleSelect} />)
1303
+
1304
+ expect(screen.getByRole("option", { name: "Today" })).toHaveAttribute("data-selected")
1305
+ expect(screen.getByRole("option", { name: "Yesterday" })).not.toHaveAttribute("data-selected")
1306
+ })
1307
+
1308
+ it("has data-slot attribute", () => {
1309
+ const handleSelect = vi.fn()
1310
+ const { container } = render(<DateRangePresets presets={mockPresets} onSelect={handleSelect} />)
1311
+
1312
+ expect(container.querySelector('[data-slot="date-range-presets"]')).toBeInTheDocument()
1313
+ })
1314
+ })
1315
+
1316
+ // ============================================
1317
+ // DEFAULT PRESETS TESTS
1318
+ // ============================================
1319
+ describe("Default Presets", () => {
1320
+ it("has correct number of presets", () => {
1321
+ expect(defaultPresets.length).toBeGreaterThan(0)
1322
+ })
1323
+
1324
+ it("each preset has label and getValue", () => {
1325
+ defaultPresets.forEach((preset) => {
1326
+ expect(preset.label).toBeTruthy()
1327
+ expect(typeof preset.getValue).toBe("function")
1328
+ })
1329
+ })
1330
+
1331
+ it("each preset returns valid DateRange (except All time)", () => {
1332
+ defaultPresets
1333
+ .filter((preset) => preset.label !== "All time")
1334
+ .forEach((preset) => {
1335
+ const range = preset.getValue()
1336
+ expect(range.from).toBeInstanceOf(Date)
1337
+ expect(range.to).toBeInstanceOf(Date)
1338
+ })
1339
+ })
1340
+
1341
+ it("Today preset returns today's date", () => {
1342
+ const todayPreset = defaultPresets.find((p) => p.label === "Today")
1343
+ if (!todayPreset) throw new Error("Today preset not found")
1344
+
1345
+ const range = todayPreset.getValue()
1346
+ const today = new Date()
1347
+ expect(range.from?.getDate()).toBe(today.getDate())
1348
+ })
1349
+
1350
+ it("Yesterday preset returns yesterday's date", () => {
1351
+ const yesterdayPreset = defaultPresets.find((p) => p.label === "Yesterday")
1352
+ if (!yesterdayPreset) throw new Error("Yesterday preset not found")
1353
+
1354
+ const range = yesterdayPreset.getValue()
1355
+ const yesterday = new Date()
1356
+ yesterday.setDate(yesterday.getDate() - 1)
1357
+ expect(range.from?.getDate()).toBe(yesterday.getDate())
1358
+ })
1359
+
1360
+ it("This year preset returns current year range", () => {
1361
+ const thisYearPreset = defaultPresets.find((p) => p.label === "This year")
1362
+ if (!thisYearPreset) throw new Error("This year preset not found")
1363
+
1364
+ const range = thisYearPreset.getValue()
1365
+ const currentYear = new Date().getFullYear()
1366
+ expect(range.from?.getFullYear()).toBe(currentYear)
1367
+ expect(range.from?.getMonth()).toBe(0) // January
1368
+ expect(range.from?.getDate()).toBe(1)
1369
+ expect(range.to?.getFullYear()).toBe(currentYear)
1370
+ expect(range.to?.getMonth()).toBe(11) // December
1371
+ expect(range.to?.getDate()).toBe(31)
1372
+ })
1373
+
1374
+ it("Last year preset returns previous year range", () => {
1375
+ const lastYearPreset = defaultPresets.find((p) => p.label === "Last year")
1376
+ if (!lastYearPreset) throw new Error("Last year preset not found")
1377
+
1378
+ const range = lastYearPreset.getValue()
1379
+ const lastYear = new Date().getFullYear() - 1
1380
+ expect(range.from?.getFullYear()).toBe(lastYear)
1381
+ expect(range.from?.getMonth()).toBe(0) // January
1382
+ expect(range.from?.getDate()).toBe(1)
1383
+ expect(range.to?.getFullYear()).toBe(lastYear)
1384
+ expect(range.to?.getMonth()).toBe(11) // December
1385
+ expect(range.to?.getDate()).toBe(31)
1386
+ })
1387
+
1388
+ it("All time preset returns undefined dates", () => {
1389
+ const allTimePreset = defaultPresets.find((p) => p.label === "All time")
1390
+ if (!allTimePreset) throw new Error("All time preset not found")
1391
+
1392
+ const range = allTimePreset.getValue()
1393
+ expect(range.from).toBeUndefined()
1394
+ expect(range.to).toBeUndefined()
1395
+ })
1396
+ })
1397
+
1398
+ // ============================================
1399
+ // TODAY BUTTON TESTS
1400
+ // ============================================
1401
+ describe("Today Button", () => {
1402
+ it("shows Today button by default", async () => {
1403
+ const user = userEvent.setup()
1404
+ render(<DateRangePicker aria-label="Select date range" />)
1405
+
1406
+ await openDateRangePicker(user)
1407
+
1408
+ await waitFor(() => {
1409
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
1410
+ })
1411
+
1412
+ expect(screen.getByRole("button", { name: "Today" })).toBeInTheDocument()
1413
+ })
1414
+
1415
+ it("hides Today button when showTodayButton is false", async () => {
1416
+ const user = userEvent.setup()
1417
+ render(<DateRangePicker aria-label="Select date range" showTodayButton={false} />)
1418
+
1419
+ await openDateRangePicker(user)
1420
+
1421
+ await waitFor(() => {
1422
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
1423
+ })
1424
+
1425
+ // Should not have the Today button (the one in header, not the preset option)
1426
+ const header = document.querySelector('[data-slot="date-range-picker-header"]')
1427
+ expect(header).not.toBeInTheDocument()
1428
+ })
1429
+
1430
+ it("has header with data-slot attribute", async () => {
1431
+ const user = userEvent.setup()
1432
+ render(<DateRangePicker aria-label="Select date range" />)
1433
+
1434
+ await openDateRangePicker(user)
1435
+
1436
+ await waitFor(() => {
1437
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
1438
+ })
1439
+
1440
+ const header = document.querySelector('[data-slot="date-range-picker-header"]')
1441
+ expect(header).toBeInTheDocument()
1442
+ })
1443
+
1444
+ it("Today button navigates calendar to current month", async () => {
1445
+ const user = userEvent.setup()
1446
+ // Start with a date in a different month/year
1447
+ const pastDate = new Date(2020, 5, 15) // June 15, 2020
1448
+ render(
1449
+ <DateRangePicker
1450
+ aria-label="Select date range"
1451
+ defaultValue={{ from: pastDate, to: pastDate }}
1452
+ />
1453
+ )
1454
+
1455
+ await openDateRangePicker(user)
1456
+
1457
+ await waitFor(() => {
1458
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
1459
+ })
1460
+
1461
+ // Click the Today button (in header, not the preset)
1462
+ const header = document.querySelector('[data-slot="date-range-picker-header"]')
1463
+ const todayButton = within(header as HTMLElement).getByRole("button", { name: "Today" })
1464
+ await user.click(todayButton)
1465
+
1466
+ // After clicking, the calendar should show the current month
1467
+ const currentMonth = new Date().toLocaleString("default", { month: "long" })
1468
+ const currentYear = new Date().getFullYear()
1469
+
1470
+ await waitFor(() => {
1471
+ // The calendar should now show the current month/year
1472
+ const calendarText = document.querySelector('[data-slot="date-range-picker-content"]')?.textContent
1473
+ expect(calendarText).toContain(currentMonth)
1474
+ expect(calendarText).toContain(String(currentYear))
1475
+ })
1476
+ })
1477
+ })
1478
+
1479
+ // ============================================
1480
+ // MODAL VARIANT TESTS
1481
+ // ============================================
1482
+ describe("Modal Variant", () => {
1483
+ it("renders in popover mode by default", () => {
1484
+ render(<DateRangePicker aria-label="Select date range" />)
1485
+ const wrapper = screen.getByRole("combobox").closest('[data-slot="date-range-picker"]')
1486
+ expect(wrapper).toHaveAttribute("data-mode", "popover")
1487
+ })
1488
+
1489
+ it("renders in modal mode when displayMode is modal", () => {
1490
+ render(<DateRangePicker aria-label="Select date range" displayMode="modal" />)
1491
+ const wrapper = screen.getByRole("combobox").closest('[data-slot="date-range-picker"]')
1492
+ expect(wrapper).toHaveAttribute("data-mode", "modal")
1493
+ })
1494
+
1495
+ it("opens modal dialog when displayMode is modal", async () => {
1496
+ const user = userEvent.setup()
1497
+ render(<DateRangePicker aria-label="Select date range" displayMode="modal" />)
1498
+
1499
+ await user.click(screen.getByRole("combobox"))
1500
+
1501
+ await waitFor(() => {
1502
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
1503
+ })
1504
+ })
1505
+
1506
+ it("shows modal title when displayMode is modal", async () => {
1507
+ const user = userEvent.setup()
1508
+ render(
1509
+ <DateRangePicker
1510
+ aria-label="Select date range"
1511
+ displayMode="modal"
1512
+ modalTitle="Choose your dates"
1513
+ />
1514
+ )
1515
+
1516
+ await user.click(screen.getByRole("combobox"))
1517
+
1518
+ await waitFor(() => {
1519
+ expect(screen.getByText("Choose your dates")).toBeInTheDocument()
1520
+ })
1521
+ })
1522
+
1523
+ it("uses default modal title when not specified", async () => {
1524
+ const user = userEvent.setup()
1525
+ render(<DateRangePicker aria-label="Select date range" displayMode="modal" />)
1526
+
1527
+ await user.click(screen.getByRole("combobox"))
1528
+
1529
+ await waitFor(() => {
1530
+ expect(screen.getByText("Select Date Range")).toBeInTheDocument()
1531
+ })
1532
+ })
1533
+
1534
+ it("modal mode supports presets", async () => {
1535
+ const user = userEvent.setup()
1536
+ render(<DateRangePicker aria-label="Select date range" displayMode="modal" />)
1537
+
1538
+ await user.click(screen.getByRole("combobox"))
1539
+
1540
+ await waitFor(() => {
1541
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
1542
+ })
1543
+
1544
+ expect(screen.getByRole("option", { name: "Today" })).toBeInTheDocument()
1545
+ })
1546
+
1547
+ it("modal mode supports confirmation buttons", async () => {
1548
+ const user = userEvent.setup()
1549
+ render(
1550
+ <DateRangePicker
1551
+ requireConfirmation
1552
+ aria-label="Select date range"
1553
+ displayMode="modal"
1554
+ />
1555
+ )
1556
+
1557
+ await user.click(screen.getByRole("combobox"))
1558
+
1559
+ await waitFor(() => {
1560
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
1561
+ })
1562
+
1563
+ expect(screen.getByRole("button", { name: "Cancel" })).toBeInTheDocument()
1564
+ expect(screen.getByRole("button", { name: "Apply" })).toBeInTheDocument()
1565
+ })
1566
+
1567
+ it("closes modal with Cancel button", async () => {
1568
+ const user = userEvent.setup()
1569
+ render(
1570
+ <DateRangePicker
1571
+ requireConfirmation
1572
+ aria-label="Select date range"
1573
+ displayMode="modal"
1574
+ />
1575
+ )
1576
+
1577
+ await user.click(screen.getByRole("combobox"))
1578
+
1579
+ await waitFor(() => {
1580
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
1581
+ })
1582
+
1583
+ await user.click(screen.getByRole("button", { name: "Cancel" }))
1584
+
1585
+ await waitFor(() => {
1586
+ expect(screen.queryByRole("dialog")).not.toBeInTheDocument()
1587
+ })
1588
+ })
1589
+ })
1590
+
1591
+ // ============================================
1592
+ // ACTIVE DATES TESTS
1593
+ // ============================================
1594
+ describe("Active Dates", () => {
1595
+ const activeDatesArray = [
1596
+ new Date(2024, 0, 15), // January 15, 2024
1597
+ new Date(2024, 0, 20), // January 20, 2024
1598
+ ]
1599
+
1600
+ it("accepts activeDates as array", async () => {
1601
+ const user = userEvent.setup()
1602
+ render(
1603
+ <DateRangePicker
1604
+ activeDates={activeDatesArray}
1605
+ aria-label="Select date range"
1606
+ defaultValue={{ from: new Date(2024, 0, 1), to: new Date(2024, 0, 10) }}
1607
+ />
1608
+ )
1609
+
1610
+ await openDateRangePicker(user)
1611
+
1612
+ await waitFor(() => {
1613
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
1614
+ })
1615
+
1616
+ // Component should render without errors
1617
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
1618
+ })
1619
+
1620
+ it("accepts activeDates as function", async () => {
1621
+ const user = userEvent.setup()
1622
+ const isActive = (date: Date) => date.getDay() === 0 // Sundays
1623
+
1624
+ render(
1625
+ <DateRangePicker
1626
+ activeDates={isActive}
1627
+ aria-label="Select date range"
1628
+ defaultValue={{ from: new Date(2024, 0, 1), to: new Date(2024, 0, 10) }}
1629
+ />
1630
+ )
1631
+
1632
+ await openDateRangePicker(user)
1633
+
1634
+ await waitFor(() => {
1635
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
1636
+ })
1637
+
1638
+ // Component should render without errors
1639
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
1640
+ })
1641
+
1642
+ it("renders active indicator on active dates", async () => {
1643
+ const user = userEvent.setup()
1644
+ render(
1645
+ <DateRangePicker
1646
+ activeDates={activeDatesArray}
1647
+ aria-label="Select date range"
1648
+ defaultValue={{ from: new Date(2024, 0, 1), to: new Date(2024, 0, 10) }}
1649
+ />
1650
+ )
1651
+
1652
+ await openDateRangePicker(user)
1653
+
1654
+ await waitFor(() => {
1655
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
1656
+ })
1657
+
1658
+ // Check for active indicators - they are rendered with data-slot="active-indicator"
1659
+ const dialog = screen.getByRole("dialog")
1660
+ const day15Button = findDayButton(dialog, 15)
1661
+ expect(day15Button).toHaveAttribute("data-active")
1662
+ })
1663
+
1664
+ it("does not show active indicator on non-active dates", async () => {
1665
+ const user = userEvent.setup()
1666
+ render(
1667
+ <DateRangePicker
1668
+ activeDates={activeDatesArray}
1669
+ aria-label="Select date range"
1670
+ defaultValue={{ from: new Date(2024, 0, 1), to: new Date(2024, 0, 10) }}
1671
+ />
1672
+ )
1673
+
1674
+ await openDateRangePicker(user)
1675
+
1676
+ await waitFor(() => {
1677
+ expect(screen.getByRole("dialog")).toBeInTheDocument()
1678
+ })
1679
+
1680
+ const dialog = screen.getByRole("dialog")
1681
+ const day16Button = findDayButton(dialog, 16)
1682
+ expect(day16Button).toHaveAttribute("data-active", "false")
1683
+ })
1684
+ })