@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,803 +0,0 @@
1
- import * as React from 'react';
2
- import { ScrollArea } from '../components/ui/scroll-area.js';
3
- import { c as cn } from './utils.Cwtlq8dh.js';
4
- import { ArrowBendUpLeft, X, MagnifyingGlass, Folder, FolderOpen, FolderDashed, DotsThree, Plus, FileDashed, File, Lightning, Article } from '@phosphor-icons/react';
5
- import { B as Button } from './button.DQL6gCAt.js';
6
- import { useToggle, useDebounceValue } from 'usehooks-ts';
7
- import { Input } from '../components/ui/input.js';
8
- import { TreeStateContext, Button as Button$1, useTreeData, useDragAndDrop, DropIndicator, Tree, TreeItem, TreeItemContent, Collection } from 'react-aria-components';
9
- import { ButtonGroup } from '../components/ui/button-group.js';
10
- import { Spinner } from '../components/ui/spinner.js';
11
- import { u as useSubstringFilter } from './hooks.BWVaVAT-.js';
12
-
13
- const SidebarContext = React.createContext(null);
14
- function SidebarProvider({
15
- collapsed,
16
- ItemLinkComponent: ItemLinkComponent2,
17
- activeArticleId,
18
- onSelectArticle,
19
- onExpandArticle,
20
- onSearchArticles,
21
- onAddArticle,
22
- onMoreActions,
23
- canMoveArticle,
24
- onMoveArticle,
25
- children
26
- }) {
27
- const [isSearching, setIsSearching] = React.useState(false);
28
- const [searchValue, setSearchValue] = React.useState("");
29
- const [lastSelectedArticleId, setLastSelectedArticleId] = React.useState(null);
30
- const handleSearchArticles = React.useCallback(
31
- (value) => {
32
- const trimmedValue = value.trim();
33
- setIsSearching(trimmedValue !== "");
34
- onSearchArticles?.(value);
35
- },
36
- [onSearchArticles]
37
- );
38
- const contextValue = React.useMemo(
39
- () => ({
40
- collapsed,
41
- ItemLinkComponent: ItemLinkComponent2,
42
- activeArticleId,
43
- onSearchArticles,
44
- onSelectArticle,
45
- onExpandArticle,
46
- onAddArticle,
47
- onMoreActions,
48
- canMoveArticle,
49
- onMoveArticle,
50
- isSearching,
51
- searchValue,
52
- setSearchValue,
53
- lastSelectedArticleId,
54
- setLastSelectedArticleId,
55
- handleSearchArticles
56
- }),
57
- [
58
- isSearching,
59
- searchValue,
60
- lastSelectedArticleId,
61
- collapsed,
62
- ItemLinkComponent2,
63
- activeArticleId,
64
- onSelectArticle,
65
- onExpandArticle,
66
- onSearchArticles,
67
- onAddArticle,
68
- onMoreActions,
69
- canMoveArticle,
70
- onMoveArticle,
71
- handleSearchArticles
72
- ]
73
- );
74
- return /* @__PURE__ */ React.createElement(SidebarContext.Provider, { value: contextValue }, children);
75
- }
76
- function useSidebar() {
77
- const sidebarContext = React.useContext(SidebarContext);
78
- if (!sidebarContext) throw new Error("useSidebar must be used within SidebarProvider");
79
- return sidebarContext;
80
- }
81
-
82
- function AppNav({ className, items, activeId, showBack, onBack }) {
83
- const { collapsed, ItemLinkComponent } = useSidebar();
84
- const hasBack = !!showBack && !!onBack;
85
- return /* @__PURE__ */ React.createElement("nav", { className: cn("flex flex-col gap-2", className), "aria-label": "App navigation" }, hasBack && /* @__PURE__ */ React.createElement(
86
- Button,
87
- {
88
- variant: "link",
89
- className: cn("py-2 text-base text-default w-full mx-4", collapsed ? "justify-center" : "justify-start"),
90
- size: "icon",
91
- onClick: onBack
92
- },
93
- /* @__PURE__ */ React.createElement(ArrowBendUpLeft, { "aria-hidden": "true" }),
94
- /* @__PURE__ */ React.createElement("span", { className: cn(collapsed && "sr-only") }, "back to Brainfish")
95
- ), /* @__PURE__ */ React.createElement(ScrollArea, { className: "min-h-0 max-h-[calc(100dvh-var(--header-nav-height)-5rem)]" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-2 mx-4" }, items?.map((item) => /* @__PURE__ */ React.createElement(
96
- ItemLinkComponent,
97
- {
98
- key: item.id,
99
- className: cn(
100
- "flex p-2 rounded-lg gap-1 text-base text-default items-center hover:text-primary-foreground focus:text-primary-foreground",
101
- item.id === activeId ? "bg-primary text-primary-foreground font-bold" : "hover:bg-lime-100 focus:bg-lime-100"
102
- ),
103
- href: item.href,
104
- "data-sidebar-item-id": item.id,
105
- "data-sidebar-item-type": "app",
106
- "data-sidebar-app-nav-item-selected": item.id === activeId
107
- },
108
- item.Icon ? /* @__PURE__ */ React.createElement(item.Icon, { weight: item.id === activeId ? "fill" : "regular", size: 16 }) : null,
109
- /* @__PURE__ */ React.createElement("span", { className: cn("transition-opacity duration-200", collapsed && "opacity-0 sr-only") }, item.label)
110
- )))));
111
- }
112
-
113
- function ArticleSearch() {
114
- const { handleSearchArticles, searchValue, setSearchValue } = useSidebar();
115
- const [searchInteracted, , setSearchInteracted] = useToggle(false);
116
- const searchInputRef = React.useRef(null);
117
- React.useEffect(() => {
118
- if (searchInteracted) handleSearchArticles?.(searchValue);
119
- }, [searchValue, handleSearchArticles, searchInteracted]);
120
- return /* @__PURE__ */ React.createElement("div", { className: "mb-2" }, /* @__PURE__ */ React.createElement(
121
- Input,
122
- {
123
- ref: searchInputRef,
124
- className: "h-auto text-subtlest border-border-subtle",
125
- startIcon: MagnifyingGlass,
126
- endIcon: searchValue ? X : void 0,
127
- onEndIconClick: () => {
128
- setSearchValue("");
129
- handleSearchArticles?.("");
130
- },
131
- value: searchValue,
132
- onChange: (e) => {
133
- const value = e.target.value;
134
- if (!searchInteracted) {
135
- setSearchInteracted(true);
136
- }
137
- setSearchValue(value);
138
- if (value.trim() === "") {
139
- handleSearchArticles("");
140
- setSearchInteracted(false);
141
- }
142
- },
143
- placeholder: "Find an article",
144
- "aria-label": "Find an article",
145
- type: "search"
146
- }
147
- ));
148
- }
149
-
150
- function FolderSlotButton({ children }) {
151
- return /* @__PURE__ */ React.createElement(Button$1, { slot: "chevron", className: "relative z-30 flex p-0" }, /* @__PURE__ */ React.createElement("span", { className: "relative inline-flex size-3 items-center justify-center" }, children));
152
- }
153
- function ArticleItem({
154
- item,
155
- hasChildItems,
156
- isSelected,
157
- isExpanded,
158
- ItemLinkComponent: ItemLinkComponent2,
159
- onAddArticle,
160
- isAddingArticle,
161
- isLoadingChildren,
162
- onMoreActions,
163
- level
164
- }) {
165
- const { isSearching } = useSidebar();
166
- const treeState = React.useContext(TreeStateContext);
167
- const shouldPreventNavigation = Boolean(isSelected);
168
- const handleAddClick = (e) => {
169
- e.stopPropagation();
170
- onAddArticle?.(item.value.id);
171
- };
172
- const handleMoreClick = (e) => {
173
- e.stopPropagation();
174
- onMoreActions?.(item.value.id);
175
- };
176
- const handleItemClick = (e) => {
177
- if (shouldPreventNavigation) {
178
- e.preventDefault();
179
- e.stopPropagation();
180
- }
181
- if (hasChildItems && treeState) {
182
- treeState.toggleKey(item.key);
183
- }
184
- };
185
- const showActions = !!(onAddArticle && !isAddingArticle || onMoreActions);
186
- const isDraft = item.value.status === "draft";
187
- let statusLabel;
188
- switch (item.value.status) {
189
- case "draft":
190
- statusLabel = "(draft)";
191
- break;
192
- case "unpublished":
193
- statusLabel = "(unpublished changes)";
194
- break;
195
- default:
196
- statusLabel = "";
197
- }
198
- const folderIcon = /* @__PURE__ */ React.createElement(FolderSlotButton, null, /* @__PURE__ */ React.createElement(
199
- Folder,
200
- {
201
- "aria-hidden": "true",
202
- weight: "fill",
203
- className: cn(
204
- "absolute size-3 transition-opacity duration-200 ease-out",
205
- isExpanded ? "opacity-0" : "opacity-100"
206
- )
207
- }
208
- ), /* @__PURE__ */ React.createElement(
209
- FolderOpen,
210
- {
211
- "aria-hidden": "true",
212
- weight: "fill",
213
- className: cn(
214
- "absolute size-3 transition-opacity duration-200 ease-out",
215
- isExpanded ? "opacity-100" : "opacity-0"
216
- )
217
- }
218
- ));
219
- const folderWithChangesIcon = /* @__PURE__ */ React.createElement(FolderSlotButton, null, /* @__PURE__ */ React.createElement(
220
- FolderDashed,
221
- {
222
- "aria-hidden": "true",
223
- weight: "fill",
224
- className: cn(
225
- "absolute size-3 transition-opacity duration-200 ease-out",
226
- isExpanded ? "opacity-0" : "opacity-100"
227
- )
228
- }
229
- ), /* @__PURE__ */ React.createElement(
230
- FolderOpen,
231
- {
232
- "aria-hidden": "true",
233
- weight: "fill",
234
- className: cn(
235
- "absolute size-3 transition-opacity duration-200 ease-out",
236
- isExpanded ? "opacity-100" : "opacity-0"
237
- )
238
- }
239
- ));
240
- const discoveryIconContent = /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("span", { className: "sr-only" }, "Knowledge Discovery"), /* @__PURE__ */ React.createElement(Lightning, { "aria-hidden": "true", weight: "fill", className: "size-3 shrink-0 text-blue-600" }));
241
- const discoveryIcon = hasChildItems ? /* @__PURE__ */ React.createElement(FolderSlotButton, null, /* @__PURE__ */ React.createElement("span", { className: "text-blue-600" }, discoveryIconContent)) : /* @__PURE__ */ React.createElement("span", { className: "flex size-3 shrink-0 items-center justify-center text-blue-600" }, discoveryIconContent);
242
- const fileIcon = /* @__PURE__ */ React.createElement("span", { className: "flex size-3 shrink-0 items-center justify-center" }, /* @__PURE__ */ React.createElement(File, { "aria-hidden": "true", className: "size-3" }));
243
- const fileWithChangesIcon = /* @__PURE__ */ React.createElement("span", { className: "flex size-3 shrink-0 items-center justify-center" }, /* @__PURE__ */ React.createElement("span", { className: "sr-only" }, "Unpublished Changes"), /* @__PURE__ */ React.createElement(FileDashed, { "aria-hidden": "true", className: "size-3" }));
244
- const loadingFolderIcon = /* @__PURE__ */ React.createElement(
245
- "span",
246
- {
247
- className: "flex size-3 shrink-0 items-center justify-center",
248
- role: "status",
249
- "aria-label": `Loading nested articles for ${item.value.label}`
250
- },
251
- /* @__PURE__ */ React.createElement(Spinner, { "aria-hidden": "true", className: "size-3 text-current" }),
252
- /* @__PURE__ */ React.createElement("span", { className: "sr-only" }, "Loading nested articles for ", item.value.label)
253
- );
254
- const renderStatusIcon = (status, hasChildItems2) => {
255
- if (status === "discovery") {
256
- return discoveryIcon;
257
- }
258
- const hasChanges = status === "unpublished" || status === "draft";
259
- if (hasChildItems2) {
260
- return hasChanges ? folderWithChangesIcon : folderIcon;
261
- } else {
262
- return hasChanges ? fileWithChangesIcon : fileIcon;
263
- }
264
- };
265
- return /* @__PURE__ */ React.createElement(
266
- "div",
267
- {
268
- style: { ["--line-offset"]: "0.875rem" },
269
- "aria-busy": isLoadingChildren || void 0,
270
- className: cn(
271
- "group relative flex items-center gap-1 rounded-md py-1 pl-1 ml-[calc((var(--tree-item-level)-1)*var(--line-offset))] pr-4 h-9",
272
- isDraft && "text-subtlest italic",
273
- isSelected ? "bg-lime-100 text-primary-foreground font-bold after:absolute after:-right-0.5 after:top-1/2 after:h-1/2 after:w-1 after:-translate-y-1/2 after:bg-lime-400" : "hover:bg-dark-200 hover:text-accent-foreground"
274
- )
275
- },
276
- Array.from({ length: level - 1 }, (_, i) => /* @__PURE__ */ React.createElement(
277
- "span",
278
- {
279
- key: `${item.value.label}-${i + 1}`,
280
- style: { ["--item-line-level"]: i + 1 },
281
- className: "absolute w-[1px] bg-dark-400 -top-2 h-9 left-[calc(-4px-var(--line-offset)*(var(--item-line-level)-1))]",
282
- "aria-hidden": true
283
- }
284
- )),
285
- /* @__PURE__ */ React.createElement(Button$1, { slot: "drag", className: "sr-only" }, "Drag ", item.value.label),
286
- isSearching ? null : isLoadingChildren ? loadingFolderIcon : renderStatusIcon(item.value.status, hasChildItems),
287
- /* @__PURE__ */ React.createElement(
288
- ItemLinkComponent2,
289
- {
290
- href: item.value.href,
291
- title: `${item.value.label} ${statusLabel}`,
292
- "data-sidebar-item-id": item.value.id,
293
- "data-sidebar-item-type": "article",
294
- className: cn(
295
- "min-w-0 text-inherit text-sm truncate flex-1 after:absolute after:inset-0 after:z-10 pr-1",
296
- isSelected && "text-primary-foreground"
297
- ),
298
- onClick: handleItemClick
299
- },
300
- item.value.label
301
- ),
302
- showActions && /* @__PURE__ */ React.createElement(
303
- ButtonGroup,
304
- {
305
- orientation: "horizontal",
306
- className: cn(
307
- "absolute h-4 my-auto right-0.5 top-0 bottom-0 z-20 hidden items-center rounded-xl",
308
- "group-hover:flex group-focus-within:flex",
309
- isSelected ? "bg-lime-100 text-primary-foreground" : "bg-dark-200"
310
- )
311
- },
312
- onMoreActions && /* @__PURE__ */ React.createElement(
313
- Button,
314
- {
315
- variant: "ghost",
316
- size: "icon",
317
- "aria-label": `More actions for ${item.value.label}`,
318
- className: "size-4 [&_svg]:size-3.5",
319
- onClick: handleMoreClick
320
- },
321
- /* @__PURE__ */ React.createElement(DotsThree, { "aria-hidden": "true", weight: "bold" })
322
- ),
323
- onAddArticle && !isAddingArticle && /* @__PURE__ */ React.createElement(
324
- Button,
325
- {
326
- variant: "ghost",
327
- size: "icon",
328
- "aria-label": `Add article to ${item.value.label}`,
329
- className: "size-4 [&_svg]:size-3.5",
330
- onClick: handleAddClick
331
- },
332
- /* @__PURE__ */ React.createElement(Plus, { "aria-hidden": "true" })
333
- )
334
- )
335
- );
336
- }
337
-
338
- function getNewlyExpandedKeys(previous, next) {
339
- const previousKeys = new Set(Array.from(previous, (key) => key.toString()));
340
- return Array.from(next, (key) => key.toString()).filter((key) => !previousKeys.has(key));
341
- }
342
-
343
- function flattenArticles(items, parentId = null, depth = 0, result = []) {
344
- items.forEach((item, index) => {
345
- result.push({ item, parentId, index, depth });
346
- if (item.items?.length) {
347
- flattenArticles(item.items, item.id, depth + 1, result);
348
- }
349
- });
350
- return result;
351
- }
352
- function haveSameValue(a, b) {
353
- return a.label === b.label && a.href === b.href && a.status === b.status && a.hasChildren === b.hasChildren && a.isLoadingChildren === b.isLoadingChildren;
354
- }
355
- function buildArticleTreeSyncOperations(currentArticles, nextArticles) {
356
- const currentEntries = flattenArticles(currentArticles);
357
- const nextEntries = flattenArticles(nextArticles);
358
- const currentMap = new Map(currentEntries.map((entry) => [entry.item.id, entry]));
359
- const nextMap = new Map(nextEntries.map((entry) => [entry.item.id, entry]));
360
- const operations = [];
361
- currentEntries.filter((entry) => !nextMap.has(entry.item.id)).sort((a, b) => b.depth - a.depth).forEach((entry) => {
362
- operations.push({ type: "remove", id: entry.item.id });
363
- });
364
- nextEntries.forEach((entry) => {
365
- const currentEntry = currentMap.get(entry.item.id);
366
- if (!currentEntry) {
367
- operations.push({
368
- type: "insert",
369
- parentId: entry.parentId,
370
- index: entry.index,
371
- item: entry.item
372
- });
373
- return;
374
- }
375
- if (currentEntry.parentId !== entry.parentId || currentEntry.index !== entry.index) {
376
- operations.push({
377
- type: "move",
378
- id: entry.item.id,
379
- parentId: entry.parentId,
380
- index: entry.index
381
- });
382
- }
383
- if (!haveSameValue(currentEntry.item, entry.item)) {
384
- operations.push({
385
- type: "update",
386
- id: entry.item.id,
387
- item: entry.item
388
- });
389
- }
390
- });
391
- return operations;
392
- }
393
-
394
- let placeholderCounter = 0;
395
- function getParentKeys(items, targetId, parents = []) {
396
- for (const item of items) {
397
- if (item.id === targetId) {
398
- return parents;
399
- }
400
- if (item.items && item.items.length > 0) {
401
- const result = getParentKeys(item.items, targetId, [...parents, item.id]);
402
- if (result) return result;
403
- }
404
- }
405
- return null;
406
- }
407
- function treeNodesToArticleNavItems(items) {
408
- return items.map((item) => ({
409
- ...item.value,
410
- items: item.children?.length ? treeNodesToArticleNavItems(item.children) : item.value.items
411
- }));
412
- }
413
- function ArticleTree({ articles, isSearching, renderEmptyState }) {
414
- const {
415
- ItemLinkComponent,
416
- activeArticleId,
417
- lastSelectedArticleId,
418
- setLastSelectedArticleId,
419
- onSelectArticle,
420
- onExpandArticle,
421
- handleSearchArticles,
422
- setSearchValue,
423
- canMoveArticle,
424
- onMoveArticle,
425
- onAddArticle,
426
- onMoreActions
427
- } = useSidebar();
428
- const effectiveActiveId = activeArticleId ?? lastSelectedArticleId ?? void 0;
429
- const articlesTree = useTreeData({
430
- initialItems: articles,
431
- getKey: (articleItem) => articleItem.id,
432
- getChildren: (articleItem) => articleItem.items ?? []
433
- });
434
- const prevArticlesRef = React.useRef(articles);
435
- React.useEffect(() => {
436
- if (prevArticlesRef.current === articles) return;
437
- prevArticlesRef.current = articles;
438
- const currentArticles = treeNodesToArticleNavItems(articlesTree.items);
439
- const operations = buildArticleTreeSyncOperations(currentArticles, articles);
440
- if (operations.length === 0) return;
441
- operations.forEach((operation) => {
442
- switch (operation.type) {
443
- case "remove":
444
- articlesTree.remove(operation.id);
445
- break;
446
- case "insert":
447
- articlesTree.insert(operation.parentId, operation.index, operation.item);
448
- break;
449
- case "move":
450
- articlesTree.move(operation.id, operation.parentId, operation.index);
451
- break;
452
- case "update":
453
- articlesTree.update(operation.id, operation.item);
454
- break;
455
- }
456
- });
457
- }, [articles, articlesTree]);
458
- const { dragAndDropHooks } = useDragAndDrop({
459
- getItems: (_keys, items) => items.map((item) => ({
460
- "text/plain": item.value.label
461
- })),
462
- onMove: (e) => {
463
- if (isSearching) return;
464
- const movedArticleId = Array.from(e.keys)[0];
465
- if (!movedArticleId) return;
466
- const targetItem = articlesTree.getItem(e.target.key);
467
- if (!targetItem) return;
468
- let movedToParentId;
469
- let movedToIndex;
470
- if (e.target.dropPosition === "on") {
471
- movedToParentId = e.target.key.toString();
472
- movedToIndex = targetItem.children?.length ?? 0;
473
- } else {
474
- movedToParentId = targetItem.parentKey?.toString() ?? null;
475
- const siblings = movedToParentId ? articlesTree.getItem(movedToParentId)?.children ?? [] : articlesTree.items;
476
- const targetIndex = siblings.findIndex((i) => i.key === e.target.key);
477
- movedToIndex = e.target.dropPosition === "before" ? targetIndex : targetIndex + 1;
478
- }
479
- const moveDetails = {
480
- id: movedArticleId.toString(),
481
- parentId: movedToParentId,
482
- index: movedToIndex
483
- };
484
- if (canMoveArticle && !canMoveArticle(moveDetails)) {
485
- return;
486
- }
487
- const movedItem = articlesTree.getItem(movedArticleId);
488
- const originalParentId = movedItem?.parentKey?.toString() ?? null;
489
- const originalSiblings = originalParentId ? articlesTree.getItem(originalParentId)?.children ?? [] : articlesTree.items;
490
- const originalIndex = originalSiblings.findIndex((i) => i.key === movedArticleId);
491
- if (e.target.dropPosition === "on") {
492
- articlesTree.move(movedArticleId, movedToParentId, movedToIndex);
493
- } else if (e.target.dropPosition === "before") {
494
- articlesTree.moveBefore(e.target.key, e.keys);
495
- } else {
496
- articlesTree.moveAfter(e.target.key, e.keys);
497
- }
498
- const result = onMoveArticle?.(moveDetails);
499
- if (result && typeof result.then === "function") {
500
- result.catch(() => {
501
- articlesTree.move(movedArticleId, originalParentId, originalIndex);
502
- });
503
- }
504
- },
505
- renderDropIndicator: (target) => /* @__PURE__ */ React.createElement(
506
- DropIndicator,
507
- {
508
- target,
509
- className: "outline outline-1 outline-lime-200 ml-[calc(var(--tree-item-level)*0.5rem)]"
510
- }
511
- )
512
- });
513
- const [localSelectedKeys, setLocalSelectedKeys] = React.useState(/* @__PURE__ */ new Set());
514
- const selectedKeys = React.useMemo(
515
- () => effectiveActiveId != null ? /* @__PURE__ */ new Set([effectiveActiveId]) : localSelectedKeys,
516
- [effectiveActiveId, localSelectedKeys]
517
- );
518
- const pathToActive = React.useMemo(() => {
519
- if (!effectiveActiveId || isSearching || !articles.length) return [];
520
- const path = getParentKeys(articles, effectiveActiveId);
521
- return path ?? [];
522
- }, [articles, effectiveActiveId, isSearching]);
523
- const [expandedKeysState, setExpandedKeysState] = React.useState(/* @__PURE__ */ new Set());
524
- const expandedKeys = React.useMemo(
525
- () => /* @__PURE__ */ new Set([...pathToActive, ...expandedKeysState]),
526
- [pathToActive, expandedKeysState]
527
- );
528
- React.useEffect(() => {
529
- if (!activeArticleId) return;
530
- setLastSelectedArticleId(null);
531
- }, [activeArticleId, lastSelectedArticleId, setLastSelectedArticleId]);
532
- const pendingAddIdsRef = React.useRef(/* @__PURE__ */ new Set());
533
- const [pendingAddIds, setPendingAddIds] = React.useState(/* @__PURE__ */ new Set());
534
- const handleAddArticle = React.useCallback(
535
- (parentId) => {
536
- if (isSearching || !onAddArticle || pendingAddIdsRef.current.has(parentId)) return;
537
- pendingAddIdsRef.current.add(parentId);
538
- setPendingAddIds(new Set(pendingAddIdsRef.current));
539
- const tempId = `__placeholder_${++placeholderCounter}`;
540
- const placeholder = { id: tempId, label: "Untitled", href: "", status: "draft" };
541
- articlesTree.append(parentId, placeholder);
542
- setExpandedKeysState((prev) => /* @__PURE__ */ new Set([...prev, parentId]));
543
- onAddArticle(parentId).then(
544
- (created) => {
545
- articlesTree.remove(tempId);
546
- articlesTree.append(parentId, created);
547
- setLocalSelectedKeys(/* @__PURE__ */ new Set([created.id]));
548
- onSelectArticle?.(created.id);
549
- pendingAddIdsRef.current.delete(parentId);
550
- setPendingAddIds(new Set(pendingAddIdsRef.current));
551
- },
552
- () => {
553
- articlesTree.remove(tempId);
554
- pendingAddIdsRef.current.delete(parentId);
555
- setPendingAddIds(new Set(pendingAddIdsRef.current));
556
- }
557
- );
558
- },
559
- [isSearching, onAddArticle, articlesTree, onSelectArticle]
560
- );
561
- const navigateToArticleId = React.useCallback(
562
- (articleId) => {
563
- onSelectArticle?.(articleId);
564
- if (activeArticleId == null) {
565
- setLocalSelectedKeys(/* @__PURE__ */ new Set([articleId]));
566
- }
567
- if (isSearching) {
568
- setLastSelectedArticleId(articleId);
569
- setSearchValue("");
570
- handleSearchArticles?.("");
571
- }
572
- },
573
- [activeArticleId, handleSearchArticles, isSearching, onSelectArticle, setLastSelectedArticleId, setSearchValue]
574
- );
575
- return /* @__PURE__ */ React.createElement(
576
- Tree,
577
- {
578
- "aria-label": isSearching ? "Search results" : "Articles tree",
579
- items: articlesTree.items,
580
- renderEmptyState,
581
- dragAndDropHooks: isSearching ? void 0 : dragAndDropHooks,
582
- className: "flex flex-col",
583
- selectionBehavior: "toggle",
584
- selectionMode: "single",
585
- expandedKeys,
586
- onExpandedChange: (nextExpandedKeys) => {
587
- const newlyExpandedKeys = getNewlyExpandedKeys(expandedKeys, nextExpandedKeys);
588
- newlyExpandedKeys.forEach((key) => {
589
- onExpandArticle?.(key);
590
- });
591
- setExpandedKeysState(nextExpandedKeys);
592
- },
593
- selectedKeys,
594
- disallowEmptySelection: true,
595
- onSelectionChange: (selection) => {
596
- if (selection !== "all") {
597
- if (effectiveActiveId == null) setLocalSelectedKeys(selection);
598
- const selected = Array.from(selection)?.[0];
599
- if (selected) {
600
- navigateToArticleId(selected.toString());
601
- }
602
- }
603
- }
604
- },
605
- function renderItem(item) {
606
- return /* @__PURE__ */ React.createElement(
607
- TreeItem,
608
- {
609
- className: "list-none",
610
- textValue: item.value.label,
611
- id: item.value.id,
612
- hasChildItems: item.value.hasChildren
613
- },
614
- /* @__PURE__ */ React.createElement(TreeItemContent, null, (props) => /* @__PURE__ */ React.createElement(
615
- ArticleItem,
616
- {
617
- ItemLinkComponent,
618
- item,
619
- onAddArticle: !isSearching && onAddArticle ? handleAddArticle : void 0,
620
- isAddingArticle: !isSearching && pendingAddIds.has(item.value.id),
621
- isLoadingChildren: !isSearching && item.value.isLoadingChildren,
622
- onMoreActions: onMoreActions ? (articleId) => onMoreActions(articleId) : void 0,
623
- ...props
624
- }
625
- )),
626
- !isSearching && item.children && /* @__PURE__ */ React.createElement(Collection, { items: item.children }, renderItem)
627
- );
628
- }
629
- );
630
- }
631
-
632
- const ARTICLE_TREE_SEARCH_DEBOUNCE_MS = 400;
633
- const ARTICLE_TREE_SEARCH_DEBOUNCE_OPTIONS = { leading: true, trailing: true };
634
- function ArticleNav({ articles, className, isLoadingArticles }) {
635
- const { isSearching, searchValue, onAddArticle } = useSidebar();
636
- const { contains } = useSubstringFilter();
637
- const trimmedQuery = searchValue.trim();
638
- const [debouncedTreeQuery] = useDebounceValue(
639
- isSearching ? trimmedQuery : "",
640
- isSearching ? ARTICLE_TREE_SEARCH_DEBOUNCE_MS : 0,
641
- isSearching ? ARTICLE_TREE_SEARCH_DEBOUNCE_OPTIONS : void 0
642
- );
643
- const shouldShowLoadingState = !isSearching && (isLoadingArticles ?? articles === void 0);
644
- const renderLoadingEmptyState = React.useCallback(
645
- () => /* @__PURE__ */ React.createElement(
646
- "div",
647
- {
648
- className: "flex min-h-20 items-center justify-center text-muted-foreground",
649
- role: "status",
650
- "aria-live": "polite",
651
- "aria-label": "Loading articles list"
652
- },
653
- /* @__PURE__ */ React.createElement(Spinner, { className: "size-5", "aria-hidden": "true" }),
654
- /* @__PURE__ */ React.createElement("span", { className: "sr-only" }, "Loading articles list")
655
- ),
656
- []
657
- );
658
- const noArticles = !shouldShowLoadingState && !isSearching && (!articles || articles.length === 0);
659
- const filteredArticles = React.useMemo(() => {
660
- if (isSearching) {
661
- if (trimmedQuery === "" || debouncedTreeQuery === "") {
662
- return [];
663
- }
664
- const result = [];
665
- const query = debouncedTreeQuery;
666
- const traverse = (nodes) => {
667
- for (const item of nodes) {
668
- if (contains(item.label, query)) {
669
- result.push({ ...item, hasChildren: false, items: [] });
670
- }
671
- if (item.items?.length) {
672
- traverse(item.items);
673
- }
674
- }
675
- };
676
- traverse(articles ?? []);
677
- return result;
678
- }
679
- if (articles && articles.length > 0) {
680
- return articles;
681
- }
682
- return [];
683
- }, [articles, isSearching, trimmedQuery, debouncedTreeQuery, contains]);
684
- return /* @__PURE__ */ React.createElement("div", { className: cn("flex flex-col gap-0.5 px-4", className) }, noArticles && /* @__PURE__ */ React.createElement(Button, { variant: "ghost", className: "text-subtlest", onClick: () => onAddArticle?.(null).catch(() => {
685
- }) }, /* @__PURE__ */ React.createElement(Article, { "aria-hidden": "true" }), "Create first article or folder"), shouldShowLoadingState ? /* @__PURE__ */ React.createElement(ArticleTree, { articles: [], renderEmptyState: renderLoadingEmptyState }) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ArticleSearch, null), /* @__PURE__ */ React.createElement("nav", { "aria-label": "Articles navigation" }, /* @__PURE__ */ React.createElement(
686
- ArticleTree,
687
- {
688
- key: isSearching ? trimmedQuery === "" ? "search:empty" : `search:${debouncedTreeQuery}` : "browse",
689
- articles: filteredArticles ?? []
690
- }
691
- ))));
692
- }
693
-
694
- function SectionNav({ className, items, activeId }) {
695
- const { ItemLinkComponent } = useSidebar();
696
- return /* @__PURE__ */ React.createElement("nav", { className: cn("flex flex-col", className), "aria-label": "App section navigation" }, items.map((item) => /* @__PURE__ */ React.createElement(
697
- ItemLinkComponent,
698
- {
699
- key: item.id,
700
- href: item.href,
701
- "data-sidebar-item-id": item.id,
702
- "data-sidebar-item-type": "section",
703
- "data-sidebar-section-nav-item-selected": item.id === activeId,
704
- className: cn(
705
- "flex p-2 mx-4 text-base text-default relative rounded-lg",
706
- "after:transition-opacity after:absolute after:top-0 after:bottom-0 after:-right-4 after:w-2 after:bg-primary after:rounded-l-md after:opacity-0",
707
- "hover:bg-lime-100 focus:bg-lime-100 hover:text-primary-foreground focus:text-primary-foreground",
708
- item.id === activeId && "font-bold after:opacity-100"
709
- )
710
- },
711
- item.label
712
- )));
713
- }
714
-
715
- const Sidebar = React.forwardRef(function Sidebar2({
716
- className,
717
- ItemLinkComponent,
718
- collapsed,
719
- showAppBack,
720
- onAppBack,
721
- appNavItems,
722
- appNavActiveId,
723
- isLoadingArticles,
724
- sectionNavItems,
725
- sectionNavActiveId,
726
- activeArticleId,
727
- showArticles,
728
- articles,
729
- onSelectArticle,
730
- onExpandArticle,
731
- onSearchArticles,
732
- onAddArticle,
733
- onMoreActions,
734
- canMoveArticle,
735
- onMoveArticle,
736
- ...props
737
- }, ref) {
738
- const [atScrollBottom, setAtScrollBottom] = React.useState(false);
739
- const handleScroll = (event) => {
740
- const { scrollHeight, scrollTop, clientHeight } = event.currentTarget;
741
- setAtScrollBottom(scrollTop + clientHeight >= scrollHeight);
742
- };
743
- return /* @__PURE__ */ React.createElement(
744
- SidebarProvider,
745
- {
746
- collapsed: !!collapsed,
747
- ItemLinkComponent,
748
- activeArticleId,
749
- onSelectArticle,
750
- onExpandArticle,
751
- onSearchArticles,
752
- onAddArticle,
753
- onMoreActions,
754
- canMoveArticle,
755
- onMoveArticle
756
- },
757
- /* @__PURE__ */ React.createElement(
758
- "aside",
759
- {
760
- ref,
761
- ...props,
762
- className: cn(
763
- "py-4 transition-width duration-200 ease-in-out flex flex-col h-dvh",
764
- collapsed ? "w-[64px]" : "w-[260px]",
765
- className
766
- ),
767
- "aria-label": "Application navigation"
768
- },
769
- /* @__PURE__ */ React.createElement(
770
- AppNav,
771
- {
772
- className: cn(
773
- "flex-shrink-0",
774
- appNavItems && appNavItems.length > 0 && "pb-4",
775
- !collapsed && "border-b border-border-subtle"
776
- ),
777
- showBack: showAppBack,
778
- items: appNavItems,
779
- activeId: appNavActiveId,
780
- onBack: onAppBack
781
- }
782
- ),
783
- !collapsed && /* @__PURE__ */ React.createElement(React.Fragment, null, showArticles && /* @__PURE__ */ React.createElement(ScrollArea, { onScroll: handleScroll }, /* @__PURE__ */ React.createElement(
784
- ArticleNav,
785
- {
786
- className: "py-4 max-w-[var(--left-nav-width,inherit)]",
787
- articles,
788
- isLoadingArticles
789
- }
790
- )), sectionNavItems && sectionNavItems.length > 0 && /* @__PURE__ */ React.createElement(
791
- SectionNav,
792
- {
793
- className: cn("pt-4 flex-shrink-0", !collapsed && !atScrollBottom && "border-t border-subtle"),
794
- items: sectionNavItems,
795
- activeId: sectionNavActiveId
796
- }
797
- ))
798
- )
799
- );
800
- });
801
-
802
- export { Sidebar as S, useSidebar as u };
803
- //# sourceMappingURL=sidebar.BamKohb5.js.map