@aleph-alpha/ui-library 1.9.0 → 1.10.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 (437) hide show
  1. package/README.md +14 -0
  2. package/dist/mcp/cli.js +21588 -0
  3. package/dist/mcp/index.js +7 -0
  4. package/dist/mcp/scripts/generate-component-meta.js +236 -0
  5. package/dist/mcp/server.js +21456 -0
  6. package/dist/system/index-CkH7HQaa.js +7 -0
  7. package/dist/system/index-CuHwEAQ_.js +7 -0
  8. package/dist/system/index.d.ts +1322 -318
  9. package/dist/system/lib.js +8839 -6993
  10. package/mcp/components-meta.json +1172 -0
  11. package/package.json +12 -2
  12. package/src/@types/shims-vue.d.ts +5 -0
  13. package/src/__tests__/placeholder.test.ts +7 -0
  14. package/src/compositions/UiCompositionPlaceholder/UiCompositionPlaceholder.vue +9 -0
  15. package/src/compositions/UiCompositionPlaceholder/index.ts +1 -0
  16. package/src/compositions/UiCompositionPlaceholder/types.ts +8 -0
  17. package/src/compositions/UiDataTable/UiDataTable.mock.ts +104 -0
  18. package/src/compositions/UiDataTable/UiDataTable.stories.ts +1575 -0
  19. package/src/compositions/UiDataTable/UiDataTable.vue +129 -0
  20. package/src/compositions/UiDataTable/UiDataTableColumnHeader.vue +97 -0
  21. package/src/compositions/UiDataTable/UiDataTablePagination.vue +147 -0
  22. package/src/compositions/UiDataTable/UiDataTableToolbar.vue +85 -0
  23. package/src/compositions/UiDataTable/__tests__/UiDataTable.test.ts +372 -0
  24. package/src/compositions/UiDataTable/__tests__/UiDataTableColumnHeader.test.ts +217 -0
  25. package/src/compositions/UiDataTable/__tests__/UiDataTablePagination.test.ts +274 -0
  26. package/src/compositions/UiDataTable/__tests__/UiDataTableToolbar.test.ts +198 -0
  27. package/src/compositions/UiDataTable/constants.ts +77 -0
  28. package/src/compositions/UiDataTable/index.ts +6 -0
  29. package/src/compositions/UiDataTable/types.ts +39 -0
  30. package/src/compositions/UiDatePicker/UiDatePicker.stories.ts +976 -0
  31. package/src/compositions/UiDatePicker/UiDatePicker.vue +193 -0
  32. package/src/compositions/UiDatePicker/__tests__/UiDatePicker.test.ts +325 -0
  33. package/src/compositions/UiDatePicker/index.ts +14 -0
  34. package/src/compositions/UiDatePicker/types.ts +220 -0
  35. package/src/compositions/index.ts +8 -0
  36. package/src/foundations/UiPlaceholder/UiPlaceholder.vue +9 -0
  37. package/src/foundations/UiPlaceholder/index.ts +1 -0
  38. package/src/foundations/UiPlaceholder/types.ts +8 -0
  39. package/src/foundations/index.ts +6 -0
  40. package/src/index.ts +27 -0
  41. package/src/lib/utils.ts +6 -0
  42. package/src/primitives/UiAccordion/UiAccordion.stories.ts +476 -0
  43. package/src/primitives/UiAccordion/UiAccordion.vue +31 -0
  44. package/src/primitives/UiAccordion/UiAccordionContent.vue +16 -0
  45. package/src/primitives/UiAccordion/UiAccordionItem.vue +16 -0
  46. package/src/primitives/UiAccordion/UiAccordionTrigger.vue +23 -0
  47. package/src/primitives/UiAccordion/__tests__/UiAccordion.test.ts +198 -0
  48. package/src/primitives/UiAccordion/index.ts +6 -0
  49. package/src/primitives/UiAccordion/types.ts +95 -0
  50. package/src/primitives/UiAlert/UiAlert.stories.ts +199 -0
  51. package/src/primitives/UiAlert/UiAlert.vue +27 -0
  52. package/src/primitives/UiAlert/UiAlertDescription.vue +13 -0
  53. package/src/primitives/UiAlert/UiAlertTitle.vue +13 -0
  54. package/src/primitives/UiAlert/__tests__/UiAlert.test.ts +20 -0
  55. package/src/primitives/UiAlert/constants.ts +3 -0
  56. package/src/primitives/UiAlert/index.ts +5 -0
  57. package/src/primitives/UiAlert/types.ts +14 -0
  58. package/src/primitives/UiAlertDialog/UiAlertDialog.stories.ts +186 -0
  59. package/src/primitives/UiAlertDialog/UiAlertDialog.vue +18 -0
  60. package/src/primitives/UiAlertDialog/UiAlertDialogAction.vue +16 -0
  61. package/src/primitives/UiAlertDialog/UiAlertDialogCancel.vue +16 -0
  62. package/src/primitives/UiAlertDialog/UiAlertDialogContent.vue +26 -0
  63. package/src/primitives/UiAlertDialog/UiAlertDialogDescription.vue +16 -0
  64. package/src/primitives/UiAlertDialog/UiAlertDialogFooter.vue +13 -0
  65. package/src/primitives/UiAlertDialog/UiAlertDialogHeader.vue +16 -0
  66. package/src/primitives/UiAlertDialog/UiAlertDialogTitle.vue +16 -0
  67. package/src/primitives/UiAlertDialog/UiAlertDialogTrigger.vue +17 -0
  68. package/src/primitives/UiAlertDialog/__tests__/UiAlertDialog.test.ts +184 -0
  69. package/src/primitives/UiAlertDialog/index.ts +9 -0
  70. package/src/primitives/UiAlertDialog/types.ts +83 -0
  71. package/src/primitives/UiAvatar/UiAvatar.stories.ts +194 -0
  72. package/src/primitives/UiAvatar/UiAvatar.vue +13 -0
  73. package/src/primitives/UiAvatar/UiAvatarFallback.vue +13 -0
  74. package/src/primitives/UiAvatar/UiAvatarImage.vue +14 -0
  75. package/src/primitives/UiAvatar/__tests__/UiAvatar.test.ts +36 -0
  76. package/src/primitives/UiAvatar/index.ts +3 -0
  77. package/src/primitives/UiAvatar/types.ts +17 -0
  78. package/src/primitives/UiBadge/UiBadge.stories.ts +373 -0
  79. package/src/primitives/UiBadge/UiBadge.vue +21 -0
  80. package/src/primitives/UiBadge/__tests__/UiBadge.test.ts +44 -0
  81. package/src/primitives/UiBadge/constants.ts +3 -0
  82. package/src/primitives/UiBadge/index.ts +2 -0
  83. package/src/primitives/UiBadge/types.ts +48 -0
  84. package/src/primitives/UiButton/UiButton.stories.ts +537 -0
  85. package/src/primitives/UiButton/UiButton.vue +72 -0
  86. package/src/primitives/UiButton/__tests__/UiButton.test.ts +133 -0
  87. package/src/primitives/UiButton/index.ts +2 -0
  88. package/src/primitives/UiButton/types.ts +87 -0
  89. package/src/primitives/UiCalendar/UiCalendar.stories.ts +797 -0
  90. package/src/primitives/UiCalendar/UiCalendar.vue +67 -0
  91. package/src/primitives/UiCalendar/__tests__/UiCalendar.test.ts +45 -0
  92. package/src/primitives/UiCalendar/index.ts +15 -0
  93. package/src/primitives/UiCalendar/types.ts +236 -0
  94. package/src/primitives/UiCard/UiCard.stories.ts +197 -0
  95. package/src/primitives/UiCard/UiCard.vue +13 -0
  96. package/src/primitives/UiCard/UiCardAction.vue +13 -0
  97. package/src/primitives/UiCard/UiCardContent.vue +13 -0
  98. package/src/primitives/UiCard/UiCardDescription.vue +13 -0
  99. package/src/primitives/UiCard/UiCardFooter.vue +13 -0
  100. package/src/primitives/UiCard/UiCardHeader.vue +13 -0
  101. package/src/primitives/UiCard/UiCardTitle.vue +13 -0
  102. package/src/primitives/UiCard/__tests__/UiCard.test.ts +19 -0
  103. package/src/primitives/UiCard/__tests__/UiCardAction.test.ts +19 -0
  104. package/src/primitives/UiCard/__tests__/UiCardContent.test.ts +19 -0
  105. package/src/primitives/UiCard/__tests__/UiCardDescription.test.ts +19 -0
  106. package/src/primitives/UiCard/__tests__/UiCardFooter.test.ts +19 -0
  107. package/src/primitives/UiCard/__tests__/UiCardHeader.test.ts +19 -0
  108. package/src/primitives/UiCard/__tests__/UiCardTitle.test.ts +19 -0
  109. package/src/primitives/UiCard/index.ts +7 -0
  110. package/src/primitives/UiCard/types.ts +10 -0
  111. package/src/primitives/UiCheckbox/UiCheckbox.stories.ts +231 -0
  112. package/src/primitives/UiCheckbox/UiCheckbox.vue +19 -0
  113. package/src/primitives/UiCheckbox/__tests__/UiCheckbox.test.ts +29 -0
  114. package/src/primitives/UiCheckbox/index.ts +2 -0
  115. package/src/primitives/UiCheckbox/types.ts +30 -0
  116. package/src/primitives/UiDrawer/UiDrawer.stories.ts +602 -0
  117. package/src/primitives/UiDrawer/UiDrawer.vue +19 -0
  118. package/src/primitives/UiDrawer/UiDrawerClose.vue +16 -0
  119. package/src/primitives/UiDrawer/UiDrawerContent.vue +29 -0
  120. package/src/primitives/UiDrawer/UiDrawerDescription.vue +16 -0
  121. package/src/primitives/UiDrawer/UiDrawerFooter.vue +16 -0
  122. package/src/primitives/UiDrawer/UiDrawerHeader.vue +16 -0
  123. package/src/primitives/UiDrawer/UiDrawerTitle.vue +16 -0
  124. package/src/primitives/UiDrawer/UiDrawerTrigger.vue +16 -0
  125. package/src/primitives/UiDrawer/__tests__/UiDrawer.test.ts +229 -0
  126. package/src/primitives/UiDrawer/index.ts +8 -0
  127. package/src/primitives/UiDrawer/types.ts +96 -0
  128. package/src/primitives/UiDropdownMenu/UiDropdownMenu.stories.ts +760 -0
  129. package/src/primitives/UiDropdownMenu/UiDropdownMenu.vue +25 -0
  130. package/src/primitives/UiDropdownMenu/UiDropdownMenuCheckboxItem.vue +29 -0
  131. package/src/primitives/UiDropdownMenu/UiDropdownMenuContent.vue +27 -0
  132. package/src/primitives/UiDropdownMenu/UiDropdownMenuGroup.vue +13 -0
  133. package/src/primitives/UiDropdownMenu/UiDropdownMenuItem.vue +26 -0
  134. package/src/primitives/UiDropdownMenu/UiDropdownMenuLabel.vue +18 -0
  135. package/src/primitives/UiDropdownMenu/UiDropdownMenuRadioGroup.vue +20 -0
  136. package/src/primitives/UiDropdownMenu/UiDropdownMenuRadioItem.vue +26 -0
  137. package/src/primitives/UiDropdownMenu/UiDropdownMenuSeparator.vue +11 -0
  138. package/src/primitives/UiDropdownMenu/UiDropdownMenuShortcut.vue +13 -0
  139. package/src/primitives/UiDropdownMenu/UiDropdownMenuSub.vue +26 -0
  140. package/src/primitives/UiDropdownMenu/UiDropdownMenuSubContent.vue +23 -0
  141. package/src/primitives/UiDropdownMenu/UiDropdownMenuSubTrigger.vue +24 -0
  142. package/src/primitives/UiDropdownMenu/UiDropdownMenuTrigger.vue +24 -0
  143. package/src/primitives/UiDropdownMenu/__tests__/UiDropdownMenu.test.ts +557 -0
  144. package/src/primitives/UiDropdownMenu/index.ts +16 -0
  145. package/src/primitives/UiDropdownMenu/types.ts +219 -0
  146. package/src/primitives/UiField/UiField.stories.ts +1496 -0
  147. package/src/primitives/UiField/UiField.vue +18 -0
  148. package/src/primitives/UiField/UiFieldContent.vue +13 -0
  149. package/src/primitives/UiField/UiFieldDescription.vue +13 -0
  150. package/src/primitives/UiField/UiFieldError.vue +20 -0
  151. package/src/primitives/UiField/UiFieldGroup.vue +13 -0
  152. package/src/primitives/UiField/UiFieldLabel.vue +16 -0
  153. package/src/primitives/UiField/UiFieldLegend.vue +13 -0
  154. package/src/primitives/UiField/UiFieldSeparator.vue +13 -0
  155. package/src/primitives/UiField/UiFieldSet.vue +13 -0
  156. package/src/primitives/UiField/UiFieldTitle.vue +13 -0
  157. package/src/primitives/UiField/__tests__/UiFieldError.test.ts +35 -0
  158. package/src/primitives/UiField/index.ts +10 -0
  159. package/src/primitives/UiField/types.ts +47 -0
  160. package/src/primitives/UiIcon/UiIcon.stories.ts +95 -0
  161. package/src/primitives/UiIcon/UiIcon.vue +14 -0
  162. package/src/primitives/UiIcon/__tests__/UiIcon.test.ts +24 -0
  163. package/src/primitives/UiIcon/index.ts +1 -0
  164. package/src/primitives/UiIcon/types.ts +23 -0
  165. package/src/primitives/UiIconButton/UiIconButton.stories.ts +446 -0
  166. package/src/primitives/UiIconButton/UiIconButton.vue +63 -0
  167. package/src/primitives/UiIconButton/__tests__/UiIconButton.test.ts +102 -0
  168. package/src/primitives/UiIconButton/index.ts +2 -0
  169. package/src/primitives/UiIconButton/types.ts +67 -0
  170. package/src/primitives/UiInput/UiInput.stories.ts +193 -0
  171. package/src/primitives/UiInput/UiInput.vue +19 -0
  172. package/src/primitives/UiInput/__tests__/UiInput.test.ts +38 -0
  173. package/src/primitives/UiInput/index.ts +2 -0
  174. package/src/primitives/UiInput/types.ts +31 -0
  175. package/src/primitives/UiPopover/UiPopover.stories.ts +394 -0
  176. package/src/primitives/UiPopover/UiPopover.vue +17 -0
  177. package/src/primitives/UiPopover/UiPopoverContent.vue +27 -0
  178. package/src/primitives/UiPopover/UiPopoverTrigger.vue +16 -0
  179. package/src/primitives/UiPopover/__tests__/UiPopover.test.ts +87 -0
  180. package/src/primitives/UiPopover/index.ts +5 -0
  181. package/src/primitives/UiPopover/types.ts +86 -0
  182. package/src/primitives/UiProgress/UiProgress.stories.ts +92 -0
  183. package/src/primitives/UiProgress/UiProgress.vue +25 -0
  184. package/src/primitives/UiProgress/__tests__/UiProgress.test.ts +46 -0
  185. package/src/primitives/UiProgress/index.ts +2 -0
  186. package/src/primitives/UiProgress/types.ts +16 -0
  187. package/src/primitives/UiRadioGroup/UiRadioGroup.stories.ts +291 -0
  188. package/src/primitives/UiRadioGroup/UiRadioGroup.vue +43 -0
  189. package/src/primitives/UiRadioGroup/UiRadioGroupItem.vue +18 -0
  190. package/src/primitives/UiRadioGroup/__tests__/UiRadioGroup.test.ts +404 -0
  191. package/src/primitives/UiRadioGroup/index.ts +4 -0
  192. package/src/primitives/UiRadioGroup/types.ts +66 -0
  193. package/src/primitives/UiRangeCalendar/UiRangeCalendar.stories.ts +609 -0
  194. package/src/primitives/UiRangeCalendar/UiRangeCalendar.vue +50 -0
  195. package/src/primitives/UiRangeCalendar/__tests__/UiRangeCalendar.test.ts +35 -0
  196. package/src/primitives/UiRangeCalendar/index.ts +13 -0
  197. package/src/primitives/UiRangeCalendar/types.ts +184 -0
  198. package/src/primitives/UiSelect/UiSelect.stories.ts +425 -0
  199. package/src/primitives/UiSelect/UiSelect.vue +47 -0
  200. package/src/primitives/UiSelect/UiSelectContent.vue +30 -0
  201. package/src/primitives/UiSelect/UiSelectGroup.vue +13 -0
  202. package/src/primitives/UiSelect/UiSelectItem.vue +19 -0
  203. package/src/primitives/UiSelect/UiSelectLabel.vue +13 -0
  204. package/src/primitives/UiSelect/UiSelectSeparator.vue +11 -0
  205. package/src/primitives/UiSelect/UiSelectTrigger.vue +30 -0
  206. package/src/primitives/UiSelect/UiSelectValue.vue +18 -0
  207. package/src/primitives/UiSelect/__tests__/UiSelect.test.ts +211 -0
  208. package/src/primitives/UiSelect/__tests__/UiSelectContent.test.ts +30 -0
  209. package/src/primitives/UiSelect/__tests__/UiSelectGroup.test.ts +85 -0
  210. package/src/primitives/UiSelect/__tests__/UiSelectItem.test.ts +79 -0
  211. package/src/primitives/UiSelect/__tests__/UiSelectLabel.test.ts +83 -0
  212. package/src/primitives/UiSelect/__tests__/UiSelectSeparator.test.ts +82 -0
  213. package/src/primitives/UiSelect/__tests__/UiSelectTrigger.test.ts +54 -0
  214. package/src/primitives/UiSelect/__tests__/UiSelectValue.test.ts +39 -0
  215. package/src/primitives/UiSelect/index.ts +10 -0
  216. package/src/primitives/UiSelect/types.ts +93 -0
  217. package/src/primitives/UiSlider/UiSlider.stories.ts +226 -0
  218. package/src/primitives/UiSlider/UiSlider.vue +44 -0
  219. package/src/primitives/UiSlider/__tests__/UiSlider.test.ts +76 -0
  220. package/src/primitives/UiSlider/index.ts +1 -0
  221. package/src/primitives/UiSlider/types.ts +101 -0
  222. package/src/primitives/UiSpinner/UiSpinner.stories.ts +143 -0
  223. package/src/primitives/UiSpinner/UiSpinner.vue +16 -0
  224. package/src/primitives/UiSpinner/__tests__/UiSpinner.test.ts +19 -0
  225. package/src/primitives/UiSpinner/index.ts +2 -0
  226. package/src/primitives/UiSpinner/types.ts +16 -0
  227. package/src/primitives/UiSwitch/UiSwitch.stories.ts +120 -0
  228. package/src/primitives/UiSwitch/UiSwitch.vue +21 -0
  229. package/src/primitives/UiSwitch/__tests__/UiSwitch.test.ts +47 -0
  230. package/src/primitives/UiSwitch/index.ts +2 -0
  231. package/src/primitives/UiSwitch/types.ts +25 -0
  232. package/src/primitives/UiTable/UiTable.stories.ts +505 -0
  233. package/src/primitives/UiTable/UiTable.vue +13 -0
  234. package/src/primitives/UiTable/UiTableBody.vue +13 -0
  235. package/src/primitives/UiTable/UiTableCaption.vue +13 -0
  236. package/src/primitives/UiTable/UiTableCell.vue +16 -0
  237. package/src/primitives/UiTable/UiTableEmpty.vue +18 -0
  238. package/src/primitives/UiTable/UiTableFooter.vue +13 -0
  239. package/src/primitives/UiTable/UiTableHead.vue +18 -0
  240. package/src/primitives/UiTable/UiTableHeader.vue +13 -0
  241. package/src/primitives/UiTable/UiTableRow.vue +18 -0
  242. package/src/primitives/UiTable/__tests__/UiTable.test.ts +19 -0
  243. package/src/primitives/UiTable/__tests__/UiTableBody.test.ts +19 -0
  244. package/src/primitives/UiTable/__tests__/UiTableCaption.test.ts +19 -0
  245. package/src/primitives/UiTable/__tests__/UiTableCell.test.ts +26 -0
  246. package/src/primitives/UiTable/__tests__/UiTableEmpty.test.ts +32 -0
  247. package/src/primitives/UiTable/__tests__/UiTableFooter.test.ts +19 -0
  248. package/src/primitives/UiTable/__tests__/UiTableHead.test.ts +43 -0
  249. package/src/primitives/UiTable/__tests__/UiTableHeader.test.ts +19 -0
  250. package/src/primitives/UiTable/__tests__/UiTableRow.test.ts +32 -0
  251. package/src/primitives/UiTable/index.ts +16 -0
  252. package/src/primitives/UiTable/types.ts +68 -0
  253. package/src/primitives/UiTabs/UiTabs.stories.ts +456 -0
  254. package/src/primitives/UiTabs/UiTabs.vue +31 -0
  255. package/src/primitives/UiTabs/UiTabsContent.vue +16 -0
  256. package/src/primitives/UiTabs/UiTabsList.vue +16 -0
  257. package/src/primitives/UiTabs/UiTabsTrigger.vue +16 -0
  258. package/src/primitives/UiTabs/__tests__/UiTabs.test.ts +122 -0
  259. package/src/primitives/UiTabs/index.ts +6 -0
  260. package/src/primitives/UiTabs/types.ts +68 -0
  261. package/src/primitives/UiTextarea/UiTextarea.stories.ts +107 -0
  262. package/src/primitives/UiTextarea/UiTextarea.vue +19 -0
  263. package/src/primitives/UiTextarea/__tests__/UiTextarea.test.ts +40 -0
  264. package/src/primitives/UiTextarea/index.ts +2 -0
  265. package/src/primitives/UiTextarea/types.ts +30 -0
  266. package/src/primitives/UiTooltip/UiTooltip.stories.ts +550 -0
  267. package/src/primitives/UiTooltip/UiTooltip.vue +42 -0
  268. package/src/primitives/UiTooltip/__tests__/UiTooltip.test.ts +78 -0
  269. package/src/primitives/UiTooltip/index.ts +2 -0
  270. package/src/primitives/UiTooltip/types.ts +53 -0
  271. package/src/primitives/index.ts +33 -0
  272. package/src/primitives/shadcn/accordion/Accordion.vue +15 -0
  273. package/src/primitives/shadcn/accordion/AccordionContent.vue +23 -0
  274. package/src/primitives/shadcn/accordion/AccordionItem.vue +24 -0
  275. package/src/primitives/shadcn/accordion/AccordionTrigger.vue +35 -0
  276. package/src/primitives/shadcn/accordion/index.ts +4 -0
  277. package/src/primitives/shadcn/alert/Alert.vue +17 -0
  278. package/src/primitives/shadcn/alert/AlertDescription.vue +22 -0
  279. package/src/primitives/shadcn/alert/AlertTitle.vue +17 -0
  280. package/src/primitives/shadcn/alert/index.ts +24 -0
  281. package/src/primitives/shadcn/alert-dialog/AlertDialog.vue +15 -0
  282. package/src/primitives/shadcn/alert-dialog/AlertDialogAction.vue +18 -0
  283. package/src/primitives/shadcn/alert-dialog/AlertDialogCancel.vue +21 -0
  284. package/src/primitives/shadcn/alert-dialog/AlertDialogContent.vue +44 -0
  285. package/src/primitives/shadcn/alert-dialog/AlertDialogDescription.vue +21 -0
  286. package/src/primitives/shadcn/alert-dialog/AlertDialogFooter.vue +17 -0
  287. package/src/primitives/shadcn/alert-dialog/AlertDialogHeader.vue +17 -0
  288. package/src/primitives/shadcn/alert-dialog/AlertDialogTitle.vue +21 -0
  289. package/src/primitives/shadcn/alert-dialog/AlertDialogTrigger.vue +12 -0
  290. package/src/primitives/shadcn/alert-dialog/index.ts +9 -0
  291. package/src/primitives/shadcn/avatar/Avatar.vue +18 -0
  292. package/src/primitives/shadcn/avatar/AvatarFallback.vue +21 -0
  293. package/src/primitives/shadcn/avatar/AvatarImage.vue +12 -0
  294. package/src/primitives/shadcn/avatar/index.ts +3 -0
  295. package/src/primitives/shadcn/badge/Badge.vue +28 -0
  296. package/src/primitives/shadcn/badge/index.ts +24 -0
  297. package/src/primitives/shadcn/button/Button.vue +29 -0
  298. package/src/primitives/shadcn/button/index.ts +36 -0
  299. package/src/primitives/shadcn/calendar/Calendar.vue +206 -0
  300. package/src/primitives/shadcn/calendar/CalendarCell.vue +28 -0
  301. package/src/primitives/shadcn/calendar/CalendarCellTrigger.vue +44 -0
  302. package/src/primitives/shadcn/calendar/CalendarGrid.vue +23 -0
  303. package/src/primitives/shadcn/calendar/CalendarGridBody.vue +12 -0
  304. package/src/primitives/shadcn/calendar/CalendarGridHead.vue +13 -0
  305. package/src/primitives/shadcn/calendar/CalendarGridRow.vue +23 -0
  306. package/src/primitives/shadcn/calendar/CalendarHeadCell.vue +23 -0
  307. package/src/primitives/shadcn/calendar/CalendarHeader.vue +23 -0
  308. package/src/primitives/shadcn/calendar/CalendarHeading.vue +30 -0
  309. package/src/primitives/shadcn/calendar/CalendarNextButton.vue +33 -0
  310. package/src/primitives/shadcn/calendar/CalendarPrevButton.vue +33 -0
  311. package/src/primitives/shadcn/calendar/index.ts +14 -0
  312. package/src/primitives/shadcn/card/Card.vue +22 -0
  313. package/src/primitives/shadcn/card/CardAction.vue +17 -0
  314. package/src/primitives/shadcn/card/CardContent.vue +14 -0
  315. package/src/primitives/shadcn/card/CardDescription.vue +14 -0
  316. package/src/primitives/shadcn/card/CardFooter.vue +14 -0
  317. package/src/primitives/shadcn/card/CardHeader.vue +22 -0
  318. package/src/primitives/shadcn/card/CardTitle.vue +14 -0
  319. package/src/primitives/shadcn/card/index.ts +7 -0
  320. package/src/primitives/shadcn/checkbox/Checkbox.vue +38 -0
  321. package/src/primitives/shadcn/checkbox/index.ts +1 -0
  322. package/src/primitives/shadcn/drawer/Drawer.vue +15 -0
  323. package/src/primitives/shadcn/drawer/DrawerClose.vue +12 -0
  324. package/src/primitives/shadcn/drawer/DrawerContent.vue +52 -0
  325. package/src/primitives/shadcn/drawer/DrawerDescription.vue +20 -0
  326. package/src/primitives/shadcn/drawer/DrawerFooter.vue +17 -0
  327. package/src/primitives/shadcn/drawer/DrawerHeader.vue +17 -0
  328. package/src/primitives/shadcn/drawer/DrawerTitle.vue +20 -0
  329. package/src/primitives/shadcn/drawer/DrawerTrigger.vue +12 -0
  330. package/src/primitives/shadcn/drawer/index.ts +8 -0
  331. package/src/primitives/shadcn/dropdown-menu/DropdownMenu.vue +15 -0
  332. package/src/primitives/shadcn/dropdown-menu/DropdownMenuCheckboxItem.vue +41 -0
  333. package/src/primitives/shadcn/dropdown-menu/DropdownMenuContent.vue +40 -0
  334. package/src/primitives/shadcn/dropdown-menu/DropdownMenuGroup.vue +12 -0
  335. package/src/primitives/shadcn/dropdown-menu/DropdownMenuItem.vue +41 -0
  336. package/src/primitives/shadcn/dropdown-menu/DropdownMenuLabel.vue +25 -0
  337. package/src/primitives/shadcn/dropdown-menu/DropdownMenuRadioGroup.vue +15 -0
  338. package/src/primitives/shadcn/dropdown-menu/DropdownMenuRadioItem.vue +38 -0
  339. package/src/primitives/shadcn/dropdown-menu/DropdownMenuSeparator.vue +23 -0
  340. package/src/primitives/shadcn/dropdown-menu/DropdownMenuShortcut.vue +17 -0
  341. package/src/primitives/shadcn/dropdown-menu/DropdownMenuSub.vue +15 -0
  342. package/src/primitives/shadcn/dropdown-menu/DropdownMenuSubContent.vue +29 -0
  343. package/src/primitives/shadcn/dropdown-menu/DropdownMenuSubTrigger.vue +31 -0
  344. package/src/primitives/shadcn/dropdown-menu/DropdownMenuTrigger.vue +14 -0
  345. package/src/primitives/shadcn/dropdown-menu/index.ts +16 -0
  346. package/src/primitives/shadcn/field/Field.vue +22 -0
  347. package/src/primitives/shadcn/field/FieldContent.vue +17 -0
  348. package/src/primitives/shadcn/field/FieldDescription.vue +24 -0
  349. package/src/primitives/shadcn/field/FieldError.vue +69 -0
  350. package/src/primitives/shadcn/field/FieldGroup.vue +22 -0
  351. package/src/primitives/shadcn/field/FieldLabel.vue +28 -0
  352. package/src/primitives/shadcn/field/FieldLegend.vue +26 -0
  353. package/src/primitives/shadcn/field/FieldSeparator.vue +28 -0
  354. package/src/primitives/shadcn/field/FieldSet.vue +23 -0
  355. package/src/primitives/shadcn/field/FieldTitle.vue +22 -0
  356. package/src/primitives/shadcn/field/index.ts +39 -0
  357. package/src/primitives/shadcn/icon/Icon.vue +38 -0
  358. package/src/primitives/shadcn/icon/index.ts +1 -0
  359. package/src/primitives/shadcn/index.ts +3 -0
  360. package/src/primitives/shadcn/input/Input.vue +35 -0
  361. package/src/primitives/shadcn/input/index.ts +1 -0
  362. package/src/primitives/shadcn/label/Label.vue +28 -0
  363. package/src/primitives/shadcn/label/index.ts +1 -0
  364. package/src/primitives/shadcn/native-select/NativeSelect.vue +56 -0
  365. package/src/primitives/shadcn/native-select/NativeSelectOptGroup.vue +18 -0
  366. package/src/primitives/shadcn/native-select/NativeSelectOption.vue +18 -0
  367. package/src/primitives/shadcn/native-select/index.ts +3 -0
  368. package/src/primitives/shadcn/popover/Popover.vue +19 -0
  369. package/src/primitives/shadcn/popover/PopoverContent.vue +41 -0
  370. package/src/primitives/shadcn/popover/PopoverTrigger.vue +11 -0
  371. package/src/primitives/shadcn/popover/index.ts +4 -0
  372. package/src/primitives/shadcn/progress/Progress.vue +30 -0
  373. package/src/primitives/shadcn/progress/index.ts +1 -0
  374. package/src/primitives/shadcn/radio-group/RadioGroup.vue +25 -0
  375. package/src/primitives/shadcn/radio-group/RadioGroupItem.vue +38 -0
  376. package/src/primitives/shadcn/radio-group/index.ts +2 -0
  377. package/src/primitives/shadcn/range-calendar/RangeCalendar.vue +73 -0
  378. package/src/primitives/shadcn/range-calendar/RangeCalendarCell.vue +28 -0
  379. package/src/primitives/shadcn/range-calendar/RangeCalendarCellTrigger.vue +46 -0
  380. package/src/primitives/shadcn/range-calendar/RangeCalendarGrid.vue +23 -0
  381. package/src/primitives/shadcn/range-calendar/RangeCalendarGridBody.vue +12 -0
  382. package/src/primitives/shadcn/range-calendar/RangeCalendarGridHead.vue +12 -0
  383. package/src/primitives/shadcn/range-calendar/RangeCalendarGridRow.vue +23 -0
  384. package/src/primitives/shadcn/range-calendar/RangeCalendarHeadCell.vue +23 -0
  385. package/src/primitives/shadcn/range-calendar/RangeCalendarHeader.vue +23 -0
  386. package/src/primitives/shadcn/range-calendar/RangeCalendarHeading.vue +30 -0
  387. package/src/primitives/shadcn/range-calendar/RangeCalendarNextButton.vue +34 -0
  388. package/src/primitives/shadcn/range-calendar/RangeCalendarPrevButton.vue +34 -0
  389. package/src/primitives/shadcn/range-calendar/index.ts +12 -0
  390. package/src/primitives/shadcn/select/Select.vue +15 -0
  391. package/src/primitives/shadcn/select/SelectContent.vue +55 -0
  392. package/src/primitives/shadcn/select/SelectGroup.vue +12 -0
  393. package/src/primitives/shadcn/select/SelectItem.vue +39 -0
  394. package/src/primitives/shadcn/select/SelectItemText.vue +12 -0
  395. package/src/primitives/shadcn/select/SelectLabel.vue +17 -0
  396. package/src/primitives/shadcn/select/SelectScrollDownButton.vue +26 -0
  397. package/src/primitives/shadcn/select/SelectScrollUpButton.vue +26 -0
  398. package/src/primitives/shadcn/select/SelectSeparator.vue +19 -0
  399. package/src/primitives/shadcn/select/SelectTrigger.vue +37 -0
  400. package/src/primitives/shadcn/select/SelectValue.vue +12 -0
  401. package/src/primitives/shadcn/select/index.ts +11 -0
  402. package/src/primitives/shadcn/separator/Separator.vue +27 -0
  403. package/src/primitives/shadcn/separator/index.ts +1 -0
  404. package/src/primitives/shadcn/slider/Slider.vue +45 -0
  405. package/src/primitives/shadcn/slider/index.ts +1 -0
  406. package/src/primitives/shadcn/spinner/Spinner.vue +18 -0
  407. package/src/primitives/shadcn/spinner/index.ts +1 -0
  408. package/src/primitives/shadcn/switch/Switch.vue +40 -0
  409. package/src/primitives/shadcn/switch/index.ts +1 -0
  410. package/src/primitives/shadcn/table/Table.vue +16 -0
  411. package/src/primitives/shadcn/table/TableBody.vue +14 -0
  412. package/src/primitives/shadcn/table/TableCaption.vue +14 -0
  413. package/src/primitives/shadcn/table/TableCell.vue +26 -0
  414. package/src/primitives/shadcn/table/TableEmpty.vue +29 -0
  415. package/src/primitives/shadcn/table/TableFooter.vue +17 -0
  416. package/src/primitives/shadcn/table/TableHead.vue +28 -0
  417. package/src/primitives/shadcn/table/TableHeader.vue +14 -0
  418. package/src/primitives/shadcn/table/TableRow.vue +21 -0
  419. package/src/primitives/shadcn/table/index.ts +9 -0
  420. package/src/primitives/shadcn/table/utils.ts +8 -0
  421. package/src/primitives/shadcn/tabs/Tabs.vue +24 -0
  422. package/src/primitives/shadcn/tabs/TabsContent.vue +21 -0
  423. package/src/primitives/shadcn/tabs/TabsList.vue +26 -0
  424. package/src/primitives/shadcn/tabs/TabsTrigger.vue +28 -0
  425. package/src/primitives/shadcn/tabs/index.ts +4 -0
  426. package/src/primitives/shadcn/textarea/Textarea.vue +33 -0
  427. package/src/primitives/shadcn/textarea/index.ts +1 -0
  428. package/src/primitives/shadcn/tooltip/Tooltip.vue +15 -0
  429. package/src/primitives/shadcn/tooltip/TooltipContent.vue +40 -0
  430. package/src/primitives/shadcn/tooltip/TooltipProvider.vue +12 -0
  431. package/src/primitives/shadcn/tooltip/TooltipTrigger.vue +12 -0
  432. package/src/primitives/shadcn/tooltip/index.ts +4 -0
  433. package/src/styles/global.css +1 -0
  434. package/src/templates/UiTemplatePlaceholder/UiTemplatePlaceholder.vue +9 -0
  435. package/src/templates/UiTemplatePlaceholder/index.ts +1 -0
  436. package/src/templates/UiTemplatePlaceholder/types.ts +8 -0
  437. package/src/templates/index.ts +6 -0
@@ -0,0 +1,274 @@
1
+ import { render, waitFor } from '@testing-library/vue';
2
+ import userEvent from '@testing-library/user-event';
3
+ import { describe, expect, test, vi } from 'vitest';
4
+ import UiDataTablePagination from '../UiDataTablePagination.vue';
5
+
6
+ // Mock table object that mimics TanStack Table's Table interface
7
+ function createMockTable(
8
+ options: {
9
+ pageIndex?: number;
10
+ pageSize?: number;
11
+ pageCount?: number;
12
+ canPreviousPage?: boolean;
13
+ canNextPage?: boolean;
14
+ selectedRows?: number;
15
+ totalRows?: number;
16
+ } = {},
17
+ ) {
18
+ const {
19
+ pageIndex = 0,
20
+ pageSize = 10,
21
+ pageCount = 5,
22
+ canPreviousPage = false,
23
+ canNextPage = true,
24
+ selectedRows = 0,
25
+ totalRows = 50,
26
+ } = options;
27
+
28
+ return {
29
+ getState: vi.fn(() => ({
30
+ pagination: { pageIndex, pageSize },
31
+ })),
32
+ getPageCount: vi.fn(() => pageCount),
33
+ getCanPreviousPage: vi.fn(() => canPreviousPage),
34
+ getCanNextPage: vi.fn(() => canNextPage),
35
+ setPageIndex: vi.fn(),
36
+ setPageSize: vi.fn(),
37
+ previousPage: vi.fn(),
38
+ nextPage: vi.fn(),
39
+ getFilteredSelectedRowModel: vi.fn(() => ({
40
+ rows: Array(selectedRows).fill({}),
41
+ })),
42
+ getFilteredRowModel: vi.fn(() => ({
43
+ rows: Array(totalRows).fill({}),
44
+ })),
45
+ };
46
+ }
47
+
48
+ describe('UiDataTablePagination', () => {
49
+ describe('Rendering', () => {
50
+ // Navigation buttons are asserted with accessible names in the Navigation Buttons suite
51
+
52
+ test('renders page info with current page and total pages', () => {
53
+ const table = createMockTable({ pageIndex: 2, pageCount: 10 });
54
+ const { getByText } = render(UiDataTablePagination, {
55
+ props: { table },
56
+ });
57
+
58
+ expect(getByText('Page 3 of 10')).toBeInTheDocument();
59
+ });
60
+
61
+ test('renders rows per page selector by default', () => {
62
+ const table = createMockTable({ pageSize: 20 });
63
+ const { getByText } = render(UiDataTablePagination, {
64
+ props: { table },
65
+ });
66
+
67
+ expect(getByText('Rows per page')).toBeInTheDocument();
68
+ expect(getByText('20')).toBeInTheDocument();
69
+ });
70
+
71
+ test('renders selection count by default', () => {
72
+ const table = createMockTable({ selectedRows: 5, totalRows: 100 });
73
+ const { getByText } = render(UiDataTablePagination, {
74
+ props: { table },
75
+ });
76
+
77
+ expect(getByText('5 of 100 row(s) selected.')).toBeInTheDocument();
78
+ });
79
+
80
+ test('hides page size selector when showPageSize is false', () => {
81
+ const table = createMockTable();
82
+ const { queryByText } = render(UiDataTablePagination, {
83
+ props: { table, showPageSize: false },
84
+ });
85
+
86
+ expect(queryByText('Rows per page')).not.toBeInTheDocument();
87
+ });
88
+
89
+ test('hides selection count when showSelection is false', () => {
90
+ const table = createMockTable({ selectedRows: 5, totalRows: 100 });
91
+ const { queryByText } = render(UiDataTablePagination, {
92
+ props: { table, showSelection: false },
93
+ });
94
+
95
+ expect(queryByText(/selected/i)).not.toBeInTheDocument();
96
+ });
97
+ });
98
+
99
+ describe('Page Size Selector', () => {
100
+ test('shows default page size options', async () => {
101
+ const user = userEvent.setup();
102
+ const table = createMockTable();
103
+ const { getByText, getByRole } = render(UiDataTablePagination, {
104
+ props: { table },
105
+ });
106
+
107
+ // Click the page size button (displays current page size)
108
+ await user.click(getByText('10'));
109
+
110
+ await waitFor(() => {
111
+ expect(getByRole('menuitem', { name: '10' })).toBeInTheDocument();
112
+ expect(getByRole('menuitem', { name: '20' })).toBeInTheDocument();
113
+ expect(getByRole('menuitem', { name: '30' })).toBeInTheDocument();
114
+ expect(getByRole('menuitem', { name: '50' })).toBeInTheDocument();
115
+ });
116
+ });
117
+
118
+ test('shows custom page size options when provided', async () => {
119
+ const user = userEvent.setup();
120
+ const table = createMockTable({ pageSize: 5 });
121
+ const { getByRole, getByText } = render(UiDataTablePagination, {
122
+ props: { table, pageSizeOptions: [5, 15, 25] },
123
+ });
124
+
125
+ await user.click(getByText('5'));
126
+
127
+ await waitFor(() => {
128
+ expect(getByRole('menuitem', { name: '5' })).toBeInTheDocument();
129
+ expect(getByRole('menuitem', { name: '15' })).toBeInTheDocument();
130
+ expect(getByRole('menuitem', { name: '25' })).toBeInTheDocument();
131
+ });
132
+ });
133
+
134
+ test('changes page size when option is selected', async () => {
135
+ const user = userEvent.setup();
136
+ const table = createMockTable();
137
+ const { getByRole, getByText } = render(UiDataTablePagination, {
138
+ props: { table },
139
+ });
140
+
141
+ await user.click(getByText('10'));
142
+ await waitFor(() => expect(getByRole('menu')).toBeInTheDocument());
143
+
144
+ await user.click(getByRole('menuitem', { name: '20' }));
145
+
146
+ expect(table.setPageSize).toHaveBeenCalledWith(20);
147
+ });
148
+ });
149
+
150
+ describe('Navigation Buttons', () => {
151
+ test('first and previous buttons are disabled on first page', () => {
152
+ const table = createMockTable({ canPreviousPage: false });
153
+ const { getByRole } = render(UiDataTablePagination, {
154
+ props: { table },
155
+ });
156
+
157
+ expect(getByRole('button', { name: /first page/i })).toBeDisabled();
158
+ expect(getByRole('button', { name: /previous page/i })).toBeDisabled();
159
+ });
160
+
161
+ test('next and last buttons are disabled on last page', () => {
162
+ const table = createMockTable({ canNextPage: false });
163
+ const { getByRole } = render(UiDataTablePagination, {
164
+ props: { table },
165
+ });
166
+
167
+ expect(getByRole('button', { name: /next page/i })).toBeDisabled();
168
+ expect(getByRole('button', { name: /last page/i })).toBeDisabled();
169
+ });
170
+
171
+ test('navigates to first page when first button is clicked', async () => {
172
+ const user = userEvent.setup();
173
+ const table = createMockTable({ canPreviousPage: true, pageIndex: 3 });
174
+ const { getByRole } = render(UiDataTablePagination, {
175
+ props: { table },
176
+ });
177
+
178
+ await user.click(getByRole('button', { name: /first page/i }));
179
+
180
+ expect(table.setPageIndex).toHaveBeenCalledWith(0);
181
+ });
182
+
183
+ test('navigates to previous page when previous button is clicked', async () => {
184
+ const user = userEvent.setup();
185
+ const table = createMockTable({ canPreviousPage: true });
186
+ const { getByRole } = render(UiDataTablePagination, {
187
+ props: { table },
188
+ });
189
+
190
+ await user.click(getByRole('button', { name: /previous page/i }));
191
+
192
+ expect(table.previousPage).toHaveBeenCalled();
193
+ });
194
+
195
+ test('navigates to next page when next button is clicked', async () => {
196
+ const user = userEvent.setup();
197
+ const table = createMockTable({ canNextPage: true });
198
+ const { getByRole } = render(UiDataTablePagination, {
199
+ props: { table },
200
+ });
201
+
202
+ await user.click(getByRole('button', { name: /next page/i }));
203
+
204
+ expect(table.nextPage).toHaveBeenCalled();
205
+ });
206
+
207
+ test('navigates to last page when last button is clicked', async () => {
208
+ const user = userEvent.setup();
209
+ const table = createMockTable({ canNextPage: true, pageCount: 10 });
210
+ const { getByRole } = render(UiDataTablePagination, {
211
+ props: { table },
212
+ });
213
+
214
+ await user.click(getByRole('button', { name: /last page/i }));
215
+
216
+ expect(table.setPageIndex).toHaveBeenCalledWith(9);
217
+ });
218
+
219
+ test('all buttons are enabled when on middle page', () => {
220
+ const table = createMockTable({ canPreviousPage: true, canNextPage: true });
221
+ const { getByRole } = render(UiDataTablePagination, {
222
+ props: { table },
223
+ });
224
+
225
+ expect(getByRole('button', { name: /first page/i })).toBeEnabled();
226
+ expect(getByRole('button', { name: /previous page/i })).toBeEnabled();
227
+ expect(getByRole('button', { name: /next page/i })).toBeEnabled();
228
+ expect(getByRole('button', { name: /last page/i })).toBeEnabled();
229
+ });
230
+ });
231
+
232
+ describe('Selection Count', () => {
233
+ test('shows zero selected when no rows are selected', () => {
234
+ const table = createMockTable({ selectedRows: 0, totalRows: 50 });
235
+ const { getByText } = render(UiDataTablePagination, {
236
+ props: { table },
237
+ });
238
+
239
+ expect(getByText('0 of 50 row(s) selected.')).toBeInTheDocument();
240
+ });
241
+
242
+ test('shows correct count when some rows are selected', () => {
243
+ const table = createMockTable({ selectedRows: 12, totalRows: 100 });
244
+ const { getByText } = render(UiDataTablePagination, {
245
+ props: { table },
246
+ });
247
+
248
+ expect(getByText('12 of 100 row(s) selected.')).toBeInTheDocument();
249
+ });
250
+ });
251
+
252
+ describe('i18n Support', () => {
253
+ test('applies custom labels when provided', () => {
254
+ const table = createMockTable({ selectedRows: 3, totalRows: 20, pageIndex: 1, pageCount: 4 });
255
+ const { getByText, getByRole } = render(UiDataTablePagination, {
256
+ props: {
257
+ table,
258
+ labels: {
259
+ rowsPerPage: 'Zeilen pro Seite',
260
+ goToFirstPage: 'Zur ersten Seite',
261
+ pageOf: (page: number, total: number) => `Seite ${page} von ${total}`,
262
+ rowsSelected: (selected: number, total: number) =>
263
+ `${selected} von ${total} ausgewählt`,
264
+ },
265
+ },
266
+ });
267
+
268
+ expect(getByText('Zeilen pro Seite')).toBeInTheDocument();
269
+ expect(getByText('Seite 2 von 4')).toBeInTheDocument();
270
+ expect(getByText('3 von 20 ausgewählt')).toBeInTheDocument();
271
+ expect(getByRole('button', { name: 'Zur ersten Seite' })).toBeInTheDocument();
272
+ });
273
+ });
274
+ });
@@ -0,0 +1,198 @@
1
+ import { render } from '@testing-library/vue';
2
+ import userEvent from '@testing-library/user-event';
3
+ import { describe, expect, test, vi } from 'vitest';
4
+ import UiDataTableToolbar from '../UiDataTableToolbar.vue';
5
+
6
+ // Mock table object that mimics TanStack Table's Table interface
7
+ function createMockTable(options: { globalFilter?: string; columnFilter?: string } = {}) {
8
+ const { globalFilter = '', columnFilter = '' } = options;
9
+ const setFilterValue = vi.fn();
10
+
11
+ return {
12
+ getState: vi.fn(() => ({
13
+ globalFilter,
14
+ })),
15
+ setGlobalFilter: vi.fn(),
16
+ getColumn: vi.fn(() => ({
17
+ getFilterValue: vi.fn(() => columnFilter),
18
+ setFilterValue,
19
+ })),
20
+ _setFilterValue: setFilterValue,
21
+ };
22
+ }
23
+
24
+ describe('UiDataTableToolbar', () => {
25
+ describe('Rendering', () => {
26
+ test('renders filter input when filtering is enabled', () => {
27
+ const table = createMockTable();
28
+
29
+ // Test with filterColumn
30
+ const { getByRole: getByColumn, unmount: unmountColumn } = render(UiDataTableToolbar, {
31
+ props: { table, filterColumn: 'name' },
32
+ });
33
+ expect(getByColumn('textbox')).toBeInTheDocument();
34
+ unmountColumn();
35
+
36
+ // Test with globalFilter
37
+ const { getByRole: getByGlobal } = render(UiDataTableToolbar, {
38
+ props: { table, globalFilter: true },
39
+ });
40
+ expect(getByGlobal('textbox')).toBeInTheDocument();
41
+ });
42
+
43
+ test('does not render filter input when neither filterColumn nor globalFilter is set', () => {
44
+ const table = createMockTable();
45
+ const { queryByRole } = render(UiDataTableToolbar, {
46
+ props: { table },
47
+ });
48
+
49
+ expect(queryByRole('textbox')).not.toBeInTheDocument();
50
+ });
51
+
52
+ test('applies custom placeholder to input', () => {
53
+ const table = createMockTable();
54
+ const { getByPlaceholderText } = render(UiDataTableToolbar, {
55
+ props: { table, globalFilter: true, filterPlaceholder: 'Type to search...' },
56
+ });
57
+
58
+ expect(getByPlaceholderText('Type to search...')).toBeInTheDocument();
59
+ });
60
+
61
+ test('uses default placeholder when not provided', () => {
62
+ const table = createMockTable();
63
+ const { getByPlaceholderText } = render(UiDataTableToolbar, {
64
+ props: { table, globalFilter: true },
65
+ });
66
+
67
+ expect(getByPlaceholderText('Search...')).toBeInTheDocument();
68
+ });
69
+ });
70
+
71
+ describe('Column Filtering', () => {
72
+ test('displays current column filter value in input', () => {
73
+ const table = createMockTable({ columnFilter: 'John' });
74
+ const { getByRole } = render(UiDataTableToolbar, {
75
+ props: { table, filterColumn: 'name' },
76
+ });
77
+
78
+ expect(getByRole('textbox')).toHaveValue('John');
79
+ });
80
+
81
+ test('updates column filter when input value changes', async () => {
82
+ const user = userEvent.setup();
83
+ const table = createMockTable();
84
+ const { getByRole } = render(UiDataTableToolbar, {
85
+ props: { table, filterColumn: 'name' },
86
+ });
87
+
88
+ await user.type(getByRole('textbox'), 'test');
89
+
90
+ expect(table._setFilterValue).toHaveBeenCalled();
91
+ });
92
+
93
+ test('clears column filter when input is emptied', async () => {
94
+ const user = userEvent.setup();
95
+ const table = createMockTable({ columnFilter: 'John' });
96
+ const { getByRole } = render(UiDataTableToolbar, {
97
+ props: { table, filterColumn: 'name' },
98
+ });
99
+
100
+ await user.clear(getByRole('textbox'));
101
+
102
+ expect(table._setFilterValue).toHaveBeenCalledWith('');
103
+ });
104
+ });
105
+
106
+ describe('Global Filtering', () => {
107
+ test('displays current global filter value in input', () => {
108
+ const table = createMockTable({ globalFilter: 'search term' });
109
+ const { getByRole } = render(UiDataTableToolbar, {
110
+ props: { table, globalFilter: true },
111
+ });
112
+
113
+ expect(getByRole('textbox')).toHaveValue('search term');
114
+ });
115
+
116
+ test('updates global filter when input value changes', async () => {
117
+ const user = userEvent.setup();
118
+ const table = createMockTable();
119
+ const { getByRole } = render(UiDataTableToolbar, {
120
+ props: { table, globalFilter: true },
121
+ });
122
+
123
+ await user.type(getByRole('textbox'), 'query');
124
+
125
+ expect(table.setGlobalFilter).toHaveBeenCalled();
126
+ });
127
+
128
+ test('clears global filter when input is emptied', async () => {
129
+ const user = userEvent.setup();
130
+ const table = createMockTable({ globalFilter: 'existing' });
131
+ const { getByRole } = render(UiDataTableToolbar, {
132
+ props: { table, globalFilter: true },
133
+ });
134
+
135
+ await user.clear(getByRole('textbox'));
136
+
137
+ expect(table.setGlobalFilter).toHaveBeenCalledWith('');
138
+ });
139
+
140
+ test('global filter takes precedence over column filter', () => {
141
+ const table = createMockTable({ globalFilter: 'global', columnFilter: 'column' });
142
+ const { getByRole } = render(UiDataTableToolbar, {
143
+ props: { table, globalFilter: true, filterColumn: 'name' },
144
+ });
145
+
146
+ // Global filter value should be displayed, not column filter
147
+ expect(getByRole('textbox')).toHaveValue('global');
148
+ });
149
+ });
150
+
151
+ describe('Accessibility', () => {
152
+ test('input has aria-label for global search', () => {
153
+ const table = createMockTable();
154
+ const { getByRole } = render(UiDataTableToolbar, {
155
+ props: { table, globalFilter: true },
156
+ });
157
+
158
+ expect(getByRole('textbox')).toHaveAttribute('aria-label', 'Search all columns');
159
+ });
160
+
161
+ test('input has aria-label for column filter including column name', () => {
162
+ const table = createMockTable();
163
+ const { getByRole } = render(UiDataTableToolbar, {
164
+ props: { table, filterColumn: 'email' },
165
+ });
166
+
167
+ expect(getByRole('textbox')).toHaveAttribute('aria-label', 'Filter by email');
168
+ });
169
+ });
170
+
171
+ describe('i18n Support', () => {
172
+ test('uses custom searchAllColumns label for global filter', () => {
173
+ const table = createMockTable();
174
+ const { getByRole } = render(UiDataTableToolbar, {
175
+ props: {
176
+ table,
177
+ globalFilter: true,
178
+ labels: { searchAllColumns: 'Alle Spalten durchsuchen' },
179
+ },
180
+ });
181
+
182
+ expect(getByRole('textbox')).toHaveAttribute('aria-label', 'Alle Spalten durchsuchen');
183
+ });
184
+
185
+ test('uses custom filterByColumn function for column filter', () => {
186
+ const table = createMockTable();
187
+ const { getByRole } = render(UiDataTableToolbar, {
188
+ props: {
189
+ table,
190
+ filterColumn: 'name',
191
+ labels: { filterByColumn: (col: string) => `Nach ${col} filtern` },
192
+ },
193
+ });
194
+
195
+ expect(getByRole('textbox')).toHaveAttribute('aria-label', 'Nach name filtern');
196
+ });
197
+ });
198
+ });
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Default labels for UiDataTable components.
3
+ * Override these by passing custom labels to component props.
4
+ */
5
+
6
+ /** TanStack Table's default column size - columns without explicit size use this value */
7
+ export const DEFAULT_COLUMN_SIZE = 150;
8
+
9
+ export const DATA_TABLE_LABELS = {
10
+ /** UiDataTable */
11
+ emptyText: 'No results.',
12
+
13
+ /** UiDataTableColumnHeader */
14
+ sortAscending: 'Asc',
15
+ sortDescending: 'Desc',
16
+ sortedAscending: 'sorted ascending',
17
+ sortedDescending: 'sorted descending',
18
+ clickToSort: 'click to sort',
19
+
20
+ /** UiDataTablePagination */
21
+ rowsPerPage: 'Rows per page',
22
+ goToFirstPage: 'Go to first page',
23
+ goToPreviousPage: 'Go to previous page',
24
+ goToNextPage: 'Go to next page',
25
+ goToLastPage: 'Go to last page',
26
+ pageOf: (page: number, total: number) => `Page ${page} of ${total}`,
27
+ rowsSelected: (selected: number, total: number) => `${selected} of ${total} row(s) selected.`,
28
+
29
+ /** UiDataTableToolbar */
30
+ filterPlaceholder: 'Search...',
31
+ searchAllColumns: 'Search all columns',
32
+ filterByColumn: (column: string) => `Filter by ${column}`,
33
+ } as const;
34
+
35
+ export type DataTableLabels = typeof DATA_TABLE_LABELS;
36
+
37
+ /** Labels for UiDataTableColumnHeader */
38
+ export interface ColumnHeaderLabels {
39
+ /** Label for ascending sort menu item */
40
+ sortAscending?: string;
41
+ /** Label for descending sort menu item */
42
+ sortDescending?: string;
43
+ /** Aria label suffix when sorted ascending */
44
+ sortedAscending?: string;
45
+ /** Aria label suffix when sorted descending */
46
+ sortedDescending?: string;
47
+ /** Aria label suffix when not sorted */
48
+ clickToSort?: string;
49
+ }
50
+
51
+ /** Labels for UiDataTablePagination */
52
+ export interface PaginationLabels {
53
+ /** Label for rows per page selector */
54
+ rowsPerPage?: string;
55
+ /** Aria label for first page button */
56
+ goToFirstPage?: string;
57
+ /** Aria label for previous page button */
58
+ goToPreviousPage?: string;
59
+ /** Aria label for next page button */
60
+ goToNextPage?: string;
61
+ /** Aria label for last page button */
62
+ goToLastPage?: string;
63
+ /** Function to generate page info text */
64
+ pageOf?: (page: number, total: number) => string;
65
+ /** Function to generate selection count text */
66
+ rowsSelected?: (selected: number, total: number) => string;
67
+ }
68
+
69
+ /** Labels for UiDataTableToolbar */
70
+ export interface ToolbarLabels {
71
+ /** Placeholder text for filter input */
72
+ filterPlaceholder?: string;
73
+ /** Aria label for global search input */
74
+ searchAllColumns?: string;
75
+ /** Function to generate aria label for column filter */
76
+ filterByColumn?: (column: string) => string;
77
+ }
@@ -0,0 +1,6 @@
1
+ export { default as UiDataTable } from './UiDataTable.vue';
2
+ export { default as UiDataTableColumnHeader } from './UiDataTableColumnHeader.vue';
3
+ export { default as UiDataTablePagination } from './UiDataTablePagination.vue';
4
+ export { default as UiDataTableToolbar } from './UiDataTableToolbar.vue';
5
+ export * from './types';
6
+ export * from './constants';
@@ -0,0 +1,39 @@
1
+ import type { ColumnDef, Row } from '@tanstack/vue-table';
2
+
3
+ /**
4
+ * A feature-rich data table with sorting, filtering, and pagination.
5
+ * Use for displaying and managing large datasets with interactive features.
6
+ *
7
+ * @category Layout
8
+ * @useCases data grid, admin table, user list, product catalog, reports
9
+ * @keywords datatable, grid, sorting, filtering, pagination, data, list
10
+ * @related UiTable
11
+ */
12
+ export interface UiDataTableProps<TData, TValue> {
13
+ /**
14
+ * The column definitions for the table.
15
+ */
16
+ columns: ColumnDef<TData, TValue>[];
17
+ /**
18
+ * The data to display in the table.
19
+ */
20
+ data: TData[];
21
+ /**
22
+ * Text to display when there are no results.
23
+ * @default "No results."
24
+ */
25
+ emptyText?: string;
26
+ /**
27
+ * Function to derive a unique ID for each row. Important for proper row selection
28
+ * and state management when data changes. Defaults to using the row index.
29
+ * @example (row) => row.id
30
+ */
31
+ getRowId?: (originalRow: TData, index: number, parent?: Row<TData>) => string;
32
+ /**
33
+ * Minimum height for the table container. Useful for preventing layout shifts
34
+ * during pagination. The last row will have a visible bottom border even when
35
+ * the container is taller than the content.
36
+ * @example "400px"
37
+ */
38
+ tableMinHeight?: string;
39
+ }