@vertesia/ui 0.79.0 → 0.80.0-dev-20251118

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 (296) 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/index.js +1 -1
  8. package/lib/esm/core/components/index.js.map +1 -1
  9. package/lib/esm/core/components/shadcn/breadcrumb.js +29 -8
  10. package/lib/esm/core/components/shadcn/breadcrumb.js.map +1 -1
  11. package/lib/esm/core/components/shadcn/button.js +3 -2
  12. package/lib/esm/core/components/shadcn/button.js.map +1 -1
  13. package/lib/esm/core/components/shadcn/filters/filterBar.js +2 -2
  14. package/lib/esm/core/components/shadcn/filters/filterBar.js.map +1 -1
  15. package/lib/esm/core/components/shadcn/index.js +1 -0
  16. package/lib/esm/core/components/shadcn/index.js.map +1 -1
  17. package/lib/esm/core/components/shadcn/input.js +4 -1
  18. package/lib/esm/core/components/shadcn/input.js.map +1 -1
  19. package/lib/esm/core/components/shadcn/resizeable.js +2 -2
  20. package/lib/esm/core/components/shadcn/resizeable.js.map +1 -1
  21. package/lib/esm/core/components/shadcn/selectBox.js +15 -9
  22. package/lib/esm/core/components/shadcn/selectBox.js.map +1 -1
  23. package/lib/esm/core/components/shadcn/tabs.js +10 -3
  24. package/lib/esm/core/components/shadcn/tabs.js.map +1 -1
  25. package/lib/esm/core/components/shadcn/textarea.js +7 -0
  26. package/lib/esm/core/components/shadcn/textarea.js.map +1 -0
  27. package/lib/esm/core/hooks/CompositeState.js +139 -1
  28. package/lib/esm/core/hooks/CompositeState.js.map +1 -1
  29. package/lib/esm/core/hooks/index.js +1 -0
  30. package/lib/esm/core/hooks/index.js.map +1 -1
  31. package/lib/esm/core/hooks/useScrollableSearch.js +92 -0
  32. package/lib/esm/core/hooks/useScrollableSearch.js.map +1 -0
  33. package/lib/esm/env/index.js +1 -1
  34. package/lib/esm/env/index.js.map +1 -1
  35. package/lib/esm/features/agent/PayloadBuilder.js +80 -55
  36. package/lib/esm/features/agent/PayloadBuilder.js.map +1 -1
  37. package/lib/esm/features/agent/chat/ModernAgentConversation.js +22 -24
  38. package/lib/esm/features/agent/chat/ModernAgentConversation.js.map +1 -1
  39. package/lib/esm/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +2 -3
  40. package/lib/esm/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
  41. package/lib/esm/features/agent/chat/ModernAgentOutput/Header.js +2 -2
  42. package/lib/esm/features/agent/chat/ModernAgentOutput/Header.js.map +1 -1
  43. package/lib/esm/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.js +15 -20
  44. package/lib/esm/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.js.map +1 -1
  45. package/lib/esm/features/agent/chat/ModernAgentOutput/PlanPanel.js +1 -0
  46. package/lib/esm/features/agent/chat/ModernAgentOutput/PlanPanel.js.map +1 -1
  47. package/lib/esm/features/agent/chat/ModernAgentOutput/SlidingPlanPanel.js +3 -3
  48. package/lib/esm/features/agent/chat/ModernAgentOutput/SlidingPlanPanel.js.map +1 -1
  49. package/lib/esm/features/agent/chat/ModernAgentOutput/WorkstreamTabs.js +6 -6
  50. package/lib/esm/features/agent/chat/ModernAgentOutput/WorkstreamTabs.js.map +1 -1
  51. package/lib/esm/features/facets/CollectionsFacetsNav.js +19 -0
  52. package/lib/esm/features/facets/CollectionsFacetsNav.js.map +1 -1
  53. package/lib/esm/features/facets/InteractionsFacetsNav.js +9 -3
  54. package/lib/esm/features/facets/InteractionsFacetsNav.js.map +1 -1
  55. package/lib/esm/features/facets/utils/VTypeFacet.js +4 -1
  56. package/lib/esm/features/facets/utils/VTypeFacet.js.map +1 -1
  57. package/lib/esm/features/layout/GenericPageNavHeader.js +58 -5
  58. package/lib/esm/features/layout/GenericPageNavHeader.js.map +1 -1
  59. package/lib/esm/features/store/collections/BrowseCollectionView.js +3 -0
  60. package/lib/esm/features/store/collections/BrowseCollectionView.js.map +1 -1
  61. package/lib/esm/features/store/collections/CreateCollection.js +2 -2
  62. package/lib/esm/features/store/collections/CreateCollection.js.map +1 -1
  63. package/lib/esm/features/store/collections/EditCollectionView.js +29 -30
  64. package/lib/esm/features/store/collections/EditCollectionView.js.map +1 -1
  65. package/lib/esm/features/store/collections/SelectCollection.js +46 -45
  66. package/lib/esm/features/store/collections/SelectCollection.js.map +1 -1
  67. package/lib/esm/features/store/objects/DocumentSearchResults.js +35 -9
  68. package/lib/esm/features/store/objects/DocumentSearchResults.js.map +1 -1
  69. package/lib/esm/features/store/objects/DocumentTable.js +6 -6
  70. package/lib/esm/features/store/objects/DocumentTable.js.map +1 -1
  71. package/lib/esm/features/store/objects/components/ContentOverview.js +158 -114
  72. package/lib/esm/features/store/objects/components/ContentOverview.js.map +1 -1
  73. package/lib/esm/features/store/objects/components/DocumentIcon.js +5 -3
  74. package/lib/esm/features/store/objects/components/DocumentIcon.js.map +1 -1
  75. package/lib/esm/features/store/objects/components/SaveVersionConfirmModal.js +11 -2
  76. package/lib/esm/features/store/objects/components/SaveVersionConfirmModal.js.map +1 -1
  77. package/lib/esm/features/store/objects/components/useDownloadObject.js +2 -2
  78. package/lib/esm/features/store/objects/components/useDownloadObject.js.map +1 -1
  79. package/lib/esm/features/store/objects/layout/DocumentTableColumn.js +13 -1
  80. package/lib/esm/features/store/objects/layout/DocumentTableColumn.js.map +1 -1
  81. package/lib/esm/features/store/objects/layout/documentLayout.js +5 -5
  82. package/lib/esm/features/store/objects/layout/documentLayout.js.map +1 -1
  83. package/lib/esm/features/store/objects/layout/renderers.js +28 -12
  84. package/lib/esm/features/store/objects/layout/renderers.js.map +1 -1
  85. package/lib/esm/features/store/objects/search/DocumentSearchContext.js +5 -1
  86. package/lib/esm/features/store/objects/search/DocumentSearchContext.js.map +1 -1
  87. package/lib/esm/features/store/objects/search/DocumentSearchProvider.js +1 -1
  88. package/lib/esm/features/store/objects/search/DocumentSearchProvider.js.map +1 -1
  89. package/lib/esm/features/store/objects/selection/ObjectsActionContext.js +3 -2
  90. package/lib/esm/features/store/objects/selection/ObjectsActionContext.js.map +1 -1
  91. package/lib/esm/features/store/objects/selection/SelectionActions.js +2 -0
  92. package/lib/esm/features/store/objects/selection/SelectionActions.js.map +1 -1
  93. package/lib/esm/features/store/objects/selection/actions/AddToCollectionAction.js +10 -2
  94. package/lib/esm/features/store/objects/selection/actions/AddToCollectionAction.js.map +1 -1
  95. package/lib/esm/features/store/objects/selection/actions/DeleteObjectsAction.js +20 -2
  96. package/lib/esm/features/store/objects/selection/actions/DeleteObjectsAction.js.map +1 -1
  97. package/lib/esm/features/store/objects/upload/DocumentUploadModal.js +15 -7
  98. package/lib/esm/features/store/objects/upload/DocumentUploadModal.js.map +1 -1
  99. package/lib/esm/features/store/types/CreateOrUpdateTypeModal.js +1 -1
  100. package/lib/esm/features/store/types/CreateOrUpdateTypeModal.js.map +1 -1
  101. package/lib/esm/features/user/UserInfo.js +2 -0
  102. package/lib/esm/features/user/UserInfo.js.map +1 -1
  103. package/lib/esm/router/HistoryNavigator.js +25 -2
  104. package/lib/esm/router/HistoryNavigator.js.map +1 -1
  105. package/lib/esm/router/Nav.js +3 -3
  106. package/lib/esm/router/Nav.js.map +1 -1
  107. package/lib/esm/session/UserSession.js +1 -0
  108. package/lib/esm/session/UserSession.js.map +1 -1
  109. package/lib/esm/session/UserSessionProvider.js +9 -2
  110. package/lib/esm/session/UserSessionProvider.js.map +1 -1
  111. package/lib/esm/session/auth/composable.js +66 -67
  112. package/lib/esm/session/auth/composable.js.map +1 -1
  113. package/lib/esm/widgets/form/Form.js +17 -30
  114. package/lib/esm/widgets/form/Form.js.map +1 -1
  115. package/lib/esm/widgets/form/FormContext.js +4 -2
  116. package/lib/esm/widgets/form/FormContext.js.map +1 -1
  117. package/lib/esm/widgets/form/ManagedObject.js +4 -0
  118. package/lib/esm/widgets/form/ManagedObject.js.map +1 -1
  119. package/lib/esm/widgets/form/fields.js +4 -3
  120. package/lib/esm/widgets/form/fields.js.map +1 -1
  121. package/lib/esm/widgets/form/inputs.js +2 -0
  122. package/lib/esm/widgets/form/inputs.js.map +1 -1
  123. package/lib/tsconfig.tsbuildinfo +1 -1
  124. package/lib/types/core/components/Panel.d.ts +11 -0
  125. package/lib/types/core/components/Panel.d.ts.map +1 -0
  126. package/lib/types/core/components/SidePanel.d.ts.map +1 -1
  127. package/lib/types/core/components/index.d.ts +1 -1
  128. package/lib/types/core/components/index.d.ts.map +1 -1
  129. package/lib/types/core/components/shadcn/breadcrumb.d.ts +3 -2
  130. package/lib/types/core/components/shadcn/breadcrumb.d.ts.map +1 -1
  131. package/lib/types/core/components/shadcn/button.d.ts.map +1 -1
  132. package/lib/types/core/components/shadcn/filters/filterBar.d.ts.map +1 -1
  133. package/lib/types/core/components/shadcn/index.d.ts +1 -0
  134. package/lib/types/core/components/shadcn/index.d.ts.map +1 -1
  135. package/lib/types/core/components/shadcn/input.d.ts.map +1 -1
  136. package/lib/types/core/components/shadcn/selectBox.d.ts +3 -2
  137. package/lib/types/core/components/shadcn/selectBox.d.ts.map +1 -1
  138. package/lib/types/core/components/shadcn/tabs.d.ts.map +1 -1
  139. package/lib/types/core/components/shadcn/textarea.d.ts +4 -0
  140. package/lib/types/core/components/shadcn/textarea.d.ts.map +1 -0
  141. package/lib/types/core/hooks/CompositeState.d.ts +115 -6
  142. package/lib/types/core/hooks/CompositeState.d.ts.map +1 -1
  143. package/lib/types/core/hooks/index.d.ts +1 -0
  144. package/lib/types/core/hooks/index.d.ts.map +1 -1
  145. package/lib/types/core/hooks/useScrollableSearch.d.ts +82 -0
  146. package/lib/types/core/hooks/useScrollableSearch.d.ts.map +1 -0
  147. package/lib/types/env/index.d.ts +3 -1
  148. package/lib/types/env/index.d.ts.map +1 -1
  149. package/lib/types/features/agent/PayloadBuilder.d.ts +11 -19
  150. package/lib/types/features/agent/PayloadBuilder.d.ts.map +1 -1
  151. package/lib/types/features/agent/chat/ModernAgentConversation.d.ts.map +1 -1
  152. package/lib/types/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts +1 -1
  153. package/lib/types/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts.map +1 -1
  154. package/lib/types/features/agent/chat/ModernAgentOutput/Header.d.ts.map +1 -1
  155. package/lib/types/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.d.ts.map +1 -1
  156. package/lib/types/features/agent/chat/ModernAgentOutput/PlanPanel.d.ts.map +1 -1
  157. package/lib/types/features/facets/CollectionsFacetsNav.d.ts.map +1 -1
  158. package/lib/types/features/facets/InteractionsFacetsNav.d.ts +1 -0
  159. package/lib/types/features/facets/InteractionsFacetsNav.d.ts.map +1 -1
  160. package/lib/types/features/facets/utils/SearchInterface.d.ts +6 -1
  161. package/lib/types/features/facets/utils/SearchInterface.d.ts.map +1 -1
  162. package/lib/types/features/facets/utils/VTypeFacet.d.ts +2 -1
  163. package/lib/types/features/facets/utils/VTypeFacet.d.ts.map +1 -1
  164. package/lib/types/features/layout/GenericPageNavHeader.d.ts +2 -1
  165. package/lib/types/features/layout/GenericPageNavHeader.d.ts.map +1 -1
  166. package/lib/types/features/store/collections/BrowseCollectionView.d.ts.map +1 -1
  167. package/lib/types/features/store/collections/CreateCollection.d.ts.map +1 -1
  168. package/lib/types/features/store/collections/EditCollectionView.d.ts.map +1 -1
  169. package/lib/types/features/store/collections/SelectCollection.d.ts +6 -4
  170. package/lib/types/features/store/collections/SelectCollection.d.ts.map +1 -1
  171. package/lib/types/features/store/objects/DocumentSearchResults.d.ts.map +1 -1
  172. package/lib/types/features/store/objects/DocumentTable.d.ts +4 -0
  173. package/lib/types/features/store/objects/DocumentTable.d.ts.map +1 -1
  174. package/lib/types/features/store/objects/components/ContentOverview.d.ts.map +1 -1
  175. package/lib/types/features/store/objects/components/DocumentIcon.d.ts +3 -1
  176. package/lib/types/features/store/objects/components/DocumentIcon.d.ts.map +1 -1
  177. package/lib/types/features/store/objects/components/SaveVersionConfirmModal.d.ts.map +1 -1
  178. package/lib/types/features/store/objects/components/useDownloadObject.d.ts +1 -1
  179. package/lib/types/features/store/objects/components/useDownloadObject.d.ts.map +1 -1
  180. package/lib/types/features/store/objects/layout/DocumentTableColumn.d.ts +2 -1
  181. package/lib/types/features/store/objects/layout/DocumentTableColumn.d.ts.map +1 -1
  182. package/lib/types/features/store/objects/layout/documentLayout.d.ts +4 -2
  183. package/lib/types/features/store/objects/layout/documentLayout.d.ts.map +1 -1
  184. package/lib/types/features/store/objects/layout/renderers.d.ts +1 -1
  185. package/lib/types/features/store/objects/layout/renderers.d.ts.map +1 -1
  186. package/lib/types/features/store/objects/search/DocumentSearchContext.d.ts +1 -0
  187. package/lib/types/features/store/objects/search/DocumentSearchContext.d.ts.map +1 -1
  188. package/lib/types/features/store/objects/selection/ObjectsActionContext.d.ts.map +1 -1
  189. package/lib/types/features/store/objects/selection/SelectionActions.d.ts.map +1 -1
  190. package/lib/types/features/store/objects/selection/actions/DeleteObjectsAction.d.ts +1 -0
  191. package/lib/types/features/store/objects/selection/actions/DeleteObjectsAction.d.ts.map +1 -1
  192. package/lib/types/features/store/objects/upload/DocumentUploadModal.d.ts.map +1 -1
  193. package/lib/types/features/user/UserInfo.d.ts.map +1 -1
  194. package/lib/types/router/HistoryNavigator.d.ts.map +1 -1
  195. package/lib/types/router/Nav.d.ts +2 -1
  196. package/lib/types/router/Nav.d.ts.map +1 -1
  197. package/lib/types/session/UserSession.d.ts.map +1 -1
  198. package/lib/types/session/UserSessionProvider.d.ts.map +1 -1
  199. package/lib/types/session/auth/composable.d.ts.map +1 -1
  200. package/lib/types/widgets/form/Form.d.ts +2 -1
  201. package/lib/types/widgets/form/Form.d.ts.map +1 -1
  202. package/lib/types/widgets/form/FormContext.d.ts +5 -2
  203. package/lib/types/widgets/form/FormContext.d.ts.map +1 -1
  204. package/lib/types/widgets/form/ManagedObject.d.ts.map +1 -1
  205. package/lib/types/widgets/form/fields.d.ts +2 -2
  206. package/lib/types/widgets/form/fields.d.ts.map +1 -1
  207. package/lib/types/widgets/form/inputs.d.ts.map +1 -1
  208. package/lib/vertesia-ui-core.js +1 -1
  209. package/lib/vertesia-ui-core.js.map +1 -1
  210. package/lib/vertesia-ui-env.js +1 -1
  211. package/lib/vertesia-ui-env.js.map +1 -1
  212. package/lib/vertesia-ui-features.js +1 -1
  213. package/lib/vertesia-ui-features.js.map +1 -1
  214. package/lib/vertesia-ui-router.js +1 -1
  215. package/lib/vertesia-ui-router.js.map +1 -1
  216. package/lib/vertesia-ui-session.js +1 -1
  217. package/lib/vertesia-ui-session.js.map +1 -1
  218. package/lib/vertesia-ui-shell.js.map +1 -1
  219. package/lib/vertesia-ui-widgets.js +1 -1
  220. package/lib/vertesia-ui-widgets.js.map +1 -1
  221. package/package.json +170 -165
  222. package/src/core/components/Panel.tsx +34 -0
  223. package/src/core/components/SelectBox.tsx +1 -1
  224. package/src/core/components/SidePanel.tsx +5 -3
  225. package/src/core/components/TagsInput.tsx +388 -0
  226. package/src/core/components/index.ts +2 -1
  227. package/src/core/components/shadcn/breadcrumb.tsx +49 -30
  228. package/src/core/components/shadcn/button.tsx +3 -2
  229. package/src/core/components/shadcn/filters/filterBar.tsx +3 -3
  230. package/src/core/components/shadcn/index.ts +2 -1
  231. package/src/core/components/shadcn/input.tsx +10 -7
  232. package/src/core/components/shadcn/popover.tsx +2 -2
  233. package/src/core/components/shadcn/resizeable.tsx +4 -4
  234. package/src/core/components/shadcn/selectBox.tsx +87 -67
  235. package/src/core/components/shadcn/tabs.tsx +10 -3
  236. package/src/core/components/shadcn/textarea.tsx +21 -0
  237. package/src/core/hooks/CompositeState.tsx +156 -6
  238. package/src/core/hooks/index.ts +1 -0
  239. package/src/core/hooks/useScrollableSearch.tsx +193 -0
  240. package/src/env/index.ts +4 -3
  241. package/src/features/agent/PayloadBuilder.tsx +92 -65
  242. package/src/features/agent/chat/ModernAgentConversation.tsx +109 -118
  243. package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +3 -23
  244. package/src/features/agent/chat/ModernAgentOutput/Header.tsx +3 -11
  245. package/src/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.tsx +39 -55
  246. package/src/features/agent/chat/ModernAgentOutput/PlanPanel.tsx +1 -0
  247. package/src/features/agent/chat/ModernAgentOutput/SlidingPlanPanel.tsx +8 -8
  248. package/src/features/agent/chat/ModernAgentOutput/WorkstreamTabs.tsx +9 -9
  249. package/src/features/facets/CollectionsFacetsNav.tsx +21 -0
  250. package/src/features/facets/InteractionsFacetsNav.tsx +13 -3
  251. package/src/features/facets/utils/SearchInterface.tsx +5 -1
  252. package/src/features/facets/utils/VTypeFacet.tsx +6 -2
  253. package/src/features/layout/GenericPageNavHeader.tsx +73 -10
  254. package/src/features/store/collections/BrowseCollectionView.tsx +4 -0
  255. package/src/features/store/collections/CreateCollection.tsx +3 -4
  256. package/src/features/store/collections/EditCollectionView.tsx +112 -85
  257. package/src/features/store/collections/SelectCollection.tsx +105 -49
  258. package/src/features/store/collections/SharedPropsEditor.tsx +61 -0
  259. package/src/features/store/collections/SyncMemberHeadsToggle.tsx +48 -0
  260. package/src/features/store/collections/index.ts +3 -1
  261. package/src/features/store/objects/DocumentSearchResults.tsx +128 -53
  262. package/src/features/store/objects/DocumentTable.tsx +14 -4
  263. package/src/features/store/objects/components/ContentOverview.tsx +208 -110
  264. package/src/features/store/objects/components/DocumentIcon.tsx +11 -12
  265. package/src/features/store/objects/components/SaveVersionConfirmModal.tsx +12 -2
  266. package/src/features/store/objects/components/useDownloadObject.ts +7 -2
  267. package/src/features/store/objects/layout/DocumentTableColumn.tsx +16 -1
  268. package/src/features/store/objects/layout/documentLayout.tsx +7 -5
  269. package/src/features/store/objects/layout/knowledge.md +10 -10
  270. package/src/features/store/objects/layout/renderers.tsx +39 -18
  271. package/src/features/store/objects/search/DocumentSearchContext.ts +6 -1
  272. package/src/features/store/objects/search/DocumentSearchProvider.tsx +1 -1
  273. package/src/features/store/objects/selection/ObjectsActionContext.tsx +3 -2
  274. package/src/features/store/objects/selection/SelectionActions.tsx +2 -0
  275. package/src/features/store/objects/selection/actions/AddToCollectionAction.tsx +8 -2
  276. package/src/features/store/objects/selection/actions/DeleteObjectsAction.tsx +22 -2
  277. package/src/features/store/objects/upload/DocumentUploadModal.tsx +18 -9
  278. package/src/features/store/objects/upload/useSmartFileUploadProcessing.ts +10 -7
  279. package/src/features/store/types/CreateOrUpdateTypeModal.tsx +1 -1
  280. package/src/features/user/UserInfo.tsx +2 -0
  281. package/src/router/HistoryNavigator.ts +33 -2
  282. package/src/router/Nav.tsx +4 -3
  283. package/src/session/UserSession.ts +1 -0
  284. package/src/session/UserSessionProvider.tsx +10 -2
  285. package/src/session/auth/composable.ts +71 -70
  286. package/src/shell/apps/AppProjectSelector.tsx +2 -2
  287. package/src/widgets/form/Form.tsx +19 -43
  288. package/src/widgets/form/FormContext.ts +5 -2
  289. package/src/widgets/form/ManagedObject.ts +4 -0
  290. package/src/widgets/form/fields.tsx +8 -6
  291. package/src/widgets/form/inputs.tsx +1 -0
  292. package/lib/esm/core/components/Textarea.js +0 -15
  293. package/lib/esm/core/components/Textarea.js.map +0 -1
  294. package/lib/types/core/components/Textarea.d.ts +0 -8
  295. package/lib/types/core/components/Textarea.d.ts.map +0 -1
  296. package/src/core/components/Textarea.tsx +0 -25
@@ -0,0 +1,388 @@
1
+ import clsx from 'clsx';
2
+ import { X } from 'lucide-react';
3
+ import { useContext, useEffect, useRef, useState } from 'react';
4
+ import { Popover, PopoverContent, PopoverContext, PopoverTrigger } from './shadcn/popover';
5
+
6
+ interface TagsInputProps {
7
+ options: string[];
8
+ value: string[];
9
+ onChange: (selected: string[]) => void;
10
+ onOptionsChange?: (options: string[]) => void;
11
+ placeholder?: string;
12
+ className?: string;
13
+ disabled?: boolean;
14
+ layout?: 'horizontal' | 'vertical';
15
+ creatable?: boolean;
16
+ createText?: string;
17
+ maxDropdownHeight?: number;
18
+ }
19
+
20
+ function TagsInputContent({
21
+ options,
22
+ value,
23
+ onChange,
24
+ onOptionsChange,
25
+ placeholder,
26
+ className,
27
+ disabled,
28
+ layout = 'horizontal',
29
+ creatable = false,
30
+ createText = 'Create "%value%"',
31
+ maxDropdownHeight = 200
32
+ }: TagsInputProps) {
33
+ const popoverContext = useContext(PopoverContext);
34
+ const [searchTerm, setSearchTerm] = useState('');
35
+ const [highlightedIndex, setHighlightedIndex] = useState(0);
36
+ const [width, setWidth] = useState<number>(0);
37
+ const [pendingDeleteIndex, setPendingDeleteIndex] = useState<number | null>(null);
38
+ const inputRef = useRef<HTMLInputElement>(null);
39
+ const triggerRef = useRef<HTMLDivElement>(null);
40
+ const dropdownRef = useRef<HTMLDivElement>(null);
41
+ const highlightedItemRef = useRef<HTMLElement | null>(null);
42
+
43
+ const isOpen = popoverContext?.open ?? false;
44
+ const setIsOpen = popoverContext?.setOpen ?? (() => { });
45
+
46
+ // Measure trigger width for popover
47
+ useEffect(() => {
48
+ const element = triggerRef.current;
49
+ if (!element) return;
50
+
51
+ const updateWidth = () => {
52
+ const contentWidth = element.getBoundingClientRect().width;
53
+ setWidth(contentWidth);
54
+ };
55
+
56
+ const resizeObserver = new ResizeObserver(() => {
57
+ updateWidth();
58
+ });
59
+
60
+ updateWidth();
61
+ resizeObserver.observe(element);
62
+
63
+ return () => {
64
+ resizeObserver.disconnect();
65
+ };
66
+ }, []);
67
+
68
+ // Filter options based on search term and exclude already selected
69
+ const filteredOptions = options.filter(
70
+ option =>
71
+ !value.includes(option) &&
72
+ option.toLowerCase().includes(searchTerm.toLowerCase())
73
+ );
74
+
75
+ // Check if create option should be shown
76
+ const showCreateOption = creatable && searchTerm && !value.includes(searchTerm) && !options.includes(searchTerm);
77
+
78
+ // Total number of items (filtered options + create option if shown)
79
+ const totalItems = filteredOptions.length + (showCreateOption ? 1 : 0);
80
+
81
+ // Reset highlighted index when filtered options change
82
+ useEffect(() => {
83
+ setHighlightedIndex(0);
84
+ }, [searchTerm, showCreateOption]);
85
+
86
+ // Clear pending delete when user starts typing
87
+ useEffect(() => {
88
+ if (searchTerm !== '') {
89
+ setPendingDeleteIndex(null);
90
+ }
91
+ }, [searchTerm]);
92
+
93
+ // Scroll highlighted item into view
94
+ useEffect(() => {
95
+ if (isOpen && highlightedItemRef.current && dropdownRef.current) {
96
+ highlightedItemRef.current.scrollIntoView({
97
+ block: 'nearest',
98
+ behavior: 'smooth'
99
+ });
100
+ }
101
+ }, [highlightedIndex, isOpen]);
102
+
103
+ // Clear search term when popover closes and refocus input when it opens
104
+ useEffect(() => {
105
+ if (!isOpen) {
106
+ setSearchTerm('');
107
+ } else {
108
+ // Ensure input stays focused when popover opens
109
+ inputRef.current?.focus();
110
+ }
111
+ }, [isOpen]);
112
+
113
+ const handleSelect = (option: string) => {
114
+ onChange([...value, option]);
115
+ setSearchTerm('');
116
+ setIsOpen(false);
117
+ setHighlightedIndex(0);
118
+ setPendingDeleteIndex(null);
119
+ };
120
+
121
+ const handleCreate = (newTag: string) => {
122
+ // Add to value
123
+ onChange([...value, newTag]);
124
+ // Add to options if callback provided
125
+ if (onOptionsChange && !options.includes(newTag)) {
126
+ onOptionsChange([...options, newTag]);
127
+ }
128
+ setSearchTerm('');
129
+ setIsOpen(false);
130
+ setHighlightedIndex(0);
131
+ setPendingDeleteIndex(null);
132
+ };
133
+
134
+ const handleRemove = (option: string, e: React.MouseEvent) => {
135
+ e.stopPropagation();
136
+ onChange(value.filter(v => v !== option));
137
+ setPendingDeleteIndex(null);
138
+ };
139
+
140
+ const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
141
+ // Handle special keys
142
+ if (e.key === 'Enter' && isOpen && totalItems > 0) {
143
+ e.preventDefault();
144
+ e.stopPropagation();
145
+ // Check if we're selecting the create option
146
+ if (highlightedIndex === filteredOptions.length && showCreateOption) {
147
+ handleCreate(searchTerm);
148
+ } else if (highlightedIndex < filteredOptions.length) {
149
+ handleSelect(filteredOptions[highlightedIndex]);
150
+ }
151
+ return;
152
+ }
153
+
154
+ if (e.key === 'ArrowDown') {
155
+ e.preventDefault();
156
+ e.stopPropagation();
157
+ if (!isOpen) {
158
+ setIsOpen(true);
159
+ } else {
160
+ setHighlightedIndex(prev =>
161
+ prev < totalItems - 1 ? prev + 1 : prev
162
+ );
163
+ }
164
+ return;
165
+ }
166
+
167
+ if (e.key === 'ArrowUp') {
168
+ e.preventDefault();
169
+ e.stopPropagation();
170
+ if (!isOpen) {
171
+ setIsOpen(true);
172
+ } else {
173
+ setHighlightedIndex(prev => (prev > 0 ? prev - 1 : 0));
174
+ }
175
+ return;
176
+ }
177
+
178
+ if (e.key === 'Escape') {
179
+ e.preventDefault();
180
+ e.stopPropagation();
181
+ setIsOpen(false);
182
+ return;
183
+ }
184
+
185
+ if (e.key === 'Backspace' && searchTerm === '' && value.length > 0) {
186
+ // Two-step deletion: first backspace marks for deletion, second backspace deletes
187
+ e.stopPropagation();
188
+ const lastIndex = value.length - 1;
189
+
190
+ if (pendingDeleteIndex === lastIndex) {
191
+ // Second backspace: actually delete the item
192
+ onChange(value.slice(0, -1));
193
+ setPendingDeleteIndex(null);
194
+ } else {
195
+ // First backspace: mark for deletion
196
+ setPendingDeleteIndex(lastIndex);
197
+ }
198
+ return;
199
+ }
200
+
201
+ // For any other key (typing characters), open dropdown
202
+ if (!isOpen && e.key.length === 1) {
203
+ setIsOpen(true);
204
+ }
205
+ };
206
+
207
+ const handleInputClick = (e: React.MouseEvent<HTMLInputElement>) => {
208
+ e.stopPropagation();
209
+ if (!disabled) {
210
+ setIsOpen(true);
211
+ }
212
+ };
213
+
214
+ const handleInputFocus = () => {
215
+ if (!disabled) {
216
+ setIsOpen(true);
217
+ }
218
+ };
219
+
220
+ const handleContainerClick = () => {
221
+ if (!disabled) {
222
+ inputRef.current?.focus();
223
+ }
224
+ };
225
+
226
+ return (
227
+ <div className={clsx('relative', className)}>
228
+ <PopoverTrigger asChild>
229
+ <div
230
+ ref={triggerRef}
231
+ className={clsx(
232
+ 'min-h-[40px] w-full rounded-md border border-input bg-background px-3 py-2',
233
+ 'flex items-center gap-1',
234
+ layout === 'horizontal' ? 'flex-wrap' : 'flex-col items-stretch',
235
+ 'cursor-text',
236
+ 'ring-offset-background',
237
+ disabled && 'opacity-50 cursor-not-allowed',
238
+ isOpen ? 'ring-1 ring-inset ring-ring' : ''
239
+ )}
240
+ onClick={handleContainerClick}
241
+ >
242
+ {/* Selected Items Badges - Vertical Layout */}
243
+ {layout === 'vertical' && value.length > 0 && (
244
+ <div className="flex flex-col gap-1 w-full">
245
+ {value.map((item, index) => (
246
+ <span
247
+ key={item}
248
+ className={clsx(
249
+ "inline-flex items-center justify-between gap-2 px-2 py-1 text-sm bg-primary/10 text-primary rounded-md w-full transition-all",
250
+ pendingDeleteIndex === index && "ring-2 ring-red-300 shadow-[0_0_8px_rgba(252,165,165,0.5)]"
251
+ )}
252
+ >
253
+ <span className="truncate">{item}</span>
254
+ <button
255
+ type="button"
256
+ onClick={(e) => handleRemove(item, e)}
257
+ disabled={disabled}
258
+ className="hover:bg-primary/20 rounded-sm transition-colors flex-shrink-0"
259
+ >
260
+ <X className="h-3 w-3" />
261
+ </button>
262
+ </span>
263
+ ))}
264
+ </div>
265
+ )}
266
+
267
+ {/* Selected Items Badges - Horizontal Layout */}
268
+ {layout === 'horizontal' && value.map((item, index) => (
269
+ <span
270
+ key={item}
271
+ className={clsx(
272
+ "inline-flex items-center gap-1 px-2 py-1 text-sm bg-primary/10 text-primary rounded-md transition-all",
273
+ pendingDeleteIndex === index && "ring-2 ring-red-300 shadow-[0_0_8px_rgba(252,165,165,0.5)]"
274
+ )}
275
+ >
276
+ {item}
277
+ <button
278
+ type="button"
279
+ onClick={(e) => handleRemove(item, e)}
280
+ disabled={disabled}
281
+ className="hover:bg-primary/20 rounded-sm transition-colors"
282
+ >
283
+ <X className="h-3 w-3" />
284
+ </button>
285
+ </span>
286
+ ))}
287
+
288
+ {/* Search Input */}
289
+ <input
290
+ ref={inputRef}
291
+ type="text"
292
+ value={searchTerm}
293
+ onChange={(e) => setSearchTerm(e.target.value)}
294
+ onKeyDown={handleKeyDown}
295
+ onClick={handleInputClick}
296
+ onFocus={handleInputFocus}
297
+ disabled={disabled}
298
+ placeholder={value.length === 0 ? placeholder : ''}
299
+ className={clsx(
300
+ 'flex-1 min-w-[120px] bg-transparent text-sm',
301
+ 'placeholder:text-muted-foreground',
302
+ 'border-none outline-none focus:outline-none focus:ring-0 p-0 m-0',
303
+ layout === 'vertical' && 'w-full'
304
+ )}
305
+ />
306
+ </div>
307
+ </PopoverTrigger>
308
+
309
+ <PopoverContent
310
+ style={{ width: `${width}px` }}
311
+ className="p-0 bg-popover border border-border shadow-lg"
312
+ align="start"
313
+ side="bottom"
314
+ onOpenAutoFocus={(e) => {
315
+ // Prevent the popover from stealing focus from the input
316
+ e.preventDefault();
317
+ }}
318
+ >
319
+ <div ref={dropdownRef} className="overflow-y-auto" style={{ maxHeight: `${maxDropdownHeight}px` }}>
320
+ {filteredOptions.length === 0 && !showCreateOption ? (
321
+ <div className="px-3 py-2 text-sm text-muted-foreground">
322
+ {searchTerm ? 'No options found' : 'No more options available'}
323
+ </div>
324
+ ) : (
325
+ <>
326
+ {filteredOptions.length > 0 && (
327
+ <ul className="py-1">
328
+ {filteredOptions.map((option, index) => (
329
+ <li
330
+ key={option}
331
+ ref={(el) => {
332
+ if (index === highlightedIndex) {
333
+ highlightedItemRef.current = el;
334
+ }
335
+ }}
336
+ onClick={() => handleSelect(option)}
337
+ onMouseEnter={() => setHighlightedIndex(index)}
338
+ className={clsx(
339
+ 'px-3 py-2 text-sm cursor-pointer transition-colors',
340
+ index === highlightedIndex
341
+ ? 'bg-blue-500/20 text-foreground'
342
+ : 'hover:bg-accent/50'
343
+ )}
344
+ >
345
+ {option}
346
+ </li>
347
+ ))}
348
+ </ul>
349
+ )}
350
+ {showCreateOption && (
351
+ <>
352
+ {filteredOptions.length > 0 && (
353
+ <div className="border-t border-border" />
354
+ )}
355
+ <div
356
+ ref={(el) => {
357
+ if (highlightedIndex === filteredOptions.length) {
358
+ highlightedItemRef.current = el;
359
+ }
360
+ }}
361
+ onClick={() => handleCreate(searchTerm)}
362
+ onMouseEnter={() => setHighlightedIndex(filteredOptions.length)}
363
+ className={clsx(
364
+ 'px-3 py-2 text-sm cursor-pointer transition-colors text-primary',
365
+ highlightedIndex === filteredOptions.length
366
+ ? 'bg-blue-500/20'
367
+ : 'hover:bg-accent/50'
368
+ )}
369
+ >
370
+ {createText.replace('%value%', searchTerm)}
371
+ </div>
372
+ </>
373
+ )}
374
+ </>
375
+ )}
376
+ </div>
377
+ </PopoverContent>
378
+ </div>
379
+ );
380
+ }
381
+
382
+ export function TagsInput(props: TagsInputProps) {
383
+ return (
384
+ <Popover click>
385
+ <TagsInputContent {...props} />
386
+ </Popover>
387
+ );
388
+ }
@@ -18,6 +18,7 @@ export * from "./MessageBox.js";
18
18
  export * from "./Modal.js";
19
19
  export * from "./NumberInput.js";
20
20
  export * from "./Overlay.js";
21
+ export * from "./Panel.js";
21
22
  export * from "./popup/index.js";
22
23
  export * from "./Portal.js";
23
24
  export * from "./RadioGroup.js";
@@ -31,7 +32,7 @@ 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
+ export * from "./TagsInput.js";
35
36
  export * from "./toast/index.js";
36
37
 
37
38
  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
  )
@@ -5,13 +5,13 @@ import { cn } from "../libs/utils"
5
5
  import { JSX } from "react";
6
6
  import { useIsInModal } from "./dialog";
7
7
 
8
- interface PopoverContextValue {
8
+ export interface PopoverContextValue {
9
9
  open: boolean;
10
10
  setOpen: React.Dispatch<React.SetStateAction<boolean>>;
11
11
  hover: boolean;
12
12
  click: boolean;
13
13
  }
14
- const PopoverContext = React.createContext<PopoverContextValue | null>(null);
14
+ export const PopoverContext = React.createContext<PopoverContextValue | null>(null);
15
15
 
16
16
  interface PopoverProps {
17
17
  _open?: boolean;
@@ -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>