@livestorm/ui-vue 2.0.5 → 4.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 (302) hide show
  1. package/README.md +9 -6
  2. package/components-vite.js +2 -2
  3. package/dist/UiButton-uyW8EHRJ.mjs +602 -0
  4. package/dist/UiTimelineItem-EiOEi1yF.mjs +7293 -0
  5. package/dist/UiTooltip-DZcPD6_N.mjs +158 -0
  6. package/dist/a11y-CaZxRWzo.mjs +6 -0
  7. package/dist/breakpoints.mjs +4 -9
  8. package/dist/bus.mjs +5 -5
  9. package/dist/components.mjs +236 -222
  10. package/dist/i18n-B8QOMuFD.mjs +46 -0
  11. package/dist/index.mjs +4 -87
  12. package/dist/integrations.mjs +3 -14
  13. package/dist/layouts.mjs +228 -236
  14. package/dist/responsive.mjs +31 -36
  15. package/dist/slot.mjs +11 -17
  16. package/dist/toastDSV2-D3xDZPe5.mjs +105 -0
  17. package/dist/types/index.d.ts +23 -1
  18. package/dist/types/src/components/Toast/ToastMessage.vue.d.ts +17 -7
  19. package/dist/types/src/components/Toast/toastDSV2.d.ts +89 -64
  20. package/dist/types/src/components/UiActionBar/UiActionBar.vue.d.ts +3 -1
  21. package/dist/types/src/components/UiActionBar/UiActionBarItem.vue.d.ts +18 -3
  22. package/dist/types/src/components/UiActionBar/types.d.ts +5 -1
  23. package/dist/types/src/components/UiAvatar/UiAvatar.vue.d.ts +4 -2
  24. package/dist/types/src/components/UiAvatarList/UiAvatarList.vue.d.ts +3 -2
  25. package/dist/types/src/components/UiBanner/UiBanner.vue.d.ts +13 -1
  26. package/dist/types/src/components/UiButton/UiButton.vue.d.ts +102 -38
  27. package/dist/types/src/components/UiButtonGroup/UiButtonGroup.vue.d.ts +8 -2
  28. package/dist/types/src/components/UiButtonGroup/UiButtonGroupItem.vue.d.ts +3 -0
  29. package/dist/types/src/components/UiButtonGroup/types.d.ts +5 -1
  30. package/dist/types/src/components/UiChoice/UiChoice.vue.d.ts +71 -0
  31. package/dist/types/src/components/UiChoice/index.d.ts +2 -0
  32. package/dist/types/src/components/UiChoice/types.d.ts +7 -0
  33. package/dist/types/src/components/UiColorField/UiColorField.vue.d.ts +1 -1
  34. package/dist/types/src/components/UiColorPicker/UiColorPicker.vue.d.ts +2 -2
  35. package/dist/types/src/components/UiCombobox/UiCombobox.types.d.ts +47 -0
  36. package/dist/types/src/components/UiCombobox/UiCombobox.vue.d.ts +40 -0
  37. package/dist/types/src/components/UiCombobox/index.d.ts +2 -0
  38. package/dist/types/src/components/UiDataTable/UiDataTable.types.d.ts +46 -0
  39. package/dist/types/src/components/UiDataTable/UiDataTable.vue.d.ts +136 -0
  40. package/dist/types/src/components/UiDataTable/index.d.ts +5 -0
  41. package/dist/types/src/components/UiDrawer/UiDrawer.vue.d.ts +28 -0
  42. package/dist/types/src/components/UiDrawer/UiDrawerContent.vue.d.ts +18 -0
  43. package/dist/types/src/components/UiDrawer/UiDrawerTrigger.vue.d.ts +14 -0
  44. package/dist/types/src/components/UiDropdown/DropdownItemCheckbox.vue.d.ts +3 -0
  45. package/dist/types/src/components/UiDropdown/UiDropdownContent.vue.d.ts +10 -0
  46. package/dist/types/src/components/UiDropdown/UiDropdownGroup.vue.d.ts +17 -0
  47. package/dist/types/src/components/UiDropdown/UiDropdownItem.vue.d.ts +9 -4
  48. package/dist/types/src/components/UiDropdown/UiDropdownTrigger.vue.d.ts +21 -5
  49. package/dist/types/src/components/UiDropdown/index.d.ts +1 -0
  50. package/dist/types/src/components/UiEmojiPickerList/UiEmojiPickerList.vue.d.ts +22 -0
  51. package/dist/types/src/components/UiEmptyState/UiEmptyState.vue.d.ts +8 -3
  52. package/dist/types/src/components/UiFieldWrapper/UiFieldWrapper.vue.d.ts +2 -2
  53. package/dist/types/src/components/UiInputCheckbox/CheckboxGlyph.vue.d.ts +17 -0
  54. package/dist/types/src/components/UiInputCheckbox/UiInputCheckbox.vue.d.ts +35 -4
  55. package/dist/types/src/components/UiInputEmoji/UiInputEmoji.vue.d.ts +45 -0
  56. package/dist/types/src/components/UiInputRadio/RadioGlyph.vue.d.ts +19 -0
  57. package/dist/types/src/components/UiInputRadio/UiInputRadio.vue.d.ts +80 -0
  58. package/dist/types/src/components/UiInputRadio/UiInputRadioGroup.vue.d.ts +86 -0
  59. package/dist/types/src/components/UiInputRadio/types.d.ts +19 -0
  60. package/dist/types/src/components/UiInputSelect/UiInputSelect.vue.d.ts +5 -5
  61. package/dist/types/src/components/UiInputTextarea/UiInputTextarea.vue.d.ts +5 -5
  62. package/dist/types/src/components/UiListItem/UiListItem.vue.d.ts +18 -4
  63. package/dist/types/src/components/UiLoader/UiLoader.vue.d.ts +6 -5
  64. package/dist/types/src/components/UiLoader/UiSpinnerIcon.vue.d.ts +3 -0
  65. package/dist/types/src/components/UiLogo/UiLogo.vue.d.ts +9 -3
  66. package/dist/types/src/components/UiMenu/UiMenuContent.vue.d.ts +15 -2
  67. package/dist/types/src/components/UiMenu/UiMenuItem.vue.d.ts +9 -3
  68. package/dist/types/src/components/UiNestedOptions/UiNestedOptions.vue.d.ts +13 -0
  69. package/dist/types/src/components/UiPage/UiPage.vue.d.ts +106 -8
  70. package/dist/types/src/components/UiPagination/UiPagination.vue.d.ts +36 -0
  71. package/dist/types/src/components/UiPagination/index.d.ts +2 -0
  72. package/dist/types/src/components/UiPagination/types.d.ts +4 -0
  73. package/dist/types/src/components/UiPane/UiPane.vue.d.ts +22 -0
  74. package/dist/types/src/components/UiPane/UiPaneContent.vue.d.ts +75 -0
  75. package/dist/types/src/components/UiPane/UiPaneTrigger.vue.d.ts +14 -0
  76. package/dist/types/src/components/UiPane/index.d.ts +5 -0
  77. package/dist/types/src/components/UiProgress/UiProgress.vue.d.ts +1 -1
  78. package/dist/types/src/components/UiRating/UiRating.vue.d.ts +62 -0
  79. package/dist/types/src/components/UiRating/types.d.ts +1 -0
  80. package/dist/types/src/components/UiRoomButton/UiRoomButton.vue.d.ts +5 -3
  81. package/dist/types/src/components/UiRoomCountdown/UiRoomCountdown.vue.d.ts +32 -0
  82. package/dist/types/src/components/UiShell/UiShell.vue.d.ts +3 -0
  83. package/dist/types/src/components/UiSideMenu/UiSideMenu.vue.d.ts +22 -1
  84. package/dist/types/src/components/UiSideMenu/UiSideMenuItemContent.vue.d.ts +2 -2
  85. package/dist/types/src/components/UiSwitch/UiSwitch.vue.d.ts +114 -0
  86. package/dist/types/src/components/UiSwitch/types.d.ts +3 -0
  87. package/dist/types/src/components/UiTable/UiTable.vue.d.ts +13 -4
  88. package/dist/types/src/components/UiTable/UiTableActionsCell.vue.d.ts +49 -0
  89. package/dist/types/src/components/UiTable/UiTableActionsHeaderCell.vue.d.ts +3 -0
  90. package/dist/types/src/components/UiTable/UiTableBody.vue.d.ts +11 -1
  91. package/dist/types/src/components/UiTable/UiTableCell.vue.d.ts +16 -1
  92. package/dist/types/src/components/UiTable/UiTableHeaderCell.vue.d.ts +31 -2
  93. package/dist/types/src/components/UiTable/UiTableRow.vue.d.ts +32 -2
  94. package/dist/types/src/components/UiTable/context.d.ts +3 -0
  95. package/dist/types/src/components/UiTable/index.d.ts +4 -0
  96. package/dist/types/src/components/UiTabs/UiTabs.vue.d.ts +8 -2
  97. package/dist/types/src/components/UiTag/UiTag.types.d.ts +25 -0
  98. package/dist/types/src/components/UiTag/UiTag.vue.d.ts +5 -26
  99. package/dist/types/src/components/UiTag/index.d.ts +2 -1
  100. package/dist/types/src/components/UiTextField/UiTextField.vue.d.ts +10 -5
  101. package/dist/types/src/components/UiTooltip/UiTooltipProvider.vue.d.ts +1 -0
  102. package/dist/types/src/components/UiTooltip/UiTooltipTrigger.vue.d.ts +2 -2
  103. package/dist/types/src/composables/storedThemingApplies.d.ts +17 -0
  104. package/dist/types/src/composables/useButtonStyles.d.ts +1 -0
  105. package/dist/types/src/composables/useChoiceboxSurface.d.ts +11 -0
  106. package/dist/types/src/composables/useContentMode.d.ts +23 -0
  107. package/dist/types/src/composables/useControlModes.d.ts +7 -0
  108. package/dist/types/src/composables/useControlShape.d.ts +24 -0
  109. package/dist/types/src/composables/useFieldFocusEvents.d.ts +12 -0
  110. package/dist/types/src/composables/useIconSize.d.ts +13 -0
  111. package/dist/types/src/composables/usePullGesture.d.ts +42 -0
  112. package/dist/types/src/composables/useThemeAndModes.d.ts +4 -0
  113. package/dist/types/src/constants/sizes.d.ts +1 -1
  114. package/dist/types/src/theming/colorScale.d.ts +165 -0
  115. package/dist/types/src/theming/legacyColorScale.d.ts +27 -0
  116. package/dist/types/src/theming/presetColors.d.ts +11 -0
  117. package/dist/types/src/theming/primitiveTokens.d.ts +2 -0
  118. package/dist/types/src/utils/effectiveOpacity.d.ts +2 -0
  119. package/dist/types/src/utils/numbers.d.ts +1 -2
  120. package/dist/types/src/utils/tokenColor.d.ts +2 -0
  121. package/dist/ui-vue.css +2 -1
  122. package/dist/utils.mjs +165 -194
  123. package/index.d.ts +22 -0
  124. package/index.js +44 -0
  125. package/package.json +28 -20
  126. package/src/components/Toast/LayoutToasts.vue +19 -11
  127. package/src/components/Toast/ToastMessage.vue +130 -73
  128. package/src/components/Toast/toastDSV2.ts +238 -67
  129. package/src/components/UiActionBar/UiActionBar.vue +15 -5
  130. package/src/components/UiActionBar/UiActionBarItem.vue +65 -38
  131. package/src/components/UiActionBar/types.ts +16 -1
  132. package/src/components/UiAvatar/UiAvatar.vue +9 -3
  133. package/src/components/UiAvatarList/UiAvatarList.vue +51 -20
  134. package/src/components/UiBadge/UiBadge.vue +1 -1
  135. package/src/components/UiBanner/UiBanner.vue +77 -27
  136. package/src/components/UiBreadcrumb/UiBreadcrumb.vue +1 -1
  137. package/src/components/UiButton/UiButton.vue +96 -29
  138. package/src/components/UiButtonGroup/UiButtonGroup.vue +22 -16
  139. package/src/components/UiButtonGroup/UiButtonGroupItem.vue +44 -14
  140. package/src/components/UiButtonGroup/types.ts +20 -1
  141. package/src/components/UiCard/UiCard.vue +20 -23
  142. package/src/components/UiCarousel/UiCarousel.vue +2 -2
  143. package/src/components/UiChoice/UiChoice.vue +187 -0
  144. package/src/components/UiChoice/index.ts +2 -0
  145. package/src/components/UiChoice/types.ts +11 -0
  146. package/src/components/UiColorField/UiColorField.vue +2 -2
  147. package/src/components/UiColorPicker/UiColorPicker.vue +16 -13
  148. package/src/components/UiCombobox/UiCombobox.types.ts +52 -0
  149. package/src/components/UiCombobox/UiCombobox.vue +296 -0
  150. package/src/components/UiCombobox/index.ts +2 -0
  151. package/src/components/UiDataTable/UiDataTable.types.ts +47 -0
  152. package/src/components/UiDataTable/UiDataTable.vue +422 -0
  153. package/src/components/UiDataTable/index.ts +12 -0
  154. package/src/components/UiDialog/UiDialogClose.vue +1 -1
  155. package/src/components/UiDialog/UiDialogContent.vue +22 -7
  156. package/src/components/UiDrawer/UiDrawer.vue +16 -0
  157. package/src/components/UiDrawer/UiDrawerContent.vue +42 -0
  158. package/src/components/UiDrawer/UiDrawerTrigger.vue +17 -0
  159. package/src/components/UiDropdown/DropdownItemCheckbox.vue +10 -0
  160. package/src/components/UiDropdown/UiDropdownContent.vue +32 -21
  161. package/src/components/UiDropdown/UiDropdownGroup.vue +23 -0
  162. package/src/components/UiDropdown/UiDropdownItem.vue +45 -18
  163. package/src/components/UiDropdown/UiDropdownSeparator.vue +1 -1
  164. package/src/components/UiDropdown/UiDropdownTrigger.vue +139 -45
  165. package/src/components/UiDropdown/index.ts +1 -0
  166. package/src/components/UiEmojiPickerList/UiEmojiPickerList.vue +122 -0
  167. package/src/components/UiEmptyState/UiEmptyState.vue +16 -4
  168. package/src/components/UiFieldWrapper/UiFieldWrapper.vue +10 -4
  169. package/src/components/UiHorizontalSeparator/UiHorizontalSeparator.vue +2 -2
  170. package/src/components/UiInputCheckbox/CheckboxGlyph.vue +78 -0
  171. package/src/components/UiInputCheckbox/UiInputCheckbox.vue +213 -177
  172. package/src/components/UiInputEmoji/UiInputEmoji.vue +96 -0
  173. package/src/components/UiInputRadio/RadioGlyph.vue +45 -0
  174. package/src/components/UiInputRadio/UiInputRadio.vue +382 -0
  175. package/src/components/UiInputRadio/UiInputRadioGroup.vue +166 -0
  176. package/src/components/UiInputRadio/types.ts +24 -0
  177. package/src/components/UiInputSelect/UiInputSelect.vue +9 -7
  178. package/src/components/UiInputTextarea/UiInputTextarea.vue +20 -35
  179. package/src/components/UiLabel/UiLabel.vue +1 -1
  180. package/src/components/UiListItem/UiListItem.vue +55 -9
  181. package/src/components/UiLoader/UiLoader.vue +11 -29
  182. package/src/components/UiLoader/UiSpinnerIcon.vue +21 -0
  183. package/src/components/UiLogo/UiLogo.vue +41 -7
  184. package/src/components/UiMenu/UiMenuContent.vue +24 -3
  185. package/src/components/UiMenu/UiMenuGroup.vue +1 -1
  186. package/src/components/UiMenu/UiMenuItem.vue +14 -3
  187. package/src/components/UiMenu/UiMenuSubContent.vue +1 -1
  188. package/src/components/UiMenu/UiMenuSubTrigger.vue +2 -2
  189. package/src/components/UiNestedOptions/UiNestedOptions.vue +6 -0
  190. package/src/components/UiPage/UiPage.vue +273 -47
  191. package/src/components/UiPageHeader/UiPageHeader.vue +29 -9
  192. package/src/components/UiPagination/UiPagination.vue +99 -0
  193. package/src/components/UiPagination/index.ts +2 -0
  194. package/src/components/UiPagination/types.ts +28 -0
  195. package/src/components/UiPane/UiPane.vue +20 -0
  196. package/src/components/UiPane/UiPaneContent.vue +232 -0
  197. package/src/components/UiPane/UiPaneTrigger.vue +14 -0
  198. package/src/components/UiPane/index.ts +12 -0
  199. package/src/components/UiPopover/UiPopoverContent.vue +21 -1
  200. package/src/components/UiProgress/UiProgress.vue +2 -2
  201. package/src/components/UiRating/UiRating.vue +258 -0
  202. package/src/components/UiRating/types.ts +1 -0
  203. package/src/components/UiRoomButton/UiRoomButton.vue +14 -45
  204. package/src/components/UiRoomCountdown/UiRoomCountdown.vue +376 -0
  205. package/src/components/UiShell/UiShell.vue +10 -4
  206. package/src/components/UiSideMenu/UiSideMenu.vue +158 -18
  207. package/src/components/UiSideMenu/UiSideMenuItemContent.vue +22 -18
  208. package/src/components/UiStepper/UiStepper.vue +3 -16
  209. package/src/components/UiStepper/UiStepperDescription.vue +1 -13
  210. package/src/components/UiStepper/UiStepperIndicator.vue +17 -57
  211. package/src/components/UiStepper/UiStepperItem.vue +1 -8
  212. package/src/components/UiStepper/UiStepperSeparator.vue +5 -16
  213. package/src/components/UiStepper/UiStepperTitle.vue +1 -10
  214. package/src/components/UiSwitch/UiSwitch.vue +375 -0
  215. package/src/components/UiSwitch/types.ts +5 -0
  216. package/src/components/UiTable/UiTable.vue +98 -8
  217. package/src/components/UiTable/UiTableActionsCell.vue +135 -0
  218. package/src/components/UiTable/UiTableActionsHeaderCell.vue +19 -0
  219. package/src/components/UiTable/UiTableBody.vue +16 -1
  220. package/src/components/UiTable/UiTableCell.vue +33 -16
  221. package/src/components/UiTable/UiTableHeader.vue +6 -5
  222. package/src/components/UiTable/UiTableHeaderCell.vue +61 -9
  223. package/src/components/UiTable/UiTableRow.vue +46 -10
  224. package/src/components/UiTable/context.ts +5 -0
  225. package/src/components/UiTable/index.ts +4 -0
  226. package/src/components/UiTabs/UiTabs.vue +61 -63
  227. package/src/components/UiTag/UiTag.types.ts +28 -0
  228. package/src/components/UiTag/UiTag.vue +24 -42
  229. package/src/components/UiTag/index.ts +2 -0
  230. package/src/components/UiTextField/UiTextField.vue +27 -47
  231. package/src/components/UiTimeline/README.md +6 -6
  232. package/src/components/UiTimeline/UiTimelineItem.vue +3 -3
  233. package/src/components/UiTooltip/UiTooltipContent.vue +1 -1
  234. package/src/components/UiTooltip/UiTooltipProvider.vue +3 -0
  235. package/src/components/UiTooltip/UiTooltipTrigger.vue +16 -1
  236. package/src/composables/storedThemingApplies.ts +19 -0
  237. package/src/composables/useButtonStyles.ts +9 -13
  238. package/src/composables/useChoiceboxSurface.ts +36 -0
  239. package/src/composables/useContentMode.ts +66 -0
  240. package/src/composables/useControlModes.ts +11 -0
  241. package/src/composables/useControlShape.ts +34 -0
  242. package/src/composables/useFieldFocusEvents.ts +30 -0
  243. package/src/composables/useIconSize.ts +43 -0
  244. package/src/composables/usePullGesture.ts +142 -0
  245. package/src/composables/useThemeAndModes.ts +28 -1
  246. package/src/constants/sizes.ts +1 -1
  247. package/src/css/body.css +16 -1
  248. package/src/css/fonts.css +39 -5
  249. package/src/global.d.ts +44 -0
  250. package/src/theming/colorScale.ts +173 -0
  251. package/src/theming/legacyColorScale.ts +58 -0
  252. package/src/theming/presetColors.ts +33 -0
  253. package/src/theming/primitiveTokens.ts +71 -0
  254. package/src/utils/effectiveOpacity.ts +8 -0
  255. package/src/utils/i18n.ts +6 -0
  256. package/src/utils/numbers.ts +1 -1
  257. package/src/utils/responsive.d.ts +14 -0
  258. package/src/utils/tokenColor.ts +9 -0
  259. package/dist/UiTimelineItem.vue_vue_type_style_index_0_lang-DJFdCn2R.mjs +0 -5456
  260. package/dist/a11y-BhF_nl7L.mjs +0 -159
  261. package/dist/i18n-Cktw9hIu.mjs +0 -49
  262. package/dist/toastDSV2-wMh-UMzW.mjs +0 -74
  263. package/dist/types/src/components/UiAvatar/index.d.ts +0 -1
  264. package/dist/types/src/components/UiAvatarList/index.d.ts +0 -1
  265. package/dist/types/src/components/UiBadge/index.d.ts +0 -1
  266. package/dist/types/src/components/UiBanner/index.d.ts +0 -2
  267. package/dist/types/src/components/UiButtonGroup/index.d.ts +0 -3
  268. package/dist/types/src/components/UiCarousel/index.d.ts +0 -2
  269. package/dist/types/src/components/UiColorField/index.d.ts +0 -2
  270. package/dist/types/src/components/UiDialog/MarketplaceHeaderExample.vue.d.ts +0 -28
  271. package/dist/types/src/components/UiDialog/index.d.ts +0 -7
  272. package/dist/types/src/components/UiFieldWrapper/index.d.ts +0 -1
  273. package/dist/types/src/components/UiInputCheckbox/index.d.ts +0 -2
  274. package/dist/types/src/components/UiInputSelect/index.d.ts +0 -2
  275. package/dist/types/src/components/UiInputTextarea/index.d.ts +0 -2
  276. package/dist/types/src/components/UiMenu/index.d.ts +0 -10
  277. package/dist/types/src/components/UiProgress/index.d.ts +0 -2
  278. package/dist/types/src/components/UiTabs/index.d.ts +0 -2
  279. package/dist/types/src/components/UiTimeline/index.d.ts +0 -2
  280. package/dist/types/src/components/UiTooltip/index.d.ts +0 -4
  281. package/dist/types/src/mixins/DynamicAction.d.ts +0 -30
  282. package/dist/useThemeAndModes-BzYwSOEv.mjs +0 -108
  283. package/src/components/UiAvatar/index.js +0 -1
  284. package/src/components/UiAvatarList/index.js +0 -1
  285. package/src/components/UiBadge/index.ts +0 -2
  286. package/src/components/UiBanner/index.ts +0 -2
  287. package/src/components/UiButtonGroup/index.ts +0 -3
  288. package/src/components/UiCarousel/index.ts +0 -2
  289. package/src/components/UiColorField/index.ts +0 -2
  290. package/src/components/UiDialog/MarketplaceHeaderExample.vue +0 -217
  291. package/src/components/UiDialog/index.ts +0 -18
  292. package/src/components/UiFieldWrapper/index.ts +0 -1
  293. package/src/components/UiInputCheckbox/index.ts +0 -2
  294. package/src/components/UiInputSelect/index.ts +0 -2
  295. package/src/components/UiInputTextarea/index.ts +0 -2
  296. package/src/components/UiMenu/index.ts +0 -10
  297. package/src/components/UiProgress/index.ts +0 -2
  298. package/src/components/UiTabs/index.ts +0 -5
  299. package/src/components/UiTag/index.js +0 -1
  300. package/src/components/UiTimeline/index.ts +0 -2
  301. package/src/components/UiTooltip/index.js +0 -4
  302. package/src/mixins/DynamicAction.js +0 -61
@@ -1,6 +1,6 @@
1
1
  <!-- UiTabs.vue - Tabs Component -->
2
2
  <script setup lang="ts">
3
- import { computed, ref, watch, nextTick, onMounted, onBeforeUnmount, type Slot, type ComponentPublicInstance } from 'vue'
3
+ import { computed, ref, watch, nextTick, onMounted, onBeforeUnmount, type ComponentPublicInstance } from 'vue'
4
4
  import { useResizeObserver, useDebounceFn } from '@vueuse/core'
5
5
 
6
6
  export interface Tab {
@@ -12,6 +12,8 @@ export interface Tab {
12
12
  icon?: string
13
13
  /** Whether the tab is disabled */
14
14
  disabled?: boolean
15
+ /** Optional data-testid rendered on the tab button */
16
+ testId?: string
15
17
  }
16
18
 
17
19
  export interface UiTabsProps {
@@ -21,26 +23,27 @@ export interface UiTabsProps {
21
23
  modelValue: string
22
24
  /** Size of the tabs */
23
25
  size?: 'sm' | 'md'
26
+ /** Horizontal alignment of the tabs inside the component */
27
+ align?: 'start' | 'center'
24
28
  }
25
29
 
26
30
  const props = withDefaults(defineProps<UiTabsProps>(), {
27
31
  size: 'md',
32
+ align: 'start',
28
33
  })
29
34
 
30
35
  const emit = defineEmits<{
31
36
  'update:modelValue': [value: string]
32
37
  }>()
33
38
 
34
- const slots = defineSlots<{
35
- badge?(): Slot
39
+ defineSlots<{
40
+ badge?(props: { tab: Tab }): unknown
36
41
  }>()
37
42
 
38
- const hasBadgeSlot = computed(() => !!slots.badge)
39
-
40
43
  const sizeClasses = computed(() => {
41
44
  return {
42
45
  container: 'gap-4',
43
- tab: props.size === 'sm' ? 'pb-4' : 'pb-6',
46
+ tab: props.size === 'sm' ? 'pb-4' : 'pb-5',
44
47
  text: props.size === 'sm' ? 'text-action-button-sm' : 'text-action-button-md',
45
48
  }
46
49
  })
@@ -122,17 +125,12 @@ function handleKeydown (event: KeyboardEvent, currentValue: string) {
122
125
  }
123
126
 
124
127
  function updateIndicatorPosition () {
125
- if (!tabsContainer.value) return
126
-
127
128
  const activeButton = tabRefs.value.get(props.modelValue)
128
129
  if (!activeButton) return
129
130
 
130
- const containerRect = tabsContainer.value.getBoundingClientRect()
131
- const buttonRect = activeButton.getBoundingClientRect()
132
-
133
131
  indicatorStyle.value = {
134
- transform: `translateX(${buttonRect.left - containerRect.left}px)`,
135
- width: `${buttonRect.width}px`,
132
+ transform: `translateX(${activeButton.offsetLeft}px)`,
133
+ width: `${activeButton.offsetWidth}px`,
136
134
  }
137
135
  }
138
136
 
@@ -150,7 +148,7 @@ onMounted(async () => {
150
148
  updateIndicatorPosition()
151
149
  })
152
150
 
153
- useResizeObserver(tabsContainer, debouncedUpdatePosition)
151
+ useResizeObserver(() => [tabsContainer.value, ...tabRefs.value.values()], debouncedUpdatePosition)
154
152
 
155
153
  onBeforeUnmount(() => {
156
154
  tabRefs.value.clear()
@@ -158,61 +156,61 @@ onBeforeUnmount(() => {
158
156
  </script>
159
157
 
160
158
  <template>
161
- <div class="ui-tabs border-b border-borders-neutral-light relative">
162
- <div
163
- ref="tabsContainer"
164
- role="tablist"
165
- class="flex items-center"
166
- :class="sizeClasses.container"
167
- >
168
- <button
169
- v-for="tab in tabs"
170
- :key="tab.value"
171
- :ref="(el) => setTabRef(el, tab.value)"
172
- type="button"
173
- role="tab"
174
- :aria-selected="isActive(tab.value)"
175
- :aria-disabled="tab.disabled"
176
- :tabindex="isActive(tab.value) ? 0 : -1"
177
- class="relative outline-none flex items-center gap-2 cursor-pointer font-semibold transition-colors duration-150"
178
- :class="[
179
- sizeClasses.tab,
180
- sizeClasses.text,
181
- {
182
- 'text-actions-primary-idle': isActive(tab.value),
183
- 'text-actions-neutral-idle-alpha-strong hover:text-actions-neutral-idle': !isActive(tab.value) && !tab.disabled,
184
- 'text-actions-neutral-idle-alpha-strong cursor-not-allowed opacity-50': tab.disabled,
185
- },
186
- ]"
187
- :disabled="tab.disabled"
188
- @click="selectTab(tab.value)"
189
- @keydown="handleKeydown($event, tab.value)"
159
+ <div class="ui-tabs border-b border-divider">
160
+ <!-- The 1px bottom overlap lays the indicator over the border -->
161
+ <div class="relative -mb-px overflow-x-auto [scrollbar-width:none]">
162
+ <div
163
+ ref="tabsContainer"
164
+ role="tablist"
165
+ class="flex items-center"
166
+ :class="[sizeClasses.container, { 'justify-center-safe': align === 'center' }]"
190
167
  >
191
- <span
192
- v-if="tab.icon"
193
- :class="tab.icon"
194
- class="w-4 h-4"
195
- />
196
- <span>{{ tab.label }}</span>
197
- <div
198
- v-if="hasBadgeSlot"
199
- class="w-4 h-4"
168
+ <button
169
+ v-for="tab in tabs"
170
+ :key="tab.value"
171
+ :ref="(el) => setTabRef(el, tab.value)"
172
+ type="button"
173
+ role="tab"
174
+ :aria-selected="isActive(tab.value)"
175
+ :aria-disabled="tab.disabled"
176
+ :data-testid="tab.testId"
177
+ :tabindex="isActive(tab.value) ? 0 : -1"
178
+ class="relative outline-none flex shrink-0 items-center gap-2 whitespace-nowrap cursor-pointer font-semibold transition-colors duration-150"
179
+ :class="[
180
+ sizeClasses.tab,
181
+ sizeClasses.text,
182
+ {
183
+ 'text-actions-primary-idle': isActive(tab.value),
184
+ 'text-actions-neutral-idle-alpha-strong hover:text-actions-neutral-idle': !isActive(tab.value) && !tab.disabled,
185
+ 'text-actions-neutral-idle-alpha-strong cursor-not-allowed opacity-50': tab.disabled,
186
+ },
187
+ ]"
188
+ :disabled="tab.disabled"
189
+ @click="selectTab(tab.value)"
190
+ @keydown="handleKeydown($event, tab.value)"
200
191
  >
192
+ <span
193
+ v-if="tab.icon"
194
+ :class="tab.icon"
195
+ class="size-5"
196
+ />
197
+ <span>{{ tab.label }}</span>
201
198
  <slot
202
199
  name="badge"
203
200
  :tab="tab"
204
201
  />
205
- </div>
206
- </button>
202
+ </button>
203
+ </div>
204
+
205
+ <!-- Sliding indicator -->
206
+ <div
207
+ data-testid="ui-tabs-indicator"
208
+ class="absolute bottom-0 left-0 h-0.5 bg-actions-primary-idle transition-[transform,width] duration-[250ms] ease-out will-change-[transform,width]"
209
+ :style="{
210
+ transform: indicatorStyle.transform,
211
+ width: indicatorStyle.width,
212
+ }"
213
+ />
207
214
  </div>
208
-
209
- <!-- Sliding indicator -->
210
- <div
211
- class="absolute -bottom-px left-0 h-0.5 bg-actions-primary-idle transition-[transform,width] duration-[250ms] ease-out will-change-[transform,width]"
212
- :style="{
213
- transform: indicatorStyle.transform,
214
- width: indicatorStyle.width,
215
- }"
216
- />
217
215
  </div>
218
216
  </template>
@@ -0,0 +1,28 @@
1
+ export type UiTagSize = 'xxs' | 'xs' | 'sm' | 'md'
2
+
3
+ export type UiTagColor = 'primary' | 'neutral' | 'danger' | 'warning' | 'success' | 'neutral-invert'
4
+
5
+ export type UiTagVariant = 'light' | 'strong'
6
+
7
+ export interface UiTagProps {
8
+ /**
9
+ * Size of the tag
10
+ */
11
+ size?: UiTagSize
12
+ /**
13
+ * Color variant of the tag
14
+ */
15
+ color?: UiTagColor
16
+ /**
17
+ * Variant of the tag
18
+ */
19
+ variant?: UiTagVariant
20
+ /**
21
+ * Label text for the tag
22
+ */
23
+ label?: string
24
+ /**
25
+ * Whether to show hover effects
26
+ */
27
+ withHoverEffect?: boolean
28
+ }
@@ -16,7 +16,10 @@
16
16
  </span>
17
17
 
18
18
  <!-- Label content -->
19
- <span class="ui-tag-label">
19
+ <span
20
+ v-if="$slots.default || label"
21
+ class="ui-tag-label"
22
+ >
20
23
  <slot>{{ label }}</slot>
21
24
  </span>
22
25
  </span>
@@ -25,30 +28,9 @@
25
28
  <script setup lang="ts">
26
29
  import { computed } from 'vue'
27
30
 
28
- interface Props {
29
- /**
30
- * Size of the tag
31
- */
32
- size?: 'xxs' | 'xs' | 'sm' | 'md'
33
- /**
34
- * Color variant of the tag
35
- */
36
- color?: 'primary' | 'neutral' | 'danger' | 'warning' | 'success' | 'neutral-invert'
37
- /**
38
- * Variant of the tag
39
- */
40
- variant?: 'light' | 'strong'
41
- /**
42
- * Label text for the tag
43
- */
44
- label?: string
45
- /**
46
- * Whether to show hover effects
47
- */
48
- withHoverEffect?: boolean
49
- }
31
+ import type { UiTagProps } from './UiTag.types'
50
32
 
51
- const props = withDefaults(defineProps<Props>(), {
33
+ const props = withDefaults(defineProps<UiTagProps>(), {
52
34
  size: 'md',
53
35
  color: 'neutral',
54
36
  variant: 'light',
@@ -61,7 +43,7 @@ const tagClasses = computed(() => {
61
43
  'ui-tag',
62
44
  'inline-flex',
63
45
  'items-center',
64
- 'rounded-3xl',
46
+ 'rounded-full',
65
47
  'transition-colors',
66
48
  'duration-150',
67
49
  'ease-in-out',
@@ -71,36 +53,36 @@ const tagClasses = computed(() => {
71
53
  // Size classes
72
54
  const sizeClasses = {
73
55
  xxs: ['px-1.5', 'gap-1', 'text-content-badges-bold-md', 'h-4'],
74
- xs: ['px-1.5', 'py-1', 'gap-1', 'text-content-badges-bold-md', 'h-6'],
75
- sm: ['px-2', 'py-1', 'gap-1', 'text-content-text-md-bold', 'h-8'],
76
- md: ['px-3', 'py-1', 'gap-2', 'text-content-text-md-bold', 'h-10'],
56
+ xs: ['px-2', 'py-1', 'gap-1', 'text-content-badges-bold-md', 'h-6'],
57
+ sm: ['px-3', 'py-1', 'gap-1', 'text-content-text-md-bold', 'h-8'],
58
+ md: ['px-4', 'py-1', 'gap-2', 'text-content-text-md-bold', 'h-10'],
77
59
  }
78
60
 
79
61
  // Color and variant classes
80
62
  const colorVariantClasses = {
81
63
  primary: {
82
- light: ['bg-actions-primary-active-overlay', 'text-actions-primary-idle'],
83
- strong: ['bg-actions-primary-idle-alpha-strong', 'text-actions-neutral-invert-idle'],
64
+ light: ['bg-actions-primary-active-overlay', 'text-text-primary-title'],
65
+ strong: ['bg-actions-primary-idle-alpha-strong', 'text-text-neutral-invert-base'],
84
66
  },
85
67
  neutral: {
86
- light: ['bg-actions-neutral-active-overlay', 'text-actions-neutral-idle'],
87
- strong: ['bg-actions-neutral-idle-alpha-strong', 'text-actions-neutral-invert-idle'],
68
+ light: ['bg-actions-neutral-active-overlay', 'text-text-neutral-base'],
69
+ strong: ['bg-actions-neutral-idle-alpha-strong', 'text-text-neutral-invert-base'],
88
70
  },
89
71
  danger: {
90
- light: ['bg-actions-danger-active-overlay', 'text-actions-danger-idle'],
91
- strong: ['bg-actions-danger-idle-alpha-strong', 'text-actions-neutral-invert-idle'],
72
+ light: ['bg-actions-danger-active-overlay', 'text-text-danger-base'],
73
+ strong: ['bg-actions-danger-idle-alpha-strong', 'text-text-neutral-invert-base'],
92
74
  },
93
75
  warning: {
94
- light: ['bg-actions-warning-active-overlay', 'text-actions-warning-idle'],
95
- strong: ['bg-actions-warning-idle-alpha-strong', 'text-actions-neutral-invert-idle'],
76
+ light: ['bg-actions-warning-active-overlay', 'text-text-warning-base'],
77
+ strong: ['bg-actions-warning-idle-alpha-strong', 'text-text-neutral-invert-base'],
96
78
  },
97
79
  success: {
98
- light: ['bg-actions-success-active-overlay', 'text-actions-success-idle'],
99
- strong: ['bg-actions-success-idle-alpha-strong', 'text-actions-neutral-invert-idle'],
80
+ light: ['bg-actions-success-active-overlay', 'text-text-success-base'],
81
+ strong: ['bg-actions-success-idle-alpha-strong', 'text-text-neutral-invert-base'],
100
82
  },
101
83
  'neutral-invert': {
102
- light: ['bg-actions-neutral-invert-active-overlay', 'text-actions-neutral-invert-idle'],
103
- strong: ['bg-actions-neutral-invert-idle-alpha-strong', 'text-actions-neutral-idle'],
84
+ light: ['bg-actions-neutral-invert-active-overlay', 'text-text-neutral-invert-base'],
85
+ strong: ['bg-actions-neutral-invert-idle-alpha-strong', 'text-text-neutral-base'],
104
86
  },
105
87
  }
106
88
 
@@ -129,7 +111,7 @@ const iconClasses = computed(() => {
129
111
 
130
112
  /* Focus ring */
131
113
  .ui-tag:focus-visible {
132
- @apply ring-2 ring-inset ring-focus-ring;
114
+ @apply focus-ring;
133
115
  }
134
116
 
135
117
  /* Hover states - only apply when withHoverEffect is true */
@@ -182,6 +164,6 @@ const iconClasses = computed(() => {
182
164
  }
183
165
 
184
166
  .ui-tag-label {
185
- @apply flex-1;
167
+ @apply flex-1 truncate;
186
168
  }
187
169
  </style>
@@ -0,0 +1,2 @@
1
+ export { default } from './UiTag.vue'
2
+ export type { UiTagColor, UiTagProps, UiTagSize, UiTagVariant } from './UiTag.types'
@@ -1,6 +1,9 @@
1
1
  <script setup lang="ts">
2
2
  import { computed, nextTick, ref, useSlots } from 'vue'
3
3
  import UiFieldWrapper from '../UiFieldWrapper/UiFieldWrapper.vue'
4
+ import { useIconSize } from '../../composables/useIconSize'
5
+ import { useControlShape } from '../../composables/useControlShape'
6
+ import { useFieldFocusEvents } from '../../composables/useFieldFocusEvents'
4
7
  import type { TextFieldSize } from './types'
5
8
 
6
9
  interface UiTextFieldProps {
@@ -8,6 +11,10 @@ interface UiTextFieldProps {
8
11
  modelValue?: string
9
12
  placeholder?: string
10
13
  disabled?: boolean
14
+ /**
15
+ * The value can be selected and copied but not edited
16
+ */
17
+ readonly?: boolean
11
18
  loading?: boolean
12
19
  error?: boolean
13
20
  label?: string
@@ -27,6 +34,7 @@ interface UiTextFieldProps {
27
34
  const props = withDefaults(defineProps<UiTextFieldProps>(), {
28
35
  size: 'md',
29
36
  disabled: false,
37
+ readonly: false,
30
38
  loading: false,
31
39
  error: false,
32
40
  required: false,
@@ -48,20 +56,17 @@ const emit = defineEmits<{
48
56
 
49
57
  const slots = useSlots()
50
58
  const textFieldRef = ref<HTMLInputElement | null>(null)
51
- const isFocused = ref(false)
59
+ const { isFocused, handleFocus, handleBlur, handleKeydown, handleKeyup } = useFieldFocusEvents(emit)
60
+
61
+ const iconSizeClass = useIconSize(() => props.size)
62
+ const shape = useControlShape('field', () => props.size)
52
63
 
53
64
  const hasLeftIcon = computed(() => !!slots.icon)
54
65
  const hasRightAction = computed(() => !!slots['right-action'])
55
- const showClearButton = computed(() => props.clearable && !!props.modelValue && !props.disabled && !props.loading)
66
+ const showClearButton = computed(() => props.clearable && !!props.modelValue && !props.disabled && !props.readonly && !props.loading)
56
67
 
57
68
  const textFieldClasses = computed(() => {
58
- const classes = ['ui-text-field-field']
59
-
60
- // Size classes
61
- if (props.size === 'sm') classes.push('h-8 text-content-text-md-regular')
62
- if (props.size === 'md') classes.push('h-10 text-content-text-md-regular')
63
- if (props.size === 'lg') classes.push('h-12 text-content-text-md-regular')
64
- if (props.size === 'xl') classes.push('h-16 text-content-text-md-regular')
69
+ const classes = ['ui-text-field-field', shape.value.radius, shape.value.height, 'text-content-text-md-regular']
65
70
 
66
71
  // State classes
67
72
  if (props.error) {
@@ -87,24 +92,6 @@ function handleClear () {
87
92
  textFieldRef.value?.focus()
88
93
  }
89
94
 
90
- function handleFocus (event: FocusEvent) {
91
- isFocused.value = true
92
- emit('focus', event)
93
- }
94
-
95
- function handleBlur (event: FocusEvent) {
96
- isFocused.value = false
97
- emit('blur', event)
98
- }
99
-
100
- function handleKeydown (event: KeyboardEvent) {
101
- emit('keydown', event)
102
- }
103
-
104
- function handleKeyup (event: KeyboardEvent) {
105
- emit('keyup', event)
106
- }
107
-
108
95
  defineExpose({
109
96
  focus: () => textFieldRef.value?.focus(),
110
97
  blur: () => textFieldRef.value?.blur(),
@@ -147,11 +134,7 @@ defineExpose({
147
134
  <div
148
135
  v-if="hasLeftIcon"
149
136
  class="ui-text-field-icon text-text-neutral-base"
150
- :class="{
151
- 'size-3': size === 'sm',
152
- 'size-4': size === 'md' || size === 'lg',
153
- 'size-5': size === 'xl',
154
- }"
137
+ :class="iconSizeClass"
155
138
  >
156
139
  <slot name="icon" />
157
140
  </div>
@@ -165,11 +148,12 @@ defineExpose({
165
148
  :value="modelValue"
166
149
  :placeholder="placeholder"
167
150
  :disabled="disabled || loading"
151
+ :readonly="readonly"
168
152
  :autocomplete="autocomplete"
169
153
  :aria-label="ariaLabel"
170
154
  :aria-invalid="error || undefined"
171
155
  :aria-describedby="ariaDescribedby || ((helperMessage || errorMessage) ? `${fieldId}-message` : undefined)"
172
- class="ui-text-field-element text-text-neutral-base placeholder:text-text-neutral-tertiary"
156
+ class="ui-text-field-element text-text-neutral-base placeholder:text-control-placeholder"
173
157
  @input="handleInput"
174
158
  @focus="handleFocus"
175
159
  @blur="handleBlur"
@@ -195,14 +179,10 @@ defineExpose({
195
179
  v-else-if="showClearButton"
196
180
  type="button"
197
181
  class="ui-text-field-clear text-text-neutral-base hover:text-text-neutral-secondary"
198
- :class="{
199
- 'size-3': size === 'sm',
200
- 'size-4': size === 'md' || size === 'lg',
201
- 'size-5': size === 'xl',
202
- }"
182
+ :class="iconSizeClass"
203
183
  @click="handleClear"
204
184
  >
205
- <div class="i-ls-x size-full" />
185
+ <div class="i-ph-x size-full" />
206
186
  </button>
207
187
  </div>
208
188
 
@@ -222,12 +202,12 @@ defineExpose({
222
202
  @reference '@livestorm/ui-tokens/output/supernova/index.css';
223
203
 
224
204
  .ui-text-field-field {
225
- @apply relative flex items-center gap-1.5 w-full rounded-lg border transition-all;
205
+ @apply relative flex items-center gap-1.5 w-full border transition-all;
226
206
  @apply pl-3 pr-0;
227
207
  }
228
208
 
229
209
  .ui-text-field-field--default {
230
- @apply bg-actions-neutral-idle-alpha-light border-borders-neutral-strong;
210
+ @apply bg-control-field-bg border-control-field-border;
231
211
 
232
212
  &:not(.ui-text-field-field--disabled) {
233
213
  &:hover .ui-text-field-overlay {
@@ -235,7 +215,7 @@ defineExpose({
235
215
  }
236
216
 
237
217
  &.ui-text-field-field--focused {
238
- @apply border-actions-primary-idle-alpha-strong ring-1 ring-inset ring-focus-ring;
218
+ @apply bg-control-field-bg-focus focus-ring;
239
219
 
240
220
  .ui-text-field-overlay {
241
221
  background: transparent;
@@ -245,7 +225,7 @@ defineExpose({
245
225
  }
246
226
 
247
227
  .ui-text-field-field--error {
248
- @apply bg-actions-danger-idle-alpha-light border-borders-danger-strong;
228
+ @apply bg-actions-danger-idle-alpha-light border-control-error-border;
249
229
 
250
230
  &:not(.ui-text-field-field--disabled) {
251
231
  &:hover .ui-text-field-overlay {
@@ -253,7 +233,7 @@ defineExpose({
253
233
  }
254
234
 
255
235
  &.ui-text-field-field--focused {
256
- @apply border-borders-danger-strong ring-1 ring-inset ring-borders-danger-strong;
236
+ @apply focus-ring;
257
237
 
258
238
  .ui-text-field-overlay {
259
239
  background: transparent;
@@ -267,7 +247,7 @@ defineExpose({
267
247
  }
268
248
 
269
249
  .ui-text-field-overlay {
270
- @apply absolute inset-0 rounded-lg pointer-events-none transition-colors;
250
+ @apply absolute -inset-px rounded-[inherit] pointer-events-none transition-colors;
271
251
  z-index: 1;
272
252
  }
273
253
 
@@ -341,7 +321,7 @@ defineExpose({
341
321
  }
342
322
 
343
323
  .ui-text-field-actions {
344
- @apply flex items-center justify-center px-3 h-full rounded-lg;
324
+ @apply flex items-center justify-center px-3 h-full rounded-[inherit];
345
325
  position: relative;
346
326
  z-index: 2;
347
327
  }
@@ -364,7 +344,7 @@ defineExpose({
364
344
  padding: 0;
365
345
 
366
346
  &:focus-visible {
367
- @apply ring-2 ring-borders-neutral-strong rounded;
347
+ @apply focus-ring rounded-row;
368
348
  }
369
349
  }
370
350
  </style>
@@ -45,7 +45,7 @@ A flexible timeline component for displaying chronological events with various v
45
45
  | `variant` | `'default' \| 'primary' \| 'success' \| 'warning' \| 'danger'` | `'default'` | Visual variant of the timeline item |
46
46
  | `showConnector` | `boolean` | `true` | Whether to show the connecting line |
47
47
  | `indicatorSize` | `'sm' \| 'md' \| 'lg'` | `'md'` | Size of the indicator dot |
48
- | `indicatorIcon` | `string` | `undefined` | Custom icon class for the indicator (e.g., `'i-ls-check-circle'`) |
48
+ | `indicatorIcon` | `string` | `undefined` | Custom icon class for the indicator (e.g., `'i-ph-check-circle'`) |
49
49
 
50
50
  ## Examples
51
51
 
@@ -72,13 +72,13 @@ A flexible timeline component for displaying chronological events with various v
72
72
 
73
73
  ```vue
74
74
  <UiTimeline>
75
- <UiTimelineItem variant="primary" indicator-icon="i-ls-user" indicator-size="md">
75
+ <UiTimelineItem variant="primary" indicator-icon="i-ph-user" indicator-size="md">
76
76
  <div>User registered</div>
77
77
  </UiTimelineItem>
78
- <UiTimelineItem variant="success" indicator-icon="i-ls-check-circle" indicator-size="md">
78
+ <UiTimelineItem variant="success" indicator-icon="i-ph-check-circle" indicator-size="md">
79
79
  <div>Email verified</div>
80
80
  </UiTimelineItem>
81
- <UiTimelineItem variant="success" indicator-icon="i-ls-play-fill" indicator-size="md">
81
+ <UiTimelineItem variant="success" indicator-icon="i-ph-play-fill" indicator-size="md">
82
82
  <div>Setup complete</div>
83
83
  </UiTimelineItem>
84
84
  </UiTimeline>
@@ -88,7 +88,7 @@ A flexible timeline component for displaying chronological events with various v
88
88
 
89
89
  ```vue
90
90
  <UiTimeline>
91
- <UiTimelineItem variant="primary" indicator-icon="i-ls-user" indicator-size="md">
91
+ <UiTimelineItem variant="primary" indicator-icon="i-ph-user" indicator-size="md">
92
92
  <div>
93
93
  <div class="flex items-center gap-2 mb-2">
94
94
  <h4 class="text-content-text-md-bold font-semibold">John Doe joined</h4>
@@ -134,7 +134,7 @@ A flexible timeline component for displaying chronological events with various v
134
134
 
135
135
  ```vue
136
136
  <UiTimeline>
137
- <UiTimelineItem variant="success" indicator-icon="i-ls-check-circle" indicator-size="md">
137
+ <UiTimelineItem variant="success" indicator-icon="i-ph-check-circle" indicator-size="md">
138
138
  <div>
139
139
  <div class="flex items-center justify-between mb-2">
140
140
  <h4 class="font-semibold">Payment Successful</h4>
@@ -76,9 +76,9 @@ const connectorClasses = computed(() => {
76
76
 
77
77
  const iconSize = computed(() => {
78
78
  const sizes = {
79
- sm: 'w-1 h-1',
80
- md: 'w-2 h-2',
81
- lg: 'w-3 h-3',
79
+ sm: 'size-2',
80
+ md: 'size-3',
81
+ lg: 'size-4',
82
82
  }
83
83
  return sizes[props.indicatorSize]
84
84
  })
@@ -63,7 +63,7 @@ const maxWidthClass = computed(() => {
63
63
  v-bind="{ ...forwarded, ...$attrs }"
64
64
  :data-colors-semantic="props.colorsSemantic"
65
65
  :class="[
66
- 'ui-tooltip-content 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',
66
+ 'ui-tooltip-content py-1.5 px-3 bg-surface-neutral-invert-bg-alpha text-text-neutral-invert-base text-content-text-md-regular rounded-row text-center z-overlay shadow-shadows-drop-shadow-lg',
67
67
  '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',
68
68
  maxWidthClass
69
69
  ]"
@@ -5,6 +5,9 @@ import { TooltipProvider } from 'reka-ui'
5
5
  withDefaults(defineProps<TooltipProviderProps>(), {
6
6
  delayDuration: 700,
7
7
  skipDelayDuration: 300,
8
+ // A tap is how touch opens a tooltip, and the click that follows it would
9
+ // close it again straight away unless the trigger stops closing on click.
10
+ disableClosingTrigger: true,
8
11
  })
9
12
  </script>
10
13
 
@@ -1,6 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { TooltipTriggerProps } from 'reka-ui'
3
- import { TooltipTrigger, useForwardProps } from 'reka-ui'
3
+ import { TooltipTrigger, injectTooltipRootContext, useForwardProps } from 'reka-ui'
4
4
 
5
5
  const props = defineProps<TooltipTriggerProps>()
6
6
 
@@ -8,11 +8,26 @@ const props = defineProps<TooltipTriggerProps>()
8
8
  // consumed here and never reach TooltipTrigger, so `as-child` would be ignored
9
9
  // and reka would wrap the slot in its own <button>.
10
10
  const forwarded = useForwardProps(props)
11
+
12
+ const rootContext = injectTooltipRootContext()
13
+
14
+ // this is to open the tooltip on touch devices, which can't hover
15
+ // Bound to `pointerup` so a scroll that starts on the trigger does not open it.
16
+ function toggleOnTouch(event: PointerEvent) {
17
+ if (event.pointerType !== 'touch' || rootContext.disabled.value) return
18
+
19
+ if (rootContext.open.value) {
20
+ rootContext.onClose()
21
+ } else {
22
+ rootContext.onOpen()
23
+ }
24
+ }
11
25
  </script>
12
26
 
13
27
  <template>
14
28
  <TooltipTrigger
15
29
  v-bind="{ ...forwarded, ...$attrs }"
30
+ @pointerup="toggleOnTouch"
16
31
  >
17
32
  <slot />
18
33
  </TooltipTrigger>
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Does stored theming output apply?
3
+ *
4
+ * The theme picker (and its playground) is the only writer of deliberate
5
+ * theming choices: the stored modes in `themeAndMode` and the seed token map
6
+ * in `customThemeTokens`. A stored value alone is not a choice signal —
7
+ * `useStorage` persists the light/light defaults for every visitor — so
8
+ * stored theming is consumed only where the picker exists, and every surface
9
+ * ships its own defaults otherwise (the dashboard light/light, the room
10
+ * dark shell over light content).
11
+ *
12
+ * This is the single place that rule lives. `ls-internal-theming` itself
13
+ * gates the picker's visibility; it does not gate any rendering path.
14
+ * When a real user-facing theming choice ships (workspace setting, OS
15
+ * follow), its mechanism replaces this predicate.
16
+ */
17
+ export function storedThemingApplies (): boolean {
18
+ return typeof localStorage !== 'undefined' && localStorage.getItem('ls-internal-theming') === 'true'
19
+ }