@brainfish-ai/components 0.30.5 → 0.30.7
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.
- package/dist/chat-search.d.ts +11 -1
- package/dist/conversation.d.ts +4 -2
- package/dist/esm/ChatSearch.css +1 -1
- package/dist/esm/chunks/{ChatSearch.BLZiMiJ3.js → ChatSearch.B0vv3DDb.js} +89 -84
- package/dist/esm/chunks/ChatSearch.B0vv3DDb.js.map +1 -0
- package/dist/esm/chunks/Conversation.UzfPizn5.js +29 -0
- package/dist/esm/chunks/Conversation.UzfPizn5.js.map +1 -0
- package/dist/esm/chunks/ConversationStatus.BhdnM1uS.js +2 -0
- package/dist/esm/chunks/ConversationStatus.BhdnM1uS.js.map +1 -0
- package/dist/esm/chunks/{FormattedMessage.CrcIzpCM.js → FormattedMessage.D_knqVl-.js} +13 -13
- package/dist/esm/chunks/{FormattedMessage.CrcIzpCM.js.map → FormattedMessage.D_knqVl-.js.map} +1 -1
- package/dist/esm/chunks/{ai-logo.Do__PIO3.js → ai-logo.Bh2bhNcG.js} +7 -6
- package/dist/esm/chunks/ai-logo.Bh2bhNcG.js.map +1 -0
- package/dist/esm/chunks/{combobox.DJCyKFxV.js → combobox.MyoPH18G.js} +4 -4
- package/dist/esm/chunks/{combobox.DJCyKFxV.js.map → combobox.MyoPH18G.js.map} +1 -1
- package/dist/esm/chunks/{data-table.CJOR-1Kf.js → data-table.bjvbLk2u.js} +2 -2
- package/dist/esm/chunks/{data-table.CJOR-1Kf.js.map → data-table.bjvbLk2u.js.map} +1 -1
- package/dist/esm/chunks/{filters.DPv-zTEC.js → filters.BHp3ukNW.js} +3 -3
- package/dist/esm/chunks/{filters.DPv-zTEC.js.map → filters.BHp3ukNW.js.map} +1 -1
- package/dist/esm/chunks/{font-picker.BE03shJT.js → font-picker.YAE99idL.js} +6 -6
- package/dist/esm/chunks/{font-picker.BE03shJT.js.map → font-picker.YAE99idL.js.map} +1 -1
- package/dist/esm/chunks/formatDate.D2xEZm8f.js.map +1 -1
- package/dist/esm/chunks/{header-nav.Bo_GNqXn.js → header-nav.BfblRKoS.js} +6 -6
- package/dist/esm/chunks/{header-nav.Bo_GNqXn.js.map → header-nav.BfblRKoS.js.map} +1 -1
- package/dist/esm/chunks/{header-pane.hQNeFYWQ.js → header-pane.CMHPm65L.js} +2 -2
- package/dist/esm/chunks/{header-pane.hQNeFYWQ.js.map → header-pane.CMHPm65L.js.map} +1 -1
- package/dist/esm/chunks/{sidebar.HOrQaimG.js → sidebar.cdQIaDi5.js} +7 -7
- package/dist/esm/chunks/{sidebar.HOrQaimG.js.map → sidebar.cdQIaDi5.js.map} +1 -1
- package/dist/esm/chunks/{simpleSelect.DK1qZSXM.js → simpleSelect.CEUUfl3O.js} +3 -3
- package/dist/esm/chunks/{simpleSelect.DK1qZSXM.js.map → simpleSelect.CEUUfl3O.js.map} +1 -1
- package/dist/esm/chunks/{two-level-combobox.DQpxBbg3.js → two-level-combobox.DJYP--W9.js} +3 -3
- package/dist/esm/chunks/{two-level-combobox.DQpxBbg3.js.map → two-level-combobox.DJYP--W9.js.map} +1 -1
- package/dist/esm/components/articles-coverage.js +3 -3
- package/dist/esm/components/chart-radial-stacked.js +2 -2
- package/dist/esm/components/chat-search.js +1 -1
- package/dist/esm/components/combobox.js +1 -1
- package/dist/esm/components/conversation.js +1 -1
- package/dist/esm/components/convos.js +1 -1
- package/dist/esm/components/data-table.js +1 -1
- package/dist/esm/components/discoveries-created.js +2 -2
- package/dist/esm/components/filter.js +1 -1
- package/dist/esm/components/font-picker.js +1 -1
- package/dist/esm/components/logo.js +1 -1
- package/dist/esm/components/markdown.js +1 -1
- package/dist/esm/components/metric-card.js +2 -2
- package/dist/esm/components/select.js +1 -1
- package/dist/esm/components/two-level-combobox.js +1 -1
- package/dist/esm/components/ui/combobox.js +1 -1
- package/dist/esm/components/ui/label.js +1 -1
- package/dist/esm/components/ui/popover.js +1 -1
- package/dist/esm/components/ui/separator.js +1 -1
- package/dist/esm/components/ui/spinner.js +2 -2
- package/dist/esm/components/ui/switch.js +2 -2
- package/dist/esm/global.css +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/layouts/full-layout.js +1 -1
- package/dist/esm/layouts/header-nav.js +1 -1
- package/dist/esm/layouts/sidebar.js +1 -1
- package/dist/esm/logos/microsoft-logo.js +2 -2
- package/dist/esm/scenes/knowledge-review.js +8 -8
- package/dist/esm/tailwind.preset.js +1 -1
- package/dist/esm/tailwind.preset.js.map +1 -1
- package/dist/index.d.ts +23 -4
- package/dist/logo.d.ts +8 -1
- package/dist/stats.html +1 -1
- package/package.json +4 -4
- package/tailwind.preset.ts +2 -0
- package/dist/esm/chunks/ChatSearch.BLZiMiJ3.js.map +0 -1
- package/dist/esm/chunks/Conversation.Biqpt5FT.js +0 -29
- package/dist/esm/chunks/Conversation.Biqpt5FT.js.map +0 -1
- package/dist/esm/chunks/ai-logo.Do__PIO3.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sidebar.HOrQaimG.js","sources":["../../../src/layouts/sidebar/context.tsx","../../../src/layouts/sidebar/section-nav/section-nav.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/tree-sync.ts","../../../src/layouts/sidebar/article-nav/article-tree.tsx","../../../src/layouts/sidebar/article-nav/expansion.ts","../../../src/layouts/sidebar/article-nav/article-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';\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-sm 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-dark-200 focus:bg-dark-200 hover:text-accent-foreground focus:text-accent-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';\nimport { ArrowBendUpLeft } from '@phosphor-icons/react';\n\nimport type { SidebarNavItem } from '../types';\nimport { useSidebar } from '../context';\nimport { SectionNav } from '../section-nav';\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 sectionNavItems?: SidebarNavItem[];\n sectionNavActiveId?: string;\n}\n\nexport function AppNav({\n className,\n items,\n activeId,\n showBack,\n onBack,\n sectionNavItems,\n sectionNavActiveId,\n}: 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 <React.Fragment key={item.id}>\n <ItemLinkComponent\n className={cn(\n 'flex p-2 rounded-lg gap-1 text-base text-default items-center',\n item.id === activeId\n ? 'bg-primary text-primary-foreground font-bold hover:text-primary-foreground focus:text-primary-foreground'\n : 'hover:bg-dark-200 focus:bg-dark-200 hover:text-accent-foreground focus:text-accent-foreground',\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 {item.id === activeId && sectionNavItems && sectionNavItems.length > 0 && !collapsed && (\n <SectionNav className={cn('flex-shrink-0')} items={sectionNavItems} activeId={sectionNavActiveId} />\n )}\n </React.Fragment>\n ))}\n </div>\n </ScrollArea>\n </nav>\n );\n}\n","import * as React from 'react';\nimport { MagnifyingGlass, X } from '@phosphor-icons/react';\nimport { useToggle } from 'usehooks-ts';\n\nimport { useSidebar } from '../context';\n\nimport { Input } from '@/components/ui/input';\n\nexport function ArticleSearch() {\n const { handleSearchArticles, searchValue, setSearchValue } = useSidebar();\n const [searchInteracted, , setSearchInteracted] = useToggle(false);\n const searchInputRef = React.useRef<HTMLInputElement>(null);\n\n React.useEffect(() => {\n if (searchInteracted) handleSearchArticles?.(searchValue);\n }, [searchValue, 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) {\n setSearchInteracted(true);\n }\n setSearchValue(value);\n if (value.trim() === '') {\n handleSearchArticles('');\n setSearchInteracted(false);\n }\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';\nimport { useSidebar } from '../context';\n\nimport { cn } from '@/lib/utils';\nimport { Button } from '@/components/ui/button';\nimport { ButtonGroup } from '@/components/ui/button-group';\nimport { Spinner } from '@/components/ui/spinner';\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 isLoadingChildren?: boolean;\n onMoreActions?: (articleId: string) => void;\n}\n\nexport function ArticleItem({\n item,\n hasChildItems,\n isSelected,\n isExpanded,\n ItemLinkComponent,\n onAddArticle,\n isAddingArticle,\n isLoadingChildren,\n onMoreActions,\n level,\n}: ArticleItemProps) {\n const { isSearching } = useSidebar();\n const treeState = React.useContext(TreeStateContext);\n const shouldPreventNavigation = Boolean(isSelected);\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 handleItemClick = (e: React.MouseEvent) => {\n if (shouldPreventNavigation) {\n e.preventDefault();\n e.stopPropagation();\n }\n\n if (hasChildItems && treeState) {\n treeState.toggleKey(item.key);\n }\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 loadingFolderIcon = (\n <span\n className=\"flex size-3 shrink-0 items-center justify-center\"\n role=\"status\"\n aria-label={`Loading nested articles for ${item.value.label}`}\n >\n <Spinner aria-hidden=\"true\" className=\"size-3 text-current\" />\n <span className=\"sr-only\">Loading nested articles for {item.value.label}</span>\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 aria-busy={isLoadingChildren || undefined}\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 : isLoadingChildren ? loadingFolderIcon : 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={handleItemClick}\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 { 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 (\n a.label === b.label &&\n a.href === b.href &&\n a.status === b.status &&\n a.hasChildren === b.hasChildren &&\n a.isLoadingChildren === b.isLoadingChildren\n );\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 renderEmptyState?: () => React.ReactNode;\n}\n\nexport function 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, renderEmptyState }: 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 const prevArticlesRef = React.useRef(articles);\n React.useEffect(() => {\n if (prevArticlesRef.current === articles) return;\n\n prevArticlesRef.current = articles;\n\n const currentArticles = treeNodesToArticleNavItems(articlesTree.items);\n const operations = buildArticleTreeSyncOperations(currentArticles, articles);\n\n if (operations.length === 0) return;\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 = React.useMemo(\n () => (effectiveActiveId != null ? new Set<Key>([effectiveActiveId]) : localSelectedKeys),\n [effectiveActiveId, localSelectedKeys],\n );\n\n const pathToActive = React.useMemo(() => {\n if (!effectiveActiveId || isSearching || !articles.length) return [];\n const path = getParentKeys(articles, effectiveActiveId);\n\n return path ?? [];\n }, [articles, effectiveActiveId, isSearching]);\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) return;\n setLastSelectedArticleId(null);\n }, [activeArticleId, lastSelectedArticleId, 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 const navigateToArticleId = React.useCallback(\n (articleId: string) => {\n onSelectArticle?.(articleId);\n // No URL/store id: keep highlight in sync for Storybook and other uncontrolled hosts.\n if (activeArticleId == null) {\n setLocalSelectedKeys(new Set<Key>([articleId]));\n }\n if (isSearching) {\n setLastSelectedArticleId(articleId);\n setSearchValue('');\n handleSearchArticles?.('');\n }\n },\n [activeArticleId, handleSearchArticles, isSearching, onSelectArticle, setLastSelectedArticleId, setSearchValue],\n );\n\n return (\n <Tree\n aria-label={isSearching ? 'Search results' : 'Articles tree'}\n items={articlesTree.items}\n renderEmptyState={renderEmptyState}\n dragAndDropHooks={isSearching ? undefined : dragAndDropHooks}\n className=\"flex flex-col\"\n // toggle → selectOnFocus off in React Aria, so ArrowUp/Down only move focus; Space updates selection → onSelectionChange.\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 navigateToArticleId(selected.toString());\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 isLoadingChildren={!isSearching && item.value.isLoadingChildren}\n onMoreActions={onMoreActions ? (articleId) => onMoreActions(articleId) : undefined}\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 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 * as React from 'react';\nimport { Article } from '@phosphor-icons/react';\nimport { useDebounceValue } from 'usehooks-ts';\n\nimport { useSidebar } from '../context';\nimport { ArticleNavItem } from '../types';\nimport { ArticleSearch } from './article-search';\nimport { ArticleTree } from './article-tree';\n\nimport { Spinner } from '@/components/ui/spinner';\nimport { cn } from '@/lib/utils';\nimport { Button } from '@/components/ui/button';\nimport { useSubstringFilter } from '@/lib/hooks';\n\n/** Debounce applied to the article tree filter + remount key while searching (avoids work every keystroke). */\nconst ARTICLE_TREE_SEARCH_DEBOUNCE_MS = 400;\n/** Stable ref for useDebounceValue options — inline objects reset debounce each render (usehooks-ts #703). */\nconst ARTICLE_TREE_SEARCH_DEBOUNCE_OPTIONS = { leading: true, trailing: true } as const;\n\nexport interface ArticleNavProps {\n className?: string;\n isLoadingArticles?: boolean;\n articles?: ArticleNavItem[];\n}\n\nexport function ArticleNav({ articles, className, isLoadingArticles }: ArticleNavProps) {\n const { isSearching, searchValue, onAddArticle } = useSidebar();\n const { contains } = useSubstringFilter();\n const trimmedQuery = searchValue.trim();\n const [debouncedTreeQuery] = useDebounceValue(\n isSearching ? trimmedQuery : '',\n isSearching ? ARTICLE_TREE_SEARCH_DEBOUNCE_MS : 0,\n isSearching ? ARTICLE_TREE_SEARCH_DEBOUNCE_OPTIONS : undefined,\n );\n\n const shouldShowLoadingState = !isSearching && (isLoadingArticles ?? articles === undefined);\n const renderLoadingEmptyState = React.useCallback(\n () => (\n <div\n className=\"flex min-h-20 items-center justify-center text-muted-foreground\"\n role=\"status\"\n aria-live=\"polite\"\n aria-label=\"Loading articles list\"\n >\n <Spinner className=\"size-5\" aria-hidden=\"true\" />\n <span className=\"sr-only\">Loading articles list</span>\n </div>\n ),\n [],\n );\n\n const noArticles = !shouldShowLoadingState && !isSearching && (!articles || articles.length === 0);\n\n const filteredArticles = React.useMemo(() => {\n if (isSearching) {\n // `includes('')` is true for every string; avoid showing the full tree with an empty query.\n if (trimmedQuery === '' || debouncedTreeQuery === '') {\n return [];\n }\n const result: ArticleNavItem[] = [];\n const query = debouncedTreeQuery;\n\n const traverse = (nodes: ArticleNavItem[]) => {\n for (const item of nodes) {\n if (contains(item.label, query)) {\n // Strip children so each hit is one row; otherwise the tree would render nested\n // items AND the same nodes again as separate roots (duplicates).\n result.push({ ...item, hasChildren: false, items: [] });\n }\n if (item.items?.length) {\n traverse(item.items);\n }\n }\n };\n\n traverse(articles ?? []);\n\n return result;\n }\n if (articles && articles.length > 0) {\n return articles;\n }\n\n return [];\n }, [articles, isSearching, trimmedQuery, debouncedTreeQuery, contains]);\n\n return (\n <div className={cn('flex flex-col gap-0.5 px-4', className)}>\n {noArticles && (\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 {shouldShowLoadingState ? (\n <ArticleTree isSearching={isSearching} articles={[]} renderEmptyState={renderLoadingEmptyState} />\n ) : (\n <>\n <ArticleSearch />\n <nav aria-label=\"Articles navigation\">\n <ArticleTree\n key={isSearching ? (trimmedQuery === '' ? 'search:empty' : `search:${debouncedTreeQuery}`) : 'browse'}\n isSearching={isSearching}\n articles={filteredArticles ?? []}\n />\n </nav>\n </>\n )}\n </div>\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';\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 isLoadingArticles?: 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 isLoadingArticles,\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 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 sectionNavItems={sectionNavItems}\n sectionNavActiveId={sectionNavActiveId}\n />\n\n {!collapsed && (\n <>\n {showArticles && (\n <ScrollArea>\n <ArticleNav\n className=\"py-4 max-w-[var(--left-nav-width,inherit)]\"\n articles={articles}\n isLoadingArticles={isLoadingArticles}\n />\n </ScrollArea>\n )}\n </>\n )}\n </aside>\n </SidebarProvider>\n );\n});\n"],"names":["SidebarContext","React","createContext","SidebarProvider","collapsed","ItemLinkComponent","activeArticleId","onSelectArticle","onExpandArticle","onSearchArticles","onAddArticle","onMoreActions","canMoveArticle","onMoveArticle","children","isSearching","setIsSearching","useState","searchValue","setSearchValue","lastSelectedArticleId","setLastSelectedArticleId","handleSearchArticles","useCallback","value","trimmedValue","trim","contextValue","useMemo","Provider","useSidebar","sidebarContext","useContext","Error","SectionNav","className","items","activeId","createElement","cn","map","item","key","id","href","label","AppNav","showBack","onBack","sectionNavItems","sectionNavActiveId","hasBack","Button","variant","size","onClick","ArrowBendUpLeft","ScrollArea","Fragment","Icon","weight","length","ArticleSearch","searchInteracted","setSearchInteracted","useToggle","searchInputRef","useRef","useEffect","Input","ref","startIcon","MagnifyingGlass","endIcon","X","onEndIconClick","onChange","e","target","placeholder","type","FolderSlotButton","AriaButton","slot","ArticleItem","hasChildItems","isSelected","isExpanded","isAddingArticle","isLoadingChildren","level","treeState","TreeStateContext","shouldPreventNavigation","Boolean","showActions","isDraft","status","statusLabel","folderIcon","Folder","FolderOpen","folderWithChangesIcon","FolderDashed","discoveryIconContent","Lightning","discoveryIcon","fileIcon","File","fileWithChangesIcon","FileDashed","loadingFolderIcon","role","Spinner","style","Array","from","_","i","hasChanges","renderStatusIcon","title","preventDefault","stopPropagation","toggleKey","ButtonGroup","orientation","DotsThree","Plus","flattenArticles","parentId","depth","result","forEach","index","push","placeholderCounter","getParentKeys","targetId","parents","treeNodesToArticleNavItems","ArticleTree","articles","renderEmptyState","effectiveActiveId","articlesTree","useTreeData","initialItems","getKey","articleItem","getChildren","prevArticlesRef","current","operations","currentArticles","nextArticles","currentEntries","nextEntries","currentMap","Map","entry","nextMap","filter","has","sort","a","b","currentEntry","get","hasChildren","buildArticleTreeSyncOperations","operation","remove","insert","move","update","dragAndDropHooks","useDragAndDrop","getItems","_keys","onMove","movedArticleId","keys","targetItem","getItem","movedToParentId","movedToIndex","dropPosition","toString","parentKey","targetIndex","findIndex","moveDetails","movedItem","originalParentId","originalIndex","moveBefore","moveAfter","then","catch","renderDropIndicator","DropIndicator","localSelectedKeys","setLocalSelectedKeys","Set","selectedKeys","pathToActive","expandedKeysState","setExpandedKeysState","expandedKeys","pendingAddIdsRef","pendingAddIds","setPendingAddIds","handleAddArticle","add","tempId","append","prev","created","delete","navigateToArticleId","articleId","Tree","selectionBehavior","selectionMode","onExpandedChange","nextExpandedKeys","previous","next","previousKeys","getNewlyExpandedKeys","disallowEmptySelection","onSelectionChange","selection","selected","renderItem","TreeItem","textValue","TreeItemContent","props","Collection","ARTICLE_TREE_SEARCH_DEBOUNCE_OPTIONS","leading","trailing","ArticleNav","isLoadingArticles","contains","useSubstringFilter","trimmedQuery","debouncedTreeQuery","useDebounceValue","shouldShowLoadingState","renderLoadingEmptyState","noArticles","filteredArticles","query","traverse","nodes","Article","Sidebar","forwardRef","showAppBack","onAppBack","appNavItems","appNavActiveId","showArticles"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sidebar.cdQIaDi5.js","sources":["../../../src/layouts/sidebar/context.tsx","../../../src/layouts/sidebar/section-nav/section-nav.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/tree-sync.ts","../../../src/layouts/sidebar/article-nav/article-tree.tsx","../../../src/layouts/sidebar/article-nav/expansion.ts","../../../src/layouts/sidebar/article-nav/article-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';\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-sm 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-dark-200 focus:bg-dark-200 hover:text-accent-foreground focus:text-accent-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';\nimport { ArrowBendUpLeft } from '@phosphor-icons/react';\n\nimport type { SidebarNavItem } from '../types';\nimport { useSidebar } from '../context';\nimport { SectionNav } from '../section-nav';\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 sectionNavItems?: SidebarNavItem[];\n sectionNavActiveId?: string;\n}\n\nexport function AppNav({\n className,\n items,\n activeId,\n showBack,\n onBack,\n sectionNavItems,\n sectionNavActiveId,\n}: 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 <React.Fragment key={item.id}>\n <ItemLinkComponent\n className={cn(\n 'flex p-2 rounded-lg gap-1 text-base text-default items-center',\n item.id === activeId\n ? 'bg-primary text-primary-foreground font-bold hover:text-primary-foreground focus:text-primary-foreground'\n : 'hover:bg-dark-200 focus:bg-dark-200 hover:text-accent-foreground focus:text-accent-foreground',\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 {item.id === activeId && sectionNavItems && sectionNavItems.length > 0 && !collapsed && (\n <SectionNav className={cn('flex-shrink-0')} items={sectionNavItems} activeId={sectionNavActiveId} />\n )}\n </React.Fragment>\n ))}\n </div>\n </ScrollArea>\n </nav>\n );\n}\n","import * as React from 'react';\nimport { MagnifyingGlass, X } from '@phosphor-icons/react';\nimport { useToggle } from 'usehooks-ts';\n\nimport { useSidebar } from '../context';\n\nimport { Input } from '@/components/ui/input';\n\nexport function ArticleSearch() {\n const { handleSearchArticles, searchValue, setSearchValue } = useSidebar();\n const [searchInteracted, , setSearchInteracted] = useToggle(false);\n const searchInputRef = React.useRef<HTMLInputElement>(null);\n\n React.useEffect(() => {\n if (searchInteracted) handleSearchArticles?.(searchValue);\n }, [searchValue, 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) {\n setSearchInteracted(true);\n }\n setSearchValue(value);\n if (value.trim() === '') {\n handleSearchArticles('');\n setSearchInteracted(false);\n }\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';\nimport { useSidebar } from '../context';\n\nimport { cn } from '@/lib/utils';\nimport { Button } from '@/components/ui/button';\nimport { ButtonGroup } from '@/components/ui/button-group';\nimport { Spinner } from '@/components/ui/spinner';\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 isLoadingChildren?: boolean;\n onMoreActions?: (articleId: string) => void;\n}\n\nexport function ArticleItem({\n item,\n hasChildItems,\n isSelected,\n isExpanded,\n ItemLinkComponent,\n onAddArticle,\n isAddingArticle,\n isLoadingChildren,\n onMoreActions,\n level,\n}: ArticleItemProps) {\n const { isSearching } = useSidebar();\n const treeState = React.useContext(TreeStateContext);\n const shouldPreventNavigation = Boolean(isSelected);\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 handleItemClick = (e: React.MouseEvent) => {\n if (shouldPreventNavigation) {\n e.preventDefault();\n e.stopPropagation();\n }\n\n if (hasChildItems && treeState) {\n treeState.toggleKey(item.key);\n }\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 loadingFolderIcon = (\n <span\n className=\"flex size-3 shrink-0 items-center justify-center\"\n role=\"status\"\n aria-label={`Loading nested articles for ${item.value.label}`}\n >\n <Spinner aria-hidden=\"true\" className=\"size-3 text-current\" />\n <span className=\"sr-only\">Loading nested articles for {item.value.label}</span>\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 aria-busy={isLoadingChildren || undefined}\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 : isLoadingChildren ? loadingFolderIcon : 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={handleItemClick}\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 { 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 (\n a.label === b.label &&\n a.href === b.href &&\n a.status === b.status &&\n a.hasChildren === b.hasChildren &&\n a.isLoadingChildren === b.isLoadingChildren\n );\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 renderEmptyState?: () => React.ReactNode;\n}\n\nexport function 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, renderEmptyState }: 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 const prevArticlesRef = React.useRef(articles);\n React.useEffect(() => {\n if (prevArticlesRef.current === articles) return;\n\n prevArticlesRef.current = articles;\n\n const currentArticles = treeNodesToArticleNavItems(articlesTree.items);\n const operations = buildArticleTreeSyncOperations(currentArticles, articles);\n\n if (operations.length === 0) return;\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 = React.useMemo(\n () => (effectiveActiveId != null ? new Set<Key>([effectiveActiveId]) : localSelectedKeys),\n [effectiveActiveId, localSelectedKeys],\n );\n\n const pathToActive = React.useMemo(() => {\n if (!effectiveActiveId || isSearching || !articles.length) return [];\n const path = getParentKeys(articles, effectiveActiveId);\n\n return path ?? [];\n }, [articles, effectiveActiveId, isSearching]);\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) return;\n setLastSelectedArticleId(null);\n }, [activeArticleId, lastSelectedArticleId, 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 const navigateToArticleId = React.useCallback(\n (articleId: string) => {\n onSelectArticle?.(articleId);\n // No URL/store id: keep highlight in sync for Storybook and other uncontrolled hosts.\n if (activeArticleId == null) {\n setLocalSelectedKeys(new Set<Key>([articleId]));\n }\n if (isSearching) {\n setLastSelectedArticleId(articleId);\n setSearchValue('');\n handleSearchArticles?.('');\n }\n },\n [activeArticleId, handleSearchArticles, isSearching, onSelectArticle, setLastSelectedArticleId, setSearchValue],\n );\n\n return (\n <Tree\n aria-label={isSearching ? 'Search results' : 'Articles tree'}\n items={articlesTree.items}\n renderEmptyState={renderEmptyState}\n dragAndDropHooks={isSearching ? undefined : dragAndDropHooks}\n className=\"flex flex-col\"\n // toggle → selectOnFocus off in React Aria, so ArrowUp/Down only move focus; Space updates selection → onSelectionChange.\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 navigateToArticleId(selected.toString());\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 isLoadingChildren={!isSearching && item.value.isLoadingChildren}\n onMoreActions={onMoreActions ? (articleId) => onMoreActions(articleId) : undefined}\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 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 * as React from 'react';\nimport { Article } from '@phosphor-icons/react';\nimport { useDebounceValue } from 'usehooks-ts';\n\nimport { useSidebar } from '../context';\nimport { ArticleNavItem } from '../types';\nimport { ArticleSearch } from './article-search';\nimport { ArticleTree } from './article-tree';\n\nimport { Spinner } from '@/components/ui/spinner';\nimport { cn } from '@/lib/utils';\nimport { Button } from '@/components/ui/button';\nimport { useSubstringFilter } from '@/lib/hooks';\n\n/** Debounce applied to the article tree filter + remount key while searching (avoids work every keystroke). */\nconst ARTICLE_TREE_SEARCH_DEBOUNCE_MS = 400;\n/** Stable ref for useDebounceValue options — inline objects reset debounce each render (usehooks-ts #703). */\nconst ARTICLE_TREE_SEARCH_DEBOUNCE_OPTIONS = { leading: true, trailing: true } as const;\n\nexport interface ArticleNavProps {\n className?: string;\n isLoadingArticles?: boolean;\n articles?: ArticleNavItem[];\n}\n\nexport function ArticleNav({ articles, className, isLoadingArticles }: ArticleNavProps) {\n const { isSearching, searchValue, onAddArticle } = useSidebar();\n const { contains } = useSubstringFilter();\n const trimmedQuery = searchValue.trim();\n const [debouncedTreeQuery] = useDebounceValue(\n isSearching ? trimmedQuery : '',\n isSearching ? ARTICLE_TREE_SEARCH_DEBOUNCE_MS : 0,\n isSearching ? ARTICLE_TREE_SEARCH_DEBOUNCE_OPTIONS : undefined,\n );\n\n const shouldShowLoadingState = !isSearching && (isLoadingArticles ?? articles === undefined);\n const renderLoadingEmptyState = React.useCallback(\n () => (\n <div\n className=\"flex min-h-20 items-center justify-center text-muted-foreground\"\n role=\"status\"\n aria-live=\"polite\"\n aria-label=\"Loading articles list\"\n >\n <Spinner className=\"size-5\" aria-hidden=\"true\" />\n <span className=\"sr-only\">Loading articles list</span>\n </div>\n ),\n [],\n );\n\n const noArticles = !shouldShowLoadingState && !isSearching && (!articles || articles.length === 0);\n\n const filteredArticles = React.useMemo(() => {\n if (isSearching) {\n // `includes('')` is true for every string; avoid showing the full tree with an empty query.\n if (trimmedQuery === '' || debouncedTreeQuery === '') {\n return [];\n }\n const result: ArticleNavItem[] = [];\n const query = debouncedTreeQuery;\n\n const traverse = (nodes: ArticleNavItem[]) => {\n for (const item of nodes) {\n if (contains(item.label, query)) {\n // Strip children so each hit is one row; otherwise the tree would render nested\n // items AND the same nodes again as separate roots (duplicates).\n result.push({ ...item, hasChildren: false, items: [] });\n }\n if (item.items?.length) {\n traverse(item.items);\n }\n }\n };\n\n traverse(articles ?? []);\n\n return result;\n }\n if (articles && articles.length > 0) {\n return articles;\n }\n\n return [];\n }, [articles, isSearching, trimmedQuery, debouncedTreeQuery, contains]);\n\n return (\n <div className={cn('flex flex-col gap-0.5 px-4', className)}>\n {noArticles && (\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 {shouldShowLoadingState ? (\n <ArticleTree isSearching={isSearching} articles={[]} renderEmptyState={renderLoadingEmptyState} />\n ) : (\n <>\n <ArticleSearch />\n <nav aria-label=\"Articles navigation\">\n <ArticleTree\n key={isSearching ? (trimmedQuery === '' ? 'search:empty' : `search:${debouncedTreeQuery}`) : 'browse'}\n isSearching={isSearching}\n articles={filteredArticles ?? []}\n />\n </nav>\n </>\n )}\n </div>\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';\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 isLoadingArticles?: 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 isLoadingArticles,\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 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 sectionNavItems={sectionNavItems}\n sectionNavActiveId={sectionNavActiveId}\n />\n\n {!collapsed && (\n <>\n {showArticles && (\n <ScrollArea>\n <ArticleNav\n className=\"py-4 max-w-[var(--left-nav-width,inherit)]\"\n articles={articles}\n isLoadingArticles={isLoadingArticles}\n />\n </ScrollArea>\n )}\n </>\n )}\n </aside>\n </SidebarProvider>\n );\n});\n"],"names":["SidebarContext","React","createContext","SidebarProvider","collapsed","ItemLinkComponent","activeArticleId","onSelectArticle","onExpandArticle","onSearchArticles","onAddArticle","onMoreActions","canMoveArticle","onMoveArticle","children","isSearching","setIsSearching","useState","searchValue","setSearchValue","lastSelectedArticleId","setLastSelectedArticleId","handleSearchArticles","useCallback","value","trimmedValue","trim","contextValue","useMemo","Provider","useSidebar","sidebarContext","useContext","Error","SectionNav","className","items","activeId","createElement","cn","map","item","key","id","href","label","AppNav","showBack","onBack","sectionNavItems","sectionNavActiveId","hasBack","Button","variant","size","onClick","ArrowBendUpLeft","ScrollArea","Fragment","Icon","weight","length","ArticleSearch","searchInteracted","setSearchInteracted","useToggle","searchInputRef","useRef","useEffect","Input","ref","startIcon","MagnifyingGlass","endIcon","X","onEndIconClick","onChange","e","target","placeholder","type","FolderSlotButton","AriaButton","slot","ArticleItem","hasChildItems","isSelected","isExpanded","isAddingArticle","isLoadingChildren","level","treeState","TreeStateContext","shouldPreventNavigation","Boolean","showActions","isDraft","status","statusLabel","folderIcon","Folder","FolderOpen","folderWithChangesIcon","FolderDashed","discoveryIconContent","Lightning","discoveryIcon","fileIcon","File","fileWithChangesIcon","FileDashed","loadingFolderIcon","role","Spinner","style","Array","from","_","i","hasChanges","renderStatusIcon","title","preventDefault","stopPropagation","toggleKey","ButtonGroup","orientation","DotsThree","Plus","flattenArticles","parentId","depth","result","forEach","index","push","placeholderCounter","getParentKeys","targetId","parents","treeNodesToArticleNavItems","ArticleTree","articles","renderEmptyState","effectiveActiveId","articlesTree","useTreeData","initialItems","getKey","articleItem","getChildren","prevArticlesRef","current","operations","currentArticles","nextArticles","currentEntries","nextEntries","currentMap","Map","entry","nextMap","filter","has","sort","a","b","currentEntry","get","hasChildren","buildArticleTreeSyncOperations","operation","remove","insert","move","update","dragAndDropHooks","useDragAndDrop","getItems","_keys","onMove","movedArticleId","keys","targetItem","getItem","movedToParentId","movedToIndex","dropPosition","toString","parentKey","targetIndex","findIndex","moveDetails","movedItem","originalParentId","originalIndex","moveBefore","moveAfter","then","catch","renderDropIndicator","DropIndicator","localSelectedKeys","setLocalSelectedKeys","Set","selectedKeys","pathToActive","expandedKeysState","setExpandedKeysState","expandedKeys","pendingAddIdsRef","pendingAddIds","setPendingAddIds","handleAddArticle","add","tempId","append","prev","created","delete","navigateToArticleId","articleId","Tree","selectionBehavior","selectionMode","onExpandedChange","nextExpandedKeys","previous","next","previousKeys","getNewlyExpandedKeys","disallowEmptySelection","onSelectionChange","selection","selected","renderItem","TreeItem","textValue","TreeItemContent","props","Collection","ARTICLE_TREE_SEARCH_DEBOUNCE_OPTIONS","leading","trailing","ArticleNav","isLoadingArticles","contains","useSubstringFilter","trimmedQuery","debouncedTreeQuery","useDebounceValue","shouldShowLoadingState","renderLoadingEmptyState","noArticles","filteredArticles","query","traverse","nodes","Article","Sidebar","forwardRef","showAppBack","onAppBack","appNavItems","appNavActiveId","showArticles"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import*as e from"react";import{c as a}from"./utils.C6Qu-kwd.js";import{Select as l,SelectTrigger as t,SelectValue as o,SelectContent as
|
|
2
|
-
return e.createElement(l,{value:m,onValueChange:e=>{s&&s(e)},disabled:u},/* @__PURE__ */e.createElement(t,{className:a("w-full",d)},/* @__PURE__ */e.createElement(o,{placeholder:p})),/* @__PURE__ */e.createElement(
|
|
3
|
-
//# sourceMappingURL=simpleSelect.
|
|
1
|
+
import*as e from"react";import{c as a}from"./utils.C6Qu-kwd.js";import{Select as l,SelectTrigger as t,SelectValue as o,SelectContent as r,SelectItem as n}from"../components/ui/select.js";function c({options:c,value:m,onChange:s,placeholder:p="Select...",disabled:u=!1,className:d,appendToBody:i=!1}){/* @__PURE__ */
|
|
2
|
+
return e.createElement(l,{value:m,onValueChange:e=>{s&&s(e)},disabled:u},/* @__PURE__ */e.createElement(t,{className:a("w-full",d)},/* @__PURE__ */e.createElement(o,{placeholder:p})),/* @__PURE__ */e.createElement(r,{appendToBody:i},c.map(a=>/* @__PURE__ */e.createElement(n,{key:a.value,value:a.value},a.label))))}export{c as S};
|
|
3
|
+
//# sourceMappingURL=simpleSelect.CEUUfl3O.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simpleSelect.
|
|
1
|
+
{"version":3,"file":"simpleSelect.CEUUfl3O.js","sources":["../../../src/components/select/simpleSelect.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { cn } from '@/lib/utils';\nimport {\n Select as SelectComponent,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/select';\n\nexport type SelectOption = {\n label: string;\n value: string;\n};\n\nexport interface SimpleSelectProps {\n options: SelectOption[];\n value?: string;\n onChange?: (value: string) => void;\n placeholder?: string;\n disabled?: boolean;\n className?: string;\n appendToBody?: boolean;\n}\n\nexport function SimpleSelect({\n options,\n value,\n onChange,\n placeholder = 'Select...',\n disabled = false,\n className,\n appendToBody = false,\n}: SimpleSelectProps) {\n const handleValueChange = (newValue: string) => {\n if (onChange) {\n onChange(newValue);\n }\n };\n\n return (\n <SelectComponent value={value} onValueChange={handleValueChange} disabled={disabled}>\n <SelectTrigger className={cn('w-full', className)}>\n <SelectValue placeholder={placeholder} />\n </SelectTrigger>\n <SelectContent appendToBody={appendToBody}>\n {options.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </SelectComponent>\n );\n}\n"],"names":["SimpleSelect","options","value","onChange","placeholder","disabled","className","appendToBody","SelectComponent","onValueChange","newValue","React","createElement","SelectTrigger","cn","SelectValue","SelectContent","map","option","SelectItem","key","label"],"mappings":"2LA0BO,SAASA,GAAaC,QAC3BA,EAAAC,MACAA,EAAAC,SACAA,EAAAC,YACAA,EAAc,YAAAC,SACdA,GAAW,EAAAC,UACXA,EAAAC,aACAA,GAAe;AAQf,uBACGC,EAAA,CAAgBN,QAAcO,cAPNC,IACrBP,GACFA,EAASO,IAKsDL,2BAC/DM,EAAAC,cAACC,EAAA,CAAcP,UAAWQ,EAAG,SAAUR,mBACrCK,EAAAC,cAACG,EAAA,CAAYX,gCAEfO,EAAAC,cAACI,EAAA,CAAcT,gBACZN,EAAQgB,IAAKC,kCACXC,EAAA,CAAWC,IAAKF,EAAOhB,MAAOA,MAAOgB,EAAOhB,OAC1CgB,EAAOG,SAMpB"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import*as e from"react";import{X as t,CaretUpDown as a,ArrowLeft as l,Spinner as s,Check as n}from"@phosphor-icons/react";import{c as m}from"./utils.C6Qu-kwd.js";import{B as c}from"./button.D_2SonNs.js";import{Command as r,CommandInput as i,CommandList as o,CommandEmpty as u,CommandGroup as d,CommandItem as p}from"../components/ui/command.js";import{Popover as f,PopoverTrigger as E,PopoverContent as v}from"../components/ui/popover.js";import{DivButton as N}from"../components/ui/div-button.js";function b({firstLevelItems:b,fetchSecondLevelItems:g,onSelectionChange:x,firstLevelLabel:h="First Level",secondLevelLabel:y="Second Level",firstLevelPlaceholder:S="Select first level...",className:L,debugMode:w=!1,displayLabel:C=!0}){const[z,k]=e.useState(!1),[$,j]=e.useState("first"),[I,P]=e.useState(null),[V,
|
|
1
|
+
import*as e from"react";import{X as t,CaretUpDown as a,ArrowLeft as l,Spinner as s,Check as n}from"@phosphor-icons/react";import{c as m}from"./utils.C6Qu-kwd.js";import{B as c}from"./button.D_2SonNs.js";import{Command as r,CommandInput as i,CommandList as o,CommandEmpty as u,CommandGroup as d,CommandItem as p}from"../components/ui/command.js";import{Popover as f,PopoverTrigger as E,PopoverContent as v}from"../components/ui/popover.js";import{DivButton as N}from"../components/ui/div-button.js";function b({firstLevelItems:b,fetchSecondLevelItems:g,onSelectionChange:x,firstLevelLabel:h="First Level",secondLevelLabel:y="Second Level",firstLevelPlaceholder:S="Select first level...",className:L,debugMode:w=!1,displayLabel:C=!0}){const[z,k]=e.useState(!1),[$,j]=e.useState("first"),[I,P]=e.useState(null),[V,B]=e.useState(null),[F,M]=e.useState([]),[O,T]=e.useState(!1),[q,A]=e.useState(""),D=e=>{e.stopPropagation(),P(null),B(null),M([]),j("first"),x?.(null,null)};/* @__PURE__ */
|
|
2
2
|
return e.createElement("div",{className:m("space-y-4",L)},/* @__PURE__ */e.createElement("div",{className:"space-y-2"},C&&/* @__PURE__ */e.createElement("label",{className:"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"},V?`${h} & ${y}`:I?`Select ${y}`:`Select ${h}`),/* @__PURE__ */e.createElement(f,{open:z,onOpenChange:e=>{k(e),e&&!I?j("first"):e&&I&&j("second")}},/* @__PURE__ */e.createElement(E,{asChild:!0},/* @__PURE__ */e.createElement(c,{variant:"outline",role:"combobox","aria-expanded":z,className:"w-full justify-between bg-transparent"},
|
|
3
3
|
/* @__PURE__ */e.createElement("div",{className:"flex items-center gap-2 flex-1 min-w-0"},V?/* @__PURE__ */e.createElement("div",{className:"truncate flex items-center gap-1"},I.label," → ",V.label):I?/* @__PURE__ */e.createElement("div",{className:"truncate flex items-center"},I.label):/* @__PURE__ */e.createElement("span",{className:"truncate"},S)),
|
|
4
4
|
/* @__PURE__ */e.createElement("div",{className:"flex items-center gap-1 shrink-0"},(I||V)&&
|
|
5
5
|
/* @__PURE__ */e.createElement(N,{variant:"ghost",size:"sm",className:"size-6 p-0 hover:bg-muted rounded-sm",onClick:D,"aria-label":"Clear selection"},
|
|
6
6
|
/* @__PURE__ */e.createElement(t,{className:"size-3"})),/* @__PURE__ */e.createElement(a,{className:"size-4 shrink-0 opacity-50"})))),/* @__PURE__ */e.createElement(v,{className:"w-full p-0",align:"start"},/* @__PURE__ */e.createElement(r,null,"second"===$&&I&&/* @__PURE__ */e.createElement("div",{className:"flex items-center gap-2 p-2 border-b"},/* @__PURE__ */e.createElement(c,{variant:"ghost",size:"sm",onClick:()=>{j("first"),A("")},className:"h-8 w-8 p-0 shrink-0"},/* @__PURE__ */e.createElement(l,{className:"size-4"})),/* @__PURE__ */e.createElement("div",{className:"text-sm font-medium truncate flex-1 min-w-0 flex items-center"},I.label),/* @__PURE__ */e.createElement(N,{variant:"ghost",size:"sm",className:"size-6 p-0 ml-auto hover:bg-muted rounded-sm shrink-0",onClick:D,"aria-label":"Clear selection"},
|
|
7
|
-
/* @__PURE__ */e.createElement(t,{className:"size-3"})),
|
|
8
|
-
//# sourceMappingURL=two-level-combobox.
|
|
7
|
+
/* @__PURE__ */e.createElement(t,{className:"size-3"})),O&&/* @__PURE__ */e.createElement(s,{className:"size-4 animate-spin text-muted-foreground shrink-0"})),/* @__PURE__ */e.createElement(i,{value:q,onValueChange:A,placeholder:"first"===$?`Search ${h.toLowerCase()}...`:`Search ${y.toLowerCase()}...`}),/* @__PURE__ */e.createElement(o,null,/* @__PURE__ */e.createElement(u,null,"first"===$?`No ${h.toLowerCase()} found.`:`No ${y.toLowerCase()} found.`),"first"===$&&/* @__PURE__ */e.createElement(d,null,b.map(t=>/* @__PURE__ */e.createElement(p,{key:t.value,value:t.label,onSelect:()=>(async e=>{P(e),B(null),T(!0),j("second"),A("");try{const t=await g(e.value);M(t)}catch(t){console.warn(t),M([])}finally{T(!1)}x?.(e,null)})(t)},/* @__PURE__ */e.createElement("span",{className:"flex items-center gap-2"},t.icon,t.label),/* @__PURE__ */e.createElement(n,{className:m("ml-2 size-4",I?.value===t.value?"opacity-100":"opacity-0")})))),"second"===$&&I&&/* @__PURE__ */e.createElement(d,null,O?/* @__PURE__ */e.createElement("div",{className:"flex items-center justify-center py-6"},/* @__PURE__ */e.createElement(s,{className:"size-4 animate-spin text-muted-foreground mr-2"}),/* @__PURE__ */e.createElement("span",{className:"text-sm text-muted-foreground"},"Loading ",y.toLowerCase(),"...")):F.map(t=>/* @__PURE__ */e.createElement(p,{key:t.value,value:t.label,onSelect:()=>(e=>{B(e),k(!1),x?.(I,e)})(t)},/* @__PURE__ */e.createElement("span",{className:"flex items-center gap-2"},t.icon,t.label),/* @__PURE__ */e.createElement(n,{className:m("ml-2 size-4",V?.value===t.value?"opacity-100":"opacity-0")}))))))))),(I||V)&&w&&/* @__PURE__ */e.createElement("div",{className:"mt-6 p-4 bg-muted/50 rounded-lg space-y-2"},/* @__PURE__ */e.createElement("h3",{className:"font-medium text-sm"},"Selected Values:"),I&&/* @__PURE__ */e.createElement("div",{className:"text-sm text-muted-foreground flex items-center gap-1"},/* @__PURE__ */e.createElement("span",{className:"font-medium"},h,":"),/* @__PURE__ */e.createElement("div",{className:"flex items-center"},I.label)),V&&/* @__PURE__ */e.createElement("div",{className:"text-sm text-muted-foreground flex items-center gap-1"},/* @__PURE__ */e.createElement("span",{className:"font-medium"},y,":"),/* @__PURE__ */e.createElement("div",{className:"flex items-center"},V.label))))}export{b as T};
|
|
8
|
+
//# sourceMappingURL=two-level-combobox.DJYP--W9.js.map
|
package/dist/esm/chunks/{two-level-combobox.DQpxBbg3.js.map → two-level-combobox.DJYP--W9.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"two-level-combobox.DQpxBbg3.js","sources":["../../../src/components/two-level-combobox/two-level-combobox.tsx"],"sourcesContent":["import * as React from 'react';\nimport { Check, CaretUpDown, Spinner, ArrowLeft, X } from '@phosphor-icons/react';\n\nimport { ComboboxItem } from '../combobox';\n\nimport { cn } from '@/lib/utils';\nimport { Button } from '@/components/ui/button';\nimport { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\nimport { DivButton } from '@/components/ui/div-button';\nexport interface TwoLevelComboboxProps {\n firstLevelItems: ComboboxItem[];\n fetchSecondLevelItems: (firstLevelId: string) => Promise<ComboboxItem[]>;\n onSelectionChange?: (firstLevel: ComboboxItem | null, secondLevel: ComboboxItem | null) => void;\n firstLevelLabel?: string;\n secondLevelLabel?: string;\n firstLevelPlaceholder?: string;\n secondLevelPlaceholder?: string;\n className?: string;\n debugMode?: boolean;\n displayLabel?: boolean;\n}\n\nexport function TwoLevelCombobox({\n firstLevelItems,\n fetchSecondLevelItems,\n onSelectionChange,\n firstLevelLabel = 'First Level',\n secondLevelLabel = 'Second Level',\n firstLevelPlaceholder = 'Select first level...',\n className,\n debugMode = false,\n displayLabel = true,\n}: TwoLevelComboboxProps) {\n const [open, setOpen] = React.useState(false);\n const [view, setView] = React.useState<'first' | 'second'>('first');\n const [selectedFirstLevel, setSelectedFirstLevel] = React.useState<ComboboxItem | null>(null);\n const [selectedSecondLevel, setSelectedSecondLevel] = React.useState<ComboboxItem | null>(null);\n const [secondLevelItems, setSecondLevelItems] = React.useState<ComboboxItem[]>([]);\n const [isLoadingSecondLevel, setIsLoadingSecondLevel] = React.useState(false);\n const [searchValue, setSearchValue] = React.useState('');\n\n const handleFirstLevelSelect = async (item: ComboboxItem) => {\n setSelectedFirstLevel(item);\n setSelectedSecondLevel(null); // Reset second level when first level changes\n setIsLoadingSecondLevel(true);\n setView('second');\n setSearchValue(''); // Clear search input when switching to second level\n\n try {\n const fetchedItems = await fetchSecondLevelItems(item.value);\n setSecondLevelItems(fetchedItems);\n } catch (error) {\n console.warn(error);\n setSecondLevelItems([]);\n } finally {\n setIsLoadingSecondLevel(false);\n }\n\n onSelectionChange?.(item, null);\n };\n\n const handleSecondLevelSelect = (item: ComboboxItem) => {\n setSelectedSecondLevel(item);\n setOpen(false);\n onSelectionChange?.(selectedFirstLevel, item);\n };\n\n const handleBackToFirstLevel = () => {\n setView('first');\n setSearchValue(''); // Clear search input when going back to first level\n };\n\n const handleOpenChange = (isOpen: boolean) => {\n setOpen(isOpen);\n if (isOpen && !selectedFirstLevel) {\n setView('first');\n } else if (isOpen && selectedFirstLevel) {\n setView('second');\n }\n };\n\n const handleClearSelection = (e: React.MouseEvent) => {\n e.stopPropagation(); // Prevent opening the popover\n setSelectedFirstLevel(null);\n setSelectedSecondLevel(null);\n setSecondLevelItems([]);\n setView('first');\n onSelectionChange?.(null, null);\n };\n\n const getLabel = () => {\n if (selectedSecondLevel) return `${firstLevelLabel} & ${secondLevelLabel}`;\n if (selectedFirstLevel) return `Select ${secondLevelLabel}`;\n\n return `Select ${firstLevelLabel}`;\n };\n\n return (\n <div className={cn('space-y-4', className)}>\n <div className=\"space-y-2\">\n {displayLabel && (\n <label className=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\">\n {getLabel()}\n </label>\n )}\n <Popover open={open} onOpenChange={handleOpenChange}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n role=\"combobox\"\n aria-expanded={open}\n className=\"w-full justify-between bg-transparent\"\n >\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n {selectedSecondLevel ? (\n <div className=\"truncate flex items-center gap-1\">\n {selectedFirstLevel!.label} → {selectedSecondLevel.label}\n </div>\n ) : selectedFirstLevel ? (\n <div className=\"truncate flex items-center\">{selectedFirstLevel.label}</div>\n ) : (\n <span className=\"truncate\">{firstLevelPlaceholder}</span>\n )}\n </div>\n <div className=\"flex items-center gap-1 shrink-0\">\n {(selectedFirstLevel || selectedSecondLevel) && (\n // Render button as div to prevent button within button error\n <DivButton\n variant=\"ghost\"\n size=\"sm\"\n className=\"size-6 p-0 hover:bg-muted rounded-sm\"\n onClick={handleClearSelection}\n aria-label=\"Clear selection\"\n >\n <X className=\"size-3\" />\n </DivButton>\n )}\n <CaretUpDown className=\"size-4 shrink-0 opacity-50\" />\n </div>\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-full p-0\" align=\"start\">\n <Command>\n {view === 'second' && selectedFirstLevel && (\n <div className=\"flex items-center gap-2 p-2 border-b\">\n <Button variant=\"ghost\" size=\"sm\" onClick={handleBackToFirstLevel} className=\"h-8 w-8 p-0 shrink-0\">\n <ArrowLeft className=\"size-4\" />\n </Button>\n <div className=\"text-sm font-medium truncate flex-1 min-w-0 flex items-center\">\n {selectedFirstLevel.label}\n </div>\n {/* Render button as div to prevent button within button error */}\n <DivButton\n variant=\"ghost\"\n size=\"sm\"\n className=\"size-6 p-0 ml-auto hover:bg-muted rounded-sm shrink-0\"\n onClick={handleClearSelection}\n aria-label=\"Clear selection\"\n >\n <X className=\"size-3\" />\n </DivButton>\n {isLoadingSecondLevel && <Spinner className=\"size-4 animate-spin text-muted-foreground shrink-0\" />}\n </div>\n )}\n\n <CommandInput\n value={searchValue}\n onValueChange={setSearchValue}\n placeholder={\n view === 'first'\n ? `Search ${firstLevelLabel.toLowerCase()}...`\n : `Search ${secondLevelLabel.toLowerCase()}...`\n }\n />\n <CommandList>\n <CommandEmpty>\n {view === 'first'\n ? `No ${firstLevelLabel.toLowerCase()} found.`\n : `No ${secondLevelLabel.toLowerCase()} found.`}\n </CommandEmpty>\n\n {view === 'first' && (\n <CommandGroup>\n {firstLevelItems.map((item) => (\n <CommandItem key={item.value} value={item.label} onSelect={() => handleFirstLevelSelect(item)}>\n <span className=\"flex items-center gap-2\">\n {item.icon}\n {item.label}\n </span>\n <Check\n className={cn(\n 'ml-2 size-4',\n selectedFirstLevel?.value === item.value ? 'opacity-100' : 'opacity-0',\n )}\n />\n </CommandItem>\n ))}\n </CommandGroup>\n )}\n\n {view === 'second' && selectedFirstLevel && (\n <CommandGroup>\n {isLoadingSecondLevel ? (\n <div className=\"flex items-center justify-center py-6\">\n <Spinner className=\"size-4 animate-spin text-muted-foreground mr-2\" />\n <span className=\"text-sm text-muted-foreground\">\n Loading {secondLevelLabel.toLowerCase()}...\n </span>\n </div>\n ) : (\n secondLevelItems.map((item) => (\n <CommandItem key={item.value} value={item.label} onSelect={() => handleSecondLevelSelect(item)}>\n <span className=\"flex items-center gap-2\">\n {item.icon}\n {item.label}\n </span>\n <Check\n className={cn(\n 'ml-2 size-4',\n selectedSecondLevel?.value === item.value ? 'opacity-100' : 'opacity-0',\n )}\n />\n </CommandItem>\n ))\n )}\n </CommandGroup>\n )}\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n </div>\n\n {(selectedFirstLevel || selectedSecondLevel) && debugMode && (\n <div className=\"mt-6 p-4 bg-muted/50 rounded-lg space-y-2\">\n <h3 className=\"font-medium text-sm\">Selected Values:</h3>\n {selectedFirstLevel && (\n <div className=\"text-sm text-muted-foreground flex items-center gap-1\">\n <span className=\"font-medium\">{firstLevelLabel}:</span>\n <div className=\"flex items-center\">{selectedFirstLevel.label}</div>\n </div>\n )}\n {selectedSecondLevel && (\n <div className=\"text-sm text-muted-foreground flex items-center gap-1\">\n <span className=\"font-medium\">{secondLevelLabel}:</span>\n <div className=\"flex items-center\">{selectedSecondLevel.label}</div>\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n"],"names":["TwoLevelCombobox","firstLevelItems","fetchSecondLevelItems","onSelectionChange","firstLevelLabel","secondLevelLabel","firstLevelPlaceholder","className","debugMode","displayLabel","open","setOpen","React","useState","view","setView","selectedFirstLevel","setSelectedFirstLevel","selectedSecondLevel","setSelectedSecondLevel","secondLevelItems","setSecondLevelItems","isLoadingSecondLevel","setIsLoadingSecondLevel","searchValue","setSearchValue","handleClearSelection","e","stopPropagation","createElement","cn","Popover","onOpenChange","isOpen","PopoverTrigger","asChild","Button","variant","role","label","DivButton","size","onClick","X","CaretUpDown","PopoverContent","align","Command","ArrowLeft","Spinner","CommandInput","value","onValueChange","placeholder","toLowerCase","CommandList","CommandEmpty","CommandGroup","map","item","CommandItem","key","onSelect","async","fetchedItems","error","console","warn","handleFirstLevelSelect","icon","Check","handleSecondLevelSelect"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"two-level-combobox.DJYP--W9.js","sources":["../../../src/components/two-level-combobox/two-level-combobox.tsx"],"sourcesContent":["import * as React from 'react';\nimport { Check, CaretUpDown, Spinner, ArrowLeft, X } from '@phosphor-icons/react';\n\nimport { ComboboxItem } from '../combobox';\n\nimport { cn } from '@/lib/utils';\nimport { Button } from '@/components/ui/button';\nimport { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\nimport { DivButton } from '@/components/ui/div-button';\nexport interface TwoLevelComboboxProps {\n firstLevelItems: ComboboxItem[];\n fetchSecondLevelItems: (firstLevelId: string) => Promise<ComboboxItem[]>;\n onSelectionChange?: (firstLevel: ComboboxItem | null, secondLevel: ComboboxItem | null) => void;\n firstLevelLabel?: string;\n secondLevelLabel?: string;\n firstLevelPlaceholder?: string;\n secondLevelPlaceholder?: string;\n className?: string;\n debugMode?: boolean;\n displayLabel?: boolean;\n}\n\nexport function TwoLevelCombobox({\n firstLevelItems,\n fetchSecondLevelItems,\n onSelectionChange,\n firstLevelLabel = 'First Level',\n secondLevelLabel = 'Second Level',\n firstLevelPlaceholder = 'Select first level...',\n className,\n debugMode = false,\n displayLabel = true,\n}: TwoLevelComboboxProps) {\n const [open, setOpen] = React.useState(false);\n const [view, setView] = React.useState<'first' | 'second'>('first');\n const [selectedFirstLevel, setSelectedFirstLevel] = React.useState<ComboboxItem | null>(null);\n const [selectedSecondLevel, setSelectedSecondLevel] = React.useState<ComboboxItem | null>(null);\n const [secondLevelItems, setSecondLevelItems] = React.useState<ComboboxItem[]>([]);\n const [isLoadingSecondLevel, setIsLoadingSecondLevel] = React.useState(false);\n const [searchValue, setSearchValue] = React.useState('');\n\n const handleFirstLevelSelect = async (item: ComboboxItem) => {\n setSelectedFirstLevel(item);\n setSelectedSecondLevel(null); // Reset second level when first level changes\n setIsLoadingSecondLevel(true);\n setView('second');\n setSearchValue(''); // Clear search input when switching to second level\n\n try {\n const fetchedItems = await fetchSecondLevelItems(item.value);\n setSecondLevelItems(fetchedItems);\n } catch (error) {\n console.warn(error);\n setSecondLevelItems([]);\n } finally {\n setIsLoadingSecondLevel(false);\n }\n\n onSelectionChange?.(item, null);\n };\n\n const handleSecondLevelSelect = (item: ComboboxItem) => {\n setSelectedSecondLevel(item);\n setOpen(false);\n onSelectionChange?.(selectedFirstLevel, item);\n };\n\n const handleBackToFirstLevel = () => {\n setView('first');\n setSearchValue(''); // Clear search input when going back to first level\n };\n\n const handleOpenChange = (isOpen: boolean) => {\n setOpen(isOpen);\n if (isOpen && !selectedFirstLevel) {\n setView('first');\n } else if (isOpen && selectedFirstLevel) {\n setView('second');\n }\n };\n\n const handleClearSelection = (e: React.MouseEvent) => {\n e.stopPropagation(); // Prevent opening the popover\n setSelectedFirstLevel(null);\n setSelectedSecondLevel(null);\n setSecondLevelItems([]);\n setView('first');\n onSelectionChange?.(null, null);\n };\n\n const getLabel = () => {\n if (selectedSecondLevel) return `${firstLevelLabel} & ${secondLevelLabel}`;\n if (selectedFirstLevel) return `Select ${secondLevelLabel}`;\n\n return `Select ${firstLevelLabel}`;\n };\n\n return (\n <div className={cn('space-y-4', className)}>\n <div className=\"space-y-2\">\n {displayLabel && (\n <label className=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\">\n {getLabel()}\n </label>\n )}\n <Popover open={open} onOpenChange={handleOpenChange}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n role=\"combobox\"\n aria-expanded={open}\n className=\"w-full justify-between bg-transparent\"\n >\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n {selectedSecondLevel ? (\n <div className=\"truncate flex items-center gap-1\">\n {selectedFirstLevel!.label} → {selectedSecondLevel.label}\n </div>\n ) : selectedFirstLevel ? (\n <div className=\"truncate flex items-center\">{selectedFirstLevel.label}</div>\n ) : (\n <span className=\"truncate\">{firstLevelPlaceholder}</span>\n )}\n </div>\n <div className=\"flex items-center gap-1 shrink-0\">\n {(selectedFirstLevel || selectedSecondLevel) && (\n // Render button as div to prevent button within button error\n <DivButton\n variant=\"ghost\"\n size=\"sm\"\n className=\"size-6 p-0 hover:bg-muted rounded-sm\"\n onClick={handleClearSelection}\n aria-label=\"Clear selection\"\n >\n <X className=\"size-3\" />\n </DivButton>\n )}\n <CaretUpDown className=\"size-4 shrink-0 opacity-50\" />\n </div>\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-full p-0\" align=\"start\">\n <Command>\n {view === 'second' && selectedFirstLevel && (\n <div className=\"flex items-center gap-2 p-2 border-b\">\n <Button variant=\"ghost\" size=\"sm\" onClick={handleBackToFirstLevel} className=\"h-8 w-8 p-0 shrink-0\">\n <ArrowLeft className=\"size-4\" />\n </Button>\n <div className=\"text-sm font-medium truncate flex-1 min-w-0 flex items-center\">\n {selectedFirstLevel.label}\n </div>\n {/* Render button as div to prevent button within button error */}\n <DivButton\n variant=\"ghost\"\n size=\"sm\"\n className=\"size-6 p-0 ml-auto hover:bg-muted rounded-sm shrink-0\"\n onClick={handleClearSelection}\n aria-label=\"Clear selection\"\n >\n <X className=\"size-3\" />\n </DivButton>\n {isLoadingSecondLevel && <Spinner className=\"size-4 animate-spin text-muted-foreground shrink-0\" />}\n </div>\n )}\n\n <CommandInput\n value={searchValue}\n onValueChange={setSearchValue}\n placeholder={\n view === 'first'\n ? `Search ${firstLevelLabel.toLowerCase()}...`\n : `Search ${secondLevelLabel.toLowerCase()}...`\n }\n />\n <CommandList>\n <CommandEmpty>\n {view === 'first'\n ? `No ${firstLevelLabel.toLowerCase()} found.`\n : `No ${secondLevelLabel.toLowerCase()} found.`}\n </CommandEmpty>\n\n {view === 'first' && (\n <CommandGroup>\n {firstLevelItems.map((item) => (\n <CommandItem key={item.value} value={item.label} onSelect={() => handleFirstLevelSelect(item)}>\n <span className=\"flex items-center gap-2\">\n {item.icon}\n {item.label}\n </span>\n <Check\n className={cn(\n 'ml-2 size-4',\n selectedFirstLevel?.value === item.value ? 'opacity-100' : 'opacity-0',\n )}\n />\n </CommandItem>\n ))}\n </CommandGroup>\n )}\n\n {view === 'second' && selectedFirstLevel && (\n <CommandGroup>\n {isLoadingSecondLevel ? (\n <div className=\"flex items-center justify-center py-6\">\n <Spinner className=\"size-4 animate-spin text-muted-foreground mr-2\" />\n <span className=\"text-sm text-muted-foreground\">\n Loading {secondLevelLabel.toLowerCase()}...\n </span>\n </div>\n ) : (\n secondLevelItems.map((item) => (\n <CommandItem key={item.value} value={item.label} onSelect={() => handleSecondLevelSelect(item)}>\n <span className=\"flex items-center gap-2\">\n {item.icon}\n {item.label}\n </span>\n <Check\n className={cn(\n 'ml-2 size-4',\n selectedSecondLevel?.value === item.value ? 'opacity-100' : 'opacity-0',\n )}\n />\n </CommandItem>\n ))\n )}\n </CommandGroup>\n )}\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n </div>\n\n {(selectedFirstLevel || selectedSecondLevel) && debugMode && (\n <div className=\"mt-6 p-4 bg-muted/50 rounded-lg space-y-2\">\n <h3 className=\"font-medium text-sm\">Selected Values:</h3>\n {selectedFirstLevel && (\n <div className=\"text-sm text-muted-foreground flex items-center gap-1\">\n <span className=\"font-medium\">{firstLevelLabel}:</span>\n <div className=\"flex items-center\">{selectedFirstLevel.label}</div>\n </div>\n )}\n {selectedSecondLevel && (\n <div className=\"text-sm text-muted-foreground flex items-center gap-1\">\n <span className=\"font-medium\">{secondLevelLabel}:</span>\n <div className=\"flex items-center\">{selectedSecondLevel.label}</div>\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n"],"names":["TwoLevelCombobox","firstLevelItems","fetchSecondLevelItems","onSelectionChange","firstLevelLabel","secondLevelLabel","firstLevelPlaceholder","className","debugMode","displayLabel","open","setOpen","React","useState","view","setView","selectedFirstLevel","setSelectedFirstLevel","selectedSecondLevel","setSelectedSecondLevel","secondLevelItems","setSecondLevelItems","isLoadingSecondLevel","setIsLoadingSecondLevel","searchValue","setSearchValue","handleClearSelection","e","stopPropagation","createElement","cn","Popover","onOpenChange","isOpen","PopoverTrigger","asChild","Button","variant","role","label","DivButton","size","onClick","X","CaretUpDown","PopoverContent","align","Command","ArrowLeft","Spinner","CommandInput","value","onValueChange","placeholder","toLowerCase","CommandList","CommandEmpty","CommandGroup","map","item","CommandItem","key","onSelect","async","fetchedItems","error","console","warn","handleFirstLevelSelect","icon","Check","handleSecondLevelSelect"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import e from"react";import{LineChart as t,CartesianGrid as a,XAxis as r,Line as l,PieChart as n,Pie as o,Label as c}from"recharts";import{a as s}from"../chunks/trend-value.BPBDBsk2.js";import{Card as m,CardHeader as i,CardContent as d}from"./ui/card.js";import{C as u,a as f,b as v}from"../chunks/chart.BDL2tf-S.js";import{f as p}from"../chunks/formatNumber.DhVn228t.js";import{u as x}from"../chunks/useChartDateFormatters.Dx2h5AAm.js";import{c as k}from"../chunks/utils.C6Qu-kwd.js";const E={covered:{label:"Covered",color:"var(--bfc-v2-color-blue-600, #357DE8)"},uncovered:{label:"Uncovered",color:"var(--bfc-v2-color-mono-300, #E5E5E5)"}};function h({total:h,trend:y,trendValue:g,coveragePercentage:b,data:N,chartConfig:j,locale:w,className:A}){const{tickFormatter:K,formatXLabel:
|
|
1
|
+
import e from"react";import{LineChart as t,CartesianGrid as a,XAxis as r,Line as l,PieChart as n,Pie as o,Label as c}from"recharts";import{a as s}from"../chunks/trend-value.BPBDBsk2.js";import{Card as m,CardHeader as i,CardContent as d}from"./ui/card.js";import{C as u,a as f,b as v}from"../chunks/chart.BDL2tf-S.js";import{f as p}from"../chunks/formatNumber.DhVn228t.js";import{u as x}from"../chunks/useChartDateFormatters.Dx2h5AAm.js";import{c as k}from"../chunks/utils.C6Qu-kwd.js";const E={covered:{label:"Covered",color:"var(--bfc-v2-color-blue-600, #357DE8)"},uncovered:{label:"Uncovered",color:"var(--bfc-v2-color-mono-300, #E5E5E5)"}};function h({total:h,trend:y,trendValue:g,coveragePercentage:b,data:N,chartConfig:j,locale:w,className:A}){const{tickFormatter:K,formatXLabel:B}=x(w),C=Object.keys(j),M=Math.round(Math.min(100,Math.max(0,b)));/* @__PURE__ */
|
|
2
2
|
return e.createElement(m,{className:k("shadow-none border border-dark-300 rounded-lg",A)},/* @__PURE__ */e.createElement(i,{className:"p-0 space-y-0 border-b border-dark-300"},/* @__PURE__ */e.createElement("div",{className:"flex flex-col gap-1 justify-center py-4 px-4"},/* @__PURE__ */e.createElement("p",{className:"uppercase heading-xxxs font-semibold text-dark tracking-normal"},"Articles Generated by Brainfish (coverage)"),/* @__PURE__ */e.createElement("div",{className:"flex items-center gap-2"},/* @__PURE__ */e.createElement("span",{className:"font-mono text-3xl leading-10 text-dark"},p(h,{})),/* @__PURE__ */e.createElement(s,{trend:y,trendValue:g})))),/* @__PURE__ */e.createElement(d,{className:"flex gap-2 p-0"},/* @__PURE__ */e.createElement("div",{className:"flex-1 min-w-0 px-4 pt-4 pb-0"},/* @__PURE__ */e.createElement(u,{config:j,className:"h-48 w-full"},/* @__PURE__ */e.createElement(t,{data:N,margin:{top:8,left:20,right:20,bottom:0}},/* @__PURE__ */e.createElement(a,{horizontal:!0,vertical:!1,className:"stroke-dark-300"}),/* @__PURE__ */e.createElement(r,{dataKey:"date",tickLine:!1,axisLine:!1,tickMargin:8,padding:{left:15,right:15},minTickGap:32,interval:"preserveStartEnd",tickFormatter:K,tick:({x:t,y:a,payload:r,index:l})=>{const n=0===l,o=l===N.length-1,c=n?"start":o?"end":"middle",s=n?t-15:o?t+15:t;/* @__PURE__ */
|
|
3
|
-
return e.createElement("text",{x:s,y:a,dy:12,textAnchor:c,className:"text-xs fill-dark-600"},K(r.value))}}),/* @__PURE__ */e.createElement(f,{cursor:!1,content:({active:t,payload:a,label:r})=>/* @__PURE__ */e.createElement(v,{active:t,payload:a,label:null!=r?
|
|
4
|
-
/* @__PURE__ */e.createElement(c,{content:({viewBox:t})=>t&&"cx"in t&&"cy"in t?/* @__PURE__ */e.createElement("text",{x:t.cx,y:t.cy,textAnchor:"middle",dominantBaseline:"central"},/* @__PURE__ */e.createElement("tspan",{className:"font-mono text-3xl fill-dark-600"},
|
|
3
|
+
return e.createElement("text",{x:s,y:a,dy:12,textAnchor:c,className:"text-xs fill-dark-600"},K(r.value))}}),/* @__PURE__ */e.createElement(f,{cursor:!1,content:({active:t,payload:a,label:r})=>/* @__PURE__ */e.createElement(v,{active:t,payload:a,label:null!=r?B(r):""})}),C.map(t=>/* @__PURE__ */e.createElement(l,{key:t,dataKey:t,type:"monotone",stroke:`var(--color-${t})`,strokeWidth:2,dot:{r:4,fill:"white",strokeWidth:2,stroke:`var(--color-${t})`},activeDot:{r:5,fill:"white",strokeWidth:2,stroke:`var(--color-${t})`}}))))),/* @__PURE__ */e.createElement("div",{className:"w-80 shrink-0 flex items-center justify-center"},/* @__PURE__ */e.createElement(u,{config:E,className:"aspect-square w-full max-w-44"},/* @__PURE__ */e.createElement(n,null,/* @__PURE__ */e.createElement(o,{data:[{value:100,fill:"var(--color-uncovered)"}],dataKey:"value",innerRadius:"76%",outerRadius:"82%",stroke:"none",isAnimationActive:!1}),/* @__PURE__ */e.createElement(o,{data:[{name:"covered",value:M,fill:"var(--color-covered)"},{name:"uncovered",value:100-M,fill:"transparent"}],dataKey:"value",nameKey:"name",innerRadius:"68%",outerRadius:"90%",startAngle:90,endAngle:-270,stroke:"none"},
|
|
4
|
+
/* @__PURE__ */e.createElement(c,{content:({viewBox:t})=>t&&"cx"in t&&"cy"in t?/* @__PURE__ */e.createElement("text",{x:t.cx,y:t.cy,textAnchor:"middle",dominantBaseline:"central"},/* @__PURE__ */e.createElement("tspan",{className:"font-mono text-3xl fill-dark-600"},M,"%")):null})))))))}export{h as ArticlesCoverage};
|
|
5
5
|
//# sourceMappingURL=articles-coverage.js.map
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import e from"react";import{RadialBarChart as t,PolarRadiusAxis as a,Label as r,RadialBar as n}from"recharts";import{a as c}from"../chunks/trend-value.BPBDBsk2.js";import{f as l}from"../chunks/formatNumber.DhVn228t.js";import{Card as s,CardHeader as m,CardTitle as o,CardContent as i}from"./ui/card.js";import{C as u,a as d,b as f}from"../chunks/chart.BDL2tf-S.js";import{c as x}from"../chunks/utils.C6Qu-kwd.js";function p({title:p,data:h,chartConfig:E,trend:
|
|
2
|
-
return e.createElement(s,{className:x("flex flex-col w-full min-w-60 p-4 shadow-none",N)},/* @__PURE__ */e.createElement(m,{className:"p-0 space-y-0","data-name":"header"},/* @__PURE__ */e.createElement(o,{className:"uppercase font-inter heading-xxxs tracking-normal"},p)),/* @__PURE__ */e.createElement(i,{"data-name":"content",className:"p-0 flex-1 min-h-0"},/* @__PURE__ */e.createElement(u,{config:E,className:"mx-auto aspect-[2/1] w-full max-w-52"},/* @__PURE__ */e.createElement(t,{data:h,endAngle:180,innerRadius:80,outerRadius:120,cy:"100%"},/* @__PURE__ */e.createElement(d,{cursor:!1,content:/* @__PURE__ */e.createElement(f,{hideLabel:!0})}),/* @__PURE__ */e.createElement(a,{tick:!1,tickLine:!1,axisLine:!1},/* @__PURE__ */e.createElement(r,{content:({viewBox:t})=>t&&"cx"in t&&"cy"in t?/* @__PURE__ */e.createElement("text",{x:t.cx,y:t.cy,textAnchor:"middle"},/* @__PURE__ */e.createElement("tspan",{x:t.cx,y:(t.cy||0)-16,className:"fill-foreground text-xl font-inter"},
|
|
1
|
+
import e from"react";import{RadialBarChart as t,PolarRadiusAxis as a,Label as r,RadialBar as n}from"recharts";import{a as c}from"../chunks/trend-value.BPBDBsk2.js";import{f as l}from"../chunks/formatNumber.DhVn228t.js";import{Card as s,CardHeader as m,CardTitle as o,CardContent as i}from"./ui/card.js";import{C as u,a as d,b as f}from"../chunks/chart.BDL2tf-S.js";import{c as x}from"../chunks/utils.C6Qu-kwd.js";function p({title:p,data:h,chartConfig:E,trend:k,trendValue:y,className:N}){if(!h||0===h.length)return null;const j=Object.values(h[0]).reduce((e,t)=>"number"==typeof t?e+t:e,0),g=l(j),b=Object.entries(h[0]).sort((e,t)=>t[1]-e[1]);/* @__PURE__ */
|
|
2
|
+
return e.createElement(s,{className:x("flex flex-col w-full min-w-60 p-4 shadow-none",N)},/* @__PURE__ */e.createElement(m,{className:"p-0 space-y-0","data-name":"header"},/* @__PURE__ */e.createElement(o,{className:"uppercase font-inter heading-xxxs tracking-normal"},p)),/* @__PURE__ */e.createElement(i,{"data-name":"content",className:"p-0 flex-1 min-h-0"},/* @__PURE__ */e.createElement(u,{config:E,className:"mx-auto aspect-[2/1] w-full max-w-52"},/* @__PURE__ */e.createElement(t,{data:h,endAngle:180,innerRadius:80,outerRadius:120,cy:"100%"},/* @__PURE__ */e.createElement(d,{cursor:!1,content:/* @__PURE__ */e.createElement(f,{hideLabel:!0})}),/* @__PURE__ */e.createElement(a,{tick:!1,tickLine:!1,axisLine:!1},/* @__PURE__ */e.createElement(r,{content:({viewBox:t})=>t&&"cx"in t&&"cy"in t?/* @__PURE__ */e.createElement("text",{x:t.cx,y:t.cy,textAnchor:"middle"},/* @__PURE__ */e.createElement("tspan",{x:t.cx,y:(t.cy||0)-16,className:"fill-foreground text-xl font-inter"},g)):null})),b.map(([t])=>/* @__PURE__ */e.createElement(n,{key:t,dataKey:t,stackId:"a",cornerRadius:4,fill:E[t]?.color||`var(--color-${t})`,className:"stroke-card stroke-2"})))),k&&y&&/* @__PURE__ */e.createElement(c,{variant:"long",trend:k,trendValue:y,className:"mt-4 justify-center"})))}export{p as ChartRadialStacked};
|
|
3
3
|
//# sourceMappingURL=chart-radial-stacked.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export{C as ChatSearch,a as ChatSearchProvider,R as ResolvedConversationFooter,u as useChatSearch,b as useIsChatSearchDirty}from"../chunks/ChatSearch.
|
|
1
|
+
export{C as ChatSearch,a as ChatSearchProvider,R as ResolvedConversationFooter,u as useChatSearch,b as useIsChatSearchDirty}from"../chunks/ChatSearch.B0vv3DDb.js";
|
|
2
2
|
//# sourceMappingURL=chat-search.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export{C as Combobox}from"../chunks/combobox.
|
|
1
|
+
export{C as Combobox}from"../chunks/combobox.MyoPH18G.js";
|
|
2
2
|
//# sourceMappingURL=combobox.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export{C as ContextPillBadge,a as Conversation,b as ConversationActions,c as ConversationInput,d as ConversationMessageAssistant,e as ConversationMessageUser,f as ConversationMessages,g as ConversationProvider,h as
|
|
1
|
+
export{C as ContextPillBadge,a as Conversation,b as ConversationActions,c as ConversationInput,d as ConversationMessageAssistant,e as ConversationMessageUser,f as ConversationMessages,g as ConversationProvider,h as ConversationSuggestions,u as useConversation}from"../chunks/Conversation.UzfPizn5.js";export{C as ConversationStatus}from"../chunks/ConversationStatus.BhdnM1uS.js";
|
|
2
2
|
//# sourceMappingURL=conversation.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import e,{useState as t,useEffect as a,useRef as s}from"react";import{S as r}from"../chunks/status-badge.Cf3R4nVr.js";import{ArrowSquareOut as n,CheckCircle as l,XCircle as c,ListMagnifyingGlass as i,UserCircle as m,Eye as o,UserFocus as d,Circle as u}from"@phosphor-icons/react";import{F as p}from"../chunks/FormattedMessage.
|
|
1
|
+
import e,{useState as t,useEffect as a,useRef as s}from"react";import{S as r}from"../chunks/status-badge.Cf3R4nVr.js";import{ArrowSquareOut as n,CheckCircle as l,XCircle as c,ListMagnifyingGlass as i,UserCircle as m,Eye as o,UserFocus as d,Circle as u}from"@phosphor-icons/react";import{F as p}from"../chunks/FormattedMessage.D_knqVl-.js";import{Spinner as f}from"./ui/spinner.js";import{B as E}from"../chunks/button.D_2SonNs.js";import{useForm as g,Controller as h}from"react-hook-form";import{Select as v,SelectTrigger as N,SelectValue as x,SelectContent as b,SelectItem as w}from"./ui/select.js";import{Label as y}from"./ui/label.js";import{Textarea as k}from"./ui/textarea.js";import{Tooltip as C,TooltipTrigger as j,TooltipContent as A}from"./ui/tooltip.js";import{c as _}from"../chunks/utils.C6Qu-kwd.js";import{DivButton as O}from"./ui/div-button.js";import{ScrollArea as S}from"./ui/scroll-area.js";import{Sheet as z,SheetTrigger as D,SheetContent as F,SheetHeader as R,SheetTitle as M,SheetDescription as I}from"./ui/sheet.js";import{Badge as q}from"./ui/badge.js";import{G as P}from"../chunks/generating-star.BN9p_FDu.js";import{Item as T,ItemHeader as B,ItemTitle as L,ItemContent as U,ItemDescription as G}from"./ui/item.js";import{Accordion as K,AccordionItem as W,AccordionTrigger as H,AccordionContent as V}from"./ui/accordion.js";import{c as J,b as Q}from"../chunks/formatDate.D2xEZm8f.js";import{createId as $}from"@paralleldrive/cuid2";import{Table as X,TableHeader as Y,TableRow as Z,TableHead as ee,TableBody as te,TableCell as ae}from"./ui/table.js";import '../global.css';import '../convos.css';/* empty css */import"@radix-ui/react-avatar";import"clsx";import"tailwind-merge";import"@radix-ui/react-collapsible";import"./ui/dropdown-menu.js";import"./ui/switch.js";import"./ui/input.js";import"./ui/popover.js";import"./ui/command.js";import"./ui/dialog.js";import"./ui/card.js";import"./ui/progress.js";import"@radix-ui/react-accordion";import"./ui/alert-dialog.js";import"./ui/alert.js";import"./ui/button-group.js";import"./ui/calendar.js";import"./ui/icon.js";import"./ui/separator.js";import"../logos/microsoft-teams-logo.js";import"../logos/slack-logo.js";import"../logos/microsoft-logo.js";import{d as se}from"../chunks/dark.DuW7JuAk.js";function re({messageId:s}){const{fetchAnswerDiagnostics:r}=ye(),[l,c]=t(null),[i,m]=t(!0);return a(()=>{r(s).then(e=>c(e)).finally(()=>m(!1))},[r,s]),/* @__PURE__ */e.createElement("div",{className:"flex flex-col gap-4 px-4 flex-shrink-0 bg-surface","data-name":"discard-dialog-answer-diagnostic"},i?/* @__PURE__ */e.createElement("div",{className:"flex items-center justify-center h-full"},/* @__PURE__ */e.createElement(f,null)):/* @__PURE__ */e.createElement(e.Fragment,null,l&&/* @__PURE__ */e.createElement(e.Fragment,null,/* @__PURE__ */e.createElement("dl",{className:"grid grid-cols-[1fr_2fr] grid-rows-2 gap-5"},/* @__PURE__ */e.createElement("div",{className:"flex flex-col gap-1"},/* @__PURE__ */e.createElement("dt",{className:"heading-xs"},"Confidence"),/* @__PURE__ */e.createElement("dd",{className:"text-sm"},l.confidence_score)),l.answer_generation_type&&/* @__PURE__ */e.createElement("div",{className:"flex flex-col gap-1"},/* @__PURE__ */e.createElement("dt",{className:"heading-xs"},"Answer Type"),/* @__PURE__ */e.createElement("dd",{className:"text-sm"},l.answer_generation_type)),l.query_context_relevance&&/* @__PURE__ */e.createElement("div",{className:"flex flex-col gap-1"},/* @__PURE__ */e.createElement("dt",{className:"heading-xs"},"Relevance"),/* @__PURE__ */e.createElement("dd",{className:"text-sm"},l.query_context_relevance)),l.context_sufficiency&&/* @__PURE__ */e.createElement("div",{className:"flex flex-col gap-1"},/* @__PURE__ */e.createElement("dt",{className:"heading-xs"},"Context"),/* @__PURE__ */e.createElement("dd",{className:"text-sm"},l.context_sufficiency))),l.confidence_justification&&/* @__PURE__ */e.createElement("div",{className:"flex flex-col gap-2","data-name":"diagnostic-justification"},/* @__PURE__ */e.createElement("span",{className:"heading-xs"},"Justification"),/* @__PURE__ */e.createElement("p",{className:"text-sm my-0"},l.confidence_justification)),l.evidence_from_context&&l.evidence_from_context.length>0&&/* @__PURE__ */e.createElement("div",{className:"flex flex-col gap-2","data-name":"diagnostic-evidence"},/* @__PURE__ */e.createElement("span",{className:"heading-xs"},"Evidence (from Knowledge Base)"),l.evidence_from_context.map((t,a)=>/* @__PURE__ */e.createElement("div",{key:a,className:"flex flex-col gap-1"},t.supporting_quote&&/* @__PURE__ */e.createElement("p",{className:"text-sm my-0"},t.supporting_quote),t.url&&/* @__PURE__ */e.createElement(E,{variant:"link",size:"sm",className:"flex gap-1 text-sm self-end items-center",asChild:!0},/* @__PURE__ */e.createElement("a",{href:t.url,target:"_blank",rel:"noopener noreferrer"},/* @__PURE__ */e.createElement("span",null,"Source"),/* @__PURE__ */e.createElement(n,{size:16})))))))))}var ne=/* @__PURE__ */(e=>(e.INCORRECT_ANSWER="incorrect_answer",e.HALLUCINATED_ANSWER="hallucinated_answer",e.OVERSHARING="oversharing",e.WRONG_ARTICLE_SURFACED="wrong_article_surfaced",e.OTHER="other",e))(ne||{});const le={incorrect_answer:"Incorrect answer",hallucinated_answer:"Hallucinated answer",oversharing:"Oversharing",wrong_article_surfaced:"Wrong article surfaced",other:"Other"};function ce({discarded:r,discardedMeta:n,onSubmit:i,onApprove:m,selectOpenRef:o,className:d}){const[u,p]=t(r??!1),[f,O]=t(!1),[S,z]=t(r),D=s(null);a(()=>{z(r),r&&p(!0)},[r]);const F=e=>{O(e),o&&(o.current.isOpen=e)};a(()=>{o&&(o.current.close=()=>F(!1))},[o]);const{control:R,register:M,handleSubmit:I,reset:q,formState:{isSubmitting:P}}=g({defaultValues:{reason:n?.reason,preferredAnswer:n?.suggestedAnswer||""}});a(()=>{q({reason:n?.reason,preferredAnswer:n?.suggestedAnswer||""})},[n,q]),a(()=>{D.current&&(D.current.inert=!u)},[u]);const T=null!=S,B=!T||!1===S,L=!T||!0===S;/* @__PURE__ */
|
|
2
2
|
return e.createElement("div",{className:_("space-y-4",d)},/* @__PURE__ */e.createElement("div",{className:"flex gap-2 px-4"},B&&/* @__PURE__ */e.createElement(C,null,/* @__PURE__ */e.createElement(j,{asChild:!0},/* @__PURE__ */e.createElement(E,{variant:"surface",elevation:"shadow",size:"sm",className:_("text-default !opacity-100",{"bg-green-600 text-dark-100":!1===S}),disabled:T,onClick:async()=>{try{await m(),z(!1),p(!1),F(!1)}catch(e){console.error("Failed to approve:",e)}}},
|
|
3
3
|
/* @__PURE__ */e.createElement(l,null)," ",!1===S?"Approved":"Approve")),/* @__PURE__ */e.createElement(A,null,/* @__PURE__ */e.createElement("span",null,"Approve the answer"))),L&&/* @__PURE__ */e.createElement(C,null,/* @__PURE__ */e.createElement(j,{asChild:!0},/* @__PURE__ */e.createElement(E,{variant:"surface",elevation:"shadow",size:"sm",className:_("text-default !opacity-100",{"bg-red-600 text-dark-100":!0===S}),disabled:T,onClick:()=>p(!u)},
|
|
4
4
|
/* @__PURE__ */e.createElement(c,null),!0===S?"Discarded":"Discard")),/* @__PURE__ */e.createElement(A,null,/* @__PURE__ */e.createElement("span",null,"Discard the answer")))),/* @__PURE__ */e.createElement("div",{className:_("grid transition-[grid-template-rows] duration-300 ease-in-out",u?"grid-rows-[1fr]":"grid-rows-[0fr]")},S?/* @__PURE__ */e.createElement("div",{className:_("overflow-hidden min-h-0 px-4 bg-dark-200 space-y-4",u?"py-4 mb-4":"py-0"),"data-name":"discard-dialog-reason"},
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export{D as DataTable}from"../chunks/data-table.
|
|
1
|
+
export{D as DataTable}from"../chunks/data-table.bjvbLk2u.js";
|
|
2
2
|
//# sourceMappingURL=data-table.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import e from"react";import{LineChart as t,CartesianGrid as a,XAxis as r,Line as l}from"recharts";import{a as s}from"../chunks/trend-value.BPBDBsk2.js";import{Card as c,CardHeader as n,CardContent as m}from"./ui/card.js";import{C as o,a as i,b as d,c as p,d as x}from"../chunks/chart.BDL2tf-S.js";import{f}from"../chunks/formatNumber.DhVn228t.js";import{u as k}from"../chunks/useChartDateFormatters.Dx2h5AAm.js";import{c as u}from"../chunks/utils.C6Qu-kwd.js";const E=e=>f(e,{});function b({total:f,trend:b,trendValue:
|
|
2
|
-
return e.createElement(c,{className:u("shadow-none border border-dark-300 rounded-lg",w)},/* @__PURE__ */e.createElement(n,{className:"p-0 space-y-0 border-b border-dark-300"},/* @__PURE__ */e.createElement("div",{className:"flex items-stretch justify-between"},/* @__PURE__ */e.createElement("div",{className:"flex flex-col gap-1 justify-center py-4 px-4"},/* @__PURE__ */e.createElement("p",{className:"uppercase heading-xxxs font-semibold text-dark tracking-normal"},"Discoveries created"),/* @__PURE__ */e.createElement("div",{className:"flex items-center gap-2"},/* @__PURE__ */e.createElement("span",{className:"font-mono text-3xl leading-10 text-dark"},E(f)),/* @__PURE__ */e.createElement(s,{trend:b,trendValue:
|
|
1
|
+
import e from"react";import{LineChart as t,CartesianGrid as a,XAxis as r,Line as l}from"recharts";import{a as s}from"../chunks/trend-value.BPBDBsk2.js";import{Card as c,CardHeader as n,CardContent as m}from"./ui/card.js";import{C as o,a as i,b as d,c as p,d as x}from"../chunks/chart.BDL2tf-S.js";import{f}from"../chunks/formatNumber.DhVn228t.js";import{u as k}from"../chunks/useChartDateFormatters.Dx2h5AAm.js";import{c as u}from"../chunks/utils.C6Qu-kwd.js";const E=e=>f(e,{});function b({total:f,trend:b,trendValue:h,subBreakdowns:y,sourceTotals:N,data:v,chartConfig:g,locale:j,className:w}){const{tickFormatter:C,formatXLabel:D}=k(j),F=Object.keys(g);/* @__PURE__ */
|
|
2
|
+
return e.createElement(c,{className:u("shadow-none border border-dark-300 rounded-lg",w)},/* @__PURE__ */e.createElement(n,{className:"p-0 space-y-0 border-b border-dark-300"},/* @__PURE__ */e.createElement("div",{className:"flex items-stretch justify-between"},/* @__PURE__ */e.createElement("div",{className:"flex flex-col gap-1 justify-center py-4 px-4"},/* @__PURE__ */e.createElement("p",{className:"uppercase heading-xxxs font-semibold text-dark tracking-normal"},"Discoveries created"),/* @__PURE__ */e.createElement("div",{className:"flex items-center gap-2"},/* @__PURE__ */e.createElement("span",{className:"font-mono text-3xl leading-10 text-dark"},E(f)),/* @__PURE__ */e.createElement(s,{trend:b,trendValue:h}),y.map((t,a)=>/* @__PURE__ */e.createElement("span",{key:t.label,className:"text-xs leading-4 text-dark-600"},a>0&&/* @__PURE__ */e.createElement("span",{className:"mr-2"},"·"),E(t.value)," ",t.label)))),/* @__PURE__ */e.createElement("div",{className:"flex items-center self-stretch"},N.map(t=>/* @__PURE__ */e.createElement("div",{key:t.key,className:"border-l border-dark-300 flex flex-col justify-center px-4 py-2 self-stretch"},
|
|
3
3
|
/* @__PURE__ */e.createElement("span",{className:"text-xs leading-4 text-dark-700"},t.label),
|
|
4
4
|
/* @__PURE__ */e.createElement("span",{className:"font-mono text-3xl leading-10 text-dark"},E(t.value))))))),/* @__PURE__ */e.createElement(m,{className:"px-4 pt-4 pb-0"},/* @__PURE__ */e.createElement(o,{config:g,className:"h-48 w-full"},/* @__PURE__ */e.createElement(t,{data:v,margin:{top:8,left:0,right:0,bottom:0}},/* @__PURE__ */e.createElement(a,{horizontal:!0,vertical:!1,className:"stroke-dark-300"}),/* @__PURE__ */e.createElement(r,{dataKey:"date",tickLine:!1,axisLine:!1,tickMargin:8,minTickGap:32,interval:"preserveStartEnd",tickFormatter:C,tick:({x:t,y:a,payload:r})=>/* @__PURE__ */e.createElement("text",{x:t,y:a,dy:12,textAnchor:"middle",className:"text-xs fill-dark-600"},C(r.value))}),/* @__PURE__ */e.createElement(i,{cursor:!1,content:({active:t,payload:a,label:r})=>/* @__PURE__ */e.createElement(d,{active:t,payload:a,label:D(r)})}),F.map(t=>/* @__PURE__ */e.createElement(l,{key:t,dataKey:t,type:"monotone",stroke:`var(--color-${t})`,strokeWidth:2,dot:!1,activeDot:{r:4,strokeWidth:0}})),/* @__PURE__ */e.createElement(p,{content:/* @__PURE__ */e.createElement(x,null)})))))}export{b as DiscoveriesCreated};
|
|
5
5
|
//# sourceMappingURL=discoveries-created.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export{F as Filter,a as Filters,O as Operator}from"../chunks/filters.
|
|
1
|
+
export{F as Filter,a as Filters,O as Operator}from"../chunks/filters.BHp3ukNW.js";
|
|
2
2
|
//# sourceMappingURL=filter.js.map
|