@brainfish-ai/components 0.26.0 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (243) hide show
  1. package/dist/alert-dialog.d.ts +6 -2
  2. package/dist/button.d.ts +4 -2
  3. package/dist/chat-search.d.ts +14 -1
  4. package/dist/confirm-dialog.d.ts +3 -1
  5. package/dist/convos.d.ts +3 -0
  6. package/dist/esm/chunks/ChatSearch.bblH7kYY.js +95 -0
  7. package/dist/esm/chunks/ChatSearch.bblH7kYY.js.map +1 -0
  8. package/dist/esm/chunks/Conversation.CuRp-tJL.js +22 -0
  9. package/dist/esm/chunks/{Conversation.BriXFYqU.js.map → Conversation.CuRp-tJL.js.map} +1 -1
  10. package/dist/esm/chunks/FormattedMessage.XNMN23hm.js +23 -0
  11. package/dist/esm/chunks/FormattedMessage.XNMN23hm.js.map +1 -0
  12. package/dist/esm/chunks/MermaidDiagram.PRgXQ5Yh.js +2 -0
  13. package/dist/esm/chunks/{MermaidDiagram.xQ0CVFOI.js.map → MermaidDiagram.PRgXQ5Yh.js.map} +1 -1
  14. package/dist/esm/chunks/_commonjsHelpers.lGe4XDVY.js +2 -0
  15. package/dist/esm/chunks/_commonjsHelpers.lGe4XDVY.js.map +1 -0
  16. package/dist/esm/chunks/button.D_2SonNs.js +3 -0
  17. package/dist/esm/chunks/button.D_2SonNs.js.map +1 -0
  18. package/dist/esm/chunks/chart.BDL2tf-S.js +10 -0
  19. package/dist/esm/chunks/{chart.4ZbtBMmR.js.map → chart.BDL2tf-S.js.map} +1 -1
  20. package/dist/esm/chunks/chat-logo.CqPppEb9.js +3 -0
  21. package/dist/esm/chunks/chat-logo.CqPppEb9.js.map +1 -0
  22. package/dist/esm/chunks/combobox.MyoPH18G.js +6 -0
  23. package/dist/esm/chunks/{combobox.CJKym3Z1.js.map → combobox.MyoPH18G.js.map} +1 -1
  24. package/dist/esm/chunks/dark.DuW7JuAk.js +2 -0
  25. package/dist/esm/chunks/{dark.Cq2RCgy4.js.map → dark.DuW7JuAk.js.map} +1 -1
  26. package/dist/esm/chunks/data-table.CJOR-1Kf.js +5 -0
  27. package/dist/esm/chunks/{data-table.DbcAYxMY.js.map → data-table.CJOR-1Kf.js.map} +1 -1
  28. package/dist/esm/chunks/date-picker.C2VT_rZ9.js +4 -0
  29. package/dist/esm/chunks/{date-picker._cBTpdEK.js.map → date-picker.C2VT_rZ9.js.map} +1 -1
  30. package/dist/esm/chunks/extends.DPdBf6DS.js +2 -0
  31. package/dist/esm/chunks/extends.DPdBf6DS.js.map +1 -0
  32. package/dist/esm/chunks/feature-flags.DOcVlPHk.js +3 -0
  33. package/dist/esm/chunks/{feature-flags.DeDEcnd1.js.map → feature-flags.DOcVlPHk.js.map} +1 -1
  34. package/dist/esm/chunks/feedback.CLMuSvsg.js +13 -0
  35. package/dist/esm/chunks/{feedback.W2OzN-5r.js.map → feedback.CLMuSvsg.js.map} +1 -1
  36. package/dist/esm/chunks/file-upload-status.D8RhMcbO.js +8 -0
  37. package/dist/esm/chunks/{file-upload-status.DP2iuttI.js.map → file-upload-status.D8RhMcbO.js.map} +1 -1
  38. package/dist/esm/chunks/filters.BHp3ukNW.js +22 -0
  39. package/dist/esm/chunks/{filters.-7vSLEQ2.js.map → filters.BHp3ukNW.js.map} +1 -1
  40. package/dist/esm/chunks/font-picker.B9GPXyK4.js +6 -0
  41. package/dist/esm/chunks/{font-picker.DisEoE8a.js.map → font-picker.B9GPXyK4.js.map} +1 -1
  42. package/dist/esm/chunks/formatDate.D2xEZm8f.js +2 -0
  43. package/dist/esm/chunks/{formatDate.CWN6IFKq.js.map → formatDate.D2xEZm8f.js.map} +1 -1
  44. package/dist/esm/chunks/formatNumber.DhVn228t.js +2 -0
  45. package/dist/esm/chunks/{formatNumber.Bm2k8QrT.js.map → formatNumber.DhVn228t.js.map} +1 -1
  46. package/dist/esm/chunks/generating-star.BN9p_FDu.js +7 -0
  47. package/dist/esm/chunks/generating-star.BN9p_FDu.js.map +1 -0
  48. package/dist/esm/chunks/header-nav.DdOXbPSM.js +10 -0
  49. package/dist/esm/chunks/{header-nav.b4hvOsKc.js.map → header-nav.DdOXbPSM.js.map} +1 -1
  50. package/dist/esm/chunks/header-pane.DrVjpN5S.js +20 -0
  51. package/dist/esm/chunks/{header-pane.BFXHXxVn.js.map → header-pane.DrVjpN5S.js.map} +1 -1
  52. package/dist/esm/chunks/hooks.BQTKhHSv.js +2 -0
  53. package/dist/esm/chunks/hooks.BQTKhHSv.js.map +1 -0
  54. package/dist/esm/chunks/index.uF4ME3WQ.js +4 -0
  55. package/dist/esm/chunks/{index.BqibIWDw.js.map → index.uF4ME3WQ.js.map} +1 -1
  56. package/dist/esm/chunks/input-with-tags.DLv9e0XI.js +5 -0
  57. package/dist/esm/chunks/{input-with-tags.tg2nhPFv.js.map → input-with-tags.DLv9e0XI.js.map} +1 -1
  58. package/dist/esm/chunks/logo.CketsPBx.js +5 -0
  59. package/dist/esm/chunks/{logo.D5BMN6Db.js.map → logo.CketsPBx.js.map} +1 -1
  60. package/dist/esm/chunks/primary.CMQbo1GJ.js +2 -0
  61. package/dist/esm/chunks/{primary.CtiRZbqq.js.map → primary.CMQbo1GJ.js.map} +1 -1
  62. package/dist/esm/chunks/review-list.Cn5bw-lP.js +6 -0
  63. package/dist/esm/chunks/review-list.Cn5bw-lP.js.map +1 -0
  64. package/dist/esm/chunks/sidebar.DsEgGwJU.js +25 -0
  65. package/dist/esm/chunks/sidebar.DsEgGwJU.js.map +1 -0
  66. package/dist/esm/chunks/simpleSelect.DK1qZSXM.js +3 -0
  67. package/dist/esm/chunks/{simpleSelect.B1rktKkt.js.map → simpleSelect.DK1qZSXM.js.map} +1 -1
  68. package/dist/esm/chunks/status-badge.BLB0pWDn.js +3 -0
  69. package/dist/esm/chunks/status-badge.BLB0pWDn.js.map +1 -0
  70. package/dist/esm/chunks/trend-value.BPBDBsk2.js +3 -0
  71. package/dist/esm/chunks/{trend-value.COSukPwk.js.map → trend-value.BPBDBsk2.js.map} +1 -1
  72. package/dist/esm/chunks/two-level-combobox.DJYP--W9.js +8 -0
  73. package/dist/esm/chunks/{two-level-combobox.BXs2z9u5.js.map → two-level-combobox.DJYP--W9.js.map} +1 -1
  74. package/dist/esm/chunks/useChartDateFormatters.Dx2h5AAm.js +2 -0
  75. package/dist/esm/chunks/{useChartDateFormatters.DS9ASgFO.js.map → useChartDateFormatters.Dx2h5AAm.js.map} +1 -1
  76. package/dist/esm/chunks/utils.C6Qu-kwd.js +2 -0
  77. package/dist/esm/chunks/{utils.Cwtlq8dh.js.map → utils.C6Qu-kwd.js.map} +1 -1
  78. package/dist/esm/colors.js +1 -169
  79. package/dist/esm/colors.js.map +1 -1
  80. package/dist/esm/components/article-suggestions-banner.js +4 -53
  81. package/dist/esm/components/article-suggestions-banner.js.map +1 -1
  82. package/dist/esm/components/articles-coverage.js +4 -116
  83. package/dist/esm/components/articles-coverage.js.map +1 -1
  84. package/dist/esm/components/articles-updated.js +4 -74
  85. package/dist/esm/components/articles-updated.js.map +1 -1
  86. package/dist/esm/components/breadcrumbs.js +3 -13
  87. package/dist/esm/components/breadcrumbs.js.map +1 -1
  88. package/dist/esm/components/chart-area-linear.js +6 -66
  89. package/dist/esm/components/chart-area-linear.js.map +1 -1
  90. package/dist/esm/components/chart-radial-stacked.js +2 -48
  91. package/dist/esm/components/chart-radial-stacked.js.map +1 -1
  92. package/dist/esm/components/chat-search.js +1 -1
  93. package/dist/esm/components/combobox.js +1 -1
  94. package/dist/esm/components/confirm-dialog.js +2 -47
  95. package/dist/esm/components/confirm-dialog.js.map +1 -1
  96. package/dist/esm/components/conversation.js +1 -1
  97. package/dist/esm/components/convos.js +27 -607
  98. package/dist/esm/components/convos.js.map +1 -1
  99. package/dist/esm/components/data-table.js +1 -1
  100. package/dist/esm/components/date-picker.js +1 -1
  101. package/dist/esm/components/discoveries-created.js +4 -64
  102. package/dist/esm/components/discoveries-created.js.map +1 -1
  103. package/dist/esm/components/feedback.js +1 -1
  104. package/dist/esm/components/file-upload.js +1 -1
  105. package/dist/esm/components/filter.js +1 -1
  106. package/dist/esm/components/font-picker.js +1 -1
  107. package/dist/esm/components/generating-star.js +1 -1
  108. package/dist/esm/components/input-with-tags.js +1 -1
  109. package/dist/esm/components/logo.js +1 -1
  110. package/dist/esm/components/markdown.js +1 -2
  111. package/dist/esm/components/markdown.js.map +1 -1
  112. package/dist/esm/components/metric-card.js +3 -29
  113. package/dist/esm/components/metric-card.js.map +1 -1
  114. package/dist/esm/components/select.js +1 -1
  115. package/dist/esm/components/trend-value.js +1 -1
  116. package/dist/esm/components/two-level-combobox.js +1 -1
  117. package/dist/esm/components/ui/accordion.js +7 -46
  118. package/dist/esm/components/ui/accordion.js.map +1 -1
  119. package/dist/esm/components/ui/alert-dialog.js +3 -114
  120. package/dist/esm/components/ui/alert-dialog.js.map +1 -1
  121. package/dist/esm/components/ui/alert.js +4 -103
  122. package/dist/esm/components/ui/alert.js.map +1 -1
  123. package/dist/esm/components/ui/avatar.js +7 -89
  124. package/dist/esm/components/ui/avatar.js.map +1 -1
  125. package/dist/esm/components/ui/badge.js +2 -26
  126. package/dist/esm/components/ui/badge.js.map +1 -1
  127. package/dist/esm/components/ui/breadcrumb.js +4 -60
  128. package/dist/esm/components/ui/breadcrumb.js.map +1 -1
  129. package/dist/esm/components/ui/button-group.js +4 -88
  130. package/dist/esm/components/ui/button-group.js.map +1 -1
  131. package/dist/esm/components/ui/button.js +1 -5
  132. package/dist/esm/components/ui/button.js.map +1 -1
  133. package/dist/esm/components/ui/calendar.js +2 -20
  134. package/dist/esm/components/ui/calendar.js.map +1 -1
  135. package/dist/esm/components/ui/card.js +1 -55
  136. package/dist/esm/components/ui/card.js.map +1 -1
  137. package/dist/esm/components/ui/collapsible.js +1 -33
  138. package/dist/esm/components/ui/collapsible.js.map +1 -1
  139. package/dist/esm/components/ui/combobox.js +1 -1
  140. package/dist/esm/components/ui/command.js +2 -79
  141. package/dist/esm/components/ui/command.js.map +1 -1
  142. package/dist/esm/components/ui/dialog.js +4 -60
  143. package/dist/esm/components/ui/dialog.js.map +1 -1
  144. package/dist/esm/components/ui/div-button.js +2 -61
  145. package/dist/esm/components/ui/div-button.js.map +1 -1
  146. package/dist/esm/components/ui/dropdown-menu.js +3 -114
  147. package/dist/esm/components/ui/dropdown-menu.js.map +1 -1
  148. package/dist/esm/components/ui/icon.js +2 -25
  149. package/dist/esm/components/ui/icon.js.map +1 -1
  150. package/dist/esm/components/ui/input.js +4 -47
  151. package/dist/esm/components/ui/input.js.map +1 -1
  152. package/dist/esm/components/ui/item.js +11 -140
  153. package/dist/esm/components/ui/item.js.map +1 -1
  154. package/dist/esm/components/ui/label.js +1 -19
  155. package/dist/esm/components/ui/label.js.map +1 -1
  156. package/dist/esm/components/ui/popover.js +1 -31
  157. package/dist/esm/components/ui/popover.js.map +1 -1
  158. package/dist/esm/components/ui/progress.js +2 -22
  159. package/dist/esm/components/ui/progress.js.map +1 -1
  160. package/dist/esm/components/ui/scroll-area.js +2 -32
  161. package/dist/esm/components/ui/scroll-area.js.map +1 -1
  162. package/dist/esm/components/ui/select.js +5 -66
  163. package/dist/esm/components/ui/select.js.map +1 -1
  164. package/dist/esm/components/ui/separator.js +1 -23
  165. package/dist/esm/components/ui/separator.js.map +1 -1
  166. package/dist/esm/components/ui/sheet.js +3 -62
  167. package/dist/esm/components/ui/sheet.js.map +1 -1
  168. package/dist/esm/components/ui/spinner.js +2 -17
  169. package/dist/esm/components/ui/spinner.js.map +1 -1
  170. package/dist/esm/components/ui/switch.js +2 -26
  171. package/dist/esm/components/ui/switch.js.map +1 -1
  172. package/dist/esm/components/ui/table.js +1 -82
  173. package/dist/esm/components/ui/table.js.map +1 -1
  174. package/dist/esm/components/ui/textarea.js +1 -33
  175. package/dist/esm/components/ui/textarea.js.map +1 -1
  176. package/dist/esm/components/ui/tooltip.js +3 -31
  177. package/dist/esm/components/ui/tooltip.js.map +1 -1
  178. package/dist/esm/global.css +1 -1
  179. package/dist/esm/index.js +1 -53
  180. package/dist/esm/index.js.map +1 -1
  181. package/dist/esm/layouts/full-layout.js +1 -1
  182. package/dist/esm/layouts/header-nav.js +1 -1
  183. package/dist/esm/layouts/sidebar.js +1 -1
  184. package/dist/esm/logos/microsoft-logo.js +6 -66
  185. package/dist/esm/logos/microsoft-logo.js.map +1 -1
  186. package/dist/esm/logos/microsoft-teams-logo.js +12 -112
  187. package/dist/esm/logos/microsoft-teams-logo.js.map +1 -1
  188. package/dist/esm/logos/slack-logo.js +3 -39
  189. package/dist/esm/logos/slack-logo.js.map +1 -1
  190. package/dist/esm/scenes/knowledge-review.js +17 -380
  191. package/dist/esm/scenes/knowledge-review.js.map +1 -1
  192. package/dist/esm/tailwind.preset.js +1 -1526
  193. package/dist/esm/tailwind.preset.js.map +1 -1
  194. package/dist/index.d.ts +32 -5
  195. package/dist/logo.d.ts +9 -0
  196. package/dist/stats.html +47 -46
  197. package/package.json +17 -18
  198. package/tailwind.preset.ts +1 -0
  199. package/dist/esm/chunks/ChatSearch.CeQrTOVx.js +0 -6825
  200. package/dist/esm/chunks/ChatSearch.CeQrTOVx.js.map +0 -1
  201. package/dist/esm/chunks/Conversation.BriXFYqU.js +0 -831
  202. package/dist/esm/chunks/FormattedMessage.CRbM-hF6.js +0 -39715
  203. package/dist/esm/chunks/FormattedMessage.CRbM-hF6.js.map +0 -1
  204. package/dist/esm/chunks/MermaidDiagram.xQ0CVFOI.js +0 -50
  205. package/dist/esm/chunks/_commonjsHelpers.BFTU3MAI.js +0 -8
  206. package/dist/esm/chunks/_commonjsHelpers.BFTU3MAI.js.map +0 -1
  207. package/dist/esm/chunks/button.DQL6gCAt.js +0 -48
  208. package/dist/esm/chunks/button.DQL6gCAt.js.map +0 -1
  209. package/dist/esm/chunks/chart.4ZbtBMmR.js +0 -199
  210. package/dist/esm/chunks/combobox.CJKym3Z1.js +0 -95
  211. package/dist/esm/chunks/dark.Cq2RCgy4.js +0 -18
  212. package/dist/esm/chunks/data-table.DbcAYxMY.js +0 -102
  213. package/dist/esm/chunks/date-picker._cBTpdEK.js +0 -26
  214. package/dist/esm/chunks/extends.mO86zOh3.js +0 -12
  215. package/dist/esm/chunks/extends.mO86zOh3.js.map +0 -1
  216. package/dist/esm/chunks/feature-flags.DeDEcnd1.js +0 -22
  217. package/dist/esm/chunks/feedback.W2OzN-5r.js +0 -214
  218. package/dist/esm/chunks/file-upload-status.DP2iuttI.js +0 -141
  219. package/dist/esm/chunks/filters.-7vSLEQ2.js +0 -565
  220. package/dist/esm/chunks/font-picker.DisEoE8a.js +0 -181
  221. package/dist/esm/chunks/formatDate.CWN6IFKq.js +0 -952
  222. package/dist/esm/chunks/formatNumber.Bm2k8QrT.js +0 -10
  223. package/dist/esm/chunks/generating-star.DMDPNTaM.js +0 -1501
  224. package/dist/esm/chunks/generating-star.DMDPNTaM.js.map +0 -1
  225. package/dist/esm/chunks/header-nav.b4hvOsKc.js +0 -197
  226. package/dist/esm/chunks/header-pane.BFXHXxVn.js +0 -559
  227. package/dist/esm/chunks/hooks.BWVaVAT-.js +0 -343
  228. package/dist/esm/chunks/hooks.BWVaVAT-.js.map +0 -1
  229. package/dist/esm/chunks/index.BqibIWDw.js +0 -137
  230. package/dist/esm/chunks/input-with-tags.tg2nhPFv.js +0 -110
  231. package/dist/esm/chunks/logo.D5BMN6Db.js +0 -191
  232. package/dist/esm/chunks/primary.CtiRZbqq.js +0 -18
  233. package/dist/esm/chunks/review-list.BtSnfpSc.js +0 -117
  234. package/dist/esm/chunks/review-list.BtSnfpSc.js.map +0 -1
  235. package/dist/esm/chunks/sidebar.BamKohb5.js +0 -803
  236. package/dist/esm/chunks/sidebar.BamKohb5.js.map +0 -1
  237. package/dist/esm/chunks/simpleSelect.B1rktKkt.js +0 -23
  238. package/dist/esm/chunks/status-badge.eFJ1PYeb.js +0 -18
  239. package/dist/esm/chunks/status-badge.eFJ1PYeb.js.map +0 -1
  240. package/dist/esm/chunks/trend-value.COSukPwk.js +0 -51
  241. package/dist/esm/chunks/two-level-combobox.BXs2z9u5.js +0 -132
  242. package/dist/esm/chunks/useChartDateFormatters.DS9ASgFO.js +0 -11
  243. package/dist/esm/chunks/utils.Cwtlq8dh.js +0 -45
@@ -1,565 +0,0 @@
1
- import React__default, { useRef, useState, forwardRef, useImperativeHandle, useEffect } from 'react';
2
- import { Check, XCircle, Plus } from '@phosphor-icons/react';
3
- import { createId } from '@paralleldrive/cuid2';
4
- import { B as Button } from './button.DQL6gCAt.js';
5
- import { Input } from '../components/ui/input.js';
6
- import { ButtonGroup } from '../components/ui/button-group.js';
7
- import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from '../components/ui/dropdown-menu.js';
8
- import { Popover, PopoverTrigger, PopoverContent } from '../components/ui/popover.js';
9
- import { c as cn } from './utils.Cwtlq8dh.js';
10
-
11
- var Operator = /* @__PURE__ */ ((Operator2) => {
12
- Operator2["IS"] = "is";
13
- Operator2["IS_NOT"] = "is not";
14
- Operator2["CONTAINS"] = "contains";
15
- Operator2["DOES_NOT_CONTAIN"] = "does not contain";
16
- Operator2["STARTS_WITH"] = "starts with";
17
- return Operator2;
18
- })(Operator || {});
19
-
20
- const useMultiSelectHelpers = (internalFilter, valueOptions, selectPlaceholder) => {
21
- const getSelectedValues = () => {
22
- if (Array.isArray(internalFilter.value)) {
23
- return internalFilter.value;
24
- }
25
- return internalFilter.value ? [internalFilter.value] : [];
26
- };
27
- const isValueSelected = (valueId) => {
28
- const selectedValues = getSelectedValues();
29
- return selectedValues.includes(valueId);
30
- };
31
- const getDisplayValue = () => {
32
- const selectedValues = getSelectedValues();
33
- if (selectedValues.length === 0) return selectPlaceholder;
34
- if (selectedValues.length === 1) {
35
- const option = valueOptions.find((opt) => opt.id === selectedValues[0]);
36
- return option?.label || selectedValues[0];
37
- }
38
- return `${selectedValues.length} selected`;
39
- };
40
- return {
41
- getSelectedValues,
42
- isValueSelected,
43
- getDisplayValue
44
- };
45
- };
46
-
47
- const CustomValueInput = ({
48
- inputValue,
49
- setInputValue,
50
- customValuePlaceholder,
51
- customValueButtonLabel,
52
- onSubmit,
53
- handleKeyDown
54
- }) => {
55
- const inputRef = useRef(null);
56
- return /* @__PURE__ */ React__default.createElement(
57
- "form",
58
- {
59
- className: "p-3",
60
- onSubmit: (e) => {
61
- e.preventDefault();
62
- onSubmit();
63
- }
64
- },
65
- /* @__PURE__ */ React__default.createElement(
66
- Input,
67
- {
68
- ref: inputRef,
69
- type: "text",
70
- value: inputValue,
71
- onChange: (e) => setInputValue(e.target.value),
72
- placeholder: customValuePlaceholder,
73
- className: "mb-2",
74
- onKeyDown: (e) => handleKeyDown(e, true)
75
- }
76
- ),
77
- /* @__PURE__ */ React__default.createElement(
78
- Button,
79
- {
80
- type: "submit",
81
- variant: "dark",
82
- className: "w-full",
83
- onKeyDown: (e) => handleKeyDown(e, false),
84
- "data-custom-submit-button": true
85
- },
86
- customValueButtonLabel
87
- )
88
- );
89
- };
90
-
91
- const getInitialValues = (value) => {
92
- if (Array.isArray(value)) {
93
- return value;
94
- } else if (value) {
95
- return [value];
96
- }
97
- return [];
98
- };
99
- const MultiSelectDropdown = ({
100
- internalFilter,
101
- valueOptions,
102
- onConfirm,
103
- onClose
104
- }) => {
105
- const [pendingValues, setPendingValues] = useState(() => getInitialValues(internalFilter.value));
106
- const [announcement, setAnnouncement] = useState("");
107
- const buttonRefs = useRef([]);
108
- const applyButtonRef = useRef(null);
109
- const handleValueToggle = (valueId) => {
110
- const option = valueOptions.find((opt) => opt.id === valueId);
111
- const isCurrentlySelected = pendingValues.includes(valueId);
112
- setPendingValues((prev) => {
113
- const newValues = prev.includes(valueId) ? prev.filter((id) => id !== valueId) : [...prev, valueId];
114
- if (option) {
115
- const action = isCurrentlySelected ? "deselected" : "selected";
116
- setAnnouncement(`${option.label} ${action}.`);
117
- }
118
- return newValues;
119
- });
120
- };
121
- const handleConfirm = () => {
122
- onConfirm(pendingValues);
123
- onClose();
124
- };
125
- const isValueSelected = (valueId) => {
126
- return pendingValues.includes(valueId);
127
- };
128
- const focusButton = (index) => {
129
- if (index < valueOptions.length) {
130
- buttonRefs.current[index]?.focus();
131
- } else {
132
- applyButtonRef.current?.focus();
133
- }
134
- };
135
- const handleKeyDown = (e, index) => {
136
- switch (e.key) {
137
- case "ArrowDown": {
138
- e.preventDefault();
139
- const nextIndex = Math.min(index + 1, valueOptions.length);
140
- focusButton(nextIndex);
141
- break;
142
- }
143
- case "ArrowUp": {
144
- e.preventDefault();
145
- const prevIndex = Math.max(index - 1, 0);
146
- focusButton(prevIndex);
147
- break;
148
- }
149
- case "Enter":
150
- case "Spacebar":
151
- e.preventDefault();
152
- if (index < valueOptions.length) {
153
- handleValueToggle(valueOptions[index].id);
154
- } else {
155
- handleConfirm();
156
- }
157
- break;
158
- case "Escape":
159
- e.preventDefault();
160
- onClose();
161
- break;
162
- }
163
- };
164
- return /* @__PURE__ */ React__default.createElement("div", { className: "py-1", role: "listbox", "aria-multiselectable": "true" }, /* @__PURE__ */ React__default.createElement("div", { "aria-live": "polite", "aria-atomic": "true", className: "sr-only" }, announcement), valueOptions.map((option, index) => /* @__PURE__ */ React__default.createElement(
165
- "button",
166
- {
167
- key: option.id,
168
- ref: (el) => buttonRefs.current[index] = el,
169
- type: "button",
170
- className: "relative flex w-full text-left cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground",
171
- onClick: () => handleValueToggle(option.id),
172
- onKeyDown: (e) => handleKeyDown(e, index),
173
- role: "option",
174
- "aria-selected": isValueSelected(option.id)
175
- },
176
- isValueSelected(option.id) && /* @__PURE__ */ React__default.createElement(Check, { size: 14, className: "mr-2" }),
177
- !isValueSelected(option.id) && /* @__PURE__ */ React__default.createElement("span", { className: "mr-2 w-3.5" }),
178
- option.label
179
- )), /* @__PURE__ */ React__default.createElement("div", { className: "border-t border-border mt-1 pt-2 px-2 pb-2" }, /* @__PURE__ */ React__default.createElement(
180
- Button,
181
- {
182
- ref: applyButtonRef,
183
- onClick: handleConfirm,
184
- size: "sm",
185
- className: "w-full",
186
- disabled: pendingValues.length === 0,
187
- onKeyDown: (e) => handleKeyDown(e, valueOptions.length)
188
- },
189
- "Apply (",
190
- pendingValues.length,
191
- " selected)"
192
- )));
193
- };
194
-
195
- const SingleSelectDropdown = ({
196
- valueOptions,
197
- isValueSelected,
198
- onValueSelect
199
- }) => {
200
- const buttonRefs = useRef([]);
201
- const focusButton = (index) => {
202
- buttonRefs.current[index]?.focus();
203
- };
204
- const handleKeyDown = (e, index) => {
205
- switch (e.key) {
206
- case "ArrowDown": {
207
- e.preventDefault();
208
- const nextIndex = Math.min(index + 1, valueOptions.length - 1);
209
- focusButton(nextIndex);
210
- break;
211
- }
212
- case "ArrowUp": {
213
- e.preventDefault();
214
- const prevIndex = Math.max(index - 1, 0);
215
- focusButton(prevIndex);
216
- break;
217
- }
218
- case "Enter":
219
- case "Spacebar":
220
- e.preventDefault();
221
- onValueSelect(valueOptions[index].id);
222
- break;
223
- }
224
- };
225
- return /* @__PURE__ */ React__default.createElement("div", { className: "py-1", role: "listbox" }, valueOptions.map((option, index) => /* @__PURE__ */ React__default.createElement(
226
- "button",
227
- {
228
- key: option.id,
229
- ref: (el) => buttonRefs.current[index] = el,
230
- type: "button",
231
- className: "relative flex w-full text-left cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground",
232
- onClick: () => onValueSelect(option.id),
233
- onKeyDown: (e) => handleKeyDown(e, index)
234
- },
235
- isValueSelected(option.id) && /* @__PURE__ */ React__default.createElement(Check, { size: 14, className: "mr-2" }),
236
- !isValueSelected(option.id) && /* @__PURE__ */ React__default.createElement("span", { className: "mr-2 w-3.5" }),
237
- option.label
238
- )));
239
- };
240
-
241
- const Filter = forwardRef(
242
- ({
243
- filter,
244
- sourceOptions,
245
- rules,
246
- onSourceChange,
247
- onRemoveFilter,
248
- onFilterChange,
249
- selectPlaceholder = "Select a value",
250
- customValuePlaceholder = "Enter custom value",
251
- customValueButtonLabel = "Done",
252
- sourceFirstMessage = "Please select a source first"
253
- }, ref) => {
254
- const [internalFilter, setInternalFilter] = useState({
255
- id: filter.id,
256
- source: filter.source,
257
- operator: filter.operator || Operator.IS,
258
- value: filter.value
259
- });
260
- const [inputValue, setInputValue] = useState("");
261
- const [openDropdownType, setOpenDropdownType] = useState(null);
262
- const inputRef = useRef(null);
263
- const sourceButtonRef = useRef(null);
264
- const divRef = useRef(null);
265
- useImperativeHandle(ref, () => ({
266
- focus: () => {
267
- sourceButtonRef.current?.focus();
268
- }
269
- }));
270
- const currentRules = internalFilter.source ? rules[internalFilter.source] : void 0;
271
- const operatorOptions = currentRules?.operators || [];
272
- const isMultiSelect = currentRules?.multiSelect || false;
273
- let inputType = currentRules?.inputType || "dropdown";
274
- if (internalFilter.operator === Operator.CONTAINS || internalFilter.operator === Operator.DOES_NOT_CONTAIN) {
275
- inputType = "custom";
276
- }
277
- const valueOptions = currentRules?.getValueOptions ? currentRules.getValueOptions() : [];
278
- const { getSelectedValues, isValueSelected, getDisplayValue } = useMultiSelectHelpers(
279
- internalFilter,
280
- valueOptions,
281
- selectPlaceholder
282
- );
283
- useEffect(() => {
284
- if (openDropdownType === "value" && inputType === "custom") {
285
- const timeoutId = setTimeout(() => inputRef.current?.focus(), 50);
286
- return () => clearTimeout(timeoutId);
287
- }
288
- return void 0;
289
- }, [openDropdownType, inputType]);
290
- useEffect(() => {
291
- setInternalFilter({
292
- id: filter.id,
293
- source: filter.source,
294
- operator: filter.operator || Operator.IS,
295
- value: filter.value
296
- });
297
- }, [filter]);
298
- const checkAndTriggerChange = (newFilter) => {
299
- const hasValue = Array.isArray(newFilter.value) ? newFilter.value.length > 0 : !!newFilter.value?.trim();
300
- const isComplete = newFilter.source && newFilter.operator && hasValue;
301
- if (isComplete) {
302
- onFilterChange(newFilter);
303
- }
304
- };
305
- const updateFilterField = (field, value) => {
306
- const newFilter = { ...internalFilter, [field]: value };
307
- if (field === "source") {
308
- const sourceRules = rules[value];
309
- newFilter.operator = sourceRules?.operators[0]?.id;
310
- newFilter.value = sourceRules?.multiSelect ? [] : "";
311
- }
312
- if (field === "operator") {
313
- if (internalFilter.source) {
314
- const sourceRules = rules[internalFilter.source];
315
- if (sourceRules?.inputType === "dropdown") {
316
- newFilter.value = sourceRules?.multiSelect ? [] : "";
317
- }
318
- }
319
- }
320
- setInternalFilter(newFilter);
321
- checkAndTriggerChange(newFilter);
322
- if (!isMultiSelect || field !== "value") {
323
- setOpenDropdownType(null);
324
- }
325
- };
326
- const handleValueToggle = (valueId) => {
327
- const selectedValues = getSelectedValues();
328
- let newValues;
329
- if (isMultiSelect) {
330
- if (selectedValues.includes(valueId)) {
331
- newValues = selectedValues.filter((id) => id !== valueId);
332
- } else {
333
- newValues = [...selectedValues, valueId];
334
- }
335
- } else {
336
- newValues = [valueId];
337
- }
338
- const newFilter = {
339
- ...internalFilter,
340
- value: isMultiSelect ? newValues : newValues[0] || ""
341
- };
342
- setInternalFilter(newFilter);
343
- checkAndTriggerChange(newFilter);
344
- if (!isMultiSelect) {
345
- setOpenDropdownType(null);
346
- }
347
- };
348
- const handleMultiSelectConfirm = (selectedValues) => {
349
- const newFilter = {
350
- ...internalFilter,
351
- value: selectedValues
352
- };
353
- setInternalFilter(newFilter);
354
- const isComplete = newFilter.source && newFilter.operator && selectedValues.length > 0;
355
- if (isComplete) onFilterChange(newFilter);
356
- setOpenDropdownType(null);
357
- };
358
- const handleCustomValueSubmit = () => {
359
- if (inputValue.trim()) {
360
- const newFilter = { ...internalFilter, value: inputValue.trim() };
361
- setInternalFilter(newFilter);
362
- setInputValue("");
363
- setOpenDropdownType(null);
364
- if (newFilter.source && newFilter.operator && newFilter.value) {
365
- onFilterChange(newFilter);
366
- }
367
- }
368
- };
369
- const handleKeyDown = (e, isInput) => {
370
- if (e.key === "Escape") {
371
- setOpenDropdownType(null);
372
- return;
373
- }
374
- if (e.key === "Tab") {
375
- if (isInput && !e.shiftKey) {
376
- e.preventDefault();
377
- const button = document.querySelector("[data-custom-submit-button]");
378
- button?.focus();
379
- } else if (!isInput) {
380
- e.preventDefault();
381
- inputRef.current?.focus();
382
- }
383
- }
384
- };
385
- return /* @__PURE__ */ React__default.createElement(
386
- ButtonGroup,
387
- {
388
- ref: divRef,
389
- orientation: "horizontal",
390
- className: "rounded-full border border-border divide-x-2 divide-dark-500"
391
- },
392
- /* @__PURE__ */ React__default.createElement(
393
- DropdownMenu,
394
- {
395
- open: openDropdownType === "source",
396
- onOpenChange: (open) => setOpenDropdownType(open ? "source" : null),
397
- modal: false
398
- },
399
- /* @__PURE__ */ React__default.createElement(DropdownMenuTrigger, { asChild: true }, /* @__PURE__ */ React__default.createElement(Button, { ref: sourceButtonRef, variant: "ghost", size: "xs", className: "rounded-l-full font-bold" }, sourceOptions.find((opt) => opt.id === internalFilter.source)?.label || sourceOptions[0]?.label || selectPlaceholder)),
400
- /* @__PURE__ */ React__default.createElement(DropdownMenuContent, { align: "start", className: "w-48" }, sourceOptions.map((option) => /* @__PURE__ */ React__default.createElement(
401
- DropdownMenuItem,
402
- {
403
- key: option.id,
404
- className: "flex items-center",
405
- onSelect: () => {
406
- updateFilterField("source", option.id);
407
- onSourceChange?.(option.id);
408
- }
409
- },
410
- option.id === internalFilter.source && /* @__PURE__ */ React__default.createElement(Check, { size: 14, className: "mr-2" }),
411
- option.label
412
- )))
413
- ),
414
- /* @__PURE__ */ React__default.createElement(
415
- DropdownMenu,
416
- {
417
- open: openDropdownType === "operator",
418
- onOpenChange: (open) => setOpenDropdownType(open ? "operator" : null),
419
- modal: false
420
- },
421
- /* @__PURE__ */ React__default.createElement(DropdownMenuTrigger, { asChild: true }, /* @__PURE__ */ React__default.createElement(Button, { variant: "ghost", size: "xs" }, operatorOptions.find((opt) => opt.id === internalFilter.operator)?.label || selectPlaceholder)),
422
- /* @__PURE__ */ React__default.createElement(DropdownMenuContent, { align: "start", className: "w-48" }, operatorOptions.map((option) => /* @__PURE__ */ React__default.createElement(
423
- DropdownMenuItem,
424
- {
425
- key: option.id,
426
- className: "flex items-center",
427
- onSelect: () => updateFilterField("operator", option.id)
428
- },
429
- option.id === internalFilter.operator && /* @__PURE__ */ React__default.createElement(Check, { size: 14, className: "mr-2" }),
430
- option.label
431
- )))
432
- ),
433
- /* @__PURE__ */ React__default.createElement(
434
- Popover,
435
- {
436
- open: openDropdownType === "value",
437
- onOpenChange: (open) => setOpenDropdownType(open ? "value" : null)
438
- },
439
- /* @__PURE__ */ React__default.createElement(PopoverTrigger, { asChild: true }, /* @__PURE__ */ React__default.createElement(Button, { variant: "ghost", size: "xs", className: "font-bold" }, getDisplayValue())),
440
- /* @__PURE__ */ React__default.createElement(PopoverContent, { align: "start", className: "w-64 max-h-[min(320px,50vh)] overflow-y-auto p-0" }, inputType === "custom" && /* @__PURE__ */ React__default.createElement("div", { className: "p-3" }, /* @__PURE__ */ React__default.createElement(
441
- CustomValueInput,
442
- {
443
- inputValue,
444
- setInputValue,
445
- customValuePlaceholder,
446
- customValueButtonLabel,
447
- onSubmit: handleCustomValueSubmit,
448
- handleKeyDown
449
- }
450
- )), inputType === "dropdown" && /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, internalFilter.source ? /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, isMultiSelect ? /* @__PURE__ */ React__default.createElement(
451
- MultiSelectDropdown,
452
- {
453
- internalFilter,
454
- valueOptions,
455
- onConfirm: handleMultiSelectConfirm,
456
- onClose: () => setOpenDropdownType(null)
457
- }
458
- ) : /* @__PURE__ */ React__default.createElement(
459
- SingleSelectDropdown,
460
- {
461
- valueOptions,
462
- isValueSelected,
463
- onValueSelect: handleValueToggle
464
- }
465
- )) : /* @__PURE__ */ React__default.createElement("div", { className: "p-3 text-sm text-gray-500" }, sourceFirstMessage)))
466
- ),
467
- /* @__PURE__ */ React__default.createElement(
468
- Button,
469
- {
470
- type: "button",
471
- variant: "ghost",
472
- size: "xs",
473
- onClick: () => {
474
- setInternalFilter({ id: filter.id });
475
- setOpenDropdownType(null);
476
- onRemoveFilter(filter.id);
477
- },
478
- className: "p-2 hover:bg-black/10 rounded-none rounded-r-full",
479
- "aria-label": "Remove filter"
480
- },
481
- /* @__PURE__ */ React__default.createElement(XCircle, { size: 16, weight: "fill" })
482
- )
483
- );
484
- }
485
- );
486
- Filter.displayName = "Filter";
487
-
488
- const Filters = ({
489
- filters,
490
- onFilterChange,
491
- onFilterRemove,
492
- onFilterAdd,
493
- sourceOptions,
494
- rules,
495
- className
496
- }) => {
497
- const [internalFilters, setInternalFilters] = useState(filters || []);
498
- const filterRefs = useRef({});
499
- useEffect(() => {
500
- setInternalFilters(filters || []);
501
- }, [filters]);
502
- const usedSources = internalFilters.map((filter) => filter.source).filter(Boolean);
503
- const availableSources = sourceOptions.filter((option) => {
504
- if (rules[option.id]?.multiSelect) {
505
- return !usedSources.includes(option.id);
506
- }
507
- return sourceOptions;
508
- });
509
- const canAddFilter = availableSources.length > 0;
510
- const handleAddFilter = () => {
511
- if (!canAddFilter) return;
512
- const newFilter = {
513
- id: createId(),
514
- source: availableSources[0].id,
515
- operator: Operator.IS,
516
- value: rules[availableSources[0].id]?.multiSelect ? [] : ""
517
- };
518
- const newFilters = [...internalFilters, newFilter];
519
- setInternalFilters(newFilters);
520
- requestAnimationFrame(() => {
521
- filterRefs.current[newFilter.id]?.focus();
522
- });
523
- onFilterAdd?.(newFilter);
524
- };
525
- const handleRemoveFilter = (filter) => {
526
- const newFilters = internalFilters.filter((f) => f.id !== filter.id);
527
- setInternalFilters(newFilters);
528
- onFilterRemove(filter.id);
529
- };
530
- return /* @__PURE__ */ React__default.createElement("fieldset", { className: cn("flex flex-wrap gap-2", className) }, /* @__PURE__ */ React__default.createElement("legend", { className: "sr-only" }, "Filters"), internalFilters?.map((filter) => {
531
- const filterSourceOptions = sourceOptions.filter(
532
- (option) => !usedSources.includes(option.id) || // Available sources
533
- option.id === filter.source
534
- // Or its own current source
535
- );
536
- return /* @__PURE__ */ React__default.createElement(
537
- Filter,
538
- {
539
- key: filter.id,
540
- ref: (ref) => {
541
- filterRefs.current[filter.id] = ref;
542
- },
543
- filter,
544
- sourceOptions: filterSourceOptions,
545
- rules,
546
- onRemoveFilter: () => handleRemoveFilter(filter),
547
- onFilterChange
548
- }
549
- );
550
- }), canAddFilter && /* @__PURE__ */ React__default.createElement(
551
- Button,
552
- {
553
- onClick: handleAddFilter,
554
- variant: "ghost",
555
- className: "border border-foreground rounded-full gap-1",
556
- size: "sm",
557
- title: "Add filter"
558
- },
559
- /* @__PURE__ */ React__default.createElement(Plus, { size: 16 }),
560
- "Add filter"
561
- ));
562
- };
563
-
564
- export { Filter as F, Operator as O, Filters as a };
565
- //# sourceMappingURL=filters.-7vSLEQ2.js.map