@livestorm/ui-vue 1.1.2 → 2.0.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 (399) hide show
  1. package/README.md +164 -32
  2. package/components-vite.js +5 -5
  3. package/components.d.ts +3 -3
  4. package/dist/UiTimelineItem.vue_vue_type_style_index_0_lang-DOLFRKcb.mjs +5565 -0
  5. package/dist/a11y-DIdrv5Mn.mjs +66 -0
  6. package/dist/breakpoints.mjs +9 -0
  7. package/dist/bus.mjs +5 -0
  8. package/dist/components.mjs +213 -1550
  9. package/dist/index.mjs +84 -166
  10. package/dist/integrations.mjs +8 -0
  11. package/dist/layouts.mjs +236 -0
  12. package/dist/responsive.mjs +25 -0
  13. package/dist/slot.mjs +21 -0
  14. package/dist/toastDSV2-wMh-UMzW.mjs +74 -0
  15. package/dist/types/index.d.ts +84 -0
  16. package/dist/types/src/components/Toast/LayoutToasts.vue.d.ts +3 -0
  17. package/dist/types/src/components/Toast/ToastMessage.vue.d.ts +21 -0
  18. package/dist/types/src/components/Toast/toastDSV2.d.ts +102 -0
  19. package/dist/types/src/components/UiActionBar/UiActionBar.vue.d.ts +44 -0
  20. package/dist/types/src/components/UiActionBar/UiActionBarItem.vue.d.ts +47 -0
  21. package/dist/types/src/components/UiActionBar/UiActionBarSeparator.vue.d.ts +3 -0
  22. package/dist/types/src/components/UiActionBar/index.d.ts +4 -0
  23. package/dist/types/src/components/UiActionBar/types.d.ts +14 -0
  24. package/dist/types/src/components/UiAnimatedLogo/UiAnimatedLogo.vue.d.ts +10 -0
  25. package/dist/types/src/components/UiAnimatedLogo/animations-links.d.ts +3 -0
  26. package/dist/types/src/components/UiAvatar/UiAvatar.vue.d.ts +55 -0
  27. package/dist/types/src/components/UiAvatar/index.d.ts +1 -0
  28. package/dist/types/src/components/UiAvatarList/UiAvatarList.vue.d.ts +28 -0
  29. package/dist/types/src/components/UiAvatarList/index.d.ts +1 -0
  30. package/dist/types/src/components/UiBadge/UiBadge.vue.d.ts +47 -0
  31. package/dist/types/src/components/UiBadge/index.d.ts +1 -0
  32. package/dist/types/src/components/UiBanner/UiBanner.vue.d.ts +96 -0
  33. package/dist/types/src/components/UiBanner/index.d.ts +2 -0
  34. package/dist/types/src/components/UiBreadcrumb/UiBreadcrumb.vue.d.ts +15 -0
  35. package/dist/types/src/components/UiBreadcrumb/index.d.ts +2 -0
  36. package/dist/types/src/components/UiButton/UiButton.vue.d.ts +249 -0
  37. package/dist/types/src/components/UiButtonGroup/UiButtonGroup.vue.d.ts +42 -0
  38. package/dist/types/src/components/UiButtonGroup/UiButtonGroupItem.vue.d.ts +21 -0
  39. package/dist/types/src/components/UiButtonGroup/index.d.ts +3 -0
  40. package/dist/types/src/components/UiButtonGroup/types.d.ts +10 -0
  41. package/dist/types/src/components/UiCard/UiCard.vue.d.ts +31 -0
  42. package/dist/types/src/components/UiCarousel/UiCarousel.vue.d.ts +63 -0
  43. package/dist/types/src/components/UiCarousel/index.d.ts +2 -0
  44. package/dist/types/src/components/UiColorField/UiColorField.vue.d.ts +19 -0
  45. package/dist/types/src/components/UiColorField/index.d.ts +2 -0
  46. package/dist/types/src/components/UiColorField/types.d.ts +29 -0
  47. package/dist/types/src/components/UiColorPicker/UiColorPicker.vue.d.ts +35 -0
  48. package/dist/types/src/components/UiColorPicker/index.d.ts +2 -0
  49. package/dist/types/src/components/UiColorPicker/types.d.ts +97 -0
  50. package/dist/types/src/components/UiDialog/MarketplaceHeaderExample.vue.d.ts +28 -0
  51. package/dist/types/src/components/UiDialog/UiDialog.vue.d.ts +18 -0
  52. package/dist/types/src/components/UiDialog/UiDialogClose.vue.d.ts +10 -0
  53. package/dist/types/src/components/UiDialog/UiDialogContent.vue.d.ts +54 -0
  54. package/dist/types/src/components/UiDialog/UiDialogFooter.vue.d.ts +13 -0
  55. package/dist/types/src/components/UiDialog/UiDialogTrigger.vue.d.ts +14 -0
  56. package/dist/types/src/components/UiDialog/index.d.ts +7 -0
  57. package/dist/types/src/components/UiDropdown/UiDropdown.vue.d.ts +42 -0
  58. package/dist/types/src/components/UiDropdown/UiDropdownContent.vue.d.ts +32 -0
  59. package/dist/types/src/components/UiDropdown/UiDropdownItem.vue.d.ts +27 -0
  60. package/dist/types/src/components/UiDropdown/UiDropdownSeparator.vue.d.ts +3 -0
  61. package/dist/types/src/components/UiDropdown/UiDropdownTrigger.vue.d.ts +45 -0
  62. package/dist/types/src/components/UiDropdown/context.d.ts +7 -0
  63. package/dist/types/src/components/UiDropdown/index.d.ts +6 -0
  64. package/dist/types/src/components/UiEmptyState/UiEmptyState.vue.d.ts +29 -0
  65. package/dist/types/src/components/UiFieldWrapper/UiFieldWrapper.vue.d.ts +36 -0
  66. package/dist/types/src/components/UiFieldWrapper/index.d.ts +1 -0
  67. package/dist/types/src/components/UiForm/UiFormField.types.d.ts +22 -0
  68. package/dist/types/src/components/UiForm/UiFormField.vue.d.ts +34 -0
  69. package/dist/types/src/components/UiForm/index.d.ts +3 -0
  70. package/dist/types/src/components/UiHorizontalSeparator/UiHorizontalSeparator.vue.d.ts +6 -0
  71. package/dist/types/src/components/UiInputCheckbox/UiInputCheckbox.vue.d.ts +108 -0
  72. package/dist/types/src/components/UiInputCheckbox/index.d.ts +2 -0
  73. package/dist/types/src/components/UiInputCheckbox/types.d.ts +1 -0
  74. package/dist/types/src/components/UiInputSelect/UiInputSelect.vue.d.ts +66 -0
  75. package/dist/types/src/components/UiInputSelect/index.d.ts +2 -0
  76. package/dist/types/src/components/UiInputSelect/types.d.ts +1 -0
  77. package/dist/types/src/components/UiInputTextarea/UiInputTextarea.vue.d.ts +49 -0
  78. package/dist/types/src/components/UiInputTextarea/index.d.ts +2 -0
  79. package/dist/types/src/components/UiInputTextarea/types.d.ts +1 -0
  80. package/dist/types/src/components/UiLabel/UiLabel.vue.d.ts +17 -0
  81. package/dist/types/src/components/UiList/UiList.vue.d.ts +27 -0
  82. package/dist/types/src/components/UiListItem/UiListItem.vue.d.ts +35 -0
  83. package/dist/types/src/components/UiLoader/UiLoader.vue.d.ts +17 -0
  84. package/dist/types/src/components/UiLogo/UiLogo.vue.d.ts +20 -0
  85. package/dist/types/src/components/UiLogo/variants/PulseVariant.vue.d.ts +3 -0
  86. package/dist/types/src/components/UiLogo/variants/TornadoVariant.vue.d.ts +3 -0
  87. package/dist/types/src/components/UiMenu/UiMenu.vue.d.ts +18 -0
  88. package/dist/types/src/components/UiMenu/UiMenuContent.vue.d.ts +30 -0
  89. package/dist/types/src/components/UiMenu/UiMenuGroup.vue.d.ts +16 -0
  90. package/dist/types/src/components/UiMenu/UiMenuItem.vue.d.ts +18 -0
  91. package/dist/types/src/components/UiMenu/UiMenuLabel.vue.d.ts +13 -0
  92. package/dist/types/src/components/UiMenu/UiMenuSeparator.vue.d.ts +13 -0
  93. package/dist/types/src/components/UiMenu/UiMenuSub.vue.d.ts +18 -0
  94. package/dist/types/src/components/UiMenu/UiMenuSubContent.vue.d.ts +32 -0
  95. package/dist/types/src/components/UiMenu/UiMenuSubTrigger.vue.d.ts +14 -0
  96. package/dist/types/src/components/UiMenu/UiMenuTrigger.vue.d.ts +14 -0
  97. package/dist/types/src/components/UiMenu/index.d.ts +10 -0
  98. package/dist/types/src/components/UiPage/UiPage.vue.d.ts +37 -0
  99. package/dist/types/src/components/UiPageHeader/UiPageHeader.vue.d.ts +33 -0
  100. package/dist/types/src/components/UiPopover/UiPopover.vue.d.ts +18 -0
  101. package/dist/types/src/components/UiPopover/UiPopoverAnchor.vue.d.ts +14 -0
  102. package/dist/types/src/components/UiPopover/UiPopoverContent.vue.d.ts +28 -0
  103. package/dist/types/src/components/UiPopover/UiPopoverTrigger.vue.d.ts +14 -0
  104. package/dist/types/src/components/UiProgress/UiProgress.vue.d.ts +15 -0
  105. package/dist/types/src/components/UiProgress/index.d.ts +2 -0
  106. package/dist/types/src/components/UiProgress/types.d.ts +4 -0
  107. package/dist/types/src/components/UiRoomButton/UiRoomButton.vue.d.ts +29 -0
  108. package/dist/types/src/components/UiShell/UiShell.vue.d.ts +24 -0
  109. package/dist/types/src/components/UiSideMenu/UiSideMenu.vue.d.ts +64 -0
  110. package/dist/types/src/components/UiSideMenu/UiSideMenuBottom.vue.d.ts +7 -0
  111. package/dist/types/src/components/UiSideMenu/UiSideMenuItem.vue.d.ts +53 -0
  112. package/dist/types/src/components/UiSideMenu/UiSideMenuItemContent.vue.d.ts +43 -0
  113. package/dist/types/src/components/UiSideMenu/UiSideMenuTop.vue.d.ts +7 -0
  114. package/dist/types/src/components/UiSideMenu/injection.d.ts +7 -0
  115. package/dist/types/src/components/UiSideMenu/types.d.ts +39 -0
  116. package/dist/types/src/components/UiSideMenu/useLabelHidden.d.ts +2 -0
  117. package/dist/types/src/components/UiSideMenu/useSideMenuLayout.d.ts +7 -0
  118. package/dist/types/src/components/UiStepper/UiStepper.vue.d.ts +18 -0
  119. package/dist/types/src/components/UiStepper/UiStepperDescription.vue.d.ts +14 -0
  120. package/dist/types/src/components/UiStepper/UiStepperIndicator.vue.d.ts +20 -0
  121. package/dist/types/src/components/UiStepper/UiStepperItem.vue.d.ts +19 -0
  122. package/dist/types/src/components/UiStepper/UiStepperSeparator.vue.d.ts +10 -0
  123. package/dist/types/src/components/UiStepper/UiStepperTitle.vue.d.ts +14 -0
  124. package/dist/types/src/components/UiStepper/index.d.ts +7 -0
  125. package/dist/types/src/components/UiTable/UiTable.vue.d.ts +20 -0
  126. package/dist/types/src/components/UiTable/UiTableBody.vue.d.ts +13 -0
  127. package/dist/types/src/components/UiTable/UiTableCell.vue.d.ts +13 -0
  128. package/dist/types/src/components/UiTable/UiTableHeader.vue.d.ts +13 -0
  129. package/dist/types/src/components/UiTable/UiTableHeaderCell.vue.d.ts +13 -0
  130. package/dist/types/src/components/UiTable/UiTableRow.vue.d.ts +16 -0
  131. package/dist/types/src/components/UiTable/index.d.ts +6 -0
  132. package/dist/types/src/components/UiTabs/UiTabs.vue.d.ts +37 -0
  133. package/dist/types/src/components/UiTabs/index.d.ts +2 -0
  134. package/dist/types/src/components/UiTag/UiTag.vue.d.ts +43 -0
  135. package/dist/types/src/components/UiTag/index.d.ts +1 -0
  136. package/dist/types/src/components/UiTextField/UiTextField.vue.d.ts +65 -0
  137. package/dist/types/src/components/UiTextField/index.d.ts +2 -0
  138. package/dist/types/src/components/UiTextField/types.d.ts +2 -0
  139. package/dist/types/src/components/UiTimeline/UiTimeline.vue.d.ts +19 -0
  140. package/dist/types/src/components/UiTimeline/UiTimelineItem.vue.d.ts +28 -0
  141. package/dist/types/src/components/UiTimeline/index.d.ts +2 -0
  142. package/dist/types/src/components/UiTooltip/UiTooltip.vue.d.ts +18 -0
  143. package/dist/types/src/components/UiTooltip/UiTooltipContent.vue.d.ts +54 -0
  144. package/dist/types/src/components/UiTooltip/UiTooltipProvider.vue.d.ts +17 -0
  145. package/dist/types/src/components/UiTooltip/UiTooltipTrigger.vue.d.ts +14 -0
  146. package/dist/types/src/components/UiTooltip/index.d.ts +4 -0
  147. package/dist/types/src/composables/useButtonStyles.d.ts +20 -0
  148. package/dist/types/src/composables/useMobileMenu.d.ts +11 -0
  149. package/dist/types/src/composables/useThemeAndModes.d.ts +34 -0
  150. package/dist/types/src/constants/index.d.ts +2 -0
  151. package/dist/types/src/constants/sizes.d.ts +2 -0
  152. package/dist/types/src/constants/themes.d.ts +22 -0
  153. package/dist/types/src/integrations/index.d.ts +1 -0
  154. package/dist/types/src/layouts/index.d.ts +2 -0
  155. package/dist/types/src/mixins/DynamicAction.d.ts +30 -0
  156. package/dist/types/src/primitives.d.ts +6 -0
  157. package/dist/types/src/theme.d.ts +1 -0
  158. package/dist/types/src/utils/a11y.d.ts +2 -0
  159. package/dist/types/src/utils/breakpoints.d.ts +9 -0
  160. package/dist/types/src/utils/bus.d.ts +2 -0
  161. package/dist/types/src/utils/clipboard.d.ts +4 -0
  162. package/dist/types/src/utils/devices.d.ts +19 -0
  163. package/dist/types/src/utils/elements.d.ts +1 -0
  164. package/dist/types/src/utils/index.d.ts +9 -0
  165. package/dist/types/src/utils/numbers.d.ts +30 -0
  166. package/dist/types/src/utils/responsive.d.ts +5 -0
  167. package/dist/types/src/utils/responsive.types.d.ts +12 -0
  168. package/dist/types/src/utils/router.d.ts +1 -0
  169. package/dist/types/src/utils/slot.d.ts +8 -0
  170. package/dist/types/src/utils/stack-view.d.ts +10 -0
  171. package/dist/types/src/utils/uid.d.ts +1 -0
  172. package/dist/types/style.d.ts +1 -0
  173. package/dist/ui-vue.css +1 -0
  174. package/dist/useThemeAndModes-DY5SDC0a.mjs +109 -0
  175. package/dist/utils.mjs +111 -0
  176. package/index.d.ts +88 -2
  177. package/index.js +169 -16
  178. package/integrations.d.ts +10 -0
  179. package/package.json +127 -58
  180. package/src/components/Toast/LayoutToasts.vue +63 -0
  181. package/src/components/Toast/ToastMessage.vue +208 -0
  182. package/src/components/Toast/toastDSV2.ts +151 -0
  183. package/src/components/UiActionBar/UiActionBar.vue +86 -0
  184. package/src/components/UiActionBar/UiActionBarItem.vue +179 -0
  185. package/src/components/UiActionBar/UiActionBarSeparator.vue +18 -0
  186. package/src/components/UiActionBar/index.ts +4 -0
  187. package/src/components/UiActionBar/types.ts +24 -0
  188. package/src/components/UiAnimatedLogo/UiAnimatedLogo.vue +47 -0
  189. package/src/components/UiAnimatedLogo/animations-links.ts +6 -0
  190. package/src/components/UiAvatar/UiAvatar.vue +186 -0
  191. package/src/components/UiAvatar/index.js +1 -0
  192. package/src/components/UiAvatarList/UiAvatarList.vue +109 -0
  193. package/src/components/UiAvatarList/index.js +1 -0
  194. package/src/components/UiBadge/UiBadge.vue +161 -0
  195. package/src/components/UiBadge/index.ts +2 -0
  196. package/src/components/UiBanner/UiBanner.vue +363 -0
  197. package/src/components/UiBanner/index.ts +2 -0
  198. package/src/components/UiBreadcrumb/UiBreadcrumb.vue +93 -0
  199. package/src/components/UiBreadcrumb/index.ts +2 -0
  200. package/src/components/UiButton/UiButton.vue +319 -0
  201. package/src/components/UiButtonGroup/UiButtonGroup.vue +198 -0
  202. package/src/components/UiButtonGroup/UiButtonGroupItem.vue +123 -0
  203. package/src/components/UiButtonGroup/index.ts +3 -0
  204. package/src/components/UiButtonGroup/types.ts +24 -0
  205. package/src/components/UiCard/UiCard.vue +112 -0
  206. package/src/components/UiCarousel/UiCarousel.vue +215 -0
  207. package/src/components/UiCarousel/index.ts +2 -0
  208. package/src/components/UiColorField/UiColorField.vue +158 -0
  209. package/src/components/UiColorField/index.ts +2 -0
  210. package/src/components/UiColorField/types.ts +30 -0
  211. package/src/components/UiColorPicker/UiColorPicker.vue +487 -0
  212. package/src/components/UiColorPicker/index.ts +2 -0
  213. package/src/components/UiColorPicker/types.ts +103 -0
  214. package/src/components/UiDialog/MarketplaceHeaderExample.vue +217 -0
  215. package/src/components/UiDialog/UiDialog.md +97 -0
  216. package/src/components/UiDialog/UiDialog.vue +16 -0
  217. package/src/components/UiDialog/UiDialogClose.vue +29 -0
  218. package/src/components/UiDialog/UiDialogContent.vue +238 -0
  219. package/src/components/UiDialog/UiDialogFooter.vue +9 -0
  220. package/src/components/UiDialog/UiDialogTrigger.vue +12 -0
  221. package/src/components/UiDialog/index.ts +18 -0
  222. package/src/components/UiDropdown/UiDropdown.vue +48 -0
  223. package/src/components/UiDropdown/UiDropdownContent.vue +72 -0
  224. package/src/components/UiDropdown/UiDropdownItem.vue +75 -0
  225. package/src/components/UiDropdown/UiDropdownSeparator.vue +7 -0
  226. package/src/components/UiDropdown/UiDropdownTrigger.vue +239 -0
  227. package/src/components/UiDropdown/context.ts +9 -0
  228. package/src/components/UiDropdown/index.ts +21 -0
  229. package/src/components/UiEmptyState/UiEmptyState.vue +80 -0
  230. package/src/components/UiFieldWrapper/UiFieldWrapper.vue +79 -0
  231. package/src/components/UiFieldWrapper/index.ts +1 -0
  232. package/src/components/UiForm/UiFormField.types.ts +24 -0
  233. package/src/components/UiForm/UiFormField.vue +66 -0
  234. package/src/components/UiForm/index.ts +3 -0
  235. package/src/components/UiHorizontalSeparator/UiHorizontalSeparator.vue +28 -0
  236. package/src/components/UiInputCheckbox/UiInputCheckbox.vue +477 -0
  237. package/src/components/UiInputCheckbox/index.ts +2 -0
  238. package/src/components/UiInputCheckbox/types.ts +1 -0
  239. package/src/components/UiInputSelect/UiInputSelect.vue +166 -0
  240. package/src/components/UiInputSelect/index.ts +2 -0
  241. package/src/components/UiInputSelect/types.ts +1 -0
  242. package/src/components/UiInputTextarea/UiInputTextarea.vue +219 -0
  243. package/src/components/UiInputTextarea/index.ts +2 -0
  244. package/src/components/UiInputTextarea/types.ts +1 -0
  245. package/src/components/UiLabel/UiLabel.vue +34 -0
  246. package/src/components/UiList/UiList.vue +45 -0
  247. package/src/components/UiListItem/UiListItem.vue +108 -0
  248. package/src/components/UiLoader/UiLoader.vue +45 -0
  249. package/src/components/UiLogo/UiLogo.vue +99 -0
  250. package/src/components/UiLogo/variants/PulseVariant.vue +51 -0
  251. package/src/components/UiLogo/variants/TornadoVariant.vue +147 -0
  252. package/src/components/UiMenu/UiMenu.vue +15 -0
  253. package/src/components/UiMenu/UiMenuContent.vue +25 -0
  254. package/src/components/UiMenu/UiMenuGroup.vue +19 -0
  255. package/src/components/UiMenu/UiMenuItem.vue +18 -0
  256. package/src/components/UiMenu/UiMenuLabel.vue +9 -0
  257. package/src/components/UiMenu/UiMenuSeparator.vue +9 -0
  258. package/src/components/UiMenu/UiMenuSub.vue +15 -0
  259. package/src/components/UiMenu/UiMenuSubContent.vue +23 -0
  260. package/src/components/UiMenu/UiMenuSubTrigger.vue +17 -0
  261. package/src/components/UiMenu/UiMenuTrigger.vue +13 -0
  262. package/src/components/UiMenu/index.ts +10 -0
  263. package/src/components/UiPage/UiPage.vue +201 -0
  264. package/src/components/UiPageHeader/UiPageHeader.vue +128 -0
  265. package/src/components/UiPopover/UiPopover.vue +16 -0
  266. package/src/components/UiPopover/UiPopoverAnchor.vue +12 -0
  267. package/src/components/UiPopover/UiPopoverContent.vue +26 -0
  268. package/src/components/UiPopover/UiPopoverTrigger.vue +19 -0
  269. package/src/components/UiProgress/UiProgress.vue +92 -0
  270. package/src/components/UiProgress/index.ts +2 -0
  271. package/src/components/UiProgress/types.ts +5 -0
  272. package/src/components/UiRoomButton/UiRoomButton.vue +240 -0
  273. package/src/components/UiShell/UiShell.vue +88 -0
  274. package/src/components/UiSideMenu/UiSideMenu.vue +513 -0
  275. package/src/components/UiSideMenu/UiSideMenuBottom.vue +27 -0
  276. package/src/components/UiSideMenu/UiSideMenuItem.vue +102 -0
  277. package/src/components/UiSideMenu/UiSideMenuItemContent.vue +172 -0
  278. package/src/components/UiSideMenu/UiSideMenuTop.vue +29 -0
  279. package/src/components/UiSideMenu/injection.ts +9 -0
  280. package/src/components/UiSideMenu/types.ts +41 -0
  281. package/src/components/UiSideMenu/useLabelHidden.ts +33 -0
  282. package/src/components/UiSideMenu/useSideMenuLayout.ts +12 -0
  283. package/src/components/UiStepper/UiStepper.vue +40 -0
  284. package/src/components/UiStepper/UiStepperDescription.vue +27 -0
  285. package/src/components/UiStepper/UiStepperIndicator.vue +93 -0
  286. package/src/components/UiStepper/UiStepperItem.vue +30 -0
  287. package/src/components/UiStepper/UiStepperSeparator.vue +49 -0
  288. package/src/components/UiStepper/UiStepperTitle.vue +24 -0
  289. package/src/components/UiStepper/index.ts +17 -0
  290. package/src/components/UiTable/UiTable.vue +24 -0
  291. package/src/components/UiTable/UiTableBody.vue +5 -0
  292. package/src/components/UiTable/UiTableCell.vue +26 -0
  293. package/src/components/UiTable/UiTableHeader.vue +17 -0
  294. package/src/components/UiTable/UiTableHeaderCell.vue +19 -0
  295. package/src/components/UiTable/UiTableRow.vue +27 -0
  296. package/src/components/UiTable/index.ts +6 -0
  297. package/src/components/UiTabs/UiTabs.vue +218 -0
  298. package/src/components/UiTabs/index.ts +5 -0
  299. package/src/components/UiTag/UiTag.vue +187 -0
  300. package/src/components/UiTag/index.js +1 -0
  301. package/src/components/UiTextField/UiTextField.vue +370 -0
  302. package/src/components/UiTextField/index.ts +2 -0
  303. package/src/components/UiTextField/types.ts +2 -0
  304. package/src/components/UiTimeline/README.md +169 -0
  305. package/src/components/UiTimeline/UiTimeline.vue +58 -0
  306. package/src/components/UiTimeline/UiTimelineItem.vue +141 -0
  307. package/src/components/UiTimeline/index.ts +2 -0
  308. package/src/components/UiTooltip/UiTooltip.vue +16 -0
  309. package/src/components/UiTooltip/UiTooltipContent.vue +86 -0
  310. package/src/components/UiTooltip/UiTooltipProvider.vue +15 -0
  311. package/src/components/UiTooltip/UiTooltipTrigger.vue +19 -0
  312. package/src/components/UiTooltip/index.js +4 -0
  313. package/src/composables/useButtonStyles.ts +242 -0
  314. package/src/composables/useMobileMenu.ts +57 -0
  315. package/src/composables/useThemeAndModes.ts +225 -0
  316. package/src/constants/index.ts +2 -0
  317. package/src/constants/sizes.ts +2 -0
  318. package/src/constants/themes.ts +34 -0
  319. package/src/css/{body.postcss → body.css} +3 -2
  320. package/src/css/reka-animations.css +209 -0
  321. package/src/css/{transitions.postcss → transitions.css} +12 -5
  322. package/src/global.d.ts +181 -0
  323. package/src/integrations/index.js +1 -0
  324. package/src/layouts/index.js +5 -0
  325. package/src/mixins/DynamicAction.js +5 -3
  326. package/src/primitives.ts +6 -0
  327. package/src/theme.ts +1 -0
  328. package/src/utils/a11y.ts +8 -0
  329. package/src/utils/{breakpoints.js → breakpoints.ts} +1 -0
  330. package/src/utils/clipboard.js +2 -2
  331. package/src/utils/devices.js +0 -3
  332. package/src/utils/index.js +2 -1
  333. package/src/utils/numbers.ts +61 -0
  334. package/src/utils/responsive.types.ts +12 -0
  335. package/src/utils/{slot.js → slot.ts} +18 -1
  336. package/style.js +3 -12
  337. package/theme.d.ts +1 -0
  338. package/.env +0 -1
  339. package/.eslintignore +0 -4
  340. package/.eslintrc.js +0 -47
  341. package/.pkg +0 -11
  342. package/babel.config.js +0 -5
  343. package/build/Dockerfile +0 -31
  344. package/ci/ci.yml +0 -54
  345. package/components-webpack.js +0 -29
  346. package/dist/environment-e70e5768.mjs +0 -1664
  347. package/dist/style.css +0 -1
  348. package/plugins.js +0 -17
  349. package/postcss.config.js +0 -1
  350. package/src/components/BaseAutocomplete/BaseAutocomplete.spec.js +0 -506
  351. package/src/components/BaseAutocomplete/BaseAutocomplete.stories.js +0 -184
  352. package/src/components/BaseAutocomplete/BaseAutocomplete.vue +0 -431
  353. package/src/components/BaseBanner/BaseBanner.spec.js +0 -32
  354. package/src/components/BaseBanner/BaseBanner.stories.js +0 -133
  355. package/src/components/BaseBanner/BaseBanner.vue +0 -229
  356. package/src/components/BaseButton/BaseButton.spec.js +0 -98
  357. package/src/components/BaseButton/BaseButton.stories.js +0 -291
  358. package/src/components/BaseButton/BaseButton.vue +0 -193
  359. package/src/components/BaseButton/__snapshots__/BaseButton.spec.js.snap +0 -37
  360. package/src/components/BaseButton/__snapshots__/BaseButton.spec.js.snap.old +0 -31
  361. package/src/components/BaseCheckbox/BaseCheckbox.stories.js +0 -82
  362. package/src/components/BaseCheckbox/BaseCheckbox.vue +0 -161
  363. package/src/components/BaseDropdownMenu/BaseDropdownMenu.stories.js +0 -84
  364. package/src/components/BaseDropdownMenu/BaseDropdownMenu.vue +0 -251
  365. package/src/components/BaseDropdownMenu/BaseDropdownMenuButton.vue +0 -26
  366. package/src/components/BaseDropdownMenu/BaseDropdownMenuDivider.vue +0 -10
  367. package/src/components/BaseDropdownMenu/BaseDropdownMenuItem.vue +0 -206
  368. package/src/components/BaseDropdownMenu/BaseDropdownMenuSearch.vue +0 -49
  369. package/src/components/BaseDropdownMenu/BaseDropdownMenuTitle.vue +0 -26
  370. package/src/components/BaseModal/BaseModal.stories.js +0 -143
  371. package/src/components/BaseModal/BaseModal.vue +0 -187
  372. package/src/components/BaseModal/BaseModalContent.vue +0 -164
  373. package/src/components/BaseModal/BaseModalContentOld.vue +0 -242
  374. package/src/components/BaseRating/BaseRating.spec.js +0 -46
  375. package/src/components/BaseRating/BaseRating.stories.js +0 -46
  376. package/src/components/BaseRating/BaseRating.vue +0 -119
  377. package/src/components/BaseSelect/BaseSelect.stories.js +0 -177
  378. package/src/components/BaseSelect/BaseSelect.vue +0 -443
  379. package/src/components/BaseSelect/BaseSelectGroup.vue +0 -34
  380. package/src/components/BaseSelect/BaseSelectOption.vue +0 -219
  381. package/src/components/BaseSwitch/BaseSwitch.stories.js +0 -44
  382. package/src/components/BaseSwitch/BaseSwitch.vue +0 -114
  383. package/src/components/BaseTag/BaseTag.stories.js +0 -123
  384. package/src/components/BaseTag/BaseTag.vue +0 -244
  385. package/src/css/button.postcss +0 -354
  386. package/src/css/checkbox-radio.postcss +0 -152
  387. package/src/css/icon.postcss +0 -9
  388. package/src/css/loader.postcss +0 -120
  389. package/src/css/popper.postcss +0 -143
  390. package/src/css/tailwind-utilities.postcss +0 -1
  391. package/src/css/tailwind.postcss +0 -2
  392. package/style-postcss.d.ts +0 -3
  393. package/style-postcss.js +0 -2
  394. package/tailwind.config.base.cjs +0 -88
  395. package/tailwind.config.js +0 -9
  396. package/tsconfig.check.json +0 -13
  397. package/tsconfig.json +0 -66
  398. package/vite.config.js +0 -43
  399. package/vitest.setup.js +0 -26
@@ -0,0 +1,63 @@
1
+ <script setup lang="ts">
2
+ import { computed, getCurrentInstance } from 'vue'
3
+ import type { ResponsiveGlobalComponentProperty } from '../../utils/responsive.types'
4
+ import { useToasts, type ToastOptions } from './toastDSV2'
5
+ import ToastMessage from './ToastMessage.vue'
6
+
7
+ const app = getCurrentInstance()
8
+ if (!app) {
9
+ throw new Error('No current instance found')
10
+ }
11
+ const responsive = computed(() => app.appContext.config.globalProperties.$responsive as ResponsiveGlobalComponentProperty)
12
+
13
+ const MAX_ITEMS_DISPLAYED = 3
14
+
15
+ const { toasts, closeToast, cancelCloseTimer, openToast } = useToasts()
16
+
17
+ const hasLockedToast = computed(() => toasts.value.some(toast => toast.locked))
18
+
19
+ function onBeforeLeave (el: Element) {
20
+ const bounds = el.getBoundingClientRect()
21
+ const { style } = el as HTMLElement
22
+ style.top = `${bounds.top}px`
23
+ style.left = `${bounds.left}px`
24
+ style.width = `${bounds.width}px`
25
+ style.height = `${bounds.height}px`
26
+ }
27
+ </script>
28
+
29
+ <template>
30
+ <transition
31
+ :duration="200"
32
+ appear
33
+ >
34
+ <div
35
+ v-if="hasLockedToast"
36
+ data-testid="layout-toasts-locked"
37
+ class="bg-alpha-black-300 fixed inset-0 z-[8000]"
38
+ />
39
+ </transition>
40
+ <TransitionGroup
41
+ name="list"
42
+ tag="div"
43
+ :class="!responsive?.mobile ? 'm-8 max-w-md w-full' : 'm-4 right-0'"
44
+ class="fixed left-0 bottom-0 flex flex-col gap-2 z-max"
45
+ @before-leave="onBeforeLeave"
46
+ >
47
+ <div
48
+ v-for="item of toasts.slice(0, MAX_ITEMS_DISPLAYED)"
49
+ :key="item.id"
50
+ class="w-full sm:max-w-[400px]"
51
+ >
52
+ <ToastMessage
53
+ v-bind="item"
54
+ class="bg-surface-neutral-bg-main p-3 rounded-2xl"
55
+ @close="closeToast(item.id)"
56
+ @mouseenter="cancelCloseTimer(item.id)"
57
+ @mouseleave="item.time ? openToast({ id: item.id } as ToastOptions) : null"
58
+ @confirm="item.confirmEventHook.trigger(undefined)"
59
+ @cancel="item.cancelEventHook.trigger(undefined)"
60
+ />
61
+ </div>
62
+ </TransitionGroup>
63
+ </template>
@@ -0,0 +1,208 @@
1
+ <script setup lang="ts">
2
+ import { computed, ref, onMounted } from 'vue'
3
+ // * The explicit import here helps the Storybook
4
+ // * but prevents the frontend from UiButton.
5
+ // * We either have the frontend app working or the Storybook working.
6
+ // import UiButton from '../UiButton/UiButton.vue'
7
+
8
+ import type { ToastOptions } from './toastDSV2'
9
+ import useThemeAndModes from '../../composables/useThemeAndModes'
10
+
11
+ type ToastMessageProps = Partial<ToastOptions>
12
+
13
+ const props = withDefaults(defineProps<ToastMessageProps>(), {
14
+ type: 'info',
15
+ locked: false,
16
+ closable: true,
17
+ confirmHrefTarget: '_blank',
18
+ })
19
+
20
+ const emit = defineEmits([
21
+ 'close',
22
+ 'confirm',
23
+ 'cancel',
24
+ 'mouseenter',
25
+ 'mouseleave',
26
+ ])
27
+
28
+ // @todo: make composable function since also used for modal icon
29
+ const modalIcon = computed(() => {
30
+ if (props.customIcon) return props.customIcon
31
+
32
+ switch (props.type) {
33
+ case 'alert':
34
+ return 'i-ls-x-circle !text-text-danger-base'
35
+ case 'warning':
36
+ return 'i-ls-alert-triangle !text-text-warning-base'
37
+ case 'info':
38
+ return 'i-ls-info text-text-primary-base'
39
+ case 'success':
40
+ return 'i-ls-check-circle text-text-success-base'
41
+ default:
42
+ return undefined
43
+ }
44
+ })
45
+
46
+ const startTimer = ref(false)
47
+ const hovered = ref(false)
48
+
49
+ const enableProgressBar = computed(() => props.progessIndeterminate || (props.time && ['success', 'info'].includes(props.type)))
50
+
51
+ function onMouseleave () {
52
+ hovered.value = false
53
+ emit('mouseleave')
54
+
55
+ // Reset the progress bar animation
56
+ if (props.time) {
57
+ startTimer.value = false
58
+
59
+ setTimeout(() => {
60
+ startTimer.value = true
61
+ }, 100)
62
+ }
63
+ }
64
+
65
+ if (props.time) {
66
+ // The delay is used to trigger the CSS transition
67
+ setTimeout(() => {
68
+ startTimer.value = true
69
+ }, 100)
70
+ }
71
+
72
+ const Toast = ref<HTMLElement | undefined>()
73
+ const { addElementToWatch } = useThemeAndModes()
74
+ onMounted(() => {
75
+ if (Toast.value) {
76
+ addElementToWatch(
77
+ 'content',
78
+ {
79
+ selector: '[data-name="ui-toast-message"]',
80
+ element: Toast.value,
81
+ modeOverride: 'light',
82
+ })
83
+ }
84
+ })
85
+ </script>
86
+
87
+ <template>
88
+ <div
89
+ class=" relative grid grid-flow-col grid-rows-[auto_auto_auto] sm:grid-rows-1 sm:grid-cols-[auto_1fr_auto] items-start p-4 bg-surface-neutral-bg-main shadow-shadows-drop-shadow-lg rounded-xl gap-x-0 overflow-hidden"
90
+ :data-testid="`toast-message-${String(id)}`"
91
+ data-colors-semantic="light"
92
+ data-name="ui-toast-message"
93
+ @mouseenter="hovered = true, emit('mouseenter')"
94
+ @mouseleave="onMouseleave"
95
+ >
96
+ <div
97
+ v-if="props.component"
98
+ ref="Toast"
99
+ class="flex-1 min-w-0"
100
+ >
101
+ <component
102
+ :is="{...props.component}"
103
+ v-bind="props.componentProps"
104
+ />
105
+ </div>
106
+ <template v-else>
107
+ <!-- TODO: handle DSV2 tokens -->
108
+ <template v-if="enableProgressBar">
109
+ <div
110
+ v-if="time"
111
+ ref="Toast"
112
+ class="absolute opacity-100 transition-opacity duration-300 h-1 bg-grey-100 top-0 left-0 w-full"
113
+ :class="{
114
+ 'opacity-0!': hovered
115
+ }"
116
+ >
117
+ <div
118
+ v-if="time"
119
+ class="h-full w-0 ease-linear duration-1000"
120
+ :class="[startTimer ? 'w-full transition-all': 'transition-none', {
121
+ 'bg-green-600': props.type === 'success',
122
+ 'bg-livestorm-600': props.type === 'info'
123
+ }]"
124
+ :style="{
125
+ transitionDuration: `${(props.time as number)/1000}s`
126
+ }"
127
+ />
128
+ </div>
129
+ <div
130
+ v-else-if="props.progessIndeterminate"
131
+ class="absolute h-1 bg-grey-100 top-0 left-0 w-full"
132
+ >
133
+ <div class="animate-progress-indeterminate w-full h-full bg-red-600 origin-left-right" />
134
+ </div>
135
+ </template>
136
+
137
+ <div class="shrink-0">
138
+ <div
139
+ v-if="modalIcon"
140
+ class="w-4 h-4 mt-0.5 mr-3 shrink-0 mb-2 sm:mb-0"
141
+ :class="modalIcon"
142
+ />
143
+ </div>
144
+ <div class="flex flex-col flex-1 sm:row-start-1 min-w-0 wrap-break-word">
145
+ <span
146
+ v-if="props.title || props.message"
147
+ class="text-content-text-md-bold text-text-neutral-base"
148
+ >{{ props.title || props.message }}</span>
149
+ <p
150
+ v-if="props.title && props.message"
151
+ class="text-content-text-md-regular"
152
+ >
153
+ {{ props.message }}
154
+ </p>
155
+ <p
156
+ v-if="props.info"
157
+ class="text-content-text-md-regular text-text-neutral-subtle mt-1"
158
+ >
159
+ {{ props.info }}
160
+ </p>
161
+ </div>
162
+ </template>
163
+
164
+ <div class="row-start-1 h-4 w-8 justify-self-end">
165
+ <UiButton
166
+ v-if="!props.locked && props.closable"
167
+ :data-testid="`toast-close-${String(props.id)}`"
168
+ color="neutral"
169
+ variant="tertiary"
170
+ icon="i-ls-x"
171
+ size="md"
172
+ aria-label="close"
173
+ class="-top-[10px] -right-[2px] sm:row-start-1"
174
+ @click="emit('close')"
175
+ @keydown.enter="emit('close')"
176
+ />
177
+ </div>
178
+
179
+ <div
180
+ v-if="props.confirmLabel || props.cancelLabel"
181
+ class="row-start-3 col-start-1 col-end-3 w-full grid sm:flex sm:col-start-2 mt-3 gap-2 justify-self-end"
182
+ >
183
+ <UiButton
184
+ v-if="props.confirmLabel"
185
+ :href="props.confirmHref"
186
+ :to="props.confirmTo"
187
+ :target="props.confirmHrefTarget"
188
+ :icon="props.confirmIcon"
189
+ color="primary"
190
+ variant="cta"
191
+ class="w-full sm:w-auto"
192
+ @click="$emit('confirm', $event)"
193
+ >
194
+ {{ props.confirmLabel }}
195
+ </UiButton>
196
+
197
+ <UiButton
198
+ v-if="props.cancelLabel"
199
+ color="neutral-invert"
200
+ variant="cta"
201
+ class="w-full sm:w-auto"
202
+ @click="$emit('cancel')"
203
+ >
204
+ {{ props.cancelLabel }}
205
+ </UiButton>
206
+ </div>
207
+ </div>
208
+ </template>
@@ -0,0 +1,151 @@
1
+ import { ref } from 'vue'
2
+ import type { Component } from 'vue'
3
+ import type { RouteLocationRaw } from 'vue-router'
4
+ import { createEventHook, type EventHook } from '@vueuse/core'
5
+
6
+ import type { ThemeColorType } from '../../theme'
7
+
8
+ let uid = 1
9
+
10
+ export type ToastType = 'alert'|'warning'|'info'|'success'
11
+
12
+ const DEFAULT_TIMER_DURATION_PER_TYPE: Record<Extract<ToastType, 'success'|'info'>, number> = {
13
+ success: 3 * 1000,
14
+ info: 7 * 1000,
15
+ }
16
+
17
+ export interface ToastOptions {
18
+ message: string
19
+ id?: PropertyKey
20
+ title?: string
21
+ info?: string
22
+ type?: ThemeColorType
23
+ time?: number | boolean // if time is explicitly false, the toast will not auto-close
24
+ progessIndeterminate?: boolean
25
+ customIcon?: string
26
+ confirmLabel?: string
27
+ confirmHref?: string
28
+ confirmHrefTarget?: '_blank'|'_self'
29
+ confirmTo?: RouteLocationRaw
30
+ confirmIcon?: string
31
+ confirmColor?: ThemeColorType
32
+ cancelLabel?: string
33
+ locked?: boolean
34
+ closable?: boolean
35
+ component?: Component
36
+ componentProps?: Record<string, unknown>
37
+ }
38
+
39
+ interface ToastItem {
40
+ id: PropertyKey
41
+ message: string
42
+ title?: string
43
+ info?: string
44
+ type?: ThemeColorType
45
+ icon?: string
46
+ time?: number
47
+ locked?: boolean
48
+ progessIndeterminate?: boolean
49
+ closeTimer: any
50
+ confirmEventHook: EventHook
51
+ cancelEventHook: EventHook
52
+ }
53
+
54
+ const toasts = ref<ToastItem[]>([])
55
+
56
+ export function useToasts () {
57
+ return {
58
+ toasts,
59
+ closeToast,
60
+ openToast,
61
+ cancelCloseTimer,
62
+ }
63
+ }
64
+
65
+ export function openToast (options: ToastOptions) {
66
+ let id: PropertyKey
67
+ let item = toasts.value.find(item => item.id === options.id)
68
+ const confirmEventHook = createEventHook<void>()
69
+ const cancelEventHook = createEventHook<void>()
70
+
71
+ if (item) {
72
+ id = item.id
73
+ Object.assign(item, {
74
+ ...options,
75
+ })
76
+
77
+ const restartTimer = options.id && Object.keys(options).length === 1
78
+ if (restartTimer) {
79
+ startTimer(item)
80
+ }
81
+ } else {
82
+ id = options.id ?? uid++
83
+
84
+ const type = options.type || 'info'
85
+ const typeWithTimer = type === 'success' || type === 'info'
86
+ // `true` picks the per-type default; a number is used as-is; `false`
87
+ // (or unset) means no auto-close — normalized to undefined so the timer
88
+ // is never started.
89
+ const time = options.time === true
90
+ ? (typeWithTimer ? DEFAULT_TIMER_DURATION_PER_TYPE[type] : undefined)
91
+ : (typeof options.time === 'number' ? options.time : undefined)
92
+ item = {
93
+ ...options,
94
+ id,
95
+ closeTimer: null,
96
+ confirmEventHook,
97
+ cancelEventHook,
98
+ time,
99
+ type,
100
+ }
101
+
102
+ toasts.value.push(item)
103
+
104
+ startTimer(item)
105
+ }
106
+
107
+ return {
108
+ id,
109
+ close: () => {
110
+ closeToast(id)
111
+ },
112
+ onConfirm: confirmEventHook.on,
113
+ onCancel: cancelEventHook.on,
114
+ }
115
+ }
116
+
117
+ export function closeToast (id: PropertyKey) {
118
+ const item = toasts.value.find(item => item.id === id)
119
+ if (item) {
120
+ clearTimeout(item.closeTimer)
121
+ removeToast(id)
122
+ }
123
+ }
124
+
125
+ export function cancelCloseTimer (id: PropertyKey) {
126
+ const item = toasts.value.find(item => item.id === id)
127
+ if (item) {
128
+ clearTimeout(item.closeTimer)
129
+ }
130
+ }
131
+
132
+ export function resetToasts () {
133
+ toasts.value = []
134
+ }
135
+
136
+ function removeToast (id: PropertyKey) {
137
+ const index = toasts.value.findIndex(item => item.id === id)
138
+ if (index !== -1) {
139
+ toasts.value.splice(index, 1)
140
+ }
141
+ }
142
+
143
+ function startTimer (item: ToastItem): void {
144
+ if (item.time) {
145
+ item.closeTimer = setTimeout(
146
+ () => {
147
+ closeToast(item.id)
148
+ }, item.time
149
+ )
150
+ }
151
+ }
@@ -0,0 +1,86 @@
1
+ <script setup lang="ts">
2
+ import { computed, provide } from 'vue'
3
+ import type { ActionBarOrientation, ActionBarPosition, ActionBarSize } from './types'
4
+ import { ACTION_BAR_CONTEXT_KEY } from './types'
5
+
6
+ interface UiActionBarProps {
7
+ /**
8
+ * Lays the items out in a horizontal bar (default) or a vertical rail,
9
+ * matching the two variants in the design system.
10
+ */
11
+ orientation?: ActionBarOrientation
12
+ size?: ActionBarSize
13
+ /**
14
+ * Anchors the bar to a corner of its nearest positioned ancestor.
15
+ * When set, the bar is rendered `absolute` — the parent must be `relative`.
16
+ * Leave undefined (default) to keep the bar in normal flow and position it
17
+ * yourself.
18
+ */
19
+ position?: ActionBarPosition
20
+ /**
21
+ * Distance (in Tailwind spacing units) from the anchored edges when
22
+ * `position` is set. Defaults to `3` (12px).
23
+ */
24
+ offset?: number
25
+ /**
26
+ * Accessible label for the toolbar landmark. Defaults to "Actions".
27
+ */
28
+ ariaLabel?: string
29
+ }
30
+
31
+ const props = withDefaults(defineProps<UiActionBarProps>(), {
32
+ orientation: 'horizontal',
33
+ size: 'md',
34
+ position: undefined,
35
+ offset: 3,
36
+ ariaLabel: 'Actions',
37
+ })
38
+
39
+ provide(ACTION_BAR_CONTEXT_KEY, {
40
+ orientation: computed<ActionBarOrientation>(() => props.orientation),
41
+ size: computed<ActionBarSize>(() => props.size),
42
+ })
43
+
44
+ const isVertical = computed(() => props.orientation === 'vertical')
45
+
46
+ // Inner padding follows the design tokens (space-0-5 = 2px).
47
+ const sizeClasses = computed(() => (props.size === 'sm' ? 'p-0.5 gap-0.5' : 'p-1 gap-0.5'))
48
+
49
+ // When `position` is set, anchor the bar to an edge of its positioned
50
+ // ancestor. Offsets are inline styles (rem) so any `offset` value works
51
+ // without relying on Tailwind JIT seeing dynamic class names. `center-*`
52
+ // pins the bar to 50% on the vertical axis and shifts it back by half its
53
+ // own height so it sits exactly centered.
54
+ const positionStyle = computed<Record<string, string>>(() => {
55
+ if (!props.position) return {}
56
+ const gap = `${props.offset * 0.25}rem`
57
+ const [vertical, horizontal] = props.position.split('-')
58
+
59
+ if (vertical === 'center') {
60
+ return {
61
+ top: '50%',
62
+ transform: 'translateY(-50%)',
63
+ [horizontal]: gap,
64
+ }
65
+ }
66
+
67
+ return {
68
+ [vertical]: gap,
69
+ [horizontal]: gap,
70
+ }
71
+ })
72
+ </script>
73
+
74
+ <template>
75
+ <div
76
+ role="toolbar"
77
+ :aria-label="ariaLabel"
78
+ :aria-orientation="orientation"
79
+ data-testid="ui-action-bar"
80
+ class="inline-flex items-center bg-surface-neutral-bg-main rounded-xl border border-borders-neutral-light shadow-lg"
81
+ :class="[sizeClasses, { 'flex-col': isVertical, 'absolute z-10': position }]"
82
+ :style="positionStyle"
83
+ >
84
+ <slot />
85
+ </div>
86
+ </template>
@@ -0,0 +1,179 @@
1
+ <script setup lang="ts">
2
+ import { computed, inject } from 'vue'
3
+ import {
4
+ TooltipProvider,
5
+ TooltipRoot,
6
+ TooltipTrigger,
7
+ TooltipContent,
8
+ TooltipPortal,
9
+ TooltipArrow,
10
+ } from 'reka-ui'
11
+ import type { RouteLocationRaw } from 'vue-router'
12
+ import { ACTION_BAR_CONTEXT_KEY } from './types'
13
+
14
+ interface UiActionBarItemProps {
15
+ /** Icon class, e.g. `i-ls-trash`. */
16
+ icon?: string
17
+ /** Visible/accessible label. Required so icon-only items stay accessible. */
18
+ label: string
19
+ /**
20
+ * Optional icon class rendered next to the label inside the hover tooltip —
21
+ * e.g. `i-ls-external-link` to flag that the action opens in a new tab.
22
+ * Only shown for icon-only items (the tooltip is suppressed when
23
+ * `showLabel` is set).
24
+ */
25
+ tooltipIcon?: string
26
+ /**
27
+ * When false (default), only the icon shows and the label is exposed as a
28
+ * hover tooltip + aria-label. Set true to render the label inline next to
29
+ * the icon (used for primary/secondary actions like "Promote").
30
+ */
31
+ showLabel?: boolean
32
+ disabled?: boolean
33
+ /** Render as a router-link instead of a button. */
34
+ to?: RouteLocationRaw
35
+ /** Render as an anchor instead of a button. */
36
+ href?: string
37
+ /**
38
+ * Marks the item as a toggle and reflects its on/off state. When set, the
39
+ * item renders `aria-pressed` and shows a pressed background while `true`.
40
+ * Leave undefined for a normal (non-toggle) action — no `aria-pressed` is
41
+ * emitted in that case.
42
+ */
43
+ active?: boolean
44
+ }
45
+
46
+ const props = withDefaults(defineProps<UiActionBarItemProps>(), {
47
+ icon: undefined,
48
+ tooltipIcon: undefined,
49
+ showLabel: false,
50
+ disabled: false,
51
+ to: undefined,
52
+ href: undefined,
53
+ active: undefined,
54
+ })
55
+
56
+ const emit = defineEmits<{ click: [event: MouseEvent] }>()
57
+
58
+ const ctx = inject(ACTION_BAR_CONTEXT_KEY, null)
59
+ const size = computed(() => ctx?.size.value ?? 'md')
60
+ const orientation = computed(() => ctx?.orientation.value ?? 'horizontal')
61
+
62
+ // Icon-only items get a tooltip; labeled items don't need one.
63
+ const showTooltip = computed(() => !props.showLabel)
64
+ const tooltipSide = computed(() => (orientation.value === 'vertical' ? 'right' : 'bottom'))
65
+
66
+ const component = computed(() => {
67
+ if (props.disabled) return { is: 'button', props: { type: 'button', disabled: true } }
68
+ if (props.to) return { is: 'router-link', props: { to: props.to } }
69
+ if (props.href) return { is: 'a', props: { href: props.href } }
70
+ return { is: 'button', props: { type: 'button' } }
71
+ })
72
+
73
+ const sizeClasses = computed(() => {
74
+ const square = size.value === 'sm' ? 'size-8' : 'size-10'
75
+ // Labeled items grow with their text instead of staying square.
76
+ const padded = size.value === 'sm' ? 'h-8 px-2.5 gap-1' : 'h-10 px-3 gap-1.5'
77
+ return props.showLabel ? padded : square
78
+ })
79
+
80
+ const iconSizeClass = computed(() => (size.value === 'sm' ? 'size-4' : 'size-5'))
81
+ const textClass = computed(() => (size.value === 'sm' ? 'text-action-button-sm' : 'text-action-button-md'))
82
+
83
+ // Persistent pressed background when the item is an active toggle. Uses the
84
+ // dedicated neutral "active" token so an active-but-not-hovered toggle stays
85
+ // visually distinct from a merely hovered item.
86
+ const stateClasses = computed(() => ({
87
+ 'bg-actions-neutral-active-overlay': props.active === true,
88
+ }))
89
+
90
+ function onClick (event: MouseEvent) {
91
+ if (props.disabled) {
92
+ event.preventDefault()
93
+ return
94
+ }
95
+ emit('click', event)
96
+ // Release focus after activating. When the bar is revealed on hover/focus
97
+ // (a common pattern — `group-hover` / `group-focus-within` on a row), a
98
+ // lingering focus would keep it visible after the pointer leaves. Blurring
99
+ // lets the reveal collapse once the cursor moves away.
100
+ ;(event.currentTarget as HTMLElement | null)?.blur()
101
+ }
102
+ </script>
103
+
104
+ <template>
105
+ <TooltipProvider
106
+ v-if="showTooltip"
107
+ :delay-duration="300"
108
+ >
109
+ <TooltipRoot>
110
+ <TooltipTrigger as-child>
111
+ <component
112
+ :is="component.is"
113
+ v-bind="component.props"
114
+ :aria-label="label"
115
+ :aria-pressed="active"
116
+ data-testid="ui-action-bar-item"
117
+ class="group inline-flex items-center justify-center rounded-lg shrink-0 outline-none transition-colors
118
+ text-actions-neutral-idle
119
+ hover:bg-actions-neutral-hover-overlay
120
+ focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-focus-ring
121
+ disabled:opacity-50 disabled:cursor-not-allowed"
122
+ :class="[sizeClasses, textClass, stateClasses, { 'cursor-pointer': !disabled }]"
123
+ @click="onClick"
124
+ >
125
+ <span
126
+ v-if="icon"
127
+ :class="[icon, iconSizeClass]"
128
+ class="shrink-0"
129
+ />
130
+ </component>
131
+ </TooltipTrigger>
132
+ <TooltipPortal>
133
+ <TooltipContent
134
+ :side="tooltipSide"
135
+ :side-offset="8"
136
+ data-colors-semantic="light"
137
+ class="inline-flex items-center justify-center gap-1.5 py-1.5 px-3 bg-surface-neutral-invert-bg-alpha text-text-neutral-invert-base text-content-text-md-regular rounded-md text-center z-50 shadow-shadows-drop-shadow-lg
138
+ data-[state=delayed-open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=delayed-open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=delayed-open]:zoom-in-95"
139
+ >
140
+ {{ label }}
141
+ <span
142
+ v-if="tooltipIcon"
143
+ :class="tooltipIcon"
144
+ class="size-3.5 shrink-0"
145
+ aria-hidden="true"
146
+ />
147
+ <TooltipArrow
148
+ :width="10"
149
+ :height="5"
150
+ class="fill-surface-neutral-invert-bg-alpha"
151
+ />
152
+ </TooltipContent>
153
+ </TooltipPortal>
154
+ </TooltipRoot>
155
+ </TooltipProvider>
156
+
157
+ <component
158
+ :is="component.is"
159
+ v-else
160
+ v-bind="component.props"
161
+ :aria-label="label"
162
+ :aria-pressed="active"
163
+ data-testid="ui-action-bar-item"
164
+ class="group inline-flex items-center justify-center rounded-lg shrink-0 outline-none transition-colors
165
+ text-actions-neutral-idle
166
+ hover:bg-actions-neutral-hover-overlay
167
+ focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-focus-ring
168
+ disabled:opacity-50 disabled:cursor-not-allowed"
169
+ :class="[sizeClasses, textClass, stateClasses, { 'cursor-pointer': !disabled }]"
170
+ @click="onClick"
171
+ >
172
+ <span
173
+ v-if="icon"
174
+ :class="[icon, iconSizeClass]"
175
+ class="shrink-0"
176
+ />
177
+ <span class="whitespace-nowrap">{{ label }}</span>
178
+ </component>
179
+ </template>