@aleph-alpha/ui-library 1.9.0 → 1.11.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 (432) hide show
  1. package/README.md +14 -0
  2. package/dist/system/index-CkH7HQaa.js +7 -0
  3. package/dist/system/index-CuHwEAQ_.js +7 -0
  4. package/dist/system/index.d.ts +1322 -318
  5. package/dist/system/lib.js +8839 -6993
  6. package/package.json +2 -1
  7. package/src/@types/shims-vue.d.ts +5 -0
  8. package/src/__tests__/placeholder.test.ts +7 -0
  9. package/src/compositions/UiCompositionPlaceholder/UiCompositionPlaceholder.vue +9 -0
  10. package/src/compositions/UiCompositionPlaceholder/index.ts +1 -0
  11. package/src/compositions/UiCompositionPlaceholder/types.ts +8 -0
  12. package/src/compositions/UiDataTable/UiDataTable.mock.ts +104 -0
  13. package/src/compositions/UiDataTable/UiDataTable.stories.ts +1575 -0
  14. package/src/compositions/UiDataTable/UiDataTable.vue +129 -0
  15. package/src/compositions/UiDataTable/UiDataTableColumnHeader.vue +97 -0
  16. package/src/compositions/UiDataTable/UiDataTablePagination.vue +147 -0
  17. package/src/compositions/UiDataTable/UiDataTableToolbar.vue +85 -0
  18. package/src/compositions/UiDataTable/__tests__/UiDataTable.test.ts +372 -0
  19. package/src/compositions/UiDataTable/__tests__/UiDataTableColumnHeader.test.ts +217 -0
  20. package/src/compositions/UiDataTable/__tests__/UiDataTablePagination.test.ts +274 -0
  21. package/src/compositions/UiDataTable/__tests__/UiDataTableToolbar.test.ts +198 -0
  22. package/src/compositions/UiDataTable/constants.ts +77 -0
  23. package/src/compositions/UiDataTable/index.ts +6 -0
  24. package/src/compositions/UiDataTable/types.ts +39 -0
  25. package/src/compositions/UiDatePicker/UiDatePicker.stories.ts +976 -0
  26. package/src/compositions/UiDatePicker/UiDatePicker.vue +193 -0
  27. package/src/compositions/UiDatePicker/__tests__/UiDatePicker.test.ts +325 -0
  28. package/src/compositions/UiDatePicker/index.ts +14 -0
  29. package/src/compositions/UiDatePicker/types.ts +220 -0
  30. package/src/compositions/index.ts +8 -0
  31. package/src/foundations/UiPlaceholder/UiPlaceholder.vue +9 -0
  32. package/src/foundations/UiPlaceholder/index.ts +1 -0
  33. package/src/foundations/UiPlaceholder/types.ts +8 -0
  34. package/src/foundations/index.ts +6 -0
  35. package/src/index.ts +27 -0
  36. package/src/lib/utils.ts +6 -0
  37. package/src/primitives/UiAccordion/UiAccordion.stories.ts +476 -0
  38. package/src/primitives/UiAccordion/UiAccordion.vue +31 -0
  39. package/src/primitives/UiAccordion/UiAccordionContent.vue +16 -0
  40. package/src/primitives/UiAccordion/UiAccordionItem.vue +16 -0
  41. package/src/primitives/UiAccordion/UiAccordionTrigger.vue +23 -0
  42. package/src/primitives/UiAccordion/__tests__/UiAccordion.test.ts +198 -0
  43. package/src/primitives/UiAccordion/index.ts +6 -0
  44. package/src/primitives/UiAccordion/types.ts +95 -0
  45. package/src/primitives/UiAlert/UiAlert.stories.ts +199 -0
  46. package/src/primitives/UiAlert/UiAlert.vue +27 -0
  47. package/src/primitives/UiAlert/UiAlertDescription.vue +13 -0
  48. package/src/primitives/UiAlert/UiAlertTitle.vue +13 -0
  49. package/src/primitives/UiAlert/__tests__/UiAlert.test.ts +20 -0
  50. package/src/primitives/UiAlert/constants.ts +3 -0
  51. package/src/primitives/UiAlert/index.ts +5 -0
  52. package/src/primitives/UiAlert/types.ts +14 -0
  53. package/src/primitives/UiAlertDialog/UiAlertDialog.stories.ts +186 -0
  54. package/src/primitives/UiAlertDialog/UiAlertDialog.vue +18 -0
  55. package/src/primitives/UiAlertDialog/UiAlertDialogAction.vue +16 -0
  56. package/src/primitives/UiAlertDialog/UiAlertDialogCancel.vue +16 -0
  57. package/src/primitives/UiAlertDialog/UiAlertDialogContent.vue +26 -0
  58. package/src/primitives/UiAlertDialog/UiAlertDialogDescription.vue +16 -0
  59. package/src/primitives/UiAlertDialog/UiAlertDialogFooter.vue +13 -0
  60. package/src/primitives/UiAlertDialog/UiAlertDialogHeader.vue +16 -0
  61. package/src/primitives/UiAlertDialog/UiAlertDialogTitle.vue +16 -0
  62. package/src/primitives/UiAlertDialog/UiAlertDialogTrigger.vue +17 -0
  63. package/src/primitives/UiAlertDialog/__tests__/UiAlertDialog.test.ts +184 -0
  64. package/src/primitives/UiAlertDialog/index.ts +9 -0
  65. package/src/primitives/UiAlertDialog/types.ts +83 -0
  66. package/src/primitives/UiAvatar/UiAvatar.stories.ts +194 -0
  67. package/src/primitives/UiAvatar/UiAvatar.vue +13 -0
  68. package/src/primitives/UiAvatar/UiAvatarFallback.vue +13 -0
  69. package/src/primitives/UiAvatar/UiAvatarImage.vue +14 -0
  70. package/src/primitives/UiAvatar/__tests__/UiAvatar.test.ts +36 -0
  71. package/src/primitives/UiAvatar/index.ts +3 -0
  72. package/src/primitives/UiAvatar/types.ts +17 -0
  73. package/src/primitives/UiBadge/UiBadge.stories.ts +373 -0
  74. package/src/primitives/UiBadge/UiBadge.vue +21 -0
  75. package/src/primitives/UiBadge/__tests__/UiBadge.test.ts +44 -0
  76. package/src/primitives/UiBadge/constants.ts +3 -0
  77. package/src/primitives/UiBadge/index.ts +2 -0
  78. package/src/primitives/UiBadge/types.ts +48 -0
  79. package/src/primitives/UiButton/UiButton.stories.ts +537 -0
  80. package/src/primitives/UiButton/UiButton.vue +72 -0
  81. package/src/primitives/UiButton/__tests__/UiButton.test.ts +133 -0
  82. package/src/primitives/UiButton/index.ts +2 -0
  83. package/src/primitives/UiButton/types.ts +87 -0
  84. package/src/primitives/UiCalendar/UiCalendar.stories.ts +797 -0
  85. package/src/primitives/UiCalendar/UiCalendar.vue +67 -0
  86. package/src/primitives/UiCalendar/__tests__/UiCalendar.test.ts +45 -0
  87. package/src/primitives/UiCalendar/index.ts +15 -0
  88. package/src/primitives/UiCalendar/types.ts +236 -0
  89. package/src/primitives/UiCard/UiCard.stories.ts +197 -0
  90. package/src/primitives/UiCard/UiCard.vue +13 -0
  91. package/src/primitives/UiCard/UiCardAction.vue +13 -0
  92. package/src/primitives/UiCard/UiCardContent.vue +13 -0
  93. package/src/primitives/UiCard/UiCardDescription.vue +13 -0
  94. package/src/primitives/UiCard/UiCardFooter.vue +13 -0
  95. package/src/primitives/UiCard/UiCardHeader.vue +13 -0
  96. package/src/primitives/UiCard/UiCardTitle.vue +13 -0
  97. package/src/primitives/UiCard/__tests__/UiCard.test.ts +19 -0
  98. package/src/primitives/UiCard/__tests__/UiCardAction.test.ts +19 -0
  99. package/src/primitives/UiCard/__tests__/UiCardContent.test.ts +19 -0
  100. package/src/primitives/UiCard/__tests__/UiCardDescription.test.ts +19 -0
  101. package/src/primitives/UiCard/__tests__/UiCardFooter.test.ts +19 -0
  102. package/src/primitives/UiCard/__tests__/UiCardHeader.test.ts +19 -0
  103. package/src/primitives/UiCard/__tests__/UiCardTitle.test.ts +19 -0
  104. package/src/primitives/UiCard/index.ts +7 -0
  105. package/src/primitives/UiCard/types.ts +10 -0
  106. package/src/primitives/UiCheckbox/UiCheckbox.stories.ts +231 -0
  107. package/src/primitives/UiCheckbox/UiCheckbox.vue +19 -0
  108. package/src/primitives/UiCheckbox/__tests__/UiCheckbox.test.ts +29 -0
  109. package/src/primitives/UiCheckbox/index.ts +2 -0
  110. package/src/primitives/UiCheckbox/types.ts +30 -0
  111. package/src/primitives/UiDrawer/UiDrawer.stories.ts +602 -0
  112. package/src/primitives/UiDrawer/UiDrawer.vue +19 -0
  113. package/src/primitives/UiDrawer/UiDrawerClose.vue +16 -0
  114. package/src/primitives/UiDrawer/UiDrawerContent.vue +29 -0
  115. package/src/primitives/UiDrawer/UiDrawerDescription.vue +16 -0
  116. package/src/primitives/UiDrawer/UiDrawerFooter.vue +16 -0
  117. package/src/primitives/UiDrawer/UiDrawerHeader.vue +16 -0
  118. package/src/primitives/UiDrawer/UiDrawerTitle.vue +16 -0
  119. package/src/primitives/UiDrawer/UiDrawerTrigger.vue +16 -0
  120. package/src/primitives/UiDrawer/__tests__/UiDrawer.test.ts +229 -0
  121. package/src/primitives/UiDrawer/index.ts +8 -0
  122. package/src/primitives/UiDrawer/types.ts +96 -0
  123. package/src/primitives/UiDropdownMenu/UiDropdownMenu.stories.ts +760 -0
  124. package/src/primitives/UiDropdownMenu/UiDropdownMenu.vue +25 -0
  125. package/src/primitives/UiDropdownMenu/UiDropdownMenuCheckboxItem.vue +29 -0
  126. package/src/primitives/UiDropdownMenu/UiDropdownMenuContent.vue +27 -0
  127. package/src/primitives/UiDropdownMenu/UiDropdownMenuGroup.vue +13 -0
  128. package/src/primitives/UiDropdownMenu/UiDropdownMenuItem.vue +26 -0
  129. package/src/primitives/UiDropdownMenu/UiDropdownMenuLabel.vue +18 -0
  130. package/src/primitives/UiDropdownMenu/UiDropdownMenuRadioGroup.vue +20 -0
  131. package/src/primitives/UiDropdownMenu/UiDropdownMenuRadioItem.vue +26 -0
  132. package/src/primitives/UiDropdownMenu/UiDropdownMenuSeparator.vue +11 -0
  133. package/src/primitives/UiDropdownMenu/UiDropdownMenuShortcut.vue +13 -0
  134. package/src/primitives/UiDropdownMenu/UiDropdownMenuSub.vue +26 -0
  135. package/src/primitives/UiDropdownMenu/UiDropdownMenuSubContent.vue +23 -0
  136. package/src/primitives/UiDropdownMenu/UiDropdownMenuSubTrigger.vue +24 -0
  137. package/src/primitives/UiDropdownMenu/UiDropdownMenuTrigger.vue +24 -0
  138. package/src/primitives/UiDropdownMenu/__tests__/UiDropdownMenu.test.ts +557 -0
  139. package/src/primitives/UiDropdownMenu/index.ts +16 -0
  140. package/src/primitives/UiDropdownMenu/types.ts +219 -0
  141. package/src/primitives/UiField/UiField.stories.ts +1496 -0
  142. package/src/primitives/UiField/UiField.vue +18 -0
  143. package/src/primitives/UiField/UiFieldContent.vue +13 -0
  144. package/src/primitives/UiField/UiFieldDescription.vue +13 -0
  145. package/src/primitives/UiField/UiFieldError.vue +20 -0
  146. package/src/primitives/UiField/UiFieldGroup.vue +13 -0
  147. package/src/primitives/UiField/UiFieldLabel.vue +16 -0
  148. package/src/primitives/UiField/UiFieldLegend.vue +13 -0
  149. package/src/primitives/UiField/UiFieldSeparator.vue +13 -0
  150. package/src/primitives/UiField/UiFieldSet.vue +13 -0
  151. package/src/primitives/UiField/UiFieldTitle.vue +13 -0
  152. package/src/primitives/UiField/__tests__/UiFieldError.test.ts +35 -0
  153. package/src/primitives/UiField/index.ts +10 -0
  154. package/src/primitives/UiField/types.ts +47 -0
  155. package/src/primitives/UiIcon/UiIcon.stories.ts +95 -0
  156. package/src/primitives/UiIcon/UiIcon.vue +14 -0
  157. package/src/primitives/UiIcon/__tests__/UiIcon.test.ts +24 -0
  158. package/src/primitives/UiIcon/index.ts +1 -0
  159. package/src/primitives/UiIcon/types.ts +23 -0
  160. package/src/primitives/UiIconButton/UiIconButton.stories.ts +446 -0
  161. package/src/primitives/UiIconButton/UiIconButton.vue +63 -0
  162. package/src/primitives/UiIconButton/__tests__/UiIconButton.test.ts +102 -0
  163. package/src/primitives/UiIconButton/index.ts +2 -0
  164. package/src/primitives/UiIconButton/types.ts +67 -0
  165. package/src/primitives/UiInput/UiInput.stories.ts +193 -0
  166. package/src/primitives/UiInput/UiInput.vue +19 -0
  167. package/src/primitives/UiInput/__tests__/UiInput.test.ts +38 -0
  168. package/src/primitives/UiInput/index.ts +2 -0
  169. package/src/primitives/UiInput/types.ts +31 -0
  170. package/src/primitives/UiPopover/UiPopover.stories.ts +394 -0
  171. package/src/primitives/UiPopover/UiPopover.vue +17 -0
  172. package/src/primitives/UiPopover/UiPopoverContent.vue +27 -0
  173. package/src/primitives/UiPopover/UiPopoverTrigger.vue +16 -0
  174. package/src/primitives/UiPopover/__tests__/UiPopover.test.ts +87 -0
  175. package/src/primitives/UiPopover/index.ts +5 -0
  176. package/src/primitives/UiPopover/types.ts +86 -0
  177. package/src/primitives/UiProgress/UiProgress.stories.ts +92 -0
  178. package/src/primitives/UiProgress/UiProgress.vue +25 -0
  179. package/src/primitives/UiProgress/__tests__/UiProgress.test.ts +46 -0
  180. package/src/primitives/UiProgress/index.ts +2 -0
  181. package/src/primitives/UiProgress/types.ts +16 -0
  182. package/src/primitives/UiRadioGroup/UiRadioGroup.stories.ts +291 -0
  183. package/src/primitives/UiRadioGroup/UiRadioGroup.vue +43 -0
  184. package/src/primitives/UiRadioGroup/UiRadioGroupItem.vue +18 -0
  185. package/src/primitives/UiRadioGroup/__tests__/UiRadioGroup.test.ts +404 -0
  186. package/src/primitives/UiRadioGroup/index.ts +4 -0
  187. package/src/primitives/UiRadioGroup/types.ts +66 -0
  188. package/src/primitives/UiRangeCalendar/UiRangeCalendar.stories.ts +609 -0
  189. package/src/primitives/UiRangeCalendar/UiRangeCalendar.vue +50 -0
  190. package/src/primitives/UiRangeCalendar/__tests__/UiRangeCalendar.test.ts +35 -0
  191. package/src/primitives/UiRangeCalendar/index.ts +13 -0
  192. package/src/primitives/UiRangeCalendar/types.ts +184 -0
  193. package/src/primitives/UiSelect/UiSelect.stories.ts +425 -0
  194. package/src/primitives/UiSelect/UiSelect.vue +47 -0
  195. package/src/primitives/UiSelect/UiSelectContent.vue +30 -0
  196. package/src/primitives/UiSelect/UiSelectGroup.vue +13 -0
  197. package/src/primitives/UiSelect/UiSelectItem.vue +19 -0
  198. package/src/primitives/UiSelect/UiSelectLabel.vue +13 -0
  199. package/src/primitives/UiSelect/UiSelectSeparator.vue +11 -0
  200. package/src/primitives/UiSelect/UiSelectTrigger.vue +30 -0
  201. package/src/primitives/UiSelect/UiSelectValue.vue +18 -0
  202. package/src/primitives/UiSelect/__tests__/UiSelect.test.ts +211 -0
  203. package/src/primitives/UiSelect/__tests__/UiSelectContent.test.ts +30 -0
  204. package/src/primitives/UiSelect/__tests__/UiSelectGroup.test.ts +85 -0
  205. package/src/primitives/UiSelect/__tests__/UiSelectItem.test.ts +79 -0
  206. package/src/primitives/UiSelect/__tests__/UiSelectLabel.test.ts +83 -0
  207. package/src/primitives/UiSelect/__tests__/UiSelectSeparator.test.ts +82 -0
  208. package/src/primitives/UiSelect/__tests__/UiSelectTrigger.test.ts +54 -0
  209. package/src/primitives/UiSelect/__tests__/UiSelectValue.test.ts +39 -0
  210. package/src/primitives/UiSelect/index.ts +10 -0
  211. package/src/primitives/UiSelect/types.ts +93 -0
  212. package/src/primitives/UiSlider/UiSlider.stories.ts +226 -0
  213. package/src/primitives/UiSlider/UiSlider.vue +44 -0
  214. package/src/primitives/UiSlider/__tests__/UiSlider.test.ts +76 -0
  215. package/src/primitives/UiSlider/index.ts +1 -0
  216. package/src/primitives/UiSlider/types.ts +101 -0
  217. package/src/primitives/UiSpinner/UiSpinner.stories.ts +143 -0
  218. package/src/primitives/UiSpinner/UiSpinner.vue +16 -0
  219. package/src/primitives/UiSpinner/__tests__/UiSpinner.test.ts +19 -0
  220. package/src/primitives/UiSpinner/index.ts +2 -0
  221. package/src/primitives/UiSpinner/types.ts +16 -0
  222. package/src/primitives/UiSwitch/UiSwitch.stories.ts +120 -0
  223. package/src/primitives/UiSwitch/UiSwitch.vue +21 -0
  224. package/src/primitives/UiSwitch/__tests__/UiSwitch.test.ts +47 -0
  225. package/src/primitives/UiSwitch/index.ts +2 -0
  226. package/src/primitives/UiSwitch/types.ts +25 -0
  227. package/src/primitives/UiTable/UiTable.stories.ts +505 -0
  228. package/src/primitives/UiTable/UiTable.vue +13 -0
  229. package/src/primitives/UiTable/UiTableBody.vue +13 -0
  230. package/src/primitives/UiTable/UiTableCaption.vue +13 -0
  231. package/src/primitives/UiTable/UiTableCell.vue +16 -0
  232. package/src/primitives/UiTable/UiTableEmpty.vue +18 -0
  233. package/src/primitives/UiTable/UiTableFooter.vue +13 -0
  234. package/src/primitives/UiTable/UiTableHead.vue +18 -0
  235. package/src/primitives/UiTable/UiTableHeader.vue +13 -0
  236. package/src/primitives/UiTable/UiTableRow.vue +18 -0
  237. package/src/primitives/UiTable/__tests__/UiTable.test.ts +19 -0
  238. package/src/primitives/UiTable/__tests__/UiTableBody.test.ts +19 -0
  239. package/src/primitives/UiTable/__tests__/UiTableCaption.test.ts +19 -0
  240. package/src/primitives/UiTable/__tests__/UiTableCell.test.ts +26 -0
  241. package/src/primitives/UiTable/__tests__/UiTableEmpty.test.ts +32 -0
  242. package/src/primitives/UiTable/__tests__/UiTableFooter.test.ts +19 -0
  243. package/src/primitives/UiTable/__tests__/UiTableHead.test.ts +43 -0
  244. package/src/primitives/UiTable/__tests__/UiTableHeader.test.ts +19 -0
  245. package/src/primitives/UiTable/__tests__/UiTableRow.test.ts +32 -0
  246. package/src/primitives/UiTable/index.ts +16 -0
  247. package/src/primitives/UiTable/types.ts +68 -0
  248. package/src/primitives/UiTabs/UiTabs.stories.ts +456 -0
  249. package/src/primitives/UiTabs/UiTabs.vue +31 -0
  250. package/src/primitives/UiTabs/UiTabsContent.vue +16 -0
  251. package/src/primitives/UiTabs/UiTabsList.vue +16 -0
  252. package/src/primitives/UiTabs/UiTabsTrigger.vue +16 -0
  253. package/src/primitives/UiTabs/__tests__/UiTabs.test.ts +122 -0
  254. package/src/primitives/UiTabs/index.ts +6 -0
  255. package/src/primitives/UiTabs/types.ts +68 -0
  256. package/src/primitives/UiTextarea/UiTextarea.stories.ts +107 -0
  257. package/src/primitives/UiTextarea/UiTextarea.vue +19 -0
  258. package/src/primitives/UiTextarea/__tests__/UiTextarea.test.ts +40 -0
  259. package/src/primitives/UiTextarea/index.ts +2 -0
  260. package/src/primitives/UiTextarea/types.ts +30 -0
  261. package/src/primitives/UiTooltip/UiTooltip.stories.ts +550 -0
  262. package/src/primitives/UiTooltip/UiTooltip.vue +42 -0
  263. package/src/primitives/UiTooltip/__tests__/UiTooltip.test.ts +78 -0
  264. package/src/primitives/UiTooltip/index.ts +2 -0
  265. package/src/primitives/UiTooltip/types.ts +53 -0
  266. package/src/primitives/index.ts +33 -0
  267. package/src/primitives/shadcn/accordion/Accordion.vue +15 -0
  268. package/src/primitives/shadcn/accordion/AccordionContent.vue +23 -0
  269. package/src/primitives/shadcn/accordion/AccordionItem.vue +24 -0
  270. package/src/primitives/shadcn/accordion/AccordionTrigger.vue +35 -0
  271. package/src/primitives/shadcn/accordion/index.ts +4 -0
  272. package/src/primitives/shadcn/alert/Alert.vue +17 -0
  273. package/src/primitives/shadcn/alert/AlertDescription.vue +22 -0
  274. package/src/primitives/shadcn/alert/AlertTitle.vue +17 -0
  275. package/src/primitives/shadcn/alert/index.ts +24 -0
  276. package/src/primitives/shadcn/alert-dialog/AlertDialog.vue +15 -0
  277. package/src/primitives/shadcn/alert-dialog/AlertDialogAction.vue +18 -0
  278. package/src/primitives/shadcn/alert-dialog/AlertDialogCancel.vue +21 -0
  279. package/src/primitives/shadcn/alert-dialog/AlertDialogContent.vue +44 -0
  280. package/src/primitives/shadcn/alert-dialog/AlertDialogDescription.vue +21 -0
  281. package/src/primitives/shadcn/alert-dialog/AlertDialogFooter.vue +17 -0
  282. package/src/primitives/shadcn/alert-dialog/AlertDialogHeader.vue +17 -0
  283. package/src/primitives/shadcn/alert-dialog/AlertDialogTitle.vue +21 -0
  284. package/src/primitives/shadcn/alert-dialog/AlertDialogTrigger.vue +12 -0
  285. package/src/primitives/shadcn/alert-dialog/index.ts +9 -0
  286. package/src/primitives/shadcn/avatar/Avatar.vue +18 -0
  287. package/src/primitives/shadcn/avatar/AvatarFallback.vue +21 -0
  288. package/src/primitives/shadcn/avatar/AvatarImage.vue +12 -0
  289. package/src/primitives/shadcn/avatar/index.ts +3 -0
  290. package/src/primitives/shadcn/badge/Badge.vue +28 -0
  291. package/src/primitives/shadcn/badge/index.ts +24 -0
  292. package/src/primitives/shadcn/button/Button.vue +29 -0
  293. package/src/primitives/shadcn/button/index.ts +36 -0
  294. package/src/primitives/shadcn/calendar/Calendar.vue +206 -0
  295. package/src/primitives/shadcn/calendar/CalendarCell.vue +28 -0
  296. package/src/primitives/shadcn/calendar/CalendarCellTrigger.vue +44 -0
  297. package/src/primitives/shadcn/calendar/CalendarGrid.vue +23 -0
  298. package/src/primitives/shadcn/calendar/CalendarGridBody.vue +12 -0
  299. package/src/primitives/shadcn/calendar/CalendarGridHead.vue +13 -0
  300. package/src/primitives/shadcn/calendar/CalendarGridRow.vue +23 -0
  301. package/src/primitives/shadcn/calendar/CalendarHeadCell.vue +23 -0
  302. package/src/primitives/shadcn/calendar/CalendarHeader.vue +23 -0
  303. package/src/primitives/shadcn/calendar/CalendarHeading.vue +30 -0
  304. package/src/primitives/shadcn/calendar/CalendarNextButton.vue +33 -0
  305. package/src/primitives/shadcn/calendar/CalendarPrevButton.vue +33 -0
  306. package/src/primitives/shadcn/calendar/index.ts +14 -0
  307. package/src/primitives/shadcn/card/Card.vue +22 -0
  308. package/src/primitives/shadcn/card/CardAction.vue +17 -0
  309. package/src/primitives/shadcn/card/CardContent.vue +14 -0
  310. package/src/primitives/shadcn/card/CardDescription.vue +14 -0
  311. package/src/primitives/shadcn/card/CardFooter.vue +14 -0
  312. package/src/primitives/shadcn/card/CardHeader.vue +22 -0
  313. package/src/primitives/shadcn/card/CardTitle.vue +14 -0
  314. package/src/primitives/shadcn/card/index.ts +7 -0
  315. package/src/primitives/shadcn/checkbox/Checkbox.vue +38 -0
  316. package/src/primitives/shadcn/checkbox/index.ts +1 -0
  317. package/src/primitives/shadcn/drawer/Drawer.vue +15 -0
  318. package/src/primitives/shadcn/drawer/DrawerClose.vue +12 -0
  319. package/src/primitives/shadcn/drawer/DrawerContent.vue +52 -0
  320. package/src/primitives/shadcn/drawer/DrawerDescription.vue +20 -0
  321. package/src/primitives/shadcn/drawer/DrawerFooter.vue +17 -0
  322. package/src/primitives/shadcn/drawer/DrawerHeader.vue +17 -0
  323. package/src/primitives/shadcn/drawer/DrawerTitle.vue +20 -0
  324. package/src/primitives/shadcn/drawer/DrawerTrigger.vue +12 -0
  325. package/src/primitives/shadcn/drawer/index.ts +8 -0
  326. package/src/primitives/shadcn/dropdown-menu/DropdownMenu.vue +15 -0
  327. package/src/primitives/shadcn/dropdown-menu/DropdownMenuCheckboxItem.vue +41 -0
  328. package/src/primitives/shadcn/dropdown-menu/DropdownMenuContent.vue +40 -0
  329. package/src/primitives/shadcn/dropdown-menu/DropdownMenuGroup.vue +12 -0
  330. package/src/primitives/shadcn/dropdown-menu/DropdownMenuItem.vue +41 -0
  331. package/src/primitives/shadcn/dropdown-menu/DropdownMenuLabel.vue +25 -0
  332. package/src/primitives/shadcn/dropdown-menu/DropdownMenuRadioGroup.vue +15 -0
  333. package/src/primitives/shadcn/dropdown-menu/DropdownMenuRadioItem.vue +38 -0
  334. package/src/primitives/shadcn/dropdown-menu/DropdownMenuSeparator.vue +23 -0
  335. package/src/primitives/shadcn/dropdown-menu/DropdownMenuShortcut.vue +17 -0
  336. package/src/primitives/shadcn/dropdown-menu/DropdownMenuSub.vue +15 -0
  337. package/src/primitives/shadcn/dropdown-menu/DropdownMenuSubContent.vue +29 -0
  338. package/src/primitives/shadcn/dropdown-menu/DropdownMenuSubTrigger.vue +31 -0
  339. package/src/primitives/shadcn/dropdown-menu/DropdownMenuTrigger.vue +14 -0
  340. package/src/primitives/shadcn/dropdown-menu/index.ts +16 -0
  341. package/src/primitives/shadcn/field/Field.vue +22 -0
  342. package/src/primitives/shadcn/field/FieldContent.vue +17 -0
  343. package/src/primitives/shadcn/field/FieldDescription.vue +24 -0
  344. package/src/primitives/shadcn/field/FieldError.vue +69 -0
  345. package/src/primitives/shadcn/field/FieldGroup.vue +22 -0
  346. package/src/primitives/shadcn/field/FieldLabel.vue +28 -0
  347. package/src/primitives/shadcn/field/FieldLegend.vue +26 -0
  348. package/src/primitives/shadcn/field/FieldSeparator.vue +28 -0
  349. package/src/primitives/shadcn/field/FieldSet.vue +23 -0
  350. package/src/primitives/shadcn/field/FieldTitle.vue +22 -0
  351. package/src/primitives/shadcn/field/index.ts +39 -0
  352. package/src/primitives/shadcn/icon/Icon.vue +38 -0
  353. package/src/primitives/shadcn/icon/index.ts +1 -0
  354. package/src/primitives/shadcn/index.ts +3 -0
  355. package/src/primitives/shadcn/input/Input.vue +35 -0
  356. package/src/primitives/shadcn/input/index.ts +1 -0
  357. package/src/primitives/shadcn/label/Label.vue +28 -0
  358. package/src/primitives/shadcn/label/index.ts +1 -0
  359. package/src/primitives/shadcn/native-select/NativeSelect.vue +56 -0
  360. package/src/primitives/shadcn/native-select/NativeSelectOptGroup.vue +18 -0
  361. package/src/primitives/shadcn/native-select/NativeSelectOption.vue +18 -0
  362. package/src/primitives/shadcn/native-select/index.ts +3 -0
  363. package/src/primitives/shadcn/popover/Popover.vue +19 -0
  364. package/src/primitives/shadcn/popover/PopoverContent.vue +41 -0
  365. package/src/primitives/shadcn/popover/PopoverTrigger.vue +11 -0
  366. package/src/primitives/shadcn/popover/index.ts +4 -0
  367. package/src/primitives/shadcn/progress/Progress.vue +30 -0
  368. package/src/primitives/shadcn/progress/index.ts +1 -0
  369. package/src/primitives/shadcn/radio-group/RadioGroup.vue +25 -0
  370. package/src/primitives/shadcn/radio-group/RadioGroupItem.vue +38 -0
  371. package/src/primitives/shadcn/radio-group/index.ts +2 -0
  372. package/src/primitives/shadcn/range-calendar/RangeCalendar.vue +73 -0
  373. package/src/primitives/shadcn/range-calendar/RangeCalendarCell.vue +28 -0
  374. package/src/primitives/shadcn/range-calendar/RangeCalendarCellTrigger.vue +46 -0
  375. package/src/primitives/shadcn/range-calendar/RangeCalendarGrid.vue +23 -0
  376. package/src/primitives/shadcn/range-calendar/RangeCalendarGridBody.vue +12 -0
  377. package/src/primitives/shadcn/range-calendar/RangeCalendarGridHead.vue +12 -0
  378. package/src/primitives/shadcn/range-calendar/RangeCalendarGridRow.vue +23 -0
  379. package/src/primitives/shadcn/range-calendar/RangeCalendarHeadCell.vue +23 -0
  380. package/src/primitives/shadcn/range-calendar/RangeCalendarHeader.vue +23 -0
  381. package/src/primitives/shadcn/range-calendar/RangeCalendarHeading.vue +30 -0
  382. package/src/primitives/shadcn/range-calendar/RangeCalendarNextButton.vue +34 -0
  383. package/src/primitives/shadcn/range-calendar/RangeCalendarPrevButton.vue +34 -0
  384. package/src/primitives/shadcn/range-calendar/index.ts +12 -0
  385. package/src/primitives/shadcn/select/Select.vue +15 -0
  386. package/src/primitives/shadcn/select/SelectContent.vue +55 -0
  387. package/src/primitives/shadcn/select/SelectGroup.vue +12 -0
  388. package/src/primitives/shadcn/select/SelectItem.vue +39 -0
  389. package/src/primitives/shadcn/select/SelectItemText.vue +12 -0
  390. package/src/primitives/shadcn/select/SelectLabel.vue +17 -0
  391. package/src/primitives/shadcn/select/SelectScrollDownButton.vue +26 -0
  392. package/src/primitives/shadcn/select/SelectScrollUpButton.vue +26 -0
  393. package/src/primitives/shadcn/select/SelectSeparator.vue +19 -0
  394. package/src/primitives/shadcn/select/SelectTrigger.vue +37 -0
  395. package/src/primitives/shadcn/select/SelectValue.vue +12 -0
  396. package/src/primitives/shadcn/select/index.ts +11 -0
  397. package/src/primitives/shadcn/separator/Separator.vue +27 -0
  398. package/src/primitives/shadcn/separator/index.ts +1 -0
  399. package/src/primitives/shadcn/slider/Slider.vue +45 -0
  400. package/src/primitives/shadcn/slider/index.ts +1 -0
  401. package/src/primitives/shadcn/spinner/Spinner.vue +18 -0
  402. package/src/primitives/shadcn/spinner/index.ts +1 -0
  403. package/src/primitives/shadcn/switch/Switch.vue +40 -0
  404. package/src/primitives/shadcn/switch/index.ts +1 -0
  405. package/src/primitives/shadcn/table/Table.vue +16 -0
  406. package/src/primitives/shadcn/table/TableBody.vue +14 -0
  407. package/src/primitives/shadcn/table/TableCaption.vue +14 -0
  408. package/src/primitives/shadcn/table/TableCell.vue +26 -0
  409. package/src/primitives/shadcn/table/TableEmpty.vue +29 -0
  410. package/src/primitives/shadcn/table/TableFooter.vue +17 -0
  411. package/src/primitives/shadcn/table/TableHead.vue +28 -0
  412. package/src/primitives/shadcn/table/TableHeader.vue +14 -0
  413. package/src/primitives/shadcn/table/TableRow.vue +21 -0
  414. package/src/primitives/shadcn/table/index.ts +9 -0
  415. package/src/primitives/shadcn/table/utils.ts +8 -0
  416. package/src/primitives/shadcn/tabs/Tabs.vue +24 -0
  417. package/src/primitives/shadcn/tabs/TabsContent.vue +21 -0
  418. package/src/primitives/shadcn/tabs/TabsList.vue +26 -0
  419. package/src/primitives/shadcn/tabs/TabsTrigger.vue +28 -0
  420. package/src/primitives/shadcn/tabs/index.ts +4 -0
  421. package/src/primitives/shadcn/textarea/Textarea.vue +33 -0
  422. package/src/primitives/shadcn/textarea/index.ts +1 -0
  423. package/src/primitives/shadcn/tooltip/Tooltip.vue +15 -0
  424. package/src/primitives/shadcn/tooltip/TooltipContent.vue +40 -0
  425. package/src/primitives/shadcn/tooltip/TooltipProvider.vue +12 -0
  426. package/src/primitives/shadcn/tooltip/TooltipTrigger.vue +12 -0
  427. package/src/primitives/shadcn/tooltip/index.ts +4 -0
  428. package/src/styles/global.css +1 -0
  429. package/src/templates/UiTemplatePlaceholder/UiTemplatePlaceholder.vue +9 -0
  430. package/src/templates/UiTemplatePlaceholder/index.ts +1 -0
  431. package/src/templates/UiTemplatePlaceholder/types.ts +8 -0
  432. package/src/templates/index.ts +6 -0
@@ -0,0 +1,54 @@
1
+ import '@testing-library/jest-dom/vitest';
2
+ import { render } from '@testing-library/vue';
3
+ import { describe, expect, test } from 'vitest';
4
+ import { UiSelect, UiSelectTrigger, UiSelectContent, UiSelectValue } from '../index';
5
+
6
+ describe('UiSelectTrigger', () => {
7
+ test('applies custom class', () => {
8
+ const { getByRole } = render({
9
+ components: { UiSelect, UiSelectTrigger, UiSelectContent, UiSelectValue },
10
+ template: `
11
+ <UiSelect>
12
+ <UiSelectTrigger class="w-[200px]">
13
+ <UiSelectValue placeholder="Select" />
14
+ </UiSelectTrigger>
15
+ <UiSelectContent />
16
+ </UiSelect>
17
+ `,
18
+ });
19
+
20
+ expect(getByRole('combobox')).toHaveClass('w-[200px]');
21
+ });
22
+
23
+ test('is disabled when disabled prop is true', () => {
24
+ const { getByRole } = render({
25
+ components: { UiSelect, UiSelectTrigger, UiSelectContent, UiSelectValue },
26
+ template: `
27
+ <UiSelect :disabled="true">
28
+ <UiSelectTrigger>
29
+ <UiSelectValue placeholder="Select" />
30
+ </UiSelectTrigger>
31
+ <UiSelectContent />
32
+ </UiSelect>
33
+ `,
34
+ });
35
+
36
+ expect(getByRole('combobox')).toBeDisabled();
37
+ });
38
+
39
+ test('applies aria-label when provided', () => {
40
+ const { getByRole } = render({
41
+ components: { UiSelect, UiSelectTrigger, UiSelectContent, UiSelectValue },
42
+ template: `
43
+ <UiSelect>
44
+ <UiSelectTrigger ariaLabel="Select your preference">
45
+ <UiSelectValue placeholder="Choose" />
46
+ </UiSelectTrigger>
47
+ <UiSelectContent />
48
+ </UiSelect>
49
+ `,
50
+ });
51
+
52
+ expect(getByRole('combobox')).toHaveAttribute('aria-label', 'Select your preference');
53
+ });
54
+ });
@@ -0,0 +1,39 @@
1
+ import '@testing-library/jest-dom/vitest';
2
+ import { render } from '@testing-library/vue';
3
+ import { describe, expect, test } from 'vitest';
4
+ import { UiSelect, UiSelectTrigger, UiSelectContent, UiSelectValue } from '../index';
5
+
6
+ describe('UiSelectValue', () => {
7
+ test('displays placeholder when no value is selected', () => {
8
+ const { getByRole } = render({
9
+ components: { UiSelect, UiSelectTrigger, UiSelectContent, UiSelectValue },
10
+ template: `
11
+ <UiSelect>
12
+ <UiSelectTrigger>
13
+ <UiSelectValue placeholder="Select an option" />
14
+ </UiSelectTrigger>
15
+ <UiSelectContent />
16
+ </UiSelect>
17
+ `,
18
+ });
19
+
20
+ expect(getByRole('combobox')).toHaveTextContent('Select an option');
21
+ });
22
+
23
+ test('applies custom class', () => {
24
+ const { container } = render({
25
+ components: { UiSelect, UiSelectTrigger, UiSelectContent, UiSelectValue },
26
+ template: `
27
+ <UiSelect>
28
+ <UiSelectTrigger>
29
+ <UiSelectValue placeholder="Select" class="text-muted" />
30
+ </UiSelectTrigger>
31
+ <UiSelectContent />
32
+ </UiSelect>
33
+ `,
34
+ });
35
+
36
+ const valueElement = container.querySelector('[data-slot="select-value"]');
37
+ expect(valueElement).toHaveClass('text-muted');
38
+ });
39
+ });
@@ -0,0 +1,10 @@
1
+ export { default as UiSelect } from './UiSelect.vue';
2
+ export { default as UiSelectTrigger } from './UiSelectTrigger.vue';
3
+ export { default as UiSelectContent } from './UiSelectContent.vue';
4
+ export { default as UiSelectItem } from './UiSelectItem.vue';
5
+ export { default as UiSelectValue } from './UiSelectValue.vue';
6
+ export { default as UiSelectLabel } from './UiSelectLabel.vue';
7
+ export { default as UiSelectGroup } from './UiSelectGroup.vue';
8
+ export { default as UiSelectSeparator } from './UiSelectSeparator.vue';
9
+
10
+ export * from './types';
@@ -0,0 +1,93 @@
1
+ /**
2
+ * A dropdown select for choosing from a list of options. Use for
3
+ * form fields where users must pick one value from many.
4
+ *
5
+ * @category Form Inputs
6
+ * @useCases dropdown selection, form picker, option list, country selector
7
+ * @keywords select, dropdown, picker, option, choice, combobox, form
8
+ * @related UiDropdownMenu, UiRadioGroup
9
+ */
10
+ export type UiSelectProps = {
11
+ /** The controlled value of the select. */
12
+ modelValue?: string;
13
+ /** The value when initially rendered (uncontrolled). */
14
+ defaultValue?: string;
15
+ /** Whether the select is open by default. */
16
+ defaultOpen?: boolean;
17
+ /** Controlled open state. */
18
+ open?: boolean;
19
+ /** Whether the select is disabled. */
20
+ disabled?: boolean;
21
+ /** Whether the select is required in a form. */
22
+ required?: boolean;
23
+ /** The name for form submission. */
24
+ name?: string;
25
+ /** Reading direction. */
26
+ dir?: 'ltr' | 'rtl';
27
+ };
28
+
29
+ /**
30
+ * Emits for the UiSelect root component.
31
+ */
32
+ export type UiSelectEmits = {
33
+ /** Emitted when the selected value changes. */
34
+ 'update:modelValue': [value: string];
35
+ /** Emitted when the open state changes. */
36
+ 'update:open': [value: boolean];
37
+ };
38
+
39
+ /**
40
+ * Props for the UiSelectTrigger component.
41
+ */
42
+ export type UiSelectTriggerProps = {
43
+ /** Accessible label for icon-only triggers. */
44
+ ariaLabel?: string;
45
+ /** Whether the trigger is disabled. */
46
+ disabled?: boolean;
47
+ /** Size of the trigger. */
48
+ size?: 'default' | 'sm';
49
+ };
50
+
51
+ /**
52
+ * Props for the UiSelectContent component.
53
+ */
54
+ export type UiSelectContentProps = {
55
+ /** Preferred side of the trigger. */
56
+ side?: 'top' | 'right' | 'bottom' | 'left';
57
+ /** Distance from the trigger in pixels. */
58
+ sideOffset?: number;
59
+ /** Alignment against the trigger. */
60
+ align?: 'start' | 'center' | 'end';
61
+ /** Positioning mode. */
62
+ position?: 'item-aligned' | 'popper';
63
+ };
64
+
65
+ /**
66
+ * Emits for the UiSelectContent component.
67
+ */
68
+ export type UiSelectContentEmits = {
69
+ /** Emitted when the Escape key is pressed. */
70
+ (e: 'escapeKeyDown', event: KeyboardEvent): void;
71
+ /** Emitted when a pointer down event occurs outside the content. */
72
+ (e: 'pointerDownOutside', event: Event): void;
73
+ };
74
+
75
+ /**
76
+ * Props for the UiSelectItem component.
77
+ */
78
+ export type UiSelectItemProps = {
79
+ /** Unique value of the item (required). */
80
+ value: string;
81
+ /** Whether the item is disabled. */
82
+ disabled?: boolean;
83
+ /** Text for typeahead purposes. */
84
+ textValue?: string;
85
+ };
86
+
87
+ /**
88
+ * Props for the UiSelectValue component.
89
+ */
90
+ export type UiSelectValueProps = {
91
+ /** Placeholder when no value is selected. */
92
+ placeholder?: string;
93
+ };
@@ -0,0 +1,226 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3-vite';
2
+ import { ref, watch } from 'vue';
3
+ import { UiSlider } from '.';
4
+
5
+ /**
6
+ * UiSlider lets users pick a numeric value (single thumb) or a range (multiple thumbs) by dragging.
7
+ * Use it for filters and settings where immediate, continuous feedback is helpful.
8
+ */
9
+ const meta: Meta<typeof UiSlider> = {
10
+ title: 'Primitives/UiSlider',
11
+ component: UiSlider,
12
+ tags: ['autodocs'],
13
+ argTypes: {
14
+ modelValue: {
15
+ control: 'object',
16
+ description:
17
+ 'Controlled slider value (array of numbers). Use `[value]` for a single thumb and `[min, max]` for a range.',
18
+ },
19
+ disabled: {
20
+ control: 'boolean',
21
+ description: 'Whether the slider is disabled.',
22
+ },
23
+ min: {
24
+ control: { type: 'number' },
25
+ description: 'Minimum value.',
26
+ },
27
+ max: {
28
+ control: { type: 'number' },
29
+ description: 'Maximum value.',
30
+ },
31
+ step: {
32
+ control: { type: 'number' },
33
+ description: 'Step size.',
34
+ },
35
+ orientation: {
36
+ control: 'select',
37
+ options: ['horizontal', 'vertical'],
38
+ description: 'Slider orientation.',
39
+ },
40
+ inverted: {
41
+ control: 'boolean',
42
+ description: 'Whether the slider direction is visually inverted (low/high swapped).',
43
+ },
44
+ },
45
+ args: {
46
+ modelValue: [50],
47
+ disabled: false,
48
+ min: 0,
49
+ max: 100,
50
+ step: 1,
51
+ orientation: 'horizontal',
52
+ inverted: false,
53
+ },
54
+ };
55
+
56
+ export default meta;
57
+ type Story = StoryObj<typeof UiSlider>;
58
+
59
+ const defaultTemplateSource = `<script setup lang="ts">
60
+ import { ref } from 'vue'
61
+ import { UiSlider } from '@aleph-alpha/ui-library'
62
+
63
+ const value = ref([50])
64
+ </script>
65
+
66
+ <template>
67
+ <div class="w-72 space-y-3">
68
+ <UiSlider v-model="value" :min="0" :max="100" :step="1" />
69
+ <div class="text-sm text-muted-foreground">Value: {{ value[0] }}</div>
70
+ </div>
71
+ </template>`;
72
+
73
+ /**
74
+ * Single-thumb slider for selecting a single numeric value.
75
+ * Use this for settings like volume/zoom/opacity.
76
+ */
77
+ export const Default: Story = {
78
+ render: (args) => ({
79
+ components: { UiSlider },
80
+ setup() {
81
+ const value = ref<number[]>(Array.isArray(args.modelValue) ? args.modelValue : [50]);
82
+ watch(
83
+ () => args.modelValue,
84
+ (val) => {
85
+ value.value = Array.isArray(val) ? val : [50];
86
+ },
87
+ );
88
+ return { args, value };
89
+ },
90
+ template: `
91
+ <div class="w-72 space-y-3">
92
+ <UiSlider
93
+ v-model="value"
94
+ :disabled="args.disabled"
95
+ :min="args.min"
96
+ :max="args.max"
97
+ :step="args.step"
98
+ :orientation="args.orientation"
99
+ :inverted="args.inverted"
100
+ />
101
+ <div class="text-sm text-muted-foreground">Value: {{ value }}</div>
102
+ </div>
103
+ `,
104
+ }),
105
+ parameters: {
106
+ docs: { source: { code: defaultTemplateSource } },
107
+ },
108
+ };
109
+
110
+ const rangeTemplateSource = `<script setup lang="ts">
111
+ import { ref } from 'vue'
112
+ import { UiSlider } from '@aleph-alpha/ui-library'
113
+
114
+ const range = ref([25, 75])
115
+ </script>
116
+
117
+ <template>
118
+ <div class="w-72 space-y-3">
119
+ <UiSlider v-model="range" :min="0" :max="100" :step="1" :min-steps-between-thumbs="5" />
120
+ <div class="text-sm text-muted-foreground">Range: {{ range[0] }} – {{ range[1] }}</div>
121
+ </div>
122
+ </template>`;
123
+
124
+ /**
125
+ * Multi-thumb slider for selecting a min/max range.
126
+ * Use this for filters like price ranges or rating ranges.
127
+ */
128
+ export const Range: Story = {
129
+ render: () => ({
130
+ components: { UiSlider },
131
+ setup() {
132
+ const range = ref([25, 75]);
133
+ return { range };
134
+ },
135
+ template: `
136
+ <div class="w-72 space-y-3">
137
+ <UiSlider v-model="range" :min="0" :max="100" :step="1" :min-steps-between-thumbs="5" />
138
+ <div class="text-sm text-muted-foreground">Range: {{ range[0] }} – {{ range[1] }}</div>
139
+ </div>
140
+ `,
141
+ }),
142
+ parameters: {
143
+ controls: { disable: true },
144
+ docs: { source: { code: rangeTemplateSource } },
145
+ },
146
+ };
147
+
148
+ const verticalTemplateSource = `<script setup lang="ts">
149
+ import { ref } from 'vue'
150
+ import { UiSlider } from '@aleph-alpha/ui-library'
151
+
152
+ const value = ref([50])
153
+ </script>
154
+
155
+ <template>
156
+ <div class="flex items-center gap-6">
157
+ <div class="h-44">
158
+ <UiSlider v-model="value" orientation="vertical" />
159
+ </div>
160
+ <div class="text-sm text-muted-foreground">Value: {{ value[0] }}</div>
161
+ </div>
162
+ </template>`;
163
+
164
+ /**
165
+ * Vertical slider orientation.
166
+ * Use this when horizontal space is limited or when matching an existing vertical control pattern.
167
+ */
168
+ export const Vertical: Story = {
169
+ render: () => ({
170
+ components: { UiSlider },
171
+ setup() {
172
+ const value = ref([50]);
173
+ return { value };
174
+ },
175
+ template: `
176
+ <div class="flex items-center gap-6">
177
+ <div class="h-44">
178
+ <UiSlider v-model="value" orientation="vertical" />
179
+ </div>
180
+ <div class="text-sm text-muted-foreground">Value: {{ value[0] }}</div>
181
+ </div>
182
+ `,
183
+ }),
184
+ parameters: {
185
+ controls: { disable: true },
186
+ docs: { source: { code: verticalTemplateSource } },
187
+ },
188
+ };
189
+
190
+ const disabledTemplateSource = `<script setup lang="ts">
191
+ import { ref } from 'vue'
192
+ import { UiSlider } from '@aleph-alpha/ui-library'
193
+
194
+ const value = ref([50])
195
+ </script>
196
+
197
+ <template>
198
+ <div class="w-72 space-y-3">
199
+ <UiSlider v-model="value" disabled />
200
+ <div class="text-sm text-muted-foreground">Value: {{ value[0] }}</div>
201
+ </div>
202
+ </template>`;
203
+
204
+ /**
205
+ * Disabled state.
206
+ * Use this when the slider is not currently applicable (e.g., gated behind another toggle).
207
+ */
208
+ export const Disabled: Story = {
209
+ render: () => ({
210
+ components: { UiSlider },
211
+ setup() {
212
+ const value = ref([50]);
213
+ return { value };
214
+ },
215
+ template: `
216
+ <div class="w-72 space-y-3">
217
+ <UiSlider v-model="value" disabled />
218
+ <div class="text-sm text-muted-foreground">Value: {{ value[0] }}</div>
219
+ </div>
220
+ `,
221
+ }),
222
+ parameters: {
223
+ controls: { disable: true },
224
+ docs: { source: { code: disabledTemplateSource } },
225
+ },
226
+ };
@@ -0,0 +1,44 @@
1
+ <script setup lang="ts">
2
+ import type { SliderRootEmits } from 'reka-ui';
3
+ import { Slider as ShadcnSlider } from '@/primitives/shadcn/slider';
4
+ import type { UiSliderProps, UiSliderEmits } from './types';
5
+
6
+ defineOptions({
7
+ name: 'UiSlider',
8
+ });
9
+
10
+ const props = defineProps<UiSliderProps>();
11
+ const emit = defineEmits<UiSliderEmits>();
12
+
13
+ function handleModelValueUpdate(
14
+ value: SliderRootEmits['update:modelValue'] extends [infer P] ? P : unknown,
15
+ ) {
16
+ if (Array.isArray(value) && value.every((v) => typeof v === 'number')) {
17
+ emit('update:modelValue', value);
18
+ return;
19
+ }
20
+
21
+ // reka-ui can emit undefined in some cases; keep our public API stable.
22
+ emit('update:modelValue', []);
23
+ }
24
+ </script>
25
+
26
+ <template>
27
+ <ShadcnSlider
28
+ :model-value="props.modelValue"
29
+ :default-value="props.defaultValue"
30
+ :disabled="props.disabled"
31
+ :orientation="props.orientation"
32
+ :dir="props.dir"
33
+ :inverted="props.inverted"
34
+ :min="props.min"
35
+ :max="props.max"
36
+ :step="props.step"
37
+ :min-steps-between-thumbs="props.minStepsBetweenThumbs"
38
+ :thumb-alignment="props.thumbAlignment"
39
+ :name="props.name"
40
+ :required="props.required"
41
+ @update:model-value="handleModelValueUpdate"
42
+ @value-commit="emit('valueCommit', $event)"
43
+ />
44
+ </template>
@@ -0,0 +1,76 @@
1
+ import { render } from '@testing-library/vue';
2
+ import { describe, expect, test, vi } from 'vitest';
3
+ import { defineComponent, h, ref } from 'vue';
4
+ import { UiSlider } from '../index';
5
+
6
+ let emitUndefinedPayload = false;
7
+
8
+ vi.mock('@/primitives/shadcn/slider', () => {
9
+ return {
10
+ Slider: defineComponent({
11
+ name: 'ShadcnSliderMock',
12
+ emits: ['update:modelValue', 'valueCommit'],
13
+ setup(_props, { emit }) {
14
+ return () =>
15
+ h('button', {
16
+ type: 'button',
17
+ onClick: () => {
18
+ const payload = emitUndefinedPayload ? undefined : [51];
19
+ emit('update:modelValue', payload);
20
+ if (!emitUndefinedPayload) {
21
+ emit('valueCommit', [51]);
22
+ }
23
+ },
24
+ });
25
+ },
26
+ }),
27
+ };
28
+ });
29
+
30
+ describe('UiSlider', () => {
31
+ test('re-emits update:modelValue and valueCommit from the vendor slider', async () => {
32
+ const { container, emitted } = render(UiSlider, {
33
+ props: { modelValue: [50] },
34
+ });
35
+
36
+ const button = container.querySelector('button');
37
+ expect(button).toBeInTheDocument();
38
+ await (button as HTMLButtonElement).click();
39
+
40
+ expect(emitted('update:modelValue')?.[0]).toEqual([[51]]);
41
+ expect(emitted('valueCommit')?.[0]).toEqual([[51]]);
42
+ });
43
+
44
+ test('normalizes invalid update:modelValue payloads to an empty array', async () => {
45
+ emitUndefinedPayload = true;
46
+ const { container, emitted } = render(UiSlider);
47
+ const button = container.querySelector('button');
48
+ expect(button).toBeInTheDocument();
49
+ await (button as HTMLButtonElement).click();
50
+
51
+ expect(emitted('update:modelValue')?.[0]).toEqual([[]]);
52
+ emitUndefinedPayload = false;
53
+ });
54
+
55
+ test('supports controlled mode via v-model:modelValue', async () => {
56
+ const { container, getByText } = render({
57
+ components: { UiSlider },
58
+ setup() {
59
+ const value = ref([50]);
60
+ return { value };
61
+ },
62
+ template: `
63
+ <div>
64
+ <div>Value: {{ value[0] }}</div>
65
+ <UiSlider v-model:modelValue="value" />
66
+ </div>
67
+ `,
68
+ });
69
+
70
+ const button = container.querySelector('button');
71
+ expect(button).toBeInTheDocument();
72
+ await (button as HTMLButtonElement).click();
73
+
74
+ expect(getByText('Value: 51')).toBeInTheDocument();
75
+ });
76
+ });
@@ -0,0 +1 @@
1
+ export { default as UiSlider } from './UiSlider.vue';
@@ -0,0 +1,101 @@
1
+ /**
2
+ * A range input for selecting numeric values by dragging a thumb along a track.
3
+ * Supports single-thumb sliders via `[value]` and multi-thumb sliders via `[min, max]`.
4
+ *
5
+ * @category Form Inputs
6
+ * @useCases volume control, price range, numeric input, filter range
7
+ * @keywords slider, range, input, thumb, track, numeric
8
+ * @related UiInput
9
+ */
10
+ export interface UiSliderProps {
11
+ /**
12
+ * The controlled value of the slider.
13
+ * Use `v-model` / `v-model:modelValue` for controlled mode.
14
+ */
15
+ modelValue?: number[];
16
+
17
+ /**
18
+ * The value of the slider when initially rendered (uncontrolled).
19
+ * @default [0]
20
+ */
21
+ defaultValue?: number[];
22
+
23
+ /**
24
+ * When `true`, prevents the user from interacting with the slider.
25
+ * @default false
26
+ */
27
+ disabled?: boolean;
28
+
29
+ /**
30
+ * The orientation of the slider.
31
+ * @default 'horizontal'
32
+ */
33
+ orientation?: 'horizontal' | 'vertical';
34
+
35
+ /**
36
+ * The reading direction.
37
+ * @default 'ltr'
38
+ */
39
+ dir?: 'ltr' | 'rtl';
40
+
41
+ /**
42
+ * Whether the slider is visually inverted.
43
+ * @default false
44
+ */
45
+ inverted?: boolean;
46
+
47
+ /**
48
+ * The minimum value for the range.
49
+ * @default 0
50
+ */
51
+ min?: number;
52
+
53
+ /**
54
+ * The maximum value for the range.
55
+ * @default 100
56
+ */
57
+ max?: number;
58
+
59
+ /**
60
+ * The stepping interval.
61
+ * @default 1
62
+ */
63
+ step?: number;
64
+
65
+ /**
66
+ * The minimum permitted steps between multiple thumbs.
67
+ * @default 0
68
+ */
69
+ minStepsBetweenThumbs?: number;
70
+
71
+ /**
72
+ * Slider thumb alignment.
73
+ * - `contain`: thumbs are contained within the track bounds.
74
+ * - `overflow`: thumbs can overflow the track bounds.
75
+ * @default 'contain'
76
+ */
77
+ thumbAlignment?: 'contain' | 'overflow';
78
+
79
+ /**
80
+ * Optional form field name (only relevant when used inside a form).
81
+ */
82
+ name?: string;
83
+
84
+ /**
85
+ * Whether the form field is required.
86
+ * @default false
87
+ */
88
+ required?: boolean;
89
+ }
90
+
91
+ export interface UiSliderEmits {
92
+ /**
93
+ * Emitted when the slider value changes.
94
+ */
95
+ (e: 'update:modelValue', value: number[]): void;
96
+
97
+ /**
98
+ * Emitted when the value changes at the end of an interaction (commit).
99
+ */
100
+ (e: 'valueCommit', value: number[]): void;
101
+ }