@ctrl-ui/react 0.8.6 → 0.8.8

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 (376) hide show
  1. package/dist/action-bar.d.ts +15 -7
  2. package/dist/action-bar.js +39 -19
  3. package/dist/activity.js +7 -15
  4. package/dist/audio-recorder.d.ts +14 -4
  5. package/dist/audio-recorder.js +82 -29
  6. package/dist/audio-visualizer.js +1 -1
  7. package/dist/blocks/coding-agent.js +54 -57
  8. package/dist/blocks/design-canvas-data.d.ts +32 -0
  9. package/dist/blocks/design-canvas-data.js +100 -0
  10. package/dist/blocks/design-canvas-inspector.d.ts +8 -0
  11. package/dist/blocks/design-canvas-inspector.js +238 -0
  12. package/dist/blocks/design-canvas.d.ts +21 -0
  13. package/dist/blocks/design-canvas.js +452 -0
  14. package/dist/blocks/discussion.d.ts +28 -0
  15. package/dist/blocks/discussion.js +67 -0
  16. package/dist/blocks/file-explorer-data.d.ts +1 -0
  17. package/dist/blocks/file-explorer-data.js +4 -1
  18. package/dist/blocks/file-explorer.d.ts +9 -1
  19. package/dist/blocks/file-explorer.js +461 -192
  20. package/dist/blocks/settings.d.ts +2 -1
  21. package/dist/blocks/settings.js +101 -79
  22. package/dist/blocks/team-chat.d.ts +12 -0
  23. package/dist/blocks/team-chat.js +26 -0
  24. package/dist/blocks/theme-toggle.js +23 -31
  25. package/dist/chat-composer-attachment.d.ts +12 -3
  26. package/dist/chat-composer-attachment.js +61 -19
  27. package/dist/chat-composer-editor/extensions/mention.d.ts +5 -1
  28. package/dist/chat-composer-editor/extensions/mention.js +58 -27
  29. package/dist/chat-composer-editor/ghost.js +2 -4
  30. package/dist/chat-composer-editor/types.d.ts +5 -0
  31. package/dist/chat-composer-editor.d.ts +1 -1
  32. package/dist/chat-composer-editor.js +71 -28
  33. package/dist/chat-composer.d.ts +13 -32
  34. package/dist/chat-composer.js +54 -13
  35. package/dist/chat-layout.d.ts +19 -0
  36. package/dist/chat-layout.js +96 -32
  37. package/dist/chat-message/social.d.ts +26 -0
  38. package/dist/chat-message/social.js +122 -0
  39. package/dist/chat-message.d.ts +28 -29
  40. package/dist/chat-message.js +106 -25
  41. package/dist/context.d.ts +2 -2
  42. package/dist/context.js +38 -23
  43. package/dist/dynamic-notification-canvas-loop.d.ts +24 -0
  44. package/dist/dynamic-notification-canvas-loop.js +113 -0
  45. package/dist/dynamic-notification-glass.js +23 -114
  46. package/dist/dynamic-notification-liquid.js +14 -118
  47. package/dist/dynamic-notification.d.ts +16 -8
  48. package/dist/dynamic-notification.js +85 -22
  49. package/dist/email/email-brand.d.ts +7 -4
  50. package/dist/email/email-brand.js +9 -6
  51. package/dist/email/email-code.d.ts +3 -2
  52. package/dist/email/email-code.js +11 -9
  53. package/dist/email/email-footer.d.ts +5 -3
  54. package/dist/email/email-footer.js +11 -5
  55. package/dist/email/email.d.ts +31 -9
  56. package/dist/email/email.js +50 -26
  57. package/dist/email/templates.d.ts +10 -9
  58. package/dist/email/templates.js +102 -38
  59. package/dist/email/theme.js +1 -1
  60. package/dist/environment-variables.d.ts +4 -2
  61. package/dist/environment-variables.js +52 -32
  62. package/dist/filter-bar/context.d.ts +32 -0
  63. package/dist/filter-bar/context.js +11 -0
  64. package/dist/filter-bar/editor.d.ts +14 -0
  65. package/dist/filter-bar/editor.js +216 -0
  66. package/dist/filter-bar/model.d.ts +10 -0
  67. package/dist/filter-bar/model.js +57 -0
  68. package/dist/filter-bar/motion.d.ts +10 -0
  69. package/dist/filter-bar/motion.js +84 -0
  70. package/dist/filter-bar/parts.d.ts +19 -0
  71. package/dist/filter-bar/parts.js +244 -0
  72. package/dist/filter-bar/types.d.ts +54 -0
  73. package/dist/filter-bar/types.js +0 -0
  74. package/dist/filter-bar.d.ts +27 -0
  75. package/dist/filter-bar.js +310 -0
  76. package/dist/hooks/use-audio-recorder.js +12 -6
  77. package/dist/hooks/use-chat-composer.d.ts +21 -7
  78. package/dist/hooks/use-chat-composer.js +32 -5
  79. package/dist/hooks/use-chat-message.d.ts +28 -2
  80. package/dist/hooks/use-chat-message.js +41 -10
  81. package/dist/hooks/use-chat-thread-scroll.js +43 -7
  82. package/dist/hooks/use-color-area.d.ts +3 -3
  83. package/dist/hooks/use-color-area.js +13 -12
  84. package/dist/hooks/use-copy-to-clipboard.d.ts +2 -1
  85. package/dist/hooks/use-copy-to-clipboard.js +20 -20
  86. package/dist/hooks/use-dropzone.d.ts +7 -4
  87. package/dist/hooks/use-dropzone.js +34 -3
  88. package/dist/hooks/use-dynamic-notification.d.ts +6 -2
  89. package/dist/hooks/use-dynamic-notification.js +26 -10
  90. package/dist/hooks/use-mobile.d.ts +3 -2
  91. package/dist/hooks/use-mobile.js +8 -4
  92. package/dist/hooks/use-textarea-trigger-menu.js +2 -1
  93. package/dist/hooks/use-trigger-menu.d.ts +54 -0
  94. package/dist/hooks/use-trigger-menu.js +102 -47
  95. package/dist/hooks/use-user-ask.d.ts +2 -0
  96. package/dist/hooks/use-user-ask.js +35 -41
  97. package/dist/inline-attachment.d.ts +6 -2
  98. package/dist/inline-attachment.js +44 -29
  99. package/dist/inline-citation.d.ts +12 -5
  100. package/dist/inline-citation.js +25 -16
  101. package/dist/knob-contracts/audio-recorder-knobs.d.ts +1 -1
  102. package/dist/knob-contracts/audio-recorder-knobs.js +2 -1
  103. package/dist/knob-contracts/audio-visualizer-knobs.d.ts +1 -1
  104. package/dist/knob-contracts/audio-visualizer-knobs.js +2 -1
  105. package/dist/knob-contracts/avatar-knobs.d.ts +1 -1
  106. package/dist/knob-contracts/avatar-knobs.js +6 -1
  107. package/dist/knob-contracts/badge-knobs.d.ts +1 -1
  108. package/dist/knob-contracts/badge-knobs.js +2 -1
  109. package/dist/knob-contracts/breadcrumb-knobs.d.ts +4 -0
  110. package/dist/knob-contracts/breadcrumb-knobs.js +8 -0
  111. package/dist/knob-contracts/button-knobs.d.ts +1 -1
  112. package/dist/knob-contracts/button-knobs.js +1 -0
  113. package/dist/knob-contracts/chat-layout-knobs.d.ts +1 -1
  114. package/dist/knob-contracts/chat-layout-knobs.js +2 -1
  115. package/dist/knob-contracts/chat-message-knobs.d.ts +1 -1
  116. package/dist/knob-contracts/chat-message-knobs.js +8 -1
  117. package/dist/knob-contracts/choice-knobs.d.ts +1 -1
  118. package/dist/knob-contracts/choice-knobs.js +1 -0
  119. package/dist/knob-contracts/code-diff-knobs.d.ts +1 -1
  120. package/dist/knob-contracts/code-diff-knobs.js +2 -0
  121. package/dist/knob-contracts/code-knobs.d.ts +1 -1
  122. package/dist/knob-contracts/code-knobs.js +2 -1
  123. package/dist/knob-contracts/collapsible-knobs.d.ts +1 -1
  124. package/dist/knob-contracts/collapsible-knobs.js +1 -1
  125. package/dist/knob-contracts/dynamic-notification-knobs.d.ts +1 -1
  126. package/dist/knob-contracts/dynamic-notification-knobs.js +2 -0
  127. package/dist/knob-contracts/emoji-picker-knobs.d.ts +4 -0
  128. package/dist/knob-contracts/emoji-picker-knobs.js +10 -0
  129. package/dist/knob-contracts/field-knobs.d.ts +1 -1
  130. package/dist/knob-contracts/field-knobs.js +5 -1
  131. package/dist/knob-contracts/filter-bar-knobs.d.ts +4 -0
  132. package/dist/knob-contracts/filter-bar-knobs.js +15 -0
  133. package/dist/knob-contracts/infinite-canvas-knobs.d.ts +1 -1
  134. package/dist/knob-contracts/infinite-canvas-knobs.js +3 -0
  135. package/dist/knob-contracts/markdown-knobs.d.ts +1 -1
  136. package/dist/knob-contracts/markdown-knobs.js +3 -1
  137. package/dist/knob-contracts/page-layout-knobs.d.ts +1 -1
  138. package/dist/knob-contracts/page-layout-knobs.js +4 -1
  139. package/dist/knob-contracts/popup-knobs.d.ts +1 -1
  140. package/dist/knob-contracts/popup-knobs.js +28 -0
  141. package/dist/knob-contracts/range-knobs.d.ts +1 -1
  142. package/dist/knob-contracts/range-knobs.js +1 -0
  143. package/dist/knob-contracts/rich-tooltip-knobs.d.ts +1 -1
  144. package/dist/knob-contracts/rich-tooltip-knobs.js +2 -1
  145. package/dist/knob-contracts/sidebar-knobs.d.ts +1 -1
  146. package/dist/knob-contracts/sidebar-knobs.js +27 -2
  147. package/dist/knob-contracts/spinner-knobs.d.ts +1 -1
  148. package/dist/knob-contracts/spinner-knobs.js +1 -1
  149. package/dist/knob-contracts/stepper-knobs.d.ts +1 -1
  150. package/dist/knob-contracts/stepper-knobs.js +4 -1
  151. package/dist/knob-contracts/switch-knobs.d.ts +1 -1
  152. package/dist/knob-contracts/switch-knobs.js +5 -0
  153. package/dist/knob-contracts/table-of-contents-knobs.d.ts +1 -1
  154. package/dist/knob-contracts/table-of-contents-knobs.js +4 -5
  155. package/dist/knob-contracts/tabs-knobs.d.ts +1 -1
  156. package/dist/knob-contracts/tabs-knobs.js +1 -0
  157. package/dist/knob-contracts/tree-knobs.d.ts +1 -1
  158. package/dist/knob-contracts/tree-knobs.js +2 -1
  159. package/dist/lib/cn.js +0 -4
  160. package/dist/lib/contrast.d.ts +1 -0
  161. package/dist/lib/contrast.js +17 -5
  162. package/dist/lib/dropzone-validation.js +41 -28
  163. package/dist/lib/env-file.d.ts +1 -1
  164. package/dist/lib/env-file.js +5 -5
  165. package/dist/lib/motion.d.ts +4 -0
  166. package/dist/lib/motion.js +15 -0
  167. package/dist/lib/trigger-detect.js +6 -8
  168. package/dist/markdown-block.js +13 -8
  169. package/dist/popup-parts.d.ts +8 -0
  170. package/dist/popup-parts.js +43 -0
  171. package/dist/scripts/contrast-eval.js +5 -4
  172. package/dist/source-badge.js +3 -1
  173. package/dist/styles/code.css +0 -2
  174. package/dist/styles/effects.css +6 -32
  175. package/dist/styles/index.css +14 -8
  176. package/dist/styles/recipes/accordion.css +9 -6
  177. package/dist/styles/recipes/action-bar.css +0 -15
  178. package/dist/styles/recipes/activity.css +5 -11
  179. package/dist/styles/recipes/alert.css +4 -4
  180. package/dist/styles/recipes/audio-recorder.css +15 -3
  181. package/dist/styles/recipes/audio-visualizer.css +13 -2
  182. package/dist/styles/recipes/avatar.css +78 -1
  183. package/dist/styles/recipes/badge.css +14 -4
  184. package/dist/styles/recipes/breadcrumb.css +77 -0
  185. package/dist/styles/recipes/button-group.css +6 -8
  186. package/dist/styles/recipes/button-states.css +66 -0
  187. package/dist/styles/recipes/button.css +26 -85
  188. package/dist/styles/recipes/calendar.css +17 -23
  189. package/dist/styles/recipes/card.css +2 -2
  190. package/dist/styles/recipes/chat-composer-attachment.css +9 -3
  191. package/dist/styles/recipes/chat-composer.css +21 -16
  192. package/dist/styles/recipes/chat-layout.css +64 -2
  193. package/dist/styles/recipes/chat-message-social.css +123 -0
  194. package/dist/styles/recipes/chat-message.css +157 -37
  195. package/dist/styles/recipes/choice.css +25 -21
  196. package/dist/styles/recipes/code-diff.css +51 -26
  197. package/dist/styles/recipes/code.css +44 -18
  198. package/dist/styles/recipes/collapsible.css +43 -1
  199. package/dist/styles/recipes/color-picker-details.css +3 -4
  200. package/dist/styles/recipes/color-picker-values.css +9 -8
  201. package/dist/styles/recipes/color-picker.css +23 -4
  202. package/dist/styles/recipes/context.css +3 -3
  203. package/dist/styles/recipes/dockable-panel.css +18 -7
  204. package/dist/styles/recipes/dropzone.css +7 -8
  205. package/dist/styles/recipes/dynamic-notification-input.css +8 -5
  206. package/dist/styles/recipes/dynamic-notification-motion.css +12 -21
  207. package/dist/styles/recipes/dynamic-notification.css +40 -26
  208. package/dist/styles/recipes/emoji-picker.css +132 -0
  209. package/dist/styles/recipes/empty.css +5 -4
  210. package/dist/styles/recipes/environment-variables.css +4 -15
  211. package/dist/styles/recipes/field-parts.css +89 -21
  212. package/dist/styles/recipes/field.css +83 -26
  213. package/dist/styles/recipes/filter-bar.css +161 -0
  214. package/dist/styles/recipes/gradient-editor.css +18 -7
  215. package/dist/styles/recipes/infinite-canvas.css +51 -4
  216. package/dist/styles/recipes/inline-attachment.css +9 -4
  217. package/dist/styles/recipes/inline-citation.css +10 -4
  218. package/dist/styles/recipes/item.css +23 -9
  219. package/dist/styles/recipes/markdown-block.css +5 -4
  220. package/dist/styles/recipes/markdown.css +68 -26
  221. package/dist/styles/recipes/morphing-panel.css +8 -8
  222. package/dist/styles/recipes/page-layout.css +36 -10
  223. package/dist/styles/recipes/pagination.css +5 -6
  224. package/dist/styles/recipes/phone-input.css +12 -8
  225. package/dist/styles/recipes/popup-controls.css +175 -26
  226. package/dist/styles/recipes/popup-drawer.css +35 -44
  227. package/dist/styles/recipes/popup-lists.css +139 -29
  228. package/dist/styles/recipes/popup-motion.css +4 -45
  229. package/dist/styles/recipes/popup-toast.css +55 -26
  230. package/dist/styles/recipes/popup.css +149 -153
  231. package/dist/styles/recipes/range.css +55 -19
  232. package/dist/styles/recipes/resizable.css +36 -7
  233. package/dist/styles/recipes/rich-tooltip.css +24 -34
  234. package/dist/styles/recipes/scroll-area.css +8 -1
  235. package/dist/styles/recipes/sidebar-menu.css +149 -34
  236. package/dist/styles/recipes/sidebar-parts.css +154 -0
  237. package/dist/styles/recipes/sidebar.css +187 -128
  238. package/dist/styles/recipes/source-badge.css +1 -1
  239. package/dist/styles/recipes/spinner.css +12 -1
  240. package/dist/styles/recipes/stepper.css +31 -13
  241. package/dist/styles/recipes/switch.css +68 -23
  242. package/dist/styles/recipes/table-of-contents.css +49 -41
  243. package/dist/styles/recipes/table.css +14 -10
  244. package/dist/styles/recipes/tabs.css +38 -12
  245. package/dist/styles/recipes/task-list.css +7 -14
  246. package/dist/styles/recipes/thread-rail.css +42 -19
  247. package/dist/styles/recipes/timeline.css +2 -0
  248. package/dist/styles/recipes/toolbar.css +27 -25
  249. package/dist/styles/recipes/track-highlight.css +12 -8
  250. package/dist/styles/recipes/transcript-divider.css +2 -2
  251. package/dist/styles/recipes/tree.css +31 -4
  252. package/dist/styles/recipes/user-ask-details.css +0 -1
  253. package/dist/styles/recipes/user-ask.css +4 -4
  254. package/dist/styles/theme.css +287 -107
  255. package/dist/task-list.d.ts +4 -1
  256. package/dist/task-list.js +24 -8
  257. package/dist/thread-rail.d.ts +1 -1
  258. package/dist/thread-rail.js +61 -19
  259. package/dist/transcript-divider.js +2 -1
  260. package/dist/ui/alert.d.ts +3 -1
  261. package/dist/ui/alert.js +14 -8
  262. package/dist/ui/autocomplete.js +7 -1
  263. package/dist/ui/avatar.d.ts +8 -0
  264. package/dist/ui/avatar.js +23 -3
  265. package/dist/ui/badge.js +1 -1
  266. package/dist/ui/breadcrumb.d.ts +27 -0
  267. package/dist/ui/breadcrumb.js +88 -0
  268. package/dist/ui/button.d.ts +2 -1
  269. package/dist/ui/button.js +1 -1
  270. package/dist/ui/calendar.js +2 -2
  271. package/dist/ui/card.d.ts +3 -1
  272. package/dist/ui/card.js +12 -7
  273. package/dist/ui/checkbox-group.js +1 -1
  274. package/dist/ui/checkbox.d.ts +2 -0
  275. package/dist/ui/code-diff.d.ts +1 -1
  276. package/dist/ui/code-diff.js +71 -27
  277. package/dist/ui/code.d.ts +5 -3
  278. package/dist/ui/code.js +27 -28
  279. package/dist/ui/color-picker.d.ts +5 -2
  280. package/dist/ui/color-picker.js +84 -36
  281. package/dist/ui/combobox-disabled-selection.d.ts +1 -2
  282. package/dist/ui/combobox-disabled-selection.js +7 -8
  283. package/dist/ui/combobox.d.ts +5 -23
  284. package/dist/ui/combobox.js +36 -16
  285. package/dist/ui/command.d.ts +8 -2
  286. package/dist/ui/command.js +39 -15
  287. package/dist/ui/context-menu.js +3 -0
  288. package/dist/ui/dialog.d.ts +2 -1
  289. package/dist/ui/dialog.js +3 -22
  290. package/dist/ui/dockable-panel-geometry.d.ts +1 -0
  291. package/dist/ui/dockable-panel-geometry.js +7 -1
  292. package/dist/ui/dockable-panel.d.ts +9 -6
  293. package/dist/ui/dockable-panel.js +81 -33
  294. package/dist/ui/drawer.d.ts +7 -4
  295. package/dist/ui/drawer.js +35 -22
  296. package/dist/ui/dropdown-menu.js +4 -3
  297. package/dist/ui/dropzone.d.ts +5 -3
  298. package/dist/ui/dropzone.js +78 -17
  299. package/dist/ui/emoji-picker.d.ts +18 -0
  300. package/dist/ui/emoji-picker.js +136 -0
  301. package/dist/ui/empty.d.ts +3 -1
  302. package/dist/ui/empty.js +12 -7
  303. package/dist/ui/field.js +1 -1
  304. package/dist/ui/gradient-editor.d.ts +1 -1
  305. package/dist/ui/gradient-editor.js +37 -21
  306. package/dist/ui/infinite-canvas.d.ts +13 -1
  307. package/dist/ui/infinite-canvas.js +139 -20
  308. package/dist/ui/input-group.d.ts +2 -4
  309. package/dist/ui/input-group.js +13 -14
  310. package/dist/ui/input-otp.d.ts +1 -1
  311. package/dist/ui/input-otp.js +32 -15
  312. package/dist/ui/input.js +11 -2
  313. package/dist/ui/item.d.ts +2 -1
  314. package/dist/ui/item.js +11 -7
  315. package/dist/ui/live-status.d.ts +7 -0
  316. package/dist/ui/live-status.js +17 -0
  317. package/dist/ui/markdown-elements.d.ts +6 -0
  318. package/dist/ui/markdown-elements.js +42 -9
  319. package/dist/ui/menubar.js +2 -2
  320. package/dist/ui/morphing-panel.js +2 -1
  321. package/dist/ui/native-select.d.ts +1 -1
  322. package/dist/ui/native-select.js +24 -11
  323. package/dist/ui/number-field.d.ts +1 -1
  324. package/dist/ui/number-field.js +13 -2
  325. package/dist/ui/page-layout.d.ts +2 -2
  326. package/dist/ui/page-layout.js +2 -4
  327. package/dist/ui/pagination.d.ts +7 -5
  328. package/dist/ui/pagination.js +19 -13
  329. package/dist/ui/phone-input.d.ts +1 -0
  330. package/dist/ui/phone-input.js +56 -58
  331. package/dist/ui/radio-group.d.ts +3 -0
  332. package/dist/ui/radio-group.js +11 -1
  333. package/dist/ui/resizable.d.ts +20 -2
  334. package/dist/ui/resizable.js +130 -8
  335. package/dist/ui/responsive-dialog.d.ts +1 -1
  336. package/dist/ui/responsive-dialog.js +9 -23
  337. package/dist/ui/rich-tooltip.d.ts +10 -4
  338. package/dist/ui/rich-tooltip.js +81 -33
  339. package/dist/ui/scroll-area.d.ts +4 -1
  340. package/dist/ui/scroll-area.js +44 -28
  341. package/dist/ui/select.d.ts +2 -1
  342. package/dist/ui/select.js +57 -32
  343. package/dist/ui/sidebar-menu.d.ts +5 -1
  344. package/dist/ui/sidebar-menu.js +31 -33
  345. package/dist/ui/sidebar-provider.d.ts +10 -1
  346. package/dist/ui/sidebar-provider.js +38 -13
  347. package/dist/ui/sidebar-resize-rail.js +7 -3
  348. package/dist/ui/sidebar.d.ts +11 -6
  349. package/dist/ui/sidebar.js +46 -23
  350. package/dist/ui/slider.js +31 -22
  351. package/dist/ui/spinner.d.ts +3 -2
  352. package/dist/ui/spinner.js +3 -2
  353. package/dist/ui/stepper.d.ts +8 -1
  354. package/dist/ui/stepper.js +74 -25
  355. package/dist/ui/switch.d.ts +1 -0
  356. package/dist/ui/table-of-contents.d.ts +5 -4
  357. package/dist/ui/table-of-contents.js +143 -52
  358. package/dist/ui/table.js +15 -9
  359. package/dist/ui/textarea.d.ts +1 -1
  360. package/dist/ui/textarea.js +20 -9
  361. package/dist/ui/timeline.d.ts +3 -1
  362. package/dist/ui/timeline.js +17 -9
  363. package/dist/ui/toast.d.ts +11 -5
  364. package/dist/ui/toast.js +100 -54
  365. package/dist/ui/toggle.d.ts +1 -1
  366. package/dist/ui/toggle.js +2 -1
  367. package/dist/ui/toolbar.d.ts +3 -2
  368. package/dist/ui/toolbar.js +4 -2
  369. package/dist/ui/tooltip.js +3 -20
  370. package/dist/ui/tree.js +120 -80
  371. package/dist/ui/trigger-menu.js +7 -2
  372. package/dist/user-ask.d.ts +10 -5
  373. package/dist/user-ask.js +31 -11
  374. package/package.json +5 -1
  375. package/dist/hooks/use-keyboard-navigation.d.ts +0 -3
  376. package/dist/hooks/use-keyboard-navigation.js +0 -22
@@ -0,0 +1,19 @@
1
+ import { ButtonProps } from "../ui/button.js";
2
+ import { FilterBarKnobStyle } from "../knob-contracts/filter-bar-knobs.js";
3
+ import { FilterBarInlineInput } from "./editor.js";
4
+ import { FilterBarItem } from "./types.js";
5
+ import { CSSProperties, ComponentProps, ReactNode } from "react";
6
+ //#region src/filter-bar/parts.d.ts
7
+ export type FilterBarChipProps = ComponentProps<"div"> & {
8
+ item: FilterBarItem;
9
+ readOnly?: boolean;
10
+ style?: CSSProperties & FilterBarKnobStyle;
11
+ };
12
+ export declare function FilterBarChip(props: FilterBarChipProps): import("react").JSX.Element;
13
+ export declare function FilterBarChips({ renderChip }: {
14
+ renderChip?: (item: FilterBarItem) => ReactNode;
15
+ }): import("react").JSX.Element;
16
+ export declare function FilterBarAddButton({ className, children, onClick, onKeyDown, ref, ...props }: ButtonProps): import("react").JSX.Element;
17
+ export declare function FilterBarInput({ className, ...props }: Omit<Parameters<typeof FilterBarInlineInput>[0], "owner" | "inputRef">): import("react").JSX.Element;
18
+ export declare function FilterBarClear({ children, onClick, ...props }: ButtonProps): import("react").JSX.Element | null;
19
+ //#endregion
@@ -0,0 +1,244 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.js";
3
+ import { Button } from "../ui/button.js";
4
+ import { useFilterBarContext } from "./context.js";
5
+ import { describeFilter, formatFilterValue } from "./model.js";
6
+ import { FilterBarEditor, FilterBarInlineInput } from "./editor.js";
7
+ import { useEffect, useId, useRef } from "react";
8
+ import { useRender } from "@base-ui/react/use-render";
9
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
10
+ import { PlusIcon, XIcon } from "lucide-react";
11
+ //#region src/filter-bar/parts.tsx
12
+ function chipSegments(item, field, operator, draft) {
13
+ const segments = [{
14
+ stage: "field",
15
+ label: field?.label ?? item.fieldId,
16
+ icon: field?.icon
17
+ }];
18
+ if (operator || draft) segments.push({
19
+ stage: "operator",
20
+ label: operator?.label ?? "Operator…",
21
+ spokenLabel: operator?.ariaLabel
22
+ });
23
+ if (item.value !== null || draft && operator) segments.push({
24
+ stage: "value",
25
+ label: item.value === null ? "Value…" : formatFilterValue(item, field)
26
+ });
27
+ return segments;
28
+ }
29
+ function FilterBarChipContent({ item, readOnly = false, className, ref, ...props }) {
30
+ const context = useFilterBarContext();
31
+ const field = context.fields.find((candidate) => candidate.id === item.fieldId);
32
+ const operator = context.operators.find((candidate) => candidate.id === item.operatorId);
33
+ const draft = Boolean(context.draft?.id === item.id && !context.draft.editing);
34
+ const locked = readOnly || context.readOnly;
35
+ const segments = chipSegments(item, field, operator, draft);
36
+ return useRender({
37
+ ref: [ref ?? null, locked ? null : (element) => context.register(`chip:${item.id}`, element)],
38
+ render: /* @__PURE__ */ jsxs("div", {
39
+ "data-control-ui": "filter-bar",
40
+ "data-control-family": "filter-bar",
41
+ "data-slot": "chip",
42
+ "data-draft": draft || void 0,
43
+ className: cn("inline-flex max-w-full min-w-0 items-stretch overflow-hidden", className),
44
+ ...props,
45
+ children: [segments.map((segment) => /* @__PURE__ */ jsx(FilterBarSegment, {
46
+ item,
47
+ segment,
48
+ locked,
49
+ draft
50
+ }, segment.stage)), !locked && !draft && /* @__PURE__ */ jsx(Button, {
51
+ ref: (element) => context.register(`${item.id}:remove`, element),
52
+ variant: "ghost",
53
+ size: "sm",
54
+ iconOnly: true,
55
+ "data-control-ui": "filter-bar",
56
+ "data-control-family": "filter-bar",
57
+ "data-slot": "remove",
58
+ "aria-label": `Remove filter: ${describeFilter(item, context.fields, context.operators)}`,
59
+ disabled: context.disabled,
60
+ onClick: () => context.remove(item),
61
+ onKeyDown: (event) => context.navigate(event, item.id, "remove"),
62
+ children: /* @__PURE__ */ jsx(XIcon, {
63
+ "aria-hidden": "true",
64
+ className: "size-3"
65
+ })
66
+ })]
67
+ })
68
+ });
69
+ }
70
+ function FilterBarSegment({ item, segment, locked, draft }) {
71
+ const context = useFilterBarContext();
72
+ if (locked) return /* @__PURE__ */ jsx("span", {
73
+ "data-control-ui": "filter-bar",
74
+ "data-control-family": "filter-bar",
75
+ "data-slot": "segment",
76
+ className: "inline-flex min-w-0 items-center",
77
+ children: /* @__PURE__ */ jsxs("span", {
78
+ className: "flex min-w-0 items-center gap-1.5",
79
+ children: [
80
+ segment.icon,
81
+ /* @__PURE__ */ jsx("span", {
82
+ className: "truncate",
83
+ title: segment.label,
84
+ "aria-hidden": segment.spokenLabel ? true : void 0,
85
+ children: segment.label
86
+ }),
87
+ segment.spokenLabel ? /* @__PURE__ */ jsx("span", {
88
+ className: "sr-only",
89
+ children: segment.spokenLabel
90
+ }) : null
91
+ ]
92
+ })
93
+ });
94
+ return /* @__PURE__ */ jsxs(Button, {
95
+ ref: (element) => context.register(`${item.id}:${segment.stage}`, element),
96
+ variant: "ghost",
97
+ size: "sm",
98
+ "data-control-ui": "filter-bar",
99
+ "data-control-family": "filter-bar",
100
+ "data-slot": "segment",
101
+ className: "shrink",
102
+ "aria-label": `Edit ${segment.stage}: ${segment.spokenLabel ?? segment.label}`,
103
+ "aria-haspopup": "listbox",
104
+ "aria-expanded": context.draft?.owner === item.id && context.draft.stage === segment.stage,
105
+ disabled: context.disabled || draft,
106
+ onClick: (event) => context.start(item.id, event.currentTarget, segment.stage, item),
107
+ onKeyDown: (event) => context.navigate(event, item.id, segment.stage),
108
+ children: [segment.icon, /* @__PURE__ */ jsx("span", {
109
+ className: "truncate",
110
+ title: segment.label,
111
+ children: segment.label
112
+ })]
113
+ });
114
+ }
115
+ function FilterBarChip(props) {
116
+ return /* @__PURE__ */ jsx(FilterBarEditor, {
117
+ owner: props.item.id,
118
+ mode: "button",
119
+ children: /* @__PURE__ */ jsx(FilterBarChipContent, { ...props })
120
+ });
121
+ }
122
+ function ExitingChip({ item, style }) {
123
+ const context = useFilterBarContext();
124
+ const ref = useRef(null);
125
+ const releaseExit = context.releaseExit;
126
+ useEffect(() => {
127
+ const animations = ref.current?.getAnimations({ subtree: true }) ?? [];
128
+ let mounted = true;
129
+ const release = () => {
130
+ if (mounted) releaseExit(item.id);
131
+ };
132
+ if (animations.length === 0) release();
133
+ else Promise.all(animations.map((animation) => animation.finished)).then(release, release);
134
+ return () => {
135
+ mounted = false;
136
+ };
137
+ }, [item.id, releaseExit]);
138
+ return /* @__PURE__ */ jsx("div", {
139
+ ref,
140
+ style,
141
+ "data-control-ui": "filter-bar",
142
+ "data-control-family": "filter-bar",
143
+ "data-slot": "exit",
144
+ "aria-hidden": "true",
145
+ inert: true,
146
+ children: /* @__PURE__ */ jsx(FilterBarChipContent, {
147
+ item,
148
+ readOnly: true
149
+ })
150
+ });
151
+ }
152
+ function FilterBarChips({ renderChip }) {
153
+ const context = useFilterBarContext();
154
+ const items = [...context.items];
155
+ const draft = context.draft;
156
+ if (draft?.fieldId && !draft.editing) items.push({
157
+ id: draft.id,
158
+ fieldId: draft.fieldId,
159
+ operatorId: draft.operatorId ?? "",
160
+ value: draft.values.length > 0 ? draft.values : null
161
+ });
162
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [items.map((item) => /* @__PURE__ */ jsx(FilterBarChipContentWithEditor, {
163
+ item,
164
+ renderChip
165
+ }, item.id)), context.exits.map((exit) => /* @__PURE__ */ jsx(ExitingChip, { ...exit }, exit.item.id))] });
166
+ }
167
+ function FilterBarChipContentWithEditor({ item, renderChip }) {
168
+ const context = useFilterBarContext();
169
+ return renderChip && item.id !== context.draft?.id ? renderChip(item) : /* @__PURE__ */ jsx(FilterBarChip, { item });
170
+ }
171
+ function FilterBarAddButton({ className, children = "Add filter", onClick, onKeyDown, ref, ...props }) {
172
+ const context = useFilterBarContext();
173
+ const owner = useId();
174
+ const button = useRender({
175
+ ref: [ref ?? null, (element) => context.register(`entry:${owner}`, element)],
176
+ render: /* @__PURE__ */ jsxs(Button, {
177
+ variant: "ghost",
178
+ size: "sm",
179
+ className,
180
+ "aria-haspopup": "listbox",
181
+ "aria-expanded": context.draft?.owner === owner,
182
+ disabled: context.disabled || context.readOnly,
183
+ ...props,
184
+ onClick: (event) => {
185
+ onClick?.(event);
186
+ if (!event.defaultPrevented) context.start(owner, event.currentTarget);
187
+ },
188
+ onKeyDown: (event) => {
189
+ onKeyDown?.(event);
190
+ context.navigate(event);
191
+ },
192
+ children: [/* @__PURE__ */ jsx(PlusIcon, {
193
+ "aria-hidden": "true",
194
+ className: "size-3.5"
195
+ }), children]
196
+ })
197
+ });
198
+ return /* @__PURE__ */ jsx(FilterBarEditor, {
199
+ owner,
200
+ mode: "button",
201
+ children: button
202
+ });
203
+ }
204
+ function FilterBarInput({ className, ...props }) {
205
+ const context = useFilterBarContext();
206
+ const owner = useId();
207
+ const inputRef = useRef(null);
208
+ return /* @__PURE__ */ jsx(FilterBarEditor, {
209
+ owner,
210
+ mode: "input",
211
+ anchorRef: inputRef,
212
+ children: /* @__PURE__ */ jsx("div", {
213
+ ref: (element) => context.register(`entry:${owner}`, element ? inputRef.current : null),
214
+ className: cn("min-w-0 max-w-full flex-[1_1_10rem]", className),
215
+ children: /* @__PURE__ */ jsx(FilterBarInlineInput, {
216
+ owner,
217
+ inputRef,
218
+ "aria-label": "Add filter",
219
+ placeholder: "Filter…",
220
+ disabled: context.disabled,
221
+ readOnly: context.readOnly,
222
+ ...props
223
+ })
224
+ })
225
+ });
226
+ }
227
+ function FilterBarClear({ children = "Clear", onClick, ...props }) {
228
+ const context = useFilterBarContext();
229
+ if (context.items.length === 0 && !context.draft) return null;
230
+ return /* @__PURE__ */ jsx(Button, {
231
+ variant: "ghost",
232
+ size: "sm",
233
+ "aria-label": "Clear filters",
234
+ disabled: context.disabled || context.readOnly,
235
+ ...props,
236
+ onClick: (event) => {
237
+ onClick?.(event);
238
+ if (!event.defaultPrevented) context.clear();
239
+ },
240
+ children
241
+ });
242
+ }
243
+ //#endregion
244
+ export { FilterBarAddButton, FilterBarChip, FilterBarChips, FilterBarClear, FilterBarInput };
@@ -0,0 +1,54 @@
1
+ import { ReactNode } from "react";
2
+ //#region src/filter-bar/types.d.ts
3
+ export type FilterBarScalar = string | number | boolean;
4
+ export type FilterBarValue = FilterBarScalar | FilterBarScalar[] | null;
5
+ export type FilterBarOperator = {
6
+ id: string;
7
+ label: string;
8
+ ariaLabel?: string;
9
+ arity?: "none" | "one" | "many";
10
+ };
11
+ export type FilterBarOption = {
12
+ value: FilterBarScalar;
13
+ label: string;
14
+ icon?: ReactNode;
15
+ disabled?: boolean;
16
+ };
17
+ export type FilterBarQuery = {
18
+ fieldId: string;
19
+ operatorId: string;
20
+ query: string;
21
+ };
22
+ export type FilterBarField = {
23
+ id: string;
24
+ label: string;
25
+ icon?: ReactNode;
26
+ type?: "text" | "number" | "boolean";
27
+ operators?: readonly string[];
28
+ options?: readonly FilterBarOption[];
29
+ allowCustomValue?: boolean;
30
+ optionsMode?: "local" | "remote";
31
+ loading?: boolean;
32
+ error?: ReactNode;
33
+ onQueryChange?: (query: FilterBarQuery) => void;
34
+ formatValue?: (value: FilterBarScalar) => string;
35
+ };
36
+ export type FilterBarItem = {
37
+ id: string;
38
+ fieldId: string;
39
+ operatorId: string;
40
+ value: FilterBarValue;
41
+ };
42
+ export type FilterBarStage = "field" | "operator" | "value";
43
+ export type FilterBarDraft = {
44
+ id: string;
45
+ owner: string;
46
+ anchor: HTMLElement;
47
+ stage: FilterBarStage;
48
+ fieldId?: string;
49
+ operatorId?: string;
50
+ values: FilterBarScalar[];
51
+ query: string;
52
+ editing: boolean;
53
+ };
54
+ //#endregion
File without changes
@@ -0,0 +1,27 @@
1
+ import { FilterBarKnobStyle } from "./knob-contracts/filter-bar-knobs.js";
2
+ import { FilterBarField, FilterBarItem, FilterBarOperator, FilterBarOption, FilterBarQuery, FilterBarScalar, FilterBarValue } from "./filter-bar/types.js";
3
+ import { FilterBarAddButton, FilterBarChip, FilterBarChipProps, FilterBarChips, FilterBarClear, FilterBarInput } from "./filter-bar/parts.js";
4
+ import { CSSProperties, ComponentProps } from "react";
5
+ //#region src/filter-bar.d.ts
6
+ export type FilterBarRootProps = Omit<ComponentProps<"fieldset">, "onChange" | "style"> & {
7
+ fields: readonly FilterBarField[];
8
+ operators: readonly FilterBarOperator[];
9
+ value: readonly FilterBarItem[];
10
+ onValueChange: (value: FilterBarItem[]) => void;
11
+ createItemId?: () => string;
12
+ disabled?: boolean;
13
+ readOnly?: boolean;
14
+ style?: CSSProperties & FilterBarKnobStyle;
15
+ };
16
+ declare function FilterBarRoot({ fields, operators, value, onValueChange, createItemId, disabled, readOnly, className, children, ref, "aria-label": ariaLabel, ...props }: FilterBarRootProps): import("react").JSX.Element;
17
+ export declare const FilterBar: {
18
+ Root: typeof FilterBarRoot;
19
+ Chips: typeof FilterBarChips;
20
+ Chip: typeof FilterBarChip;
21
+ AddButton: typeof FilterBarAddButton;
22
+ Input: typeof FilterBarInput;
23
+ Clear: typeof FilterBarClear;
24
+ };
25
+ export declare const DEFAULT_FILTER_OPERATORS: readonly FilterBarOperator[];
26
+ //#endregion
27
+ export type { FilterBarChipProps, FilterBarField, FilterBarItem, FilterBarOperator, FilterBarOption, FilterBarQuery, FilterBarScalar, FilterBarValue };
@@ -0,0 +1,310 @@
1
+ "use client";
2
+ import { cn } from "./lib/cn.js";
3
+ import { LiveStatus } from "./ui/live-status.js";
4
+ import { FilterBarContext } from "./filter-bar/context.js";
5
+ import { describeFilter, fieldOperators, filterNavigationKeys } from "./filter-bar/model.js";
6
+ import { filterMotionEnabled, useFilterBarMotion } from "./filter-bar/motion.js";
7
+ import { FilterBarAddButton, FilterBarChip, FilterBarChips, FilterBarClear, FilterBarInput } from "./filter-bar/parts.js";
8
+ import { useState } from "react";
9
+ import { useRender } from "@base-ui/react/use-render";
10
+ import { jsx, jsxs } from "react/jsx-runtime";
11
+ //#region src/filter-bar.tsx
12
+ function valueStatusMessage(field) {
13
+ if (field?.error) return typeof field.error === "string" ? field.error : "Couldn’t load values.";
14
+ if (field?.loading) return "Loading values…";
15
+ }
16
+ function FilterBarRoot({ fields, operators, value, onValueChange, createItemId = () => crypto.randomUUID(), disabled = false, readOnly = false, className, children, ref, "aria-label": ariaLabel = "Filters", ...props }) {
17
+ const [draft, setDraft] = useState(null);
18
+ const [exits, setExits] = useState([]);
19
+ const [announcement, setAnnouncement] = useState("");
20
+ const [focusNodes] = useState(() => /* @__PURE__ */ new Map());
21
+ const { rootRef, ...motion } = useFilterBarMotion();
22
+ function register(key, element) {
23
+ if (key.startsWith("chip:") || key.startsWith("entry:")) motion.register(key, element);
24
+ if (element) focusNodes.set(key, element);
25
+ else focusNodes.delete(key);
26
+ }
27
+ function transition(next) {
28
+ motion.capture();
29
+ setDraft(next);
30
+ if (next.stage === "value" && next.fieldId && next.operatorId) fields.find((field) => field.id === next.fieldId)?.onQueryChange?.({
31
+ fieldId: next.fieldId,
32
+ operatorId: next.operatorId,
33
+ query: next.query
34
+ });
35
+ }
36
+ function start(owner, anchor, stage = "field", item, initialQuery) {
37
+ if (disabled || readOnly) return;
38
+ if (draft?.owner === owner && draft.stage === stage) return;
39
+ const values = item?.value === null || item?.value === void 0 ? [] : [item.value].flat();
40
+ const query = initialQuery ?? "";
41
+ transition({
42
+ id: item?.id ?? createItemId(),
43
+ owner,
44
+ anchor,
45
+ stage,
46
+ fieldId: item?.fieldId,
47
+ operatorId: item?.operatorId,
48
+ values,
49
+ query,
50
+ editing: Boolean(item)
51
+ });
52
+ }
53
+ function close(restoreFocus = true) {
54
+ motion.capture();
55
+ if (restoreFocus && draft?.anchor.isConnected) draft.anchor.focus();
56
+ setDraft(null);
57
+ }
58
+ function back() {
59
+ if (!draft) return;
60
+ if (draft.stage === "field") return close();
61
+ if (draft.stage === "operator") return transition({
62
+ ...draft,
63
+ stage: "field",
64
+ operatorId: void 0,
65
+ values: [],
66
+ query: ""
67
+ });
68
+ const field = fields.find((candidate) => candidate.id === draft.fieldId);
69
+ const stage = field && fieldOperators(field, operators).length === 1 ? "field" : "operator";
70
+ transition({
71
+ ...draft,
72
+ stage,
73
+ values: [],
74
+ query: ""
75
+ });
76
+ }
77
+ function setQuery(query) {
78
+ if (!draft) return;
79
+ setDraft({
80
+ ...draft,
81
+ query
82
+ });
83
+ if (draft.stage === "value" && draft.fieldId && draft.operatorId) fields.find((field) => field.id === draft.fieldId)?.onQueryChange?.({
84
+ fieldId: draft.fieldId,
85
+ operatorId: draft.operatorId,
86
+ query
87
+ });
88
+ }
89
+ function commitDraft(next, nextValue) {
90
+ if (disabled || readOnly) return;
91
+ if (!next.fieldId || !next.operatorId) return;
92
+ const item = {
93
+ id: next.id,
94
+ fieldId: next.fieldId,
95
+ operatorId: next.operatorId,
96
+ value: nextValue
97
+ };
98
+ motion.capture();
99
+ onValueChange(next.editing ? value.map((current) => current.id === item.id ? item : current) : [...value, item]);
100
+ setAnnouncement(`${next.editing ? "Updated" : "Added"} filter: ${describeFilter(item, fields, operators)}`);
101
+ if (next.anchor.isConnected) next.anchor.focus();
102
+ setDraft(null);
103
+ }
104
+ function selectOperator(operatorId, next = draft) {
105
+ if (!next) return;
106
+ const operator = operators.find((candidate) => candidate.id === operatorId);
107
+ if (!operator) return;
108
+ const nextDraft = {
109
+ ...next,
110
+ operatorId,
111
+ stage: "value",
112
+ values: [],
113
+ query: ""
114
+ };
115
+ if (operator.arity === "none") commitDraft(nextDraft, null);
116
+ else transition(nextDraft);
117
+ }
118
+ function selectField(fieldId) {
119
+ if (!draft) return;
120
+ const field = fields.find((candidate) => candidate.id === fieldId);
121
+ if (!field) return;
122
+ const available = fieldOperators(field, operators);
123
+ const next = {
124
+ ...draft,
125
+ fieldId,
126
+ operatorId: void 0,
127
+ stage: "operator",
128
+ values: [],
129
+ query: ""
130
+ };
131
+ if (available.length === 1 && available[0]) selectOperator(available[0].id, next);
132
+ else transition(next);
133
+ }
134
+ function addExits(items) {
135
+ const root = rootRef.current;
136
+ if (!root || !filterMotionEnabled(root)) return;
137
+ const rootBounds = root.getBoundingClientRect();
138
+ const leaving = items.flatMap((item) => {
139
+ const node = focusNodes.get(`chip:${item.id}`);
140
+ if (!node) return [];
141
+ const bounds = node.getBoundingClientRect();
142
+ return [{
143
+ item,
144
+ style: {
145
+ position: "absolute",
146
+ left: bounds.left - rootBounds.left,
147
+ top: bounds.top - rootBounds.top,
148
+ width: bounds.width,
149
+ height: bounds.height
150
+ }
151
+ }];
152
+ });
153
+ setExits((current) => [...current, ...leaving]);
154
+ }
155
+ function focusEntry() {
156
+ [...focusNodes].find(([key]) => key.startsWith("entry:"))?.[1].focus();
157
+ }
158
+ function remove(item) {
159
+ if (disabled || readOnly) return;
160
+ motion.capture();
161
+ addExits([item]);
162
+ const index = value.findIndex((candidate) => candidate.id === item.id);
163
+ const neighbour = value[index + 1] ?? value[index - 1];
164
+ if (neighbour) focusNodes.get(`${neighbour.id}:field`)?.focus();
165
+ else focusEntry();
166
+ if (draft?.id === item.id) setDraft(null);
167
+ onValueChange(value.filter((candidate) => candidate.id !== item.id));
168
+ setAnnouncement(`Removed filter: ${describeFilter(item, fields, operators)}`);
169
+ }
170
+ function clear() {
171
+ if (disabled || readOnly) return;
172
+ motion.capture();
173
+ addExits(value);
174
+ setDraft(null);
175
+ onValueChange([]);
176
+ focusEntry();
177
+ setAnnouncement("Cleared all filters");
178
+ }
179
+ function deleteFocusedFilter(event, itemId) {
180
+ const item = value.find((candidate) => candidate.id === itemId);
181
+ if (!item) return;
182
+ event.preventDefault();
183
+ remove(item);
184
+ }
185
+ function focusAdjacentFilter(event, itemId, part) {
186
+ const keys = filterNavigationKeys(value);
187
+ const target = keys[(itemId ? keys.indexOf(`${itemId}:${part}`) : keys.length) + (event.key === "ArrowLeft" ? -1 : 1)];
188
+ event.preventDefault();
189
+ if (target) focusNodes.get(target)?.focus();
190
+ else if (itemId) focusEntry();
191
+ }
192
+ function navigate(event, itemId, part) {
193
+ if (event.defaultPrevented) return;
194
+ const removing = event.key === "Delete" || event.key === "Backspace";
195
+ if (itemId && removing) return deleteFocusedFilter(event, itemId);
196
+ if (event.key === "ArrowLeft" || event.key === "ArrowRight") focusAdjacentFilter(event, itemId, part);
197
+ }
198
+ const context = {
199
+ fields,
200
+ operators,
201
+ items: value,
202
+ draft,
203
+ exits,
204
+ disabled,
205
+ readOnly,
206
+ register,
207
+ start,
208
+ close,
209
+ back,
210
+ setQuery,
211
+ selectField,
212
+ selectOperator,
213
+ selectValues: (values) => {
214
+ if (draft) transition({
215
+ ...draft,
216
+ values,
217
+ query: ""
218
+ });
219
+ },
220
+ commit: (nextValue) => {
221
+ if (draft) commitDraft(draft, nextValue);
222
+ },
223
+ remove,
224
+ clear,
225
+ releaseExit: (id) => setExits((current) => current.filter((exit) => exit.item.id !== id)),
226
+ navigate
227
+ };
228
+ const liveMessage = valueStatusMessage(draft?.stage === "value" ? fields.find((field) => field.id === draft.fieldId) : void 0) ?? announcement;
229
+ const rootElement = useRender({
230
+ ref: [rootRef, ref ?? null],
231
+ render: /* @__PURE__ */ jsxs("fieldset", {
232
+ "aria-label": ariaLabel,
233
+ "data-control-ui": "filter-bar",
234
+ "data-control-family": "filter-bar",
235
+ "data-slot": "root",
236
+ "data-disabled": disabled || void 0,
237
+ "data-readonly": readOnly || void 0,
238
+ className: cn("relative flex min-w-0 flex-wrap items-center", className),
239
+ ...props,
240
+ children: [children, /* @__PURE__ */ jsx(LiveStatus, { message: liveMessage })]
241
+ })
242
+ });
243
+ return /* @__PURE__ */ jsx(FilterBarContext.Provider, {
244
+ value: context,
245
+ children: rootElement
246
+ });
247
+ }
248
+ const FilterBar = {
249
+ Root: FilterBarRoot,
250
+ Chips: FilterBarChips,
251
+ Chip: FilterBarChip,
252
+ AddButton: FilterBarAddButton,
253
+ Input: FilterBarInput,
254
+ Clear: FilterBarClear
255
+ };
256
+ const DEFAULT_FILTER_OPERATORS = [
257
+ {
258
+ id: "is",
259
+ label: "is"
260
+ },
261
+ {
262
+ id: "is-not",
263
+ label: "is not"
264
+ },
265
+ {
266
+ id: "contains",
267
+ label: "contains"
268
+ },
269
+ {
270
+ id: "starts-with",
271
+ label: "starts with"
272
+ },
273
+ {
274
+ id: "gt",
275
+ label: ">",
276
+ ariaLabel: "greater than"
277
+ },
278
+ {
279
+ id: "gte",
280
+ label: "≥",
281
+ ariaLabel: "at least"
282
+ },
283
+ {
284
+ id: "lt",
285
+ label: "<",
286
+ ariaLabel: "less than"
287
+ },
288
+ {
289
+ id: "lte",
290
+ label: "≤",
291
+ ariaLabel: "at most"
292
+ },
293
+ {
294
+ id: "in",
295
+ label: "is any of",
296
+ arity: "many"
297
+ },
298
+ {
299
+ id: "is-empty",
300
+ label: "is empty",
301
+ arity: "none"
302
+ },
303
+ {
304
+ id: "is-not-empty",
305
+ label: "is not empty",
306
+ arity: "none"
307
+ }
308
+ ];
309
+ //#endregion
310
+ export { DEFAULT_FILTER_OPERATORS, FilterBar };