@livestorm/ui-vue 3.0.0 → 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 (291) hide show
  1. package/README.md +3 -3
  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 -231
  10. package/dist/i18n-B8QOMuFD.mjs +46 -0
  11. package/dist/index.mjs +4 -91
  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 +19 -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/types.d.ts +2 -0
  21. package/dist/types/src/components/UiAvatar/UiAvatar.vue.d.ts +4 -2
  22. package/dist/types/src/components/UiAvatarList/UiAvatarList.vue.d.ts +3 -2
  23. package/dist/types/src/components/UiBanner/UiBanner.vue.d.ts +13 -1
  24. package/dist/types/src/components/UiButton/UiButton.vue.d.ts +95 -35
  25. package/dist/types/src/components/UiButtonGroup/UiButtonGroup.vue.d.ts +8 -2
  26. package/dist/types/src/components/UiButtonGroup/types.d.ts +4 -0
  27. package/dist/types/src/components/UiChoice/UiChoice.vue.d.ts +71 -0
  28. package/dist/types/src/components/UiChoice/index.d.ts +2 -0
  29. package/dist/types/src/components/UiChoice/types.d.ts +7 -0
  30. package/dist/types/src/components/UiColorField/UiColorField.vue.d.ts +1 -1
  31. package/dist/types/src/components/UiColorPicker/UiColorPicker.vue.d.ts +2 -2
  32. package/dist/types/src/components/UiCombobox/UiCombobox.types.d.ts +47 -0
  33. package/dist/types/src/components/UiCombobox/UiCombobox.vue.d.ts +40 -0
  34. package/dist/types/src/components/UiCombobox/index.d.ts +2 -0
  35. package/dist/types/src/components/UiDataTable/UiDataTable.types.d.ts +46 -0
  36. package/dist/types/src/components/UiDataTable/UiDataTable.vue.d.ts +136 -0
  37. package/dist/types/src/components/UiDataTable/index.d.ts +5 -0
  38. package/dist/types/src/components/UiDrawer/UiDrawer.vue.d.ts +28 -0
  39. package/dist/types/src/components/UiDrawer/UiDrawerContent.vue.d.ts +18 -0
  40. package/dist/types/src/components/UiDrawer/UiDrawerTrigger.vue.d.ts +14 -0
  41. package/dist/types/src/components/UiDropdown/DropdownItemCheckbox.vue.d.ts +3 -0
  42. package/dist/types/src/components/UiDropdown/UiDropdownContent.vue.d.ts +10 -0
  43. package/dist/types/src/components/UiDropdown/UiDropdownGroup.vue.d.ts +17 -0
  44. package/dist/types/src/components/UiDropdown/UiDropdownItem.vue.d.ts +8 -5
  45. package/dist/types/src/components/UiDropdown/UiDropdownTrigger.vue.d.ts +21 -5
  46. package/dist/types/src/components/UiDropdown/index.d.ts +1 -0
  47. package/dist/types/src/components/UiEmojiPickerList/UiEmojiPickerList.vue.d.ts +22 -0
  48. package/dist/types/src/components/UiEmptyState/UiEmptyState.vue.d.ts +8 -3
  49. package/dist/types/src/components/UiFieldWrapper/UiFieldWrapper.vue.d.ts +2 -2
  50. package/dist/types/src/components/UiInputCheckbox/CheckboxGlyph.vue.d.ts +17 -0
  51. package/dist/types/src/components/UiInputCheckbox/UiInputCheckbox.vue.d.ts +35 -4
  52. package/dist/types/src/components/UiInputRadio/RadioGlyph.vue.d.ts +19 -0
  53. package/dist/types/src/components/UiInputRadio/UiInputRadio.vue.d.ts +21 -8
  54. package/dist/types/src/components/UiInputRadio/UiInputRadioGroup.vue.d.ts +6 -1
  55. package/dist/types/src/components/UiInputRadio/types.d.ts +1 -1
  56. package/dist/types/src/components/UiInputSelect/UiInputSelect.vue.d.ts +5 -5
  57. package/dist/types/src/components/UiInputTextarea/UiInputTextarea.vue.d.ts +5 -5
  58. package/dist/types/src/components/UiListItem/UiListItem.vue.d.ts +18 -4
  59. package/dist/types/src/components/UiLoader/UiSpinnerIcon.vue.d.ts +3 -0
  60. package/dist/types/src/components/UiMenu/UiMenuContent.vue.d.ts +15 -2
  61. package/dist/types/src/components/UiMenu/UiMenuItem.vue.d.ts +9 -3
  62. package/dist/types/src/components/UiNestedOptions/UiNestedOptions.vue.d.ts +13 -0
  63. package/dist/types/src/components/UiPage/UiPage.vue.d.ts +79 -15
  64. package/dist/types/src/components/UiPagination/UiPagination.vue.d.ts +36 -0
  65. package/dist/types/src/components/UiPagination/index.d.ts +2 -0
  66. package/dist/types/src/components/UiPagination/types.d.ts +4 -0
  67. package/dist/types/src/components/UiPane/UiPane.vue.d.ts +22 -0
  68. package/dist/types/src/components/UiPane/UiPaneContent.vue.d.ts +75 -0
  69. package/dist/types/src/components/UiPane/UiPaneTrigger.vue.d.ts +14 -0
  70. package/dist/types/src/components/UiPane/index.d.ts +5 -0
  71. package/dist/types/src/components/UiRating/UiRating.vue.d.ts +62 -0
  72. package/dist/types/src/components/UiRating/types.d.ts +1 -0
  73. package/dist/types/src/components/UiRoomButton/UiRoomButton.vue.d.ts +5 -3
  74. package/dist/types/src/components/UiRoomCountdown/UiRoomCountdown.vue.d.ts +32 -0
  75. package/dist/types/src/components/UiShell/UiShell.vue.d.ts +3 -0
  76. package/dist/types/src/components/UiSideMenu/UiSideMenu.vue.d.ts +22 -1
  77. package/dist/types/src/components/UiSideMenu/UiSideMenuItemContent.vue.d.ts +2 -2
  78. package/dist/types/src/components/UiSwitch/UiSwitch.vue.d.ts +10 -5
  79. package/dist/types/src/components/UiTable/UiTable.vue.d.ts +13 -4
  80. package/dist/types/src/components/UiTable/UiTableActionsCell.vue.d.ts +49 -0
  81. package/dist/types/src/components/UiTable/UiTableActionsHeaderCell.vue.d.ts +3 -0
  82. package/dist/types/src/components/UiTable/UiTableBody.vue.d.ts +11 -1
  83. package/dist/types/src/components/UiTable/UiTableCell.vue.d.ts +16 -1
  84. package/dist/types/src/components/UiTable/UiTableHeaderCell.vue.d.ts +31 -2
  85. package/dist/types/src/components/UiTable/UiTableRow.vue.d.ts +32 -2
  86. package/dist/types/src/components/UiTable/context.d.ts +3 -0
  87. package/dist/types/src/components/UiTable/index.d.ts +4 -0
  88. package/dist/types/src/components/UiTabs/UiTabs.vue.d.ts +3 -0
  89. package/dist/types/src/components/UiTag/UiTag.types.d.ts +25 -0
  90. package/dist/types/src/components/UiTag/UiTag.vue.d.ts +5 -26
  91. package/dist/types/src/components/UiTag/index.d.ts +2 -1
  92. package/dist/types/src/components/UiTextField/UiTextField.vue.d.ts +10 -5
  93. package/dist/types/src/components/UiTooltip/UiTooltipProvider.vue.d.ts +1 -0
  94. package/dist/types/src/components/UiTooltip/UiTooltipTrigger.vue.d.ts +2 -2
  95. package/dist/types/src/composables/storedThemingApplies.d.ts +17 -0
  96. package/dist/types/src/composables/useButtonStyles.d.ts +1 -0
  97. package/dist/types/src/composables/useChoiceboxSurface.d.ts +11 -0
  98. package/dist/types/src/composables/useContentMode.d.ts +7 -9
  99. package/dist/types/src/composables/useControlModes.d.ts +7 -0
  100. package/dist/types/src/composables/useControlShape.d.ts +24 -0
  101. package/dist/types/src/composables/useFieldFocusEvents.d.ts +12 -0
  102. package/dist/types/src/composables/useIconSize.d.ts +2 -0
  103. package/dist/types/src/composables/usePullGesture.d.ts +42 -0
  104. package/dist/types/src/composables/useThemeAndModes.d.ts +4 -0
  105. package/dist/types/src/theming/colorScale.d.ts +165 -0
  106. package/dist/types/src/theming/legacyColorScale.d.ts +27 -0
  107. package/dist/types/src/theming/presetColors.d.ts +11 -0
  108. package/dist/types/src/theming/primitiveTokens.d.ts +2 -0
  109. package/dist/types/src/utils/effectiveOpacity.d.ts +2 -0
  110. package/dist/types/src/utils/numbers.d.ts +1 -2
  111. package/dist/types/src/utils/tokenColor.d.ts +2 -0
  112. package/dist/ui-vue.css +2 -1
  113. package/dist/utils.mjs +165 -194
  114. package/index.d.ts +18 -0
  115. package/index.js +36 -0
  116. package/package.json +26 -21
  117. package/src/components/Toast/LayoutToasts.vue +19 -11
  118. package/src/components/Toast/ToastMessage.vue +125 -68
  119. package/src/components/Toast/toastDSV2.ts +238 -67
  120. package/src/components/UiActionBar/UiActionBar.vue +4 -3
  121. package/src/components/UiActionBar/UiActionBarItem.vue +9 -6
  122. package/src/components/UiActionBar/types.ts +13 -0
  123. package/src/components/UiAvatar/UiAvatar.vue +8 -2
  124. package/src/components/UiAvatarList/UiAvatarList.vue +51 -20
  125. package/src/components/UiBadge/UiBadge.vue +1 -1
  126. package/src/components/UiBanner/UiBanner.vue +71 -21
  127. package/src/components/UiBreadcrumb/UiBreadcrumb.vue +1 -1
  128. package/src/components/UiButton/UiButton.vue +92 -25
  129. package/src/components/UiButtonGroup/UiButtonGroup.vue +21 -17
  130. package/src/components/UiButtonGroup/UiButtonGroupItem.vue +33 -15
  131. package/src/components/UiButtonGroup/types.ts +19 -0
  132. package/src/components/UiCard/UiCard.vue +20 -23
  133. package/src/components/UiChoice/UiChoice.vue +187 -0
  134. package/src/components/UiChoice/index.ts +2 -0
  135. package/src/components/UiChoice/types.ts +11 -0
  136. package/src/components/UiColorField/UiColorField.vue +2 -2
  137. package/src/components/UiColorPicker/UiColorPicker.vue +11 -8
  138. package/src/components/UiCombobox/UiCombobox.types.ts +52 -0
  139. package/src/components/UiCombobox/UiCombobox.vue +296 -0
  140. package/src/components/UiCombobox/index.ts +2 -0
  141. package/src/components/UiDataTable/UiDataTable.types.ts +47 -0
  142. package/src/components/UiDataTable/UiDataTable.vue +422 -0
  143. package/src/components/UiDataTable/index.ts +12 -0
  144. package/src/components/UiDialog/UiDialogContent.vue +22 -7
  145. package/src/components/UiDrawer/UiDrawer.vue +16 -0
  146. package/src/components/UiDrawer/UiDrawerContent.vue +42 -0
  147. package/src/components/UiDrawer/UiDrawerTrigger.vue +17 -0
  148. package/src/components/UiDropdown/DropdownItemCheckbox.vue +10 -0
  149. package/src/components/UiDropdown/UiDropdownContent.vue +32 -21
  150. package/src/components/UiDropdown/UiDropdownGroup.vue +23 -0
  151. package/src/components/UiDropdown/UiDropdownItem.vue +38 -18
  152. package/src/components/UiDropdown/UiDropdownSeparator.vue +1 -1
  153. package/src/components/UiDropdown/UiDropdownTrigger.vue +138 -43
  154. package/src/components/UiDropdown/index.ts +1 -0
  155. package/src/components/UiEmojiPickerList/UiEmojiPickerList.vue +122 -0
  156. package/src/components/UiEmptyState/UiEmptyState.vue +16 -4
  157. package/src/components/UiFieldWrapper/UiFieldWrapper.vue +9 -3
  158. package/src/components/UiHorizontalSeparator/UiHorizontalSeparator.vue +2 -2
  159. package/src/components/UiInputCheckbox/CheckboxGlyph.vue +78 -0
  160. package/src/components/UiInputCheckbox/UiInputCheckbox.vue +213 -177
  161. package/src/components/UiInputEmoji/UiInputEmoji.vue +18 -95
  162. package/src/components/UiInputRadio/RadioGlyph.vue +45 -0
  163. package/src/components/UiInputRadio/UiInputRadio.vue +177 -169
  164. package/src/components/UiInputRadio/UiInputRadioGroup.vue +15 -5
  165. package/src/components/UiInputRadio/types.ts +1 -2
  166. package/src/components/UiInputSelect/UiInputSelect.vue +9 -7
  167. package/src/components/UiInputTextarea/UiInputTextarea.vue +20 -35
  168. package/src/components/UiLabel/UiLabel.vue +1 -1
  169. package/src/components/UiListItem/UiListItem.vue +55 -9
  170. package/src/components/UiLoader/UiLoader.vue +4 -20
  171. package/src/components/UiLoader/UiSpinnerIcon.vue +21 -0
  172. package/src/components/UiMenu/UiMenuContent.vue +24 -3
  173. package/src/components/UiMenu/UiMenuGroup.vue +1 -1
  174. package/src/components/UiMenu/UiMenuItem.vue +14 -3
  175. package/src/components/UiMenu/UiMenuSubContent.vue +1 -1
  176. package/src/components/UiMenu/UiMenuSubTrigger.vue +1 -1
  177. package/src/components/UiNestedOptions/UiNestedOptions.vue +6 -0
  178. package/src/components/UiPage/UiPage.vue +190 -32
  179. package/src/components/UiPagination/UiPagination.vue +99 -0
  180. package/src/components/UiPagination/index.ts +2 -0
  181. package/src/components/UiPagination/types.ts +28 -0
  182. package/src/components/UiPane/UiPane.vue +20 -0
  183. package/src/components/UiPane/UiPaneContent.vue +232 -0
  184. package/src/components/UiPane/UiPaneTrigger.vue +14 -0
  185. package/src/components/UiPane/index.ts +12 -0
  186. package/src/components/UiPopover/UiPopoverContent.vue +21 -1
  187. package/src/components/UiProgress/UiProgress.vue +2 -2
  188. package/src/components/UiRating/UiRating.vue +258 -0
  189. package/src/components/UiRating/types.ts +1 -0
  190. package/src/components/UiRoomButton/UiRoomButton.vue +10 -41
  191. package/src/components/UiRoomCountdown/UiRoomCountdown.vue +376 -0
  192. package/src/components/UiShell/UiShell.vue +9 -3
  193. package/src/components/UiSideMenu/UiSideMenu.vue +155 -18
  194. package/src/components/UiSideMenu/UiSideMenuItemContent.vue +20 -16
  195. package/src/components/UiStepper/UiStepper.vue +3 -16
  196. package/src/components/UiStepper/UiStepperDescription.vue +1 -13
  197. package/src/components/UiStepper/UiStepperIndicator.vue +11 -48
  198. package/src/components/UiStepper/UiStepperItem.vue +1 -8
  199. package/src/components/UiStepper/UiStepperSeparator.vue +5 -16
  200. package/src/components/UiStepper/UiStepperTitle.vue +1 -10
  201. package/src/components/UiSwitch/UiSwitch.vue +44 -28
  202. package/src/components/UiTable/UiTable.vue +98 -8
  203. package/src/components/UiTable/UiTableActionsCell.vue +135 -0
  204. package/src/components/UiTable/UiTableActionsHeaderCell.vue +19 -0
  205. package/src/components/UiTable/UiTableBody.vue +16 -1
  206. package/src/components/UiTable/UiTableCell.vue +33 -16
  207. package/src/components/UiTable/UiTableHeader.vue +6 -5
  208. package/src/components/UiTable/UiTableHeaderCell.vue +61 -9
  209. package/src/components/UiTable/UiTableRow.vue +46 -10
  210. package/src/components/UiTable/context.ts +5 -0
  211. package/src/components/UiTable/index.ts +4 -0
  212. package/src/components/UiTabs/UiTabs.vue +56 -61
  213. package/src/components/UiTag/UiTag.types.ts +28 -0
  214. package/src/components/UiTag/UiTag.vue +24 -42
  215. package/src/components/UiTag/index.ts +2 -0
  216. package/src/components/UiTextField/UiTextField.vue +21 -36
  217. package/src/components/UiTooltip/UiTooltipContent.vue +1 -1
  218. package/src/components/UiTooltip/UiTooltipProvider.vue +3 -0
  219. package/src/components/UiTooltip/UiTooltipTrigger.vue +16 -1
  220. package/src/composables/storedThemingApplies.ts +19 -0
  221. package/src/composables/useButtonStyles.ts +9 -13
  222. package/src/composables/useChoiceboxSurface.ts +36 -0
  223. package/src/composables/useContentMode.ts +29 -16
  224. package/src/composables/useControlModes.ts +11 -0
  225. package/src/composables/useControlShape.ts +34 -0
  226. package/src/composables/useFieldFocusEvents.ts +30 -0
  227. package/src/composables/useIconSize.ts +15 -0
  228. package/src/composables/usePullGesture.ts +142 -0
  229. package/src/composables/useThemeAndModes.ts +28 -1
  230. package/src/css/body.css +16 -1
  231. package/src/css/fonts.css +39 -5
  232. package/src/global.d.ts +36 -0
  233. package/src/theming/colorScale.ts +173 -0
  234. package/src/theming/legacyColorScale.ts +58 -0
  235. package/src/theming/presetColors.ts +33 -0
  236. package/src/theming/primitiveTokens.ts +71 -0
  237. package/src/utils/effectiveOpacity.ts +8 -0
  238. package/src/utils/i18n.ts +6 -0
  239. package/src/utils/numbers.ts +1 -1
  240. package/src/utils/responsive.d.ts +14 -0
  241. package/src/utils/tokenColor.ts +9 -0
  242. package/dist/UiTimelineItem.vue_vue_type_style_index_0_lang-LpdvGf5X.mjs +0 -6093
  243. package/dist/a11y-BhF_nl7L.mjs +0 -159
  244. package/dist/i18n-Cktw9hIu.mjs +0 -49
  245. package/dist/toastDSV2-wMh-UMzW.mjs +0 -74
  246. package/dist/types/src/components/UiAvatar/index.d.ts +0 -1
  247. package/dist/types/src/components/UiAvatarList/index.d.ts +0 -1
  248. package/dist/types/src/components/UiBadge/index.d.ts +0 -1
  249. package/dist/types/src/components/UiBanner/index.d.ts +0 -2
  250. package/dist/types/src/components/UiButtonGroup/index.d.ts +0 -3
  251. package/dist/types/src/components/UiCarousel/index.d.ts +0 -2
  252. package/dist/types/src/components/UiColorField/index.d.ts +0 -2
  253. package/dist/types/src/components/UiDialog/MarketplaceHeaderExample.vue.d.ts +0 -28
  254. package/dist/types/src/components/UiDialog/index.d.ts +0 -7
  255. package/dist/types/src/components/UiFieldWrapper/index.d.ts +0 -1
  256. package/dist/types/src/components/UiInputCheckbox/index.d.ts +0 -2
  257. package/dist/types/src/components/UiInputEmoji/index.d.ts +0 -1
  258. package/dist/types/src/components/UiInputRadio/index.d.ts +0 -3
  259. package/dist/types/src/components/UiInputSelect/index.d.ts +0 -2
  260. package/dist/types/src/components/UiInputTextarea/index.d.ts +0 -2
  261. package/dist/types/src/components/UiMenu/index.d.ts +0 -10
  262. package/dist/types/src/components/UiProgress/index.d.ts +0 -2
  263. package/dist/types/src/components/UiSwitch/index.d.ts +0 -2
  264. package/dist/types/src/components/UiTabs/index.d.ts +0 -2
  265. package/dist/types/src/components/UiTimeline/index.d.ts +0 -2
  266. package/dist/types/src/components/UiTooltip/index.d.ts +0 -4
  267. package/dist/types/src/mixins/DynamicAction.d.ts +0 -30
  268. package/dist/useThemeAndModes-BzYwSOEv.mjs +0 -108
  269. package/src/components/UiAvatar/index.js +0 -1
  270. package/src/components/UiAvatarList/index.js +0 -1
  271. package/src/components/UiBadge/index.ts +0 -2
  272. package/src/components/UiBanner/index.ts +0 -2
  273. package/src/components/UiButtonGroup/index.ts +0 -3
  274. package/src/components/UiCarousel/index.ts +0 -2
  275. package/src/components/UiColorField/index.ts +0 -2
  276. package/src/components/UiDialog/MarketplaceHeaderExample.vue +0 -217
  277. package/src/components/UiDialog/index.ts +0 -18
  278. package/src/components/UiFieldWrapper/index.ts +0 -1
  279. package/src/components/UiInputCheckbox/index.ts +0 -2
  280. package/src/components/UiInputEmoji/index.ts +0 -1
  281. package/src/components/UiInputRadio/index.ts +0 -3
  282. package/src/components/UiInputSelect/index.ts +0 -2
  283. package/src/components/UiInputTextarea/index.ts +0 -2
  284. package/src/components/UiMenu/index.ts +0 -10
  285. package/src/components/UiProgress/index.ts +0 -2
  286. package/src/components/UiSwitch/index.ts +0 -2
  287. package/src/components/UiTabs/index.ts +0 -5
  288. package/src/components/UiTag/index.js +0 -1
  289. package/src/components/UiTimeline/index.ts +0 -2
  290. package/src/components/UiTooltip/index.js +0 -4
  291. package/src/mixins/DynamicAction.js +0 -61
@@ -0,0 +1,422 @@
1
+ <script setup lang="ts" generic="TData extends Record<string, unknown>">
2
+ import type { ColumnDef, RowSelectionState, SortingState, Updater } from '@tanstack/vue-table'
3
+ import { rowSelectionFeature, rowSortingFeature, tableFeatures, useTable } from '@tanstack/vue-table'
4
+ import { useResizeObserver } from '@vueuse/core'
5
+ import { computed, ref, useSlots, useTemplateRef } from 'vue'
6
+ import type { RouteLocationRaw } from 'vue-router'
7
+ import {
8
+ UiTable,
9
+ UiTableHeader,
10
+ UiTableHeaderCell,
11
+ UiTableActionsHeaderCell,
12
+ UiTableBody,
13
+ UiTableRow,
14
+ UiTableCell,
15
+ UiTableActionsCell,
16
+ } from '../UiTable/index'
17
+ import UiInputCheckbox from '../UiInputCheckbox/UiInputCheckbox.vue'
18
+ import type { UiTableSize } from '../UiTable/context'
19
+ import { useTranslate } from '../../utils/i18n'
20
+ import type { UiDataTableColumn, UiDataTableSort } from './UiDataTable.types'
21
+
22
+ export interface UiDataTableProps<TData> {
23
+ /** Column definitions. Each column can be customized via `#cell-<id>` and `#header-<id>` slots. */
24
+ columns: UiDataTableColumn<TData>[]
25
+ /** Rows, already sorted/filtered by the consumer. */
26
+ data: TData[]
27
+ /**
28
+ * Row heights: `md` = 40px header / 48px rows, `lg` = 48px header / 64px rows.
29
+ * @default 'md'
30
+ */
31
+ size?: UiTableSize
32
+ /**
33
+ * Alternating row backgrounds. Preferred over row dividers.
34
+ * @default true
35
+ */
36
+ zebra?: boolean
37
+ /**
38
+ * Renders skeleton rows instead of data.
39
+ * @default false
40
+ */
41
+ loading?: boolean
42
+ /**
43
+ * Number of skeleton rows while loading.
44
+ * @default 5
45
+ */
46
+ skeletonRows?: number
47
+ /**
48
+ * Current sort, controlled by the consumer (`v-model:sorting`). The table
49
+ * only renders the affordance and emits; sorting the data stays consumer-side.
50
+ * @default null
51
+ */
52
+ sorting?: UiDataTableSort | null
53
+ /**
54
+ * Makes rows interactive: hover feedback, keyboard focus and `row-click` emits.
55
+ * @default false
56
+ */
57
+ rowClickable?: boolean
58
+ /**
59
+ * Turns each row into a link to the returned location. The first cell holds
60
+ * a router link stretched over the row, so Cmd/Ctrl click, middle click and
61
+ * keyboard focus behave like any link. The first column's content sits
62
+ * inside the link, so it must hold no interactive content. Content of other
63
+ * cells that must stay interactive above the link (tooltips, buttons) needs
64
+ * `relative z-10`; the selection checkbox and `#actions` already sit above
65
+ * it. Takes precedence over `rowClickable`.
66
+ */
67
+ rowLink?: (row: TData) => RouteLocationRaw
68
+ /**
69
+ * Adds a leftmost checkbox column with a select-all header. Selection is
70
+ * controlled through `v-model:selectedRowIds`; pass `getRowId` so ids stay
71
+ * stable across data changes.
72
+ * @default false
73
+ */
74
+ selectable?: boolean
75
+ /**
76
+ * Selected row ids, controlled by the consumer (`v-model:selectedRowIds`).
77
+ * @default []
78
+ */
79
+ selectedRowIds?: string[]
80
+ /**
81
+ * How the `#actions` slot attaches to the row. `default` reveals it on
82
+ * hover, masking the cells behind bare action buttons; `floating` also
83
+ * reveals on hover but drops that backdrop for self-contained content
84
+ * like a UiActionBar; `menu` tucks it behind an always-visible trigger
85
+ * button that opens a popover on click.
86
+ * @default 'default'
87
+ */
88
+ actionsVariant?: 'default' | 'floating' | 'menu'
89
+ /**
90
+ * Whether a row has trailing actions. Rows that return false get an empty
91
+ * actions cell, so nothing reveals over them on hover. All rows have
92
+ * actions when omitted.
93
+ */
94
+ rowHasActions?: (row: TData) => boolean
95
+ /**
96
+ * Id of the row whose hover actions stay shown without hover or focus,
97
+ * e.g. while a menu opened from them is open. Matches `getRowId`.
98
+ * @default null
99
+ */
100
+ revealedActionsRowId?: string | null
101
+ /** Stable row identity; falls back to the row index. */
102
+ getRowId?: (row: TData, index: number) => string
103
+ }
104
+
105
+ const props = withDefaults(defineProps<UiDataTableProps<TData>>(), {
106
+ size: 'md',
107
+ zebra: true,
108
+ loading: false,
109
+ skeletonRows: 5,
110
+ sorting: null,
111
+ rowClickable: false,
112
+ rowLink: undefined,
113
+ selectable: false,
114
+ selectedRowIds: () => [],
115
+ actionsVariant: 'default',
116
+ rowHasActions: undefined,
117
+ revealedActionsRowId: null,
118
+ getRowId: undefined,
119
+ })
120
+
121
+ const emit = defineEmits<{
122
+ 'update:sorting': [sort: UiDataTableSort | null]
123
+ 'update:selectedRowIds': [ids: string[]]
124
+ 'rowClick': [row: TData]
125
+ }>()
126
+
127
+ const translate = useTranslate()
128
+
129
+ defineSlots<
130
+ {
131
+ /** Trailing row actions, revealed on row hover/focus. */
132
+ actions?: (props: { row: TData }) => unknown
133
+ /**
134
+ * Rows after the data rows, in a second body of the same table, e.g. a
135
+ * teaser for rows the plan hides. They share the column grid and the
136
+ * zebra of the data rows. Render a `UiTableCell` per column, after an
137
+ * empty one when `selectable`, and end each row with an empty
138
+ * `UiTableActionsCell` when `hasActions`. The body is positioned, so an
139
+ * overlay over these rows can sit in a `UiTableRow` with `zebra` off.
140
+ */
141
+ 'body-end'?: (props: {
142
+ columns: UiDataTableColumn<TData>[]
143
+ selectable: boolean
144
+ hasActions: boolean
145
+ actionsVariant: 'default' | 'floating' | 'menu'
146
+ }) => unknown
147
+ }
148
+ & Partial<Record<`cell-${string}`, (props: { row: TData, value: unknown }) => unknown>>
149
+ & Partial<Record<`header-${string}`, (props: { column: UiDataTableColumn<TData> }) => unknown>>
150
+ >()
151
+
152
+ const slots = useSlots()
153
+ const hasActions = computed(() => !!slots.actions)
154
+
155
+ const features = tableFeatures({ rowSortingFeature, rowSelectionFeature })
156
+
157
+ const tanstackColumns = computed(() => props.columns.map(column => ({
158
+ id: column.id,
159
+ header: column.header,
160
+ ...(column.accessorKey ? { accessorKey: column.accessorKey } : {}),
161
+ enableSorting: column.sortable ?? false,
162
+ }) as ColumnDef<typeof features, TData>))
163
+
164
+ const sortingState = computed<SortingState>(() => (
165
+ props.sorting
166
+ ? [{ id: props.sorting.id, desc: props.sorting.direction === 'desc' }]
167
+ : []
168
+ ))
169
+
170
+ function toSort (state: SortingState): UiDataTableSort | null {
171
+ const [first] = state
172
+ if (!first) return null
173
+ return { id: first.id, direction: first.desc ? 'desc' : 'asc' }
174
+ }
175
+
176
+ const rowSelectionState = computed<RowSelectionState>(() => (
177
+ Object.fromEntries(props.selectedRowIds.map(id => [id, true as const]))
178
+ ))
179
+
180
+ const table = useTable<typeof features, TData>({
181
+ features,
182
+ columns: tanstackColumns,
183
+ data: computed(() => props.data),
184
+ ...(props.getRowId ? { getRowId: props.getRowId } : {}),
185
+ manualSorting: true,
186
+ enableMultiSort: false,
187
+ enableSortingRemoval: false,
188
+ enableRowSelection: computed(() => props.selectable),
189
+ state: computed(() => ({ sorting: sortingState.value, rowSelection: rowSelectionState.value })),
190
+ onSortingChange: (updater: Updater<SortingState>) => {
191
+ const next = typeof updater === 'function' ? updater(sortingState.value) : updater
192
+ emit('update:sorting', toSort(next))
193
+ },
194
+ onRowSelectionChange: (updater: Updater<RowSelectionState>) => {
195
+ const next = typeof updater === 'function' ? updater(rowSelectionState.value) : updater
196
+ emit('update:selectedRowIds', Object.keys(next))
197
+ },
198
+ })
199
+
200
+ // Escape hatch: the underlying TanStack table instance, e.g.
201
+ // `tableRef.value?.table.setSorting(...)`.
202
+ defineExpose({ table })
203
+
204
+ function sortDirectionFor (columnId: string) {
205
+ if (props.sorting?.id !== columnId) return 'none'
206
+ return props.sorting.direction
207
+ }
208
+
209
+ function onHeaderSort (column: UiDataTableColumn<TData>) {
210
+ const direction = sortDirectionFor(column.id) === 'asc' ? 'desc' : 'asc'
211
+ emit('update:sorting', { id: column.id, direction })
212
+ }
213
+
214
+ const columnById = computed(() => new Map(props.columns.map(column => [column.id, column])))
215
+
216
+ function headerStyle (columnId: string) {
217
+ const column = columnById.value.get(columnId)
218
+ return { width: column?.width, minWidth: column?.minWidth }
219
+ }
220
+
221
+ function cellStyle (columnId: string) {
222
+ return { minWidth: columnById.value.get(columnId)?.minWidth }
223
+ }
224
+
225
+ function wrapClass (columnId: string) {
226
+ return columnById.value.get(columnId)?.nowrap ? 'whitespace-nowrap' : undefined
227
+ }
228
+
229
+ function isEmptyValue (value: unknown) {
230
+ return value === null || value === undefined || value === ''
231
+ }
232
+
233
+ function isEmptyCell (columnId: string, value: unknown) {
234
+ return !slots[`cell-${columnId}`] && isEmptyValue(value)
235
+ }
236
+
237
+ function isLinkCell (cellIndex: number) {
238
+ return !!props.rowLink && cellIndex === 0
239
+ }
240
+
241
+ const renderedRowCount = computed(() => (props.loading ? props.skeletonRows : table.getRowModel().rows.length))
242
+
243
+ // A scroll container captures the sticky header, so the region only scrolls once the columns overflow it
244
+ const region = useTemplateRef<HTMLElement>('region')
245
+ const columnsOverflow = ref(true)
246
+
247
+ const regionTable = computed(() => region.value?.firstElementChild as HTMLElement | null | undefined)
248
+
249
+ useResizeObserver(() => [region.value, regionTable.value], () => {
250
+ const element = region.value
251
+ const table = regionTable.value
252
+ if (!element || !table) return
253
+ const { paddingLeft, paddingRight } = getComputedStyle(element)
254
+ columnsOverflow.value = table.offsetWidth > element.clientWidth - parseFloat(paddingLeft) - parseFloat(paddingRight)
255
+ })
256
+
257
+ const regionClasses = computed(() => columnsOverflow.value && 'overflow-x-auto')
258
+
259
+ // A row link stretches over the row, so the selection cell rises above it to stay clickable
260
+ const selectionCellClasses = computed(() => props.rowLink && 'relative z-10')
261
+ </script>
262
+
263
+ <template>
264
+ <div
265
+ ref="region"
266
+ class="px-(--ui-page-inline,0px)"
267
+ :class="regionClasses"
268
+ data-testid="ui-data-table-region"
269
+ >
270
+ <UiTable
271
+ :size="size"
272
+ :zebra="zebra"
273
+ >
274
+ <UiTableHeader>
275
+ <tr
276
+ v-for="headerGroup in table.getHeaderGroups()"
277
+ :key="headerGroup.id"
278
+ >
279
+ <UiTableHeaderCell
280
+ v-if="selectable"
281
+ class="w-0"
282
+ >
283
+ <UiInputCheckbox
284
+ :checked="table.getIsAllRowsSelected()"
285
+ :indeterminate="table.getIsSomeRowsSelected() && !table.getIsAllRowsSelected()"
286
+ :aria-label="translate('general_form_multiselect-select-all')"
287
+ @change="table.toggleAllRowsSelected()"
288
+ />
289
+ </UiTableHeaderCell>
290
+ <UiTableHeaderCell
291
+ v-for="header in headerGroup.headers"
292
+ :key="header.id"
293
+ :sortable="columnById.get(header.column.id)?.sortable ?? false"
294
+ :sort-direction="sortDirectionFor(header.column.id)"
295
+ :align="columnById.get(header.column.id)?.align ?? 'left'"
296
+ :class="wrapClass(header.column.id)"
297
+ :style="headerStyle(header.column.id)"
298
+ @sort="onHeaderSort(columnById.get(header.column.id)!)"
299
+ >
300
+ <slot
301
+ :name="`header-${header.column.id}`"
302
+ :column="columnById.get(header.column.id)!"
303
+ >
304
+ {{ columnById.get(header.column.id)?.header }}
305
+ </slot>
306
+ </UiTableHeaderCell>
307
+ <UiTableActionsHeaderCell v-if="hasActions" />
308
+ </tr>
309
+ </UiTableHeader>
310
+ <UiTableBody>
311
+ <template v-if="loading">
312
+ <UiTableRow
313
+ v-for="index in skeletonRows"
314
+ :key="`skeleton-${index}`"
315
+ >
316
+ <UiTableCell v-if="selectable" />
317
+ <UiTableCell
318
+ v-for="column in columns"
319
+ :key="column.id"
320
+ :align="column.align ?? 'left'"
321
+ >
322
+ <div
323
+ class="h-4 animate-pulse rounded-sm bg-surface-neutral-alpha-200"
324
+ :class="index % 2 === 0 ? 'w-1/2' : 'w-2/3'"
325
+ />
326
+ </UiTableCell>
327
+ <UiTableActionsCell v-if="hasActions" />
328
+ </UiTableRow>
329
+ </template>
330
+ <template v-else>
331
+ <UiTableRow
332
+ v-for="row in table.getRowModel().rows"
333
+ :key="row.id"
334
+ :clickable="rowClickable && !rowLink"
335
+ :linked="!!rowLink"
336
+ :selected="selectable && row.getIsSelected()"
337
+ @click="emit('rowClick', row.original)"
338
+ >
339
+ <UiTableCell
340
+ v-if="selectable"
341
+ :class="selectionCellClasses"
342
+ @click.stop
343
+ >
344
+ <UiInputCheckbox
345
+ :checked="row.getIsSelected()"
346
+ :aria-label="translate('general_table_select-row')"
347
+ @change="row.toggleSelected()"
348
+ />
349
+ </UiTableCell>
350
+ <UiTableCell
351
+ v-for="(cell, cellIndex) in row.getAllCells()"
352
+ :key="cell.id"
353
+ :align="columnById.get(cell.column.id)?.align ?? 'left'"
354
+ :empty="!isLinkCell(cellIndex) && isEmptyCell(cell.column.id, cell.getValue())"
355
+ :class="wrapClass(cell.column.id)"
356
+ :style="cellStyle(cell.column.id)"
357
+ >
358
+ <component
359
+ :is="'router-link'"
360
+ v-if="isLinkCell(cellIndex)"
361
+ :to="rowLink!(row.original)"
362
+ class="block min-w-0 text-inherit no-underline focus-indicator-none after:absolute after:inset-0 after:rounded-table-row focus-visible:after:focus-ring"
363
+ data-testid="ui-data-table-row-link"
364
+ >
365
+ <slot
366
+ :name="`cell-${cell.column.id}`"
367
+ :row="row.original"
368
+ :value="cell.getValue()"
369
+ >
370
+ <span
371
+ v-if="isEmptyValue(cell.getValue())"
372
+ class="text-text-neutral-secondary"
373
+ >–</span>
374
+ <template v-else>
375
+ {{ cell.getValue() }}
376
+ </template>
377
+ </slot>
378
+ </component>
379
+ <slot
380
+ v-else
381
+ :name="`cell-${cell.column.id}`"
382
+ :row="row.original"
383
+ :value="cell.getValue()"
384
+ >
385
+ {{ cell.getValue() }}
386
+ </slot>
387
+ </UiTableCell>
388
+ <template v-if="hasActions">
389
+ <UiTableActionsCell
390
+ v-if="!rowHasActions || rowHasActions(row.original)"
391
+ :variant="actionsVariant"
392
+ :revealed="row.id === revealedActionsRowId"
393
+ >
394
+ <slot
395
+ name="actions"
396
+ :row="row.original"
397
+ />
398
+ </UiTableActionsCell>
399
+ <UiTableActionsCell
400
+ v-else
401
+ :variant="actionsVariant"
402
+ />
403
+ </template>
404
+ </UiTableRow>
405
+ </template>
406
+ </UiTableBody>
407
+ <UiTableBody
408
+ v-if="slots['body-end']"
409
+ class="relative"
410
+ :zebra-offset="renderedRowCount % 2 === 1"
411
+ >
412
+ <slot
413
+ name="body-end"
414
+ :columns="columns"
415
+ :selectable="selectable"
416
+ :has-actions="hasActions"
417
+ :actions-variant="actionsVariant"
418
+ />
419
+ </UiTableBody>
420
+ </UiTable>
421
+ </div>
422
+ </template>
@@ -0,0 +1,12 @@
1
+ export { default as UiDataTable } from './UiDataTable.vue'
2
+ export type { UiDataTableProps } from './UiDataTable.vue'
3
+ export type { UiDataTableColumn, UiDataTableSort } from './UiDataTable.types'
4
+
5
+ // Escape hatch for tables that outgrow UiDataTable: compose the UiTable
6
+ // primitives with TanStack Table directly.
7
+ export {
8
+ FlexRender,
9
+ tableFeatures,
10
+ useTable,
11
+ } from '@tanstack/vue-table'
12
+ export type { ColumnDef, SortingState } from '@tanstack/vue-table'
@@ -110,12 +110,12 @@ useMutationObserver(contentRef, () => {
110
110
  <DialogPortal>
111
111
  <DialogOverlay
112
112
  :class="[
113
- 'fixed inset-0 bg-surface-overlay-alpha z-50',
113
+ 'fixed inset-0 bg-surface-overlay-alpha z-overlay',
114
114
  'ui-dialog-overlay',
115
115
  overlayClass,
116
116
  ]"
117
117
  />
118
- <div class="fixed inset-0 z-50 flex items-center justify-center pointer-events-none">
118
+ <div class="fixed inset-0 z-overlay flex items-center justify-center pointer-events-none">
119
119
  <DialogContent
120
120
  v-bind="{ ...forwarded, ...$attrs }"
121
121
  :class="[
@@ -124,7 +124,7 @@ useMutationObserver(contentRef, () => {
124
124
  'w-[95vw] max-h-[85vh]',
125
125
  widthClass,
126
126
  'overflow-hidden flex flex-col',
127
- 'ui-dialog-content animate-fade-scale',
127
+ 'ui-dialog-content',
128
128
  'focus:outline-hidden focus-indicator-none',
129
129
  'm-2',
130
130
  !noPadding && 'py-6'
@@ -205,7 +205,7 @@ useMutationObserver(contentRef, () => {
205
205
  v-if="$slots.footer"
206
206
  :class="[
207
207
  !noPadding && 'px-6 pt-6',
208
- hasScroll && 'border-t border-borders-neutral-light',
208
+ hasScroll && 'border-t border-divider',
209
209
  ]"
210
210
  >
211
211
  <slot name="footer" />
@@ -235,12 +235,27 @@ useMutationObserver(contentRef, () => {
235
235
  animation: fade-out 150ms ease-in;
236
236
  }
237
237
 
238
- /* Content animations */
238
+ /* Content animations — the panel carries its own keyframes rather than the
239
+ shared reka-animations.css ones: a consumer that does not load that
240
+ stylesheet would otherwise leave reka waiting for an `animationend` that
241
+ never fires, and the panel would never unmount on close. In and out need
242
+ distinct names for the same reason — a same-name animation never restarts,
243
+ so no end event would ever come. */
244
+ @keyframes fade-scale-in {
245
+ from { opacity: 0; transform: scale(0.95); }
246
+ to { opacity: 1; transform: scale(1); }
247
+ }
248
+
249
+ @keyframes fade-scale-out {
250
+ from { opacity: 1; transform: scale(1); }
251
+ to { opacity: 0; transform: scale(0.95); }
252
+ }
253
+
239
254
  .ui-dialog-content[data-state='open'] {
240
- animation: fade-scale 200ms ease-out;
255
+ animation: fade-scale-in 200ms ease-out both;
241
256
  }
242
257
 
243
258
  .ui-dialog-content[data-state='closed'] {
244
- animation: fade-scale 150ms ease-in reverse;
259
+ animation: fade-scale-out 150ms ease-in both;
245
260
  }
246
261
  </style>
@@ -0,0 +1,16 @@
1
+ <script setup lang="ts">
2
+ import type { DrawerRootEmits, DrawerRootProps } from 'vaul-vue'
3
+ import { DrawerRoot } from 'vaul-vue'
4
+ import { useForwardPropsEmits } from 'reka-ui'
5
+
6
+ const props = defineProps<DrawerRootProps>()
7
+ const emits = defineEmits<DrawerRootEmits>()
8
+
9
+ const forwarded = useForwardPropsEmits(props, emits)
10
+ </script>
11
+
12
+ <template>
13
+ <DrawerRoot v-bind="{ ...forwarded, ...$attrs }">
14
+ <slot />
15
+ </DrawerRoot>
16
+ </template>
@@ -0,0 +1,42 @@
1
+ <script setup lang="ts">
2
+ import { DrawerContent, DrawerHandle, DrawerOverlay, DrawerPortal, DrawerTitle } from 'vaul-vue'
3
+ import { VisuallyHidden } from 'reka-ui'
4
+ import { useTranslate } from '../../utils/i18n'
5
+
6
+ interface UiDrawerContentProps {
7
+ title?: string
8
+ }
9
+
10
+ const props = withDefaults(defineProps<UiDrawerContentProps>(), {
11
+ title: undefined,
12
+ })
13
+
14
+ const translate = useTranslate()
15
+ </script>
16
+
17
+ <template>
18
+ <DrawerPortal>
19
+ <DrawerOverlay class="fixed inset-0 z-overlay bg-surface-overlay-alpha" />
20
+
21
+ <DrawerContent
22
+ v-bind="$attrs"
23
+ class="fixed inset-x-0 bottom-0 z-overlay flex max-h-[85vh] flex-col rounded-t-2xl border-t border-divider bg-surface-neutral-bg-main shadow-shadows-drop-shadow-2xl focus:outline-hidden focus-indicator-none"
24
+ >
25
+ <VisuallyHidden as-child>
26
+ <DrawerTitle>{{ props.title ?? translate('general_dialog_title') }}</DrawerTitle>
27
+ </VisuallyHidden>
28
+
29
+ <DrawerHandle class="mt-2 bg-borders-neutral-default!" />
30
+
31
+ <div class="ui-drawer-content-body min-h-0 flex-1 overflow-y-auto">
32
+ <slot />
33
+ </div>
34
+ </DrawerContent>
35
+ </DrawerPortal>
36
+ </template>
37
+
38
+ <style scoped>
39
+ .ui-drawer-content-body {
40
+ padding-bottom: env(safe-area-inset-bottom);
41
+ }
42
+ </style>
@@ -0,0 +1,17 @@
1
+ <script setup lang="ts">
2
+ import type { DrawerTriggerProps } from 'vaul-vue'
3
+ import { DrawerTrigger } from 'vaul-vue'
4
+ import { useForwardProps } from 'reka-ui'
5
+
6
+ const props = defineProps<DrawerTriggerProps>()
7
+
8
+ const forwarded = useForwardProps(props)
9
+ </script>
10
+
11
+ <template>
12
+ <DrawerTrigger
13
+ v-bind="{ ...forwarded, ...$attrs }"
14
+ >
15
+ <slot />
16
+ </DrawerTrigger>
17
+ </template>
@@ -0,0 +1,10 @@
1
+ <script setup lang="ts">
2
+ import { injectSelectItemContext } from 'reka-ui'
3
+ import CheckboxGlyph from '../UiInputCheckbox/CheckboxGlyph.vue'
4
+
5
+ const item = injectSelectItemContext()
6
+ </script>
7
+
8
+ <template>
9
+ <CheckboxGlyph :checked="item.isSelected.value" />
10
+ </template>
@@ -3,8 +3,18 @@ import type { SelectContentProps } from 'reka-ui'
3
3
  import { SelectContent, SelectPortal, SelectScrollDownButton, SelectScrollUpButton, SelectViewport } from 'reka-ui'
4
4
  import { useSlots } from 'vue'
5
5
 
6
+ const WIDTH_CLASSES = {
7
+ auto: '',
8
+ lg: 'w-75',
9
+ } as const
10
+
6
11
  interface Props extends SelectContentProps {
7
12
  showScrollButtons?: boolean
13
+ /**
14
+ * 'auto' sizes the content to the trigger and its items; 'lg' gives items with descriptions a fixed 300px
15
+ * @default 'auto'
16
+ */
17
+ width?: keyof typeof WIDTH_CLASSES
8
18
  /**
9
19
  * The color semantic mode for the dropdown content
10
20
  * @default 'light'
@@ -12,7 +22,8 @@ interface Props extends SelectContentProps {
12
22
  colorsSemantic?: 'light' | 'dark'
13
23
  }
14
24
 
15
- withDefaults(defineProps<Props>(), {
25
+ const props = withDefaults(defineProps<Props>(), {
26
+ width: 'auto',
16
27
  position: 'popper',
17
28
  side: 'bottom',
18
29
  sideOffset: 8,
@@ -26,44 +37,44 @@ const slots = useSlots()
26
37
  <template>
27
38
  <SelectPortal>
28
39
  <SelectContent
40
+ data-testid="ui-dropdown-content"
29
41
  v-bind="$attrs"
30
42
  :position="position"
31
43
  :side-offset="sideOffset"
32
44
  :align="align"
33
45
  :side="side"
34
46
  :data-colors-semantic="colorsSemantic"
35
- class="ui-dropdown-content focus-indicator-none z-50 relative py-3 px-2 rounded-xl bg-surface-neutral-bg-main min-w-(--reka-select-trigger-width) max-h-(--reka-select-content-available-height) shadow-shadows-drop-shadow-lg data-[state=open]:animate-[slideDownAndFade_0.2s_ease] data-[state=closed]:animate-[slideUpAndFade_0.15s_ease]"
47
+ :class="WIDTH_CLASSES[props.width]"
48
+ class="ui-dropdown-content focus-indicator-none z-overlay relative p-1 rounded-container border border-container-border bg-surface-neutral-bg-main min-w-(--reka-select-trigger-width) max-w-(--reka-select-content-available-width) max-h-(--reka-select-content-available-height) shadow-shadows-drop-shadow-lg data-[state=open]:animate-[slideDownAndFade_0.2s_ease] data-[state=closed]:animate-[slideUpAndFade_0.15s_ease]"
36
49
  >
37
50
  <div
38
51
  v-if="slots.header"
39
- class="sticky top-0 bg-surface-neutral-bg-main px-3 mb-3"
52
+ class="pb-1"
40
53
  >
41
54
  <slot name="header" />
42
55
  </div>
43
56
 
44
- <div class="flex flex-col gap-1 overflow-y-auto max-h-[300px]">
45
- <SelectScrollUpButton
46
- v-if="showScrollButtons"
47
- class="flex items-center justify-center h-6 cursor-default text-text-neutral-base"
48
- >
49
- <div class="i-ph-caret-up size-4" />
50
- </SelectScrollUpButton>
57
+ <SelectScrollUpButton
58
+ v-if="showScrollButtons"
59
+ class="flex items-center justify-center h-6 cursor-default text-text-neutral-base"
60
+ >
61
+ <div class="i-ph-caret-up size-4" />
62
+ </SelectScrollUpButton>
51
63
 
52
- <SelectViewport class="flex flex-col gap-1">
53
- <slot />
54
- </SelectViewport>
64
+ <SelectViewport class="flex flex-col gap-1 max-h-[300px] rounded-row">
65
+ <slot />
66
+ </SelectViewport>
55
67
 
56
- <SelectScrollDownButton
57
- v-if="showScrollButtons"
58
- class="flex items-center justify-center h-6 cursor-default text-text-neutral-base"
59
- >
60
- <div class="i-ph-caret-down size-4" />
61
- </SelectScrollDownButton>
62
- </div>
68
+ <SelectScrollDownButton
69
+ v-if="showScrollButtons"
70
+ class="flex items-center justify-center h-6 cursor-default text-text-neutral-base"
71
+ >
72
+ <div class="i-ph-caret-down size-4" />
73
+ </SelectScrollDownButton>
63
74
 
64
75
  <div
65
76
  v-if="slots.footer"
66
- class="sticky bottom-0 bg-surface-neutral-bg-main"
77
+ class="pt-1"
67
78
  >
68
79
  <slot name="footer" />
69
80
  </div>