@vertesia/ui 0.79.0 → 0.79.2

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 (307) hide show
  1. package/lib/esm/core/components/Panel.js +8 -0
  2. package/lib/esm/core/components/Panel.js.map +1 -0
  3. package/lib/esm/core/components/SelectBox.js +1 -1
  4. package/lib/esm/core/components/SelectBox.js.map +1 -1
  5. package/lib/esm/core/components/SidePanel.js +2 -2
  6. package/lib/esm/core/components/SidePanel.js.map +1 -1
  7. package/lib/esm/core/components/TagsInput.js +194 -0
  8. package/lib/esm/core/components/TagsInput.js.map +1 -0
  9. package/lib/esm/core/components/index.js +2 -1
  10. package/lib/esm/core/components/index.js.map +1 -1
  11. package/lib/esm/core/components/shadcn/breadcrumb.js +29 -8
  12. package/lib/esm/core/components/shadcn/breadcrumb.js.map +1 -1
  13. package/lib/esm/core/components/shadcn/button.js +3 -2
  14. package/lib/esm/core/components/shadcn/button.js.map +1 -1
  15. package/lib/esm/core/components/shadcn/filters/filterBar.js +2 -2
  16. package/lib/esm/core/components/shadcn/filters/filterBar.js.map +1 -1
  17. package/lib/esm/core/components/shadcn/index.js +1 -0
  18. package/lib/esm/core/components/shadcn/index.js.map +1 -1
  19. package/lib/esm/core/components/shadcn/input.js +4 -1
  20. package/lib/esm/core/components/shadcn/input.js.map +1 -1
  21. package/lib/esm/core/components/shadcn/popover.js +1 -1
  22. package/lib/esm/core/components/shadcn/popover.js.map +1 -1
  23. package/lib/esm/core/components/shadcn/resizeable.js +2 -2
  24. package/lib/esm/core/components/shadcn/resizeable.js.map +1 -1
  25. package/lib/esm/core/components/shadcn/selectBox.js +15 -9
  26. package/lib/esm/core/components/shadcn/selectBox.js.map +1 -1
  27. package/lib/esm/core/components/shadcn/tabs.js +10 -3
  28. package/lib/esm/core/components/shadcn/tabs.js.map +1 -1
  29. package/lib/esm/core/components/shadcn/textarea.js +7 -0
  30. package/lib/esm/core/components/shadcn/textarea.js.map +1 -0
  31. package/lib/esm/core/hooks/CompositeState.js +139 -1
  32. package/lib/esm/core/hooks/CompositeState.js.map +1 -1
  33. package/lib/esm/core/hooks/index.js +1 -0
  34. package/lib/esm/core/hooks/index.js.map +1 -1
  35. package/lib/esm/core/hooks/useScrollableSearch.js +92 -0
  36. package/lib/esm/core/hooks/useScrollableSearch.js.map +1 -0
  37. package/lib/esm/env/index.js +2 -2
  38. package/lib/esm/env/index.js.map +1 -1
  39. package/lib/esm/features/agent/PayloadBuilder.js +80 -55
  40. package/lib/esm/features/agent/PayloadBuilder.js.map +1 -1
  41. package/lib/esm/features/agent/chat/ModernAgentConversation.js +22 -24
  42. package/lib/esm/features/agent/chat/ModernAgentConversation.js.map +1 -1
  43. package/lib/esm/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +2 -3
  44. package/lib/esm/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
  45. package/lib/esm/features/agent/chat/ModernAgentOutput/Header.js +2 -2
  46. package/lib/esm/features/agent/chat/ModernAgentOutput/Header.js.map +1 -1
  47. package/lib/esm/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.js +15 -20
  48. package/lib/esm/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.js.map +1 -1
  49. package/lib/esm/features/agent/chat/ModernAgentOutput/PlanPanel.js +1 -0
  50. package/lib/esm/features/agent/chat/ModernAgentOutput/PlanPanel.js.map +1 -1
  51. package/lib/esm/features/agent/chat/ModernAgentOutput/SlidingPlanPanel.js +3 -3
  52. package/lib/esm/features/agent/chat/ModernAgentOutput/SlidingPlanPanel.js.map +1 -1
  53. package/lib/esm/features/agent/chat/ModernAgentOutput/WorkstreamTabs.js +6 -6
  54. package/lib/esm/features/agent/chat/ModernAgentOutput/WorkstreamTabs.js.map +1 -1
  55. package/lib/esm/features/facets/CollectionsFacetsNav.js +19 -0
  56. package/lib/esm/features/facets/CollectionsFacetsNav.js.map +1 -1
  57. package/lib/esm/features/facets/InteractionsFacetsNav.js +9 -3
  58. package/lib/esm/features/facets/InteractionsFacetsNav.js.map +1 -1
  59. package/lib/esm/features/facets/utils/VTypeFacet.js +4 -1
  60. package/lib/esm/features/facets/utils/VTypeFacet.js.map +1 -1
  61. package/lib/esm/features/layout/GenericPageNavHeader.js +58 -5
  62. package/lib/esm/features/layout/GenericPageNavHeader.js.map +1 -1
  63. package/lib/esm/features/store/collections/BrowseCollectionView.js +3 -0
  64. package/lib/esm/features/store/collections/BrowseCollectionView.js.map +1 -1
  65. package/lib/esm/features/store/collections/CreateCollection.js +2 -2
  66. package/lib/esm/features/store/collections/CreateCollection.js.map +1 -1
  67. package/lib/esm/features/store/collections/EditCollectionView.js +39 -29
  68. package/lib/esm/features/store/collections/EditCollectionView.js.map +1 -1
  69. package/lib/esm/features/store/collections/SelectCollection.js +82 -16
  70. package/lib/esm/features/store/collections/SelectCollection.js.map +1 -1
  71. package/lib/esm/features/store/collections/SharedPropsEditor.js +40 -0
  72. package/lib/esm/features/store/collections/SharedPropsEditor.js.map +1 -0
  73. package/lib/esm/features/store/collections/SyncMemberHeadsToggle.js +35 -0
  74. package/lib/esm/features/store/collections/SyncMemberHeadsToggle.js.map +1 -0
  75. package/lib/esm/features/store/collections/index.js +2 -0
  76. package/lib/esm/features/store/collections/index.js.map +1 -1
  77. package/lib/esm/features/store/objects/DocumentSearchResults.js +35 -9
  78. package/lib/esm/features/store/objects/DocumentSearchResults.js.map +1 -1
  79. package/lib/esm/features/store/objects/DocumentTable.js +6 -6
  80. package/lib/esm/features/store/objects/DocumentTable.js.map +1 -1
  81. package/lib/esm/features/store/objects/components/ContentOverview.js +158 -114
  82. package/lib/esm/features/store/objects/components/ContentOverview.js.map +1 -1
  83. package/lib/esm/features/store/objects/components/DocumentIcon.js +5 -3
  84. package/lib/esm/features/store/objects/components/DocumentIcon.js.map +1 -1
  85. package/lib/esm/features/store/objects/components/SaveVersionConfirmModal.js +11 -2
  86. package/lib/esm/features/store/objects/components/SaveVersionConfirmModal.js.map +1 -1
  87. package/lib/esm/features/store/objects/components/useDownloadObject.js +2 -2
  88. package/lib/esm/features/store/objects/components/useDownloadObject.js.map +1 -1
  89. package/lib/esm/features/store/objects/layout/DocumentTableColumn.js +13 -1
  90. package/lib/esm/features/store/objects/layout/DocumentTableColumn.js.map +1 -1
  91. package/lib/esm/features/store/objects/layout/documentLayout.js +5 -5
  92. package/lib/esm/features/store/objects/layout/documentLayout.js.map +1 -1
  93. package/lib/esm/features/store/objects/layout/renderers.js +28 -12
  94. package/lib/esm/features/store/objects/layout/renderers.js.map +1 -1
  95. package/lib/esm/features/store/objects/search/DocumentSearchContext.js +5 -1
  96. package/lib/esm/features/store/objects/search/DocumentSearchContext.js.map +1 -1
  97. package/lib/esm/features/store/objects/search/DocumentSearchProvider.js +1 -1
  98. package/lib/esm/features/store/objects/search/DocumentSearchProvider.js.map +1 -1
  99. package/lib/esm/features/store/objects/selection/ObjectsActionContext.js +3 -2
  100. package/lib/esm/features/store/objects/selection/ObjectsActionContext.js.map +1 -1
  101. package/lib/esm/features/store/objects/selection/SelectionActions.js +2 -0
  102. package/lib/esm/features/store/objects/selection/SelectionActions.js.map +1 -1
  103. package/lib/esm/features/store/objects/selection/actions/AddToCollectionAction.js +10 -2
  104. package/lib/esm/features/store/objects/selection/actions/AddToCollectionAction.js.map +1 -1
  105. package/lib/esm/features/store/objects/selection/actions/DeleteObjectsAction.js +20 -2
  106. package/lib/esm/features/store/objects/selection/actions/DeleteObjectsAction.js.map +1 -1
  107. package/lib/esm/features/store/objects/upload/DocumentUploadModal.js +15 -7
  108. package/lib/esm/features/store/objects/upload/DocumentUploadModal.js.map +1 -1
  109. package/lib/esm/features/store/objects/upload/useSmartFileUploadProcessing.js +10 -9
  110. package/lib/esm/features/store/objects/upload/useSmartFileUploadProcessing.js.map +1 -1
  111. package/lib/esm/features/store/types/CreateOrUpdateTypeModal.js +1 -1
  112. package/lib/esm/features/store/types/CreateOrUpdateTypeModal.js.map +1 -1
  113. package/lib/esm/features/user/UserInfo.js +2 -0
  114. package/lib/esm/features/user/UserInfo.js.map +1 -1
  115. package/lib/esm/router/HistoryNavigator.js +25 -2
  116. package/lib/esm/router/HistoryNavigator.js.map +1 -1
  117. package/lib/esm/router/Nav.js +3 -3
  118. package/lib/esm/router/Nav.js.map +1 -1
  119. package/lib/esm/session/UserSession.js +1 -0
  120. package/lib/esm/session/UserSession.js.map +1 -1
  121. package/lib/esm/session/UserSessionProvider.js +9 -2
  122. package/lib/esm/session/UserSessionProvider.js.map +1 -1
  123. package/lib/esm/session/auth/composable.js +66 -67
  124. package/lib/esm/session/auth/composable.js.map +1 -1
  125. package/lib/esm/shell/apps/AppProjectSelector.js +2 -2
  126. package/lib/esm/shell/apps/AppProjectSelector.js.map +1 -1
  127. package/lib/esm/widgets/form/Form.js +17 -30
  128. package/lib/esm/widgets/form/Form.js.map +1 -1
  129. package/lib/esm/widgets/form/FormContext.js +4 -2
  130. package/lib/esm/widgets/form/FormContext.js.map +1 -1
  131. package/lib/esm/widgets/form/ManagedObject.js +4 -0
  132. package/lib/esm/widgets/form/ManagedObject.js.map +1 -1
  133. package/lib/esm/widgets/form/fields.js +4 -3
  134. package/lib/esm/widgets/form/fields.js.map +1 -1
  135. package/lib/esm/widgets/form/inputs.js +2 -0
  136. package/lib/esm/widgets/form/inputs.js.map +1 -1
  137. package/lib/tsconfig.tsbuildinfo +1 -1
  138. package/lib/types/core/components/Panel.d.ts +11 -0
  139. package/lib/types/core/components/Panel.d.ts.map +1 -0
  140. package/lib/types/core/components/SidePanel.d.ts.map +1 -1
  141. package/lib/types/core/components/TagsInput.d.ts +16 -0
  142. package/lib/types/core/components/TagsInput.d.ts.map +1 -0
  143. package/lib/types/core/components/index.d.ts +2 -1
  144. package/lib/types/core/components/index.d.ts.map +1 -1
  145. package/lib/types/core/components/shadcn/breadcrumb.d.ts +3 -2
  146. package/lib/types/core/components/shadcn/breadcrumb.d.ts.map +1 -1
  147. package/lib/types/core/components/shadcn/button.d.ts.map +1 -1
  148. package/lib/types/core/components/shadcn/filters/filterBar.d.ts.map +1 -1
  149. package/lib/types/core/components/shadcn/index.d.ts +1 -0
  150. package/lib/types/core/components/shadcn/index.d.ts.map +1 -1
  151. package/lib/types/core/components/shadcn/input.d.ts.map +1 -1
  152. package/lib/types/core/components/shadcn/popover.d.ts +7 -0
  153. package/lib/types/core/components/shadcn/popover.d.ts.map +1 -1
  154. package/lib/types/core/components/shadcn/selectBox.d.ts +3 -2
  155. package/lib/types/core/components/shadcn/selectBox.d.ts.map +1 -1
  156. package/lib/types/core/components/shadcn/tabs.d.ts.map +1 -1
  157. package/lib/types/core/components/shadcn/textarea.d.ts +4 -0
  158. package/lib/types/core/components/shadcn/textarea.d.ts.map +1 -0
  159. package/lib/types/core/hooks/CompositeState.d.ts +115 -6
  160. package/lib/types/core/hooks/CompositeState.d.ts.map +1 -1
  161. package/lib/types/core/hooks/index.d.ts +1 -0
  162. package/lib/types/core/hooks/index.d.ts.map +1 -1
  163. package/lib/types/core/hooks/useScrollableSearch.d.ts +82 -0
  164. package/lib/types/core/hooks/useScrollableSearch.d.ts.map +1 -0
  165. package/lib/types/env/index.d.ts +3 -1
  166. package/lib/types/env/index.d.ts.map +1 -1
  167. package/lib/types/features/agent/PayloadBuilder.d.ts +11 -19
  168. package/lib/types/features/agent/PayloadBuilder.d.ts.map +1 -1
  169. package/lib/types/features/agent/chat/ModernAgentConversation.d.ts.map +1 -1
  170. package/lib/types/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts +1 -1
  171. package/lib/types/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts.map +1 -1
  172. package/lib/types/features/agent/chat/ModernAgentOutput/Header.d.ts.map +1 -1
  173. package/lib/types/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.d.ts.map +1 -1
  174. package/lib/types/features/agent/chat/ModernAgentOutput/PlanPanel.d.ts.map +1 -1
  175. package/lib/types/features/facets/CollectionsFacetsNav.d.ts.map +1 -1
  176. package/lib/types/features/facets/InteractionsFacetsNav.d.ts +1 -0
  177. package/lib/types/features/facets/InteractionsFacetsNav.d.ts.map +1 -1
  178. package/lib/types/features/facets/utils/SearchInterface.d.ts +6 -1
  179. package/lib/types/features/facets/utils/SearchInterface.d.ts.map +1 -1
  180. package/lib/types/features/facets/utils/VTypeFacet.d.ts +2 -1
  181. package/lib/types/features/facets/utils/VTypeFacet.d.ts.map +1 -1
  182. package/lib/types/features/layout/GenericPageNavHeader.d.ts +2 -1
  183. package/lib/types/features/layout/GenericPageNavHeader.d.ts.map +1 -1
  184. package/lib/types/features/store/collections/BrowseCollectionView.d.ts.map +1 -1
  185. package/lib/types/features/store/collections/CreateCollection.d.ts.map +1 -1
  186. package/lib/types/features/store/collections/EditCollectionView.d.ts.map +1 -1
  187. package/lib/types/features/store/collections/SelectCollection.d.ts +6 -3
  188. package/lib/types/features/store/collections/SelectCollection.d.ts.map +1 -1
  189. package/lib/types/features/store/collections/SharedPropsEditor.d.ts +7 -0
  190. package/lib/types/features/store/collections/SharedPropsEditor.d.ts.map +1 -0
  191. package/lib/types/features/store/collections/SyncMemberHeadsToggle.d.ts +7 -0
  192. package/lib/types/features/store/collections/SyncMemberHeadsToggle.d.ts.map +1 -0
  193. package/lib/types/features/store/collections/index.d.ts +2 -0
  194. package/lib/types/features/store/collections/index.d.ts.map +1 -1
  195. package/lib/types/features/store/objects/DocumentSearchResults.d.ts.map +1 -1
  196. package/lib/types/features/store/objects/DocumentTable.d.ts +4 -0
  197. package/lib/types/features/store/objects/DocumentTable.d.ts.map +1 -1
  198. package/lib/types/features/store/objects/components/ContentOverview.d.ts.map +1 -1
  199. package/lib/types/features/store/objects/components/DocumentIcon.d.ts +3 -1
  200. package/lib/types/features/store/objects/components/DocumentIcon.d.ts.map +1 -1
  201. package/lib/types/features/store/objects/components/SaveVersionConfirmModal.d.ts.map +1 -1
  202. package/lib/types/features/store/objects/components/useDownloadObject.d.ts +1 -1
  203. package/lib/types/features/store/objects/components/useDownloadObject.d.ts.map +1 -1
  204. package/lib/types/features/store/objects/layout/DocumentTableColumn.d.ts +2 -1
  205. package/lib/types/features/store/objects/layout/DocumentTableColumn.d.ts.map +1 -1
  206. package/lib/types/features/store/objects/layout/documentLayout.d.ts +4 -2
  207. package/lib/types/features/store/objects/layout/documentLayout.d.ts.map +1 -1
  208. package/lib/types/features/store/objects/layout/renderers.d.ts +1 -1
  209. package/lib/types/features/store/objects/layout/renderers.d.ts.map +1 -1
  210. package/lib/types/features/store/objects/search/DocumentSearchContext.d.ts +1 -0
  211. package/lib/types/features/store/objects/search/DocumentSearchContext.d.ts.map +1 -1
  212. package/lib/types/features/store/objects/selection/ObjectsActionContext.d.ts.map +1 -1
  213. package/lib/types/features/store/objects/selection/SelectionActions.d.ts.map +1 -1
  214. package/lib/types/features/store/objects/selection/actions/DeleteObjectsAction.d.ts +1 -0
  215. package/lib/types/features/store/objects/selection/actions/DeleteObjectsAction.d.ts.map +1 -1
  216. package/lib/types/features/store/objects/upload/DocumentUploadModal.d.ts.map +1 -1
  217. package/lib/types/features/store/objects/upload/useSmartFileUploadProcessing.d.ts.map +1 -1
  218. package/lib/types/features/user/UserInfo.d.ts.map +1 -1
  219. package/lib/types/router/HistoryNavigator.d.ts.map +1 -1
  220. package/lib/types/router/Nav.d.ts +2 -1
  221. package/lib/types/router/Nav.d.ts.map +1 -1
  222. package/lib/types/session/UserSession.d.ts.map +1 -1
  223. package/lib/types/session/UserSessionProvider.d.ts.map +1 -1
  224. package/lib/types/session/auth/composable.d.ts.map +1 -1
  225. package/lib/types/widgets/form/Form.d.ts +2 -1
  226. package/lib/types/widgets/form/Form.d.ts.map +1 -1
  227. package/lib/types/widgets/form/FormContext.d.ts +5 -2
  228. package/lib/types/widgets/form/FormContext.d.ts.map +1 -1
  229. package/lib/types/widgets/form/ManagedObject.d.ts.map +1 -1
  230. package/lib/types/widgets/form/fields.d.ts +2 -2
  231. package/lib/types/widgets/form/fields.d.ts.map +1 -1
  232. package/lib/types/widgets/form/inputs.d.ts.map +1 -1
  233. package/lib/vertesia-ui-core.js +1 -1
  234. package/lib/vertesia-ui-core.js.map +1 -1
  235. package/lib/vertesia-ui-env.js +1 -1
  236. package/lib/vertesia-ui-env.js.map +1 -1
  237. package/lib/vertesia-ui-features.js +1 -1
  238. package/lib/vertesia-ui-features.js.map +1 -1
  239. package/lib/vertesia-ui-router.js +1 -1
  240. package/lib/vertesia-ui-router.js.map +1 -1
  241. package/lib/vertesia-ui-session.js +1 -1
  242. package/lib/vertesia-ui-session.js.map +1 -1
  243. package/lib/vertesia-ui-shell.js +1 -1
  244. package/lib/vertesia-ui-shell.js.map +1 -1
  245. package/lib/vertesia-ui-widgets.js +1 -1
  246. package/lib/vertesia-ui-widgets.js.map +1 -1
  247. package/package.json +4 -4
  248. package/src/core/components/Panel.tsx +34 -0
  249. package/src/core/components/SidePanel.tsx +5 -3
  250. package/src/core/components/index.ts +1 -1
  251. package/src/core/components/shadcn/breadcrumb.tsx +49 -30
  252. package/src/core/components/shadcn/button.tsx +3 -2
  253. package/src/core/components/shadcn/filters/filterBar.tsx +3 -3
  254. package/src/core/components/shadcn/index.ts +2 -1
  255. package/src/core/components/shadcn/input.tsx +10 -7
  256. package/src/core/components/shadcn/resizeable.tsx +4 -4
  257. package/src/core/components/shadcn/selectBox.tsx +87 -67
  258. package/src/core/components/shadcn/tabs.tsx +10 -3
  259. package/src/core/components/shadcn/textarea.tsx +21 -0
  260. package/src/core/hooks/index.ts +1 -0
  261. package/src/core/hooks/useScrollableSearch.tsx +193 -0
  262. package/src/env/index.ts +1 -1
  263. package/src/features/agent/chat/ModernAgentConversation.tsx +109 -118
  264. package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +2 -22
  265. package/src/features/agent/chat/ModernAgentOutput/Header.tsx +1 -9
  266. package/src/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.tsx +39 -55
  267. package/src/features/agent/chat/ModernAgentOutput/PlanPanel.tsx +1 -0
  268. package/src/features/agent/chat/ModernAgentOutput/SlidingPlanPanel.tsx +8 -8
  269. package/src/features/agent/chat/ModernAgentOutput/WorkstreamTabs.tsx +8 -8
  270. package/src/features/facets/CollectionsFacetsNav.tsx +21 -0
  271. package/src/features/facets/InteractionsFacetsNav.tsx +13 -3
  272. package/src/features/facets/utils/SearchInterface.tsx +5 -1
  273. package/src/features/facets/utils/VTypeFacet.tsx +6 -2
  274. package/src/features/layout/GenericPageNavHeader.tsx +73 -10
  275. package/src/features/store/collections/BrowseCollectionView.tsx +4 -0
  276. package/src/features/store/collections/CreateCollection.tsx +3 -4
  277. package/src/features/store/collections/EditCollectionView.tsx +91 -85
  278. package/src/features/store/collections/SelectCollection.tsx +105 -49
  279. package/src/features/store/objects/DocumentSearchResults.tsx +117 -51
  280. package/src/features/store/objects/DocumentTable.tsx +14 -4
  281. package/src/features/store/objects/components/ContentOverview.tsx +208 -110
  282. package/src/features/store/objects/components/DocumentIcon.tsx +11 -12
  283. package/src/features/store/objects/components/SaveVersionConfirmModal.tsx +12 -2
  284. package/src/features/store/objects/layout/DocumentTableColumn.tsx +16 -1
  285. package/src/features/store/objects/layout/documentLayout.tsx +7 -5
  286. package/src/features/store/objects/layout/knowledge.md +10 -10
  287. package/src/features/store/objects/layout/renderers.tsx +39 -18
  288. package/src/features/store/objects/search/DocumentSearchContext.ts +6 -1
  289. package/src/features/store/objects/search/DocumentSearchProvider.tsx +1 -1
  290. package/src/features/store/objects/selection/ObjectsActionContext.tsx +3 -2
  291. package/src/features/store/objects/selection/SelectionActions.tsx +2 -0
  292. package/src/features/store/objects/selection/actions/AddToCollectionAction.tsx +8 -2
  293. package/src/features/store/objects/selection/actions/DeleteObjectsAction.tsx +22 -2
  294. package/src/features/store/objects/upload/DocumentUploadModal.tsx +18 -9
  295. package/src/features/store/objects/upload/useSmartFileUploadProcessing.ts +11 -10
  296. package/src/features/store/types/CreateOrUpdateTypeModal.tsx +1 -1
  297. package/src/router/HistoryNavigator.ts +33 -2
  298. package/src/router/Nav.tsx +4 -3
  299. package/src/widgets/form/Form.tsx +19 -43
  300. package/src/widgets/form/FormContext.ts +5 -2
  301. package/src/widgets/form/fields.tsx +8 -6
  302. package/src/widgets/form/inputs.tsx +1 -0
  303. package/lib/esm/core/components/Textarea.js +0 -15
  304. package/lib/esm/core/components/Textarea.js.map +0 -1
  305. package/lib/types/core/components/Textarea.d.ts +0 -8
  306. package/lib/types/core/components/Textarea.d.ts.map +0 -1
  307. package/src/core/components/Textarea.tsx +0 -25
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vertesia/ui",
3
- "version": "0.79.0",
3
+ "version": "0.79.2",
4
4
  "description": "Vertesia UI components and and hooks",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -61,9 +61,9 @@
61
61
  "tailwind-merge": "^3.3.0",
62
62
  "ts-md5": "^1.3.1",
63
63
  "unist-util-visit": "^5.0.0",
64
- "@vertesia/client": "0.79.0",
65
- "@vertesia/json": "0.79.0",
66
- "@vertesia/common": "0.79.0"
64
+ "@vertesia/client": "0.79.2",
65
+ "@vertesia/common": "0.79.2",
66
+ "@vertesia/json": "0.79.2"
67
67
  },
68
68
  "devDependencies": {
69
69
  "@eslint/js": "^9.27.0",
@@ -0,0 +1,34 @@
1
+ import { VTooltip } from "./shadcn/tooltip"
2
+ import { Info } from "lucide-react"
3
+
4
+ interface PanelProps {
5
+ title: string | React.ReactNode
6
+ description?: React.ReactNode
7
+ action?: React.ReactNode
8
+ children: React.ReactNode
9
+ footer?: string | React.ReactNode
10
+ className?: string
11
+ }
12
+
13
+ export function Panel({ children, action, title, description, footer, className }: PanelProps) {
14
+
15
+ return (
16
+ <div className={`p-4 flex flex-col gap-2 rounded-sm border bg-card ${className}`}>
17
+ <div className="flex items-center justify-between">
18
+ <div className="flex items-center gap-2">
19
+ <div className="font-semibold text-lg">
20
+ {title}
21
+ </div>
22
+ {description && <VTooltip description={description}><Info className="size-4 text-muted" /></VTooltip>}
23
+ </div>
24
+ {action}
25
+ </div>
26
+
27
+ {children}
28
+ {footer &&
29
+ <div className="border-t border-muted flex flex-col-2 text-sm pt-4">
30
+ {footer}
31
+ </div>}
32
+ </div>
33
+ )
34
+ }
@@ -1,6 +1,6 @@
1
1
  import { useState } from 'react';
2
2
  import { motion, AnimatePresence } from 'framer-motion';
3
- import { X } from 'lucide-react';
3
+ import { Minus, X } from 'lucide-react';
4
4
  import { Button } from './shadcn/button';
5
5
 
6
6
  interface SidePanelProps {
@@ -68,9 +68,11 @@ export function SidePanel({ isOpen, title, onClose, children, panelWidth = 768,
68
68
  <div className="relative flex h-full">
69
69
  {/* Drag Handle */}
70
70
  <div
71
- className="absolute left-0 top-0 bottom-0 w-1 cursor-ew-resize hover:bg-indigo-500 transition-colors"
71
+ className="absolute -left-1 top-0 bottom-0 w-3 cursor-ew-resize hover:bg-indigo-500 transition-colors flex items-center justify-center"
72
72
  onMouseDown={handleDragStart}
73
- />
73
+ >
74
+ <Minus className="rotate-90 font-semibold" strokeWidth={4} />
75
+ </div>
74
76
  <div className="flex-1 flex flex-col overflow-y-scroll gap-4 bg-background py-2 shadow-xl">
75
77
  {title && (
76
78
  <div className="px-2 sm:px-4">
@@ -26,12 +26,12 @@ export * from "./SelectList.js";
26
26
  export * from "./SelectStack.js";
27
27
  export * from "./shadcn/index.js";
28
28
  export * from "./SidePanel.js";
29
+ export * from "./Panel.js";
29
30
  export * from "./Spinner.js";
30
31
  export * from "./styles.js";
31
32
  export * from "./Switch.js";
32
33
  export * from "./table/index.js";
33
34
  export * from "./tabs/index.js";
34
- export * from "./Textarea.js";
35
35
  export * from "./toast/index.js";
36
36
 
37
37
  export type HeroIcon = React.ForwardRefExoticComponent<Omit<React.SVGProps<SVGSVGElement>, "ref"> & {
@@ -6,28 +6,37 @@ import { cn } from "../libs/utils"
6
6
  interface BreadcrumbProps {
7
7
  label: string
8
8
  href?: string
9
+ onClick?: () => void
9
10
  }
10
11
  interface BreadcrumbItemProps {
11
- children: BreadcrumbProps[]
12
+ path: BreadcrumbProps[]
12
13
  className?: string
13
14
  maxItems?: number
14
15
  separator?: React.ReactNode
15
16
  }
16
- export function Breadcrumbs({ children, maxItems = 3, className, separator }: BreadcrumbItemProps) {
17
- if (children.length <= maxItems) {
17
+ export function Breadcrumbs({ path, maxItems = 3, className, separator }: BreadcrumbItemProps) {
18
+ const items = path || [];
19
+
20
+ const renderBreadcrumbItem = (item: BreadcrumbProps) => {
21
+ if (item.onClick) {
22
+ return <BreadcrumbButton onClick={item.onClick} href={item.href}>{item.label}</BreadcrumbButton>;
23
+ } else if (item.href) {
24
+ return <BreadcrumbButton href={item.href}>{item.label}</BreadcrumbButton>;
25
+ } else {
26
+ return <BreadcrumbPage>{item.label}</BreadcrumbPage>;
27
+ }
28
+ };
29
+
30
+ if (items.length <= maxItems) {
18
31
  return (
19
32
  <Breadcrumb className={cn("w-full", className)}>
20
33
  <BreadcrumbList>
21
- {children.map((item, index) => (
34
+ {items.map((item, index) => (
22
35
  <React.Fragment key={index}>
23
36
  <BreadcrumbItem>
24
- {item.href ? (
25
- <BreadcrumbLink href={item.href}>{item.label}</BreadcrumbLink>
26
- ) : (
27
- <BreadcrumbPage>{item.label}</BreadcrumbPage>
28
- )}
37
+ {renderBreadcrumbItem(item)}
29
38
  </BreadcrumbItem>
30
- {index < children.length - 1 &&
39
+ {index < items.length - 1 &&
31
40
  <BreadcrumbSeparator>{separator ?? <ChevronRight />}</BreadcrumbSeparator>
32
41
  }
33
42
  </React.Fragment>
@@ -37,36 +46,22 @@ export function Breadcrumbs({ children, maxItems = 3, className, separator }: Br
37
46
  );
38
47
  }
39
48
 
40
- const firstItem = children[0];
41
- const lastItems = children.slice(-(maxItems - 2));
49
+ const lastThreeItems = items.slice(-(maxItems - 1));
42
50
 
43
51
  return (
44
52
  <Breadcrumb className={cn("w-full", className)}>
45
53
  <BreadcrumbList>
46
- <BreadcrumbItem>
47
- {firstItem.href ? (
48
- <BreadcrumbLink href={firstItem.href}>{firstItem.label}</BreadcrumbLink>
49
- ) : (
50
- <BreadcrumbPage>{firstItem.label}</BreadcrumbPage>
51
- )}
52
- </BreadcrumbItem>
53
- <BreadcrumbSeparator>{separator ?? <ChevronRight />}</BreadcrumbSeparator>
54
-
55
54
  <BreadcrumbItem>
56
55
  <BreadcrumbEllipsis />
57
56
  </BreadcrumbItem>
58
57
  <BreadcrumbSeparator>{separator ?? <ChevronRight />}</BreadcrumbSeparator>
59
58
 
60
- {lastItems.map((item, index) => (
59
+ {lastThreeItems.map((item, index) => (
61
60
  <React.Fragment key={index}>
62
61
  <BreadcrumbItem>
63
- {item.href ? (
64
- <BreadcrumbLink href={item.href}>{item.label}</BreadcrumbLink>
65
- ) : (
66
- <BreadcrumbPage>{item.label}</BreadcrumbPage>
67
- )}
62
+ {renderBreadcrumbItem(item)}
68
63
  </BreadcrumbItem>
69
- {index < lastItems.length - 1 && <BreadcrumbSeparator>{separator ?? <ChevronRight />}</BreadcrumbSeparator>
64
+ {index < lastThreeItems.length - 1 && <BreadcrumbSeparator>{separator ?? <ChevronRight />}</BreadcrumbSeparator>
70
65
  }
71
66
  </React.Fragment>
72
67
  ))}
@@ -104,7 +99,7 @@ const BreadcrumbItem = React.forwardRef<
104
99
  >(({ className, ...props }, ref) => (
105
100
  <li
106
101
  ref={ref}
107
- className={cn("inline-flex items-center gap-1.5", className)}
102
+ className={cn("inline-flex items-center gap-1.5 text-muted", className)}
108
103
  {...props}
109
104
  />
110
105
  ))
@@ -119,13 +114,37 @@ const BreadcrumbLink = React.forwardRef<
119
114
  return (
120
115
  <a
121
116
  ref={ref}
122
- className={cn("transition-colors hover:text-foreground", className)}
117
+ className={cn("transition-colors hover:text-muted", className)}
123
118
  {...props}
124
119
  />
125
120
  )
126
121
  })
127
122
  BreadcrumbLink.displayName = "BreadcrumbLink"
128
123
 
124
+ const BreadcrumbButton = React.forwardRef<
125
+ HTMLButtonElement,
126
+ React.ComponentPropsWithoutRef<"button"> & {
127
+ href?: string
128
+ }
129
+ >(({ className, href, onClick, ...props }, ref) => {
130
+ const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
131
+ e.preventDefault();
132
+ if (onClick) {
133
+ onClick(e);
134
+ }
135
+ };
136
+
137
+ return (
138
+ <button
139
+ ref={ref}
140
+ className={cn("transition-colors hover:text-foreground cursor-pointer", className)}
141
+ onClick={handleClick}
142
+ {...props}
143
+ />
144
+ );
145
+ })
146
+ BreadcrumbButton.displayName = "BreadcrumbButton"
147
+
129
148
  const BreadcrumbPage = React.forwardRef<
130
149
  HTMLSpanElement,
131
150
  React.ComponentPropsWithoutRef<"span">
@@ -20,7 +20,7 @@ const buttonVariants = cva(
20
20
  secondary:
21
21
  "bg-primary/5 dark:bg-primary/10 text-primary shadow-xs hover:bg-primary/10 dark:hover:bg-primary/20 ring-inset",
22
22
  ghost: "hover:bg-muted/50 dark:hover:bg-muted/20 ring-inset",
23
- link: "text-white underline-offset-4 hover:underline ring-inset",
23
+ link: "text-foreground underline-offset-4 hover:underline ring-inset",
24
24
  primary:
25
25
  "bg-primary text-white shadow-xs hover:bg-primary/90 ring-inset",
26
26
  unstyled:
@@ -108,7 +108,8 @@ const CopyButton = React.forwardRef<HTMLButtonElement, CopyButtonProps>(
108
108
 
109
109
  const [isCopied, setIsCopied] = useState(false);
110
110
 
111
- const handleCopy = () => {
111
+ const handleCopy = (e: React.MouseEvent) => {
112
+ e.stopPropagation();
112
113
  navigator.clipboard.writeText(content).then(() => {
113
114
  setIsCopied(true)
114
115
  setTimeout(() => setIsCopied(false), 2000)
@@ -71,8 +71,8 @@ const FilterProvider = ({ filters, setFilters, filterGroups, children }: FilterP
71
71
  params.delete('filters');
72
72
  }
73
73
 
74
- const newUrl = `${window.location.pathname}?${params.toString()}`;
75
- window.history.replaceState({}, '', newUrl);
74
+ const newUrl = `${window.location.pathname}?${params.toString()}${window.location.hash}`;
75
+ window.history.replaceState(window.history.state || {}, '', newUrl);
76
76
  } catch (error) {
77
77
  console.error("Failed to update URL with filters:", error);
78
78
  }
@@ -350,7 +350,7 @@ const FilterBar = ({ className }: { className?: string }) => {
350
350
  );
351
351
  };
352
352
 
353
- const FilterClear = ({ className }: { className?: string }) => {
353
+ const FilterClear = ({ className }: { className?: string}) => {
354
354
  const { filters, setFilters } = React.useContext(FilterContext);
355
355
 
356
356
  const hasActiveFilters = filters.filter((filter) => filter.value?.length > 0).length > 0;
@@ -20,4 +20,5 @@ export * from './command';
20
20
  export * from './checkbox';
21
21
  export * from './heading';
22
22
  export * from './text';
23
- export * from './resizeable';
23
+ export * from './resizeable';
24
+ export * from './textarea';
@@ -4,6 +4,7 @@ import { cva, type VariantProps } from "class-variance-authority"
4
4
  import { cn } from "../libs/utils"
5
5
  import { X } from "lucide-react";
6
6
  import { ChangeEvent } from "react";
7
+ import { Button } from "@vertesia/ui/core";
7
8
 
8
9
  const variants = cva(
9
10
  "",
@@ -53,14 +54,14 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
53
54
  };
54
55
 
55
56
  return (
56
- <div className="w-full" style={{ position: 'relative', display: 'inline-block' }}>
57
+ <div className="w-full relative inline-block [&:hover_.clear-button]:opacity-100">
57
58
  <input
58
59
  type={type}
59
60
  className={
60
61
  cn(
61
62
  variants({ size, variant }),
62
63
  className,
63
- clearable && value ? "pr-6" : "",
64
+ clearable && value ? "pr-8" : "",
64
65
  )}
65
66
  ref={ref}
66
67
  value={value == null ? '' : value}
@@ -68,14 +69,16 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
68
69
  {...props}
69
70
  />
70
71
  {clearable && value && !props.readOnly && !props.disabled && (
71
- <button
72
- onClick={_onClear}
73
- className={`absolute ${type !== 'number' ? 'right-0' : 'right-7'} top-1/2 -translate-y-1/2 size-7 text-muted-foreground hover:text-destructive cursor-pointer flex items-center justify-center`}
72
+ <Button variant={"link"} size={"icon"}
74
73
  type="button"
75
- aria-label="Clear input"
74
+ onClick={_onClear}
75
+ className={`clear-button opacity-0 transition-opacity duration-200
76
+ absolute top-1/2 -translate-y-1/2 text-muted !hover:text-destructive cursor-pointer
77
+ flex items-center justify-center size-6 rounded right-2`}
78
+ alt="Clear input"
76
79
  >
77
80
  <X size={16} />
78
- </button>
81
+ </Button>
79
82
  )}
80
83
  </div>
81
84
  )
@@ -1,5 +1,5 @@
1
1
  import * as React from "react"
2
- import { GripVerticalIcon } from "lucide-react"
2
+ import { Minus } from "lucide-react"
3
3
  import * as ResizablePrimitive from "react-resizable-panels"
4
4
 
5
5
  import { cn } from "../libs/utils"
@@ -37,14 +37,14 @@ function ResizableHandle({
37
37
  <ResizablePrimitive.PanelResizeHandle
38
38
  data-slot="resizable-handle"
39
39
  className={cn(
40
- "bg-border focus-visible:ring-ring relative flex w-px items-center justify-center after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-offset-1 focus-visible:outline-hidden data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:translate-x-0 data-[panel-group-direction=vertical]:after:-translate-y-1/2 [&[data-panel-group-direction=vertical]>div]:rotate-90",
40
+ "bg-muted focus-visible:ring-ring relative flex w-px items-center justify-center after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-offset-1 focus-visible:outline-hidden data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:translate-x-0 data-[panel-group-direction=vertical]:after:-translate-y-1/2 [&[data-panel-group-direction=vertical]>div]:rotate-90",
41
41
  className
42
42
  )}
43
43
  {...props}
44
44
  >
45
45
  {withHandle && (
46
- <div className="bg-border z-10 flex h-4 w-3 items-center justify-center rounded-xs border">
47
- <GripVerticalIcon className="size-2.5" />
46
+ <div className="z-10 flex size-4 items-center justify-center rounded-xs font-semibold">
47
+ <Minus className="size-4 rotate-90" />
48
48
  </div>
49
49
  )}
50
50
  </ResizablePrimitive.PanelResizeHandle>
@@ -6,8 +6,9 @@ import { useState, useEffect, useRef } from 'react';
6
6
  import { Popover, PopoverContent, PopoverTrigger, PopoverClose } from './popover';
7
7
  import { Command, CommandEmpty, CommandGroup, CommandItem, CommandList } from './command';
8
8
  import { Input } from './input';
9
+ import { Button } from '@vertesia/ui/core';
9
10
 
10
- interface VSelectBoxBaseProps<T> {
11
+ export interface VSelectBoxBaseProps<T> {
11
12
  options: T[] | undefined;
12
13
  optionLabel?: (option: T) => React.ReactNode;
13
14
  onBlur?: () => void;
@@ -23,6 +24,7 @@ interface VSelectBoxBaseProps<T> {
23
24
  popupClass?: string;
24
25
  isClearable?: boolean;
25
26
  border?: boolean;
27
+ inline?: boolean;
26
28
  }
27
29
 
28
30
  interface VSelectBoxSingleProps<T> extends VSelectBoxBaseProps<T> {
@@ -39,7 +41,7 @@ interface VSelectBoxMultipleProps<T> extends VSelectBoxBaseProps<T> {
39
41
 
40
42
  type VSelectBoxProps<T> = VSelectBoxSingleProps<T> | VSelectBoxMultipleProps<T>;
41
43
 
42
- export function VSelectBox<T = any>({ options, optionLabel, value, onChange, addNew, addNewLabel, disabled, filterBy, label, placeholder, className, popupClass, isClearable, border = true, multiple = false, by }: Readonly<VSelectBoxProps<T>>) {
44
+ export function VSelectBox<T = any>({ options, optionLabel, value, onChange, addNew, addNewLabel, disabled, filterBy, label, placeholder, className, popupClass, isClearable, border = true, multiple = false, by, inline = false }: Readonly<VSelectBoxProps<T>>) {
43
45
  const triggerRef = useRef<HTMLDivElement>(null);
44
46
  const [open, setOpen] = useState(false);
45
47
  const [width, setWidth] = useState<number>(0);
@@ -169,6 +171,82 @@ export function VSelectBox<T = any>({ options, optionLabel, value, onChange, add
169
171
  );
170
172
  };
171
173
 
174
+ // Render the options list content
175
+ const renderOptionsContent = () => (
176
+ <>
177
+ {filterBy && (
178
+ <div className='flex justify-start items-center mb-1'>
179
+ <div className='mx-2'>
180
+ <SearchIcon className="size-4" />
181
+ </div>
182
+ <Input variant='unstyled' value={filterValue} onChange={setFilterValue} className="w-full p-1 rounded-md" placeholder="Search..." />
183
+ </div>
184
+ )}
185
+ <Command className="overflow-hidden">
186
+ <CommandList className={inline ? "max-h-full overflow-y-auto" : "max-h-[200px] overflow-y-auto"}>
187
+ <CommandEmpty>No result found.</CommandEmpty>
188
+ <CommandGroup className="overflow-visible">
189
+ {filteredOptions?.map((opt, index) => {
190
+ const isSelected = multiple
191
+ ? isOptionSelected(opt, Array.isArray(value) ? value : [])
192
+ : value != null ? isOptionsEqual(value as T, opt) : false;
193
+
194
+ return (
195
+ <CommandItem
196
+ key={index}
197
+ onSelect={() => _onClick(opt)}
198
+ className="w-full"
199
+ >
200
+ {multiple || inline ? (
201
+ <div className='w-full flex justify-between items-center cursor-pointer'>
202
+ <div className='w-full truncate text-left'>
203
+ {optionLabel ? optionLabel(opt) : opt as String}
204
+ </div>
205
+ {isSelected && <Check className="size-4" />}
206
+ </div>
207
+ ) : (
208
+ <PopoverClose className='w-full flex justify-between items-center'>
209
+ <div className='w-full truncate text-left'>
210
+ {optionLabel ? optionLabel(opt) : opt as String}
211
+ </div>
212
+ {isSelected && <Check className="size-4" />}
213
+ </PopoverClose>
214
+ )}
215
+ </CommandItem>
216
+ );
217
+ })}
218
+ </CommandGroup>
219
+ </CommandList>
220
+ </Command>
221
+ {addNew && (
222
+ <div className='p-1'>
223
+ <a
224
+ onClick={addNew}
225
+ className={clsx(
226
+ 'gap-x-2 px-2 py-1.5 truncate group flex rounded-md items-center text-sm cursor-pointer hover:bg-accent',
227
+ )}
228
+ >
229
+ <SquarePlus size={16} strokeWidth={1.25} absoluteStrokeWidth />
230
+ {addNewLabel}
231
+ </a>
232
+ </div>
233
+ )}
234
+ </>
235
+ );
236
+
237
+ if (inline) {
238
+ return (
239
+ <div className={clsx(
240
+ className,
241
+ border && 'border border-border rounded-md',
242
+ "bg-popover p-1",
243
+ popupClass
244
+ )}>
245
+ {renderOptionsContent()}
246
+ </div>
247
+ );
248
+ }
249
+
172
250
  return (
173
251
  <Popover>
174
252
  <PopoverTrigger asChild>
@@ -178,7 +256,7 @@ export function VSelectBox<T = any>({ options, optionLabel, value, onChange, add
178
256
  className={clsx(
179
257
  className,
180
258
  border && 'border border-border',
181
- 'flex flex-row gap-2 items-center justify-between p-2 rounded-md group relative',
259
+ 'flex flex-row gap-2 items-center justify-between p-2 rounded-md group relative [&:hover_.clear-button]:opacity-100',
182
260
  !disabled ? "cursor-pointer hover:bg-muted" : "cursor-not-allowed text-muted",
183
261
  )}
184
262
  >
@@ -194,9 +272,10 @@ export function VSelectBox<T = any>({ options, optionLabel, value, onChange, add
194
272
  {multiple ? renderMultipleValue() : renderSingleValue()}
195
273
  </div>
196
274
  </div>
197
- <div className="flex items-center gap-1">
275
+ <div className="flex items-center gap-1 group">
198
276
  {isClearable && value && (Array.isArray(value) ? value.length > 0 : true) && (
199
- <div
277
+ <Button variant={"link"} size={"icon"}
278
+ alt="Clear selection"
200
279
  onClick={(e) => {
201
280
  e.stopPropagation();
202
281
  if (multiple) {
@@ -205,10 +284,10 @@ export function VSelectBox<T = any>({ options, optionLabel, value, onChange, add
205
284
  (onChange as (option: T) => void)(undefined as any);
206
285
  }
207
286
  }}
208
- className="cursor-pointer hover:bg-muted/20 rounded p-1"
287
+ className="cursor-pointer hover:bg-muted/20 clear-button opacity-0 transition-opacity duration-200 rounded p-1"
209
288
  >
210
289
  <X className="size-4" />
211
- </div>
290
+ </Button>
212
291
  )}
213
292
  {!disabled && (
214
293
  <ChevronsUpDown className="size-4 opacity-50" />
@@ -225,66 +304,7 @@ export function VSelectBox<T = any>({ options, optionLabel, value, onChange, add
225
304
  popupClass
226
305
  )}
227
306
  >
228
- {filterBy && (
229
-
230
- <div className='flex justify-start items-center mb-1'>
231
- <div className='mx-2'>
232
- <SearchIcon className="size-4" />
233
- </div>
234
- <Input variant='unstyled' value={filterValue} onChange={setFilterValue} className="w-full p-1 rounded-md" placeholder="Search..." />
235
- </div>
236
- )}
237
- <Command className="overflow-hidden">
238
- <CommandList className="max-h-[200px] overflow-y-auto">
239
- <CommandEmpty>No result found.</CommandEmpty>
240
- <CommandGroup className="overflow-visible">
241
- {filteredOptions?.map((opt, index) => {
242
- const isSelected = multiple
243
- ? isOptionSelected(opt, Array.isArray(value) ? value : [])
244
- : value != null ? isOptionsEqual(value as T, opt) : false;
245
-
246
- return (
247
- <CommandItem
248
- key={index}
249
- onSelect={() => _onClick(opt)}
250
- className="w-full"
251
- >
252
- {multiple ? (
253
- <div className='w-full flex justify-between items-center cursor-pointer'>
254
- <div className='w-full truncate text-left'>
255
- {optionLabel ? optionLabel(opt) : opt as String}
256
- </div>
257
- {isSelected && <Check className="size-4" />}
258
- </div>
259
- ) : (
260
- <PopoverClose className='w-full flex justify-between items-center'>
261
- <div className='w-full truncate text-left'>
262
- {optionLabel ? optionLabel(opt) : opt as String}
263
- </div>
264
- {isSelected && <Check className="size-4" />}
265
- </PopoverClose>
266
- )}
267
- </CommandItem>
268
- );
269
- })}
270
- </CommandGroup>
271
- </CommandList>
272
- </Command>
273
- {
274
- addNew && (
275
- <div className='p-1'>
276
- <a
277
- onClick={addNew}
278
- className={clsx(
279
- 'gap-x-2 px-2 py-1.5 truncate group flex rounded-md items-center text-sm cursor-pointer hover:bg-accent',
280
- )}
281
- >
282
- <SquarePlus size={16} strokeWidth={1.25} absoluteStrokeWidth />
283
- {addNewLabel}
284
- </a>
285
- </div>
286
- )
287
- }
307
+ {renderOptionsContent()}
288
308
  </PopoverContent>
289
309
  </Popover>
290
310
  );
@@ -106,7 +106,10 @@ const VTabs = ({
106
106
 
107
107
  // Update the URL hash when tab changes (only if updateHash is true and not controlled by parent)
108
108
  if (updateHash && !current) {
109
- window.location.hash = newValue;
109
+ // Preserve existing history state when changing hash
110
+ const currentState = window.history.state;
111
+ const newUrl = window.location.pathname + window.location.search + '#' + newValue;
112
+ window.history.pushState(currentState, '', newUrl);
110
113
  }
111
114
 
112
115
  if (onTabChange) {
@@ -143,7 +146,9 @@ const VTabsBar = ({ className }: { className?: string }) => {
143
146
  const tab = tabs.find(t => t.name === tabName);
144
147
 
145
148
  if (tab?.href && updateHash) {
146
- window.history.pushState(null, '', tab.href);
149
+ // Preserve existing history state when changing tabs
150
+ const currentState = window.history.state;
151
+ window.history.pushState(currentState, '', tab.href);
147
152
  }
148
153
 
149
154
  setTab(tabName);
@@ -236,7 +241,9 @@ const TabsTrigger = React.forwardRef<
236
241
  const handleClick = React.useCallback((event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
237
242
  if (href) {
238
243
  event.preventDefault();
239
- window.history.pushState(null, '', href);
244
+ // Preserve existing history state when changing tabs
245
+ const currentState = window.history.state;
246
+ window.history.pushState(currentState, '', href);
240
247
  }
241
248
  if (props.onClick) {
242
249
  (props.onClick as React.MouseEventHandler<HTMLButtonElement>)(event);
@@ -0,0 +1,21 @@
1
+ import * as React from "react"
2
+
3
+ import { cn } from "../libs/utils"
4
+
5
+ function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
6
+ return (
7
+ <textarea
8
+ data-slot="textarea"
9
+ className={cn(
10
+ "py-2 text-sm",
11
+ "flex w-full rounded-md border border-input bg-background ring-offset-background",
12
+ "placeholder:text-muted focus-visible:outline-none focus-visible:ring-1 ring-inset focus-visible:ring-ring",
13
+ "disabled:cursor-not-allowed disabled:opacity-50",
14
+ className
15
+ )}
16
+ {...props}
17
+ />
18
+ )
19
+ }
20
+
21
+ export { Textarea }
@@ -11,4 +11,5 @@ export * from "./useFlag.js"
11
11
  export * from "./useIntersectionObserver.js"
12
12
  export * from "./useIsFistRendering.js"
13
13
  export * from "./useSafeLayoutEffect.js"
14
+ export * from "./useScrollableSearch.js"
14
15
  export * from "./useSharedValue.js"