@brainfish-ai/components 0.22.5 → 0.22.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.
@@ -1,11 +1,11 @@
1
1
  import * as React from 'react';
2
2
  import { ScrollArea } from '../components/ui/scroll-area.js';
3
3
  import { c as cn } from './utils.Cwtlq8dh.js';
4
- import { ArrowBendUpLeft, MagnifyingGlass, CaretRight, DotsThree, Plus, Lightning, Circle, Article } from '@phosphor-icons/react';
4
+ import { ArrowBendUpLeft, X, MagnifyingGlass, Folder, FolderOpen, FolderDashed, DotsThree, Plus, FileDashed, File, Lightning, Article } from '@phosphor-icons/react';
5
5
  import { Button } from '../components/ui/button.js';
6
6
  import { u as useDebounce } from './hooks.CKojclfe.js';
7
7
  import { Input } from '../components/ui/input.js';
8
- import { Button as Button$1, useTreeData, useDragAndDrop, DropIndicator, Tree, TreeItem, TreeItemContent, Collection } from 'react-aria-components';
8
+ import { TreeStateContext, Button as Button$1, useTreeData, useDragAndDrop, DropIndicator, Tree, TreeItem, TreeItemContent, Collection } from 'react-aria-components';
9
9
  import { ButtonGroup } from '../components/ui/button-group.js';
10
10
 
11
11
  const SidebarContext = React.createContext(null);
@@ -22,9 +22,12 @@ function SidebarProvider({
22
22
  children
23
23
  }) {
24
24
  const [isSearching, setIsSearching] = React.useState(false);
25
+ const [searchValue, setSearchValue] = React.useState("");
26
+ const [lastSelectedArticleId, setLastSelectedArticleId] = React.useState(null);
25
27
  const handleSearchArticles = React.useCallback(
26
28
  (value) => {
27
- setIsSearching(value.trim() !== "");
29
+ const trimmedValue = value.trim();
30
+ setIsSearching(trimmedValue !== "");
28
31
  onSearchArticles?.(value);
29
32
  },
30
33
  [onSearchArticles]
@@ -41,10 +44,16 @@ function SidebarProvider({
41
44
  canMoveArticle,
42
45
  onMoveArticle,
43
46
  isSearching,
47
+ searchValue,
48
+ setSearchValue,
49
+ lastSelectedArticleId,
50
+ setLastSelectedArticleId,
44
51
  handleSearchArticles
45
52
  }),
46
53
  [
47
54
  isSearching,
55
+ searchValue,
56
+ lastSelectedArticleId,
48
57
  collapsed,
49
58
  ItemLinkComponent2,
50
59
  activeArticleId,
@@ -97,29 +106,41 @@ function AppNav({ className, items, activeId, showBack, onBack }) {
97
106
  }
98
107
 
99
108
  function ArticleSearch() {
100
- const { handleSearchArticles } = useSidebar();
109
+ const { handleSearchArticles, searchValue, setSearchValue } = useSidebar();
101
110
  const [searchInteracted, setSearchInteracted] = React.useState(false);
102
- const [searchValue, setSearchValue] = React.useState("");
103
- const debouncedSearchValue = useDebounce(searchValue, 500);
111
+ const debouncedSearchValue = useDebounce(searchValue, 300);
112
+ const searchInputRef = React.useRef(null);
104
113
  React.useEffect(() => {
105
114
  if (searchInteracted) handleSearchArticles?.(debouncedSearchValue);
106
115
  }, [debouncedSearchValue, handleSearchArticles, searchInteracted]);
107
116
  return /* @__PURE__ */ React.createElement("div", { className: "mb-2" }, /* @__PURE__ */ React.createElement(
108
117
  Input,
109
118
  {
119
+ ref: searchInputRef,
110
120
  className: "h-auto text-subtlest border-border-subtle",
111
- endIcon: MagnifyingGlass,
121
+ startIcon: MagnifyingGlass,
122
+ endIcon: searchValue ? X : void 0,
123
+ onEndIconClick: () => {
124
+ setSearchValue("");
125
+ handleSearchArticles?.("");
126
+ },
112
127
  value: searchValue,
113
128
  onChange: (e) => {
129
+ const value = e.target.value;
114
130
  if (!searchInteracted) setSearchInteracted(true);
115
- setSearchValue(e.target.value);
131
+ setSearchValue(value);
132
+ if (value.trim() === "") handleSearchArticles("");
116
133
  },
117
134
  placeholder: "Find an article",
118
- "aria-label": "Find an article"
135
+ "aria-label": "Find an article",
136
+ type: "search"
119
137
  }
120
138
  ));
121
139
  }
122
140
 
141
+ function FolderSlotButton({ children }) {
142
+ return /* @__PURE__ */ React.createElement(Button$1, { slot: "chevron", className: "relative z-30 flex p-0" }, /* @__PURE__ */ React.createElement("span", { className: "relative inline-flex size-4 items-center justify-center" }, children));
143
+ }
123
144
  function ArticleItem({
124
145
  item,
125
146
  hasChildItems,
@@ -128,8 +149,10 @@ function ArticleItem({
128
149
  ItemLinkComponent: ItemLinkComponent2,
129
150
  onAddArticle,
130
151
  isAddingArticle,
131
- onMoreActions
152
+ onMoreActions,
153
+ isSearching
132
154
  }) {
155
+ const treeState = React.useContext(TreeStateContext);
133
156
  const handleAddClick = (e) => {
134
157
  e.stopPropagation();
135
158
  onAddArticle?.(item.value.id);
@@ -151,20 +174,62 @@ function ArticleItem({
151
174
  default:
152
175
  statusLabel = "";
153
176
  }
154
- const chevronIcon = /* @__PURE__ */ React.createElement(Button$1, { slot: "chevron", className: "relative z-30 flex p-0 h-auto w-auto [&_svg]:size-4" }, /* @__PURE__ */ React.createElement(CaretRight, { "aria-hidden": "true", className: cn("transition-transform", isExpanded && "rotate-90") }));
155
- const discoveryIcon = /* @__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-4 shrink-0 text-blue-600" }));
156
- const unpublishedIcon = /* @__PURE__ */ React.createElement("span", { className: "flex size-4 shrink-0 items-center justify-center" }, /* @__PURE__ */ React.createElement("span", { className: "sr-only" }, "Unpublished Changes"), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border-2 size-1.5 border-current" }));
157
- const publishedIcon = /* @__PURE__ */ React.createElement("span", { className: "flex size-4 shrink-0 items-center justify-center" }, /* @__PURE__ */ React.createElement(Circle, { "aria-hidden": "true", className: "size-1.5", weight: "fill" }));
158
- const renderStatusIcon = (status, showPublishedIcon) => {
177
+ const folderIcon = /* @__PURE__ */ React.createElement(FolderSlotButton, null, /* @__PURE__ */ React.createElement(
178
+ Folder,
179
+ {
180
+ "aria-hidden": "true",
181
+ weight: "fill",
182
+ className: cn(
183
+ "absolute size-4 transition-opacity duration-200 ease-out",
184
+ isExpanded ? "opacity-0" : "opacity-100"
185
+ )
186
+ }
187
+ ), /* @__PURE__ */ React.createElement(
188
+ FolderOpen,
189
+ {
190
+ "aria-hidden": "true",
191
+ weight: "fill",
192
+ className: cn(
193
+ "absolute size-4 transition-opacity duration-200 ease-out",
194
+ isExpanded ? "opacity-100" : "opacity-0"
195
+ )
196
+ }
197
+ ));
198
+ const folderWithChangesIcon = /* @__PURE__ */ React.createElement(FolderSlotButton, null, /* @__PURE__ */ React.createElement(
199
+ FolderDashed,
200
+ {
201
+ "aria-hidden": "true",
202
+ weight: "fill",
203
+ className: cn(
204
+ "absolute size-4 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-4 transition-opacity duration-200 ease-out",
215
+ isExpanded ? "opacity-100" : "opacity-0"
216
+ )
217
+ }
218
+ ));
219
+ 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-4 shrink-0 text-blue-600" }));
220
+ const discoveryIcon = hasChildItems ? /* @__PURE__ */ React.createElement(FolderSlotButton, null, /* @__PURE__ */ React.createElement("span", { className: "text-blue-600" }, discoveryIconContent)) : /* @__PURE__ */ React.createElement("span", { className: "flex size-4 shrink-0 items-center justify-center text-blue-600" }, discoveryIconContent);
221
+ const fileIcon = /* @__PURE__ */ React.createElement("span", { className: "flex size-4 shrink-0 items-center justify-center" }, /* @__PURE__ */ React.createElement(File, { "aria-hidden": "true", className: "size-4" }));
222
+ const fileWithChangesIcon = /* @__PURE__ */ React.createElement("span", { className: "flex size-4 shrink-0 items-center justify-center" }, /* @__PURE__ */ React.createElement("span", { className: "sr-only" }, "Unpublished Changes"), /* @__PURE__ */ React.createElement(FileDashed, { "aria-hidden": "true", className: "size-4" }));
223
+ const renderStatusIcon = (status, hasChildItems2) => {
159
224
  if (status === "discovery") {
160
225
  return discoveryIcon;
161
- } else if (status === "unpublished" || status === "draft") {
162
- return unpublishedIcon;
163
226
  }
164
- if (showPublishedIcon) {
165
- return publishedIcon;
227
+ const hasChanges = status === "unpublished" || status === "draft";
228
+ if (hasChildItems2) {
229
+ return hasChanges ? folderWithChangesIcon : folderIcon;
230
+ } else {
231
+ return hasChanges ? fileWithChangesIcon : fileIcon;
166
232
  }
167
- return null;
168
233
  };
169
234
  return /* @__PURE__ */ React.createElement(
170
235
  "div",
@@ -176,8 +241,7 @@ function ArticleItem({
176
241
  )
177
242
  },
178
243
  /* @__PURE__ */ React.createElement(Button$1, { slot: "drag", className: "sr-only" }, "Drag ", item.value.label),
179
- hasChildItems && chevronIcon,
180
- renderStatusIcon(item.value.status, !hasChildItems),
244
+ isSearching ? null : renderStatusIcon(item.value.status, hasChildItems),
181
245
  /* @__PURE__ */ React.createElement(
182
246
  ItemLinkComponent2,
183
247
  {
@@ -188,7 +252,15 @@ function ArticleItem({
188
252
  className: cn(
189
253
  "min-w-0 text-inherit text-sm truncate flex-1 after:absolute after:inset-0 after:z-10 pr-1",
190
254
  isSelected && "text-primary-foreground"
191
- )
255
+ ),
256
+ onClick: hasChildItems && treeState ? () => {
257
+ treeState.toggleKey(item.key);
258
+ } : void 0,
259
+ onKeyDown: hasChildItems && treeState ? (e) => {
260
+ if (e.key === "Enter" || e.key === " ") {
261
+ treeState?.toggleKey(item.key);
262
+ }
263
+ } : void 0
192
264
  },
193
265
  item.value.label
194
266
  ),
@@ -241,16 +313,21 @@ function getParentKeys(items, targetId, parents = []) {
241
313
  }
242
314
  return null;
243
315
  }
244
- function ArticleTree({ articles }) {
316
+ function ArticleTree({ articles, isSearching }) {
245
317
  const {
246
318
  ItemLinkComponent,
247
319
  activeArticleId,
320
+ lastSelectedArticleId,
321
+ setLastSelectedArticleId,
248
322
  onSelectArticle,
323
+ handleSearchArticles,
324
+ setSearchValue,
249
325
  canMoveArticle,
250
326
  onMoveArticle,
251
327
  onAddArticle,
252
328
  onMoreActions
253
329
  } = useSidebar();
330
+ const effectiveActiveId = activeArticleId ?? lastSelectedArticleId ?? void 0;
254
331
  const articlesTree = useTreeData({
255
332
  initialItems: articles,
256
333
  getKey: (articleItem) => articleItem.id,
@@ -261,6 +338,7 @@ function ArticleTree({ articles }) {
261
338
  "text/plain": item.value.label
262
339
  })),
263
340
  onMove: (e) => {
341
+ if (isSearching) return;
264
342
  const movedArticleId = Array.from(e.keys)[0];
265
343
  if (!movedArticleId) return;
266
344
  const targetItem = articlesTree.getItem(e.target.key);
@@ -310,31 +388,40 @@ function ArticleTree({ articles }) {
310
388
  }
311
389
  )
312
390
  });
313
- const [selectedKeys, setSelectedKeys] = React.useState(new Set(activeArticleId ? [activeArticleId] : []));
314
- const [expandedKeys, setExpandedKeys] = React.useState(() => {
315
- if (!activeArticleId || !articlesTree?.items) return /* @__PURE__ */ new Set();
391
+ const [localSelectedKeys, setLocalSelectedKeys] = React.useState(/* @__PURE__ */ new Set());
392
+ const selectedKeys = effectiveActiveId != null ? /* @__PURE__ */ new Set([effectiveActiveId]) : localSelectedKeys;
393
+ const pathToActive = React.useMemo(() => {
394
+ if (!effectiveActiveId || isSearching || !articlesTree?.items?.length) return [];
316
395
  const path = getParentKeys(
317
396
  articlesTree.items.map((node) => node.value),
318
- activeArticleId
397
+ effectiveActiveId
319
398
  );
320
- return path ? new Set(path) : /* @__PURE__ */ new Set();
321
- });
399
+ return path ?? [];
400
+ }, [effectiveActiveId, isSearching, articlesTree.items]);
401
+ const [expandedKeysState, setExpandedKeysState] = React.useState(/* @__PURE__ */ new Set());
402
+ const expandedKeys = React.useMemo(
403
+ () => /* @__PURE__ */ new Set([...pathToActive, ...expandedKeysState]),
404
+ [pathToActive, expandedKeysState]
405
+ );
406
+ React.useEffect(() => {
407
+ if (activeArticleId) setLastSelectedArticleId(null);
408
+ }, [activeArticleId, setLastSelectedArticleId]);
322
409
  const pendingAddIdsRef = React.useRef(/* @__PURE__ */ new Set());
323
410
  const [pendingAddIds, setPendingAddIds] = React.useState(/* @__PURE__ */ new Set());
324
411
  const handleAddArticle = React.useCallback(
325
412
  (parentId) => {
326
- if (!onAddArticle || pendingAddIdsRef.current.has(parentId)) return;
413
+ if (isSearching || !onAddArticle || pendingAddIdsRef.current.has(parentId)) return;
327
414
  pendingAddIdsRef.current.add(parentId);
328
415
  setPendingAddIds(new Set(pendingAddIdsRef.current));
329
416
  const tempId = `__placeholder_${++placeholderCounter}`;
330
417
  const placeholder = { id: tempId, label: "Untitled", href: "", status: "draft" };
331
418
  articlesTree.append(parentId, placeholder);
332
- setExpandedKeys((prev) => /* @__PURE__ */ new Set([...prev, parentId]));
419
+ setExpandedKeysState((prev) => /* @__PURE__ */ new Set([...prev, parentId]));
333
420
  onAddArticle(parentId).then(
334
421
  (created) => {
335
422
  articlesTree.remove(tempId);
336
423
  articlesTree.append(parentId, created);
337
- setSelectedKeys(/* @__PURE__ */ new Set([created.id]));
424
+ setLocalSelectedKeys(/* @__PURE__ */ new Set([created.id]));
338
425
  onSelectArticle?.(created.id);
339
426
  pendingAddIdsRef.current.delete(parentId);
340
427
  setPendingAddIds(new Set(pendingAddIdsRef.current));
@@ -346,26 +433,34 @@ function ArticleTree({ articles }) {
346
433
  }
347
434
  );
348
435
  },
349
- [onAddArticle, articlesTree, onSelectArticle]
436
+ [isSearching, onAddArticle, articlesTree, onSelectArticle]
350
437
  );
351
438
  return /* @__PURE__ */ React.createElement(
352
439
  Tree,
353
440
  {
354
- "aria-label": "Articles tree",
441
+ "aria-label": isSearching ? "Search results" : "Articles tree",
355
442
  items: articlesTree.items,
356
- dragAndDropHooks,
443
+ dragAndDropHooks: isSearching ? void 0 : dragAndDropHooks,
357
444
  className: "flex flex-col gap-0.5",
358
445
  selectionBehavior: "toggle",
359
446
  selectionMode: "single",
360
447
  expandedKeys,
361
- onExpandedChange: setExpandedKeys,
448
+ onExpandedChange: setExpandedKeysState,
362
449
  selectedKeys,
363
450
  disallowEmptySelection: true,
364
451
  onSelectionChange: (selection) => {
365
452
  if (selection !== "all") {
366
- setSelectedKeys(selection);
453
+ if (effectiveActiveId == null) setLocalSelectedKeys(selection);
367
454
  const selected = Array.from(selection)?.[0];
368
- selected && onSelectArticle?.(selected.toString());
455
+ if (selected) {
456
+ const selectedId = selected.toString();
457
+ onSelectArticle?.(selectedId);
458
+ if (isSearching) {
459
+ setLastSelectedArticleId(selectedId);
460
+ setSearchValue("");
461
+ handleSearchArticles?.("");
462
+ }
463
+ }
369
464
  }
370
465
  }
371
466
  },
@@ -375,20 +470,43 @@ function ArticleTree({ articles }) {
375
470
  {
376
471
  ItemLinkComponent,
377
472
  item,
378
- onAddArticle: onAddArticle ? handleAddArticle : void 0,
379
- isAddingArticle: pendingAddIds.has(item.value.id),
473
+ onAddArticle: !isSearching && onAddArticle ? handleAddArticle : void 0,
474
+ isAddingArticle: !isSearching && pendingAddIds.has(item.value.id),
380
475
  onMoreActions: onMoreActions ? (articleId) => onMoreActions(articleId) : void 0,
476
+ isSearching,
381
477
  ...props
382
478
  }
383
- )), item.children && /* @__PURE__ */ React.createElement(Collection, { items: item.children }, renderItem));
479
+ )), !isSearching && item.children && /* @__PURE__ */ React.createElement(Collection, { items: item.children }, renderItem));
384
480
  }
385
481
  );
386
482
  }
387
483
 
484
+ function flattenAndFilterArticles(articles, query) {
485
+ const result = [];
486
+ const queryWords = query.toLowerCase().split(/\s+/).filter(Boolean);
487
+ const traverse = (items) => {
488
+ items.forEach((item) => {
489
+ const label = item.label.toLowerCase();
490
+ const isMatch = queryWords.every((word) => label.includes(word));
491
+ if (isMatch) {
492
+ result.push({ ...item, items: [] });
493
+ }
494
+ if (item.items) {
495
+ traverse(item.items);
496
+ }
497
+ });
498
+ };
499
+ traverse(articles);
500
+ return result;
501
+ }
388
502
  function ArticleNav({ articles, className }) {
389
- const { isSearching, onAddArticle } = useSidebar();
503
+ const { isSearching, searchValue, onAddArticle } = useSidebar();
504
+ const filteredArticles = React.useMemo(() => {
505
+ if (!isSearching || !articles) return [];
506
+ return flattenAndFilterArticles(articles, searchValue);
507
+ }, [articles, isSearching, searchValue]);
390
508
  return /* @__PURE__ */ React.createElement("div", { className: cn("flex flex-col gap-0.5 px-4", className) }, !isSearching && (!articles || articles.length === 0) ? /* @__PURE__ */ React.createElement(Button, { variant: "ghost", className: "text-subtlest", onClick: () => onAddArticle?.(null).catch(() => {
391
- }) }, /* @__PURE__ */ React.createElement(Article, { "aria-hidden": "true" }), "Create first article or folder") : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ArticleSearch, null), articles?.length ? /* @__PURE__ */ React.createElement("nav", { "aria-label": "Articles navigation" }, /* @__PURE__ */ React.createElement(ArticleTree, { articles })) : isSearching && articles?.length === 0 ? /* @__PURE__ */ React.createElement("span", null, "No articles found") : null));
509
+ }) }, /* @__PURE__ */ React.createElement(Article, { "aria-hidden": "true" }), "Create first article or folder") : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ArticleSearch, null), isSearching ? filteredArticles.length > 0 ? /* @__PURE__ */ React.createElement(ArticleTree, { key: searchValue, articles: filteredArticles, isSearching: true }) : /* @__PURE__ */ React.createElement("span", { className: "text-subtlest text-sm px-2" }, "No articles found") : articles?.length ? /* @__PURE__ */ React.createElement("nav", { "aria-label": "Articles navigation" }, /* @__PURE__ */ React.createElement(ArticleTree, { articles })) : null));
392
510
  }
393
511
 
394
512
  function SectionNav({ className, items, activeId }) {
@@ -457,7 +575,7 @@ const Sidebar = React.forwardRef(function Sidebar2({
457
575
  ref,
458
576
  ...props,
459
577
  className: cn(
460
- "py-4 transition-width duration-200 ease-in-out flex flex-col h-dvh justify-between",
578
+ "py-4 transition-width duration-200 ease-in-out flex flex-col h-dvh",
461
579
  collapsed ? "w-[64px]" : "w-[260px]",
462
580
  className
463
581
  ),
@@ -477,7 +595,7 @@ const Sidebar = React.forwardRef(function Sidebar2({
477
595
  onBack: onAppBack
478
596
  }
479
597
  ),
480
- !collapsed && /* @__PURE__ */ React.createElement(React.Fragment, null, showArticles && /* @__PURE__ */ React.createElement(ScrollArea, { className: "flex-1", onScroll: handleScroll }, /* @__PURE__ */ React.createElement(ArticleNav, { className: "py-4 max-w-[var(--left-nav-width,inherit)]", articles })), sectionNavItems && sectionNavItems.length > 0 && /* @__PURE__ */ React.createElement(
598
+ !collapsed && /* @__PURE__ */ React.createElement(React.Fragment, null, showArticles && /* @__PURE__ */ React.createElement(ScrollArea, { onScroll: handleScroll }, /* @__PURE__ */ React.createElement(ArticleNav, { className: "py-4 max-w-[var(--left-nav-width,inherit)]", articles })), sectionNavItems && sectionNavItems.length > 0 && /* @__PURE__ */ React.createElement(
481
599
  SectionNav,
482
600
  {
483
601
  className: cn("pt-4 flex-shrink-0", !collapsed && !atScrollBottom && "border-t border-subtle"),
@@ -490,4 +608,4 @@ const Sidebar = React.forwardRef(function Sidebar2({
490
608
  });
491
609
 
492
610
  export { Sidebar as S, useSidebar as u };
493
- //# sourceMappingURL=sidebar.DCi9MWl5.js.map
611
+ //# sourceMappingURL=sidebar.kcc3uFga.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sidebar.kcc3uFga.js","sources":["../../../src/layouts/sidebar/context.tsx","../../../src/layouts/sidebar/app-nav/app-nav.tsx","../../../src/layouts/sidebar/article-nav/article-search.tsx","../../../src/layouts/sidebar/article-nav/article-item.tsx","../../../src/layouts/sidebar/article-nav/article-tree.tsx","../../../src/layouts/sidebar/article-nav/article-nav.tsx","../../../src/layouts/sidebar/section-nav/section-nav.tsx","../../../src/layouts/sidebar/sidebar.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { ArticleNavItem, ItemLinkComponent } from './types';\n\nexport interface SidebarContextProps {\n collapsed: boolean;\n ItemLinkComponent: ItemLinkComponent;\n activeArticleId?: string;\n onSelectArticle?: (id: string) => void;\n onSearchArticles?: (value: string) => void;\n onAddArticle?: (parentId: string | null) => Promise<ArticleNavItem>;\n onMoreActions?: (articleId: string) => void;\n canMoveArticle?: (move: { id: string; parentId: string | null; index: number }) => boolean;\n onMoveArticle?: (moved: { id: string; parentId: string | null; index: number }) => void | Promise<void>;\n}\n\nexport interface SidebarContextValue extends SidebarContextProps {\n handleSearchArticles: (value: string) => void;\n isSearching: boolean;\n searchValue: string;\n setSearchValue: React.Dispatch<React.SetStateAction<string>>;\n /** Set when user selects from search results; tree uses this until activeArticleId catches up */\n lastSelectedArticleId: string | null;\n setLastSelectedArticleId: React.Dispatch<React.SetStateAction<string | null>>;\n}\n\nconst SidebarContext = React.createContext<SidebarContextValue | null>(null);\n\nexport function SidebarProvider({\n collapsed,\n ItemLinkComponent,\n activeArticleId,\n onSelectArticle,\n onSearchArticles,\n onAddArticle,\n onMoreActions,\n canMoveArticle,\n onMoveArticle,\n children,\n}: React.PropsWithChildren<SidebarContextProps>) {\n const [isSearching, setIsSearching] = React.useState<boolean>(false);\n const [searchValue, setSearchValue] = React.useState<string>('');\n const [lastSelectedArticleId, setLastSelectedArticleId] = React.useState<string | null>(null);\n\n const handleSearchArticles = React.useCallback(\n (value: string) => {\n const trimmedValue = value.trim();\n setIsSearching(trimmedValue !== '');\n onSearchArticles?.(value);\n },\n [onSearchArticles],\n );\n\n const contextValue = React.useMemo<SidebarContextValue>(\n () => ({\n collapsed,\n ItemLinkComponent,\n activeArticleId,\n onSearchArticles,\n onSelectArticle,\n onAddArticle,\n onMoreActions,\n canMoveArticle,\n onMoveArticle,\n isSearching,\n searchValue,\n setSearchValue,\n lastSelectedArticleId,\n setLastSelectedArticleId,\n handleSearchArticles,\n }),\n [\n isSearching,\n searchValue,\n lastSelectedArticleId,\n collapsed,\n ItemLinkComponent,\n activeArticleId,\n onSelectArticle,\n onSearchArticles,\n onAddArticle,\n onMoreActions,\n canMoveArticle,\n onMoveArticle,\n handleSearchArticles,\n ],\n );\n\n return <SidebarContext.Provider value={contextValue}>{children}</SidebarContext.Provider>;\n}\n\nexport function useSidebar() {\n const sidebarContext = React.useContext(SidebarContext);\n\n if (!sidebarContext) throw new Error('useSidebar must be used within SidebarProvider');\n\n return sidebarContext;\n}\n","import * as React from 'react';\nimport { ArrowBendUpLeft } from '@phosphor-icons/react';\n\nimport type { SidebarNavItem } from '../types';\nimport { useSidebar } from '../context';\n\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/lib/utils';\n\nexport interface AppNavProps {\n className?: string;\n items?: SidebarNavItem[];\n activeId?: string;\n showBack?: boolean;\n onBack?: () => void;\n}\n\nexport function AppNav({ className, items, activeId, showBack, onBack }: AppNavProps) {\n const { collapsed, ItemLinkComponent } = useSidebar();\n\n const hasBack = !!showBack && !!onBack;\n\n return (\n <nav className={cn('flex flex-col gap-2', className)} aria-label=\"App navigation\">\n {hasBack && (\n <Button\n variant=\"link\"\n className={cn('py-2 text-base text-default w-full', collapsed ? 'justify-center' : 'justify-start')}\n size=\"icon\"\n onClick={onBack}\n >\n <ArrowBendUpLeft aria-hidden=\"true\" />\n <span className={cn(collapsed && 'sr-only')}>back to Brainfish</span>\n </Button>\n )}\n {items?.map((item) => (\n <ItemLinkComponent\n key={item.id}\n className={cn(\n 'flex p-2 rounded-lg gap-1 text-base text-default items-center hover:text-primary-foreground focus:text-primary-foreground',\n item.id === activeId\n ? 'bg-primary text-primary-foreground font-bold'\n : 'hover:bg-lime-100 focus:bg-lime-100',\n )}\n href={item.href}\n data-sidebar-item-id={item.id}\n data-sidebar-item-type=\"app\"\n data-sidebar-app-nav-item-selected={item.id === activeId}\n >\n {item.Icon ? <item.Icon weight={item.id === activeId ? 'fill' : 'regular'} size={16} /> : null}\n <span className={cn('transition-opacity duration-200', collapsed && 'opacity-0 sr-only')}>{item.label}</span>\n </ItemLinkComponent>\n ))}\n </nav>\n );\n}\n","import * as React from 'react';\nimport { MagnifyingGlass, X } from '@phosphor-icons/react';\n\nimport { useSidebar } from '../context';\n\nimport { useDebounce } from '@/lib/hooks';\nimport { Input } from '@/components/ui/input';\n\nexport function ArticleSearch() {\n const { handleSearchArticles, searchValue, setSearchValue } = useSidebar();\n const [searchInteracted, setSearchInteracted] = React.useState(false);\n const debouncedSearchValue = useDebounce(searchValue, 300);\n const searchInputRef = React.useRef<HTMLInputElement>(null);\n\n React.useEffect(() => {\n if (searchInteracted) handleSearchArticles?.(debouncedSearchValue);\n }, [debouncedSearchValue, handleSearchArticles, searchInteracted]);\n\n return (\n <div className=\"mb-2\">\n <Input\n ref={searchInputRef}\n className=\"h-auto text-subtlest border-border-subtle\"\n startIcon={MagnifyingGlass}\n endIcon={searchValue ? X : undefined}\n onEndIconClick={() => {\n setSearchValue('');\n handleSearchArticles?.('');\n }}\n value={searchValue}\n onChange={(e) => {\n const value = e.target.value;\n if (!searchInteracted) setSearchInteracted(true);\n setSearchValue(value);\n if (value.trim() === '') handleSearchArticles('');\n }}\n placeholder=\"Find an article\"\n aria-label=\"Find an article\"\n type=\"search\"\n />\n </div>\n );\n}\n","import * as React from 'react';\nimport { Folder, FolderDashed, FolderOpen, File, FileDashed, DotsThree, Lightning, Plus } from '@phosphor-icons/react';\nimport { Key, TreeItemContentRenderProps, TreeStateContext, Button as AriaButton } from 'react-aria-components';\n\nimport { ArticleNavItem, ItemLinkComponent } from '../types';\n\nimport { cn } from '@/lib/utils';\nimport { Button } from '@/components/ui/button';\nimport { ButtonGroup } from '@/components/ui/button-group';\n\ntype ArticleItemTreeNode = {\n key: Key;\n value: ArticleNavItem;\n children: ArticleItemTreeNode[] | null;\n};\n\nfunction FolderSlotButton({ children }: { children: React.ReactNode }) {\n return (\n <AriaButton slot=\"chevron\" className=\"relative z-30 flex p-0\">\n <span className=\"relative inline-flex size-4 items-center justify-center\">{children}</span>\n </AriaButton>\n );\n}\n\nexport interface ArticleItemProps extends TreeItemContentRenderProps {\n ItemLinkComponent: ItemLinkComponent;\n item: ArticleItemTreeNode;\n onAddArticle?: (parentId: string) => void;\n isAddingArticle?: boolean;\n onMoreActions?: (articleId: string) => void;\n isSearching?: boolean;\n}\n\nexport function ArticleItem({\n item,\n hasChildItems,\n isSelected,\n isExpanded,\n ItemLinkComponent,\n onAddArticle,\n isAddingArticle,\n onMoreActions,\n isSearching,\n}: ArticleItemProps) {\n const treeState = React.useContext(TreeStateContext);\n\n const handleAddClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n onAddArticle?.(item.value.id);\n };\n\n const handleMoreClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n onMoreActions?.(item.value.id);\n };\n\n const showActions = !!((onAddArticle && !isAddingArticle) || onMoreActions);\n\n const isDraft = item.value.status === 'draft';\n\n let statusLabel: string;\n switch (item.value.status) {\n case 'draft':\n statusLabel = '(draft)';\n break;\n case 'unpublished':\n statusLabel = '(unpublished changes)';\n break;\n default:\n statusLabel = '';\n }\n\n const folderIcon = (\n <FolderSlotButton>\n <Folder\n aria-hidden=\"true\"\n weight=\"fill\"\n className={cn(\n 'absolute size-4 transition-opacity duration-200 ease-out',\n isExpanded ? 'opacity-0' : 'opacity-100',\n )}\n />\n <FolderOpen\n aria-hidden=\"true\"\n weight=\"fill\"\n className={cn(\n 'absolute size-4 transition-opacity duration-200 ease-out',\n isExpanded ? 'opacity-100' : 'opacity-0',\n )}\n />\n </FolderSlotButton>\n );\n\n const folderWithChangesIcon = (\n <FolderSlotButton>\n <FolderDashed\n aria-hidden=\"true\"\n weight=\"fill\"\n className={cn(\n 'absolute size-4 transition-opacity duration-200 ease-out',\n isExpanded ? 'opacity-0' : 'opacity-100',\n )}\n />\n <FolderOpen\n aria-hidden=\"true\"\n weight=\"fill\"\n className={cn(\n 'absolute size-4 transition-opacity duration-200 ease-out',\n isExpanded ? 'opacity-100' : 'opacity-0',\n )}\n />\n </FolderSlotButton>\n );\n\n const discoveryIconContent = (\n <>\n <span className=\"sr-only\">Knowledge Discovery</span>\n <Lightning aria-hidden=\"true\" weight=\"fill\" className=\"size-4 shrink-0 text-blue-600\" />\n </>\n );\n\n const discoveryIcon = hasChildItems ? (\n <FolderSlotButton>\n <span className=\"text-blue-600\">{discoveryIconContent}</span>\n </FolderSlotButton>\n ) : (\n <span className=\"flex size-4 shrink-0 items-center justify-center text-blue-600\">{discoveryIconContent}</span>\n );\n\n const fileIcon = (\n <span className=\"flex size-4 shrink-0 items-center justify-center\">\n <File aria-hidden=\"true\" className=\"size-4\" />\n </span>\n );\n\n const fileWithChangesIcon = (\n <span className=\"flex size-4 shrink-0 items-center justify-center\">\n <span className=\"sr-only\">Unpublished Changes</span>\n <FileDashed aria-hidden=\"true\" className=\"size-4\" />\n </span>\n );\n\n const renderStatusIcon = (status: ArticleNavItem['status'], hasChildItems: boolean) => {\n if (status === 'discovery') {\n return discoveryIcon;\n }\n\n const hasChanges = status === 'unpublished' || status === 'draft';\n\n if (hasChildItems) {\n return hasChanges ? folderWithChangesIcon : folderIcon;\n } else {\n return hasChanges ? fileWithChangesIcon : fileIcon;\n }\n };\n\n return (\n <div\n className={cn(\n 'group relative flex items-center gap-1 rounded-md py-1 pl-[calc(var(--tree-item-level)*0.5rem)] pr-4 h-9',\n isDraft && 'text-subtlest italic',\n isSelected\n ? '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'\n : 'hover:bg-dark-200 hover:text-accent-foreground',\n )}\n >\n <AriaButton slot=\"drag\" className=\"sr-only\">\n Drag {item.value.label}\n </AriaButton>\n\n {isSearching ? null : renderStatusIcon(item.value.status, hasChildItems)}\n\n <ItemLinkComponent\n href={item.value.href}\n title={`${item.value.label} ${statusLabel}`}\n data-sidebar-item-id={item.value.id}\n data-sidebar-item-type=\"article\"\n className={cn(\n 'min-w-0 text-inherit text-sm truncate flex-1 after:absolute after:inset-0 after:z-10 pr-1',\n isSelected && 'text-primary-foreground',\n )}\n onClick={\n hasChildItems && treeState\n ? () => {\n treeState.toggleKey(item.key);\n }\n : undefined\n }\n onKeyDown={\n hasChildItems && treeState\n ? (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n treeState?.toggleKey(item.key);\n }\n }\n : undefined\n }\n >\n {item.value.label}\n </ItemLinkComponent>\n\n {showActions && (\n <ButtonGroup\n orientation=\"horizontal\"\n className={cn(\n 'absolute h-4 my-auto right-0.5 top-0 bottom-0 z-20 hidden items-center rounded-xl',\n 'group-hover:flex group-focus-within:flex',\n isSelected ? 'bg-lime-100 text-primary-foreground' : 'bg-dark-200',\n )}\n >\n {onMoreActions && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={`More actions for ${item.value.label}`}\n className=\"size-4 [&_svg]:size-3.5\"\n onClick={handleMoreClick}\n >\n <DotsThree aria-hidden=\"true\" weight=\"bold\" />\n </Button>\n )}\n\n {onAddArticle && !isAddingArticle && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={`Add article to ${item.value.label}`}\n className=\"size-4 [&_svg]:size-3.5\"\n onClick={handleAddClick}\n >\n <Plus aria-hidden=\"true\" />\n </Button>\n )}\n </ButtonGroup>\n )}\n </div>\n );\n}\n","import * as React from 'react';\nimport {\n useDragAndDrop,\n useTreeData,\n Tree,\n TreeItem,\n TreeItemContent,\n Collection,\n DropIndicator,\n type Key,\n} from 'react-aria-components';\n\nimport { ArticleNavItem } from '../types';\nimport { ArticleItem } from './article-item';\nimport { useSidebar } from '../context';\n\nlet placeholderCounter = 0;\n\ninterface ArticleTreeProps {\n articles: ArticleNavItem[];\n isSearching?: boolean;\n}\n\nfunction getParentKeys(items: ArticleNavItem[], targetId: string, parents: string[] = []): string[] | null {\n for (const item of items) {\n if (item.id === targetId) {\n return parents;\n }\n if (item.items && item.items.length > 0) {\n const result = getParentKeys(item.items, targetId, [...parents, item.id]);\n if (result) return result;\n }\n }\n\n return null;\n}\n\nexport function ArticleTree({ articles, isSearching }: ArticleTreeProps) {\n const {\n ItemLinkComponent,\n activeArticleId,\n lastSelectedArticleId,\n setLastSelectedArticleId,\n onSelectArticle,\n handleSearchArticles,\n setSearchValue,\n canMoveArticle,\n onMoveArticle,\n onAddArticle,\n onMoreActions,\n } = useSidebar();\n\n const effectiveActiveId = activeArticleId ?? lastSelectedArticleId ?? undefined;\n\n const articlesTree = useTreeData({\n initialItems: articles,\n getKey: (articleItem) => articleItem.id,\n getChildren: (articleItem) => articleItem.items ?? [],\n });\n\n const { dragAndDropHooks } = useDragAndDrop({\n getItems: (_keys, items: typeof articlesTree.items) =>\n items.map((item) => ({\n 'text/plain': item.value.label,\n })),\n onMove: (e) => {\n if (isSearching) return;\n const movedArticleId = Array.from(e.keys)[0];\n if (!movedArticleId) return;\n\n const targetItem = articlesTree.getItem(e.target.key);\n if (!targetItem) return;\n\n let movedToParentId: string | null;\n let movedToIndex: number;\n\n if (e.target.dropPosition === 'on') {\n movedToParentId = e.target.key.toString();\n movedToIndex = targetItem.children?.length ?? 0;\n } else {\n movedToParentId = targetItem.parentKey?.toString() ?? null;\n const siblings = movedToParentId ? (articlesTree.getItem(movedToParentId)?.children ?? []) : articlesTree.items;\n const targetIndex = siblings.findIndex((i) => i.key === e.target.key);\n movedToIndex = e.target.dropPosition === 'before' ? targetIndex : targetIndex + 1;\n }\n\n const moveDetails = {\n id: movedArticleId.toString(),\n parentId: movedToParentId,\n index: movedToIndex,\n };\n\n if (canMoveArticle && !canMoveArticle(moveDetails)) {\n return;\n }\n\n const movedItem = articlesTree.getItem(movedArticleId);\n const originalParentId = movedItem?.parentKey?.toString() ?? null;\n const originalSiblings = originalParentId\n ? (articlesTree.getItem(originalParentId)?.children ?? [])\n : articlesTree.items;\n const originalIndex = originalSiblings.findIndex((i) => i.key === movedArticleId);\n\n if (e.target.dropPosition === 'on') {\n articlesTree.move(movedArticleId, movedToParentId, movedToIndex);\n } else if (e.target.dropPosition === 'before') {\n articlesTree.moveBefore(e.target.key, e.keys);\n } else {\n articlesTree.moveAfter(e.target.key, e.keys);\n }\n\n const result = onMoveArticle?.(moveDetails);\n\n if (result && typeof result.then === 'function') {\n result.catch(() => {\n articlesTree.move(movedArticleId, originalParentId, originalIndex);\n });\n }\n },\n renderDropIndicator: (target) => (\n <DropIndicator\n target={target}\n className=\"outline outline-1 outline-lime-200 ml-[calc(var(--tree-item-level)*0.5rem)]\"\n />\n ),\n });\n\n // Selection when there's no active article from URL/context; used so the tree can show a selection before navigation.\n const [localSelectedKeys, setLocalSelectedKeys] = React.useState<Set<Key>>(new Set());\n const selectedKeys = effectiveActiveId != null ? new Set<Key>([effectiveActiveId]) : localSelectedKeys;\n\n const pathToActive = React.useMemo(() => {\n if (!effectiveActiveId || isSearching || !articlesTree?.items?.length) return [];\n const path = getParentKeys(\n articlesTree.items.map((node) => node.value),\n effectiveActiveId,\n );\n\n return path ?? [];\n }, [effectiveActiveId, isSearching, articlesTree.items]);\n\n const [expandedKeysState, setExpandedKeysState] = React.useState<Set<Key>>(new Set());\n const expandedKeys = React.useMemo(\n () => new Set<Key>([...pathToActive, ...expandedKeysState]),\n [pathToActive, expandedKeysState],\n );\n\n React.useEffect(() => {\n if (activeArticleId) setLastSelectedArticleId(null);\n }, [activeArticleId, setLastSelectedArticleId]);\n\n const pendingAddIdsRef = React.useRef<Set<string>>(new Set());\n const [pendingAddIds, setPendingAddIds] = React.useState<Set<string>>(new Set());\n\n const handleAddArticle = React.useCallback(\n (parentId: string) => {\n if (isSearching || !onAddArticle || pendingAddIdsRef.current.has(parentId)) return;\n\n pendingAddIdsRef.current.add(parentId);\n setPendingAddIds(new Set(pendingAddIdsRef.current));\n\n const tempId = `__placeholder_${++placeholderCounter}`;\n const placeholder: ArticleNavItem = { id: tempId, label: 'Untitled', href: '', status: 'draft' };\n\n articlesTree.append(parentId, placeholder);\n setExpandedKeysState((prev) => new Set([...prev, parentId]));\n\n onAddArticle(parentId).then(\n (created) => {\n articlesTree.remove(tempId);\n articlesTree.append(parentId, created);\n // Highlight the newly created article in the tree.\n setLocalSelectedKeys(new Set([created.id]));\n onSelectArticle?.(created.id);\n pendingAddIdsRef.current.delete(parentId);\n setPendingAddIds(new Set(pendingAddIdsRef.current));\n },\n () => {\n articlesTree.remove(tempId);\n pendingAddIdsRef.current.delete(parentId);\n setPendingAddIds(new Set(pendingAddIdsRef.current));\n },\n );\n },\n [isSearching, onAddArticle, articlesTree, onSelectArticle],\n );\n\n return (\n <Tree\n aria-label={isSearching ? 'Search results' : 'Articles tree'}\n items={articlesTree.items}\n dragAndDropHooks={isSearching ? undefined : dragAndDropHooks}\n className=\"flex flex-col gap-0.5\"\n selectionBehavior=\"toggle\"\n selectionMode=\"single\"\n expandedKeys={expandedKeys}\n onExpandedChange={setExpandedKeysState}\n selectedKeys={selectedKeys}\n disallowEmptySelection\n onSelectionChange={(selection) => {\n if (selection !== 'all') {\n // Keep local selection in sync when we're not driven by URL/active article.\n if (effectiveActiveId == null) setLocalSelectedKeys(selection);\n const selected = Array.from(selection)?.[0];\n\n if (selected) {\n const selectedId = selected.toString();\n onSelectArticle?.(selectedId);\n\n if (isSearching) {\n setLastSelectedArticleId(selectedId);\n setSearchValue('');\n handleSearchArticles?.('');\n }\n }\n }\n }}\n >\n {function renderItem(item) {\n return (\n <TreeItem className=\"list-none\" textValue={item.value.label} id={item.value.id}>\n <TreeItemContent>\n {(props) => (\n <ArticleItem\n ItemLinkComponent={ItemLinkComponent}\n item={item}\n onAddArticle={!isSearching && onAddArticle ? handleAddArticle : undefined}\n isAddingArticle={!isSearching && pendingAddIds.has(item.value.id)}\n onMoreActions={onMoreActions ? (articleId) => onMoreActions(articleId) : undefined}\n isSearching={isSearching}\n {...props}\n />\n )}\n </TreeItemContent>\n\n {!isSearching && item.children && <Collection items={item.children}>{renderItem}</Collection>}\n </TreeItem>\n );\n }}\n </Tree>\n );\n}\n","import * as React from 'react';\nimport { Article } from '@phosphor-icons/react';\n\nimport { useSidebar } from '../context';\nimport { ArticleNavItem } from '../types';\nimport { ArticleSearch } from './article-search';\nimport { ArticleTree } from './article-tree';\n\nimport { cn } from '@/lib/utils';\nimport { Button } from '@/components/ui/button';\n\nexport interface ArticleNavProps {\n className?: string;\n articles?: ArticleNavItem[];\n}\n\nfunction flattenAndFilterArticles(articles: ArticleNavItem[], query: string): ArticleNavItem[] {\n const result: ArticleNavItem[] = [];\n const queryWords = query.toLowerCase().split(/\\s+/).filter(Boolean);\n\n const traverse = (items: ArticleNavItem[]) => {\n items.forEach((item) => {\n const label = item.label.toLowerCase();\n const isMatch = queryWords.every((word) => label.includes(word));\n\n if (isMatch) {\n // Keep the original item but without its children for the flat view\n result.push({ ...item, items: [] });\n }\n if (item.items) {\n traverse(item.items);\n }\n });\n };\n\n traverse(articles);\n\n return result;\n}\n\nexport function ArticleNav({ articles, className }: ArticleNavProps) {\n const { isSearching, searchValue, onAddArticle } = useSidebar();\n\n const filteredArticles = React.useMemo(() => {\n if (!isSearching || !articles) return [];\n\n return flattenAndFilterArticles(articles, searchValue);\n }, [articles, isSearching, searchValue]);\n\n return (\n <div className={cn('flex flex-col gap-0.5 px-4', className)}>\n {!isSearching && (!articles || articles.length === 0) ? (\n <Button variant=\"ghost\" className=\"text-subtlest\" onClick={() => onAddArticle?.(null).catch(() => {})}>\n <Article aria-hidden=\"true\" />\n Create first article or folder\n </Button>\n ) : (\n <>\n <ArticleSearch />\n {isSearching ? (\n filteredArticles.length > 0 ? (\n <ArticleTree key={searchValue} articles={filteredArticles} isSearching />\n ) : (\n <span className=\"text-subtlest text-sm px-2\">No articles found</span>\n )\n ) : articles?.length ? (\n <nav aria-label=\"Articles navigation\">\n <ArticleTree articles={articles} />\n </nav>\n ) : null}\n </>\n )}\n </div>\n );\n}\n","import * as React from 'react';\n\nimport { SidebarNavItem } from '../types';\nimport { useSidebar } from '../context';\n\nimport { cn } from '@/lib/utils';\n\nexport interface SectionNavProps {\n className?: string;\n items: SidebarNavItem[];\n activeId?: string;\n}\n\nexport function SectionNav({ className, items, activeId }: SectionNavProps) {\n const { ItemLinkComponent } = useSidebar();\n\n return (\n <nav className={cn('flex flex-col', className)} aria-label=\"App section navigation\">\n {items.map((item) => (\n <ItemLinkComponent\n key={item.id}\n href={item.href}\n data-sidebar-item-id={item.id}\n data-sidebar-item-type=\"section\"\n data-sidebar-section-nav-item-selected={item.id === activeId}\n className={cn(\n 'flex p-2 mx-4 text-base text-default relative rounded-lg',\n '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',\n 'hover:bg-lime-100 focus:bg-lime-100 hover:text-primary-foreground focus:text-primary-foreground',\n item.id === activeId && 'font-bold after:opacity-100',\n )}\n >\n {item.label}\n </ItemLinkComponent>\n ))}\n </nav>\n );\n}\n","import * as React from 'react';\n\nimport { SidebarNavItem, ArticleNavItem } from './types';\nimport { SidebarContextProps, SidebarProvider } from './context';\nimport { AppNav } from './app-nav';\nimport { ArticleNav } from './article-nav';\nimport { SectionNav } from './section-nav';\n\nimport { ScrollArea } from '@/components/ui/scroll-area';\nimport { cn } from '@/lib/utils';\n\nexport interface SidebarProps extends React.ComponentPropsWithoutRef<'aside'>, SidebarContextProps {\n showAppBack?: boolean;\n onAppBack?: () => void;\n appNavItems?: SidebarNavItem[];\n appNavActiveId?: string;\n showArticles?: boolean;\n articles?: ArticleNavItem[];\n sectionNavItems?: SidebarNavItem[];\n sectionNavActiveId?: string;\n}\n\nexport const Sidebar = React.forwardRef<HTMLElement, SidebarProps>(function Sidebar(\n {\n className,\n ItemLinkComponent,\n collapsed,\n showAppBack,\n onAppBack,\n appNavItems,\n appNavActiveId,\n sectionNavItems,\n sectionNavActiveId,\n activeArticleId,\n showArticles,\n articles,\n onSelectArticle,\n onSearchArticles,\n onAddArticle,\n onMoreActions,\n canMoveArticle,\n onMoveArticle,\n ...props\n },\n ref,\n) {\n // indicates if the scroll area is at the bottom\n const [atScrollBottom, setAtScrollBottom] = React.useState(false);\n\n // detect if the scroll area is at the bottom\n const handleScroll = (event: React.UIEvent<HTMLDivElement>) => {\n const { scrollHeight, scrollTop, clientHeight } = event.currentTarget;\n setAtScrollBottom(scrollTop + clientHeight >= scrollHeight);\n };\n\n return (\n <SidebarProvider\n collapsed={!!collapsed}\n ItemLinkComponent={ItemLinkComponent}\n activeArticleId={activeArticleId}\n onSelectArticle={onSelectArticle}\n onSearchArticles={onSearchArticles}\n onAddArticle={onAddArticle}\n onMoreActions={onMoreActions}\n canMoveArticle={canMoveArticle}\n onMoveArticle={onMoveArticle}\n >\n <aside\n ref={ref}\n {...props}\n className={cn(\n 'py-4 transition-width duration-200 ease-in-out flex flex-col h-dvh',\n collapsed ? 'w-[64px]' : 'w-[260px]',\n className,\n )}\n aria-label=\"Application navigation\"\n >\n <AppNav\n className={cn(\n 'px-4 flex-shrink-0',\n appNavItems && appNavItems.length > 0 && 'pb-4',\n !collapsed && 'border-b border-border-subtle',\n )}\n showBack={showAppBack}\n items={appNavItems}\n activeId={appNavActiveId}\n onBack={onAppBack}\n />\n\n {!collapsed && (\n <>\n {showArticles && (\n <ScrollArea onScroll={handleScroll}>\n <ArticleNav className=\"py-4 max-w-[var(--left-nav-width,inherit)]\" articles={articles} />\n </ScrollArea>\n )}\n {sectionNavItems && sectionNavItems.length > 0 && (\n <SectionNav\n className={cn('pt-4 flex-shrink-0', !collapsed && !atScrollBottom && 'border-t border-subtle')}\n items={sectionNavItems}\n activeId={sectionNavActiveId}\n />\n )}\n </>\n )}\n </aside>\n </SidebarProvider>\n );\n});\n"],"names":["ItemLinkComponent","AriaButton","hasChildItems","Sidebar"],"mappings":"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"}
@@ -2,15 +2,25 @@ import React__default from 'react';
2
2
  import { c as cn } from '../../chunks/utils.Cwtlq8dh.js';
3
3
 
4
4
  const Input = React__default.forwardRef(
5
- ({ className, type, startIcon, endIcon, ...props }, ref) => {
5
+ ({ className, type, startIcon, endIcon, onStartIconClick, onEndIconClick, ...props }, ref) => {
6
6
  const StartIcon = startIcon;
7
7
  const EndIcon = endIcon;
8
- return /* @__PURE__ */ React__default.createElement("div", { className: "w-full relative" }, StartIcon && /* @__PURE__ */ React__default.createElement("div", { className: "absolute left-1.5 top-1/2 transform -translate-y-1/2" }, /* @__PURE__ */ React__default.createElement(StartIcon, { size: 18, className: "text-muted-foreground" })), /* @__PURE__ */ React__default.createElement(
8
+ return /* @__PURE__ */ React__default.createElement("div", { className: "w-full relative" }, StartIcon && /* @__PURE__ */ React__default.createElement("div", { className: "absolute left-2 top-1/2 transform -translate-y-1/2" }, onStartIconClick ? /* @__PURE__ */ React__default.createElement(
9
+ "button",
10
+ {
11
+ type: "button",
12
+ onClick: onStartIconClick,
13
+ className: "flex items-center justify-center cursor-pointer hover:opacity-70 transition-opacity",
14
+ "aria-label": "Clear start icon"
15
+ },
16
+ /* @__PURE__ */ React__default.createElement(StartIcon, { size: 18, className: "text-muted-foreground" })
17
+ ) : /* @__PURE__ */ React__default.createElement(StartIcon, { size: 18, className: "text-muted-foreground" })), /* @__PURE__ */ React__default.createElement(
9
18
  "input",
10
19
  {
11
20
  type,
12
21
  className: cn(
13
22
  "flex h-12 w-full rounded-md border border-border bg-transparent py-3 text-base transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
23
+ type === "search" && !!endIcon && "appearance-none [&::-webkit-search-cancel-button]:hidden [&::-webkit-search-decoration]:hidden [&::-webkit-search-results-button]:hidden [&::-webkit-search-results-decoration]:hidden",
14
24
  startIcon && "pl-8 pr-4",
15
25
  endIcon && "pl-4 pr-8",
16
26
  startIcon && endIcon && "px-8",
@@ -20,7 +30,16 @@ const Input = React__default.forwardRef(
20
30
  ref,
21
31
  ...props
22
32
  }
23
- ), EndIcon && /* @__PURE__ */ React__default.createElement("div", { className: "absolute right-3 top-1/2 transform -translate-y-1/2" }, /* @__PURE__ */ React__default.createElement(EndIcon, { className: "text-muted-foreground", size: 18 })));
33
+ ), EndIcon && /* @__PURE__ */ React__default.createElement("div", { className: "absolute right-3 top-1/2 transform -translate-y-1/2" }, onEndIconClick ? /* @__PURE__ */ React__default.createElement(
34
+ "button",
35
+ {
36
+ type: "button",
37
+ onClick: onEndIconClick,
38
+ className: "flex items-center justify-center cursor-pointer hover:opacity-70 transition-opacity",
39
+ "aria-label": "Clear input"
40
+ },
41
+ /* @__PURE__ */ React__default.createElement(EndIcon, { className: "text-muted-foreground", size: 18 })
42
+ ) : /* @__PURE__ */ React__default.createElement(EndIcon, { className: "text-muted-foreground", size: 18 })));
24
43
  }
25
44
  );
26
45
  Input.displayName = "Input";
@@ -1 +1 @@
1
- {"version":3,"file":"input.js","sources":["../../../../src/components/ui/input.tsx"],"sourcesContent":["import React from 'react';\nimport { type Icon } from '@phosphor-icons/react';\n\nimport { cn } from '@/lib/utils';\n\nexport interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {\n startIcon?: Icon;\n endIcon?: Icon;\n}\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, type, startIcon, endIcon, ...props }, ref) => {\n const StartIcon = startIcon;\n const EndIcon = endIcon;\n\n return (\n <div className=\"w-full relative\">\n {StartIcon && (\n <div className=\"absolute left-1.5 top-1/2 transform -translate-y-1/2\">\n <StartIcon size={18} className=\"text-muted-foreground\" />\n </div>\n )}\n <input\n type={type}\n className={cn(\n 'flex h-12 w-full rounded-md border border-border bg-transparent py-3 text-base transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',\n startIcon && 'pl-8 pr-4',\n endIcon && 'pl-4 pr-8',\n startIcon && endIcon && 'px-8',\n !startIcon && !endIcon && 'px-4',\n className,\n )}\n ref={ref}\n {...props}\n />\n {EndIcon && (\n <div className=\"absolute right-3 top-1/2 transform -translate-y-1/2\">\n <EndIcon className=\"text-muted-foreground\" size={18} />\n </div>\n )}\n </div>\n );\n },\n);\nInput.displayName = 'Input';\n\nexport { Input };\n"],"names":["React"],"mappings":";;;AAUA,MAAM,QAAQA,cAAA,CAAM,UAAA;AAAA,EAClB,CAAC,EAAE,SAAA,EAAW,IAAA,EAAM,WAAW,OAAA,EAAS,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AAC1D,IAAA,MAAM,SAAA,GAAY,SAAA;AAClB,IAAA,MAAM,OAAA,GAAU,OAAA;AAEhB,IAAA,oDACG,KAAA,EAAA,EAAI,SAAA,EAAU,iBAAA,EAAA,EACZ,SAAA,iDACE,KAAA,EAAA,EAAI,SAAA,EAAU,sDAAA,EAAA,kBACbA,cAAA,CAAA,aAAA,CAAC,aAAU,IAAA,EAAM,EAAA,EAAI,SAAA,EAAU,uBAAA,EAAwB,CACzD,CAAA,kBAEFA,cAAA,CAAA,aAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,IAAA;AAAA,QACA,SAAA,EAAW,EAAA;AAAA,UACT,4VAAA;AAAA,UACA,SAAA,IAAa,WAAA;AAAA,UACb,OAAA,IAAW,WAAA;AAAA,UACX,aAAa,OAAA,IAAW,MAAA;AAAA,UACxB,CAAC,SAAA,IAAa,CAAC,OAAA,IAAW,MAAA;AAAA,UAC1B;AAAA,SACF;AAAA,QACA,GAAA;AAAA,QACC,GAAG;AAAA;AAAA,KACN,EACC,OAAA,oBACCA,cAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qDAAA,EAAA,kBACbA,cAAA,CAAA,aAAA,CAAC,OAAA,EAAA,EAAQ,SAAA,EAAU,uBAAA,EAAwB,IAAA,EAAM,EAAA,EAAI,CACvD,CAEJ,CAAA;AAAA,EAEJ;AACF;AACA,KAAA,CAAM,WAAA,GAAc,OAAA;;;;"}
1
+ {"version":3,"file":"input.js","sources":["../../../../src/components/ui/input.tsx"],"sourcesContent":["import React from 'react';\nimport { type Icon } from '@phosphor-icons/react';\n\nimport { cn } from '@/lib/utils';\n\nexport interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {\n startIcon?: Icon;\n endIcon?: Icon;\n onStartIconClick?: () => void;\n onEndIconClick?: () => void;\n}\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, type, startIcon, endIcon, onStartIconClick, onEndIconClick, ...props }, ref) => {\n const StartIcon = startIcon;\n const EndIcon = endIcon;\n\n return (\n <div className=\"w-full relative\">\n {StartIcon && (\n <div className=\"absolute left-2 top-1/2 transform -translate-y-1/2\">\n {onStartIconClick ? (\n <button\n type=\"button\"\n onClick={onStartIconClick}\n className=\"flex items-center justify-center cursor-pointer hover:opacity-70 transition-opacity\"\n aria-label=\"Clear start icon\"\n >\n <StartIcon size={18} className=\"text-muted-foreground\" />\n </button>\n ) : (\n <StartIcon size={18} className=\"text-muted-foreground\" />\n )}\n </div>\n )}\n <input\n type={type}\n className={cn(\n 'flex h-12 w-full rounded-md border border-border bg-transparent py-3 text-base transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',\n type === 'search' &&\n !!endIcon &&\n 'appearance-none [&::-webkit-search-cancel-button]:hidden [&::-webkit-search-decoration]:hidden [&::-webkit-search-results-button]:hidden [&::-webkit-search-results-decoration]:hidden',\n startIcon && 'pl-8 pr-4',\n endIcon && 'pl-4 pr-8',\n startIcon && endIcon && 'px-8',\n !startIcon && !endIcon && 'px-4',\n className,\n )}\n ref={ref}\n {...props}\n />\n {EndIcon && (\n <div className=\"absolute right-3 top-1/2 transform -translate-y-1/2\">\n {onEndIconClick ? (\n <button\n type=\"button\"\n onClick={onEndIconClick}\n className=\"flex items-center justify-center cursor-pointer hover:opacity-70 transition-opacity\"\n aria-label=\"Clear input\"\n >\n <EndIcon className=\"text-muted-foreground\" size={18} />\n </button>\n ) : (\n <EndIcon className=\"text-muted-foreground\" size={18} />\n )}\n </div>\n )}\n </div>\n );\n },\n);\nInput.displayName = 'Input';\n\nexport { Input };\n"],"names":["React"],"mappings":";;;AAYA,MAAM,QAAQA,cAAA,CAAM,UAAA;AAAA,EAClB,CAAC,EAAE,SAAA,EAAW,IAAA,EAAM,SAAA,EAAW,OAAA,EAAS,gBAAA,EAAkB,cAAA,EAAgB,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AAC5F,IAAA,MAAM,SAAA,GAAY,SAAA;AAClB,IAAA,MAAM,OAAA,GAAU,OAAA;AAEhB,IAAA,uBACEA,cAAA,CAAA,aAAA,CAAC,SAAI,SAAA,EAAU,iBAAA,EAAA,EACZ,6BACCA,cAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oDAAA,EAAA,EACZ,gBAAA,mBACCA,cAAA,CAAA,aAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,OAAA,EAAS,gBAAA;AAAA,QACT,SAAA,EAAU,qFAAA;AAAA,QACV,YAAA,EAAW;AAAA,OAAA;AAAA,sBAEXA,cAAA,CAAA,aAAA,CAAC,SAAA,EAAA,EAAU,IAAA,EAAM,EAAA,EAAI,WAAU,uBAAA,EAAwB;AAAA,KACzD,gDAEC,SAAA,EAAA,EAAU,IAAA,EAAM,IAAI,SAAA,EAAU,uBAAA,EAAwB,CAE3D,CAAA,kBAEFA,cAAA,CAAA,aAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,IAAA;AAAA,QACA,SAAA,EAAW,EAAA;AAAA,UACT,4VAAA;AAAA,UACA,IAAA,KAAS,QAAA,IACP,CAAC,CAAC,OAAA,IACF,wLAAA;AAAA,UACF,SAAA,IAAa,WAAA;AAAA,UACb,OAAA,IAAW,WAAA;AAAA,UACX,aAAa,OAAA,IAAW,MAAA;AAAA,UACxB,CAAC,SAAA,IAAa,CAAC,OAAA,IAAW,MAAA;AAAA,UAC1B;AAAA,SACF;AAAA,QACA,GAAA;AAAA,QACC,GAAG;AAAA;AAAA,OAEL,OAAA,oBACCA,cAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yDACZ,cAAA,mBACCA,cAAA,CAAA,aAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,OAAA,EAAS,cAAA;AAAA,QACT,SAAA,EAAU,qFAAA;AAAA,QACV,YAAA,EAAW;AAAA,OAAA;AAAA,sBAEXA,cAAA,CAAA,aAAA,CAAC,OAAA,EAAA,EAAQ,SAAA,EAAU,uBAAA,EAAwB,MAAM,EAAA,EAAI;AAAA,KACvD,gDAEC,OAAA,EAAA,EAAQ,SAAA,EAAU,yBAAwB,IAAA,EAAM,EAAA,EAAI,CAEzD,CAEJ,CAAA;AAAA,EAEJ;AACF;AACA,KAAA,CAAM,WAAA,GAAc,OAAA;;;;"}
@@ -2,7 +2,15 @@ import * as React from 'react';
2
2
  import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
3
3
  import { c as cn } from '../../chunks/utils.Cwtlq8dh.js';
4
4
 
5
- const ScrollArea = React.forwardRef(({ className, children, onScroll, ...props }, ref) => /* @__PURE__ */ React.createElement(ScrollAreaPrimitive.Root, { className: cn("relative overflow-hidden", className), ...props }, /* @__PURE__ */ React.createElement(ScrollAreaPrimitive.Viewport, { ref, className: "h-full w-full rounded-[inherit]", onScroll }, children), /* @__PURE__ */ React.createElement(ScrollBar, null), /* @__PURE__ */ React.createElement(ScrollAreaPrimitive.Corner, null)));
5
+ const ScrollArea = React.forwardRef(({ className, children, onScroll, ...props }, ref) => /* @__PURE__ */ React.createElement(ScrollAreaPrimitive.Root, { className: cn("relative overflow-hidden", className), ...props }, /* @__PURE__ */ React.createElement(
6
+ ScrollAreaPrimitive.Viewport,
7
+ {
8
+ ref,
9
+ className: "h-full w-full rounded-[inherit] [&_>div]:w-full [&_>div]:table-fixed",
10
+ onScroll
11
+ },
12
+ children
13
+ ), /* @__PURE__ */ React.createElement(ScrollBar, null), /* @__PURE__ */ React.createElement(ScrollAreaPrimitive.Corner, null)));
6
14
  ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
7
15
  const ScrollBar = React.forwardRef(({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */ React.createElement(
8
16
  ScrollAreaPrimitive.ScrollAreaScrollbar,
@@ -1 +1 @@
1
- {"version":3,"file":"scroll-area.js","sources":["../../../../src/components/ui/scroll-area.tsx"],"sourcesContent":["import * as React from 'react';\nimport * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';\n\nimport { cn } from '@/lib/utils';\n\nconst ScrollArea = React.forwardRef<\n React.ElementRef<typeof ScrollAreaPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>\n>(({ className, children, onScroll, ...props }, ref) => (\n <ScrollAreaPrimitive.Root className={cn('relative overflow-hidden', className)} {...props}>\n <ScrollAreaPrimitive.Viewport ref={ref} className=\"h-full w-full rounded-[inherit]\" onScroll={onScroll}>\n {children}\n </ScrollAreaPrimitive.Viewport>\n <ScrollBar />\n <ScrollAreaPrimitive.Corner />\n </ScrollAreaPrimitive.Root>\n));\nScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;\n\nconst ScrollBar = React.forwardRef<\n React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,\n React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>\n>(({ className, orientation = 'vertical', ...props }, ref) => (\n <ScrollAreaPrimitive.ScrollAreaScrollbar\n ref={ref}\n orientation={orientation}\n className={cn(\n 'flex touch-none select-none transition-colors',\n orientation === 'vertical' && 'h-full w-2.5 border-l border-l-transparent p-[1px]',\n orientation === 'horizontal' && 'h-2.5 flex-col border-t border-t-transparent p-[1px]',\n className,\n )}\n {...props}\n >\n <ScrollAreaPrimitive.ScrollAreaThumb className=\"relative flex-1 rounded-full bg-dark-400\" />\n </ScrollAreaPrimitive.ScrollAreaScrollbar>\n));\nScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;\n\nexport { ScrollArea, ScrollBar };\n"],"names":[],"mappings":";;;;AAKA,MAAM,aAAa,KAAA,CAAM,UAAA,CAGvB,CAAC,EAAE,SAAA,EAAW,UAAU,QAAA,EAAU,GAAG,KAAA,EAAM,EAAG,wBAC9C,KAAA,CAAA,aAAA,CAAC,mBAAA,CAAoB,MAApB,EAAyB,SAAA,EAAW,GAAG,0BAAA,EAA4B,SAAS,CAAA,EAAI,GAAG,yBAClF,KAAA,CAAA,aAAA,CAAC,mBAAA,CAAoB,UAApB,EAA6B,GAAA,EAAU,WAAU,iCAAA,EAAkC,QAAA,EAAA,EACjF,QACH,CAAA,kBACA,KAAA,CAAA,aAAA,CAAC,eAAU,CAAA,kBACX,KAAA,CAAA,aAAA,CAAC,oBAAoB,MAAA,EAApB,IAA2B,CAC9B,CACD;AACD,UAAA,CAAW,WAAA,GAAc,oBAAoB,IAAA,CAAK,WAAA;AAElD,MAAM,SAAA,GAAY,KAAA,CAAM,UAAA,CAGtB,CAAC,EAAE,SAAA,EAAW,WAAA,GAAc,UAAA,EAAY,GAAG,KAAA,EAAM,EAAG,GAAA,qBACpD,KAAA,CAAA,aAAA;AAAA,EAAC,mBAAA,CAAoB,mBAAA;AAAA,EAApB;AAAA,IACC,GAAA;AAAA,IACA,WAAA;AAAA,IACA,SAAA,EAAW,EAAA;AAAA,MACT,+CAAA;AAAA,MACA,gBAAgB,UAAA,IAAc,oDAAA;AAAA,MAC9B,gBAAgB,YAAA,IAAgB,sDAAA;AAAA,MAChC;AAAA,KACF;AAAA,IACC,GAAG;AAAA,GAAA;AAAA,kBAEJ,KAAA,CAAA,aAAA,CAAC,mBAAA,CAAoB,eAAA,EAApB,EAAoC,WAAU,0CAAA,EAA2C;AAC5F,CACD;AACD,SAAA,CAAU,WAAA,GAAc,oBAAoB,mBAAA,CAAoB,WAAA;;;;"}
1
+ {"version":3,"file":"scroll-area.js","sources":["../../../../src/components/ui/scroll-area.tsx"],"sourcesContent":["import * as React from 'react';\nimport * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';\n\nimport { cn } from '@/lib/utils';\n\nconst ScrollArea = React.forwardRef<\n React.ElementRef<typeof ScrollAreaPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>\n>(({ className, children, onScroll, ...props }, ref) => (\n <ScrollAreaPrimitive.Root className={cn('relative overflow-hidden', className)} {...props}>\n <ScrollAreaPrimitive.Viewport\n ref={ref}\n className=\"h-full w-full rounded-[inherit] [&_>div]:w-full [&_>div]:table-fixed\"\n onScroll={onScroll}\n >\n {children}\n </ScrollAreaPrimitive.Viewport>\n <ScrollBar />\n <ScrollAreaPrimitive.Corner />\n </ScrollAreaPrimitive.Root>\n));\nScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;\n\nconst ScrollBar = React.forwardRef<\n React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,\n React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>\n>(({ className, orientation = 'vertical', ...props }, ref) => (\n <ScrollAreaPrimitive.ScrollAreaScrollbar\n ref={ref}\n orientation={orientation}\n className={cn(\n 'flex touch-none select-none transition-colors',\n orientation === 'vertical' && 'h-full w-2.5 border-l border-l-transparent p-[1px]',\n orientation === 'horizontal' && 'h-2.5 flex-col border-t border-t-transparent p-[1px]',\n className,\n )}\n {...props}\n >\n <ScrollAreaPrimitive.ScrollAreaThumb className=\"relative flex-1 rounded-full bg-dark-400\" />\n </ScrollAreaPrimitive.ScrollAreaScrollbar>\n));\nScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;\n\nexport { ScrollArea, ScrollBar };\n"],"names":[],"mappings":";;;;AAKA,MAAM,UAAA,GAAa,MAAM,UAAA,CAGvB,CAAC,EAAE,SAAA,EAAW,QAAA,EAAU,QAAA,EAAU,GAAG,KAAA,EAAM,EAAG,wBAC9C,KAAA,CAAA,aAAA,CAAC,mBAAA,CAAoB,MAApB,EAAyB,SAAA,EAAW,GAAG,0BAAA,EAA4B,SAAS,CAAA,EAAI,GAAG,KAAA,EAAA,kBAClF,KAAA,CAAA,aAAA;AAAA,EAAC,mBAAA,CAAoB,QAAA;AAAA,EAApB;AAAA,IACC,GAAA;AAAA,IACA,SAAA,EAAU,sEAAA;AAAA,IACV;AAAA,GAAA;AAAA,EAEC;AACH,CAAA,kBACA,KAAA,CAAA,aAAA,CAAC,eAAU,CAAA,kBACX,KAAA,CAAA,aAAA,CAAC,oBAAoB,MAAA,EAApB,IAA2B,CAC9B,CACD;AACD,UAAA,CAAW,WAAA,GAAc,oBAAoB,IAAA,CAAK,WAAA;AAElD,MAAM,SAAA,GAAY,KAAA,CAAM,UAAA,CAGtB,CAAC,EAAE,SAAA,EAAW,WAAA,GAAc,UAAA,EAAY,GAAG,KAAA,EAAM,EAAG,GAAA,qBACpD,KAAA,CAAA,aAAA;AAAA,EAAC,mBAAA,CAAoB,mBAAA;AAAA,EAApB;AAAA,IACC,GAAA;AAAA,IACA,WAAA;AAAA,IACA,SAAA,EAAW,EAAA;AAAA,MACT,+CAAA;AAAA,MACA,gBAAgB,UAAA,IAAc,oDAAA;AAAA,MAC9B,gBAAgB,YAAA,IAAgB,sDAAA;AAAA,MAChC;AAAA,KACF;AAAA,IACC,GAAG;AAAA,GAAA;AAAA,kBAEJ,KAAA,CAAA,aAAA,CAAC,mBAAA,CAAoB,eAAA,EAApB,EAAoC,WAAU,0CAAA,EAA2C;AAC5F,CACD;AACD,SAAA,CAAU,WAAA,GAAc,oBAAoB,mBAAA,CAAoB,WAAA;;;;"}