@brainfish-ai/components 0.23.7 → 0.23.9

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sidebar.Ck_Z9Zmb.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/expansion.ts","../../../src/layouts/sidebar/article-nav/tree-sync.ts","../../../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 onExpandArticle?: (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 onExpandArticle,\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 onExpandArticle,\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 onExpandArticle,\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 { ScrollArea } from '@/components/ui/scroll-area';\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 mx-4', 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 <ScrollArea className=\"min-h-0 max-h-[calc(100dvh-var(--header-nav-height)-5rem)]\">\n <div className=\"flex flex-col gap-2 mx-4\">\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')}>\n {item.label}\n </span>\n </ItemLinkComponent>\n ))}\n </div>\n </ScrollArea>\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-3 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 level,\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-3 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-3 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-3 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-3 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-3 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-3 shrink-0 items-center justify-center text-blue-600\">{discoveryIconContent}</span>\n );\n\n const fileIcon = (\n <span className=\"flex size-3 shrink-0 items-center justify-center\">\n <File aria-hidden=\"true\" className=\"size-3\" />\n </span>\n );\n\n const fileWithChangesIcon = (\n <span className=\"flex size-3 shrink-0 items-center justify-center\">\n <span className=\"sr-only\">Unpublished Changes</span>\n <FileDashed aria-hidden=\"true\" className=\"size-3\" />\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 style={{ ['--line-offset' as string]: '0.875rem' }}\n className={cn(\n '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',\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 {Array.from({ length: level - 1 }, (_, i) => (\n <span\n key={`${item.value.label}-${i + 1}`}\n style={{ ['--item-line-level' as string]: i + 1 }}\n // Don't mess with the calc: forumula for multiple lines.\n className=\"absolute w-[1px] bg-dark-400 -top-2 h-9 left-[calc(-4px-var(--line-offset)*(var(--item-line-level)-1))]\"\n aria-hidden={true}\n />\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 type { Key } from 'react-aria-components';\n\nexport function getNewlyExpandedKeys(previous: Iterable<Key>, next: Iterable<Key>): string[] {\n const previousKeys = new Set(Array.from(previous, (key) => key.toString()));\n\n return Array.from(next, (key) => key.toString()).filter((key) => !previousKeys.has(key));\n}\n","import type { ArticleNavItem } from '../types';\n\ntype TreeEntry = {\n item: ArticleNavItem;\n parentId: string | null;\n index: number;\n depth: number;\n};\n\nexport type TreeSyncOperation =\n | { type: 'remove'; id: string }\n | { type: 'insert'; parentId: string | null; index: number; item: ArticleNavItem }\n | { type: 'move'; id: string; parentId: string | null; index: number }\n | { type: 'update'; id: string; item: ArticleNavItem };\n\nfunction flattenArticles(items: ArticleNavItem[], parentId: string | null = null, depth = 0, result: TreeEntry[] = []): TreeEntry[] {\n items.forEach((item, index) => {\n result.push({ item, parentId, index, depth });\n if (item.items?.length) {\n flattenArticles(item.items, item.id, depth + 1, result);\n }\n });\n\n return result;\n}\n\nfunction haveSameValue(a: ArticleNavItem, b: ArticleNavItem) {\n return a.label === b.label && a.href === b.href && a.status === b.status && a.hasChildren === b.hasChildren;\n}\n\nexport function buildArticleTreeSyncOperations(currentArticles: ArticleNavItem[], nextArticles: ArticleNavItem[]): TreeSyncOperation[] {\n const currentEntries = flattenArticles(currentArticles);\n const nextEntries = flattenArticles(nextArticles);\n\n const currentMap = new Map(currentEntries.map((entry) => [entry.item.id, entry]));\n const nextMap = new Map(nextEntries.map((entry) => [entry.item.id, entry]));\n const operations: TreeSyncOperation[] = [];\n\n currentEntries\n .filter((entry) => !nextMap.has(entry.item.id))\n .sort((a, b) => b.depth - a.depth)\n .forEach((entry) => {\n operations.push({ type: 'remove', id: entry.item.id });\n });\n\n nextEntries.forEach((entry) => {\n const currentEntry = currentMap.get(entry.item.id);\n\n if (!currentEntry) {\n operations.push({\n type: 'insert',\n parentId: entry.parentId,\n index: entry.index,\n item: entry.item,\n });\n\n return;\n }\n\n if (currentEntry.parentId !== entry.parentId || currentEntry.index !== entry.index) {\n operations.push({\n type: 'move',\n id: entry.item.id,\n parentId: entry.parentId,\n index: entry.index,\n });\n }\n\n if (!haveSameValue(currentEntry.item, entry.item)) {\n operations.push({\n type: 'update',\n id: entry.item.id,\n item: entry.item,\n });\n }\n });\n\n return operations;\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';\nimport { getNewlyExpandedKeys } from './expansion';\nimport { buildArticleTreeSyncOperations } from './tree-sync';\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\ntype ArticleTreeNode = {\n value: ArticleNavItem;\n children: ArticleTreeNode[] | null;\n};\n\nfunction treeNodesToArticleNavItems(items: ArticleTreeNode[]): ArticleNavItem[] {\n return items.map((item) => ({\n ...item.value,\n items: item.children?.length ? treeNodesToArticleNavItems(item.children) : item.value.items,\n }));\n}\n\nexport function ArticleTree({ articles, isSearching }: ArticleTreeProps) {\n const {\n ItemLinkComponent,\n activeArticleId,\n lastSelectedArticleId,\n setLastSelectedArticleId,\n onSelectArticle,\n onExpandArticle,\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 React.useEffect(() => {\n const currentArticles = treeNodesToArticleNavItems(articlesTree.items);\n const operations = buildArticleTreeSyncOperations(currentArticles, articles);\n\n operations.forEach((operation) => {\n switch (operation.type) {\n case 'remove':\n articlesTree.remove(operation.id);\n break;\n case 'insert':\n articlesTree.insert(operation.parentId, operation.index, operation.item);\n break;\n case 'move':\n articlesTree.move(operation.id, operation.parentId, operation.index);\n break;\n case 'update':\n articlesTree.update(operation.id, operation.item);\n break;\n }\n });\n }, [articles, articlesTree]);\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\"\n selectionBehavior=\"toggle\"\n selectionMode=\"single\"\n expandedKeys={expandedKeys}\n onExpandedChange={(nextExpandedKeys) => {\n const newlyExpandedKeys = getNewlyExpandedKeys(expandedKeys, nextExpandedKeys);\n\n newlyExpandedKeys.forEach((key) => {\n onExpandArticle?.(key);\n });\n\n setExpandedKeysState(nextExpandedKeys);\n }}\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\n className=\"list-none\"\n textValue={item.value.label}\n id={item.value.id}\n hasChildItems={item.value.hasChildren}\n >\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, hasChildren: false, 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 onExpandArticle,\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 onExpandArticle={onExpandArticle}\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 '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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"}
@@ -0,0 +1,75 @@
1
+ import React__default from 'react';
2
+ import { LineChart, CartesianGrid, XAxis, Line } from 'recharts';
3
+ import { a as TrendValue } from '../chunks/trend-value.COSukPwk.js';
4
+ import { Card, CardHeader, CardContent } from './ui/card.js';
5
+ import { C as ChartContainer, a as ChartTooltip, b as ChartTooltipContent, c as ChartLegend, d as ChartLegendContent } from '../chunks/chart.4ZbtBMmR.js';
6
+ import { f as formatNumber } from '../chunks/formatNumber.Bm2k8QrT.js';
7
+ import { u as useChartDateFormatters } from '../chunks/useChartDateFormatters.DS9ASgFO.js';
8
+ import { c as cn } from '../chunks/utils.Cwtlq8dh.js';
9
+
10
+ const formatWhole = (value) => formatNumber(value, {});
11
+ function ArticlesUpdated({
12
+ total,
13
+ trend,
14
+ trendValue,
15
+ data,
16
+ chartConfig,
17
+ dashedKeys = [],
18
+ locale,
19
+ className
20
+ }) {
21
+ const { tickFormatter, formatXLabel } = useChartDateFormatters(locale);
22
+ const lineKeys = Object.keys(chartConfig);
23
+ return /* @__PURE__ */ React__default.createElement(Card, { className: cn("shadow-none border border-dark-300 rounded-lg", className) }, /* @__PURE__ */ React__default.createElement(CardHeader, { className: "p-0 space-y-0 border-b border-dark-300" }, /* @__PURE__ */ React__default.createElement("div", { className: "flex flex-col gap-1 justify-center py-4 px-4" }, /* @__PURE__ */ React__default.createElement("p", { className: "uppercase heading-xxxs font-semibold text-dark tracking-normal" }, "Articles updated"), /* @__PURE__ */ React__default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React__default.createElement("span", { className: "font-mono text-3xl leading-10 text-dark" }, formatWhole(total)), /* @__PURE__ */ React__default.createElement(TrendValue, { trend, trendValue })))), /* @__PURE__ */ React__default.createElement(CardContent, { className: "p-4" }, /* @__PURE__ */ React__default.createElement(ChartContainer, { config: chartConfig, className: "h-48 w-full" }, /* @__PURE__ */ React__default.createElement(LineChart, { data, margin: { top: 8, left: 20, right: 20, bottom: 0 } }, /* @__PURE__ */ React__default.createElement(CartesianGrid, { horizontal: true, vertical: false, className: "stroke-dark-300" }), /* @__PURE__ */ React__default.createElement(
24
+ XAxis,
25
+ {
26
+ dataKey: "date",
27
+ tickLine: false,
28
+ axisLine: false,
29
+ tickMargin: 8,
30
+ padding: { left: 15, right: 15 },
31
+ minTickGap: 32,
32
+ interval: "preserveStartEnd",
33
+ tickFormatter,
34
+ tick: ({ x, y, payload, index }) => {
35
+ const isFirst = index === 0;
36
+ const isLast = index === data.length - 1;
37
+ const anchor = isFirst ? "start" : isLast ? "end" : "middle";
38
+ const tickX = isFirst ? x - 15 : isLast ? x + 15 : x;
39
+ return /* @__PURE__ */ React__default.createElement("text", { x: tickX, y, dy: 12, textAnchor: anchor, className: "text-xs fill-dark-600" }, tickFormatter(payload.value));
40
+ }
41
+ }
42
+ ), /* @__PURE__ */ React__default.createElement(
43
+ ChartTooltip,
44
+ {
45
+ cursor: false,
46
+ content: ({ active, payload, label }) => /* @__PURE__ */ React__default.createElement(
47
+ ChartTooltipContent,
48
+ {
49
+ active,
50
+ payload,
51
+ label: formatXLabel(label),
52
+ className: "min-w-52"
53
+ }
54
+ )
55
+ }
56
+ ), lineKeys.map((key) => {
57
+ const isDashed = dashedKeys.includes(key);
58
+ return /* @__PURE__ */ React__default.createElement(
59
+ Line,
60
+ {
61
+ key,
62
+ dataKey: key,
63
+ type: "monotone",
64
+ stroke: `var(--color-${key})`,
65
+ strokeWidth: 2,
66
+ strokeDasharray: isDashed ? "5 5" : void 0,
67
+ dot: ({ cx, cy, stroke }) => /* @__PURE__ */ React__default.createElement("circle", { cx, cy, r: 4, fill: "white", stroke, strokeWidth: 2 }),
68
+ activeDot: { r: 5, strokeWidth: 0 }
69
+ }
70
+ );
71
+ }), /* @__PURE__ */ React__default.createElement(ChartLegend, { content: /* @__PURE__ */ React__default.createElement(ChartLegendContent, null) })))));
72
+ }
73
+
74
+ export { ArticlesUpdated };
75
+ //# sourceMappingURL=articles-updated.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"articles-updated.js","sources":["../../../src/components/articles-updated/articles-updated.tsx"],"sourcesContent":["import React from 'react';\nimport { CartesianGrid, Line, LineChart, XAxis } from 'recharts';\n\nimport { Trend, TrendValue } from '../trend-value';\n\nimport { Card, CardContent, CardHeader } from '@/components/ui/card';\nimport {\n ChartConfig,\n ChartContainer,\n ChartLegend,\n ChartLegendContent,\n ChartTooltip,\n ChartTooltipContent,\n} from '@/components/ui/chart';\nimport { formatNumber } from '@/lib/formatNumber';\nimport { useChartDateFormatters } from '@/lib/useChartDateFormatters';\nimport { cn } from '@/lib/utils';\n\nexport interface ArticlesUpdatedProps {\n total: number;\n trend: Trend;\n trendValue: string;\n data: Array<Record<string, number | string | Date>>;\n chartConfig: ChartConfig;\n dashedKeys?: string[];\n locale?: string;\n className?: string;\n}\n\nconst formatWhole = (value: number) => formatNumber(value, {});\n\nexport function ArticlesUpdated({\n total,\n trend,\n trendValue,\n data,\n chartConfig,\n dashedKeys = [],\n locale,\n className,\n}: ArticlesUpdatedProps) {\n const { tickFormatter, formatXLabel } = useChartDateFormatters(locale);\n const lineKeys = Object.keys(chartConfig);\n\n return (\n <Card className={cn('shadow-none border border-dark-300 rounded-lg', className)}>\n <CardHeader className=\"p-0 space-y-0 border-b border-dark-300\">\n <div className=\"flex flex-col gap-1 justify-center py-4 px-4\">\n <p className=\"uppercase heading-xxxs font-semibold text-dark tracking-normal\">Articles updated</p>\n <div className=\"flex items-center gap-2\">\n <span className=\"font-mono text-3xl leading-10 text-dark\">{formatWhole(total)}</span>\n <TrendValue trend={trend} trendValue={trendValue} />\n </div>\n </div>\n </CardHeader>\n\n <CardContent className=\"p-4\">\n <ChartContainer config={chartConfig} className=\"h-48 w-full\">\n <LineChart data={data} margin={{ top: 8, left: 20, right: 20, bottom: 0 }}>\n <CartesianGrid horizontal vertical={false} className=\"stroke-dark-300\" />\n <XAxis\n dataKey=\"date\"\n tickLine={false}\n axisLine={false}\n tickMargin={8}\n padding={{ left: 15, right: 15 }}\n minTickGap={32}\n interval=\"preserveStartEnd\"\n tickFormatter={tickFormatter}\n tick={({ x, y, payload, index }) => {\n const isFirst = index === 0;\n const isLast = index === data.length - 1;\n const anchor = isFirst ? 'start' : isLast ? 'end' : 'middle';\n const tickX = isFirst ? x - 15 : isLast ? x + 15 : x;\n\n return (\n <text x={tickX} y={y} dy={12} textAnchor={anchor} className=\"text-xs fill-dark-600\">\n {tickFormatter(payload.value)}\n </text>\n );\n }}\n />\n <ChartTooltip\n cursor={false}\n content={({ active, payload, label }) => (\n <ChartTooltipContent\n active={active}\n payload={payload}\n label={formatXLabel(label)}\n className=\"min-w-52\"\n />\n )}\n />\n {lineKeys.map((key) => {\n const isDashed = dashedKeys.includes(key);\n\n return (\n <Line\n key={key}\n dataKey={key}\n type=\"monotone\"\n stroke={`var(--color-${key})`}\n strokeWidth={2}\n strokeDasharray={isDashed ? '5 5' : undefined}\n dot={({ cx, cy, stroke }: { cx: number; cy: number; stroke: string }) => (\n <circle cx={cx} cy={cy} r={4} fill=\"white\" stroke={stroke} strokeWidth={2} />\n )}\n activeDot={{ r: 5, strokeWidth: 0 }}\n />\n );\n })}\n <ChartLegend content={<ChartLegendContent />} />\n </LineChart>\n </ChartContainer>\n </CardContent>\n </Card>\n );\n}\n"],"names":["React"],"mappings":"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"}