@anymux/ui-kit 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/dist/{calendar-DSlrbHoj.js → calendar-DQKfYSQS.js} +48 -45
  2. package/dist/calendar-DQKfYSQS.js.map +1 -0
  3. package/dist/calendar.d.ts +1 -1
  4. package/dist/calendar.js +1 -1
  5. package/dist/{contacts-DQXTZzHc.js → contacts-By9Wg3kn.js} +35 -33
  6. package/dist/contacts-By9Wg3kn.js.map +1 -0
  7. package/dist/contacts.d.ts +1 -1
  8. package/dist/contacts.js +1 -1
  9. package/dist/{file-browser-m5atC3kF.js → file-browser-CkhNwADU.js} +61 -133
  10. package/dist/file-browser-CkhNwADU.js.map +1 -0
  11. package/dist/file-browser.d.ts +6 -6
  12. package/dist/file-browser.js +4 -4
  13. package/dist/{git-B55e6LL-.js → git-m4lboTfx.js} +29 -29
  14. package/dist/git-m4lboTfx.js.map +1 -0
  15. package/dist/git.js +1 -1
  16. package/dist/{iconMap-V4B8P-Uh.js → iconMap-DDpe35ek.js} +5 -5
  17. package/dist/iconMap-DDpe35ek.js.map +1 -0
  18. package/dist/icons.js +1 -1
  19. package/dist/{index-Bryv_GCG.d.ts → index-BP4IYXiF.d.ts} +46 -53
  20. package/dist/index-BP4IYXiF.d.ts.map +1 -0
  21. package/dist/{index-kHr9udZD.d.ts → index-BkIh8oov.d.ts} +17 -17
  22. package/dist/{index-kHr9udZD.d.ts.map → index-BkIh8oov.d.ts.map} +1 -1
  23. package/dist/{index-DSu19mq0.d.ts → index-D3Ob3aXg.d.ts} +9 -9
  24. package/dist/{index-DSu19mq0.d.ts.map → index-D3Ob3aXg.d.ts.map} +1 -1
  25. package/dist/{index-Ml_SgiKa.d.ts → index-DGoLQBX6.d.ts} +18 -42
  26. package/dist/index-DGoLQBX6.d.ts.map +1 -0
  27. package/dist/index-DnJaZr08.d.ts +67 -0
  28. package/dist/index-DnJaZr08.d.ts.map +1 -0
  29. package/dist/{index-DmsyeHFr.d.ts → index-Pty-N7-g.d.ts} +5 -5
  30. package/dist/{index-DmsyeHFr.d.ts.map → index-Pty-N7-g.d.ts.map} +1 -1
  31. package/dist/index.d.ts +7 -7
  32. package/dist/index.js +10 -10
  33. package/dist/layout-BYsc16hD.js +183 -0
  34. package/dist/layout-BYsc16hD.js.map +1 -0
  35. package/dist/layout.d.ts +2 -2
  36. package/dist/layout.js +2 -2
  37. package/dist/{list-CxfT6hix.js → list-DAq-b6RR.js} +49 -63
  38. package/dist/list-DAq-b6RR.js.map +1 -0
  39. package/dist/list.d.ts +2 -2
  40. package/dist/list.js +4 -3
  41. package/dist/{media-DZ292aKK.js → media-DuczOGsk.js} +32 -31
  42. package/dist/media-DuczOGsk.js.map +1 -0
  43. package/dist/media.js +1 -1
  44. package/dist/{tree-Dd9Z0Aso.js → tree-B9VQcKBp.js} +2 -2
  45. package/dist/{tree-Dd9Z0Aso.js.map → tree-B9VQcKBp.js.map} +1 -1
  46. package/dist/tree.d.ts +1 -1
  47. package/dist/tree.js +2 -2
  48. package/package.json +2 -2
  49. package/src/calendar/AgendaView.tsx +2 -2
  50. package/src/calendar/CalendarBrowser.tsx +11 -11
  51. package/src/calendar/CalendarSidebar.tsx +10 -10
  52. package/src/calendar/DayView.tsx +5 -5
  53. package/src/calendar/EventCard.tsx +3 -3
  54. package/src/calendar/MonthView.tsx +6 -6
  55. package/src/calendar/WeekView.tsx +10 -10
  56. package/src/contacts/ContactBrowser.tsx +8 -8
  57. package/src/contacts/ContactCard.tsx +4 -4
  58. package/src/contacts/ContactDetail.tsx +10 -10
  59. package/src/contacts/ContactGroupSidebar.tsx +6 -6
  60. package/src/contacts/ContactList.tsx +3 -3
  61. package/src/file-browser/components/FileBrowser.tsx +3 -2
  62. package/src/file-browser/components/FileBrowserContent.tsx +1 -1
  63. package/src/file-browser/examples/BasicUsage.tsx +2 -2
  64. package/src/file-browser/index.ts +1 -1
  65. package/src/file-browser/providers/FileSystemProvider.ts +1 -1
  66. package/src/git/BranchList.tsx +12 -12
  67. package/src/git/CommitList.tsx +11 -11
  68. package/src/git/DiffViewer.tsx +11 -11
  69. package/src/icons/iconMap.ts +4 -4
  70. package/src/layout/index.ts +6 -2
  71. package/src/layout/models/ResponsiveLayoutModel.ts +116 -0
  72. package/src/list/components/ListItem.tsx +1 -1
  73. package/src/list/index.ts +1 -1
  74. package/src/media/AlbumSidebar.tsx +4 -4
  75. package/src/media/MediaBrowser.tsx +11 -11
  76. package/src/media/MediaGrid.tsx +3 -3
  77. package/src/media/MediaList.tsx +6 -6
  78. package/src/media/MediaPreview.tsx +2 -2
  79. package/src/media/MediaTimeline.tsx +3 -3
  80. package/src/{file-browser/components/shared → shared}/ErrorBoundary.tsx +3 -3
  81. package/dist/calendar-DSlrbHoj.js.map +0 -1
  82. package/dist/contacts-DQXTZzHc.js.map +0 -1
  83. package/dist/file-browser-m5atC3kF.js.map +0 -1
  84. package/dist/git-B55e6LL-.js.map +0 -1
  85. package/dist/iconMap-V4B8P-Uh.js.map +0 -1
  86. package/dist/index-Bryv_GCG.d.ts.map +0 -1
  87. package/dist/index-DzfY1Tok.d.ts +0 -32
  88. package/dist/index-DzfY1Tok.d.ts.map +0 -1
  89. package/dist/index-Ml_SgiKa.d.ts.map +0 -1
  90. package/dist/layout-Ca_4r8ka.js +0 -89
  91. package/dist/layout-Ca_4r8ka.js.map +0 -1
  92. package/dist/list-CxfT6hix.js.map +0 -1
  93. package/dist/media-DZ292aKK.js.map +0 -1
  94. package/src/list/components/shared/ErrorBoundary.tsx +0 -123
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-DAq-b6RR.js","names":["config: {\n viewType: string;\n isMultiSelect: boolean;\n totalItems: number;\n selectedCount: number;\n label?: string;\n labelledBy?: string;\n describedBy?: string;\n}","ariaOrientation: 'horizontal' | 'vertical'","config: {\n item: any;\n index: number;\n totalItems: number;\n isSelected: boolean;\n isFocused: boolean;\n viewType: string;\n isExpandable?: boolean;\n isExpanded?: boolean;\n level?: number;\n}","config: {\n action: 'select' | 'deselect' | 'focus' | 'activate' | 'load' | 'error';\n itemName?: string;\n itemCount?: number;\n selectedCount?: number;\n totalCount?: number;\n errorMessage?: string;\n}","key: string","config: KeyboardNavigationConfig","bytes: number","date: Date | string","container: HTMLElement","id: string","message: string","priority: 'polite' | 'assertive'","InlineRenameInput: React.FC<{\n currentName: string;\n onCommit: (newName: string) => void;\n onCancel: () => void;\n className?: string;\n}>","extraClass?: string","event: React.MouseEvent","event: React.DragEvent","iconName: string | undefined","size: 'small' | 'medium' | 'large'","ContextMenuItemRow: React.FC<ContextMenuItemRowProps>","providerItems: ListContextMenuItem[]","event: MouseEvent","event: KeyboardEvent","menuItem: ListContextMenuItem","item: any","event: React.MouseEvent","item: any","event: React.MouseEvent","model: ListItemsModel","options: KeyboardNavigationOptions","event: Event","element?: HTMLElement","shiftKey: boolean","index: number","extendSelection: boolean","options?: KeyboardNavigationOptions","containerRef?: React.RefObject<HTMLElement | HTMLDivElement | null>","MasonryItem: React.FC<MasonryItemProps>","e: React.MouseEvent","MasonryView: React.FC<MasonryViewProps>","masonryLayout: { layout: MasonryItemPosition[]; totalHeight: number }","item: ListItemData","MasonryItem: React.FC<MasonryItemProps>","e: React.MouseEvent","VirtualizedMasonryView: React.FC<VirtualizedMasonryViewProps>","masonryLayout: { layout: MasonryItemPosition[]; totalHeight: number }","visibleItems: MasonryItemPosition[]","item: ListItemData","ListLoaderComponent: React.FC<ListLoaderProps>","SkeletonItem: React.FC<SkeletonItemProps>","ErrorDisplayComponent: React.FC<ErrorDisplayProps>","mappedError: Error | string","NetworkErrorComponent: React.FC<NetworkErrorProps>","LoadErrorComponent: React.FC<LoadErrorProps>","EmptyStateComponent: React.FC<EmptyStateProps>","NoItemsComponent: React.FC<NoItemsProps>","NoSearchResultsComponent: React.FC<NoSearchResultsProps>","NoSelectionComponent: React.FC<NoSelectionProps>","enabled: boolean","operation: string","metadata?: Record<string, any>","result: BenchmarkResult","fn: () => T","fn: () => Promise<T>","duration: number","operations: BenchmarkResult[]","CalculatedGridViewComponent: React.FC<CalculatedGridViewProps>","visibleItems: Array<{ item: ListItemData; layout: GridItemLayout; index: number }>","EXTENSION_CATEGORIES: Record<string, [number, number, number, number]>","DIRECTORY_COLOR: [number, number, number, number]","OTHER_COLOR: [number, number, number, number]","EXTENSION_LEGEND: Array<{ label: string; color: string }>","name: string","isDirectory: boolean","bytes: number","path: string","path: string | null","scheme: ColorScheme","ext: string | null","result: Array<{ name: string; path: string }>","item: ListItemData","CATEGORY_EXTENSIONS: Record<string, Set<string>>","name: string","isDirectory: boolean","category: string","node: TreemapNodeData","nodes: TreemapNodeData[]","root: INode<string>","items: ListItemData[]","children: INode<string>[]","path: string","node: INode<string>","id: string","result: Array<{\n id: string;\n info: TileInfo;\n x: number;\n y: number;\n w: number;\n h: number;\n }>","info: TileInfo","event: React.MouseEvent","fakeItem: ListItemData","LIST_VIEW_TYPE: ListViewType","GRID_VIEW_TYPE: ListViewType","DETAILS_VIEW_TYPE: ListViewType","MASONRY_HORIZONTAL_VIEW_TYPE: ListViewType","MASONRY_VERTICAL_VIEW_TYPE: ListViewType","TREEMAP_VIEW_TYPE: ListViewType","pages: (number | 'ellipsis')[]","sizeStyle: React.CSSProperties | undefined","item: any","event: React.MouseEvent","item: ListItemData","event: React.DragEvent","itemsToDrag: ListItemData[]","position: 'before' | 'after' | 'inside'","info: TileInfo","fakeItem: ListItemData","items: ListContextMenuItem[]","actionId: string","items: ListItemData[]","parentItem: ListItemData","viewTypeId: string","e: MouseEvent","item: any","event: React.MouseEvent","ViewSizeControlsComponent: React.FC<ViewSizeControlsProps>","sizePresets: Array<{ value: 'small' | 'medium' | 'large' | 'extra-large'; label: string }>","size: 'small' | 'medium' | 'large' | 'extra-large'","event: React.ChangeEvent<HTMLInputElement>","LoadingIndicatorComponent: React.FC<LoadingIndicatorProps>","InlineLoadingComponent: React.FC<InlineLoadingProps>","LoadingProgressComponent: React.FC<LoadingProgressProps>","props: ErrorBoundaryProps","error: Error","errorInfo: React.ErrorInfo","config: GridLayoutConfig","updates: Partial<GridLayoutConfig>","itemsPerRow: number","itemWidth: number","itemHeight: number","totalItems: number","items: GridItemLayout[]","scrollTop: number","viewportHeight: number","overscan: number","itemIndex: number","x: number","y: number","containerWidth: number","containerHeight: number","options: Partial<GridLayoutConfig>","defaultConfig: GridLayoutConfig","config: MasonryConfig","newConfig: Partial<MasonryConfig>","items: MasonryItem[]","positions: MasonryItemPosition[]","result: MasonryLayoutResult","item: MasonryItem","colSpan: number","colGroup: number[]","col: number","containerWidth: number","columnWidth?: number","gutter: number","provider: ListItemsProvider","page: number","options?: ListLoadOptions","result: ListLoadResult","item: ListItemData","start: number","end: number","missingRanges: Array<{ start: number; end: number }>","query: string","count: number","itemIndex: number","itemId: string","size: number","modifiers?: { ctrl?: boolean; shift?: boolean }","fromId: string","toId: string","viewType: ListViewType","size: 'small' | 'medium' | 'large' | 'extra-large'","width: number","height: number","itemsPerRow: number | 'auto'","enabled: boolean","compact: boolean","show: boolean","column: 'type' | 'modified' | 'size'","visible: boolean","cols: string[]","id: string","containerWidth?: number","itemId: string | null","event: KeyboardEvent","index: number","extendSelection: boolean","draggedItems: ListItemData[]","targetItem: ListItemData | null","position: 'before' | 'after' | 'inside'","items: ListItemData[]","event: DragEvent","position: 'before' | 'after' | 'inside' | null","dragDropInfo: ListDragDropInfo","success: boolean","position: number","masonryItems: MasonryItem[]","scrollTop: number","viewportHeight: number","isHorizontal: boolean","overscan: number","item: ListItemData","type: string","iconMap: Record<string, string>","options?: ListLoadOptions","start: number","end: number","items: ListItemData[]","viewType: ListViewType","selectionInfo: ListSelectionInfo","baseMenu: ListContextMenuItem[]","multiMenu: ListContextMenuItem[]","menuItemId: string","draggedItems: ListItemData[]","targetItem: ListItemData | null","position: 'before' | 'after' | 'inside'","event: DragEvent","dragDropInfo: ListDragDropInfo","i: ListItemData","success: boolean","listener: ListItemsProviderListener","item: Partial<ListItemData>","newItem: ListItemData","itemId: string","updates: Partial<ListItemData>","config: MasonryLayoutConfig","updates: Partial<MasonryLayoutConfig>","columnCount: number","item: MasonryItemData","columnWidth: number","baseHeight: number","textLength: number","itemHeight: number","items: MasonryItemData[]","layoutItems: MasonryItemLayout[]","scrollTop: number","viewportHeight: number","overscan: number","visibleIndices: number[]","visibleItems: MasonryItemLayout[]","itemIndex: number","x: number","y: number","containerWidth: number","containerHeight: number","options: Partial<MasonryLayoutConfig>","defaultConfig: MasonryLayoutConfig"],"sources":["../src/list/utils/ListAccessibility.ts","../src/list/components/ListItem.tsx","../src/list/components/ListContextMenu.tsx","../src/list/components/VirtualizedList.tsx","../src/list/components/VirtualizedDetailsView.tsx","../src/list/utils/ListKeyboard.ts","../src/list/components/MasonryView.tsx","../src/list/components/VirtualizedMasonryView.tsx","../src/list/components/shared/ListLoader.tsx","../src/list/components/shared/ErrorDisplay.tsx","../src/list/components/shared/EmptyState.tsx","../src/list/utils/BenchmarkLogger.ts","../src/list/components/CalculatedGridView.tsx","../src/list/models/TreemapModel.ts","../src/list/components/TreemapView.tsx","../src/list/providers/ListItemsProvider.ts","../src/list/components/ListItems.tsx","../src/list/components/ViewTypeSelector.tsx","../src/list/components/SearchFilter.tsx","../src/list/components/VirtualizedGrid.tsx","../src/list/components/ViewSizeControls.tsx","../src/list/components/shared/LoadingIndicator.tsx","../src/shared/ErrorBoundary.tsx","../src/list/utils/GridLayoutCalculator.ts","../src/list/utils/MasonryLayoutEngine.ts","../src/list/models/ListItemsModel.ts","../src/list/providers/TestListProvider.ts","../src/list/utils/MasonryLayoutCalculator.ts"],"sourcesContent":["// AICODE-NOTE: Accessibility utilities for list components\nexport interface AccessibilityConfig {\n role?: string;\n ariaLabel?: string;\n ariaLabelledBy?: string;\n ariaDescribedBy?: string;\n ariaMultiSelectable?: boolean;\n ariaOrientation?: 'horizontal' | 'vertical';\n tabIndex?: number;\n}\n\nexport interface ItemAccessibilityConfig {\n role?: string;\n ariaLabel?: string;\n ariaSelected?: boolean;\n ariaExpanded?: boolean;\n ariaLevel?: number;\n ariaSetSize?: number;\n ariaPosInSet?: number;\n tabIndex?: number;\n}\n\n// AICODE-NOTE: Generate accessibility attributes for list container\nexport function getListAccessibilityProps(config: {\n viewType: string;\n isMultiSelect: boolean;\n totalItems: number;\n selectedCount: number;\n label?: string;\n labelledBy?: string;\n describedBy?: string;\n}): AccessibilityConfig {\n const { viewType, isMultiSelect, totalItems, selectedCount, label, labelledBy, describedBy } = config;\n\n // AICODE-NOTE: Base role depends on view type\n let role = 'listbox';\n let ariaOrientation: 'horizontal' | 'vertical' = 'vertical';\n\n switch (viewType) {\n case 'grid':\n case 'masonry-horizontal':\n case 'masonry-vertical':\n role = 'grid';\n ariaOrientation = viewType === 'masonry-horizontal' ? 'horizontal' : 'vertical';\n break;\n case 'details':\n role = 'table';\n break;\n default:\n role = 'listbox';\n }\n\n return {\n role,\n ariaLabel: label || `${viewType} view with ${totalItems} items, ${selectedCount} selected`,\n ariaLabelledBy: labelledBy,\n ariaDescribedBy: describedBy,\n ariaMultiSelectable: isMultiSelect,\n ariaOrientation,\n tabIndex: 0\n };\n}\n\n// AICODE-NOTE: Generate accessibility attributes for list items\nexport function getItemAccessibilityProps(config: {\n item: any;\n index: number;\n totalItems: number;\n isSelected: boolean;\n isFocused: boolean;\n viewType: string;\n isExpandable?: boolean;\n isExpanded?: boolean;\n level?: number;\n}): ItemAccessibilityConfig {\n const { \n item, \n index, \n totalItems, \n isSelected, \n isFocused, \n viewType, \n isExpandable = false, \n isExpanded, \n level = 1 \n } = config;\n\n // AICODE-NOTE: Base role depends on view type\n let role = 'option';\n \n switch (viewType) {\n case 'grid':\n case 'masonry-horizontal':\n case 'masonry-vertical':\n role = 'gridcell';\n break;\n case 'details':\n role = 'row';\n break;\n default:\n role = 'option';\n }\n\n // AICODE-NOTE: Generate descriptive label\n const itemType = item?.type || 'item';\n const itemSize = item?.size ? `, ${formatFileSize(item.size)}` : '';\n const itemDate = item?.modifiedDate ? `, modified ${formatDate(item.modifiedDate)}` : '';\n const selectionState = isSelected ? ', selected' : '';\n const expandState = isExpandable ? (isExpanded ? ', expanded' : ', collapsed') : '';\n \n const ariaLabel = `${item?.name || 'Unknown item'}, ${itemType}${itemSize}${itemDate}${selectionState}${expandState}`;\n\n return {\n role,\n ariaLabel,\n ariaSelected: isSelected,\n ariaExpanded: isExpandable ? isExpanded : undefined,\n ariaLevel: level,\n ariaSetSize: totalItems,\n ariaPosInSet: index + 1,\n tabIndex: isFocused ? 0 : -1\n };\n}\n\n// AICODE-NOTE: Generate live region announcements for screen readers\nexport function createLiveRegionAnnouncement(config: {\n action: 'select' | 'deselect' | 'focus' | 'activate' | 'load' | 'error';\n itemName?: string;\n itemCount?: number;\n selectedCount?: number;\n totalCount?: number;\n errorMessage?: string;\n}): string {\n const { action, itemName, itemCount, selectedCount, totalCount, errorMessage } = config;\n\n switch (action) {\n case 'select':\n if (itemName && selectedCount !== undefined) {\n return `${itemName} selected. ${selectedCount} of ${totalCount} items selected.`;\n }\n return 'Item selected';\n\n case 'deselect':\n if (itemName && selectedCount !== undefined) {\n return `${itemName} deselected. ${selectedCount} of ${totalCount} items selected.`;\n }\n return 'Item deselected';\n\n case 'focus':\n return itemName ? `${itemName} focused` : 'Item focused';\n\n case 'activate':\n return itemName ? `${itemName} activated` : 'Item activated';\n\n case 'load':\n if (itemCount !== undefined) {\n return `${itemCount} items loaded`;\n }\n return 'Items loaded';\n\n case 'error':\n return errorMessage || 'An error occurred';\n\n default:\n return '';\n }\n}\n\n// AICODE-NOTE: Keyboard navigation helpers\nexport interface KeyboardNavigationConfig {\n currentIndex: number;\n totalItems: number;\n itemsPerRow?: number;\n viewType: string;\n}\n\nexport function getNextFocusIndex(\n key: string,\n config: KeyboardNavigationConfig\n): number | null {\n const { currentIndex, totalItems, itemsPerRow = 1, viewType } = config;\n\n switch (key) {\n case 'ArrowDown':\n if (viewType === 'grid' || viewType.includes('masonry')) {\n // AICODE-NOTE: Grid navigation - move down by itemsPerRow\n const nextIndex = currentIndex + itemsPerRow;\n return nextIndex < totalItems ? nextIndex : null;\n } else {\n // AICODE-NOTE: List navigation - next item\n return currentIndex < totalItems - 1 ? currentIndex + 1 : null;\n }\n\n case 'ArrowUp':\n if (viewType === 'grid' || viewType.includes('masonry')) {\n // AICODE-NOTE: Grid navigation - move up by itemsPerRow\n const prevIndex = currentIndex - itemsPerRow;\n return prevIndex >= 0 ? prevIndex : null;\n } else {\n // AICODE-NOTE: List navigation - previous item\n return currentIndex > 0 ? currentIndex - 1 : null;\n }\n\n case 'ArrowRight':\n if (viewType === 'grid' || viewType.includes('masonry')) {\n // AICODE-NOTE: Grid navigation - next item in row\n const nextIndex = currentIndex + 1;\n const currentRow = Math.floor(currentIndex / itemsPerRow);\n const nextRow = Math.floor(nextIndex / itemsPerRow);\n return nextIndex < totalItems && currentRow === nextRow ? nextIndex : null;\n }\n return null;\n\n case 'ArrowLeft':\n if (viewType === 'grid' || viewType.includes('masonry')) {\n // AICODE-NOTE: Grid navigation - previous item in row\n const prevIndex = currentIndex - 1;\n const currentRow = Math.floor(currentIndex / itemsPerRow);\n const prevRow = Math.floor(prevIndex / itemsPerRow);\n return prevIndex >= 0 && currentRow === prevRow ? prevIndex : null;\n }\n return null;\n\n case 'Home':\n return 0;\n\n case 'End':\n return totalItems - 1;\n\n case 'PageUp':\n // AICODE-NOTE: Move up by approximately 10 items or one screen\n const pageUpIndex = Math.max(0, currentIndex - 10);\n return pageUpIndex !== currentIndex ? pageUpIndex : null;\n\n case 'PageDown':\n // AICODE-NOTE: Move down by approximately 10 items or one screen\n const pageDownIndex = Math.min(totalItems - 1, currentIndex + 10);\n return pageDownIndex !== currentIndex ? pageDownIndex : null;\n\n default:\n return null;\n }\n}\n\n// AICODE-NOTE: Format file size for screen readers\nfunction formatFileSize(bytes: number): string {\n if (bytes === 0) return '0 bytes';\n \n const k = 1024;\n const sizes = ['bytes', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n \n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;\n}\n\n// AICODE-NOTE: Format date for screen readers\nfunction formatDate(date: Date | string): string {\n const dateObj = typeof date === 'string' ? new Date(date) : date;\n return dateObj.toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit'\n });\n}\n\n// AICODE-NOTE: Focus management utilities\nexport class FocusManager {\n private focusedElement: HTMLElement | null = null;\n private focusHistory: HTMLElement[] = [];\n\n // AICODE-NOTE: Save current focus for restoration\n saveFocus(): void {\n const activeElement = document.activeElement as HTMLElement;\n if (activeElement && activeElement !== document.body) {\n this.focusedElement = activeElement;\n this.focusHistory.push(activeElement);\n }\n }\n\n // AICODE-NOTE: Restore previously saved focus\n restoreFocus(): boolean {\n if (this.focusedElement && document.contains(this.focusedElement)) {\n this.focusedElement.focus();\n return true;\n }\n \n // AICODE-NOTE: Try focus history\n while (this.focusHistory.length > 0) {\n const element = this.focusHistory.pop();\n if (element && document.contains(element)) {\n element.focus();\n return true;\n }\n }\n \n return false;\n }\n\n // AICODE-NOTE: Focus first focusable element in container\n focusFirst(container: HTMLElement): boolean {\n const focusable = this.getFocusableElements(container);\n if (focusable.length > 0 && focusable[0]) {\n focusable[0].focus();\n return true;\n }\n return false;\n }\n\n // AICODE-NOTE: Focus last focusable element in container\n focusLast(container: HTMLElement): boolean {\n const focusable = this.getFocusableElements(container);\n const lastElement = focusable[focusable.length - 1];\n if (focusable.length > 0 && lastElement) {\n lastElement.focus();\n return true;\n }\n return false;\n }\n\n // AICODE-NOTE: Get all focusable elements in container\n private getFocusableElements(container: HTMLElement): HTMLElement[] {\n const focusableSelectors = [\n 'button:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n 'a[href]',\n '[tabindex]:not([tabindex=\"-1\"])'\n ].join(', ');\n\n return Array.from(container.querySelectorAll(focusableSelectors)) as HTMLElement[];\n }\n}\n\n// AICODE-NOTE: Create live region element for announcements\nexport function createLiveRegion(id: string = 'list-live-region'): HTMLElement {\n let liveRegion = document.getElementById(id);\n \n if (!liveRegion) {\n liveRegion = document.createElement('div');\n liveRegion.id = id;\n liveRegion.setAttribute('aria-live', 'polite');\n liveRegion.setAttribute('aria-atomic', 'true');\n liveRegion.style.position = 'absolute';\n liveRegion.style.left = '-10000px';\n liveRegion.style.width = '1px';\n liveRegion.style.height = '1px';\n liveRegion.style.overflow = 'hidden';\n document.body.appendChild(liveRegion);\n }\n \n return liveRegion;\n}\n\n// AICODE-NOTE: Announce message to screen readers\nexport function announceToScreenReader(message: string, priority: 'polite' | 'assertive' = 'polite'): void {\n const liveRegion = createLiveRegion();\n liveRegion.setAttribute('aria-live', priority);\n \n // AICODE-NOTE: Clear and set new message\n liveRegion.textContent = '';\n setTimeout(() => {\n liveRegion.textContent = message;\n }, 100);\n} ","import React, { useState, useRef, useEffect } from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { getItemAccessibilityProps } from '../utils/ListAccessibility';\nimport { ListItemData, ListViewType } from '../types/ListTypes';\nimport { ListItemsProvider } from '../providers/ListItemsProvider';\nimport { ListItemsModel } from '../models/ListItemsModel';\nimport { File } from 'lucide-react';\nimport { lucideIconMap, iconColorMap } from '../../icons/iconMap';\nimport { useFileBrowserContext } from '../../file-browser/context/FileBrowserContext';\n\n// AICODE-NOTE: Basic list item component with click handling and flexible rendering\n\nexport interface ListItemProps {\n item: ListItemData;\n index: number;\n totalItems: number;\n viewType: ListViewType;\n provider?: ListItemsProvider;\n model?: ListItemsModel; // AICODE-NOTE: Model for debug visualization and other reactive state\n itemWidth?: number;\n itemHeight?: number;\n thumbnailSize?: number; // AICODE-NOTE: Precise thumbnail size from calculator\n isSelected?: boolean;\n isFocused?: boolean;\n isDraggedOver?: boolean;\n dragOverPosition?: 'before' | 'after' | 'inside' | null;\n canDrag?: boolean;\n onClick?: (item: ListItemData, event: React.MouseEvent) => void;\n onDoubleClick?: (item: ListItemData, event: React.MouseEvent) => void;\n onContextMenu?: (item: ListItemData, event: React.MouseEvent) => void;\n onDragStart?: (item: ListItemData, event: React.DragEvent) => void;\n onDragOver?: (item: ListItemData, event: React.DragEvent) => void;\n onDragLeave?: (item: ListItemData, event: React.DragEvent) => void;\n onDrop?: (item: ListItemData, event: React.DragEvent) => void;\n}\n\n// Inline rename input component\nconst InlineRenameInput: React.FC<{\n currentName: string;\n onCommit: (newName: string) => void;\n onCancel: () => void;\n className?: string;\n}> = ({ currentName, onCommit, onCancel, className }) => {\n const [value, setValue] = useState(currentName);\n const inputRef = useRef<HTMLInputElement>(null);\n const mountTimeRef = useRef(Date.now());\n const committedRef = useRef(false);\n\n useEffect(() => {\n mountTimeRef.current = Date.now();\n const raf = requestAnimationFrame(() => {\n const input = inputRef.current;\n if (input) {\n input.focus();\n const dotIndex = currentName.lastIndexOf('.');\n input.setSelectionRange(0, dotIndex > 0 ? dotIndex : currentName.length);\n }\n });\n return () => cancelAnimationFrame(raf);\n }, [currentName]);\n\n const commit = () => {\n if (committedRef.current) return;\n committedRef.current = true;\n const trimmed = value.trim();\n if (trimmed && trimmed !== currentName) {\n onCommit(trimmed);\n } else {\n onCancel();\n }\n };\n\n const handleBlur = () => {\n if (Date.now() - mountTimeRef.current < 200) return;\n commit();\n };\n\n return (\n <input\n ref={inputRef}\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={(e) => {\n e.stopPropagation();\n if (e.key === 'Enter') { e.preventDefault(); commit(); }\n if (e.key === 'Escape') { e.preventDefault(); onCancel(); }\n }}\n onBlur={handleBlur}\n onClick={(e) => e.stopPropagation()}\n onDoubleClick={(e) => e.stopPropagation()}\n className={`bg-background border border-primary rounded px-1 py-0 text-sm outline-none ${className || ''}`}\n style={{ minWidth: 60, maxWidth: '100%' }}\n />\n );\n};\n\n// AICODE-NOTE: Memoized component for performance optimization\nconst ListItemComponent = observer<ListItemProps>(({\n item,\n index,\n totalItems,\n viewType,\n provider,\n model,\n itemWidth,\n itemHeight,\n thumbnailSize,\n isSelected = false,\n isFocused = false,\n isDraggedOver = false,\n dragOverPosition = null,\n canDrag = false,\n onClick,\n onDoubleClick,\n onContextMenu,\n onDragStart,\n onDragOver,\n onDragLeave,\n onDrop\n}) => {\n // Inline rename support\n const fileBrowserCtx = useFileBrowserContext();\n const isRenaming = fileBrowserCtx?.renameState?.itemId === item.id && fileBrowserCtx?.renameState?.source === 'list';\n\n // Resolve thumbnail blob URL from provider cache (reactive via MobX)\n const resolvedThumbnailUrl = item.thumbnailUrl && model ? model.resolveThumbnailUrl(item) : item.imageUrl;\n\n const renderNameOrRename = (extraClass?: string) => {\n if (isRenaming && fileBrowserCtx) {\n return (\n <InlineRenameInput\n currentName={fileBrowserCtx.renameState!.currentName}\n onCommit={fileBrowserCtx.onRenameCommit}\n onCancel={fileBrowserCtx.onRenameCancel}\n className={extraClass}\n />\n );\n }\n return null;\n };\n\n // AICODE-NOTE: Generate accessibility props\n const accessibilityProps = getItemAccessibilityProps({\n item,\n index,\n totalItems,\n isSelected,\n isFocused,\n viewType: viewType.id\n });\n\n // AICODE-NOTE: Handle clicks with proper event handling and modifiers\n const handleClick = (event: React.MouseEvent) => {\n if (onClick) {\n onClick(item, event);\n }\n };\n\n const handleDoubleClick = (event: React.MouseEvent) => {\n if (onDoubleClick) {\n onDoubleClick(item, event);\n }\n };\n\n const handleContextMenu = (event: React.MouseEvent) => {\n event.preventDefault();\n if (onContextMenu) {\n onContextMenu(item, event);\n }\n };\n\n // AICODE-NOTE: Drag and drop event handlers\n const handleDragStart = (event: React.DragEvent) => {\n if (onDragStart) {\n onDragStart(item, event);\n }\n };\n\n const handleDragOver = (event: React.DragEvent) => {\n event.preventDefault();\n if (onDragOver) {\n onDragOver(item, event);\n }\n };\n\n const handleDragLeave = (event: React.DragEvent) => {\n if (onDragLeave) {\n onDragLeave(item, event);\n }\n };\n\n const handleDrop = (event: React.DragEvent) => {\n event.preventDefault();\n if (onDrop) {\n onDrop(item, event);\n }\n };\n\n // AICODE-NOTE: Import shared resolveIcon for consistent icon rendering\n const resolveItemIcon = (iconName: string | undefined, sizeClass = 'w-4 h-4') => {\n const name = iconName || 'file';\n const MappedIcon = lucideIconMap[name] || File;\n const colorClass = iconColorMap[name] || 'text-muted-foreground';\n return <MappedIcon className={`${sizeClass} ${colorClass}`} />;\n };\n\n // AICODE-NOTE: Render icon using provider's getItemIcon method\n const renderIcon = (sizeClass = 'w-4 h-4') => {\n const customIcon = provider?.getItemIcon?.(item);\n if (customIcon) {\n if (typeof customIcon === 'string') {\n return resolveItemIcon(customIcon, sizeClass);\n } else {\n const IconComponent = customIcon;\n return <IconComponent className={sizeClass} />;\n }\n }\n if (item.icon) {\n return resolveItemIcon(item.icon, sizeClass);\n }\n return <File className={`${sizeClass} text-muted-foreground`} />;\n };\n\n // AICODE-NOTE: Render image or icon for list/details views\n const renderImageOrIcon = (size: 'small' | 'medium' | 'large' = 'medium') => {\n const iconSizeClasses = {\n small: 'w-4 h-4',\n medium: 'w-8 h-8',\n large: 'w-12 h-12'\n };\n\n const containerClasses = {\n small: 'h-6 w-6',\n medium: 'h-12 w-12',\n large: 'h-16 w-16'\n };\n\n const imgSrc = resolvedThumbnailUrl || item.imageUrl;\n const pxSizes = { small: 24, medium: 48, large: 64 };\n const px = pxSizes[size];\n if (imgSrc) {\n return (\n <img\n src={imgSrc}\n alt={item.name}\n className=\"object-cover rounded flex-shrink-0\"\n style={{ width: px, height: px, maxWidth: px, maxHeight: px }}\n loading=\"lazy\"\n onError={(e) => {\n const target = e.target as HTMLImageElement;\n target.style.display = 'none';\n target.nextElementSibling?.classList.remove('hidden');\n }}\n />\n );\n }\n\n return (\n <div className={`${containerClasses[size]} flex items-center justify-center`}>\n {renderIcon(iconSizeClasses[size])}\n </div>\n );\n };\n\n // AICODE-NOTE: Get item dimensions for variable sizing\n const getItemDimensions = () => {\n if (item.getDimensions) {\n return item.getDimensions();\n }\n \n if (item.aspectRatio && itemWidth) {\n return {\n width: itemWidth,\n height: itemWidth / item.aspectRatio\n };\n }\n \n return null;\n };\n\n // AICODE-NOTE: Enhanced styles with better selection and focus states\n const baseClasses = `\n flex items-center gap-2 py-1 px-2 text-[13px] cursor-default select-none transition-colors duration-200\n hover:bg-muted/50 border border-transparent rounded-md\n ${isSelected ? 'bg-primary/10 border-primary/20' : ''}\n ${isFocused ? 'ring-2 ring-primary/50' : ''}\n ${isDraggedOver ? 'bg-accent/20 border-accent' : ''}\n ${dragOverPosition === 'before' ? 'border-t-2 border-t-primary' : ''}\n ${dragOverPosition === 'after' ? 'border-b-2 border-b-primary' : ''}\n ${dragOverPosition === 'inside' ? 'bg-primary/5 border-primary/30' : ''}\n `;\n\n // AICODE-NOTE: Grid-specific styles with better spacing and sizing\n const gridClasses = `\n flex flex-col items-center justify-start p-3 cursor-default select-none transition-colors duration-200\n hover:bg-muted/50 border border-transparent rounded-lg min-h-[140px] max-w-full\n ${isSelected ? 'bg-primary/10 border-primary/20 shadow-sm' : ''}\n ${isFocused ? 'ring-2 ring-primary/50' : ''}\n ${isDraggedOver ? 'bg-accent/20 border-accent' : ''}\n ${dragOverPosition === 'before' ? 'border-t-2 border-t-primary' : ''}\n ${dragOverPosition === 'after' ? 'border-b-2 border-b-primary' : ''}\n ${dragOverPosition === 'inside' ? 'bg-primary/5 border-primary/30' : ''}\n `;\n\n // AICODE-NOTE: Debug styles for layout visualization\n const isDebugMode = model?.debugVisualization ?? false;\n \n const debugStyles = isDebugMode ? {\n container: { backgroundColor: 'rgba(0, 255, 255, 0.05)', border: '2px solid rgba(0, 255, 255, 0.3)' },\n imageContainer: { backgroundColor: 'rgba(255, 0, 0, 0.1)', border: '1px solid rgba(255, 0, 0, 0.3)' },\n image: { backgroundColor: 'rgba(0, 255, 0, 0.1)', border: '1px solid rgba(0, 255, 0, 0.5)' },\n icon: { backgroundColor: 'rgba(0, 0, 255, 0.1)', border: '1px solid rgba(0, 0, 255, 0.3)' },\n textContainer: { backgroundColor: 'rgba(255, 255, 0, 0.1)', border: '1px solid rgba(255, 255, 0, 0.3)' },\n text: { backgroundColor: 'rgba(255, 165, 0, 0.1)', border: '1px solid rgba(255, 165, 0, 0.3)' },\n metadata: { backgroundColor: 'rgba(128, 0, 128, 0.1)', border: '1px solid rgba(128, 0, 128, 0.3)' }\n } : {\n container: {},\n imageContainer: {},\n image: {},\n icon: {},\n textContainer: {},\n text: {},\n metadata: {}\n };\n\n // AICODE-NOTE: Grid view layout — cell dimensions are uniform, thumbnail adapts to image aspect ratio\n if (viewType.id === 'grid') {\n const containerWidth = itemWidth || 200;\n const containerHeight = itemHeight || 140;\n const maxThumbWidth = containerWidth - 16;\n const maxThumbHeight = thumbnailSize ?? Math.min(maxThumbWidth, containerHeight - 48);\n\n // Get image aspect ratio (w/h) from provider cache if available\n const imageAspectRatio = model?.provider?.getAspectRatio?.(item.path);\n // Fit thumbnail to image aspect ratio within the available cell space\n let thumbWidth = maxThumbWidth;\n let thumbHeight = maxThumbHeight;\n if (resolvedThumbnailUrl && imageAspectRatio && imageAspectRatio > 0) {\n // Start with full width, calculate height\n const heightFromWidth = maxThumbWidth / imageAspectRatio;\n if (heightFromWidth <= maxThumbHeight) {\n // Landscape or moderate: full width, shorter height\n thumbWidth = maxThumbWidth;\n thumbHeight = Math.round(heightFromWidth);\n } else {\n // Portrait: full height, narrower width\n thumbHeight = maxThumbHeight;\n thumbWidth = Math.round(maxThumbHeight * imageAspectRatio);\n }\n }\n\n return (\n <div\n className={`${gridClasses} flex flex-col items-center`}\n style={{\n width: containerWidth,\n height: containerHeight,\n minHeight: containerHeight,\n boxSizing: 'border-box',\n ...debugStyles.container\n }}\n role={accessibilityProps.role}\n aria-label={accessibilityProps.ariaLabel}\n aria-selected={accessibilityProps.ariaSelected}\n aria-setsize={accessibilityProps.ariaSetSize}\n aria-posinset={accessibilityProps.ariaPosInSet}\n tabIndex={accessibilityProps.tabIndex}\n draggable={canDrag}\n onClick={handleClick}\n onDoubleClick={handleDoubleClick}\n onContextMenu={handleContextMenu}\n onDragStart={handleDragStart}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n >\n {/* AICODE-NOTE: Thumbnail container sized to image aspect ratio */}\n <div\n className=\"relative rounded-lg overflow-hidden mb-2 flex-shrink-0 flex items-center justify-center\"\n style={{\n width: thumbWidth,\n height: thumbHeight,\n ...debugStyles.imageContainer\n }}\n >\n {resolvedThumbnailUrl ? (\n <img\n src={resolvedThumbnailUrl}\n alt={item.name}\n className=\"object-cover\"\n loading=\"lazy\"\n style={{\n width: '100%',\n height: '100%',\n ...debugStyles.image\n }}\n />\n ) : (\n <div\n className=\"w-full h-full flex items-center justify-center bg-muted/30 rounded-lg\"\n style={{\n ...debugStyles.icon\n }}\n >\n {renderIcon('w-12 h-12')}\n </div>\n )}\n\n {/* AICODE-NOTE: Selection overlay */}\n {isSelected && (\n <div className=\"absolute inset-0 bg-primary/20 border-2 border-primary rounded-lg\" />\n )}\n\n {/* Checkbox overlay for grid items */}\n {(model?.showCheckboxes) && (\n <div className=\"absolute top-1 left-1 z-10\">\n <input\n type=\"checkbox\"\n checked={isSelected}\n onChange={() => {}}\n onClick={(e) => {\n e.stopPropagation();\n model?.selectItem(item, { ctrl: true });\n }}\n className=\"h-4 w-4 rounded border-muted-foreground/50 accent-primary cursor-pointer bg-background shadow-sm\"\n />\n </div>\n )}\n </div>\n \n {/* AICODE-NOTE: Item name with debug background */}\n <div \n className=\"text-sm font-medium text-center px-2 leading-tight\"\n style={{ \n width: containerWidth - 16,\n maxWidth: containerWidth - 16,\n ...debugStyles.textContainer\n }}\n >\n <div \n className=\"truncate\"\n style={{ \n width: '100%',\n maxWidth: '100%',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n ...debugStyles.text\n }}\n title={item.name}\n >\n {isRenaming ? renderNameOrRename('text-center') : item.name}\n </div>\n </div>\n\n {/* AICODE-NOTE: Optional metadata with debug background */}\n {item.size && (\n <div \n className=\"text-xs text-muted-foreground mt-1 text-center truncate\"\n style={{ \n width: containerWidth - 16,\n maxWidth: containerWidth - 16,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n ...debugStyles.metadata\n }}\n >\n {item.size > 1024 * 1024 \n ? `${(item.size / (1024 * 1024)).toFixed(1)} MB`\n : `${(item.size / 1024).toFixed(1)} KB`\n }\n </div>\n )}\n </div>\n );\n }\n\n // AICODE-NOTE: Masonry view layout (similar to grid but with flexible height)\n if (viewType.id === 'masonry-horizontal' || viewType.id === 'masonry-vertical') {\n const customDimensions = getItemDimensions();\n const containerWidth = customDimensions?.width || itemWidth || 200;\n const containerHeight = customDimensions?.height || itemHeight || 140;\n \n return (\n <div\n className={gridClasses}\n style={{ \n width: containerWidth, \n minHeight: containerHeight + 80,\n boxSizing: 'border-box',\n ...debugStyles.container\n }}\n role={accessibilityProps.role}\n aria-label={accessibilityProps.ariaLabel}\n aria-selected={accessibilityProps.ariaSelected}\n aria-setsize={accessibilityProps.ariaSetSize}\n aria-posinset={accessibilityProps.ariaPosInSet}\n tabIndex={accessibilityProps.tabIndex}\n draggable={canDrag}\n onClick={handleClick}\n onDoubleClick={handleDoubleClick}\n onContextMenu={handleContextMenu}\n onDragStart={handleDragStart}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n >\n {/* AICODE-NOTE: Image or icon with variable size */}\n <div \n className=\"flex items-center justify-center mb-3 flex-1 overflow-hidden rounded-lg\"\n style={{\n width: containerWidth - 16,\n height: containerHeight - 20,\n maxWidth: containerWidth - 16,\n maxHeight: containerHeight - 20,\n ...debugStyles.imageContainer\n }}\n >\n {resolvedThumbnailUrl ? (\n <img\n src={resolvedThumbnailUrl}\n alt={item.name}\n className=\"object-contain rounded\"\n style={{\n width: 'auto',\n height: 'auto',\n maxWidth: '100%',\n maxHeight: '100%',\n ...debugStyles.image\n }}\n loading=\"lazy\"\n />\n ) : (\n <div \n className=\"text-4xl flex items-center justify-center w-full h-full\"\n style={{\n ...debugStyles.icon\n }}\n >\n {renderIcon()}\n </div>\n )}\n </div>\n \n {/* AICODE-NOTE: Item name with flexible height for masonry */}\n <div \n className=\"text-sm font-medium text-center px-2 leading-tight\"\n style={{\n width: containerWidth - 16,\n maxWidth: containerWidth - 16,\n ...debugStyles.textContainer\n }}\n >\n <div \n className=\"break-words\"\n style={{\n width: '100%',\n maxWidth: '100%',\n ...debugStyles.text\n }}\n title={item.name}\n >\n {isRenaming ? renderNameOrRename('text-center') : item.name}\n </div>\n </div>\n\n {/* AICODE-NOTE: Extended metadata for masonry view */}\n <div \n className=\"text-xs text-muted-foreground mt-2 space-y-1 text-center\"\n style={{\n width: containerWidth - 16,\n maxWidth: containerWidth - 16,\n ...debugStyles.metadata\n }}\n >\n {item.size && (\n <div className=\"truncate\">\n {item.size > 1024 * 1024 \n ? `${(item.size / (1024 * 1024)).toFixed(1)} MB`\n : `${(item.size / 1024).toFixed(1)} KB`\n }\n </div>\n )}\n {item.modified && (\n <div className=\"truncate\">{item.modified.toLocaleDateString()}</div>\n )}\n </div>\n </div>\n );\n }\n\n // AICODE-NOTE: Details view layout — uses CSS grid matching the header in VirtualizedDetailsView\n if (viewType.id === 'details') {\n // Selection/focus classes without flex/gap from baseClasses\n const detailsStateClasses = `\n items-center py-1 px-4 text-[13px] cursor-default select-none transition-colors duration-200\n hover:bg-muted/50 border border-transparent\n ${isSelected ? 'bg-primary/10 border-primary/20' : ''}\n ${isFocused ? 'ring-2 ring-primary/50' : ''}\n ${isDraggedOver ? 'bg-accent/20 border-accent' : ''}\n ${dragOverPosition === 'before' ? 'border-t-2 border-t-primary' : ''}\n ${dragOverPosition === 'after' ? 'border-b-2 border-b-primary' : ''}\n ${dragOverPosition === 'inside' ? 'bg-primary/5 border-primary/30' : ''}\n `;\n\n const isCompact = model?.compactMode ?? false;\n const colVis = model?.columnVisibility ?? { type: true, modified: true, size: true };\n const gridCols = model?.detailsGridTemplateColumns ?? '24px 1fr 96px 128px 80px';\n const showCb = model?.showCheckboxes ?? false;\n\n return (\n <div\n className={`grid ${detailsStateClasses}`}\n style={{\n gridTemplateColumns: gridCols,\n columnGap: 16,\n ...debugStyles.container\n }}\n draggable={canDrag}\n onClick={handleClick}\n onDoubleClick={handleDoubleClick}\n onContextMenu={handleContextMenu}\n onDragStart={handleDragStart}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n >\n {showCb && (\n <div className=\"flex items-center justify-center\">\n <input\n type=\"checkbox\"\n checked={isSelected}\n onChange={() => {}}\n onClick={(e) => {\n e.stopPropagation();\n model?.selectItem(item, { ctrl: true });\n }}\n className=\"h-3.5 w-3.5 rounded border-muted-foreground/50 accent-primary cursor-pointer\"\n />\n </div>\n )}\n\n <div className=\"flex items-center justify-center\" style={debugStyles.icon}>\n {renderImageOrIcon('small')}\n </div>\n\n <div className=\"truncate font-medium min-w-0\" style={debugStyles.text} title={item.name}>\n {isRenaming ? renderNameOrRename() : item.name}\n </div>\n\n {!isCompact && colVis.type && (\n <div className=\"text-sm text-muted-foreground truncate min-w-0\" style={debugStyles.metadata}>\n {item.type || 'Unknown'}\n </div>\n )}\n\n {!isCompact && colVis.modified && (\n <div className=\"text-sm text-muted-foreground truncate min-w-0\" style={debugStyles.metadata}>\n {item.modified ? item.modified.toLocaleDateString() : '-'}\n </div>\n )}\n\n {!isCompact && colVis.size && (\n <div className=\"text-sm text-muted-foreground text-right truncate min-w-0\" style={debugStyles.metadata}>\n {item.size ? `${(item.size / 1024).toFixed(1)} KB` : '-'}\n </div>\n )}\n </div>\n );\n }\n\n // AICODE-NOTE: Default list view layout\n const listCompact = model?.compactMode ?? false;\n const listShowCb = model?.showCheckboxes ?? false;\n return (\n <div\n className={baseClasses}\n style={{\n ...debugStyles.container\n }}\n draggable={canDrag}\n onClick={handleClick}\n onDoubleClick={handleDoubleClick}\n onContextMenu={handleContextMenu}\n onDragStart={handleDragStart}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n >\n {listShowCb && (\n <div className=\"flex items-center flex-shrink-0\">\n <input\n type=\"checkbox\"\n checked={isSelected}\n onChange={() => {}}\n onClick={(e) => {\n e.stopPropagation();\n model?.selectItem(item, { ctrl: true });\n }}\n className=\"h-3.5 w-3.5 rounded border-muted-foreground/50 accent-primary cursor-pointer\"\n />\n </div>\n )}\n\n <div\n className=\"text-lg flex-shrink-0 flex items-center\"\n style={{\n ...debugStyles.icon\n }}\n >\n {renderImageOrIcon()}\n </div>\n\n <div\n className=\"flex-1 min-w-0\"\n style={{\n ...debugStyles.textContainer\n }}\n >\n <div\n className=\"font-medium truncate\"\n style={{\n ...debugStyles.text\n }}\n title={item.name}\n >\n {isRenaming ? renderNameOrRename() : item.name}\n </div>\n {!listCompact && item.size && (\n <div\n className=\"text-sm text-muted-foreground\"\n style={{\n ...debugStyles.metadata\n }}\n >\n {(item.size / 1024).toFixed(1)} KB\n </div>\n )}\n </div>\n\n {!listCompact && item.modified && (\n <div\n className=\"text-xs text-muted-foreground flex-shrink-0\"\n style={{\n ...debugStyles.metadata\n }}\n >\n {item.modified.toLocaleDateString()}\n </div>\n )}\n </div>\n );\n});\n\nListItemComponent.displayName = 'ListItem';\n\n// AICODE-NOTE: observer handles efficient re-rendering via MobX observable tracking.\n// Custom React.memo was removed because it blocked MobX-triggered re-renders\n// (e.g., thumbnail cache updates) since resolvedThumbnailUrl is computed inside render.\nexport const ListItem = ListItemComponent; ","import React, { useRef, useEffect, useState, useCallback } from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { ListItemData, ListContextMenuItem } from '../types/ListTypes';\nimport { ListItemsProvider } from '../providers/ListItemsProvider';\nimport { contextMenuIconMap } from '../../icons/iconMap';\n\n// AICODE-NOTE: Context menu component for list items — positioned near cursor,\n// closes on click-outside, Escape, or scroll. Styled to match @anymux/ui context-menu.\n\nexport interface ListContextMenuProps {\n isOpen: boolean;\n position: { x: number; y: number };\n items: ListItemData[];\n provider: ListItemsProvider;\n onClose: () => void;\n /** Extra menu items to prepend before provider items */\n extraMenuItems?: ListContextMenuItem[];\n /** Handler for extra menu item actions (called instead of provider.onContextMenuAction) */\n onExtraMenuAction?: (actionId: string, items: ListItemData[]) => void;\n}\n\n// AICODE-NOTE: Individual context menu item with icon, label, shortcut, destructive variant\ninterface ContextMenuItemRowProps {\n menuItem: ListContextMenuItem;\n isFocused: boolean;\n onMenuItemClick: (menuItem: ListContextMenuItem) => void;\n onMouseEnter: () => void;\n}\n\nconst ContextMenuItemRow: React.FC<ContextMenuItemRowProps> = ({\n menuItem,\n isFocused,\n onMenuItemClick,\n onMouseEnter,\n}) => {\n if (menuItem.type === 'separator') {\n return <div className=\"bg-border -mx-1 my-1 h-px\" />;\n }\n\n const isDestructive = menuItem.destructive;\n\n return (\n <button\n role=\"menuitem\"\n onClick={() => !menuItem.disabled && onMenuItemClick(menuItem)}\n onMouseEnter={onMouseEnter}\n disabled={menuItem.disabled}\n className={[\n 'w-full text-left px-2 py-1.5 text-sm outline-hidden select-none',\n 'flex items-center gap-2 rounded-sm cursor-default',\n menuItem.disabled\n ? 'pointer-events-none opacity-50'\n : '',\n !menuItem.disabled && !isDestructive\n ? 'text-foreground'\n : '',\n !menuItem.disabled && isDestructive\n ? 'text-destructive'\n : '',\n isFocused && !isDestructive\n ? 'bg-accent text-accent-foreground'\n : '',\n isFocused && isDestructive\n ? 'bg-destructive/10 text-destructive'\n : '',\n ].filter(Boolean).join(' ')}\n title={menuItem.tooltip}\n >\n {/* AICODE-NOTE: Menu item icon */}\n {menuItem.icon && (\n <span className={[\n 'w-4 h-4 flex-shrink-0 flex items-center justify-center',\n !isDestructive ? '[&_svg]:text-muted-foreground' : '',\n ].filter(Boolean).join(' ')}>\n {typeof menuItem.icon === 'string' ? (\n (() => {\n const Icon = contextMenuIconMap[menuItem.icon as string];\n return Icon ? <Icon className=\"size-4\" /> : null;\n })()\n ) : (\n React.createElement(menuItem.icon, { className: 'size-4' })\n )}\n </span>\n )}\n\n {/* AICODE-NOTE: Menu item label */}\n <span className=\"flex-1 truncate\">{menuItem.label}</span>\n\n {/* AICODE-NOTE: Keyboard shortcut hint */}\n {menuItem.shortcut && (\n <span className=\"text-xs text-muted-foreground ml-auto tracking-widest\">\n {menuItem.shortcut}\n </span>\n )}\n </button>\n );\n};\n\nContextMenuItemRow.displayName = 'ContextMenuItemRow';\n\nexport const ListContextMenu = observer<ListContextMenuProps>(({\n isOpen,\n position,\n items,\n provider,\n onClose,\n extraMenuItems,\n onExtraMenuAction,\n}) => {\n const menuRef = useRef<HTMLDivElement>(null);\n const [menuItems, setMenuItems] = useState<ListContextMenuItem[]>([]);\n const [focusedIndex, setFocusedIndex] = useState(-1);\n const [adjustedPosition, setAdjustedPosition] = useState(position);\n\n // Get the actionable (non-separator) items for keyboard navigation\n const actionableIndices = menuItems\n .map((item, idx) => (item.type !== 'separator' ? idx : -1))\n .filter(idx => idx !== -1);\n\n // AICODE-NOTE: Get context menu items from provider when menu opens\n useEffect(() => {\n if (isOpen) {\n let providerItems: ListContextMenuItem[] = [];\n if (items.length === 0) {\n providerItems = provider.getEmptySpaceContextMenu?.() || [];\n } else if (items.length === 1) {\n const firstItem = items[0];\n if (firstItem) {\n providerItems = provider.getItemContextMenu?.(firstItem) || [];\n }\n } else {\n providerItems = provider.getMultiItemContextMenu?.(items) || [];\n }\n // Prepend extra menu items if provided\n if (extraMenuItems && extraMenuItems.length > 0) {\n setMenuItems([...extraMenuItems, ...providerItems]);\n } else {\n setMenuItems(providerItems);\n }\n setFocusedIndex(-1);\n setAdjustedPosition(position);\n }\n }, [isOpen, items, provider, position, extraMenuItems]);\n\n // AICODE-NOTE: Adjust position once the menu has rendered to keep within viewport\n useEffect(() => {\n if (!isOpen || !menuRef.current) return;\n\n const menu = menuRef.current;\n const rect = menu.getBoundingClientRect();\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n\n let left = position.x;\n let top = position.y;\n\n if (left + rect.width > vw - 8) {\n left = Math.max(8, position.x - rect.width);\n }\n if (top + rect.height > vh - 8) {\n top = Math.max(8, position.y - rect.height);\n }\n\n left = Math.max(8, Math.min(left, vw - rect.width - 8));\n top = Math.max(8, Math.min(top, vh - rect.height - 8));\n\n setAdjustedPosition({ x: left, y: top });\n }, [isOpen, menuItems, position]);\n\n // AICODE-NOTE: Close on click-outside, Escape, or scroll\n useEffect(() => {\n if (!isOpen) return;\n\n const handleClickOutside = (event: MouseEvent) => {\n if (menuRef.current && !menuRef.current.contains(event.target as Node)) {\n onClose();\n }\n };\n\n const handleKeyDown = (event: KeyboardEvent) => {\n switch (event.key) {\n case 'Escape':\n event.preventDefault();\n onClose();\n break;\n case 'ArrowDown': {\n event.preventDefault();\n const currentActionIdx = actionableIndices.indexOf(focusedIndex);\n const nextIdx = currentActionIdx < actionableIndices.length - 1\n ? actionableIndices[currentActionIdx + 1]\n : actionableIndices[0];\n if (nextIdx !== undefined) setFocusedIndex(nextIdx);\n break;\n }\n case 'ArrowUp': {\n event.preventDefault();\n const currentActionIdx = actionableIndices.indexOf(focusedIndex);\n const prevIdx = currentActionIdx > 0\n ? actionableIndices[currentActionIdx - 1]\n : actionableIndices[actionableIndices.length - 1];\n if (prevIdx !== undefined) setFocusedIndex(prevIdx);\n break;\n }\n case 'Enter': {\n event.preventDefault();\n const focused = menuItems[focusedIndex];\n if (focused && focused.type !== 'separator' && !focused.disabled) {\n handleMenuItemClick(focused);\n }\n break;\n }\n }\n };\n\n const handleScroll = () => onClose();\n\n // Use capture phase for mousedown so we close before other handlers fire\n document.addEventListener('mousedown', handleClickOutside, true);\n document.addEventListener('keydown', handleKeyDown);\n window.addEventListener('scroll', handleScroll, true);\n\n return () => {\n document.removeEventListener('mousedown', handleClickOutside, true);\n document.removeEventListener('keydown', handleKeyDown);\n window.removeEventListener('scroll', handleScroll, true);\n };\n }, [isOpen, onClose, focusedIndex, menuItems, actionableIndices]);\n\n // AICODE-NOTE: Handle menu item click — dispatch to extra handler or provider and close\n const handleMenuItemClick = useCallback((menuItem: ListContextMenuItem) => {\n if (extraMenuItems?.some(m => m.type !== 'separator' && m.id === menuItem.id) && onExtraMenuAction) {\n onExtraMenuAction(menuItem.id, items);\n } else if (provider.onContextMenuAction) {\n provider.onContextMenuAction(menuItem.id, items);\n }\n onClose();\n }, [provider, items, onClose, extraMenuItems, onExtraMenuAction]);\n\n if (!isOpen || menuItems.length === 0) {\n return null;\n }\n\n return (\n <div\n ref={menuRef}\n role=\"menu\"\n style={{\n position: 'fixed',\n left: adjustedPosition.x,\n top: adjustedPosition.y,\n zIndex: 50,\n }}\n className={[\n 'bg-popover text-popover-foreground',\n 'rounded-md border p-1 shadow-md',\n 'min-w-[180px] max-w-[260px]',\n 'animate-in fade-in-0 zoom-in-95',\n 'origin-top-left',\n ].join(' ')}\n >\n {menuItems.map((menuItem, index) => (\n <ContextMenuItemRow\n key={menuItem.type === 'separator' ? `sep-${index}` : menuItem.id}\n menuItem={menuItem}\n isFocused={focusedIndex === index}\n onMenuItemClick={handleMenuItemClick}\n onMouseEnter={() => setFocusedIndex(index)}\n />\n ))}\n </div>\n );\n});\n\nListContextMenu.displayName = 'ListContextMenu';\n","import React, { useCallback, useState } from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { FixedSizeList as List } from 'react-window';\nimport { ListItemsModel } from '../models/ListItemsModel';\nimport { ListItem } from './ListItem';\nimport { ListContextMenu } from './ListContextMenu';\n\nexport interface VirtualizedListProps {\n model: ListItemsModel;\n height: number;\n width?: number;\n className?: string;\n overscanCount?: number;\n}\n\ninterface ItemRendererProps {\n index: number;\n style: React.CSSProperties;\n data: {\n model: ListItemsModel;\n onItemClick: (item: any, event: React.MouseEvent) => void;\n onItemDoubleClick: (item: any, event: React.MouseEvent) => void;\n onItemContextMenu: (item: any, event: React.MouseEvent) => void;\n };\n}\n\nconst ItemRendererComponent = observer<ItemRendererProps>(({ index, style, data }) => {\n const { model, onItemClick, onItemDoubleClick, onItemContextMenu } = data;\n const item = model.items[index];\n\n if (!item) {\n return (\n <div style={style} className=\"flex items-center p-2 animate-pulse\">\n <div className=\"w-4 h-4 bg-muted rounded mr-2\" />\n <div className=\"flex-1 h-4 bg-muted rounded\" />\n </div>\n );\n }\n\n return (\n <div style={style}>\n <ListItem\n item={item}\n index={index}\n totalItems={model.totalItemCount}\n viewType={model.currentViewType}\n provider={model.provider}\n model={model}\n isSelected={model.isItemSelected(item.id)}\n isFocused={model.focusedItem === item.id}\n onClick={onItemClick}\n onDoubleClick={onItemDoubleClick}\n onContextMenu={onItemContextMenu}\n />\n </div>\n );\n});\n\nconst ItemRenderer = React.memo(ItemRendererComponent, (prevProps, nextProps) => {\n const prevItem = prevProps.data.model.items[prevProps.index];\n const nextItem = nextProps.data.model.items[nextProps.index];\n\n return (\n prevProps.index === nextProps.index &&\n prevItem?.id === nextItem?.id &&\n prevItem?.name === nextItem?.name &&\n prevItem?.modified?.getTime() === nextItem?.modified?.getTime() &&\n prevProps.data.model.isItemSelected(prevItem?.id || '') === nextProps.data.model.isItemSelected(nextItem?.id || '') &&\n prevProps.data.model.focusedItem === nextProps.data.model.focusedItem\n );\n});\n\nItemRenderer.displayName = 'VirtualizedListItemRenderer';\n\nexport const VirtualizedList = observer<VirtualizedListProps>(({\n model,\n height,\n width = '100%',\n className = '',\n overscanCount = 5\n}) => {\n // Context menu state\n const [contextMenu, setContextMenu] = useState<{\n isOpen: boolean;\n position: { x: number; y: number };\n }>({ isOpen: false, position: { x: 0, y: 0 } });\n\n const handleItemClick = useCallback((item: any, event: React.MouseEvent) => {\n const modifiers = {\n ctrl: event.ctrlKey || event.metaKey,\n shift: event.shiftKey\n };\n model.selectItem(item, modifiers);\n }, [model]);\n\n const handleItemDoubleClick = useCallback((item: any, event: React.MouseEvent) => {\n if (model.provider.onItemDoubleClick) {\n model.provider.onItemDoubleClick(item);\n }\n }, [model]);\n\n const handleItemContextMenu = useCallback((item: any, event: React.MouseEvent) => {\n event.preventDefault();\n // Select item if not already selected\n if (!model.isItemSelected(item.id)) {\n model.selectItem(item);\n }\n setContextMenu({\n isOpen: true,\n position: { x: event.clientX, y: event.clientY }\n });\n }, [model]);\n\n const handleCloseContextMenu = useCallback(() => {\n setContextMenu(prev => ({ ...prev, isOpen: false }));\n }, []);\n\n const itemHeight = model.provider.getItemHeight(model.currentViewType);\n\n const itemData = {\n model,\n onItemClick: handleItemClick,\n onItemDoubleClick: handleItemDoubleClick,\n onItemContextMenu: handleItemContextMenu\n };\n\n return (\n <>\n <List\n className={className}\n height={height}\n width={width}\n itemCount={model.totalItemCount}\n itemSize={itemHeight}\n itemData={itemData}\n overscanCount={overscanCount}\n onItemsRendered={({ visibleStartIndex, visibleStopIndex }) => {\n model.updateViewportRange(visibleStartIndex, visibleStopIndex);\n }}\n >\n {ItemRenderer}\n </List>\n <ListContextMenu\n isOpen={contextMenu.isOpen}\n position={contextMenu.position}\n items={model.selectedItemsArray}\n provider={model.provider}\n onClose={handleCloseContextMenu}\n />\n </>\n );\n});\n\nVirtualizedList.displayName = 'VirtualizedList';\n","import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { FixedSizeList as List } from 'react-window';\nimport { Columns3 } from 'lucide-react';\nimport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuCheckboxItem,\n DropdownMenuSeparator,\n DropdownMenuLabel,\n} from '@anymux/ui/components/dropdown-menu';\nimport { ListItemsModel } from '../models/ListItemsModel';\nimport { ListItem } from './ListItem';\nimport { ListContextMenu } from './ListContextMenu';\n\nexport interface VirtualizedDetailsViewProps {\n model: ListItemsModel;\n height: number;\n width?: number;\n className?: string;\n overscanCount?: number;\n}\n\ninterface DetailsItemRendererProps {\n index: number;\n style: React.CSSProperties;\n data: {\n model: ListItemsModel;\n onItemClick: (item: any, event: React.MouseEvent) => void;\n onItemDoubleClick: (item: any, event: React.MouseEvent) => void;\n onItemContextMenu: (item: any, event: React.MouseEvent) => void;\n };\n}\n\nconst DetailsItemRenderer = observer<DetailsItemRendererProps>(({ index, style, data }) => {\n const { model, onItemClick, onItemDoubleClick, onItemContextMenu } = data;\n const item = model.items[index];\n\n if (!item) {\n return (\n <div style={{ ...style, gridTemplateColumns: model.detailsGridTemplateColumns, columnGap: 16 }} className=\"grid items-center px-4 py-1 animate-pulse\">\n <div className=\"h-4 w-4 bg-muted rounded\" />\n <div className=\"h-4 bg-muted rounded\" />\n {!model.compactMode && model.columnVisibility.type && <div className=\"h-4 bg-muted rounded\" />}\n {!model.compactMode && model.columnVisibility.modified && <div className=\"h-4 bg-muted rounded\" />}\n {!model.compactMode && model.columnVisibility.size && <div className=\"h-4 bg-muted rounded\" />}\n </div>\n );\n }\n\n return (\n <div style={style}>\n <ListItem\n item={item}\n index={index}\n totalItems={model.totalItemCount}\n viewType={model.currentViewType}\n provider={model.provider}\n model={model}\n isSelected={model.isItemSelected(item.id)}\n isFocused={model.focusedItem === item.id}\n onClick={onItemClick}\n onDoubleClick={onItemDoubleClick}\n onContextMenu={onItemContextMenu}\n />\n </div>\n );\n});\n\nDetailsItemRenderer.displayName = 'VirtualizedDetailsItemRenderer';\n\nexport const VirtualizedDetailsView = observer<VirtualizedDetailsViewProps>(({\n model,\n height,\n width = '100%',\n className = '',\n overscanCount = 5\n}) => {\n const handleItemClick = useCallback((item: any, event: React.MouseEvent) => {\n const modifiers = {\n ctrl: event.ctrlKey || event.metaKey,\n shift: event.shiftKey\n };\n model.selectItem(item, modifiers);\n }, [model]);\n\n const handleItemDoubleClick = useCallback((item: any, event: React.MouseEvent) => {\n if (model.provider.onItemDoubleClick) {\n model.provider.onItemDoubleClick(item);\n }\n }, [model]);\n\n // Context menu state\n const [contextMenu, setContextMenu] = useState<{\n isOpen: boolean;\n position: { x: number; y: number };\n }>({ isOpen: false, position: { x: 0, y: 0 } });\n\n const handleItemContextMenu = useCallback((item: any, event: React.MouseEvent) => {\n event.preventDefault();\n if (!model.isItemSelected(item.id)) {\n model.selectItem(item);\n }\n setContextMenu({\n isOpen: true,\n position: { x: event.clientX, y: event.clientY }\n });\n }, [model]);\n\n const handleCloseContextMenu = useCallback(() => {\n setContextMenu(prev => ({ ...prev, isOpen: false }));\n }, []);\n\n const itemHeight = model.provider.getItemHeight(model.currentViewType);\n const headerHeight = 40;\n\n const itemData = {\n model,\n onItemClick: handleItemClick,\n onItemDoubleClick: handleItemDoubleClick,\n onItemContextMenu: handleItemContextMenu\n };\n\n return (\n <div className={`${className}`} style={{ height, width }}>\n {/* Fixed header — same CSS grid as ListItem details rows */}\n <div\n className=\"grid items-center bg-background border-b px-4 text-sm font-medium text-muted-foreground\"\n style={{ gridTemplateColumns: model.detailsGridTemplateColumns, columnGap: 16, height: headerHeight }}\n >\n {model.showCheckboxes && (\n <div className=\"flex items-center justify-center\">\n <input\n type=\"checkbox\"\n checked={model.items.length > 0 && model.selectedItems.size === model.items.length}\n ref={(el) => {\n if (el) el.indeterminate = model.selectedItems.size > 0 && model.selectedItems.size < model.items.length;\n }}\n onChange={() => {\n if (model.selectedItems.size === model.items.length) {\n model.clearSelection();\n } else {\n model.selectAll();\n }\n }}\n className=\"h-3.5 w-3.5 rounded border-muted-foreground/50 accent-primary cursor-pointer\"\n aria-label=\"Select all\"\n />\n </div>\n )}\n <div>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button className=\"flex items-center justify-center hover:text-foreground transition-colors\" aria-label=\"Toggle columns\">\n <Columns3 className=\"size-4\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\">\n <DropdownMenuLabel>Columns</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuCheckboxItem\n checked={!model.compactMode && model.columnVisibility.type}\n onCheckedChange={(checked) => {\n if (model.compactMode) model.setCompactMode(false);\n model.setColumnVisibility('type', !!checked);\n }}\n >\n Type\n </DropdownMenuCheckboxItem>\n <DropdownMenuCheckboxItem\n checked={!model.compactMode && model.columnVisibility.modified}\n onCheckedChange={(checked) => {\n if (model.compactMode) model.setCompactMode(false);\n model.setColumnVisibility('modified', !!checked);\n }}\n >\n Modified\n </DropdownMenuCheckboxItem>\n <DropdownMenuCheckboxItem\n checked={!model.compactMode && model.columnVisibility.size}\n onCheckedChange={(checked) => {\n if (model.compactMode) model.setCompactMode(false);\n model.setColumnVisibility('size', !!checked);\n }}\n >\n Size\n </DropdownMenuCheckboxItem>\n <DropdownMenuSeparator />\n <DropdownMenuCheckboxItem\n checked={model.compactMode}\n onCheckedChange={(checked) => model.setCompactMode(!!checked)}\n >\n Compact\n </DropdownMenuCheckboxItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n <div>Name</div>\n {!model.compactMode && model.columnVisibility.type && <div>Type</div>}\n {!model.compactMode && model.columnVisibility.modified && <div>Modified</div>}\n {!model.compactMode && model.columnVisibility.size && <div className=\"text-right\">Size</div>}\n </div>\n\n {/* Virtualized content */}\n <List\n height={height - headerHeight}\n width={width}\n itemCount={model.totalItemCount}\n itemSize={itemHeight}\n itemData={itemData}\n overscanCount={overscanCount}\n onItemsRendered={({ visibleStartIndex, visibleStopIndex }) => {\n model.updateViewportRange(visibleStartIndex, visibleStopIndex);\n }}\n >\n {DetailsItemRenderer}\n </List>\n\n <ListContextMenu\n isOpen={contextMenu.isOpen}\n position={contextMenu.position}\n items={model.selectedItemsArray}\n provider={model.provider}\n onClose={handleCloseContextMenu}\n />\n </div>\n );\n});\n\nVirtualizedDetailsView.displayName = 'VirtualizedDetailsView';\n","import React from 'react';\nimport { ListItemsModel } from '../models/ListItemsModel';\n\n// AICODE-NOTE: Keyboard navigation utility for list components\n\nexport interface KeyboardNavigationOptions {\n enableArrowKeys?: boolean;\n enableHomeEnd?: boolean;\n enableSpaceEnter?: boolean;\n enableSelectAll?: boolean;\n enableEscape?: boolean;\n enablePageUpDown?: boolean;\n}\n\nexport class ListKeyboardHandler {\n private model: ListItemsModel;\n private options: Required<KeyboardNavigationOptions>;\n private isAttached: boolean = false;\n\n constructor(model: ListItemsModel, options: KeyboardNavigationOptions = {}) {\n this.model = model;\n this.options = {\n enableArrowKeys: true,\n enableHomeEnd: true,\n enableSpaceEnter: true,\n enableSelectAll: true,\n enableEscape: true,\n enablePageUpDown: true,\n ...options\n };\n }\n\n /**\n * Attach keyboard event listeners\n */\n attach(element?: HTMLElement): void {\n if (this.isAttached) return;\n \n const target = element || document;\n target.addEventListener('keydown', this.handleKeyDown as EventListener);\n this.isAttached = true;\n }\n\n /**\n * Detach keyboard event listeners\n */\n detach(element?: HTMLElement): void {\n if (!this.isAttached) return;\n \n const target = element || document;\n target.removeEventListener('keydown', this.handleKeyDown as EventListener);\n this.isAttached = false;\n }\n\n /**\n * Main keyboard event handler\n */\n private handleKeyDown = (event: Event): void => {\n const keyboardEvent = event as KeyboardEvent;\n\n // Skip when an input/textarea is focused (e.g. inline rename)\n const tag = (keyboardEvent.target as HTMLElement)?.tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA') return;\n\n // AICODE-NOTE: Only handle keyboard events when list has focus or items\n if (this.model.items.length === 0) return;\n\n const { key, ctrlKey, metaKey, shiftKey } = keyboardEvent;\n const isModifierPressed = ctrlKey || metaKey;\n\n // AICODE-NOTE: Handle different keyboard shortcuts\n switch (key) {\n case 'ArrowUp':\n if (this.options.enableArrowKeys) {\n keyboardEvent.preventDefault();\n this.handleArrowUp(shiftKey);\n }\n break;\n\n case 'ArrowDown':\n if (this.options.enableArrowKeys) {\n keyboardEvent.preventDefault();\n this.handleArrowDown(shiftKey);\n }\n break;\n\n case 'ArrowLeft':\n if (this.options.enableArrowKeys && this.model.currentViewType.id === 'grid') {\n keyboardEvent.preventDefault();\n this.handleArrowLeft(shiftKey);\n }\n break;\n\n case 'ArrowRight':\n if (this.options.enableArrowKeys && this.model.currentViewType.id === 'grid') {\n keyboardEvent.preventDefault();\n this.handleArrowRight(shiftKey);\n }\n break;\n\n case 'Home':\n if (this.options.enableHomeEnd) {\n keyboardEvent.preventDefault();\n this.handleHome(shiftKey);\n }\n break;\n\n case 'End':\n if (this.options.enableHomeEnd) {\n keyboardEvent.preventDefault();\n this.handleEnd(shiftKey);\n }\n break;\n\n case 'PageUp':\n if (this.options.enablePageUpDown) {\n keyboardEvent.preventDefault();\n this.handlePageUp(shiftKey);\n }\n break;\n\n case 'PageDown':\n if (this.options.enablePageUpDown) {\n keyboardEvent.preventDefault();\n this.handlePageDown(shiftKey);\n }\n break;\n\n case ' ': // Space\n if (this.options.enableSpaceEnter) {\n keyboardEvent.preventDefault();\n this.handleSpace(shiftKey);\n }\n break;\n\n case 'Enter':\n if (this.options.enableSpaceEnter) {\n keyboardEvent.preventDefault();\n this.handleEnter();\n }\n break;\n\n case 'a':\n case 'A':\n if (this.options.enableSelectAll && isModifierPressed) {\n keyboardEvent.preventDefault();\n this.handleSelectAll();\n }\n break;\n\n case 'Escape':\n if (this.options.enableEscape) {\n keyboardEvent.preventDefault();\n this.handleEscape();\n }\n break;\n }\n };\n\n /**\n * Handle arrow up navigation\n */\n private handleArrowUp(shiftKey: boolean): void {\n if (this.model.currentViewType.id === 'grid') {\n this.handleGridArrowUp(shiftKey);\n } else {\n this.handleListArrowUp(shiftKey);\n }\n }\n\n /**\n * Handle arrow down navigation\n */\n private handleArrowDown(shiftKey: boolean): void {\n if (this.model.currentViewType.id === 'grid') {\n this.handleGridArrowDown(shiftKey);\n } else {\n this.handleListArrowDown(shiftKey);\n }\n }\n\n /**\n * Handle arrow left navigation (grid view)\n */\n private handleArrowLeft(shiftKey: boolean): void {\n const currentIndex = this.getCurrentFocusedIndex();\n if (currentIndex > 0) {\n this.navigateToIndex(currentIndex - 1, shiftKey);\n }\n }\n\n /**\n * Handle arrow right navigation (grid view)\n */\n private handleArrowRight(shiftKey: boolean): void {\n const currentIndex = this.getCurrentFocusedIndex();\n if (currentIndex < this.model.items.length - 1) {\n this.navigateToIndex(currentIndex + 1, shiftKey);\n }\n }\n\n /**\n * Handle list view arrow up\n */\n private handleListArrowUp(shiftKey: boolean): void {\n const currentIndex = this.getCurrentFocusedIndex();\n if (currentIndex > 0) {\n this.navigateToIndex(currentIndex - 1, shiftKey);\n }\n }\n\n /**\n * Handle list view arrow down\n */\n private handleListArrowDown(shiftKey: boolean): void {\n const currentIndex = this.getCurrentFocusedIndex();\n if (currentIndex < this.model.items.length - 1) {\n this.navigateToIndex(currentIndex + 1, shiftKey);\n }\n }\n\n /**\n * Handle grid view arrow up (move up by grid columns)\n */\n private handleGridArrowUp(shiftKey: boolean): void {\n const currentIndex = this.getCurrentFocusedIndex();\n const columnsPerRow = this.getGridColumnsPerRow();\n const newIndex = Math.max(0, currentIndex - columnsPerRow);\n this.navigateToIndex(newIndex, shiftKey);\n }\n\n /**\n * Handle grid view arrow down (move down by grid columns)\n */\n private handleGridArrowDown(shiftKey: boolean): void {\n const currentIndex = this.getCurrentFocusedIndex();\n const columnsPerRow = this.getGridColumnsPerRow();\n const newIndex = Math.min(this.model.items.length - 1, currentIndex + columnsPerRow);\n this.navigateToIndex(newIndex, shiftKey);\n }\n\n /**\n * Handle Home key - go to first item\n */\n private handleHome(shiftKey: boolean): void {\n this.navigateToIndex(0, shiftKey);\n }\n\n /**\n * Handle End key - go to last item\n */\n private handleEnd(shiftKey: boolean): void {\n this.navigateToIndex(this.model.items.length - 1, shiftKey);\n }\n\n /**\n * Handle Page Up - move up by visible page size\n */\n private handlePageUp(shiftKey: boolean): void {\n const currentIndex = this.getCurrentFocusedIndex();\n const pageSize = this.getPageSize();\n const newIndex = Math.max(0, currentIndex - pageSize);\n this.navigateToIndex(newIndex, shiftKey);\n }\n\n /**\n * Handle Page Down - move down by visible page size\n */\n private handlePageDown(shiftKey: boolean): void {\n const currentIndex = this.getCurrentFocusedIndex();\n const pageSize = this.getPageSize();\n const newIndex = Math.min(this.model.items.length - 1, currentIndex + pageSize);\n this.navigateToIndex(newIndex, shiftKey);\n }\n\n /**\n * Handle Space key - toggle selection of focused item\n */\n private handleSpace(shiftKey: boolean): void {\n const focusedItem = this.getFocusedItem();\n if (focusedItem) {\n this.model.selectItem(focusedItem, { ctrl: true, shift: shiftKey });\n }\n }\n\n /**\n * Handle Enter key - activate focused item\n */\n private handleEnter(): void {\n const focusedItem = this.getFocusedItem();\n if (focusedItem && this.model.provider.onItemDoubleClick) {\n this.model.provider.onItemDoubleClick(focusedItem);\n }\n }\n\n /**\n * Handle Ctrl+A - select all items\n */\n private handleSelectAll(): void {\n this.model.selectAll();\n }\n\n /**\n * Handle Escape - clear selection first, then navigate up one directory\n */\n private handleEscape(): void {\n if (this.model.hasSelection) {\n this.model.clearSelection();\n } else if (this.model.provider.onNavigateUp) {\n this.model.provider.onNavigateUp();\n }\n }\n\n /**\n * Navigate to specific index with optional range selection\n */\n private navigateToIndex(index: number, extendSelection: boolean = false): void {\n const item = this.model.items[index];\n if (!item) return;\n\n // Update focused item\n this.model.setFocusedItem(item.id);\n\n // Handle selection based on shift key\n if (extendSelection && this.model.provider.isMultiSelectEnabled) {\n // Shift+arrow: extend range selection from anchor\n if (!this.model.selectionAnchor) {\n // Set anchor if not already set\n this.model.selectionAnchor = this.model.focusedItem || item.id;\n }\n this.model.selectRange(this.model.selectionAnchor, item.id);\n } else {\n // Plain arrow: single selection, reset anchor\n this.model.selectItem(item);\n }\n\n // Ensure item is visible\n this.model.ensureItemVisible(item.id);\n }\n\n /**\n * Get current focused item index\n */\n private getCurrentFocusedIndex(): number {\n if (!this.model.focusedItem) {\n return 0;\n }\n return this.model.getItemIndex(this.model.focusedItem);\n }\n\n /**\n * Get currently focused item\n */\n private getFocusedItem() {\n if (!this.model.focusedItem) {\n // AICODE-NOTE: If no item is focused, focus the first item\n if (this.model.items.length > 0) {\n const firstItem = this.model.items[0];\n if (firstItem) {\n this.model.setFocusedItem(firstItem.id);\n return firstItem;\n }\n }\n return null;\n }\n const item = this.model.getItem(this.model.focusedItem);\n return item || null;\n }\n\n /**\n * Get number of columns per row in grid view\n */\n private getGridColumnsPerRow(): number {\n // AICODE-NOTE: Default to 4 columns, could be made configurable\n return 4;\n }\n\n /**\n * Get page size for page up/down navigation\n */\n private getPageSize(): number {\n // AICODE-NOTE: Default to 10 items per page, could be calculated from viewport\n return 10;\n }\n}\n\n/**\n * Hook for using keyboard navigation in React components\n */\nexport const useListKeyboard = (\n model: ListItemsModel,\n options?: KeyboardNavigationOptions,\n containerRef?: React.RefObject<HTMLElement | HTMLDivElement | null>\n) => {\n const keyboardHandler = React.useMemo(\n () => new ListKeyboardHandler(model, options),\n [model, options]\n );\n\n React.useEffect(() => {\n const element = containerRef?.current;\n if (element) {\n keyboardHandler.attach(element);\n }\n\n return () => {\n if (element) {\n keyboardHandler.detach(element);\n }\n };\n }, [keyboardHandler, containerRef]);\n\n return keyboardHandler;\n}; ","import React, { useEffect } from 'react';\nimport { observer } from 'mobx-react-lite';\nimport type { ListItemsModel } from '../models/ListItemsModel';\nimport type { ListItemData } from '../types/ListTypes';\nimport type { MasonryItemPosition } from '../utils/MasonryLayoutEngine';\n\n// AICODE-NOTE: Simplified masonry view showing only images without labels\n// Supports both horizontal and vertical masonry layouts with proper aspect ratio handling\n\ninterface MasonryViewProps {\n model: ListItemsModel;\n items: ListItemData[];\n containerWidth: number;\n containerHeight: number;\n isHorizontal?: boolean; // true for horizontal masonry, false for vertical\n}\n\ninterface MasonryItemProps {\n item: ListItemData;\n position: MasonryItemPosition;\n model: ListItemsModel;\n onClick: (item: ListItemData) => void;\n onDoubleClick: (item: ListItemData) => void;\n}\n\nconst MasonryItem: React.FC<MasonryItemProps> = observer(({ item, position, model, onClick, onDoubleClick }) => {\n const isSelected = model.isItemSelected(item.id);\n const isFocused = model.focusedItem === item.id;\n // Resolve blob URL from provider cache (reactive — re-renders when ready)\n const thumbnailUrl = item.thumbnailUrl ? model.resolveThumbnailUrl(item) : undefined;\n\n const handleClick = (e: React.MouseEvent) => {\n e.preventDefault();\n onClick(item);\n };\n\n const handleDoubleClick = (e: React.MouseEvent) => {\n e.preventDefault();\n onDoubleClick(item);\n };\n\n const debugStyles = model.debugVisualization ? {\n border: '2px solid lightcyan',\n boxSizing: 'border-box' as const\n } : {};\n\n return (\n <div\n style={{\n position: 'absolute',\n left: position.x,\n top: position.y,\n width: position.width,\n height: position.height,\n cursor: 'pointer',\n backgroundColor: isSelected ? 'rgba(0, 123, 255, 0.1)' : 'transparent',\n borderRadius: model.debugVisualization ? '0px' : '2px',\n overflow: 'hidden',\n transition: 'background-color 0.15s ease, box-shadow 0.15s ease',\n boxShadow: isSelected\n ? '0 0 0 2px rgba(0, 123, 255, 0.5)'\n : 'none',\n ...debugStyles\n }}\n onClick={handleClick}\n onDoubleClick={handleDoubleClick}\n data-item-id={item.id}\n >\n {thumbnailUrl ? (\n <>\n <img\n src={thumbnailUrl}\n alt={item.name}\n style={{\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n display: 'block',\n pointerEvents: 'none',\n ...(model.debugVisualization ? { border: '1px solid lightblue' } : {})\n }}\n loading=\"lazy\"\n />\n \n {/* Overlay label at the bottom */}\n <div\n style={{\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n background: 'linear-gradient(to top, rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0.3), transparent)',\n color: 'white',\n padding: '12px 8px 8px 8px',\n fontSize: '12px',\n fontWeight: '500',\n textAlign: 'left',\n lineHeight: '1.3',\n maxHeight: '40px',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n pointerEvents: 'none',\n ...(model.debugVisualization ? { border: '1px solid yellow' } : {})\n }}\n >\n {item.name}\n </div>\n </>\n ) : (\n // Fallback for items without thumbnails\n <div\n style={{\n width: '100%',\n height: '100%',\n backgroundColor: '#f0f0f0',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '24px',\n color: '#888',\n position: 'relative',\n ...(model.debugVisualization ? { border: '1px solid orange' } : {})\n }}\n >\n <div>📄</div>\n {/* Label for non-image items */}\n <div\n style={{\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n background: 'rgba(0, 0, 0, 0.6)',\n color: 'white',\n padding: '8px',\n fontSize: '11px',\n fontWeight: '500',\n textAlign: 'center',\n lineHeight: '1.3',\n maxHeight: '32px',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n pointerEvents: 'none'\n }}\n >\n {item.name}\n </div>\n </div>\n )}\n </div>\n );\n});\n\nexport const MasonryView: React.FC<MasonryViewProps> = observer(({ \n model, \n items, \n containerWidth, \n containerHeight,\n isHorizontal = false \n}) => {\n // Update container size in model via effect (not during render)\n useEffect(() => {\n if (containerWidth > 0 && containerHeight > 0) {\n model.updateContainerSize(containerWidth, containerHeight);\n }\n }, [model, containerWidth, containerHeight]);\n\n // Calculate masonry layout directly (no useMemo — MobX observer tracks dependencies)\n // The useEffect above sets containerSize, which triggers updateLayoutCalculators\n // and creates the masonry engines. MobX observer re-renders when those change.\n let masonryLayout: { layout: MasonryItemPosition[]; totalHeight: number } = { layout: [], totalHeight: 0 };\n\n if (items.length > 0 && containerWidth > 0 && model.containerSize.width > 0) {\n const result = isHorizontal\n ? model.getHorizontalMasonryLayout()\n : model.getVerticalMasonryLayout();\n\n if (result) {\n masonryLayout = result;\n }\n }\n\n const handleItemClick = (item: ListItemData) => {\n model.selectItem(item);\n };\n\n const handleItemDoubleClick = (item: ListItemData) => {\n if (model.provider.onItemDoubleClick) {\n model.provider.onItemDoubleClick(item);\n }\n };\n\n if (items.length === 0) {\n return (\n <div style={{ \n width: '100%', \n height: '100%', \n display: 'flex', \n alignItems: 'center', \n justifyContent: 'center',\n color: '#6c757d',\n fontSize: '16px'\n }}>\n No items to display\n </div>\n );\n }\n\n return (\n <div\n style={{\n position: 'relative',\n width: '100%',\n maxWidth: containerWidth,\n height: masonryLayout.totalHeight\n }}\n >\n {masonryLayout.layout.map((position) => {\n const item = items.find(i => i.id === position.id);\n if (!item) return null;\n\n return (\n <MasonryItem\n key={item.id}\n item={item}\n position={position}\n model={model}\n onClick={handleItemClick}\n onDoubleClick={handleItemDoubleClick}\n />\n );\n })}\n </div>\n );\n});\n\nMasonryItem.displayName = 'MasonryItem';\nMasonryView.displayName = 'MasonryView'; ","import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { observer } from 'mobx-react-lite';\nimport type { ListItemsModel } from '../models/ListItemsModel';\nimport type { ListItemData } from '../types/ListTypes';\nimport type { MasonryItemPosition } from '../utils/MasonryLayoutEngine';\n\n// AICODE-NOTE: Virtualized masonry view that only renders visible items for performance with large datasets\n// Uses viewport-based culling to handle thousands of items efficiently\n\ninterface VirtualizedMasonryViewProps {\n model: ListItemsModel;\n items: ListItemData[];\n containerWidth: number;\n containerHeight: number;\n isHorizontal?: boolean; // true for horizontal masonry, false for vertical\n overscanCount?: number; // Extra items to render outside viewport\n className?: string;\n}\n\ninterface MasonryItemProps {\n item: ListItemData;\n position: MasonryItemPosition;\n model: ListItemsModel;\n onClick: (item: ListItemData) => void;\n onDoubleClick: (item: ListItemData) => void;\n}\n\nconst MasonryItem: React.FC<MasonryItemProps> = observer(({ item, position, model, onClick, onDoubleClick }) => {\n const isSelected = model.isItemSelected(item.id);\n const isFocused = model.focusedItem === item.id;\n const thumbnailUrl = item.thumbnailUrl ? model.resolveThumbnailUrl(item) : undefined;\n\n const handleClick = (e: React.MouseEvent) => {\n e.preventDefault();\n onClick(item);\n };\n\n const handleDoubleClick = (e: React.MouseEvent) => {\n e.preventDefault();\n onDoubleClick(item);\n };\n\n const debugStyles = model.debugVisualization ? {\n border: '2px solid lightcyan',\n boxSizing: 'border-box' as const\n } : {};\n\n return (\n <div\n style={{\n position: 'absolute',\n left: position.x,\n top: position.y,\n width: position.width,\n height: position.height,\n cursor: 'pointer',\n backgroundColor: isSelected ? 'rgba(0, 123, 255, 0.1)' : 'transparent',\n borderRadius: model.debugVisualization ? '0px' : '2px',\n overflow: 'hidden',\n transition: 'background-color 0.15s ease, box-shadow 0.15s ease',\n boxShadow: isSelected\n ? '0 0 0 2px rgba(0, 123, 255, 0.5)'\n : 'none',\n ...debugStyles\n }}\n onClick={handleClick}\n onDoubleClick={handleDoubleClick}\n data-item-id={item.id}\n >\n {thumbnailUrl ? (\n <>\n <img\n src={thumbnailUrl}\n alt={item.name}\n style={{\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n display: 'block',\n ...(model.debugVisualization ? { border: '1px solid lightblue' } : {})\n }}\n loading=\"lazy\"\n />\n \n {/* Overlay label at the bottom */}\n <div\n style={{\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n background: 'linear-gradient(to top, rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0.3), transparent)',\n color: 'white',\n padding: '12px 8px 8px 8px',\n fontSize: '12px',\n fontWeight: '500',\n textAlign: 'left',\n lineHeight: '1.3',\n maxHeight: '40px',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n pointerEvents: 'none',\n ...(model.debugVisualization ? { border: '1px solid yellow' } : {})\n }}\n >\n {item.name}\n </div>\n </>\n ) : (\n // Fallback for items without thumbnails\n <div\n style={{\n width: '100%',\n height: '100%',\n backgroundColor: '#f0f0f0',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '24px',\n color: '#888',\n position: 'relative',\n ...(model.debugVisualization ? { border: '1px solid orange' } : {})\n }}\n >\n <div>📄</div>\n {/* Label for non-image items */}\n <div\n style={{\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n background: 'rgba(0, 0, 0, 0.6)',\n color: 'white',\n padding: '8px',\n fontSize: '11px',\n fontWeight: '500',\n textAlign: 'center',\n lineHeight: '1.3',\n maxHeight: '32px',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n pointerEvents: 'none'\n }}\n >\n {item.name}\n </div>\n </div>\n )}\n </div>\n );\n});\n\nexport const VirtualizedMasonryView: React.FC<VirtualizedMasonryViewProps> = observer(({ \n model, \n items, \n containerWidth, \n containerHeight,\n isHorizontal = false,\n overscanCount = 10,\n className = ''\n}) => {\n const scrollContainerRef = useRef<HTMLDivElement>(null);\n const [scrollTop, setScrollTop] = useState(0);\n\n // Update container size in model via effect (not during render)\n useEffect(() => {\n if (containerWidth > 0 && containerHeight > 0) {\n model.updateContainerSize(containerWidth, containerHeight);\n }\n }, [model, containerWidth, containerHeight]);\n\n // Calculate layout directly (MobX observer tracks dependencies)\n let masonryLayout: { layout: MasonryItemPosition[]; totalHeight: number } = { layout: [], totalHeight: 0 };\n\n if (items.length > 0 && containerWidth > 0 && model.containerSize.width > 0) {\n const result = isHorizontal\n ? model.getHorizontalMasonryLayout()\n : model.getVerticalMasonryLayout();\n\n if (result) {\n masonryLayout = result;\n }\n }\n\n // Calculate visible items for viewport culling\n let visibleItems: MasonryItemPosition[] = [];\n if (masonryLayout.layout.length > 0) {\n const overscan = overscanCount * 50;\n visibleItems = model.getVisibleMasonryItems(scrollTop, containerHeight, isHorizontal, overscan);\n }\n\n // AICODE-NOTE: Handle scroll events with throttling\n const handleScroll = useCallback(() => {\n const container = scrollContainerRef.current;\n if (!container) return;\n\n const newScrollTop = container.scrollTop;\n setScrollTop(newScrollTop);\n\n // Update model viewport range for potential dynamic loading\n const startIndex = Math.floor(newScrollTop / 200); // Rough estimate\n const endIndex = Math.min(items.length - 1, startIndex + Math.ceil(containerHeight / 200) + overscanCount);\n model.updateViewportRange(startIndex, endIndex);\n }, [containerHeight, items.length, overscanCount, model]);\n\n // AICODE-NOTE: Set up scroll listener with throttling\n useEffect(() => {\n const container = scrollContainerRef.current;\n if (!container) return;\n\n let ticking = false;\n const throttledScroll = () => {\n if (!ticking) {\n requestAnimationFrame(() => {\n handleScroll();\n ticking = false;\n });\n ticking = true;\n }\n };\n\n container.addEventListener('scroll', throttledScroll);\n \n // Calculate initial visible items\n handleScroll();\n\n return () => {\n container.removeEventListener('scroll', throttledScroll);\n };\n }, [handleScroll]);\n\n // Scroll to item when model requests it\n useEffect(() => {\n const targetId = model.scrollToItemId;\n if (!targetId || !scrollContainerRef.current) return;\n const el = scrollContainerRef.current.querySelector(`[data-item-id=\"${CSS.escape(targetId)}\"]`);\n if (el) {\n el.scrollIntoView({ block: 'nearest', behavior: 'smooth' });\n } else {\n // Item not rendered yet — find position from layout and scroll to it\n const pos = masonryLayout.layout.find(p => p.id === targetId);\n if (pos) {\n scrollContainerRef.current.scrollTop = Math.max(0, pos.y - containerHeight / 2);\n }\n }\n model.clearScrollToItem();\n }, [model.scrollToItemId, model, masonryLayout.layout, containerHeight]);\n\n // AICODE-NOTE: Handle item interactions\n const handleItemClick = useCallback((item: ListItemData) => {\n model.selectItem(item);\n }, [model]);\n\n const handleItemDoubleClick = useCallback((item: ListItemData) => {\n if (model.provider.onItemDoubleClick) {\n model.provider.onItemDoubleClick(item);\n }\n }, [model]);\n\n if (items.length === 0) {\n return (\n <div style={{ \n width: '100%', \n height: '100%', \n display: 'flex', \n alignItems: 'center', \n justifyContent: 'center',\n color: '#6c757d',\n fontSize: '16px'\n }}>\n No items to display\n </div>\n );\n }\n\n return (\n <div\n ref={scrollContainerRef}\n className={`overflow-y-auto overflow-x-hidden ${className}`}\n style={{\n width: containerWidth,\n height: containerHeight\n }}\n >\n {/* AICODE-NOTE: Container with total height for proper scrollbar */}\n <div\n style={{\n position: 'relative',\n width: containerWidth,\n height: Math.max(masonryLayout.totalHeight, containerHeight),\n overflow: 'hidden'\n }}\n >\n {/* AICODE-NOTE: Render only visible items */}\n {visibleItems.map((position) => {\n const item = items.find(i => i.id === position.id);\n if (!item) return null;\n\n return (\n <MasonryItem\n key={item.id}\n item={item}\n position={position}\n model={model}\n onClick={handleItemClick}\n onDoubleClick={handleItemDoubleClick}\n />\n );\n })}\n \n {/* AICODE-NOTE: Debug info when debug visualization is enabled */}\n {model.debugVisualization && (\n <div\n style={{\n position: 'fixed',\n top: 10,\n right: 10,\n background: 'rgba(0, 0, 0, 0.8)',\n color: 'white',\n padding: '8px 12px',\n borderRadius: '4px',\n fontSize: '12px',\n fontFamily: 'monospace',\n zIndex: 1000,\n pointerEvents: 'none'\n }}\n >\n <div>Total: {masonryLayout.layout.length}</div>\n <div>Visible: {visibleItems.length}</div>\n <div>Scroll: {Math.round(scrollTop)}px</div>\n <div>Height: {Math.round(masonryLayout.totalHeight)}px</div>\n </div>\n )}\n </div>\n </div>\n );\n});\n\nMasonryItem.displayName = 'MasonryItem';\nVirtualizedMasonryView.displayName = 'VirtualizedMasonryView'; ","import React from 'react';\nimport { observer } from 'mobx-react-lite';\nimport type { ListViewType } from '../../providers/ListItemsProvider';\n\n// AICODE-NOTE: Skeleton loader component for list items during loading\nexport interface ListLoaderProps {\n viewType: ListViewType;\n itemCount?: number;\n itemWidth?: number;\n itemHeight?: number;\n className?: string;\n}\n\nconst ListLoaderComponent: React.FC<ListLoaderProps> = ({\n viewType,\n itemCount = 12,\n itemWidth = 200,\n itemHeight = 140,\n className = ''\n}) => {\n // AICODE-NOTE: Generate skeleton items based on view type\n const skeletonItems = Array.from({ length: itemCount }, (_, index) => (\n <SkeletonItem\n key={index}\n viewType={viewType}\n itemWidth={itemWidth}\n itemHeight={itemHeight}\n />\n ));\n\n // AICODE-NOTE: Container styles based on view type\n const getContainerClasses = () => {\n switch (viewType.id) {\n case 'grid':\n case 'masonry-horizontal':\n case 'masonry-vertical':\n return `grid gap-3 p-4 ${className}`;\n case 'details':\n return `divide-y ${className}`;\n default:\n return `divide-y ${className}`;\n }\n };\n\n const getContainerStyle = () => {\n if (viewType.id === 'grid' || viewType.id.includes('masonry')) {\n return {\n gridTemplateColumns: 'repeat(auto-fill, minmax(160px, 1fr))'\n };\n }\n return {};\n };\n\n return (\n <div className={getContainerClasses()} style={getContainerStyle()}>\n {skeletonItems}\n </div>\n );\n};\n\n// AICODE-NOTE: Individual skeleton item component\ninterface SkeletonItemProps {\n viewType: ListViewType;\n itemWidth: number;\n itemHeight: number;\n}\n\nconst SkeletonItem: React.FC<SkeletonItemProps> = ({\n viewType,\n itemWidth,\n itemHeight\n}) => {\n // AICODE-NOTE: Base skeleton classes with animation\n const baseSkeletonClasses = \"animate-pulse bg-muted rounded\";\n \n // AICODE-NOTE: Grid/Masonry skeleton layout\n if (viewType.id === 'grid' || viewType.id.includes('masonry')) {\n return (\n <div \n className=\"flex flex-col items-center justify-start p-3 rounded-lg border border-transparent min-h-[140px]\"\n style={{ width: itemWidth }}\n >\n {/* AICODE-NOTE: Image/icon skeleton */}\n <div \n className={`${baseSkeletonClasses} mb-2 flex-1`}\n style={{ \n width: itemWidth - 24, \n height: itemHeight - 60,\n minHeight: '80px'\n }}\n />\n \n {/* AICODE-NOTE: Title skeleton */}\n <div className=\"w-full space-y-1\">\n <div className={`${baseSkeletonClasses} h-4 w-3/4 mx-auto`} />\n <div className={`${baseSkeletonClasses} h-3 w-1/2 mx-auto`} />\n </div>\n \n {/* AICODE-NOTE: Metadata skeleton */}\n <div className={`${baseSkeletonClasses} h-3 w-16 mt-1`} />\n </div>\n );\n }\n\n // AICODE-NOTE: Details view skeleton layout\n if (viewType.id === 'details') {\n return (\n <div className=\"flex items-center gap-4 p-2\">\n {/* AICODE-NOTE: Icon skeleton */}\n <div className={`${baseSkeletonClasses} w-4 h-4 flex-shrink-0`} />\n \n {/* AICODE-NOTE: Name column skeleton */}\n <div className={`${baseSkeletonClasses} h-4 flex-1`} />\n \n {/* AICODE-NOTE: Type column skeleton */}\n <div className={`${baseSkeletonClasses} h-4 w-24`} />\n \n {/* AICODE-NOTE: Modified column skeleton */}\n <div className={`${baseSkeletonClasses} h-4 w-32`} />\n \n {/* AICODE-NOTE: Size column skeleton */}\n <div className={`${baseSkeletonClasses} h-4 w-20`} />\n </div>\n );\n }\n\n // AICODE-NOTE: Default list view skeleton layout\n return (\n <div className=\"flex items-center gap-3 p-2\">\n {/* AICODE-NOTE: Icon skeleton */}\n <div className={`${baseSkeletonClasses} w-4 h-4 flex-shrink-0`} />\n \n {/* AICODE-NOTE: Content skeleton */}\n <div className=\"flex-1 min-w-0 space-y-1\">\n <div className={`${baseSkeletonClasses} h-4 w-3/4`} />\n <div className={`${baseSkeletonClasses} h-3 w-1/2`} />\n </div>\n \n {/* AICODE-NOTE: Metadata skeleton */}\n <div className={`${baseSkeletonClasses} h-3 w-16 flex-shrink-0`} />\n </div>\n );\n};\n\n// AICODE-NOTE: Export memoized component for performance\nexport const ListLoader = observer(ListLoaderComponent); ","import React from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { ErrorDisplay as UIErrorDisplay } from '@anymux/ui/components/error-display';\n\nconst sizeMap = { small: 'sm', medium: 'md', large: 'lg' } as const;\n\nexport interface ErrorDisplayProps {\n error: Error | string;\n title?: string;\n message?: string;\n onRetry?: () => void;\n onDismiss?: () => void;\n className?: string;\n size?: 'small' | 'medium' | 'large';\n variant?: 'default' | 'destructive' | 'warning';\n}\n\nconst ErrorDisplayComponent: React.FC<ErrorDisplayProps> = ({\n error,\n title = 'Error',\n message,\n onRetry,\n onDismiss,\n className = '',\n size = 'medium',\n variant = 'destructive'\n}) => {\n const mappedSize = sizeMap[size];\n const mappedVariant = variant === 'default' ? undefined : variant;\n\n // If message override is provided, create a modified error preserving stack\n let mappedError: Error | string = error;\n if (message) {\n if (typeof error === 'object') {\n mappedError = Object.assign(new Error(message), { stack: error.stack });\n } else {\n mappedError = message;\n }\n }\n\n return (\n <UIErrorDisplay\n error={mappedError}\n title={title}\n size={mappedSize}\n variant={mappedVariant}\n showDetails={typeof error === 'object' && !!error.stack}\n className={className}\n {...(onRetry != null ? { onRetry } : {})}\n {...(onDismiss != null ? { onDismiss } : {})}\n />\n );\n};\n\nexport interface NetworkErrorProps {\n onRetry?: () => void;\n className?: string;\n}\n\nconst NetworkErrorComponent: React.FC<NetworkErrorProps> = ({\n onRetry,\n className = ''\n}) => {\n return (\n <ErrorDisplayComponent\n error=\"Network request failed\"\n title=\"Connection Error\"\n message=\"Unable to load items. Please check your internet connection and try again.\"\n variant=\"warning\"\n className={className}\n {...(onRetry != null ? { onRetry } : {})}\n />\n );\n};\n\nexport interface LoadErrorProps {\n error: Error | string;\n onRetry?: () => void;\n className?: string;\n}\n\nconst LoadErrorComponent: React.FC<LoadErrorProps> = ({\n error,\n onRetry,\n className = ''\n}) => {\n return (\n <ErrorDisplayComponent\n error={error}\n title=\"Failed to Load Items\"\n variant=\"destructive\"\n className={className}\n {...(onRetry != null ? { onRetry } : {})}\n />\n );\n};\n\nexport const ErrorDisplay = observer(ErrorDisplayComponent);\nexport const NetworkError = observer(NetworkErrorComponent);\nexport const LoadError = observer(LoadErrorComponent);\n","import React from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { EmptyState as UIEmptyState } from '@anymux/ui/components/empty-state';\n\nconst SIZE_MAP = { small: 'sm', medium: 'md', large: 'lg' } as const;\n\nexport interface EmptyStateProps {\n title?: string;\n message?: string;\n icon?: React.ReactNode;\n actions?: React.ReactNode;\n className?: string;\n size?: 'small' | 'medium' | 'large';\n}\n\nconst EmptyStateComponent: React.FC<EmptyStateProps> = ({\n title = 'No items found',\n message = 'There are no items to display.',\n icon,\n actions,\n className = '',\n size = 'medium',\n}) => {\n return (\n <UIEmptyState\n preset=\"generic\"\n title={title}\n description={message}\n icon={icon}\n size={SIZE_MAP[size]}\n className={className}\n >\n {actions && <div className=\"mt-6\">{actions}</div>}\n </UIEmptyState>\n );\n};\n\nexport interface NoItemsProps {\n onRefresh?: () => void;\n className?: string;\n}\n\nconst NoItemsComponent: React.FC<NoItemsProps> = ({ onRefresh, className = '' }) => {\n return (\n <UIEmptyState\n preset=\"empty-folder\"\n title=\"No items found\"\n description=\"This folder appears to be empty.\"\n {...(onRefresh ? { action: { label: 'Refresh', onClick: onRefresh } } : {})}\n className={className}\n />\n );\n};\n\nexport interface NoSearchResultsProps {\n searchQuery?: string;\n onClearSearch?: () => void;\n className?: string;\n}\n\nconst NoSearchResultsComponent: React.FC<NoSearchResultsProps> = ({\n searchQuery,\n onClearSearch,\n className = '',\n}) => {\n const message = searchQuery\n ? `No items match \"${searchQuery}\". Try adjusting your search terms.`\n : 'No items match your search criteria.';\n\n return (\n <UIEmptyState\n preset=\"no-results\"\n title=\"No search results\"\n description={message}\n {...(onClearSearch ? { action: { label: 'Clear Search', onClick: onClearSearch } } : {})}\n className={className}\n />\n );\n};\n\nexport interface NoSelectionProps {\n message?: string;\n className?: string;\n}\n\nconst NoSelectionComponent: React.FC<NoSelectionProps> = ({\n message = 'Select items to see details and available actions.',\n className = '',\n}) => {\n return (\n <UIEmptyState\n preset=\"no-selection\"\n description={message}\n size=\"sm\"\n className={className}\n />\n );\n};\n\nexport const EmptyState = observer(EmptyStateComponent);\nexport const NoItems = observer(NoItemsComponent);\nexport const NoSearchResults = observer(NoSearchResultsComponent);\nexport const NoSelection = observer(NoSelectionComponent);\n","// AICODE-NOTE: Benchmark logging utility for performance monitoring and optimization\n\nexport interface BenchmarkResult {\n operation: string;\n duration: number;\n timestamp: number;\n metadata?: Record<string, any>;\n}\n\nexport interface BenchmarkReport {\n totalOperations: number;\n totalDuration: number;\n averageDuration: number;\n slowestOperation: BenchmarkResult | null;\n fastestOperation: BenchmarkResult | null;\n operations: BenchmarkResult[];\n}\n\nexport class BenchmarkLogger {\n private results: BenchmarkResult[] = [];\n private activeTimers = new Map<string, number>();\n private enabled: boolean = true;\n\n constructor(enabled: boolean = true) {\n this.enabled = enabled;\n }\n\n /**\n * Start timing an operation\n */\n start(operation: string, metadata?: Record<string, any>): void {\n if (!this.enabled) return;\n \n const startTime = performance.now();\n this.activeTimers.set(operation, startTime);\n \n if (metadata) {\n console.log(`🚀 [BENCHMARK] Starting: ${operation}`, metadata);\n } else {\n console.log(`🚀 [BENCHMARK] Starting: ${operation}`);\n }\n }\n\n /**\n * End timing an operation and log the result\n */\n end(operation: string, metadata?: Record<string, any>): number {\n if (!this.enabled) return 0;\n \n const startTime = this.activeTimers.get(operation);\n if (!startTime) {\n console.warn(`⚠️ [BENCHMARK] No start time found for operation: ${operation}`);\n return 0;\n }\n\n const endTime = performance.now();\n const duration = endTime - startTime;\n \n const result: BenchmarkResult = {\n operation,\n duration,\n timestamp: Date.now(),\n metadata\n };\n \n this.results.push(result);\n this.activeTimers.delete(operation);\n \n // Color-coded logging based on duration\n const color = this.getDurationColor(duration);\n const formattedDuration = this.formatDuration(duration);\n \n if (metadata) {\n console.log(`${color} [BENCHMARK] Completed: ${operation} in ${formattedDuration}`, metadata);\n } else {\n console.log(`${color} [BENCHMARK] Completed: ${operation} in ${formattedDuration}`);\n }\n \n return duration;\n }\n\n /**\n * Time a synchronous operation\n */\n time<T>(operation: string, fn: () => T, metadata?: Record<string, any>): T {\n this.start(operation, metadata);\n try {\n const result = fn();\n this.end(operation, metadata);\n return result;\n } catch (error) {\n this.end(operation, { ...metadata, error: error instanceof Error ? error.message : String(error) });\n throw error;\n }\n }\n\n /**\n * Time an asynchronous operation\n */\n async timeAsync<T>(operation: string, fn: () => Promise<T>, metadata?: Record<string, any>): Promise<T> {\n this.start(operation, metadata);\n try {\n const result = await fn();\n this.end(operation, metadata);\n return result;\n } catch (error) {\n this.end(operation, { ...metadata, error: error instanceof Error ? error.message : String(error) });\n throw error;\n }\n }\n\n /**\n * Get a performance report\n */\n getReport(): BenchmarkReport {\n if (this.results.length === 0) {\n return {\n totalOperations: 0,\n totalDuration: 0,\n averageDuration: 0,\n slowestOperation: null,\n fastestOperation: null,\n operations: []\n };\n }\n\n const totalDuration = this.results.reduce((sum, result) => sum + result.duration, 0);\n const averageDuration = totalDuration / this.results.length;\n \n const sortedByDuration = [...this.results].sort((a, b) => a.duration - b.duration);\n const fastestOperation = sortedByDuration[0] || null;\n const slowestOperation = sortedByDuration[sortedByDuration.length - 1] || null;\n\n return {\n totalOperations: this.results.length,\n totalDuration,\n averageDuration,\n slowestOperation,\n fastestOperation,\n operations: [...this.results]\n };\n }\n\n /**\n * Log a performance report\n */\n logReport(): void {\n if (!this.enabled) return;\n \n const report = this.getReport();\n \n console.group('📊 [BENCHMARK] Performance Report');\n console.log(`Total Operations: ${report.totalOperations}`);\n console.log(`Total Duration: ${this.formatDuration(report.totalDuration)}`);\n console.log(`Average Duration: ${this.formatDuration(report.averageDuration)}`);\n \n if (report.slowestOperation) {\n console.log(`Slowest: ${report.slowestOperation.operation} (${this.formatDuration(report.slowestOperation.duration)})`);\n }\n \n if (report.fastestOperation) {\n console.log(`Fastest: ${report.fastestOperation.operation} (${this.formatDuration(report.fastestOperation.duration)})`);\n }\n \n // Group operations by name\n const operationGroups = this.groupOperationsByName(report.operations);\n console.log('\\n📈 Operations Summary:');\n \n Object.entries(operationGroups).forEach(([name, operations]) => {\n const avgDuration = operations.reduce((sum, op) => sum + op.duration, 0) / operations.length;\n console.log(` ${name}: ${operations.length}x, avg ${this.formatDuration(avgDuration)}`);\n });\n \n console.groupEnd();\n }\n\n /**\n * Clear all benchmark results\n */\n clear(): void {\n this.results = [];\n this.activeTimers.clear();\n }\n\n /**\n * Enable or disable benchmarking\n */\n setEnabled(enabled: boolean): void {\n this.enabled = enabled;\n }\n\n /**\n * Check if benchmarking is enabled\n */\n isEnabled(): boolean {\n return this.enabled;\n }\n\n private getDurationColor(duration: number): string {\n if (duration < 1) return '🟢'; // Green - very fast\n if (duration < 10) return '🟡'; // Yellow - fast\n if (duration < 50) return '🟠'; // Orange - moderate\n return '🔴'; // Red - slow\n }\n\n private formatDuration(duration: number): string {\n if (duration < 1) {\n return `${duration.toFixed(3)}ms`;\n } else if (duration < 1000) {\n return `${duration.toFixed(1)}ms`;\n } else {\n return `${(duration / 1000).toFixed(2)}s`;\n }\n }\n\n private groupOperationsByName(operations: BenchmarkResult[]): Record<string, BenchmarkResult[]> {\n return operations.reduce((groups, operation) => {\n const name = operation.operation;\n if (!groups[name]) {\n groups[name] = [];\n }\n groups[name].push(operation);\n return groups;\n }, {} as Record<string, BenchmarkResult[]>);\n }\n}\n\n// AICODE-NOTE: Global benchmark logger instance\nexport const benchmarkLogger = new BenchmarkLogger(\n typeof window !== 'undefined' && \n (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1')\n);\n\n// AICODE-NOTE: Convenience functions for common benchmarking patterns\nexport const benchmark = {\n start: (operation: string, metadata?: Record<string, any>) => benchmarkLogger.start(operation, metadata),\n end: (operation: string, metadata?: Record<string, any>) => benchmarkLogger.end(operation, metadata),\n time: <T>(operation: string, fn: () => T, metadata?: Record<string, any>) => benchmarkLogger.time(operation, fn, metadata),\n timeAsync: <T>(operation: string, fn: () => Promise<T>, metadata?: Record<string, any>) => benchmarkLogger.timeAsync(operation, fn, metadata),\n report: () => benchmarkLogger.logReport(),\n clear: () => benchmarkLogger.clear(),\n setEnabled: (enabled: boolean) => benchmarkLogger.setEnabled(enabled)\n}; ","import React, { useEffect, useRef, useState, useCallback } from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { ListItemsModel } from '../models/ListItemsModel';\nimport { ListItem } from './ListItem';\nimport type { GridItemLayout } from '../utils/GridLayoutCalculator';\nimport type { ListItemData } from '../types/ListTypes';\n\n// AICODE-NOTE: Grid view component using precise calculator-based positioning\nexport interface CalculatedGridViewProps {\n model: ListItemsModel;\n className?: string;\n height?: number;\n width?: number;\n enableVirtualization?: boolean;\n onItemClick?: (item: ListItemData, event: React.MouseEvent) => void;\n onItemDoubleClick?: (item: ListItemData, event: React.MouseEvent) => void;\n onItemContextMenu?: (item: ListItemData, event: React.MouseEvent) => void;\n onItemDragStart?: (item: ListItemData, event: React.DragEvent) => void;\n onItemDragOver?: (item: ListItemData, event: React.DragEvent) => void;\n onItemDragLeave?: (item: ListItemData, event: React.DragEvent) => void;\n onItemDrop?: (item: ListItemData, event: React.DragEvent) => void;\n}\n\n// AICODE-NOTE: Extract grid item into separate observer component for MobX reactivity\ninterface GridItemWrapperProps {\n item: ListItemData;\n layout: GridItemLayout;\n index: number;\n model: ListItemsModel;\n onItemClick?: (item: ListItemData, event: React.MouseEvent) => void;\n onItemDoubleClick?: (item: ListItemData, event: React.MouseEvent) => void;\n onItemContextMenu?: (item: ListItemData, event: React.MouseEvent) => void;\n onItemDragStart?: (item: ListItemData, event: React.DragEvent) => void;\n onItemDragOver?: (item: ListItemData, event: React.DragEvent) => void;\n onItemDragLeave?: (item: ListItemData, event: React.DragEvent) => void;\n onItemDrop?: (item: ListItemData, event: React.DragEvent) => void;\n}\n\nconst GridItemWrapper = observer<GridItemWrapperProps>(({\n item,\n layout,\n index,\n model,\n onItemClick,\n onItemDoubleClick,\n onItemContextMenu,\n onItemDragStart,\n onItemDragOver,\n onItemDragLeave,\n onItemDrop\n}) => (\n <div\n data-item-id={item.id}\n style={{\n position: 'absolute',\n left: layout.x,\n top: layout.y,\n width: layout.width,\n height: layout.height\n }}\n >\n <ListItem\n item={item}\n index={index}\n totalItems={model.totalItemCount}\n viewType={model.currentViewType}\n provider={model.provider}\n model={model}\n itemWidth={layout.width}\n itemHeight={layout.height}\n thumbnailSize={layout.thumbnailSize}\n isSelected={model.isItemSelected(item.id)}\n isFocused={model.focusedItem === item.id}\n isDraggedOver={model.dragOverItem === item.id}\n dragOverPosition={model.dragOverItem === item.id ? model.dragOverPosition : null}\n canDrag={model.canDragItem(item)}\n onClick={onItemClick}\n onDoubleClick={onItemDoubleClick}\n onContextMenu={onItemContextMenu}\n onDragStart={onItemDragStart}\n onDragOver={onItemDragOver}\n onDragLeave={onItemDragLeave}\n onDrop={onItemDrop}\n />\n </div>\n));\n\nGridItemWrapper.displayName = 'CalculatedGridItemWrapper';\n\nconst CalculatedGridViewComponent: React.FC<CalculatedGridViewProps> = ({\n model,\n className = '',\n height,\n width,\n enableVirtualization = true,\n onItemClick,\n onItemDoubleClick,\n onItemContextMenu,\n onItemDragStart,\n onItemDragOver,\n onItemDragLeave,\n onItemDrop\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const [scrollTop, setScrollTop] = useState(0);\n // AICODE-NOTE: Initialize with provided dimensions so first render doesn't flash at 0x0\n const [containerSize, setContainerSize] = useState({ width: width || 0, height: height || 0 });\n const [hasMeasured, setHasMeasured] = useState(!!(width && height));\n\n // AICODE-NOTE: Update container size when dimensions change\n useEffect(() => {\n const updateSize = () => {\n if (containerRef.current) {\n const rect = containerRef.current.getBoundingClientRect();\n const newSize = {\n width: width || rect.width,\n height: height || rect.height\n };\n setContainerSize(newSize);\n setHasMeasured(true);\n model.updateContainerSize(newSize.width, newSize.height);\n }\n };\n\n updateSize();\n \n // Set up resize observer\n const resizeObserver = new ResizeObserver(updateSize);\n if (containerRef.current) {\n resizeObserver.observe(containerRef.current);\n }\n\n return () => {\n resizeObserver.disconnect();\n };\n }, [width, height, model]);\n\n // AICODE-NOTE: Handle scroll for virtualization\n const handleScroll = useCallback(() => {\n if (containerRef.current) {\n setScrollTop(containerRef.current.scrollTop);\n }\n }, []);\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container || !enableVirtualization) return;\n\n let ticking = false;\n const throttledScroll = () => {\n if (!ticking) {\n requestAnimationFrame(() => {\n handleScroll();\n ticking = false;\n });\n ticking = true;\n }\n };\n\n container.addEventListener('scroll', throttledScroll);\n return () => {\n container.removeEventListener('scroll', throttledScroll);\n };\n }, [handleScroll, enableVirtualization]);\n\n // Scroll to item when model requests it\n useEffect(() => {\n const targetId = model.scrollToItemId;\n if (!targetId || !containerRef.current) return;\n const el = containerRef.current.querySelector(`[data-item-id=\"${CSS.escape(targetId)}\"]`);\n if (el) {\n el.scrollIntoView({ block: 'nearest', behavior: 'smooth' });\n }\n model.clearScrollToItem();\n }, [model.scrollToItemId, model]);\n\n // AICODE-NOTE: Don't render items until container has been measured to prevent 0→final size flash\n const gridLayout = model.getGridLayout();\n if (!gridLayout || !hasMeasured || containerSize.width === 0) {\n return (\n <div\n ref={containerRef}\n className={`relative overflow-auto ${className}`}\n style={{ height, width, overflowX: 'hidden' }}\n />\n );\n }\n\n const { layout: itemLayouts, totalHeight } = gridLayout;\n\n // AICODE-NOTE: Determine which items to render\n let visibleItems: Array<{ item: ListItemData; layout: GridItemLayout; index: number }> = [];\n\n if (enableVirtualization && containerSize.height > 0) {\n // Use virtualization - only render visible items\n const visibleLayouts = model.getVisibleGridItems(scrollTop, containerSize.height);\n visibleItems = visibleLayouts.map((layout, layoutIndex) => {\n // Find the actual item index from the layout position\n const itemIndex = itemLayouts.findIndex(l => l.x === layout.x && l.y === layout.y);\n const item = model.items[itemIndex];\n return item ? { item, layout, index: itemIndex } : null;\n }).filter(Boolean) as Array<{ item: ListItemData; layout: GridItemLayout; index: number }>;\n } else {\n // Render all items\n visibleItems = model.items.map((item, index) => {\n const layout = itemLayouts[index];\n return layout ? { item, layout, index } : null;\n }).filter(Boolean) as Array<{ item: ListItemData; layout: GridItemLayout; index: number }>;\n }\n\n // console.log('🎨 [CALCULATED GRID] Rendering', visibleItems.length, 'items out of', model.items.length, 'total');\n // console.log('📐 [GRID LAYOUT] Container:', containerSize, 'Total height:', totalHeight);\n\n return (\n <div \n ref={containerRef}\n className={`relative overflow-auto ${className}`}\n style={{ height, width, overflowX: 'hidden' }}\n >\n {/* AICODE-NOTE: Container with calculated total height and no horizontal overflow */}\n <div \n style={{ \n position: 'relative',\n height: totalHeight,\n width: '100%',\n maxWidth: containerSize.width || '100%',\n overflow: 'hidden'\n }}\n >\n {visibleItems.map(({ item, layout, index }) => (\n <GridItemWrapper\n key={item.id}\n item={item}\n layout={layout}\n index={index}\n model={model}\n onItemClick={onItemClick}\n onItemDoubleClick={onItemDoubleClick}\n onItemContextMenu={onItemContextMenu}\n onItemDragStart={onItemDragStart}\n onItemDragOver={onItemDragOver}\n onItemDragLeave={onItemDragLeave}\n onItemDrop={onItemDrop}\n />\n ))}\n </div>\n </div>\n );\n};\n\n// AICODE-NOTE: Export memoized component for performance\nexport const CalculatedGridView = observer(CalculatedGridViewComponent); ","import { makeAutoObservable } from 'mobx';\nimport type { ListItemData } from '../types/ListTypes';\n\n/**\n * Extension category color map.\n * Maps file extensions to RGBA colors for the cushion treemap renderer.\n */\nexport const EXTENSION_CATEGORIES: Record<string, [number, number, number, number]> = {\n // JavaScript/TypeScript — blue\n js: [49, 120, 198, 255],\n jsx: [49, 120, 198, 255],\n ts: [49, 120, 198, 255],\n tsx: [49, 120, 198, 255],\n mjs: [49, 120, 198, 255],\n cjs: [49, 120, 198, 255],\n // Styles — teal\n css: [21, 114, 182, 255],\n scss: [21, 114, 182, 255],\n less: [21, 114, 182, 255],\n sass: [21, 114, 182, 255],\n // Markup — orange\n html: [227, 79, 38, 255],\n xml: [227, 79, 38, 255],\n svg: [227, 79, 38, 255],\n vue: [227, 79, 38, 255],\n // Data — gray\n json: [107, 114, 128, 255],\n yaml: [107, 114, 128, 255],\n yml: [107, 114, 128, 255],\n toml: [107, 114, 128, 255],\n env: [107, 114, 128, 255],\n // Images — green\n png: [16, 185, 129, 255],\n jpg: [16, 185, 129, 255],\n jpeg: [16, 185, 129, 255],\n gif: [16, 185, 129, 255],\n webp: [16, 185, 129, 255],\n avif: [16, 185, 129, 255],\n ico: [16, 185, 129, 255],\n // Documents — purple\n md: [139, 92, 246, 255],\n txt: [139, 92, 246, 255],\n pdf: [139, 92, 246, 255],\n doc: [139, 92, 246, 255],\n docx: [139, 92, 246, 255],\n // Archives — amber\n zip: [245, 158, 11, 255],\n tar: [245, 158, 11, 255],\n gz: [245, 158, 11, 255],\n br: [245, 158, 11, 255],\n rar: [245, 158, 11, 255],\n '7z': [245, 158, 11, 255],\n};\n\n/** Default color for directories — lighter blue */\nconst DIRECTORY_COLOR: [number, number, number, number] = [96, 165, 250, 255];\n\n/** Default color for unknown file types — neutral gray */\nconst OTHER_COLOR: [number, number, number, number] = [156, 163, 175, 255];\n\n/** Color scheme category labels and CSS hex colors for the legend */\nexport const EXTENSION_LEGEND: Array<{ label: string; color: string }> = [\n { label: 'JS/TS', color: '#3178C6' },\n { label: 'Styles', color: '#1572B6' },\n { label: 'Markup', color: '#E34F26' },\n { label: 'Data', color: '#6B7280' },\n { label: 'Images', color: '#10B981' },\n { label: 'Docs', color: '#8B5CF6' },\n { label: 'Archives', color: '#F59E0B' },\n { label: 'Folders', color: '#60A5FA' },\n { label: 'Other', color: '#9CA3AF' },\n];\n\nexport type ColorScheme = 'extension' | 'size' | 'type';\n\n/**\n * Get the RGBA color for a file extension (used by the cushion treemap renderer).\n */\nexport function getColorForExtension(name: string, isDirectory: boolean): [number, number, number, number] {\n if (isDirectory) return DIRECTORY_COLOR;\n const ext = name.split('.').pop()?.toLowerCase() ?? '';\n return EXTENSION_CATEGORIES[ext] ?? OTHER_COLOR;\n}\n\n/**\n * Get the CSS hex color string for an extension (used by overlays/tooltips).\n */\nexport function getHexColorForExtension(name: string, isDirectory: boolean): string {\n const [r, g, b] = getColorForExtension(name, isDirectory);\n return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;\n}\n\n/**\n * Format bytes to a human-readable string.\n */\nexport function formatBytes(bytes: number): string {\n if (bytes === 0) return '0 B';\n const units = ['B', 'KB', 'MB', 'GB', 'TB'];\n const k = 1024;\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n const value = bytes / Math.pow(k, i);\n return `${value < 10 ? value.toFixed(1) : Math.round(value)} ${units[i]}`;\n}\n\n/**\n * Phase 1 TreemapModel — works with items already loaded in ListItemsModel.\n *\n * No worker scanning, no async. Computes layout from the flat items list,\n * using file `size` for proportional rectangles (directories get size=1).\n */\nexport class TreemapModel {\n // === Observable state ===\n\n /** Current zoom path within the treemap */\n zoomPath: string = '';\n\n /** Path of the hovered tile (for tooltip) */\n hoveredPath: string | null = null;\n\n /** Active color scheme */\n colorScheme: ColorScheme = 'extension';\n\n /** Whether to show file name labels on tiles */\n showLabels: boolean = true;\n\n /** Whether to show size labels on tiles */\n showSizes: boolean = true;\n\n /** Highlighted extension category label (e.g. 'JS/TS') for legend filtering */\n highlightedExtension: string | null = null;\n\n constructor() {\n makeAutoObservable(this);\n }\n\n // === Actions ===\n\n zoomIn(path: string): void {\n this.zoomPath = path;\n }\n\n zoomOut(): void {\n if (!this.zoomPath) return;\n const parts = this.zoomPath.split('/');\n parts.pop();\n this.zoomPath = parts.join('/');\n }\n\n resetZoom(): void {\n this.zoomPath = '';\n }\n\n setHoveredPath(path: string | null): void {\n this.hoveredPath = path;\n }\n\n setColorScheme(scheme: ColorScheme): void {\n this.colorScheme = scheme;\n }\n\n toggleLabels(): void {\n this.showLabels = !this.showLabels;\n }\n\n toggleSizes(): void {\n this.showSizes = !this.showSizes;\n }\n\n setHighlightedExtension(ext: string | null): void {\n this.highlightedExtension = this.highlightedExtension === ext ? null : ext;\n }\n\n // === Computed helpers ===\n\n get breadcrumbs(): Array<{ name: string; path: string }> {\n if (!this.zoomPath) return [];\n const parts = this.zoomPath.split('/').filter(Boolean);\n const result: Array<{ name: string; path: string }> = [];\n for (let i = 0; i < parts.length; i++) {\n result.push({\n name: parts[i]!,\n path: parts.slice(0, i + 1).join('/')\n });\n }\n return result;\n }\n\n /**\n * Get the RGBA color for a node based on the current color scheme.\n */\n getNodeColor(item: ListItemData): [number, number, number, number] {\n switch (this.colorScheme) {\n case 'extension':\n return getColorForExtension(item.name, !!item.isDirectory);\n case 'type':\n return item.isDirectory ? DIRECTORY_COLOR : [16, 185, 129, 255];\n case 'size':\n // Placeholder — would need maxSize context. Just use extension for now.\n return getColorForExtension(item.name, !!item.isDirectory);\n default:\n return OTHER_COLOR;\n }\n }\n}\n","import React, { useRef, useEffect, useMemo, useState } from 'react';\nimport { observer } from 'mobx-react-lite';\nimport {\n layoutSquarefy,\n createSurfaces,\n drawToImageData,\n Rectangle,\n} from '@cushiontreemap/core';\nimport type { INode, Color } from '@cushiontreemap/core';\nimport { ListItemsModel } from '../models/ListItemsModel';\nimport {\n TreemapModel,\n formatBytes,\n getColorForExtension,\n getHexColorForExtension,\n EXTENSION_LEGEND,\n EXTENSION_CATEGORIES,\n} from '../models/TreemapModel';\nimport type { ListItemData } from '../types/ListTypes';\nimport type { TreemapNodeData, TreemapScanProgress } from '../providers/ListItemsProvider';\n\n/** Node metadata for overlay tiles */\nexport interface TileInfo {\n path: string;\n name: string;\n size?: number;\n isDirectory: boolean;\n}\n\nexport interface TreemapViewProps {\n model: ListItemsModel;\n treemapModel: TreemapModel;\n width: number;\n height: number;\n className?: string;\n onTileContextMenu?: (info: TileInfo, event: React.MouseEvent) => void;\n onEmptyContextMenu?: (event: React.MouseEvent) => void;\n}\n\n/** Minimum pixel area for a tile to get an interactive overlay div */\nconst MIN_TILE_AREA = 50;\n\n/** Minimum dimensions for showing file name label */\nconst MIN_LABEL_WIDTH = 60;\nconst MIN_LABEL_HEIGHT = 24;\n\n/** Minimum dimensions for showing size label */\nconst MIN_SIZE_LABEL_WIDTH = 80;\nconst MIN_SIZE_LABEL_HEIGHT = 40;\n\n/** Base height for legend bar */\nconst LEGEND_HEIGHT = 28;\n\n/** Height for breadcrumb bar */\nconst BREADCRUMB_HEIGHT = 28;\n\n/**\n * Map extension category labels to their extension sets for legend highlighting.\n */\nconst CATEGORY_EXTENSIONS: Record<string, Set<string>> = {\n 'JS/TS': new Set(['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs']),\n 'Styles': new Set(['css', 'scss', 'less', 'sass']),\n 'Markup': new Set(['html', 'xml', 'svg', 'vue']),\n 'Data': new Set(['json', 'yaml', 'yml', 'toml', 'env']),\n 'Images': new Set(['png', 'jpg', 'jpeg', 'gif', 'webp', 'avif', 'ico']),\n 'Docs': new Set(['md', 'txt', 'pdf', 'doc', 'docx']),\n 'Archives': new Set(['zip', 'tar', 'gz', 'br', 'rar', '7z']),\n};\n\n/**\n * Check if a file matches a given extension category label.\n */\nfunction matchesExtensionCategory(name: string, isDirectory: boolean, category: string): boolean {\n if (category === 'Folders') return isDirectory;\n if (category === 'Other') {\n if (isDirectory) return false;\n const ext = name.split('.').pop()?.toLowerCase() ?? '';\n return !EXTENSION_CATEGORIES[ext];\n }\n const exts = CATEGORY_EXTENSIONS[category];\n if (!exts) return false;\n const ext = name.split('.').pop()?.toLowerCase() ?? '';\n return exts.has(ext);\n}\n\n/**\n * Compute recursive size for a TreemapNodeData (sum of all descendant file sizes).\n */\nfunction computeSize(node: TreemapNodeData): number {\n if (!node.isDirectory || !node.children || node.children.length === 0) {\n return node.size ?? 1;\n }\n return node.children.reduce((sum, child) => sum + computeSize(child), 0);\n}\n\n/**\n * Build an INode tree from recursive TreemapNodeData.\n * Directories become internal nodes with children; files become leaves.\n */\nfunction buildNestedTree(nodes: TreemapNodeData[]): {\n root: INode<string>;\n infoMap: Map<string, TileInfo>;\n} {\n const infoMap = new Map<string, TileInfo>();\n\n function convertNode(node: TreemapNodeData): INode<string> {\n const size = computeSize(node);\n infoMap.set(node.path, {\n path: node.path,\n name: node.name,\n size: node.size,\n isDirectory: node.isDirectory,\n });\n\n if (node.isDirectory && node.children && node.children.length > 0) {\n const children = node.children\n .map(child => convertNode(child))\n .filter(c => (c.value ?? 0) > 0)\n .sort((a, b) => (b.value ?? 0) - (a.value ?? 0));\n\n return {\n id: node.path,\n value: size,\n children: children.length > 0 ? children : undefined,\n };\n }\n\n return {\n id: node.path,\n value: size,\n };\n }\n\n const children = nodes\n .map(n => convertNode(n))\n .filter(c => (c.value ?? 0) > 0)\n .sort((a, b) => (b.value ?? 0) - (a.value ?? 0));\n\n const root: INode<string> = {\n id: '__root__',\n value: children.reduce((sum, c) => sum + (c.value ?? 0), 0),\n children,\n };\n\n return { root, infoMap };\n}\n\n/**\n * Build flat INode tree from ListItemData (fallback when no recursive data).\n */\nfunction buildFlatTree(items: ListItemData[]): {\n root: INode<string>;\n infoMap: Map<string, TileInfo>;\n} {\n const infoMap = new Map<string, TileInfo>();\n\n const children: INode<string>[] = items\n .filter(item => (item.size ?? 1) > 0)\n .map(item => {\n infoMap.set(item.id, {\n path: item.path,\n name: item.name,\n size: item.size,\n isDirectory: !!item.isDirectory,\n });\n return {\n id: item.id,\n value: item.size ?? 1,\n };\n })\n .sort((a, b) => (b.value ?? 0) - (a.value ?? 0));\n\n const root: INode<string> = {\n id: '__root__',\n value: children.reduce((sum, c) => sum + (c.value ?? 0), 0),\n children,\n };\n\n return { root, infoMap };\n}\n\n/**\n * Find a subtree's children in recursive TreemapNodeData by path.\n * Returns the children of the directory at the given path, or null if not found.\n */\nfunction findSubtree(nodes: TreemapNodeData[], path: string): TreemapNodeData[] | null {\n for (const node of nodes) {\n if (node.path === path && node.isDirectory && node.children) {\n return node.children;\n }\n if (node.children) {\n const found = findSubtree(node.children, path);\n if (found) return found;\n }\n }\n return null;\n}\n\n/** Find a node by ID in the INode tree */\nfunction findNode(node: INode<string>, id: string): INode<string> | null {\n if (node.id === id) return node;\n if (node.children) {\n for (const child of node.children) {\n const found = findNode(child, id);\n if (found) return found;\n }\n }\n return null;\n}\n\n/**\n * TreemapView — renders items from ListItemsModel as a cushion-shaded treemap.\n *\n * Uses @cushiontreemap/core to render to a canvas, with transparent overlaid\n * divs for click/hover interactivity.\n *\n * If the provider supports loadTreemapData(), shows recursive subdirectory content.\n */\nexport const TreemapView = observer<TreemapViewProps>(({\n model,\n treemapModel,\n width,\n height,\n className = '',\n onTileContextMenu,\n onEmptyContextMenu,\n}) => {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n\n // Recursive data loading\n const [recursiveData, setRecursiveData] = useState<TreemapNodeData[] | null>(null);\n const [loading, setLoading] = useState(false);\n const [scanProgress, setScanProgress] = useState<TreemapScanProgress | null>(null);\n\n useEffect(() => {\n if (!model.provider.loadTreemapData) return;\n let cancelled = false;\n setLoading(true);\n setScanProgress(null);\n treemapModel.resetZoom();\n model.provider.loadTreemapData((progress) => {\n if (!cancelled) setScanProgress({ ...progress });\n })\n .then(data => { if (!cancelled) setRecursiveData(data); })\n .catch(err => console.warn('[TreemapView] Failed to load recursive data:', err))\n .finally(() => { if (!cancelled) { setLoading(false); setScanProgress(null); } });\n return () => { cancelled = true; };\n }, [model.provider, model.items]); // reload when items change (path navigation)\n\n // Compute chrome height (legend + optional breadcrumb)\n const hasBreadcrumbs = treemapModel.breadcrumbs.length > 0;\n const chromeHeight = LEGEND_HEIGHT + (hasBreadcrumbs ? BREADCRUMB_HEIGHT : 0);\n\n // Compute available canvas dimensions (subtract chrome)\n const canvasWidth = Math.max(1, Math.floor(width));\n const canvasHeight = Math.max(1, Math.floor(height - chromeHeight));\n\n // When zoomed, find subtree from recursive data\n const effectiveData = useMemo(() => {\n if (!recursiveData || !treemapModel.zoomPath) return recursiveData;\n const subtree = findSubtree(recursiveData, treemapModel.zoomPath);\n return subtree ?? recursiveData;\n }, [recursiveData, treemapModel.zoomPath]);\n\n // Build the tree — prefer recursive data if available\n const { root, infoMap, rects } = useMemo(() => {\n const items = effectiveData ?? model.items;\n if ((!effectiveData && model.items.length === 0) || (effectiveData && effectiveData.length === 0)) {\n return {\n root: null,\n infoMap: new Map<string, TileInfo>(),\n rects: new Map<string, Rectangle>(),\n };\n }\n\n const { root: r, infoMap: im } = effectiveData\n ? buildNestedTree(effectiveData)\n : buildFlatTree(model.items);\n\n if (!r.children || r.children.length === 0) {\n return { root: null, infoMap: im, rects: new Map<string, Rectangle>() };\n }\n\n const rectMap = layoutSquarefy(r, canvasWidth, canvasHeight);\n return { root: r, infoMap: im, rects: rectMap };\n }, [effectiveData, model.items, canvasWidth, canvasHeight]);\n\n // Draw the cushion treemap to the canvas\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas || !root || rects.size === 0) return;\n\n canvas.width = canvasWidth;\n canvas.height = canvasHeight;\n\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n\n const imageData = ctx.createImageData(canvasWidth, canvasHeight);\n\n const surfaces = createSurfaces(root, rects);\n\n const getColor = (node: INode<string>): Color => {\n if (node.id === '__root__') return [128, 128, 128, 255];\n const info = infoMap.get(node.id);\n if (!info) return [156, 163, 175, 255];\n return getColorForExtension(info.name, info.isDirectory);\n };\n\n drawToImageData(root, rects, surfaces, imageData, getColor, {\n Ia: 40,\n Is: 215,\n Lx: 0.09759,\n Ly: 0.19518,\n Lz: 0.9759,\n });\n\n ctx.putImageData(imageData, 0, 0);\n\n // Draw border lines between tiles\n ctx.strokeStyle = 'rgba(0, 0, 0, 0.15)';\n ctx.lineWidth = 1;\n for (const [id, rect] of rects) {\n if (id === '__root__') continue;\n const x = Math.round(rect.x0) + 0.5;\n const y = Math.round(rect.y0) + 0.5;\n const w = Math.round(rect.x1 - rect.x0);\n const h = Math.round(rect.y1 - rect.y0);\n if (w > 2 && h > 2) {\n ctx.strokeRect(x, y, w, h);\n }\n }\n }, [root, rects, infoMap, canvasWidth, canvasHeight]);\n\n // Build overlay tile data — only for leaf nodes (visible tiles)\n const tiles = useMemo(() => {\n if (!root || rects.size === 0) return [];\n\n const result: Array<{\n id: string;\n info: TileInfo;\n x: number;\n y: number;\n w: number;\n h: number;\n }> = [];\n\n for (const [id, rect] of rects) {\n if (id === '__root__') continue;\n const info = infoMap.get(id);\n if (!info) continue;\n\n const x = rect.x0;\n const y = rect.y0;\n const w = rect.x1 - rect.x0;\n const h = rect.y1 - rect.y0;\n\n if (w * h < MIN_TILE_AREA) continue;\n\n // Skip internal nodes (directories with children that got subdivided)\n // Only show leaf nodes as interactive tiles\n const node = findNode(root, id);\n if (node && node.children && node.children.length > 0) continue;\n\n result.push({ id, info, x, y, w, h });\n }\n\n return result;\n }, [root, rects, infoMap]);\n\n // Event handlers\n const handleTileClick = (info: TileInfo, event: React.MouseEvent) => {\n // For directories, zoom in on single click (instead of navigating away)\n if (info.isDirectory) {\n treemapModel.zoomIn(info.path);\n return;\n }\n // For files, select\n const item = model.items.find(i => i.path === info.path || i.id === info.path);\n if (item) {\n model.selectItem(item, {\n ctrl: event.ctrlKey || event.metaKey,\n shift: event.shiftKey,\n });\n }\n };\n\n const handleTileDoubleClick = (info: TileInfo) => {\n if (!model.provider.onItemDoubleClick) return;\n const item = model.items.find(i => i.path === info.path || i.id === info.path);\n if (item) {\n model.provider.onItemDoubleClick(item);\n } else {\n // For recursive items not in the flat list, create a fake item\n const fakeItem: ListItemData = {\n id: info.path,\n name: info.name,\n path: info.path,\n type: info.isDirectory ? 'directory' : 'file',\n isDirectory: info.isDirectory,\n size: info.size,\n };\n model.provider.onItemDoubleClick(fakeItem);\n }\n };\n\n const handleTileContextMenu = (info: TileInfo, event: React.MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n onTileContextMenu?.(info, event);\n };\n\n const handleEmptyContextMenu = (event: React.MouseEvent) => {\n event.preventDefault();\n onEmptyContextMenu?.(event);\n };\n\n const handleTileMouseEnter = (id: string) => {\n treemapModel.setHoveredPath(id);\n };\n\n const handleTileMouseLeave = () => {\n treemapModel.setHoveredPath(null);\n };\n\n // Tooltip data\n const hoveredInfo = treemapModel.hoveredPath\n ? infoMap.get(treemapModel.hoveredPath)\n : null;\n const hoveredRect = treemapModel.hoveredPath\n ? rects.get(treemapModel.hoveredPath)\n : null;\n\n const totalSize = useMemo(() => root?.value ?? 0, [root]);\n\n // Extension highlighting\n const highlighted = treemapModel.highlightedExtension;\n\n if (loading) {\n return (\n <div className={`flex items-center justify-center text-muted-foreground ${className}`} style={{ width, height }}>\n <div className=\"flex flex-col items-center gap-3\">\n <div className=\"w-6 h-6 border-2 border-muted-foreground/40 border-t-muted-foreground rounded-full animate-spin\" />\n <p className=\"text-sm font-medium\">Scanning directories...</p>\n {scanProgress && (\n <div className=\"flex items-center gap-4 text-xs\">\n <span>{scanProgress.directoriesScanned} folders</span>\n <span>{scanProgress.filesFound} files</span>\n {scanProgress.totalSize > 0 && (\n <span>{formatBytes(scanProgress.totalSize)}</span>\n )}\n </div>\n )}\n </div>\n </div>\n );\n }\n\n if (model.items.length === 0 && !effectiveData) {\n return (\n <div className={`flex items-center justify-center text-muted-foreground ${className}`} style={{ width, height }}>\n <p className=\"text-sm\">No items to display</p>\n </div>\n );\n }\n\n return (\n <div className={`flex flex-col select-none ${className}`} style={{ width, height }}>\n {/* Legend bar — interactive: click to highlight extension category */}\n <div className=\"flex items-center gap-3 px-3 py-1 border-b bg-background/80 flex-shrink-0 overflow-x-auto\" style={{ height: LEGEND_HEIGHT }}>\n <span className=\"text-xs font-medium text-muted-foreground whitespace-nowrap\">Filter:</span>\n {EXTENSION_LEGEND.map(({ label, color }) => {\n const isActive = highlighted === label;\n return (\n <button\n key={label}\n type=\"button\"\n onClick={() => treemapModel.setHighlightedExtension(label)}\n className={`flex items-center gap-1 whitespace-nowrap rounded px-1 py-0.5 transition-colors ${\n isActive\n ? 'bg-accent ring-1 ring-accent-foreground/20'\n : 'hover:bg-accent/50'\n }`}\n >\n <div\n className=\"w-2.5 h-2.5 rounded-sm flex-shrink-0\"\n style={{ backgroundColor: color }}\n />\n <span className={`text-[10px] ${isActive ? 'text-foreground font-medium' : 'text-muted-foreground'}`}>\n {label}\n </span>\n </button>\n );\n })}\n <div className=\"ml-auto text-[10px] text-muted-foreground whitespace-nowrap\">\n {infoMap.size} items • {formatBytes(totalSize)}\n </div>\n </div>\n\n {/* Breadcrumb bar — only when zoomed */}\n {hasBreadcrumbs && (\n <div className=\"flex items-center gap-1 px-3 border-b bg-background/60 flex-shrink-0 overflow-x-auto\" style={{ height: BREADCRUMB_HEIGHT }}>\n <button\n type=\"button\"\n onClick={() => treemapModel.resetZoom()}\n className=\"text-[11px] text-primary hover:underline\"\n >\n Root\n </button>\n {treemapModel.breadcrumbs.map((crumb) => (\n <React.Fragment key={crumb.path}>\n <span className=\"text-[10px] text-muted-foreground\">/</span>\n <button\n type=\"button\"\n onClick={() => treemapModel.zoomIn(crumb.path)}\n className={`text-[11px] ${\n crumb.path === treemapModel.zoomPath\n ? 'text-foreground font-medium'\n : 'text-primary hover:underline'\n }`}\n >\n {crumb.name}\n </button>\n </React.Fragment>\n ))}\n </div>\n )}\n\n {/* Treemap canvas + overlay container */}\n <div\n className=\"relative flex-1 overflow-hidden\"\n style={{ width: canvasWidth, height: canvasHeight }}\n onContextMenu={handleEmptyContextMenu}\n >\n {/* Canvas layer — the cushion-shaded treemap */}\n <canvas\n ref={canvasRef}\n width={canvasWidth}\n height={canvasHeight}\n className=\"absolute inset-0\"\n style={{ imageRendering: 'auto' }}\n />\n\n {/* Interactive overlay layer */}\n {tiles.map(({ id, info, x, y, w, h }) => {\n const isSelected = model.isItemSelected(info.path);\n const isHovered = treemapModel.hoveredPath === id;\n const showLabel = w >= MIN_LABEL_WIDTH && h >= MIN_LABEL_HEIGHT;\n const showSize = w >= MIN_SIZE_LABEL_WIDTH && h >= MIN_SIZE_LABEL_HEIGHT;\n\n // Extension highlighting: dim non-matching tiles\n const isDimmed = highlighted != null && !matchesExtensionCategory(info.name, info.isDirectory, highlighted);\n\n return (\n <div\n key={id}\n className=\"absolute cursor-pointer\"\n style={{\n left: x,\n top: y,\n width: w,\n height: h,\n opacity: isDimmed ? 0.3 : 1,\n transition: 'opacity 0.15s ease',\n }}\n onClick={(e) => handleTileClick(info, e)}\n onDoubleClick={() => handleTileDoubleClick(info)}\n onContextMenu={(e) => handleTileContextMenu(info, e)}\n onMouseEnter={() => handleTileMouseEnter(id)}\n onMouseLeave={handleTileMouseLeave}\n aria-label={`${info.name}${info.size ? ` (${formatBytes(info.size)})` : ''}`}\n >\n {/* Selection / hover highlight */}\n {(isSelected || isHovered) && (\n <div\n className=\"absolute inset-0 pointer-events-none\"\n style={{\n backgroundColor: isSelected\n ? 'rgba(255, 255, 255, 0.25)'\n : 'rgba(255, 255, 255, 0.12)',\n outline: isSelected\n ? '2px solid rgba(59, 130, 246, 0.8)'\n : '1px solid rgba(255, 255, 255, 0.4)',\n outlineOffset: isSelected ? '-2px' : '-1px',\n zIndex: isSelected ? 2 : 1,\n }}\n />\n )}\n\n {/* Text label overlay */}\n {showLabel && treemapModel.showLabels && (\n <div\n className=\"absolute inset-0 flex flex-col items-center justify-center pointer-events-none overflow-hidden px-1\"\n style={{ zIndex: 3 }}\n >\n <span\n className=\"text-white font-medium truncate max-w-full text-center leading-tight\"\n style={{\n fontSize: w > 150 && h > 60 ? '12px' : '10px',\n textShadow: '0 1px 3px rgba(0,0,0,0.8), 0 0px 1px rgba(0,0,0,0.9)',\n }}\n >\n {info.name}\n </span>\n {showSize && treemapModel.showSizes && info.size != null && info.size > 0 && (\n <span\n className=\"text-white/80 truncate max-w-full text-center leading-tight\"\n style={{\n fontSize: '9px',\n textShadow: '0 1px 2px rgba(0,0,0,0.8)',\n }}\n >\n {formatBytes(info.size)}\n </span>\n )}\n </div>\n )}\n </div>\n );\n })}\n\n {/* Tooltip */}\n {hoveredInfo && hoveredRect && (\n <TreemapTooltip\n info={hoveredInfo}\n rect={hoveredRect}\n canvasWidth={canvasWidth}\n canvasHeight={canvasHeight}\n totalSize={totalSize}\n />\n )}\n </div>\n </div>\n );\n});\n\nTreemapView.displayName = 'TreemapView';\n\n/** Floating tooltip for hovered treemap tile */\nconst TreemapTooltip = observer<{\n info: TileInfo;\n rect: Rectangle;\n canvasWidth: number;\n canvasHeight: number;\n totalSize: number;\n}>(({ info, rect, canvasWidth, canvasHeight, totalSize }) => {\n const centerX = (rect.x0 + rect.x1) / 2;\n const centerY = rect.y0;\n\n const tooltipWidth = 200;\n const tooltipHeight = 80;\n\n let left = centerX - tooltipWidth / 2;\n let top = centerY - tooltipHeight - 8;\n\n if (left < 4) left = 4;\n if (left + tooltipWidth > canvasWidth - 4) left = canvasWidth - tooltipWidth - 4;\n if (top < 4) {\n top = rect.y1 + 8;\n }\n if (top + tooltipHeight > canvasHeight - 4) {\n top = canvasHeight - tooltipHeight - 4;\n }\n\n const ext = info.name.split('.').pop()?.toLowerCase() ?? '';\n const percentage = totalSize > 0 && info.size\n ? ((info.size / totalSize) * 100).toFixed(1)\n : null;\n const colorHex = getHexColorForExtension(info.name, info.isDirectory);\n\n return (\n <div\n className=\"absolute z-50 pointer-events-none rounded-md border bg-popover/95 px-3 py-2 shadow-lg backdrop-blur-sm\"\n style={{\n left,\n top,\n width: tooltipWidth,\n }}\n >\n <div className=\"flex items-center gap-2 mb-1\">\n <div\n className=\"w-2.5 h-2.5 rounded-sm flex-shrink-0\"\n style={{ backgroundColor: colorHex }}\n />\n <span className=\"text-xs font-medium text-foreground truncate\">{info.name}</span>\n </div>\n <div className=\"text-[10px] text-muted-foreground space-y-0.5\">\n <div className=\"flex justify-between\">\n <span>Type</span>\n <span>{info.isDirectory ? 'Directory' : (ext ? `.${ext}` : 'File')}</span>\n </div>\n {info.size != null && (\n <div className=\"flex justify-between\">\n <span>Size</span>\n <span>{formatBytes(info.size)}</span>\n </div>\n )}\n {percentage && (\n <div className=\"flex justify-between\">\n <span>Share</span>\n <span>{percentage}%</span>\n </div>\n )}\n </div>\n </div>\n );\n});\n\nTreemapTooltip.displayName = 'TreemapTooltip';\n","import type { \n ListItemData, \n ListLoadOptions, \n ListLoadResult, \n ListSelectionInfo,\n ListViewType as BaseListViewType,\n ListDragDropInfo,\n ListContextMenuItem,\n VirtualizationConfig\n} from '../types/ListTypes';\n\nexport interface ListItemsProviderListener {\n onItemsCountChanged(count: number): void;\n onItemChanged(itemIndex: number): void;\n}\n\n// AICODE-NOTE: Extended view type with additional properties for different view modes\nexport interface ListViewType extends BaseListViewType {\n // Inherits all properties from base type\n}\n\n// AICODE-NOTE: Built-in view types with extended properties\nexport const LIST_VIEW_TYPE: ListViewType = {\n id: \"list\",\n name: \"List\",\n icon: \"list\",\n itemsPerRow: 1,\n showDetails: false\n};\n\nexport const GRID_VIEW_TYPE: ListViewType = {\n id: \"grid\",\n name: \"Grid\",\n icon: \"grid\",\n itemsPerRow: 'auto',\n showThumbnails: true,\n thumbnailSizes: ['small', 'medium', 'large', 'extra-large']\n};\n\nexport const DETAILS_VIEW_TYPE: ListViewType = {\n id: \"details\",\n name: \"Details\",\n icon: \"table\",\n itemsPerRow: 1,\n showDetails: true,\n columns: ['name', 'size', 'modified', 'type']\n};\n\nexport const MASONRY_HORIZONTAL_VIEW_TYPE: ListViewType = {\n id: \"masonry-horizontal\",\n name: \"Masonry Horizontal\",\n icon: \"layout-grid\",\n itemsPerRow: 'auto',\n showThumbnails: true,\n thumbnailSizes: ['small', 'medium', 'large', 'extra-large']\n};\n\nexport const MASONRY_VERTICAL_VIEW_TYPE: ListViewType = {\n id: \"masonry-vertical\",\n name: \"Masonry Vertical\",\n icon: \"columns\",\n itemsPerRow: 'auto',\n showThumbnails: true,\n thumbnailSizes: ['small', 'medium', 'large', 'extra-large']\n};\n\nexport const TREEMAP_VIEW_TYPE: ListViewType = {\n id: \"treemap\",\n name: \"Treemap\",\n icon: \"square-stack\",\n itemsPerRow: 'auto',\n showDetails: false\n};\n\n/** Recursive tree node for treemap view */\nexport interface TreemapNodeData {\n name: string;\n path: string;\n size?: number;\n isDirectory: boolean;\n children?: TreemapNodeData[];\n}\n\n/** Progress info reported during recursive directory scan */\nexport interface TreemapScanProgress {\n directoriesScanned: number;\n filesFound: number;\n totalSize: number;\n}\n\n// AICODE-NOTE: Core provider interface with essential methods for MVP\nexport interface ListItemsProvider {\n // =====================\n // Basic Configuration\n // =====================\n \n /** Provider identifier */\n readonly id: string;\n \n /** Human-readable name */\n readonly name: string;\n \n /** Supported view types for this provider */\n readonly supportedViewTypes: ListViewType[];\n \n /** Whether multi-selection is enabled */\n readonly isMultiSelectEnabled: boolean;\n \n /** Whether virtualization is enabled */\n readonly isVirtualizationEnabled: boolean;\n \n // =====================\n // Data Loading Methods\n // =====================\n \n /**\n * Load items from the data source\n * @param options Loading options for filtering, sorting, pagination\n * @returns Promise resolving to loaded items\n */\n loadItems(options?: ListLoadOptions): Promise<ListLoadResult>;\n \n /**\n * Get total count of items (for virtualization)\n * @returns Promise resolving to total item count\n */\n getItemCount(): Promise<number>;\n \n /**\n * Load a specific range of items (for virtualization)\n * @param start Starting index\n * @param end Ending index\n * @returns Promise resolving to items in range\n */\n loadItemRange?(start: number, end: number): Promise<ListLoadResult>;\n \n /**\n * Refresh/reload items\n * @returns Promise resolving to refreshed items\n */\n refresh?(): Promise<ListLoadResult>;\n \n // =====================\n // View Configuration\n // =====================\n \n /**\n * Get item height for a specific view type (for virtualization)\n * @param viewType The view type to get height for\n * @returns Fixed height in pixels\n */\n getItemHeight(viewType: ListViewType): number;\n \n /**\n * Get item width for grid-based view types\n * @param viewType The view type to get width for\n * @returns Fixed width in pixels\n */\n getItemWidth?(viewType: ListViewType): number;\n \n /**\n * Get virtualization configuration\n * @returns Virtualization config object\n */\n getVirtualizationConfig?(): VirtualizationConfig;\n \n // =====================\n // Event Callbacks\n // =====================\n \n /**\n * Called when selection changes\n * @param selectionInfo Information about the selection change\n */\n onSelectionChange?(selectionInfo: ListSelectionInfo): void;\n \n /**\n * Called when view type changes\n * @param viewType New view type\n */\n onViewTypeChange?(viewType: ListViewType): void;\n \n /**\n * Called when an item is double-clicked\n * @param item The item that was double-clicked\n */\n onItemDoubleClick?(item: ListItemData): void;\n\n /**\n * Called when keyboard navigation requests going up one level (Escape key).\n * Providers that support hierarchical navigation should implement this.\n */\n onNavigateUp?(): void;\n \n // =====================\n // Legacy Listener Support\n // =====================\n \n addListener(listener: ListItemsProviderListener): void;\n removeListener(listener: ListItemsProviderListener): void;\n \n // =====================\n // Item Rendering\n // =====================\n \n /**\n * Get custom icon for an item\n * @param item Target item\n * @returns Icon identifier or React component\n */\n getItemIcon?(item: ListItemData): string | React.ComponentType<any>;\n\n /**\n * Resolve a thumbnail URL for an item. Providers with async thumbnail\n * loading return blob URLs from an observable cache — MobX observer\n * components re-render when the URL becomes available.\n */\n resolveThumbnailUrl?(item: ListItemData): string | undefined;\n\n /**\n * Get measured aspect ratio (width/height) for an item by path.\n * Used by masonry layout to size items correctly instead of using\n * deterministic random fallback ratios.\n */\n getAspectRatio?(path: string): number | undefined;\n \n // =====================\n // Treemap Data (recursive directory scan)\n // =====================\n\n /**\n * Load recursive directory data for treemap view.\n * Returns a nested tree of items including subfolder contents.\n * @param onProgress Optional callback reporting scan progress\n */\n loadTreemapData?(onProgress?: (progress: TreemapScanProgress) => void): Promise<TreemapNodeData[]>;\n\n // =====================\n // Context Menu Support (for future phases)\n // =====================\n \n /**\n * Get context menu items for a specific item\n * @param item Target item\n * @returns Array of context menu items\n */\n getItemContextMenu?(item: ListItemData): ListContextMenuItem[];\n \n /**\n * Get context menu items for multiple selected items\n * @param items Selected items\n * @returns Array of context menu items\n */\n getMultiItemContextMenu?(items: ListItemData[]): ListContextMenuItem[];\n\n /**\n * Get context menu items for empty space (no item right-clicked)\n * @returns Array of context menu items\n */\n getEmptySpaceContextMenu?(): ListContextMenuItem[];\n\n /**\n * Called when a context menu action is selected\n * @param menuItemId Menu item identifier\n * @param items Items the action applies to (empty array for empty-space actions)\n */\n onContextMenuAction?(menuItemId: string, items: ListItemData[]): void;\n \n // =====================\n // Drag and Drop Support\n // =====================\n \n /**\n * Whether drag and drop is enabled\n */\n readonly isDragDropEnabled?: boolean;\n \n /**\n * Check if an item can be dragged\n * @param item Item to check\n * @returns Whether the item can be dragged\n */\n canDragItem?(item: ListItemData): boolean;\n \n /**\n * Check if items can be dropped on a target\n * @param draggedItems Items being dragged\n * @param targetItem Target item (null for empty space)\n * @param position Drop position relative to target\n * @returns Whether the drop is allowed\n */\n canDropItems?(draggedItems: ListItemData[], targetItem: ListItemData | null, position: 'before' | 'after' | 'inside'): boolean;\n \n /**\n * Called when drag operation starts\n * @param draggedItems Items being dragged\n * @param event Original drag event\n */\n onDragStart?(draggedItems: ListItemData[], event: DragEvent): void;\n \n /**\n * Called when items are dropped\n * @param dragDropInfo Information about the drag and drop operation\n */\n onDrop?(dragDropInfo: ListDragDropInfo): void;\n \n /**\n * Called when drag operation ends (whether successful or not)\n * @param draggedItems Items that were being dragged\n * @param success Whether the drop was successful\n */\n onDragEnd?(draggedItems: ListItemData[], success: boolean): void;\n}","import React, { useEffect, useMemo, useRef, useState } from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { ListItemsModel } from '../models/ListItemsModel';\nimport { ListItem } from './ListItem';\nimport { VirtualizedList } from './VirtualizedList';\nimport { VirtualizedGrid } from './VirtualizedGrid';\nimport { VirtualizedDetailsView } from './VirtualizedDetailsView';\nimport { ListContextMenu } from './ListContextMenu';\nimport { useListKeyboard } from '../utils/ListKeyboard';\nimport { MasonryView } from './MasonryView';\nimport { VirtualizedMasonryView } from './VirtualizedMasonryView';\nimport { ListLoader } from './shared/ListLoader';\nimport { LoadError } from './shared/ErrorDisplay';\nimport { NoItems } from './shared/EmptyState';\nimport { SearchX } from 'lucide-react';\nimport { getListAccessibilityProps, announceToScreenReader, createLiveRegionAnnouncement } from '../utils/ListAccessibility';\nimport { benchmark } from '../utils/BenchmarkLogger';\nimport { CalculatedGridView } from './CalculatedGridView';\nimport { TreemapView } from './TreemapView';\nimport type { TileInfo } from './TreemapView';\nimport { TreemapModel } from '../models/TreemapModel';\nimport { LIST_VIEW_TYPE } from '../providers/ListItemsProvider';\nimport type { ListItemData, ListContextMenuItem } from '../types/ListTypes';\nimport {\n Pagination,\n PaginationContent,\n PaginationItem,\n PaginationLink,\n PaginationPrevious,\n PaginationNext,\n PaginationEllipsis,\n} from '@anymux/ui/components/pagination';\n\nconst ListPagination = observer<{ model: ListItemsModel }>(({ model }) => {\n if (model.totalPages <= 1) return null;\n\n const pages: (number | 'ellipsis')[] = [];\n const total = model.totalPages;\n const current = model.currentPage;\n\n pages.push(0);\n if (current > 2) pages.push('ellipsis');\n for (let i = Math.max(1, current - 1); i <= Math.min(total - 2, current + 1); i++) {\n pages.push(i);\n }\n if (current < total - 3) pages.push('ellipsis');\n if (total > 1) pages.push(total - 1);\n\n return (\n <Pagination className=\"py-2 border-t flex-shrink-0\">\n <PaginationContent>\n <PaginationItem>\n <PaginationPrevious\n onClick={(e) => { e.preventDefault(); model.prevPage(); }}\n className={model.hasPreviousPage ? 'cursor-pointer' : 'pointer-events-none opacity-50'}\n />\n </PaginationItem>\n {pages.map((page, i) =>\n page === 'ellipsis' ? (\n <PaginationItem key={`e${i}`}>\n <PaginationEllipsis />\n </PaginationItem>\n ) : (\n <PaginationItem key={page}>\n <PaginationLink\n isActive={page === current}\n onClick={(e) => { e.preventDefault(); model.goToPage(page); }}\n className=\"cursor-pointer\"\n >\n {page + 1}\n </PaginationLink>\n </PaginationItem>\n )\n )}\n <PaginationItem>\n <PaginationNext\n onClick={(e) => { e.preventDefault(); model.nextPage(); }}\n className={model.hasNextPage ? 'cursor-pointer' : 'pointer-events-none opacity-50'}\n />\n </PaginationItem>\n </PaginationContent>\n </Pagination>\n );\n});\n\n// AICODE-NOTE: Basic list container component that connects model with UI\n\nexport interface ListItemsProps {\n model: ListItemsModel;\n className?: string;\n style?: React.CSSProperties;\n height?: number;\n width?: number;\n enableVirtualization?: boolean;\n enableKeyboardNavigation?: boolean;\n}\n\nexport const ListItems = observer<ListItemsProps>(({\n model,\n className = '',\n style,\n height,\n width,\n enableVirtualization = true,\n enableKeyboardNavigation = true\n}) => {\n // AICODE-NOTE: Benchmark render performance\n benchmark.start('ListItems.render', {\n viewType: model.currentViewType.id,\n itemCount: model.items.length,\n enableVirtualization,\n hasSelection: model.hasSelection\n });\n // AICODE-NOTE: Container ref for keyboard navigation\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Auto-measure container size when width/height props are not provided\n const [measuredSize, setMeasuredSize] = useState({ w: 0, h: 0 });\n const resizeTimerRef = useRef<ReturnType<typeof setTimeout>>();\n\n useEffect(() => {\n if (width !== undefined && height !== undefined) return;\n const el = containerRef.current;\n if (!el) return;\n let isFirst = true;\n const ro = new ResizeObserver((entries) => {\n const entry = entries[0];\n if (!entry) return;\n const newW = Math.round(entry.contentRect.width);\n const newH = Math.round(entry.contentRect.height);\n if (isFirst) {\n // First measurement is immediate so layout renders correctly\n isFirst = false;\n setMeasuredSize({ w: newW, h: newH });\n return;\n }\n // Subsequent resize events are debounced\n clearTimeout(resizeTimerRef.current);\n resizeTimerRef.current = setTimeout(() => {\n setMeasuredSize({ w: newW, h: newH });\n }, 150);\n });\n ro.observe(el);\n return () => { ro.disconnect(); clearTimeout(resizeTimerRef.current); };\n }, [width, height]);\n\n const effectiveWidth = width ?? measuredSize.w || 800;\n const effectiveHeight = height ?? measuredSize.h || 600;\n\n // When no explicit dimensions, use CSS sizing; otherwise inline style\n const sizeStyle: React.CSSProperties | undefined =\n height !== undefined || width !== undefined\n ? { height, width }\n : undefined;\n const sizeClass = height === undefined ? 'h-full' : '';\n\n // AICODE-NOTE: Context menu state\n const [contextMenu, setContextMenu] = useState<{\n isOpen: boolean;\n position: { x: number; y: number };\n items: ListItemData[];\n }>({\n isOpen: false,\n position: { x: 0, y: 0 },\n items: []\n });\n\n // AICODE-NOTE: Set up keyboard navigation\n useListKeyboard(\n model,\n {\n enableArrowKeys: true,\n enableHomeEnd: true,\n enableSpaceEnter: true,\n enableSelectAll: true,\n enableEscape: true,\n enablePageUpDown: true\n },\n enableKeyboardNavigation ? containerRef : undefined\n );\n\n // Scroll to item for list/details views (grid/masonry handle it themselves)\n useEffect(() => {\n const targetId = model.scrollToItemId;\n if (!targetId || !containerRef.current) return;\n const viewType = model.currentViewType.id;\n if (viewType === 'grid' || viewType.includes('masonry')) return; // handled by grid/masonry views\n const index = model.items.findIndex(item => item.id === targetId);\n if (index === -1) return;\n const divideY = containerRef.current.querySelector('.divide-y');\n const child = divideY?.children[index] as HTMLElement | undefined;\n if (child) {\n child.scrollIntoView({ block: 'nearest', behavior: 'smooth' });\n }\n model.clearScrollToItem();\n }, [model.scrollToItemId, model]);\n\n // AICODE-NOTE: Load items when component mounts\n useEffect(() => {\n if (model.allItemsCount === 0 && !model.isLoading) {\n model.loadItems();\n }\n }, [model]);\n\n // AICODE-NOTE: Handle item clicks with proper modifier support\n const handleItemClick = (item: any, event: React.MouseEvent) => {\n const modifiers = {\n ctrl: event.ctrlKey || event.metaKey,\n shift: event.shiftKey\n };\n model.selectItem(item, modifiers);\n };\n\n // AICODE-NOTE: Handle item double clicks\n const handleItemDoubleClick = (item: any, event: React.MouseEvent) => {\n if (model.provider.onItemDoubleClick) {\n model.provider.onItemDoubleClick(item);\n }\n };\n\n // AICODE-NOTE: Handle context menu\n const handleItemContextMenu = (item: any, event: React.MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n\n // AICODE-NOTE: If item is not selected, select it first\n if (!model.isItemSelected(item.id)) {\n model.selectItem(item);\n }\n \n // AICODE-NOTE: Get items for context menu (selected items or just this item)\n const contextItems = model.hasSelection ? model.selectedItemsArray : [item];\n \n setContextMenu({\n isOpen: true,\n position: { x: event.clientX, y: event.clientY },\n items: contextItems\n });\n };\n\n // AICODE-NOTE: Close context menu\n const handleCloseContextMenu = () => {\n setContextMenu(prev => ({ ...prev, isOpen: false }));\n };\n\n // AICODE-NOTE: Handle empty-space right-click for \"New Folder\" / \"New File\" actions\n const handleContainerContextMenu = (event: React.MouseEvent) => {\n // Only fire if the target is the container itself (not an item)\n // Item context menus call stopPropagation, so this only fires for empty space\n event.preventDefault();\n const emptyMenuItems = model.provider.getEmptySpaceContextMenu?.();\n if (emptyMenuItems && emptyMenuItems.length > 0) {\n setContextMenu({\n isOpen: true,\n position: { x: event.clientX, y: event.clientY },\n items: [] // empty items array signals empty-space menu\n });\n }\n };\n\n // AICODE-NOTE: Drag and drop handlers\n const handleItemDragStart = (item: ListItemData, event: React.DragEvent) => {\n // AICODE-NOTE: Determine items to drag before any selection changes\n let itemsToDrag: ListItemData[];\n \n if (model.isItemSelected(item.id) && model.hasSelection) {\n // Item is already selected and we have a selection - drag all selected items\n itemsToDrag = model.selectedItemsArray;\n } else {\n // Item is not selected or no selection - select it first, then drag just this item\n model.selectItem(item);\n itemsToDrag = [item];\n }\n \n model.startDrag(itemsToDrag, event.nativeEvent as DragEvent);\n };\n\n const handleItemDragOver = (item: ListItemData, event: React.DragEvent) => {\n if (!model.isDragging) return;\n \n // AICODE-NOTE: Calculate drop position based on mouse position\n const rect = (event.currentTarget as HTMLElement).getBoundingClientRect();\n const y = event.clientY - rect.top;\n const height = rect.height;\n \n let position: 'before' | 'after' | 'inside' = 'inside';\n \n if (y < height * 0.25) {\n position = 'before';\n } else if (y > height * 0.75) {\n position = 'after';\n } else {\n position = 'inside';\n }\n \n // AICODE-NOTE: Check if drop is allowed\n if (model.canDropItems(model.draggedItems, item, position)) {\n model.setDragOver(item.id, position);\n }\n };\n\n const handleItemDragLeave = (item: ListItemData, event: React.DragEvent) => {\n // AICODE-NOTE: Only clear drag over if we're actually leaving the item\n const rect = (event.currentTarget as HTMLElement).getBoundingClientRect();\n const x = event.clientX;\n const y = event.clientY;\n \n if (x < rect.left || x > rect.right || y < rect.top || y > rect.bottom) {\n model.setDragOver(null, null);\n }\n };\n\n const handleItemDrop = (item: ListItemData, event: React.DragEvent) => {\n if (!model.isDragging) return;\n \n // AICODE-NOTE: Calculate drop position\n const rect = (event.currentTarget as HTMLElement).getBoundingClientRect();\n const y = event.clientY - rect.top;\n const height = rect.height;\n \n let position: 'before' | 'after' | 'inside' = 'inside';\n \n if (y < height * 0.25) {\n position = 'before';\n } else if (y > height * 0.75) {\n position = 'after';\n } else {\n position = 'inside';\n }\n \n model.handleDrop(item, position, event.nativeEvent as DragEvent);\n };\n\n // AICODE-NOTE: Handle drag end\n const handleDragEnd = () => {\n if (model.isDragging) {\n model.endDrag(false);\n }\n };\n\n // AICODE-NOTE: Get item width from provider if available\n const getItemWidth = () => {\n // AICODE-NOTE: Use model dimensions first (from size controls), then fallback to provider\n if (model.currentViewType.id === 'grid' || model.currentViewType.id.includes('masonry')) {\n return model.itemDimensions.width;\n }\n \n if (model.provider.getItemWidth) {\n return model.provider.getItemWidth(model.currentViewType);\n }\n return undefined;\n };\n\n // AICODE-NOTE: Get item height from model dimensions\n const getItemHeight = () => {\n if (model.currentViewType.id === 'grid' || model.currentViewType.id.includes('masonry')) {\n return model.itemDimensions.height;\n }\n return undefined;\n };\n\n // AICODE-NOTE: Render loading state with skeleton\n if (model.isLoading && model.allItemsCount === 0) {\n benchmark.end('ListItems.render', { renderType: 'loading' });\n return (\n <div\n ref={containerRef}\n className={`${sizeClass} ${className}`}\n style={sizeStyle}\n tabIndex={0}\n >\n <ListLoader\n viewType={model.currentViewType}\n itemCount={12}\n itemWidth={model.itemDimensions.width}\n itemHeight={model.itemDimensions.height}\n className=\"w-full h-full\"\n />\n </div>\n );\n }\n\n // AICODE-NOTE: Render error state\n if (model.hasErrors && model.allItemsCount === 0) {\n const errors = Array.from(model.errors.values());\n const firstError = errors[0] || new Error('Unknown error occurred');\n benchmark.end('ListItems.render', { renderType: 'error' });\n return (\n <div\n ref={containerRef}\n className={`flex items-center justify-center ${sizeClass} ${className}`}\n style={sizeStyle}\n tabIndex={0}\n >\n <LoadError\n error={firstError}\n onRetry={() => model.refresh()}\n className=\"max-w-md\"\n />\n </div>\n );\n }\n\n // AICODE-NOTE: Render empty state\n if (!model.isLoading && model.items.length === 0) {\n benchmark.end('ListItems.render', { renderType: 'empty' });\n\n // Search returned no results but directory has items\n if (model.hasSearchQuery) {\n return (\n <div\n ref={containerRef}\n className={`flex flex-col items-center justify-center gap-2 text-muted-foreground ${sizeClass} ${className}`}\n style={sizeStyle}\n tabIndex={0}\n >\n <SearchX className=\"w-10 h-10 opacity-40\" />\n <p className=\"text-sm\">No files match &ldquo;{model.searchQuery}&rdquo;</p>\n <button\n onClick={() => model.clearSearch()}\n className=\"text-xs text-primary hover:underline\"\n >\n Clear filter\n </button>\n </div>\n );\n }\n\n return (\n <>\n <div\n ref={containerRef}\n className={`${sizeClass} ${className}`}\n style={sizeStyle}\n tabIndex={0}\n onContextMenu={handleContainerContextMenu}\n >\n <NoItems\n onRefresh={() => model.refresh()}\n className=\"h-full\"\n />\n </div>\n <ListContextMenu\n isOpen={contextMenu.isOpen}\n position={contextMenu.position}\n items={contextMenu.items}\n provider={model.provider}\n onClose={handleCloseContextMenu}\n />\n </>\n );\n }\n\n // AICODE-NOTE: Base container styles\n const containerClasses = `\n h-full w-full overflow-auto \n ${className}\n `;\n\n // AICODE-NOTE: Generate accessibility props\n const accessibilityProps = getListAccessibilityProps({\n viewType: model.currentViewType.id,\n isMultiSelect: model.provider.isMultiSelectEnabled,\n totalItems: model.totalItemCount,\n selectedCount: model.selectedItemsArray.length,\n label: `${model.currentViewType.name} view`\n });\n\n // AICODE-NOTE: Treemap layout for treemap view\n if (model.currentViewType.id === 'treemap') {\n benchmark.end('ListItems.render', { renderType: 'treemap' });\n return (\n <TreemapSection\n model={model}\n containerRef={containerRef}\n sizeClass={sizeClass}\n className={className}\n sizeStyle={sizeStyle}\n effectiveWidth={effectiveWidth}\n effectiveHeight={effectiveHeight}\n contextMenu={contextMenu}\n setContextMenu={setContextMenu}\n handleCloseContextMenu={handleCloseContextMenu}\n handleContainerContextMenu={handleContainerContextMenu}\n />\n );\n }\n\n // AICODE-NOTE: Grid layout for grid view\n if (model.currentViewType.id === 'grid') {\n benchmark.end('ListItems.render', { renderType: 'grid-calculated' });\n return (\n <>\n <CalculatedGridView\n model={model}\n className={`${sizeClass} ${className}`}\n height={effectiveHeight}\n width={effectiveWidth}\n enableVirtualization={enableVirtualization}\n onItemClick={handleItemClick}\n onItemDoubleClick={handleItemDoubleClick}\n onItemContextMenu={handleItemContextMenu}\n onItemDragStart={handleItemDragStart}\n onItemDragOver={handleItemDragOver}\n onItemDragLeave={handleItemDragLeave}\n onItemDrop={handleItemDrop}\n />\n <ListPagination model={model} />\n\n {/* AICODE-NOTE: Context menu */}\n <ListContextMenu\n isOpen={contextMenu.isOpen}\n position={contextMenu.position}\n items={contextMenu.items}\n provider={model.provider}\n onClose={handleCloseContextMenu}\n />\n </>\n );\n }\n\n // AICODE-NOTE: Masonry layouts for masonry views\n if (model.currentViewType.id === 'masonry-horizontal' || model.currentViewType.id === 'masonry-vertical') {\n // AICODE-NOTE: Always use virtualized masonry when container dimensions are available\n // Masonry layouts can have thousands of items, so virtualization is essential\n if (effectiveHeight && effectiveWidth) {\n benchmark.end('ListItems.render', { renderType: 'masonry-virtualized' });\n return (\n <>\n <div ref={containerRef} tabIndex={0} className={`${sizeClass} ${className}`} style={sizeStyle}>\n <VirtualizedMasonryView\n model={model}\n items={model.items}\n containerWidth={effectiveWidth}\n containerHeight={effectiveHeight}\n isHorizontal={model.currentViewType.id === 'masonry-horizontal'}\n overscanCount={10}\n className=\"w-full h-full\"\n />\n </div>\n <ListPagination model={model} />\n\n {/* AICODE-NOTE: Context menu */}\n <ListContextMenu\n isOpen={contextMenu.isOpen}\n position={contextMenu.position}\n items={contextMenu.items}\n provider={model.provider}\n onClose={handleCloseContextMenu}\n />\n </>\n );\n }\n\n // AICODE-NOTE: Fallback to non-virtualized masonry (when container dimensions not yet available)\n benchmark.end('ListItems.render', { renderType: 'masonry-standard' });\n return (\n <>\n <div\n ref={containerRef}\n className={`overflow-y-auto overflow-x-hidden ${sizeClass} ${className}`}\n style={sizeStyle}\n tabIndex={0}\n >\n <MasonryView\n model={model}\n items={model.items}\n containerWidth={effectiveWidth}\n containerHeight={effectiveHeight}\n isHorizontal={model.currentViewType.id === 'masonry-horizontal'}\n />\n </div>\n <ListPagination model={model} />\n\n {/* AICODE-NOTE: Context menu */}\n <ListContextMenu\n isOpen={contextMenu.isOpen}\n position={contextMenu.position}\n items={contextMenu.items}\n provider={model.provider}\n onClose={handleCloseContextMenu}\n />\n </>\n );\n }\n\n // AICODE-NOTE: Details view with headers\n if (model.currentViewType.id === 'details') {\n // AICODE-NOTE: Use virtualized details view if enabled and height provided\n if (enableVirtualization && effectiveHeight && model.provider.isVirtualizationEnabled) {\n benchmark.end('ListItems.render', { renderType: 'details-virtualized' });\n return (\n <>\n <div ref={containerRef} tabIndex={0} className={`${sizeClass} ${className}`} style={sizeStyle}>\n <VirtualizedDetailsView\n model={model}\n height={effectiveHeight}\n width={effectiveWidth}\n />\n </div>\n <ListPagination model={model} />\n </>\n );\n }\n\n // AICODE-NOTE: Fallback to non-virtualized details view\n benchmark.end('ListItems.render', { renderType: 'details-standard' });\n return (\n <>\n <div\n ref={containerRef}\n className={`overflow-auto ${sizeClass} ${className}`}\n style={sizeStyle}\n role={accessibilityProps.role}\n aria-label={accessibilityProps.ariaLabel}\n aria-multiselectable={accessibilityProps.ariaMultiSelectable}\n tabIndex={accessibilityProps.tabIndex}\n onContextMenu={handleContainerContextMenu}\n >\n {/* AICODE-NOTE: Column headers — same CSS grid as ListItem details rows */}\n <div\n className=\"sticky top-0 grid items-center bg-background border-b px-4 py-2 text-sm font-medium text-muted-foreground\"\n style={{ gridTemplateColumns: model.detailsGridTemplateColumns, columnGap: 16 }}\n >\n {model.showCheckboxes && (\n <div className=\"flex items-center justify-center\">\n <input\n type=\"checkbox\"\n checked={model.items.length > 0 && model.selectedItems.size === model.items.length}\n ref={(el) => {\n if (el) el.indeterminate = model.selectedItems.size > 0 && model.selectedItems.size < model.items.length;\n }}\n onChange={() => {\n if (model.selectedItems.size === model.items.length) {\n model.clearSelection();\n } else {\n model.selectAll();\n }\n }}\n className=\"h-3.5 w-3.5 rounded border-muted-foreground/50 accent-primary cursor-pointer\"\n aria-label=\"Select all\"\n />\n </div>\n )}\n <div />\n <div>Name</div>\n {!model.compactMode && model.columnVisibility.type && <div>Type</div>}\n {!model.compactMode && model.columnVisibility.modified && <div>Modified</div>}\n {!model.compactMode && model.columnVisibility.size && <div className=\"text-right\">Size</div>}\n </div>\n \n {/* AICODE-NOTE: Items */}\n <div className=\"divide-y\">\n {benchmark.time('details-items-render', () => {\n return model.items.map((item, index) => (\n <ListItem\n key={item.id}\n item={item}\n index={index}\n totalItems={model.totalItemCount}\n viewType={model.currentViewType}\n provider={model.provider}\n model={model}\n isSelected={model.isItemSelected(item.id)}\n isFocused={model.focusedItem === item.id}\n isDraggedOver={model.dragOverItem === item.id}\n dragOverPosition={model.dragOverItem === item.id ? model.dragOverPosition : null}\n canDrag={model.canDragItem(item)}\n onClick={handleItemClick}\n onDoubleClick={handleItemDoubleClick}\n onContextMenu={handleItemContextMenu}\n onDragStart={handleItemDragStart}\n onDragOver={handleItemDragOver}\n onDragLeave={handleItemDragLeave}\n onDrop={handleItemDrop}\n />\n ));\n })}\n </div>\n </div>\n <ListPagination model={model} />\n\n {/* AICODE-NOTE: Context menu */}\n <ListContextMenu\n isOpen={contextMenu.isOpen}\n position={contextMenu.position}\n items={contextMenu.items}\n provider={model.provider}\n onClose={handleCloseContextMenu}\n />\n </>\n );\n }\n\n // AICODE-NOTE: Default list view — use virtualized list if enabled and height provided\n if (enableVirtualization && effectiveHeight && model.provider.isVirtualizationEnabled) {\n benchmark.end('ListItems.render', { renderType: 'list-virtualized' });\n return (\n <>\n <div ref={containerRef} tabIndex={0} className={`${sizeClass} ${className}`} style={sizeStyle}>\n <VirtualizedList\n model={model}\n height={effectiveHeight}\n width={effectiveWidth}\n />\n </div>\n <ListPagination model={model} />\n </>\n );\n }\n\n benchmark.end('ListItems.render', { renderType: 'list-standard' });\n return (\n <>\n <div\n ref={containerRef}\n className={`overflow-auto ${sizeClass} ${className}`}\n style={sizeStyle}\n role={accessibilityProps.role}\n aria-label={accessibilityProps.ariaLabel}\n aria-multiselectable={accessibilityProps.ariaMultiSelectable}\n tabIndex={accessibilityProps.tabIndex}\n onContextMenu={handleContainerContextMenu}\n >\n <div className=\"divide-y\">\n {benchmark.time('list-items-render', () => {\n return model.items.map((item, index) => (\n <ListItem\n key={item.id}\n item={item}\n index={index}\n totalItems={model.totalItemCount}\n viewType={model.currentViewType}\n provider={model.provider}\n model={model}\n isSelected={model.isItemSelected(item.id)}\n isFocused={model.focusedItem === item.id}\n isDraggedOver={model.dragOverItem === item.id}\n dragOverPosition={model.dragOverItem === item.id ? model.dragOverPosition : null}\n canDrag={model.canDragItem(item)}\n onClick={handleItemClick}\n onDoubleClick={handleItemDoubleClick}\n onContextMenu={handleItemContextMenu}\n onDragStart={handleItemDragStart}\n onDragOver={handleItemDragOver}\n onDragLeave={handleItemDragLeave}\n onDrop={handleItemDrop}\n />\n ));\n })}\n </div>\n </div>\n <ListPagination model={model} />\n\n {/* AICODE-NOTE: Context menu */}\n <ListContextMenu\n isOpen={contextMenu.isOpen}\n position={contextMenu.position}\n items={contextMenu.items}\n provider={model.provider}\n onClose={handleCloseContextMenu}\n />\n </>\n );\n});\n\nListItems.displayName = 'ListItems';\n\n/** Treemap section — owns the TreemapModel and wires context menu */\nconst TreemapSection = observer<{\n model: ListItemsModel;\n containerRef: React.RefObject<HTMLDivElement | null>;\n sizeClass: string;\n className: string;\n sizeStyle: React.CSSProperties | undefined;\n effectiveWidth: number;\n effectiveHeight: number;\n contextMenu: { isOpen: boolean; position: { x: number; y: number }; items: ListItemData[] };\n setContextMenu: React.Dispatch<React.SetStateAction<{ isOpen: boolean; position: { x: number; y: number }; items: ListItemData[] }>>;\n handleCloseContextMenu: () => void;\n handleContainerContextMenu: (event: React.MouseEvent) => void;\n}>(({\n model,\n containerRef,\n sizeClass,\n className,\n sizeStyle,\n effectiveWidth,\n effectiveHeight,\n contextMenu,\n setContextMenu,\n handleCloseContextMenu,\n handleContainerContextMenu,\n}) => {\n const treemapModelRef = useRef<TreemapModel | null>(null);\n if (!treemapModelRef.current) {\n treemapModelRef.current = new TreemapModel();\n }\n const treemapModel = treemapModelRef.current;\n\n // Track the context-menu'd item for treemap-specific actions\n const contextItemRef = useRef<ListItemData | null>(null);\n\n const handleTileContextMenu = (info: TileInfo, event: React.MouseEvent) => {\n // Build a fake ListItemData from TileInfo\n const fakeItem: ListItemData = {\n id: info.path,\n name: info.name,\n path: info.path,\n type: info.isDirectory ? 'directory' : 'file',\n isDirectory: info.isDirectory,\n size: info.size,\n };\n\n // Select item in model\n if (!model.isItemSelected(fakeItem.id)) {\n model.selectItem(fakeItem);\n }\n\n contextItemRef.current = fakeItem;\n\n const contextItems = model.hasSelection ? model.selectedItemsArray : [fakeItem];\n setContextMenu({\n isOpen: true,\n position: { x: event.clientX, y: event.clientY },\n items: contextItems,\n });\n };\n\n const handleEmptyContextMenu = (event: React.MouseEvent) => {\n contextItemRef.current = null;\n handleContainerContextMenu(event);\n };\n\n // Build treemap-specific extra menu items\n const extraMenuItems = useMemo((): ListContextMenuItem[] => {\n const item = contextItemRef.current;\n if (!item) return [];\n\n const items: ListContextMenuItem[] = [];\n\n if (item.isDirectory) {\n items.push({\n id: 'zoom-into',\n label: 'Zoom Into',\n icon: 'zoom-in',\n type: 'item',\n });\n }\n\n items.push({\n id: 'show-in-list',\n label: 'Show in File Browser',\n icon: 'list',\n type: 'item',\n });\n\n items.push({\n id: 'sep-treemap',\n label: '',\n type: 'separator',\n });\n\n return items;\n // Re-derive when context menu opens (items change)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [contextMenu.isOpen, contextMenu.items]);\n\n const handleExtraMenuAction = (actionId: string, items: ListItemData[]) => {\n const item = items[0];\n if (!item) return;\n\n if (actionId === 'zoom-into') {\n treemapModel.zoomIn(item.path);\n } else if (actionId === 'show-in-list') {\n // Switch to list view\n model.setViewType(LIST_VIEW_TYPE);\n // Navigate to parent directory\n if (model.provider.onItemDoubleClick) {\n const parentPath = item.path.split('/').slice(0, -1).join('/');\n const parentName = parentPath.split('/').pop() || '';\n const parentItem: ListItemData = {\n id: parentPath,\n name: parentName,\n path: parentPath,\n type: 'directory',\n isDirectory: true,\n };\n model.provider.onItemDoubleClick(parentItem);\n }\n }\n };\n\n return (\n <>\n <div ref={containerRef} tabIndex={0} className={`${sizeClass} ${className}`} style={sizeStyle}>\n <TreemapView\n model={model}\n treemapModel={treemapModel}\n width={effectiveWidth}\n height={effectiveHeight}\n onTileContextMenu={handleTileContextMenu}\n onEmptyContextMenu={handleEmptyContextMenu}\n />\n </div>\n <ListContextMenu\n isOpen={contextMenu.isOpen}\n position={contextMenu.position}\n items={contextMenu.items}\n provider={model.provider}\n onClose={handleCloseContextMenu}\n extraMenuItems={extraMenuItems}\n onExtraMenuAction={handleExtraMenuAction}\n />\n </>\n );\n});\n\nTreemapSection.displayName = 'TreemapSection';","import React, { useState, useEffect, useRef } from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { ListViewType } from '../types/ListTypes';\nimport { List, Grid, Table, LayoutList, Columns, MoreHorizontal, ChevronDown, SquareStack } from 'lucide-react';\n\nexport interface ViewTypeSelectorProps {\n viewTypes: ListViewType[];\n currentViewType: ListViewType;\n onViewTypeChange: (viewType: ListViewType) => void;\n variant?: 'buttons' | 'tabs' | 'dropdown';\n size?: 'sm' | 'md' | 'lg';\n className?: string;\n}\n\nconst PRIMARY_VIEW_IDS = new Set(['list', 'grid', 'details']);\n\nconst getViewTypeIcon = (viewTypeId: string) => {\n switch (viewTypeId) {\n case 'list':\n return List;\n case 'grid':\n return Grid;\n case 'details':\n return Table;\n case 'masonry-horizontal':\n return LayoutList;\n case 'masonry-vertical':\n return Columns;\n case 'treemap':\n return SquareStack;\n default:\n return List;\n }\n};\n\ninterface ViewTypeButtonProps {\n viewType: ListViewType;\n isActive: boolean;\n onViewTypeChange: (viewType: ListViewType) => void;\n sizeClasses: string;\n variant: 'buttons' | 'tabs' | 'dropdown';\n}\n\nconst ViewTypeButton = observer<ViewTypeButtonProps>(({\n viewType,\n isActive,\n onViewTypeChange,\n sizeClasses,\n variant\n}) => {\n const Icon = getViewTypeIcon(viewType.id);\n\n if (variant === 'buttons') {\n return (\n <button\n onClick={() => onViewTypeChange(viewType)}\n className={`\n ${sizeClasses}\n flex items-center gap-2 font-medium transition-all\n first:rounded-l-lg last:rounded-r-lg\n ${isActive\n ? 'bg-primary text-primary-foreground shadow-sm'\n : 'hover:bg-muted text-muted-foreground hover:text-foreground'\n }\n `}\n title={viewType.name}\n >\n <Icon className=\"w-4 h-4\" />\n <span className=\"hidden sm:inline\">{viewType.name}</span>\n </button>\n );\n }\n\n if (variant === 'tabs') {\n return (\n <button\n onClick={() => onViewTypeChange(viewType)}\n className={`\n ${sizeClasses}\n flex items-center gap-2 font-medium transition-all\n border-b-2 -mb-px\n ${isActive\n ? 'border-primary text-primary'\n : 'border-transparent text-muted-foreground hover:text-foreground hover:border-muted-foreground'\n }\n `}\n >\n <Icon className=\"w-4 h-4\" />\n {viewType.name}\n </button>\n );\n }\n\n return null;\n});\n\nViewTypeButton.displayName = 'ViewTypeButton';\n\n/** \"More views\" dropdown for advanced view types (masonry, treemap, etc.) */\nconst MoreViewsDropdown = observer<{\n viewTypes: ListViewType[];\n currentViewType: ListViewType;\n onViewTypeChange: (viewType: ListViewType) => void;\n sizeClasses: string;\n}>(({ viewTypes, currentViewType, onViewTypeChange, sizeClasses }) => {\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n const isAdvancedActive = viewTypes.some(vt => vt.id === currentViewType.id);\n\n useEffect(() => {\n if (!open) return;\n const handleClickOutside = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) {\n setOpen(false);\n }\n };\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, [open]);\n\n if (viewTypes.length === 0) return null;\n\n // If an advanced view is active, show its icon instead of the generic \"more\" icon\n const ActiveIcon = isAdvancedActive ? getViewTypeIcon(currentViewType.id) : MoreHorizontal;\n\n return (\n <div ref={ref} className=\"relative\">\n <button\n onClick={() => setOpen(prev => !prev)}\n className={`\n ${sizeClasses}\n flex items-center gap-1 font-medium transition-all rounded-lg\n ${isAdvancedActive\n ? 'bg-primary text-primary-foreground shadow-sm'\n : 'hover:bg-muted text-muted-foreground hover:text-foreground'\n }\n `}\n title={isAdvancedActive ? currentViewType.name : 'More views'}\n >\n <ActiveIcon className=\"w-4 h-4\" />\n {isAdvancedActive && <span className=\"hidden sm:inline\">{currentViewType.name}</span>}\n <ChevronDown className=\"w-3 h-3\" />\n </button>\n\n {open && (\n <div className=\"absolute top-full right-0 mt-1 z-50 min-w-[180px] border rounded-lg bg-background shadow-md py-1\">\n {viewTypes.map((viewType) => {\n const Icon = getViewTypeIcon(viewType.id);\n const isActive = currentViewType.id === viewType.id;\n return (\n <button\n key={viewType.id}\n className={`\n w-full flex items-center gap-2 px-3 py-2 text-sm transition-colors\n ${isActive\n ? 'bg-primary text-primary-foreground'\n : 'text-foreground hover:bg-muted'\n }\n `}\n onClick={() => {\n onViewTypeChange(viewType);\n setOpen(false);\n }}\n >\n <Icon className=\"w-4 h-4\" />\n <span>{viewType.name}</span>\n </button>\n );\n })}\n </div>\n )}\n </div>\n );\n});\n\nMoreViewsDropdown.displayName = 'MoreViewsDropdown';\n\nconst ViewTypeSelectorComponent = observer<ViewTypeSelectorProps>(({\n viewTypes,\n currentViewType,\n onViewTypeChange,\n variant = 'buttons',\n size = 'md',\n className = ''\n}) => {\n const sizeClasses = {\n sm: 'px-2 py-1 text-xs',\n md: 'px-3 py-2 text-sm',\n lg: 'px-4 py-3 text-base'\n };\n\n if (variant === 'buttons') {\n const primaryViews = viewTypes.filter(vt => PRIMARY_VIEW_IDS.has(vt.id));\n const advancedViews = viewTypes.filter(vt => !PRIMARY_VIEW_IDS.has(vt.id));\n\n return (\n <div className={`flex items-center gap-1 ${className}`}>\n <div className=\"flex rounded-lg border bg-background\">\n {primaryViews.map((viewType) => (\n <ViewTypeButton\n key={viewType.id}\n viewType={viewType}\n isActive={currentViewType.id === viewType.id}\n onViewTypeChange={onViewTypeChange}\n sizeClasses={sizeClasses[size]}\n variant={variant}\n />\n ))}\n </div>\n <MoreViewsDropdown\n viewTypes={advancedViews}\n currentViewType={currentViewType}\n onViewTypeChange={onViewTypeChange}\n sizeClasses={sizeClasses[size]}\n />\n </div>\n );\n }\n\n if (variant === 'tabs') {\n return (\n <div className={`flex border-b ${className}`}>\n {viewTypes.map((viewType) => (\n <ViewTypeButton\n key={viewType.id}\n viewType={viewType}\n isActive={currentViewType.id === viewType.id}\n onViewTypeChange={onViewTypeChange}\n sizeClasses={sizeClasses[size]}\n variant={variant}\n />\n ))}\n </div>\n );\n }\n\n if (variant === 'dropdown') {\n const [dropdownOpen, setDropdownOpen] = useState(false);\n const dropdownRef = useRef<HTMLDivElement>(null);\n const CurrentIcon = getViewTypeIcon(currentViewType.id);\n\n useEffect(() => {\n if (!dropdownOpen) return;\n const handleClickOutside = (e: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(e.target as Node)) {\n setDropdownOpen(false);\n }\n };\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, [dropdownOpen]);\n\n return (\n <div ref={dropdownRef} className={`relative ${className}`}>\n <button\n className={`\n ${sizeClasses[size]}\n flex items-center gap-2 font-medium border rounded-lg bg-background hover:bg-muted transition-colors\n `}\n onClick={() => setDropdownOpen((prev) => !prev)}\n >\n <CurrentIcon className=\"w-4 h-4\" />\n <span>{currentViewType.name}</span>\n <ChevronDown className=\"w-4 h-4\" />\n </button>\n\n {dropdownOpen && (\n <div className=\"absolute top-full left-0 mt-1 z-50 min-w-[160px] border rounded-lg bg-background shadow-md py-1\">\n {viewTypes.map((viewType) => {\n const Icon = getViewTypeIcon(viewType.id);\n const isActive = currentViewType.id === viewType.id;\n return (\n <button\n key={viewType.id}\n className={`\n w-full flex items-center gap-2 px-3 py-2 text-sm transition-colors\n ${isActive\n ? 'bg-primary text-primary-foreground'\n : 'text-foreground hover:bg-muted'\n }\n `}\n onClick={() => {\n onViewTypeChange(viewType);\n setDropdownOpen(false);\n }}\n >\n <Icon className=\"w-4 h-4\" />\n <span>{viewType.name}</span>\n </button>\n );\n })}\n </div>\n )}\n </div>\n );\n }\n\n return null;\n});\n\nViewTypeSelectorComponent.displayName = 'ViewTypeSelector';\n\nexport const ViewTypeSelector = React.memo(ViewTypeSelectorComponent, (prevProps, nextProps) => {\n return (\n prevProps.currentViewType.id === nextProps.currentViewType.id &&\n prevProps.viewTypes.length === nextProps.viewTypes.length &&\n prevProps.variant === nextProps.variant &&\n prevProps.className === nextProps.className &&\n prevProps.size === nextProps.size &&\n prevProps.viewTypes.every((vt, index) => vt.id === nextProps.viewTypes[index]?.id)\n );\n});\n","import React, { useRef } from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { Search, X } from 'lucide-react';\nimport { ListItemsModel } from '../models/ListItemsModel';\n\nexport interface SearchFilterProps {\n model: ListItemsModel;\n placeholder?: string;\n className?: string;\n}\n\nexport const SearchFilter = observer<SearchFilterProps>(({ model, placeholder = 'Filter...', className }) => {\n const inputRef = useRef<HTMLInputElement>(null);\n\n return (\n <div className={`relative flex items-center ${className ?? ''}`}>\n <Search className=\"absolute left-1.5 w-3 h-3 text-muted-foreground pointer-events-none\" />\n <input\n ref={inputRef}\n type=\"text\"\n placeholder={placeholder}\n value={model.searchQuery}\n onChange={(e) => model.setSearchQuery(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Escape') {\n model.clearSearch();\n inputRef.current?.blur();\n }\n }}\n className=\"h-6 w-[120px] focus:w-[160px] transition-all pl-5 pr-5 text-xs rounded border border-input bg-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n {model.searchQuery && (\n <button\n onClick={() => { model.clearSearch(); inputRef.current?.focus(); }}\n className=\"absolute right-1 p-0.5 rounded-sm hover:bg-muted text-muted-foreground hover:text-foreground\"\n >\n <X className=\"w-3 h-3\" />\n </button>\n )}\n </div>\n );\n});\n\nSearchFilter.displayName = 'SearchFilter';\n","import React, { useCallback, useMemo, useState } from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { FixedSizeGrid as Grid } from 'react-window';\nimport { ListItemsModel } from '../models/ListItemsModel';\nimport type { ListItemData } from '../types/ListTypes';\nimport { ListItem } from './ListItem';\nimport { ListContextMenu } from './ListContextMenu';\n\nexport interface VirtualizedGridProps {\n model: ListItemsModel;\n height: number;\n width: number;\n className?: string;\n overscanCount?: number;\n}\n\ninterface GridItemRendererProps {\n columnIndex: number;\n rowIndex: number;\n style: React.CSSProperties;\n data: {\n model: ListItemsModel;\n itemsPerRow: number;\n itemWidth: number;\n onItemClick: (item: any, event: React.MouseEvent) => void;\n onItemDoubleClick: (item: any, event: React.MouseEvent) => void;\n onItemContextMenu: (item: any, event: React.MouseEvent) => void;\n };\n}\n\nconst GridItemRenderer = observer<GridItemRendererProps>(({\n columnIndex,\n rowIndex,\n style,\n data\n}) => {\n const { model, itemsPerRow, onItemClick, onItemDoubleClick, onItemContextMenu } = data;\n const itemIndex = rowIndex * itemsPerRow + columnIndex;\n const item = model.items[itemIndex];\n\n if (!item) {\n return (\n <div style={style} className=\"p-2\">\n <div className=\"w-full h-full bg-muted/20 rounded animate-pulse\" />\n </div>\n );\n }\n\n return (\n <div style={style} className=\"p-1\">\n <ListItem\n item={item}\n index={itemIndex}\n totalItems={model.totalItemCount}\n viewType={model.currentViewType}\n provider={model.provider}\n itemWidth={model.itemDimensions.width}\n itemHeight={model.itemDimensions.height}\n isSelected={model.isItemSelected(item.id)}\n isFocused={model.focusedItem === item.id}\n onClick={onItemClick}\n onDoubleClick={onItemDoubleClick}\n onContextMenu={onItemContextMenu}\n />\n </div>\n );\n});\n\nGridItemRenderer.displayName = 'VirtualizedGridItemRenderer';\n\nexport const VirtualizedGrid = observer<VirtualizedGridProps>(({\n model,\n height,\n width,\n className = '',\n overscanCount = 5\n}) => {\n const itemWidth = model.provider.getItemWidth?.(model.currentViewType) || 200;\n const itemHeight = model.provider.getItemHeight(model.currentViewType);\n const itemsPerRow = Math.max(1, Math.floor(width / itemWidth));\n const rowCount = Math.ceil(model.totalItemCount / itemsPerRow);\n\n // Context menu state\n const [contextMenu, setContextMenu] = useState<{\n isOpen: boolean;\n position: { x: number; y: number };\n }>({ isOpen: false, position: { x: 0, y: 0 } });\n\n const handleItemClick = useCallback((item: any, event: React.MouseEvent) => {\n const modifiers = {\n ctrl: event.ctrlKey || event.metaKey,\n shift: event.shiftKey\n };\n model.selectItem(item, modifiers);\n }, [model]);\n\n const handleItemDoubleClick = useCallback((item: any, event: React.MouseEvent) => {\n if (model.provider.onItemDoubleClick) {\n model.provider.onItemDoubleClick(item);\n }\n }, [model]);\n\n const handleItemContextMenu = useCallback((item: any, event: React.MouseEvent) => {\n event.preventDefault();\n if (!model.isItemSelected(item.id)) {\n model.selectItem(item);\n }\n setContextMenu({\n isOpen: true,\n position: { x: event.clientX, y: event.clientY }\n });\n }, [model]);\n\n const handleCloseContextMenu = useCallback(() => {\n setContextMenu(prev => ({ ...prev, isOpen: false }));\n }, []);\n\n const gridData = useMemo(() => ({\n model,\n itemsPerRow,\n itemWidth,\n onItemClick: handleItemClick,\n onItemDoubleClick: handleItemDoubleClick,\n onItemContextMenu: handleItemContextMenu\n }), [model, itemsPerRow, itemWidth, handleItemClick, handleItemDoubleClick, handleItemContextMenu]);\n\n return (\n <>\n <Grid\n className={className}\n height={height}\n width={width}\n columnCount={itemsPerRow}\n rowCount={rowCount}\n columnWidth={itemWidth}\n rowHeight={itemHeight}\n itemData={gridData}\n overscanColumnCount={overscanCount}\n overscanRowCount={overscanCount}\n onItemsRendered={({\n visibleColumnStartIndex,\n visibleColumnStopIndex,\n visibleRowStartIndex,\n visibleRowStopIndex\n }) => {\n const startIndex = visibleRowStartIndex * itemsPerRow + visibleColumnStartIndex;\n const stopIndex = visibleRowStopIndex * itemsPerRow + visibleColumnStopIndex;\n model.updateViewportRange(startIndex, stopIndex);\n }}\n >\n {GridItemRenderer}\n </Grid>\n <ListContextMenu\n isOpen={contextMenu.isOpen}\n position={contextMenu.position}\n items={model.selectedItemsArray}\n provider={model.provider}\n onClose={handleCloseContextMenu}\n />\n </>\n );\n});\n\nVirtualizedGrid.displayName = 'VirtualizedGrid';\n","import React from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { ListItemsModel } from '../models/ListItemsModel';\n\n// AICODE-NOTE: View size controls component for adjusting item sizes\nexport interface ViewSizeControlsProps {\n model: ListItemsModel;\n className?: string;\n showSizePresets?: boolean;\n showCustomSliders?: boolean;\n showDebugToggle?: boolean;\n}\n\n// AICODE-NOTE: Extract size preset button into separate observer component for MobX reactivity\ninterface SizePresetButtonProps {\n preset: { value: 'small' | 'medium' | 'large' | 'extra-large'; label: string };\n isActive: boolean;\n onSizeChange: (size: 'small' | 'medium' | 'large' | 'extra-large') => void;\n}\n\nconst SizePresetButton = observer<SizePresetButtonProps>(({ preset, isActive, onSizeChange }) => (\n <button\n onClick={() => onSizeChange(preset.value)}\n className={`\n px-3 py-1 text-xs rounded-md border transition-colors\n ${isActive \n ? 'bg-primary text-primary-foreground border-primary' \n : 'bg-background hover:bg-muted border-border'\n }\n `}\n >\n {preset.label}\n </button>\n));\n\nSizePresetButton.displayName = 'SizePresetButton';\n\nconst ViewSizeControlsComponent: React.FC<ViewSizeControlsProps> = ({\n model,\n className = '',\n showSizePresets = true,\n showCustomSliders = false,\n showDebugToggle = false\n}) => {\n // AICODE-NOTE: Check if current view supports size controls\n const supportsSize = ['grid', 'masonry-horizontal', 'masonry-vertical'].includes(model.currentViewType.id);\n \n if (!supportsSize && !showDebugToggle) {\n return null;\n }\n\n // AICODE-NOTE: Size preset options\n const sizePresets: Array<{ value: 'small' | 'medium' | 'large' | 'extra-large'; label: string }> = [\n { value: 'small', label: 'Small' },\n { value: 'medium', label: 'Medium' },\n { value: 'large', label: 'Large' },\n { value: 'extra-large', label: 'Extra Large' }\n ];\n\n // AICODE-NOTE: Handle size preset change\n const handleSizePresetChange = (size: 'small' | 'medium' | 'large' | 'extra-large') => {\n model.setItemSize(size);\n };\n\n // AICODE-NOTE: Handle custom width change\n const handleWidthChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const width = parseInt(event.target.value, 10);\n model.setCustomItemWidth(width);\n };\n\n // AICODE-NOTE: Handle custom height change\n const handleHeightChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const height = parseInt(event.target.value, 10);\n model.setCustomItemHeight(height);\n };\n\n // AICODE-NOTE: Handle items per row change\n const handleItemsPerRowChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const value = parseInt(event.target.value, 10);\n model.setItemsPerRow(value);\n };\n\n // AICODE-NOTE: Handle auto items per row\n const handleAutoItemsPerRow = () => {\n model.setItemsPerRow('auto');\n };\n\n return (\n <div className={`view-size-controls space-y-3 ${className}`}>\n {/* AICODE-NOTE: Debug toggle for all views */}\n {showDebugToggle && (\n <div className=\"debug-toggle flex items-center gap-2\">\n <input\n type=\"checkbox\"\n id=\"debug-visualization\"\n checked={model.debugVisualization || false}\n onChange={(e) => model.setDebugVisualization?.(e.target.checked)}\n className=\"w-4 h-4 text-primary bg-background border-border rounded focus:ring-primary focus:ring-2\"\n />\n <label htmlFor=\"debug-visualization\" className=\"text-sm font-medium text-foreground\">\n Debug Visualization\n </label>\n <span className=\"text-xs text-muted-foreground\">\n Show colored borders for layout debugging\n </span>\n </div>\n )}\n\n {/* AICODE-NOTE: Size preset buttons */}\n {supportsSize && showSizePresets && (\n <div className=\"size-presets flex items-center gap-2\">\n <span className=\"text-sm font-medium text-muted-foreground\">Size:</span>\n <div className=\"flex gap-1\">\n {sizePresets.map((preset) => (\n <SizePresetButton\n key={preset.value}\n preset={preset}\n isActive={model.itemSize === preset.value}\n onSizeChange={handleSizePresetChange}\n />\n ))}\n </div>\n </div>\n )}\n\n {/* AICODE-NOTE: Items per row slider */}\n {supportsSize && (\n <div className=\"items-per-row flex items-center gap-2\">\n <span className=\"text-sm font-medium text-muted-foreground\">Items per row:</span>\n <button\n onClick={handleAutoItemsPerRow}\n className={`\n px-2 py-1 text-xs rounded border transition-colors\n ${model.itemsPerRow === 'auto' \n ? 'bg-primary text-primary-foreground border-primary' \n : 'bg-background hover:bg-muted border-border'\n }\n `}\n >\n Auto\n </button>\n <input\n type=\"range\"\n min=\"1\"\n max=\"8\"\n step=\"1\"\n value={typeof model.itemsPerRow === 'number' ? model.itemsPerRow : 4}\n onChange={handleItemsPerRowChange}\n className=\"w-24 h-2 bg-muted rounded-lg appearance-none cursor-pointer\"\n />\n <span className=\"text-xs text-muted-foreground w-4\">\n {typeof model.itemsPerRow === 'number' ? model.itemsPerRow : 'Auto'}\n </span>\n </div>\n )}\n\n {/* AICODE-NOTE: Custom size sliders */}\n {supportsSize && showCustomSliders && (\n <div className=\"custom-sliders flex items-center gap-4\">\n <div className=\"width-slider flex items-center gap-2\">\n <span className=\"text-xs text-muted-foreground\">W:</span>\n <input\n type=\"range\"\n min=\"120\"\n max=\"600\"\n step=\"10\"\n value={model.customItemWidth}\n onChange={handleWidthChange}\n className=\"w-20 h-2 bg-muted rounded-lg appearance-none cursor-pointer\"\n />\n <span className=\"text-xs text-muted-foreground w-8\">\n {model.customItemWidth}\n </span>\n </div>\n \n <div className=\"height-slider flex items-center gap-2\">\n <span className=\"text-xs text-muted-foreground\">H:</span>\n <input\n type=\"range\"\n min=\"80\"\n max=\"500\"\n step=\"10\"\n value={model.customItemHeight}\n onChange={handleHeightChange}\n className=\"w-20 h-2 bg-muted rounded-lg appearance-none cursor-pointer\"\n />\n <span className=\"text-xs text-muted-foreground w-8\">\n {model.customItemHeight}\n </span>\n </div>\n </div>\n )}\n\n {/* AICODE-NOTE: Current dimensions display */}\n {supportsSize && (\n <div className=\"dimensions-display text-xs text-muted-foreground\">\n {model.itemDimensions.width} × {model.itemDimensions.height}\n </div>\n )}\n </div>\n );\n};\n\n// AICODE-NOTE: Export memoized component for performance\nexport const ViewSizeControls = observer(ViewSizeControlsComponent);","import React from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { LoadingSpinner } from '@anymux/ui/components/loading-spinner';\n\nconst SIZE_MAP = { small: 'sm', medium: 'md', large: 'lg' } as const;\nconst TEXT_SIZE_MAP = { small: 'text-xs', medium: 'text-sm', large: 'text-base' } as const;\nconst SPACING_MAP = { small: 'space-y-1', medium: 'space-y-2', large: 'space-y-3' } as const;\n\nexport interface LoadingIndicatorProps {\n size?: 'small' | 'medium' | 'large';\n message?: string;\n className?: string;\n showSpinner?: boolean;\n}\n\nconst LoadingIndicatorComponent: React.FC<LoadingIndicatorProps> = ({\n size = 'medium',\n message = 'Loading...',\n className = '',\n showSpinner = true,\n}) => {\n return (\n <div className={`flex items-center justify-center ${className}`}>\n <div className={`text-center ${SPACING_MAP[size]}`}>\n {showSpinner && (\n <div className=\"flex justify-center\">\n <LoadingSpinner size={SIZE_MAP[size]} label={message || 'Loading...'} />\n </div>\n )}\n {message && (\n <p className={`text-muted-foreground ${TEXT_SIZE_MAP[size]}`}>{message}</p>\n )}\n </div>\n </div>\n );\n};\n\nexport interface InlineLoadingProps {\n className?: string;\n}\n\nconst InlineLoadingComponent: React.FC<InlineLoadingProps> = ({ className = '' }) => {\n return (\n <div className={`flex items-center gap-2 ${className}`}>\n <LoadingSpinner size=\"sm\" label=\"Loading...\" className=\"size-3\" />\n <span className=\"text-xs text-muted-foreground\">Loading...</span>\n </div>\n );\n};\n\nexport interface LoadingProgressProps {\n progress: number;\n message?: string;\n className?: string;\n}\n\nconst LoadingProgressComponent: React.FC<LoadingProgressProps> = ({\n progress,\n message,\n className = '',\n}) => {\n return (\n <div className={`space-y-2 ${className}`}>\n {message && (\n <p className=\"text-sm text-muted-foreground text-center\">{message}</p>\n )}\n <div className=\"w-full bg-muted rounded-full h-2\">\n <div\n className=\"bg-primary h-2 rounded-full transition-all duration-300 ease-out\"\n style={{ width: `${Math.max(0, Math.min(100, progress))}%` }}\n />\n </div>\n <p className=\"text-xs text-muted-foreground text-center\">{Math.round(progress)}%</p>\n </div>\n );\n};\n\nexport const LoadingIndicator = observer(LoadingIndicatorComponent);\nexport const InlineLoading = observer(InlineLoadingComponent);\nexport const LoadingProgress = observer(LoadingProgressComponent);\n","import React, { Component, ReactNode } from 'react';\nimport { AlertTriangle } from 'lucide-react';\nimport { cn } from '../lib/utils';\n\nexport interface ErrorBoundaryProps {\n children: ReactNode;\n fallback?: (error: Error, errorInfo: string, onReset: () => void) => ReactNode;\n onError?: (error: Error, errorInfo: string) => void;\n className?: string;\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n errorInfo: string | null;\n}\n\nexport class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = {\n hasError: false,\n error: null,\n errorInfo: null,\n };\n }\n\n static getDerivedStateFromError(error: Error): Partial<ErrorBoundaryState> {\n return {\n hasError: true,\n error,\n };\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {\n const errorInfoString = errorInfo.componentStack || '';\n \n this.setState({\n errorInfo: errorInfoString,\n });\n\n // Call optional error reporting callback\n this.props.onError?.(error, errorInfoString);\n\n // Log error for debugging\n console.error('ErrorBoundary caught an error:', error);\n console.error('Error Info:', errorInfo);\n }\n\n handleReset = () => {\n this.setState({\n hasError: false,\n error: null,\n errorInfo: null,\n });\n };\n\n render() {\n if (this.state.hasError) {\n const { fallback, className } = this.props;\n const { error, errorInfo } = this.state;\n\n // Use custom fallback if provided\n if (fallback && error) {\n return fallback(error, errorInfo || '', this.handleReset);\n }\n\n // Default error UI\n return (\n <div\n className={cn(\n 'flex flex-col items-center justify-center p-8 text-center border border-destructive/20 rounded-lg bg-destructive/5',\n className\n )}\n role=\"alert\"\n aria-live=\"assertive\"\n >\n <AlertTriangle \n className=\"w-12 h-12 text-destructive mb-4\" \n aria-hidden=\"true\"\n />\n \n <h2 className=\"text-lg font-semibold text-destructive mb-2\">\n Something went wrong\n </h2>\n \n <p className=\"text-sm text-muted-foreground mb-4 max-w-md\">\n {error?.message || 'An unexpected error occurred.'}\n </p>\n \n <div className=\"flex gap-2\">\n <button\n onClick={this.handleReset}\n className=\"px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90 focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 transition-colors\"\n >\n Try Again\n </button>\n \n <button\n onClick={() => window.location.reload()}\n className=\"px-4 py-2 bg-secondary text-secondary-foreground rounded-md hover:bg-secondary/90 focus:outline-none focus:ring-2 focus:ring-secondary focus:ring-offset-2 transition-colors\"\n >\n Reload Page\n </button>\n </div>\n \n {/* Error details removed to prevent build issues */}\n </div>\n );\n }\n\n return this.props.children;\n }\n}\n\nexport default ErrorBoundary; ","import { makeAutoObservable } from \"mobx\";\n\n// AICODE-NOTE: Grid layout calculator for precise positioning and sizing\nexport interface GridLayoutConfig {\n containerWidth: number;\n containerHeight: number;\n itemsPerRow: number | 'auto';\n gap: number;\n padding: number;\n minItemWidth: number;\n maxItemWidth: number;\n aspectRatio: number; // width/height ratio for items\n}\n\nexport interface GridItemLayout {\n x: number;\n y: number;\n width: number;\n height: number;\n thumbnailSize: number;\n textHeight: number;\n}\n\nexport interface GridLayoutResult {\n itemsPerRow: number;\n itemWidth: number;\n itemHeight: number;\n totalRows: number;\n totalHeight: number;\n items: GridItemLayout[];\n}\n\n// AICODE-NOTE: MobX-enabled calculation class for grid layouts with reactive updates\nexport class GridLayoutCalculator {\n private config: GridLayoutConfig;\n\n constructor(config: GridLayoutConfig) {\n this.config = config;\n makeAutoObservable(this, {});\n }\n\n // AICODE-NOTE: Update configuration and trigger reactive updates\n updateConfig(updates: Partial<GridLayoutConfig>): void {\n this.config = { ...this.config, ...updates };\n }\n\n // AICODE-NOTE: Computed getter for current configuration\n get currentConfig(): GridLayoutConfig {\n return this.config;\n }\n\n // AICODE-NOTE: Calculate optimal items per row based on container width\n calculateItemsPerRow(): number {\n if (typeof this.config.itemsPerRow === 'number') {\n return Math.max(1, this.config.itemsPerRow);\n }\n\n const { containerWidth, gap, padding, minItemWidth, maxItemWidth } = this.config;\n const availableWidth = containerWidth - (padding * 2);\n \n // console.log('🔢 [ITEMS PER ROW] Calculating:', {\n // containerWidth,\n // availableWidth,\n // minItemWidth,\n // maxItemWidth,\n // gap,\n // padding\n // });\n \n // If container is too small, return 1\n if (availableWidth < minItemWidth) {\n // console.log('🔢 [ITEMS PER ROW] Container too small, returning 1');\n return 1;\n }\n \n // Find the maximum number of items that can fit while respecting minItemWidth\n let bestItemsPerRow = 1;\n \n for (let itemsPerRow = 1; itemsPerRow <= 12; itemsPerRow++) {\n const totalGaps = (itemsPerRow - 1) * gap;\n const itemWidth = (availableWidth - totalGaps) / itemsPerRow;\n \n // console.log(`🔢 [ITEMS PER ROW] Testing ${itemsPerRow} items: itemWidth=${itemWidth.toFixed(1)}, fits=${itemWidth >= minItemWidth}, withinMax=${itemWidth <= maxItemWidth}`);\n \n if (itemWidth >= minItemWidth) {\n // Always use this if it fits the minimum width requirement\n bestItemsPerRow = itemsPerRow;\n // console.log(`🔢 [ITEMS PER ROW] Fits minimum: ${itemsPerRow} items (width: ${itemWidth.toFixed(1)})`);\n } else {\n // console.log(`🔢 [ITEMS PER ROW] Too narrow, breaking at ${itemsPerRow} items`);\n break; // Too many items per row\n }\n }\n \n // console.log(`🔢 [ITEMS PER ROW] Final result: ${bestItemsPerRow} items per row (container: ${containerWidth}px, min: ${minItemWidth}px)`);\n return bestItemsPerRow;\n }\n\n // AICODE-NOTE: Calculate item dimensions based on items per row\n calculateItemDimensions(itemsPerRow: number): { width: number; height: number } {\n const { containerWidth, gap, padding, aspectRatio } = this.config;\n const availableWidth = containerWidth - (padding * 2);\n const totalGaps = (itemsPerRow - 1) * gap;\n const itemWidth = (availableWidth - totalGaps) / itemsPerRow;\n const itemHeight = itemWidth / aspectRatio;\n \n // AICODE-NOTE: Ensure calculated width doesn't cause overflow\n const maxAllowedWidth = (containerWidth - (padding * 2) - ((itemsPerRow - 1) * gap)) / itemsPerRow;\n const safeItemWidth = Math.min(itemWidth, maxAllowedWidth);\n const safeItemHeight = safeItemWidth / aspectRatio;\n \n\n \n return {\n width: Math.floor(safeItemWidth),\n height: Math.floor(safeItemHeight)\n };\n }\n\n // AICODE-NOTE: Calculate thumbnail size within item with proper spacing\n calculateThumbnailSize(itemWidth: number, itemHeight: number): number {\n const textHeight = 40; // Reserve space for text and metadata\n const itemPadding = 8; // Internal padding around thumbnail\n const availableWidth = itemWidth - itemPadding;\n const availableHeight = itemHeight - textHeight - itemPadding;\n \n // Use the smaller dimension to ensure thumbnail fits properly\n const maxThumbnailSize = Math.min(availableWidth, availableHeight);\n \n // Ensure minimum thumbnail size for usability\n return Math.max(32, Math.floor(maxThumbnailSize));\n }\n\n // AICODE-NOTE: Calculate layout for all items with precise thumbnail sizing\n calculateLayout(totalItems: number): GridLayoutResult {\n const itemsPerRow = this.calculateItemsPerRow();\n const { width: itemWidth, height: itemHeight } = this.calculateItemDimensions(itemsPerRow);\n const thumbnailSize = this.calculateThumbnailSize(itemWidth, itemHeight);\n const textHeight = 60;\n \n // AICODE-NOTE: Validate that layout doesn't exceed container width\n const totalRowWidth = (itemsPerRow * itemWidth) + ((itemsPerRow - 1) * this.config.gap) + (this.config.padding * 2);\n \n // console.log('🧮 [GRID CALCULATOR] Layout debug:', {\n // totalItems,\n // itemsPerRow,\n // itemWidth,\n // itemHeight,\n // thumbnailSize,\n // totalRowWidth,\n // containerWidth: this.config.containerWidth,\n // exceeds: totalRowWidth > this.config.containerWidth,\n // config: this.config\n // });\n \n const totalRows = Math.ceil(totalItems / itemsPerRow);\n const totalHeight = (totalRows * itemHeight) + ((totalRows - 1) * this.config.gap) + (this.config.padding * 2);\n \n const items: GridItemLayout[] = [];\n \n for (let i = 0; i < totalItems; i++) {\n const row = Math.floor(i / itemsPerRow);\n const col = i % itemsPerRow;\n \n const x = this.config.padding + (col * (itemWidth + this.config.gap));\n const y = this.config.padding + (row * (itemHeight + this.config.gap));\n \n // AICODE-NOTE: Ensure item doesn't exceed container bounds\n const clampedX = Math.min(x, this.config.containerWidth - itemWidth - this.config.padding);\n \n items.push({\n x: clampedX,\n y,\n width: itemWidth,\n height: itemHeight,\n thumbnailSize,\n textHeight\n });\n }\n \n return {\n itemsPerRow,\n itemWidth,\n itemHeight,\n totalRows,\n totalHeight,\n items\n };\n }\n\n // AICODE-NOTE: Calculate visible items for virtualization\n calculateVisibleItems(\n totalItems: number,\n scrollTop: number,\n viewportHeight: number,\n overscan: number = 2\n ): { startIndex: number; endIndex: number; visibleItems: GridItemLayout[] } {\n const layout = this.calculateLayout(totalItems);\n const rowHeight = layout.itemHeight + this.config.gap;\n \n // Calculate visible row range\n const startRow = Math.max(0, Math.floor(scrollTop / rowHeight) - overscan);\n const endRow = Math.min(\n layout.totalRows - 1,\n Math.ceil((scrollTop + viewportHeight) / rowHeight) + overscan\n );\n \n const startIndex = startRow * layout.itemsPerRow;\n const endIndex = Math.min(totalItems - 1, (endRow + 1) * layout.itemsPerRow - 1);\n \n const visibleItems = layout.items.slice(startIndex, endIndex + 1);\n \n return {\n startIndex,\n endIndex,\n visibleItems\n };\n }\n\n // AICODE-NOTE: Get item position by index\n getItemPosition(itemIndex: number, totalItems: number): GridItemLayout | null {\n const layout = this.calculateLayout(totalItems);\n return layout.items[itemIndex] || null;\n }\n\n // AICODE-NOTE: Find item at position (for hit testing)\n getItemAtPosition(x: number, y: number, totalItems: number): number | null {\n const layout = this.calculateLayout(totalItems);\n \n for (let i = 0; i < layout.items.length; i++) {\n const item = layout.items[i];\n if (item && \n x >= item.x &&\n x <= item.x + item.width &&\n y >= item.y &&\n y <= item.y + item.height\n ) {\n return i;\n }\n }\n \n return null;\n }\n}\n\n// AICODE-NOTE: Factory function for common grid configurations\nexport function createGridCalculator(\n containerWidth: number,\n containerHeight: number,\n options: Partial<GridLayoutConfig> = {}\n): GridLayoutCalculator {\n const defaultConfig: GridLayoutConfig = {\n containerWidth,\n containerHeight,\n itemsPerRow: 'auto',\n gap: 12,\n padding: 16,\n minItemWidth: 160,\n maxItemWidth: 400,\n aspectRatio: 0.9, // Slightly portrait for better thumbnails\n ...options\n };\n \n return new GridLayoutCalculator(defaultConfig);\n}\n\n// AICODE-NOTE: Preset configurations for different use cases\nexport const GRID_PRESETS = {\n compact: {\n gap: 8,\n padding: 12,\n minItemWidth: 120,\n maxItemWidth: 200,\n aspectRatio: 0.85\n },\n comfortable: {\n gap: 16,\n padding: 20,\n minItemWidth: 200,\n maxItemWidth: 300,\n aspectRatio: 0.9\n },\n spacious: {\n gap: 24,\n padding: 32,\n minItemWidth: 280,\n maxItemWidth: 400,\n aspectRatio: 0.95\n }\n} as const; ","// AICODE-NOTE: DOM-free masonry layout engine based on Masonry.js algorithm\n// Supports both horizontal and vertical masonry with aspect ratio preservation\n\nexport interface MasonryItem {\n id: string;\n width: number;\n height: number;\n aspectRatio?: number; // width/height ratio\n}\n\nexport interface MasonryItemPosition {\n id: string;\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface MasonryLayoutResult {\n items: MasonryItemPosition[];\n totalHeight: number;\n totalWidth: number;\n columns: number;\n}\n\nexport interface MasonryConfig {\n containerWidth: number;\n columnWidth?: number; // If not provided, calculated from first item or container\n gutter: number;\n horizontalOrder: boolean; // true for horizontal masonry, false for vertical\n fitWidth?: boolean; // Fit container to used columns\n}\n\nexport class MasonryLayoutEngine {\n private config: MasonryConfig;\n private cache = new Map<string, MasonryLayoutResult>();\n private cacheKey = '';\n\n // Layout state\n private cols: number = 0;\n private colYs: number[] = [];\n private maxY: number = 0;\n private horizontalColIndex: number = 0;\n private calculatedColumnWidth: number = 0;\n\n // Horizontal masonry state\n private rows: Array<{ y: number; height: number; items: Array<{ x: number; width: number }> }> = [];\n\n // Public getter for calculated column width\n get columnWidth(): number {\n return this.calculatedColumnWidth;\n }\n\n constructor(config: MasonryConfig) {\n this.config = { ...config };\n this.resetLayout();\n }\n\n updateConfig(newConfig: Partial<MasonryConfig>): void {\n this.config = { ...this.config, ...newConfig };\n this.cache.clear(); // Clear cache when config changes\n this.resetLayout();\n }\n\n calculateLayout(items: MasonryItem[]): MasonryLayoutResult {\n // Early return for empty items\n if (items.length === 0) {\n return {\n items: [],\n totalHeight: 0,\n totalWidth: this.config.containerWidth,\n columns: 0\n };\n }\n\n // Generate cache key (optimized for large datasets)\n const configKey = `${this.config.containerWidth}:${this.config.columnWidth}:${this.config.gutter}:${this.config.horizontalOrder}`;\n const itemsHash = this.hashItems(items);\n const cacheKey = `${configKey}:${itemsHash}`;\n\n // Return cached result if available\n if (this.cache.has(cacheKey)) {\n return this.cache.get(cacheKey)!;\n }\n\n // Calculate fresh layout\n this.resetLayout();\n this.measureColumns(items);\n\n const positions: MasonryItemPosition[] = [];\n\n for (const item of items) {\n const position = this.getItemLayoutPosition(item);\n positions.push({\n id: item.id,\n x: position.x,\n y: position.y,\n width: item.width,\n height: item.height\n });\n }\n\n const result: MasonryLayoutResult = {\n items: positions,\n totalHeight: this.getContainerSize().height,\n totalWidth: this.getContainerSize().width,\n columns: this.cols\n };\n\n // Cache the result\n this.cache.set(cacheKey, result);\n \n // Limit cache size to prevent memory leaks\n if (this.cache.size > 50) { // Reduced cache size for better memory usage\n const firstKey = this.cache.keys().next().value;\n if (firstKey) {\n this.cache.delete(firstKey);\n }\n }\n\n return result;\n }\n\n // AICODE-NOTE: Optimized hash function for large item arrays\n private hashItems(items: MasonryItem[]): string {\n if (items.length <= 100) {\n // For small arrays, use detailed hash\n return items.map(item => `${item.id}:${item.width}:${item.height}`).join('|');\n } else {\n // For large arrays, use summary hash to avoid performance issues\n const summary = {\n count: items.length,\n firstId: items[0]?.id,\n lastId: items[items.length - 1]?.id,\n avgWidth: items.reduce((sum, item) => sum + item.width, 0) / items.length,\n avgHeight: items.reduce((sum, item) => sum + item.height, 0) / items.length\n };\n return JSON.stringify(summary);\n }\n }\n\n private resetLayout(): void {\n this.colYs = [];\n this.maxY = 0;\n this.horizontalColIndex = 0;\n this.rows = [];\n }\n\n private measureColumns(items: MasonryItem[]): void {\n // Calculate column width if not provided\n if (!this.config.columnWidth) {\n const firstItem = items[0];\n this.calculatedColumnWidth = firstItem?.width || this.config.containerWidth;\n } else {\n this.calculatedColumnWidth = this.config.columnWidth;\n }\n\n const columnWidth = this.calculatedColumnWidth + this.config.gutter;\n const containerWidth = this.config.containerWidth;\n let cols = (containerWidth + this.config.gutter) / columnWidth;\n\n // Fix rounding errors, typically with gutters\n const excess = columnWidth - (containerWidth % columnWidth);\n const mathMethod = excess && excess < 1 ? 'round' : 'floor';\n cols = Math[mathMethod](cols);\n this.cols = Math.max(cols, 1);\n\n // Initialize column Y positions with initial gutter offset\n this.colYs = [];\n for (let i = 0; i < this.cols; i++) {\n this.colYs.push(0);\n }\n }\n\n private getItemLayoutPosition(item: MasonryItem): { x: number; y: number } {\n if (this.config.horizontalOrder) {\n return this.getHorizontalLayoutPosition(item);\n } else {\n return this.getVerticalLayoutPosition(item);\n }\n }\n\n private getVerticalLayoutPosition(item: MasonryItem): { x: number; y: number } {\n // Calculate how many columns this item spans\n const remainder = item.width % this.calculatedColumnWidth;\n const mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';\n let colSpan = Math[mathMethod](item.width / this.calculatedColumnWidth);\n colSpan = Math.min(colSpan, this.cols);\n\n const colPosition = this.getTopColPosition(colSpan);\n\n // Calculate position: gutter on left edge, then (columnWidth + gutter) per column\n const position = {\n x: this.config.gutter + colPosition.col * (this.calculatedColumnWidth + this.config.gutter),\n y: colPosition.y + this.config.gutter\n };\n\n // Update column heights with gutter spacing\n const setHeight = colPosition.y + item.height + this.config.gutter;\n const setMax = colSpan + colPosition.col;\n for (let i = colPosition.col; i < setMax; i++) {\n this.colYs[i] = setHeight;\n }\n\n this.maxY = Math.max(this.maxY, setHeight);\n\n return position;\n }\n\n private getHorizontalLayoutPosition(item: MasonryItem): { x: number; y: number } {\n const itemWidth = item.width;\n const itemHeight = item.height;\n const gutter = this.config.gutter;\n const containerWidth = this.config.containerWidth;\n\n // Find the row with the shortest current width or create new row\n let targetRowIndex = -1;\n let targetX = gutter; // Start with left margin\n\n // Check existing rows to see if item fits\n for (let i = 0; i < this.rows.length; i++) {\n const row = this.rows[i];\n if (!row) continue;\n \n const currentRowWidth = row.items.reduce((sum, item) => sum + item.width + gutter, gutter);\n \n // Check if item fits in this row\n if (currentRowWidth + itemWidth + gutter <= containerWidth) {\n targetRowIndex = i;\n targetX = currentRowWidth;\n break;\n }\n }\n\n // If no existing row can fit the item, create a new row\n if (targetRowIndex === -1) {\n const lastRow = this.rows[this.rows.length - 1];\n const newRowY = this.rows.length === 0 ? gutter : \n (lastRow ? lastRow.y + lastRow.height + gutter : gutter);\n \n this.rows.push({\n y: newRowY,\n height: itemHeight,\n items: []\n });\n targetRowIndex = this.rows.length - 1;\n targetX = gutter;\n }\n\n const targetRow = this.rows[targetRowIndex];\n if (!targetRow) {\n // Fallback: create a new row if somehow targetRow is undefined\n this.rows.push({\n y: gutter,\n height: itemHeight,\n items: []\n });\n targetRowIndex = this.rows.length - 1;\n targetX = gutter;\n }\n\n const finalTargetRow = this.rows[targetRowIndex];\n if (finalTargetRow) {\n // Add item to the row\n finalTargetRow.items.push({\n x: targetX,\n width: itemWidth\n });\n\n // Update row height to accommodate the tallest item\n finalTargetRow.height = Math.max(finalTargetRow.height, itemHeight);\n\n // Calculate total height\n this.maxY = Math.max(this.maxY, finalTargetRow.y + finalTargetRow.height);\n }\n\n const finalRow = this.rows[targetRowIndex];\n return {\n x: targetX,\n y: finalRow ? finalRow.y : gutter\n };\n }\n\n private getTopColPosition(colSpan: number): { col: number; y: number } {\n const colGroup = this.getTopColGroup(colSpan);\n const minimumY = Math.min(...colGroup);\n const colIndex = colGroup.indexOf(minimumY);\n\n return {\n col: colIndex >= 0 ? colIndex : 0,\n y: minimumY\n };\n }\n\n private getTopColGroup(colSpan: number): number[] {\n if (colSpan < 2) {\n return this.colYs;\n }\n\n const colGroup: number[] = [];\n const groupCount = this.cols + 1 - colSpan;\n \n for (let i = 0; i < groupCount; i++) {\n colGroup[i] = this.getColGroupY(i, colSpan);\n }\n \n return colGroup;\n }\n\n private getColGroupY(col: number, colSpan: number): number {\n if (colSpan < 2) {\n return this.colYs[col] ?? 0;\n }\n \n const groupColYs = this.colYs.slice(col, col + colSpan);\n return groupColYs.length > 0 ? Math.max(...groupColYs) : 0;\n }\n\n private getHorizontalColPosition(colSpan: number, item: MasonryItem): { col: number; y: number } {\n let col = this.horizontalColIndex % this.cols;\n const isOver = colSpan > 1 && col + colSpan > this.cols;\n \n // Shift to next row if item can't fit on current row\n col = isOver ? 0 : col;\n \n // Don't let zero-size items take up space\n const hasSize = item.width && item.height;\n this.horizontalColIndex = hasSize ? col + colSpan : this.horizontalColIndex;\n\n return {\n col: col,\n y: this.getColGroupY(col, colSpan)\n };\n }\n\n private getContainerSize(): { height: number; width: number } {\n // For vertical masonry, maxY comes from colYs (column heights).\n // For horizontal masonry, maxY is accumulated in getHorizontalLayoutPosition\n // from this.rows — do NOT overwrite it from colYs (which are never updated).\n if (!this.config.horizontalOrder) {\n this.maxY = this.colYs.length > 0 ? Math.max(...this.colYs) : 0;\n }\n\n const size = {\n height: this.maxY + this.config.gutter, // Add final bottom gutter\n width: this.config.containerWidth\n };\n\n if (this.config.fitWidth) {\n size.width = this.getContainerFitWidth();\n }\n\n return size;\n }\n\n private getContainerFitWidth(): number {\n let unusedCols = 0;\n let i = this.cols;\n \n while (--i) {\n if (this.colYs[i] !== 0) {\n break;\n }\n unusedCols++;\n }\n \n return (this.cols - unusedCols) * this.calculatedColumnWidth - this.config.gutter;\n }\n\n // Utility method to clear cache manually\n clearCache(): void {\n this.cache.clear();\n }\n\n // Get cache statistics for debugging\n getCacheStats(): { size: number; keys: string[] } {\n return {\n size: this.cache.size,\n keys: Array.from(this.cache.keys())\n };\n }\n}\n\n// Factory functions for common configurations\nexport function createVerticalMasonry(containerWidth: number, columnWidth?: number, gutter: number = 4): MasonryLayoutEngine {\n return new MasonryLayoutEngine({\n containerWidth,\n columnWidth,\n gutter,\n horizontalOrder: false\n });\n}\n\nexport function createHorizontalMasonry(containerWidth: number, columnWidth?: number, gutter: number = 4): MasonryLayoutEngine {\n return new MasonryLayoutEngine({\n containerWidth,\n columnWidth,\n gutter,\n horizontalOrder: true\n });\n} ","import { makeAutoObservable, observable, flow } from \"mobx\";\nimport {\n LIST_VIEW_TYPE,\n} from \"../providers/ListItemsProvider\";\nimport type {\n ListItemsProvider,\n ListItemsProviderListener,\n ListViewType,\n} from \"../providers/ListItemsProvider\";\nimport type {\n ListItemData,\n ListLoadOptions,\n ListLoadResult,\n ListSelectionInfo,\n ListDragDropInfo\n} from \"../types/ListTypes\";\nimport { benchmark } from \"../utils/BenchmarkLogger\";\nimport { GridLayoutCalculator, createGridCalculator, type GridItemLayout } from \"../utils/GridLayoutCalculator\";\nimport { MasonryLayoutEngine, createVerticalMasonry, createHorizontalMasonry, type MasonryItem, type MasonryItemPosition } from \"../utils/MasonryLayoutEngine\";\n\n// AICODE-NOTE: List could be in different states: thumbnail, grid, list, details and shuld be possible to define custom states..\n// AICODE-NOTE: It could be used in file explorer like windows explorer or finder but also in other places\n// AICODE-NOTE: Should use virtualized list like react-window\n// AICODE-NOTE: for provider/model design see ../TreeComponent/models/TreeModel.ts\n\n// AICODE-NOTE: Skeleton UI or shimmer for items while loading; graceful error display.\n// AICODE-NOTE: Expose imperative methods (scroll to item, focus item, programmatically select, refresh, etc.).\n// AICODE-NOTE: Support single, multiple, and range selection with shift/control modifiers; expose selected item(s) via API.\n// AICODE-NOTE: Think about Item interface, it should be flexible and support different types of items.\n\nexport class ListItemsModel implements ListItemsProviderListener {\n currentViewType: ListViewType = LIST_VIEW_TYPE;\n \n // AICODE-NOTE: Core data using observable collections for reactive updates\n _allItems: ListItemData[] = [];\n itemMap = observable.map<string, ListItemData>();\n totalItemCount: number = 0;\n\n // Search/filter state\n searchQuery: string = '';\n \n // AICODE-NOTE: Selection state using observable.map for O(1) lookups\n selectedItems = observable.map<string, ListItemData>();\n previousSelection: ListItemData[] = [];\n focusedItem: string | null = null;\n\n // Range selection anchor - tracks the starting point for shift+click range selection\n selectionAnchor: string | null = null;\n\n // AICODE-NOTE: Loading state for different ranges and operations\n isLoading: boolean = false;\n loadingRanges = observable.map<string, boolean>();\n errors = observable.map<string, Error>();\n \n // AICODE-NOTE: Virtualization state for handling huge datasets\n viewportRange: { start: number; end: number } = { start: 0, end: 0 };\n scrollPosition: number = 0;\n containerSize: { width: number; height: number } = { width: 0, height: 0 };\n \n // AICODE-NOTE: Drag and drop state\n isDragging: boolean = false;\n draggedItems: ListItemData[] = [];\n dragOverItem: string | null = null;\n dragOverPosition: 'before' | 'after' | 'inside' | null = null;\n \n // AICODE-NOTE: View size management state\n itemSize: 'small' | 'medium' | 'large' | 'extra-large' = 'medium';\n customItemWidth: number = 200;\n customItemHeight: number = 220;\n itemsPerRow: number | 'auto' = 'auto';\n \n // AICODE-NOTE: Layout calculators for precise positioning\n private gridCalculator: GridLayoutCalculator | null = null;\n private verticalMasonryEngine: MasonryLayoutEngine | null = null;\n private horizontalMasonryEngine: MasonryLayoutEngine | null = null;\n \n // AICODE-NOTE: Debug visualization toggle\n debugVisualization: boolean = false;\n\n // Compact mode: details view shows only Icon + Name\n compactMode: boolean = false;\n\n // Column visibility for details view (only relevant when compactMode is false)\n columnVisibility: { type: boolean; modified: boolean; size: boolean } = {\n type: true,\n modified: true,\n size: true\n };\n\n // Checkbox mode for multi-select\n showCheckboxes: boolean = false;\n\n // Scroll-to-item: views watch this and scroll their container when set\n scrollToItemId: string | null = null;\n\n // Pagination state\n pageSize: number = 50;\n currentPage: number = 0;\n\n constructor(public provider: ListItemsProvider) {\n makeAutoObservable(this, {});\n }\n\n // =====================\n // Computed filtered items\n // =====================\n\n get items(): ListItemData[] {\n if (!this.searchQuery) return this._allItems;\n const q = this.searchQuery.toLowerCase();\n return this._allItems.filter(item => item.name.toLowerCase().includes(q));\n }\n\n get hasSearchQuery(): boolean {\n return this.searchQuery.length > 0;\n }\n\n get allItemsCount(): number {\n return this._allItems.length;\n }\n\n setSearchQuery(query: string): void {\n this.searchQuery = query;\n }\n\n clearSearch(): void {\n this.searchQuery = '';\n }\n\n clearItems(): void {\n this._allItems = [];\n }\n\n // =====================\n // ListItemsProviderListener Implementation\n // =====================\n \n onItemsCountChanged(count: number): void {\n this.totalItemCount = count;\n // AICODE-NOTE: Notify UI components that the total count has changed\n // This is useful for virtualization and pagination\n }\n \n onItemChanged(itemIndex: number): void {\n // AICODE-NOTE: Handle individual item changes for reactive updates\n // This allows providers to notify of granular changes without full reload\n if (itemIndex >= 0 && itemIndex < this._allItems.length) {\n // Trigger re-render for specific item by updating the map\n const item = this._allItems[itemIndex];\n if (item) {\n this.itemMap.set(item.id, { ...item });\n }\n }\n }\n\n // =====================\n // Computed Properties\n // =====================\n \n get selectedItemsArray(): ListItemData[] {\n return Array.from(this.selectedItems.values());\n }\n \n get hasSelection(): boolean {\n return this.selectedItems.size > 0;\n }\n \n get isItemSelected() {\n return (itemId: string) => this.selectedItems.has(itemId);\n }\n \n get itemHeight(): number {\n return this.provider.getItemHeight(this.currentViewType);\n }\n\n get isLoaded(): boolean {\n return !this.isLoading && this._allItems.length > 0;\n }\n\n get hasErrors(): boolean {\n return this.errors.size > 0;\n }\n\n // AICODE-NOTE: Performance optimized computed properties\n get selectedItemIds(): Set<string> {\n return new Set(this.selectedItems.keys());\n }\n\n get visibleItemsCount(): number {\n const { start, end } = this.viewportRange;\n return Math.max(0, end - start + 1);\n }\n\n get loadedItemsCount(): number {\n return this._allItems.filter(item => item !== null && item !== undefined).length;\n }\n\n get loadingProgress(): number {\n if (this.totalItemCount === 0) return 0;\n return Math.min(100, (this.loadedItemsCount / this.totalItemCount) * 100);\n }\n\n get isFullyLoaded(): boolean {\n return this.loadedItemsCount >= this.totalItemCount;\n }\n\n get totalPages(): number {\n if (this.pageSize <= 0 || this.totalItemCount <= 0) return 0;\n return Math.ceil(this.totalItemCount / this.pageSize);\n }\n\n get hasNextPage(): boolean {\n return this.currentPage < this.totalPages - 1;\n }\n\n get hasPreviousPage(): boolean {\n return this.currentPage > 0;\n }\n\n // =====================\n // Pagination Actions\n // =====================\n\n goToPage = flow(function* (this: ListItemsModel, page: number) {\n if (page < 0 || page >= this.totalPages) return;\n this.currentPage = page;\n yield this.loadItems({ limit: this.pageSize, offset: page * this.pageSize });\n });\n\n nextPage = flow(function* (this: ListItemsModel) {\n if (this.hasNextPage) {\n yield this.goToPage(this.currentPage + 1);\n }\n });\n\n prevPage = flow(function* (this: ListItemsModel) {\n if (this.hasPreviousPage) {\n yield this.goToPage(this.currentPage - 1);\n }\n });\n\n setPageSize(size: number): void {\n if (size > 0) {\n this.pageSize = size;\n this.currentPage = 0;\n }\n }\n\n // =====================\n // Async Actions (using flow for MobX best practices)\n // =====================\n \n /**\n * Load items from the provider\n * Uses MobX flow for proper async action handling\n */\n loadItems = flow(function* (this: ListItemsModel, options?: ListLoadOptions) {\n benchmark.start('loadItems', { \n itemCount: this.items.length, \n viewType: this.currentViewType.id,\n options \n });\n \n this.isLoading = true;\n this.errors.clear();\n \n try {\n benchmark.start('provider.loadItems');\n const result: ListLoadResult = yield this.provider.loadItems(options);\n benchmark.end('provider.loadItems', { itemCount: result.items.length });\n \n benchmark.start('updateItemsAndMap');\n // Update items and item map\n this._allItems = result.items;\n this.totalItemCount = result.totalCount ?? result.items.length;\n\n // Update item map for fast lookups\n this.itemMap.clear();\n result.items.forEach((item: ListItemData) => this.itemMap.set(item.id, item));\n benchmark.end('updateItemsAndMap', { itemCount: result.items.length });\n \n } catch (error) {\n const errorKey = 'loadItems';\n this.errors.set(errorKey, error instanceof Error ? error : new Error(String(error)));\n } finally {\n this.isLoading = false;\n benchmark.end('loadItems', { \n finalItemCount: this.items.length,\n hasErrors: this.errors.size > 0\n });\n }\n });\n\n /**\n * Load a specific range of items for virtualization\n */\n loadItemRange = flow(function* (this: ListItemsModel, start: number, end: number) {\n const rangeKey = `${start}-${end}`;\n this.loadingRanges.set(rangeKey, true);\n \n try {\n const result: ListLoadResult = yield this.provider.loadItemRange?.(start, end) ?? { items: [] };\n \n // Merge items into existing array at correct positions\n result.items.forEach((item, index) => {\n const absoluteIndex = start + index;\n this._allItems[absoluteIndex] = item;\n this.itemMap.set(item.id, item);\n });\n \n } catch (error) {\n this.errors.set(rangeKey, error instanceof Error ? error : new Error(String(error)));\n } finally {\n this.loadingRanges.delete(rangeKey);\n }\n });\n\n /**\n * Refresh items from provider\n */\n refresh = flow(function* (this: ListItemsModel) {\n if (this.provider.refresh) {\n this.isLoading = true;\n this.errors.clear();\n \n try {\n const result: ListLoadResult = yield this.provider.refresh();\n this._allItems = result.items;\n this.totalItemCount = result.totalCount ?? result.items.length;\n\n // Update item map\n this.itemMap.clear();\n result.items.forEach((item: ListItemData) => this.itemMap.set(item.id, item));\n \n } catch (error) {\n this.errors.set('refresh', error instanceof Error ? error : new Error(String(error)));\n } finally {\n this.isLoading = false;\n }\n }\n });\n\n // =====================\n // Selection Actions\n // =====================\n \n /**\n * Select a single item with proper single/multi-selection logic\n */\n selectItem(item: ListItemData, modifiers?: { ctrl?: boolean; shift?: boolean }): void {\n // Store previous selection for callback\n this.previousSelection = [...this.selectedItemsArray];\n\n const wasSelected = this.selectedItems.has(item.id);\n const isMultiSelectMode = this.provider.isMultiSelectEnabled && modifiers?.ctrl;\n const isRangeSelectMode = this.provider.isMultiSelectEnabled && modifiers?.shift;\n\n if (isRangeSelectMode && this.selectionAnchor) {\n // Shift+click: select range from anchor to clicked item\n this.selectRange(this.selectionAnchor, item.id);\n } else if (isMultiSelectMode) {\n // Ctrl+click: toggle individual item\n if (wasSelected) {\n this.selectedItems.delete(item.id);\n } else {\n this.selectedItems.set(item.id, item);\n }\n // Update anchor to current item for future range selections\n this.selectionAnchor = item.id;\n } else {\n // Plain click: single selection\n this.selectedItems.clear();\n this.selectedItems.set(item.id, item);\n // Set anchor for future shift+click range selections\n this.selectionAnchor = item.id;\n }\n\n // Always update focused item when clicking\n this.focusedItem = item.id;\n\n // Notify provider of selection change\n if (this.provider.onSelectionChange) {\n this.provider.onSelectionChange({\n selectedItems: this.selectedItemsArray,\n previousSelection: this.previousSelection,\n selectionType: isRangeSelectMode ? 'range' : (isMultiSelectMode ? 'multi' : 'single'),\n trigger: 'click'\n });\n }\n }\n\n /**\n * Select a contiguous range of items between two item IDs\n */\n selectRange(fromId: string, toId: string): void {\n const fromIndex = this.items.findIndex(item => item.id === fromId);\n const toIndex = this.items.findIndex(item => item.id === toId);\n\n if (fromIndex === -1 || toIndex === -1) return;\n\n const start = Math.min(fromIndex, toIndex);\n const end = Math.max(fromIndex, toIndex);\n\n this.selectedItems.clear();\n for (let i = start; i <= end; i++) {\n const item = this.items[i];\n if (item) {\n this.selectedItems.set(item.id, item);\n }\n }\n }\n\n /**\n * Clear all selection\n */\n clearSelection(): void {\n const hadSelection = this.selectedItems.size > 0;\n if (!hadSelection) return;\n \n // Store previous selection for callback\n this.previousSelection = [...this.selectedItemsArray];\n this.selectedItems.clear();\n \n if (this.provider.onSelectionChange) {\n this.provider.onSelectionChange({\n selectedItems: [],\n previousSelection: this.previousSelection,\n selectionType: this.provider.isMultiSelectEnabled ? 'multi' : 'single',\n trigger: 'api'\n });\n }\n }\n\n /**\n * Select all items (if multi-select enabled)\n */\n selectAll(): void {\n if (!this.provider.isMultiSelectEnabled) return;\n \n this.selectedItems.clear();\n this.items.forEach(item => {\n this.selectedItems.set(item.id, item);\n });\n \n if (this.provider.onSelectionChange) {\n this.provider.onSelectionChange({\n selectedItems: this.selectedItemsArray,\n previousSelection: [],\n selectionType: 'multi',\n trigger: 'api'\n });\n }\n }\n\n // =====================\n // View Type Management\n // =====================\n \n /**\n * Set the current view type\n */\n setViewType(viewType: ListViewType): void {\n console.log('ListItemsModel.setViewType called:', {\n from: this.currentViewType.id,\n to: viewType.id,\n same: this.currentViewType.id === viewType.id\n });\n \n if (this.currentViewType.id !== viewType.id) {\n this.currentViewType = viewType;\n console.log('View type changed to:', this.currentViewType.id);\n \n // Notify provider\n if (this.provider.onViewTypeChange) {\n this.provider.onViewTypeChange(viewType);\n }\n } else {\n console.log('View type not changed - same as current');\n }\n }\n\n // =====================\n // Size Management\n // =====================\n \n /**\n * Set item size for grid and masonry views\n */\n setItemSize(size: 'small' | 'medium' | 'large' | 'extra-large'): void {\n this.itemSize = size;\n \n // Update custom dimensions based on size\n const sizeMap = {\n 'small': { width: 160, height: 120 },\n 'medium': { width: 240, height: 180 },\n 'large': { width: 320, height: 240 },\n 'extra-large': { width: 400, height: 300 }\n };\n \n const dimensions = sizeMap[size];\n this.customItemWidth = dimensions.width;\n this.customItemHeight = dimensions.height;\n \n // Update calculators with new dimensions\n this.updateLayoutCalculators();\n }\n \n /**\n * Set custom item width and update calculators\n */\n setCustomItemWidth(width: number): void {\n this.customItemWidth = Math.max(120, Math.min(600, width));\n this.updateLayoutCalculators();\n }\n \n /**\n * Set custom item height and update calculators\n */\n setCustomItemHeight(height: number): void {\n this.customItemHeight = Math.max(80, Math.min(500, height));\n this.updateLayoutCalculators();\n }\n \n /**\n * Get current item dimensions\n */\n get itemDimensions(): { width: number; height: number } {\n return {\n width: this.customItemWidth,\n height: this.customItemHeight\n };\n }\n \n /**\n * Set items per row for grid and masonry views\n */\n setItemsPerRow(itemsPerRow: number | 'auto'): void {\n this.itemsPerRow = itemsPerRow;\n this.updateLayoutCalculators();\n }\n \n /**\n * Set debug visualization mode\n */\n setDebugVisualization(enabled: boolean): void {\n this.debugVisualization = enabled;\n }\n\n setCompactMode(compact: boolean): void {\n this.compactMode = compact;\n }\n\n toggleCheckboxes(): void {\n this.showCheckboxes = !this.showCheckboxes;\n }\n\n setShowCheckboxes(show: boolean): void {\n this.showCheckboxes = show;\n }\n\n setColumnVisibility(column: 'type' | 'modified' | 'size', visible: boolean): void {\n this.columnVisibility = { ...this.columnVisibility, [column]: visible };\n }\n\n get detailsGridTemplateColumns(): string {\n const cols: string[] = [];\n if (this.showCheckboxes) cols.push('20px');\n cols.push('24px', 'minmax(0, 1fr)');\n if (!this.compactMode) {\n if (this.columnVisibility.type) cols.push('100px');\n if (this.columnVisibility.modified) cols.push('140px');\n if (this.columnVisibility.size) cols.push('90px');\n }\n return cols.join(' ');\n }\n\n /**\n * Generate random aspect ratio for Pinterest-like variety\n */\n /**\n * Deterministic aspect ratio based on item id (stable across re-renders).\n * Uses a simple hash to pick from predefined ratios.\n */\n private generateDeterministicAspectRatio(id: string): number {\n const ratios = [0.6, 0.7, 0.8, 1.0, 1.2, 1.4, 1.6];\n let hash = 0;\n for (let i = 0; i < id.length; i++) {\n hash = ((hash << 5) - hash + id.charCodeAt(i)) | 0;\n }\n const index = Math.abs(hash) % ratios.length;\n return ratios[index] ?? 1.0;\n }\n \n /**\n * Get effective items per row based on view and container width\n */\n getEffectiveItemsPerRow(containerWidth?: number): number {\n if (typeof this.itemsPerRow === 'number') {\n return this.itemsPerRow;\n }\n \n // Auto calculation based on container width and item width\n if (containerWidth) {\n const itemWidth = this.customItemWidth;\n const gap = 12; // Default gap\n const availableWidth = containerWidth - (gap * 2);\n const itemsWithGaps = Math.floor((availableWidth + gap) / (itemWidth + gap));\n return Math.max(1, Math.min(8, itemsWithGaps));\n }\n \n return 4; // Default fallback\n }\n\n // =====================\n // Focus Management\n // =====================\n\n /**\n * Set focused item\n */\n setFocusedItem(itemId: string | null): void {\n this.focusedItem = itemId;\n }\n\n /**\n * Focus next item\n */\n focusNext(): boolean {\n if (this.items.length === 0) return false;\n\n const currentIndex = this.focusedItem\n ? this.items.findIndex(item => item.id === this.focusedItem)\n : -1;\n\n const nextIndex = currentIndex < this.items.length - 1 ? currentIndex + 1 : 0;\n const nextItem = this.items[nextIndex];\n if (nextItem) {\n this.focusedItem = nextItem.id;\n }\n return true;\n }\n\n /**\n * Focus previous item\n */\n focusPrevious(): boolean {\n if (this.items.length === 0) return false;\n\n const currentIndex = this.focusedItem\n ? this.items.findIndex(item => item.id === this.focusedItem)\n : 0;\n\n const prevIndex = currentIndex > 0 ? currentIndex - 1 : this.items.length - 1;\n const prevItem = this.items[prevIndex];\n if (prevItem) {\n this.focusedItem = prevItem.id;\n }\n return true;\n }\n\n /**\n * Focus the first item in the list\n */\n focusFirst(): boolean {\n if (this.items.length === 0) return false;\n const firstItem = this.items[0];\n if (firstItem) {\n this.focusedItem = firstItem.id;\n this.ensureItemVisible(firstItem.id);\n }\n return true;\n }\n\n /**\n * Focus the last item in the list\n */\n focusLast(): boolean {\n if (this.items.length === 0) return false;\n const lastItem = this.items[this.items.length - 1];\n if (lastItem) {\n this.focusedItem = lastItem.id;\n this.ensureItemVisible(lastItem.id);\n }\n return true;\n }\n\n // =====================\n // Keyboard Navigation\n // =====================\n\n /**\n * Handle keyboard events for list navigation.\n * Can be used directly via onKeyDown on a container element,\n * or the useListKeyboard hook can be used for automatic attachment.\n *\n * - ArrowUp/ArrowDown: navigate between items\n * - Home/End: jump to first/last item\n * - Enter: open focused item (navigate into folder or open file)\n * - Space: toggle selection of focused item\n * - Escape: clear selection, or navigate up one directory level if nothing selected\n * - Ctrl+A: select all items\n */\n handleKeyDown(event: KeyboardEvent): void {\n // Skip when an input/textarea is focused (e.g. inline rename)\n const tag = (event.target as HTMLElement)?.tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA') return;\n\n if (this.items.length === 0) return;\n\n const { key, ctrlKey, metaKey, shiftKey } = event;\n const isModifier = ctrlKey || metaKey;\n\n switch (key) {\n case 'ArrowUp': {\n event.preventDefault();\n const idx = this.getFocusedIndex();\n if (idx > 0) {\n this.navigateToIndex(idx - 1, shiftKey);\n }\n break;\n }\n case 'ArrowDown': {\n event.preventDefault();\n const idx = this.getFocusedIndex();\n if (idx < this.items.length - 1) {\n this.navigateToIndex(idx + 1, shiftKey);\n }\n break;\n }\n case 'Home': {\n event.preventDefault();\n this.navigateToIndex(0, shiftKey);\n break;\n }\n case 'End': {\n event.preventDefault();\n this.navigateToIndex(this.items.length - 1, shiftKey);\n break;\n }\n case 'Enter': {\n event.preventDefault();\n const item = this.focusedItem ? this.getItem(this.focusedItem) : this.items[0];\n if (item && this.provider.onItemDoubleClick) {\n this.provider.onItemDoubleClick(item);\n }\n break;\n }\n case ' ': {\n event.preventDefault();\n const item = this.focusedItem ? this.getItem(this.focusedItem) : this.items[0];\n if (item) {\n this.selectItem(item, { ctrl: true, shift: shiftKey });\n }\n break;\n }\n case 'Escape': {\n event.preventDefault();\n if (this.hasSelection) {\n this.clearSelection();\n } else if (this.provider.onNavigateUp) {\n this.provider.onNavigateUp();\n }\n break;\n }\n case 'a':\n case 'A': {\n if (isModifier) {\n event.preventDefault();\n this.selectAll();\n }\n break;\n }\n }\n }\n\n /**\n * Get the index of the currently focused item, defaulting to 0\n */\n private getFocusedIndex(): number {\n if (!this.focusedItem) return 0;\n const idx = this.items.findIndex(item => item.id === this.focusedItem);\n return idx === -1 ? 0 : idx;\n }\n\n /**\n * Navigate to a specific item index, updating focus, selection, and scroll\n */\n private navigateToIndex(index: number, extendSelection: boolean = false): void {\n const item = this.items[index];\n if (!item) return;\n\n this.focusedItem = item.id;\n\n if (extendSelection && this.provider.isMultiSelectEnabled) {\n if (!this.selectionAnchor) {\n this.selectionAnchor = this.focusedItem || item.id;\n }\n this.selectRange(this.selectionAnchor, item.id);\n } else {\n this.selectItem(item);\n }\n\n this.ensureItemVisible(item.id);\n }\n\n // =====================\n // Drag and Drop Management\n // =====================\n \n /**\n * Check if an item can be dragged\n */\n canDragItem(item: ListItemData): boolean {\n if (!this.provider.isDragDropEnabled) return false;\n return this.provider.canDragItem?.(item) ?? true;\n }\n \n /**\n * Check if items can be dropped on a target\n */\n canDropItems(draggedItems: ListItemData[], targetItem: ListItemData | null, position: 'before' | 'after' | 'inside'): boolean {\n if (!this.provider.isDragDropEnabled) return false;\n return this.provider.canDropItems?.(draggedItems, targetItem, position) ?? true;\n }\n \n /**\n * Start drag operation\n */\n startDrag(items: ListItemData[], event: DragEvent): void {\n if (!this.provider.isDragDropEnabled) return;\n \n this.isDragging = true;\n this.draggedItems = items;\n \n // AICODE-NOTE: Set drag data for HTML5 drag and drop\n const itemIds = items.map(item => item.id);\n event.dataTransfer?.setData('application/json', JSON.stringify({\n type: 'list-items',\n itemIds\n }));\n \n // AICODE-NOTE: Set drag effect\n if (event.dataTransfer) {\n event.dataTransfer.effectAllowed = 'move';\n }\n \n // Notify provider\n if (this.provider.onDragStart) {\n this.provider.onDragStart(items, event);\n }\n }\n \n /**\n * Handle drag over item\n */\n setDragOver(itemId: string | null, position: 'before' | 'after' | 'inside' | null): void {\n this.dragOverItem = itemId;\n this.dragOverPosition = position;\n }\n \n /**\n * Handle drop operation\n */\n handleDrop(targetItem: ListItemData | null, position: 'before' | 'after' | 'inside', event: DragEvent): boolean {\n if (!this.isDragging || this.draggedItems.length === 0) return false;\n \n // AICODE-NOTE: Check if drop is allowed\n if (!this.canDropItems(this.draggedItems, targetItem, position)) {\n this.endDrag(false);\n return false;\n }\n \n // AICODE-NOTE: Create drag drop info\n const dragDropInfo: ListDragDropInfo = {\n draggedItems: this.draggedItems,\n targetItem,\n position,\n event\n };\n \n // Notify provider\n if (this.provider.onDrop) {\n this.provider.onDrop(dragDropInfo);\n }\n \n this.endDrag(true);\n return true;\n }\n \n /**\n * End drag operation\n */\n endDrag(success: boolean): void {\n const draggedItems = [...this.draggedItems];\n \n this.isDragging = false;\n this.draggedItems = [];\n this.dragOverItem = null;\n this.dragOverPosition = null;\n \n // Notify provider\n if (this.provider.onDragEnd) {\n this.provider.onDragEnd(draggedItems, success);\n }\n }\n\n // =====================\n // Virtualization Support\n // =====================\n \n /**\n * Update viewport range for virtualization and trigger dynamic loading\n */\n updateViewportRange(start: number, end: number): void {\n this.viewportRange = { start, end };\n \n // AICODE-NOTE: Trigger dynamic loading for visible range\n this.loadVisibleItems(start, end);\n }\n\n /**\n * Load items that are visible in the current viewport\n */\n private loadVisibleItems = flow(function* (this: ListItemsModel, start: number, end: number) {\n // AICODE-NOTE: Check if provider supports range loading\n if (!this.provider.loadItemRange) {\n return;\n }\n\n // AICODE-NOTE: Expand range to include overscan for smoother scrolling\n const overscan = 10;\n const expandedStart = Math.max(0, start - overscan);\n const expandedEnd = Math.min(this.totalItemCount, end + overscan);\n\n // AICODE-NOTE: Check which items in the range are missing\n const missingRanges: Array<{ start: number; end: number }> = [];\n let rangeStart = -1;\n\n for (let i = expandedStart; i <= expandedEnd; i++) {\n const hasItem = i < this._allItems.length && this._allItems[i] !== undefined;\n \n if (!hasItem) {\n if (rangeStart === -1) {\n rangeStart = i;\n }\n } else {\n if (rangeStart !== -1) {\n missingRanges.push({ start: rangeStart, end: i - 1 });\n rangeStart = -1;\n }\n }\n }\n\n // AICODE-NOTE: Add final range if it extends to the end\n if (rangeStart !== -1) {\n missingRanges.push({ start: rangeStart, end: expandedEnd });\n }\n\n // AICODE-NOTE: Load missing ranges\n for (const range of missingRanges) {\n // AICODE-NOTE: Skip if already loading this range\n const rangeKey = `${range.start}-${range.end}`;\n if (this.loadingRanges.has(rangeKey)) {\n continue;\n }\n\n try {\n yield this.loadItemRange(range.start, range.end + 1);\n } catch (error) {\n console.warn('Failed to load item range:', range, error);\n }\n }\n });\n\n /**\n * Update scroll position\n */\n updateScrollPosition(position: number): void {\n this.scrollPosition = position;\n }\n\n /**\n * Update container size\n */\n updateContainerSize(width: number, height: number): void {\n this.containerSize = { width, height };\n \n // Update calculators with new container size\n this.updateLayoutCalculators();\n }\n\n // AICODE-NOTE: Layout calculator management\n \n /**\n * Update layout calculators with current settings\n */\n private updateLayoutCalculators(): void {\n const { width, height } = this.containerSize;\n \n\n \n if (width > 0 && height > 0) {\n // Update grid calculator with very flexible constraints for better auto-calculation\n // AICODE-NOTE: Prioritize fitting multiple items over exact size matching\n const minWidth = 120; // Absolute minimum for readability\n const maxWidth = width * 0.95; // Allow up to 95% of container width\n \n // console.log('📐 [MODEL] Grid constraints:', {\n // container: `${width}x${height}`,\n // minWidth,\n // maxWidth,\n // customItemWidth: this.customItemWidth,\n // itemsPerRow: this.itemsPerRow\n // });\n \n if (this.gridCalculator) {\n this.gridCalculator.updateConfig({\n containerWidth: width,\n containerHeight: height,\n itemsPerRow: this.itemsPerRow,\n minItemWidth: minWidth,\n maxItemWidth: maxWidth,\n aspectRatio: this.customItemWidth / this.customItemHeight\n });\n } else {\n this.gridCalculator = createGridCalculator(width, height, {\n itemsPerRow: this.itemsPerRow,\n minItemWidth: minWidth,\n maxItemWidth: maxWidth,\n aspectRatio: this.customItemWidth / this.customItemHeight\n });\n }\n \n // Update masonry engines with tight spacing for compact layout\n const gutter = 4; // Tight spacing for dense masonry layout\n\n // Calculate optimal column width for masonry layout\n const targetColumns = this.itemsPerRow === 'auto' ?\n Math.floor(width / 250) || 3 : // Default to ~250px columns\n (typeof this.itemsPerRow === 'number' ? this.itemsPerRow : 3);\n \n const availableWidth = width - (gutter * (targetColumns + 1));\n const columnWidth = Math.floor(availableWidth / targetColumns);\n \n if (this.verticalMasonryEngine) {\n this.verticalMasonryEngine.updateConfig({\n containerWidth: width,\n columnWidth,\n gutter,\n horizontalOrder: false\n });\n } else {\n this.verticalMasonryEngine = createVerticalMasonry(width, columnWidth, gutter);\n }\n \n if (this.horizontalMasonryEngine) {\n this.horizontalMasonryEngine.updateConfig({\n containerWidth: width,\n columnWidth,\n gutter,\n horizontalOrder: true\n });\n } else {\n this.horizontalMasonryEngine = createHorizontalMasonry(width, columnWidth, gutter);\n }\n }\n }\n\n /**\n * Get grid layout for current items\n */\n getGridLayout(): { layout: GridItemLayout[]; totalHeight: number } | null {\n // Don't call updateLayoutCalculators() here — it modifies observables and\n // would violate MobX strict mode when called during render.\n \n if (this.gridCalculator) {\n const result = this.gridCalculator.calculateLayout(this.items.length);\n return {\n layout: result.items,\n totalHeight: result.totalHeight\n };\n }\n \n return null;\n }\n\n /**\n * Check whether an item is an actual image that should get variable height\n * in masonry layout. Non-image items (folders, docs, code files) get uniform height.\n */\n private isImageItem(item: ListItemData): boolean {\n // Has an explicit aspect ratio set on the item data\n if (item.aspectRatio) return true;\n // Has a thumbnail URL (provider-supplied image)\n if (item.thumbnailUrl) return true;\n // Has an image URL\n if (item.imageUrl) return true;\n // Provider reports a measured aspect ratio for this path\n if (this.provider.getAspectRatio?.(item.path) !== undefined) return true;\n return false;\n }\n\n /**\n * Get vertical masonry layout for current items\n */\n getVerticalMasonryLayout(): { layout: MasonryItemPosition[]; totalHeight: number } | null {\n // Don't call updateLayoutCalculators() here — it modifies observables and\n // would violate MobX strict mode when called during render. The engine is\n // created by updateContainerSize() which runs in useEffect.\n\n if (this.verticalMasonryEngine) {\n // Convert items to masonry data.\n // Only images get variable height based on aspect ratio.\n // Non-image items (folders, documents, etc.) get a uniform fixed height.\n const columnWidth = this.verticalMasonryEngine?.columnWidth || 250;\n const fixedNonImageHeight = Math.round(columnWidth * 0.75); // 4:3 aspect for uniform tiles\n\n const masonryItems: MasonryItem[] = this.items.map(item => {\n const width = columnWidth;\n\n if (this.isImageItem(item)) {\n const aspectRatio = item.aspectRatio\n || this.provider.getAspectRatio?.(item.path)\n || this.generateDeterministicAspectRatio(item.id);\n const height = Math.round(width / aspectRatio);\n return { id: item.id, width, height, aspectRatio };\n }\n\n // Non-image: fixed uniform height\n return { id: item.id, width, height: fixedNonImageHeight };\n });\n\n const result = this.verticalMasonryEngine.calculateLayout(masonryItems);\n return {\n layout: result.items,\n totalHeight: result.totalHeight\n };\n }\n\n return null;\n }\n\n /**\n * Get horizontal masonry layout for current items\n */\n getHorizontalMasonryLayout(): { layout: MasonryItemPosition[]; totalHeight: number } | null {\n // Don't call updateLayoutCalculators() here — same reason as vertical.\n\n if (this.horizontalMasonryEngine) {\n // Convert items to masonry data.\n // Only images get variable height; non-image items get uniform height.\n const columnWidth = this.horizontalMasonryEngine?.columnWidth || 250;\n const fixedNonImageHeight = Math.round(columnWidth * 0.75); // 4:3 aspect for uniform tiles\n\n const masonryItems: MasonryItem[] = this.items.map(item => {\n const width = columnWidth;\n\n if (this.isImageItem(item)) {\n const aspectRatio = item.aspectRatio\n || this.provider.getAspectRatio?.(item.path)\n || this.generateDeterministicAspectRatio(item.id);\n const height = Math.round(width / aspectRatio);\n return { id: item.id, width, height, aspectRatio };\n }\n\n // Non-image: fixed uniform height\n return { id: item.id, width, height: fixedNonImageHeight };\n });\n\n const result = this.horizontalMasonryEngine.calculateLayout(masonryItems);\n return {\n layout: result.items,\n totalHeight: result.totalHeight\n };\n }\n\n return null;\n }\n\n /**\n * Get visible items for virtualization\n */\n getVisibleGridItems(scrollTop: number, viewportHeight: number): GridItemLayout[] {\n if (!this.gridCalculator) return [];\n \n const result = this.gridCalculator.calculateVisibleItems(\n this.items.length,\n scrollTop,\n viewportHeight\n );\n \n return result.visibleItems;\n }\n\n /**\n * Get visible vertical masonry items for virtualization\n */\n getVisibleVerticalMasonryItems(scrollTop: number, viewportHeight: number): MasonryItemPosition[] {\n const layout = this.getVerticalMasonryLayout();\n if (!layout) return [];\n \n // Filter items that are visible in the viewport\n return layout.layout.filter(item => {\n const itemTop = item.y;\n const itemBottom = item.y + item.height;\n const viewportTop = scrollTop;\n const viewportBottom = scrollTop + viewportHeight;\n \n return itemBottom >= viewportTop && itemTop <= viewportBottom;\n });\n }\n\n /**\n * Get visible horizontal masonry items for virtualization\n */\n getVisibleHorizontalMasonryItems(scrollTop: number, viewportHeight: number): MasonryItemPosition[] {\n const layout = this.getHorizontalMasonryLayout();\n if (!layout) return [];\n \n // Filter items that are visible in the viewport\n return layout.layout.filter(item => {\n const itemTop = item.y;\n const itemBottom = item.y + item.height;\n const viewportTop = scrollTop;\n const viewportBottom = scrollTop + viewportHeight;\n \n return itemBottom >= viewportTop && itemTop <= viewportBottom;\n });\n }\n\n /**\n * Get visible masonry items for virtualization (unified method)\n */\n getVisibleMasonryItems(scrollTop: number, viewportHeight: number, isHorizontal: boolean = false, overscan: number = 100): MasonryItemPosition[] {\n const layout = isHorizontal ? this.getHorizontalMasonryLayout() : this.getVerticalMasonryLayout();\n if (!layout) return [];\n \n // Add overscan to viewport for smoother scrolling\n const viewportTop = scrollTop - overscan;\n const viewportBottom = scrollTop + viewportHeight + overscan;\n \n // Filter items that intersect with the extended viewport\n return layout.layout.filter(item => {\n const itemTop = item.y;\n const itemBottom = item.y + item.height;\n \n return itemBottom >= viewportTop && itemTop <= viewportBottom;\n });\n }\n\n // =====================\n // Imperative Methods\n // =====================\n \n /**\n * Ensure item is visible (scroll to item)\n */\n ensureItemVisible(itemId: string): boolean {\n const index = this.items.findIndex(item => item.id === itemId);\n if (index === -1) return false;\n\n this.scrollToItemId = itemId;\n return true;\n }\n\n clearScrollToItem(): void {\n this.scrollToItemId = null;\n }\n\n /**\n * Get item by ID\n */\n getItem(itemId: string): ListItemData | undefined {\n return this.itemMap.get(itemId);\n }\n\n /**\n * Get item index\n */\n getItemIndex(itemId: string): number {\n return this.items.findIndex(item => item.id === itemId);\n }\n\n /**\n * Resolve thumbnail URL for an item via provider cache.\n * Returns blob URL when ready, undefined while loading.\n * MobX observer components re-render when the URL becomes available.\n */\n resolveThumbnailUrl(item: ListItemData): string | undefined {\n return this.provider.resolveThumbnailUrl?.(item);\n }\n\n // AICODE-NOTE: Should have functionality like ensure visible etc.\n // AICODE-NOTE: Should have support for selection, focus, etc.\n // AICODE-NOTE: Use similar approach as in TreeComponent for context menu, icons, multi-select, etc.\n // AICODE-NOTE: Should support custom item drawing\n // AICODE-NOTE: Should have ellipsis for long text\n\n // AICODE-NOTE: Should have different sizes for thumbnail(grid) view\n // AICODE-NOTE: thumbnail should be from N per line until 1 per line\n}\n","import {\n ListItemsProvider,\n ListItemsProviderListener,\n LIST_VIEW_TYPE,\n GRID_VIEW_TYPE,\n DETAILS_VIEW_TYPE,\n MASONRY_HORIZONTAL_VIEW_TYPE,\n MASONRY_VERTICAL_VIEW_TYPE,\n type ListViewType\n} from './ListItemsProvider';\nimport type { \n ListItemData, \n ListLoadOptions, \n ListLoadResult, \n ListSelectionInfo,\n ListContextMenuItem,\n ListDragDropInfo,\n VirtualizationConfig\n} from '../types/ListTypes';\nimport React from 'react';\nimport { \n FileText, Image, Video, Music, Folder, Archive, \n File, Settings, Code, Database, Globe, Palette,\n Package, BookOpen, TestTube, GitBranch, Key,\n Braces, Play, Zap, Component\n} from 'lucide-react';\nimport { makeAutoObservable } from 'mobx';\n\n// AICODE-NOTE: Simple test provider for development and testing with mock data\nexport class TestListProvider implements ListItemsProvider {\n // =====================\n // Basic Configuration\n // =====================\n \n readonly id = 'test-list-provider';\n readonly name = 'Test List Provider';\n readonly isMultiSelectEnabled = true;\n readonly isVirtualizationEnabled = true;\n readonly isDragDropEnabled = true;\n \n readonly supportedViewTypes: ListViewType[] = [\n LIST_VIEW_TYPE,\n GRID_VIEW_TYPE,\n DETAILS_VIEW_TYPE,\n MASONRY_HORIZONTAL_VIEW_TYPE,\n MASONRY_VERTICAL_VIEW_TYPE\n ];\n\n // AICODE-NOTE: Mock data for testing - different types of items\n private items: ListItemData[] = [];\n private listener?: ListItemsProviderListener;\n\n constructor() {\n makeAutoObservable(this, {});\n // AICODE-NOTE: Generate large dataset with 10,000 items for performance testing\n this.generateLargeDataset();\n }\n\n // =====================\n // Mock Data Generation\n // =====================\n \n private generateLargeDataset(): void {\n // AICODE-NOTE: Generate 10,000 items with varied dimensions and images\n const start = performance.now();\n const fileTypes = [\n { ext: 'jpg', icon: '🖼️', type: 'Image' },\n { ext: 'png', icon: '🖼️', type: 'Image' },\n { ext: 'pdf', icon: '📄', type: 'Document' },\n { ext: 'doc', icon: '📝', type: 'Document' },\n { ext: 'mp4', icon: '🎬', type: 'Video' },\n { ext: 'mp3', icon: '🎵', type: 'Audio' },\n { ext: 'zip', icon: '📦', type: 'Archive' },\n { ext: 'txt', icon: '📄', type: 'Text' },\n { ext: 'js', icon: '⚡', type: 'Code' },\n { ext: 'css', icon: '🎨', type: 'Style' }\n ];\n\n const adjectives = ['Amazing', 'Beautiful', 'Creative', 'Dynamic', 'Elegant', 'Fantastic', 'Gorgeous', 'Incredible', 'Lovely', 'Magnificent'];\n const nouns = ['Photo', 'Document', 'Project', 'Design', 'Artwork', 'Report', 'Presentation', 'Video', 'Music', 'Archive'];\n\n for (let i = 0; i < 10000; i++) {\n const fileType = fileTypes[i % fileTypes.length]!;\n const adjective = adjectives[i % adjectives.length]!;\n const noun = nouns[Math.floor(i / adjectives.length) % nouns.length]!;\n \n // Generate variable dimensions for realistic masonry layout\n const baseWidth = 200 + (i % 5) * 40; // 200-360px width\n const aspectRatios = [1, 1.2, 1.5, 0.8, 0.6, 1.8]; // Various aspect ratios\n const aspectRatio = aspectRatios[i % aspectRatios.length]!;\n const height = Math.round(baseWidth / aspectRatio);\n \n // Generate image URL for visual items\n const isImageType = fileType.type === 'Image' || (i % 3 === 0); // Show images for image types and every 3rd item\n const thumbnailUrl = isImageType \n ? `https://picsum.photos/${baseWidth}/${height}?random=${i}`\n : undefined;\n\n const item: ListItemData = {\n id: `item-${i}`,\n name: `${adjective} ${noun} ${i + 1}.${fileType.ext}`,\n type: fileType.type,\n icon: fileType.icon,\n size: Math.floor(Math.random() * 10000000) + 1000, // 1KB to 10MB\n modified: new Date(Date.now() - Math.random() * 365 * 24 * 60 * 60 * 1000), // Random date within last year\n thumbnailUrl,\n aspectRatio,\n getDimensions: () => ({ width: baseWidth, height })\n };\n\n this.items.push(item);\n }\n console.log('Generated 10,000 items in', performance.now() - start, 'ms');\n }\n\n private getIconForType(type: string): string {\n const iconMap: Record<string, string> = {\n document: 'file-text',\n image: 'image',\n video: 'video',\n audio: 'music',\n folder: 'folder',\n archive: 'archive'\n };\n return iconMap[type] || 'file';\n }\n\n /**\n * Get custom icon for an item based on file type and extension\n */\n getItemIcon(item: ListItemData): string | React.ComponentType<any> {\n // If it's a folder, use folder icon\n if (item.type === 'folder') {\n return Folder;\n }\n \n // Get file extension\n const extension = item.name.split('.').pop()?.toLowerCase() || '';\n \n // Return appropriate icon based on extension\n switch (extension) {\n // Web Development\n case 'js':\n case 'jsx':\n return Code; // JavaScript icon\n \n case 'ts':\n case 'tsx':\n return FileText; // TypeScript icon\n \n case 'html':\n case 'htm':\n return Globe; // HTML icon\n \n case 'css':\n case 'scss':\n case 'sass':\n case 'less':\n return Palette; // Stylesheet icon\n \n // Documentation\n case 'md':\n case 'mdx':\n return BookOpen; // Markdown icon\n \n case 'txt':\n return FileText;\n \n case 'pdf':\n return FileText;\n \n // Data & Configuration\n case 'json':\n return Braces; // JSON icon\n \n case 'yml':\n case 'yaml':\n return Settings; // YAML icon\n \n case 'xml':\n return Code; // XML icon\n \n case 'env':\n return Key; // Environment file icon\n \n case 'config':\n return Settings; // Config file icon\n \n // Images\n case 'jpg':\n case 'jpeg':\n case 'png':\n case 'gif':\n case 'webp':\n case 'bmp':\n case 'tiff':\n case 'ico':\n return Image; // Image icon\n \n case 'svg':\n return Zap; // SVG icon (special since it's vector)\n \n // Media\n case 'mp4':\n case 'avi':\n case 'mov':\n case 'mkv':\n return Play; // Video icon\n \n case 'mp3':\n case 'wav':\n case 'flac':\n case 'ogg':\n return Music; // Audio icon\n \n // Archives\n case 'zip':\n case 'tar':\n case 'gz':\n case '7z':\n case 'rar':\n return Archive; // Archive icon\n \n // Executables\n case 'exe':\n case 'app':\n case 'deb':\n case 'dmg':\n return Zap; // Executable icon\n \n // Development Tools\n case 'git':\n case 'gitignore':\n return GitBranch;\n \n case 'dockerfile':\n return Package; // Docker icon\n \n case 'sql':\n return Database; // Database icon\n \n case 'log':\n return FileText; // Log file icon\n \n // Default file icon\n default:\n return File; // Use default File icon\n }\n }\n\n // =====================\n // Data Loading Methods\n // =====================\n \n async loadItems(options?: ListLoadOptions): Promise<ListLoadResult> {\n // AICODE-NOTE: Simulate async loading with small delay\n await new Promise(resolve => setTimeout(resolve, 100));\n \n let items = [...this.items];\n \n // Apply search filter\n if (options?.searchQuery) {\n const query = options.searchQuery.toLowerCase();\n items = items.filter(item => \n item.name.toLowerCase().includes(query) ||\n item.type?.toLowerCase().includes(query)\n );\n }\n \n // Apply sorting\n if (options?.sortBy) {\n const sortField = options.sortBy;\n items.sort((a, b) => {\n const aVal = a[sortField];\n const bVal = b[sortField];\n \n if (aVal === undefined) return 1;\n if (bVal === undefined) return -1;\n \n let comparison = 0;\n if (aVal < bVal) comparison = -1;\n if (aVal > bVal) comparison = 1;\n \n return options.sortDirection === 'desc' ? -comparison : comparison;\n });\n }\n \n // Apply pagination\n const limit = options?.limit || items.length;\n const offset = options?.offset || 0;\n const paginatedItems = items.slice(offset, offset + limit);\n \n return {\n items: paginatedItems,\n totalCount: items.length,\n hasMore: offset + limit < items.length\n };\n }\n\n async getItemCount(): Promise<number> {\n return this.items.length;\n }\n\n async loadItemRange(start: number, end: number): Promise<ListLoadResult> {\n // AICODE-NOTE: Simulate async range loading with delay\n await new Promise(resolve => setTimeout(resolve, 200));\n \n const items: ListItemData[] = [];\n \n // AICODE-NOTE: Generate items on demand for the requested range\n for (let i = start; i < end && i < this.items.length; i++) {\n // AICODE-NOTE: Check if item already exists in cache\n const existingItem = i < this.items.length ? this.items[i] : null;\n if (existingItem) {\n items.push(existingItem);\n } else {\n // AICODE-NOTE: Item should already exist from generateLargeDataset\n // If we reach here, something is wrong with the data generation\n console.warn(`Item at index ${i} not found in pre-generated dataset`);\n continue;\n }\n }\n \n return {\n items,\n totalCount: this.items.length,\n hasMore: end < this.items.length\n };\n }\n\n async refresh(): Promise<ListLoadResult> {\n // AICODE-NOTE: For testing, just return all items\n return this.loadItems();\n }\n\n // =====================\n // View Configuration\n // =====================\n \n getItemHeight(viewType: ListViewType): number {\n // AICODE-NOTE: Different heights for different view types\n switch (viewType.id) {\n case 'list': return 40;\n case 'grid': return 120;\n case 'details': return 32;\n default: return 40;\n }\n }\n\n getItemWidth(viewType: ListViewType): number {\n // AICODE-NOTE: Fixed widths for grid layouts\n switch (viewType.id) {\n case 'grid': return 200;\n default: return 200;\n }\n }\n\n getVirtualizationConfig(): VirtualizationConfig {\n return {\n itemHeight: 40,\n overscan: 5,\n threshold: 50,\n rangeSize: 20\n };\n }\n\n // =====================\n // Event Callbacks\n // =====================\n \n onSelectionChange(selectionInfo: ListSelectionInfo): void {\n // AICODE-NOTE: Log selection changes for debugging\n console.log('Selection changed:', {\n selectedCount: selectionInfo.selectedItems.length,\n selectionType: selectionInfo.selectionType,\n trigger: selectionInfo.trigger\n });\n }\n\n onViewTypeChange(viewType: ListViewType): void {\n console.log('View type changed to:', viewType.name);\n }\n\n onItemDoubleClick(item: ListItemData): void {\n console.log('Item double-clicked:', item.name);\n }\n\n // =====================\n // Context Menu Support\n // =====================\n \n getItemContextMenu(item: ListItemData): ListContextMenuItem[] {\n // AICODE-NOTE: Basic context menu for testing\n const baseMenu: ListContextMenuItem[] = [\n { id: 'open', label: 'Open', icon: 'eye' },\n { id: 'rename', label: 'Rename', icon: 'edit' },\n { id: 'separator', label: '', type: 'separator' },\n { id: 'delete', label: 'Delete', icon: 'trash', destructive: true }\n ];\n\n // Add type-specific items\n if (item.type === 'folder') {\n baseMenu.unshift({ id: 'open-folder', label: 'Open Folder', icon: 'folder-open' });\n }\n\n return baseMenu;\n }\n\n getMultiItemContextMenu(items: ListItemData[]): ListContextMenuItem[] {\n // AICODE-NOTE: Context menu for multiple selected items\n const multiMenu: ListContextMenuItem[] = [\n { \n id: 'delete-multiple', \n label: `Delete ${items.length} items`, \n icon: 'trash',\n destructive: true,\n shortcut: 'Del'\n },\n { id: 'separator', label: '', type: 'separator' },\n { \n id: 'copy-multiple', \n label: `Copy ${items.length} items`, \n icon: 'copy',\n shortcut: 'Ctrl+C'\n },\n { \n id: 'cut-multiple', \n label: `Cut ${items.length} items`, \n icon: 'scissors',\n shortcut: 'Ctrl+X'\n }\n ];\n\n // AICODE-NOTE: Add archive option if multiple files selected\n const hasFiles = items.some(item => item.type !== 'folder');\n if (hasFiles) {\n multiMenu.push(\n { id: 'separator2', label: '', type: 'separator' },\n { \n id: 'archive-multiple', \n label: `Archive ${items.length} items`, \n icon: 'archive',\n tooltip: 'Create a zip archive of selected items'\n }\n );\n }\n\n return multiMenu;\n }\n\n onContextMenuAction(menuItemId: string, items: ListItemData[]): void {\n console.log(`Context menu action '${menuItemId}' on items:`, items.map(i => i.name));\n \n switch (menuItemId) {\n case 'delete':\n case 'delete-multiple':\n // AICODE-NOTE: For testing, just log - real provider would delete items\n console.log('Would delete items:', items.map(i => i.name));\n break;\n case 'rename':\n console.log('Would rename item:', items[0]?.name);\n break;\n case 'copy-multiple':\n console.log('Would copy items to clipboard:', items.map(i => i.name));\n break;\n case 'cut-multiple':\n console.log('Would cut items to clipboard:', items.map(i => i.name));\n break;\n case 'archive-multiple':\n console.log('Would create archive of items:', items.map(i => i.name));\n break;\n case 'open':\n case 'open-folder':\n console.log('Would open item:', items[0]?.name);\n break;\n default:\n console.log('Unhandled menu action:', menuItemId);\n }\n }\n\n // =====================\n // Drag and Drop Support\n // =====================\n \n canDragItem(item: ListItemData): boolean {\n // AICODE-NOTE: For testing, allow dragging all items except system files\n return !item.name.startsWith('.');\n }\n \n canDropItems(draggedItems: ListItemData[], targetItem: ListItemData | null, position: 'before' | 'after' | 'inside'): boolean {\n // AICODE-NOTE: For testing, allow most drops with some restrictions\n \n // Can't drop on itself\n if (targetItem && draggedItems.some(item => item.id === targetItem.id)) {\n return false;\n }\n \n // Can only drop inside folders\n if (position === 'inside' && targetItem?.type !== 'folder') {\n return false;\n }\n \n return true;\n }\n \n onDragStart(draggedItems: ListItemData[], event: DragEvent): void {\n console.log('Drag started with items:', draggedItems.map(i => i.name));\n }\n \n onDrop(dragDropInfo: ListDragDropInfo): void {\n const { draggedItems, targetItem, position } = dragDropInfo;\n \n console.log('Drop operation:', {\n draggedItems: draggedItems.map((i: ListItemData) => i.name),\n targetItem: targetItem?.name || 'empty space',\n position\n });\n \n // AICODE-NOTE: For testing, simulate reordering by logging\n if (position === 'before' || position === 'after') {\n console.log(`Would reorder items ${position} ${targetItem?.name}`);\n } else if (position === 'inside' && targetItem?.type === 'folder') {\n console.log(`Would move items into folder: ${targetItem.name}`);\n }\n }\n \n onDragEnd(draggedItems: ListItemData[], success: boolean): void {\n console.log('Drag ended:', {\n items: draggedItems.map(i => i.name),\n success\n });\n }\n\n // =====================\n // Legacy Listener Support\n // =====================\n \n addListener(listener: ListItemsProviderListener): void {\n this.listener = listener;\n }\n\n removeListener(listener: ListItemsProviderListener): void {\n this.listener = undefined;\n }\n\n // =====================\n // Helper Methods for Testing\n // =====================\n \n /**\n * Add a new mock item (useful for testing dynamic updates)\n */\n addMockItem(item: Partial<ListItemData>): void {\n const { id, name, ...rest } = item;\n const newItem: ListItemData = {\n id: id || `item-${Date.now()}`,\n name: name || 'New Item',\n type: 'document',\n modified: new Date(),\n icon: 'file',\n ...rest\n };\n \n this.items.push(newItem);\n \n // Notify listeners\n this.listener?.onItemsCountChanged(this.items.length);\n }\n\n /**\n * Remove an item by ID (useful for testing dynamic updates)\n */\n removeMockItem(itemId: string): void {\n const index = this.items.findIndex(item => item.id === itemId);\n if (index >= 0) {\n this.items.splice(index, 1);\n \n // Notify listeners\n this.listener?.onItemsCountChanged(this.items.length);\n }\n }\n\n /**\n * Update an existing item (useful for testing dynamic updates)\n */\n updateMockItem(itemId: string, updates: Partial<ListItemData>): void {\n const index = this.items.findIndex(item => item.id === itemId);\n if (index >= 0) {\n const currentItem = this.items[index]!;\n const { id, name, ...rest } = updates;\n \n this.items[index] = {\n ...currentItem,\n ...rest,\n // Ensure required fields are never undefined\n id: id || currentItem.id,\n name: name || currentItem.name\n };\n \n // Notify listeners\n this.listener?.onItemChanged(index);\n }\n }\n} ","import { makeAutoObservable } from \"mobx\";\n\n// AICODE-NOTE: Masonry layout calculator for variable height items\nexport interface MasonryLayoutConfig {\n containerWidth: number;\n containerHeight: number;\n columnCount: number | 'auto';\n gap: number;\n padding: number;\n minColumnWidth: number;\n maxColumnWidth: number;\n}\n\nexport interface MasonryItemLayout {\n x: number;\n y: number;\n width: number;\n height: number;\n column: number;\n thumbnailWidth: number;\n thumbnailHeight: number;\n textHeight: number;\n}\n\nexport interface MasonryLayoutResult {\n columnCount: number;\n columnWidth: number;\n totalHeight: number;\n items: MasonryItemLayout[];\n columnHeights: number[];\n}\n\n// AICODE-NOTE: Item data interface for masonry calculations\nexport interface MasonryItemData {\n id: string;\n aspectRatio?: number;\n customHeight?: number;\n textLength?: number;\n}\n\n// AICODE-NOTE: MobX-enabled calculation class for masonry layouts with reactive updates\nexport class MasonryLayoutCalculator {\n private config: MasonryLayoutConfig;\n\n constructor(config: MasonryLayoutConfig) {\n this.config = config;\n makeAutoObservable(this, {});\n }\n\n // AICODE-NOTE: Update configuration and trigger reactive updates\n updateConfig(updates: Partial<MasonryLayoutConfig>): void {\n this.config = { ...this.config, ...updates };\n }\n\n // AICODE-NOTE: Computed getter for current configuration\n get currentConfig(): MasonryLayoutConfig {\n return this.config;\n }\n\n // AICODE-NOTE: Calculate optimal column count\n calculateColumnCount(): number {\n if (typeof this.config.columnCount === 'number') {\n return Math.max(1, this.config.columnCount);\n }\n\n const { containerWidth, gap, padding, minColumnWidth, maxColumnWidth } = this.config;\n const availableWidth = containerWidth - (padding * 2);\n \n // Find optimal column count\n let bestColumnCount = 1;\n \n for (let columnCount = 1; columnCount <= 8; columnCount++) {\n const totalGaps = (columnCount - 1) * gap;\n const columnWidth = (availableWidth - totalGaps) / columnCount;\n \n if (columnWidth >= minColumnWidth && columnWidth <= maxColumnWidth) {\n bestColumnCount = columnCount;\n } else if (columnWidth < minColumnWidth) {\n break;\n }\n }\n \n return bestColumnCount;\n }\n\n // AICODE-NOTE: Calculate column width\n calculateColumnWidth(columnCount: number): number {\n const { containerWidth, gap, padding } = this.config;\n const availableWidth = containerWidth - (padding * 2);\n const totalGaps = (columnCount - 1) * gap;\n return Math.floor((availableWidth - totalGaps) / columnCount);\n }\n\n // AICODE-NOTE: Calculate item height based on content\n calculateItemHeight(\n item: MasonryItemData,\n columnWidth: number,\n baseHeight: number = 200\n ): number {\n // Use custom height if provided\n if (item.customHeight) {\n return item.customHeight;\n }\n\n // Calculate height based on aspect ratio\n if (item.aspectRatio) {\n const thumbnailHeight = columnWidth / item.aspectRatio;\n const textHeight = this.calculateTextHeight(item.textLength || 0);\n const padding = 16;\n return Math.floor(thumbnailHeight + textHeight + padding);\n }\n\n // Default height with text consideration\n const textHeight = this.calculateTextHeight(item.textLength || 0);\n return baseHeight + textHeight;\n }\n\n // AICODE-NOTE: Calculate text height based on content length\n private calculateTextHeight(textLength: number): number {\n const baseTextHeight = 40;\n const extraLines = Math.floor(textLength / 30); // Rough estimate\n return baseTextHeight + (extraLines * 20);\n }\n\n // AICODE-NOTE: Calculate thumbnail dimensions within item\n calculateThumbnailDimensions(\n item: MasonryItemData,\n columnWidth: number,\n itemHeight: number\n ): { width: number; height: number } {\n const padding = 16;\n const textHeight = this.calculateTextHeight(item.textLength || 0);\n const availableWidth = columnWidth - padding;\n const availableHeight = itemHeight - textHeight - padding;\n\n if (item.aspectRatio) {\n const thumbnailWidth = Math.min(availableWidth, availableHeight * item.aspectRatio);\n const thumbnailHeight = thumbnailWidth / item.aspectRatio;\n return {\n width: Math.floor(thumbnailWidth),\n height: Math.floor(thumbnailHeight)\n };\n }\n\n // Square thumbnail by default\n const size = Math.min(availableWidth, availableHeight);\n return {\n width: Math.floor(size),\n height: Math.floor(size)\n };\n }\n\n // AICODE-NOTE: Calculate layout for all items\n calculateLayout(items: MasonryItemData[]): MasonryLayoutResult {\n const columnCount = this.calculateColumnCount();\n const columnWidth = this.calculateColumnWidth(columnCount);\n const columnHeights = new Array(columnCount).fill(this.config.padding);\n const layoutItems: MasonryItemLayout[] = [];\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n if (!item) continue;\n \n // Find shortest column\n const shortestColumnIndex = columnHeights.indexOf(Math.min(...columnHeights));\n const currentHeight = columnHeights[shortestColumnIndex];\n \n // Calculate item dimensions\n const itemHeight = this.calculateItemHeight(item, columnWidth);\n const { width: thumbnailWidth, height: thumbnailHeight } = \n this.calculateThumbnailDimensions(item, columnWidth, itemHeight);\n const textHeight = this.calculateTextHeight(item.textLength || 0);\n \n // Calculate position\n const x = this.config.padding + (shortestColumnIndex * (columnWidth + this.config.gap));\n const y = currentHeight;\n \n layoutItems.push({\n x,\n y,\n width: columnWidth,\n height: itemHeight,\n column: shortestColumnIndex,\n thumbnailWidth,\n thumbnailHeight,\n textHeight\n });\n \n // Update column height\n columnHeights[shortestColumnIndex] = currentHeight + itemHeight + this.config.gap;\n }\n\n const totalHeight = Math.max(...columnHeights) + this.config.padding;\n\n return {\n columnCount,\n columnWidth,\n totalHeight,\n items: layoutItems,\n columnHeights\n };\n }\n\n // AICODE-NOTE: Calculate visible items for virtualization\n calculateVisibleItems(\n items: MasonryItemData[],\n scrollTop: number,\n viewportHeight: number,\n overscan: number = 200\n ): { startIndex: number; endIndex: number; visibleItems: MasonryItemLayout[] } {\n const layout = this.calculateLayout(items);\n const viewportTop = scrollTop - overscan;\n const viewportBottom = scrollTop + viewportHeight + overscan;\n \n const visibleIndices: number[] = [];\n const visibleItems: MasonryItemLayout[] = [];\n \n for (let i = 0; i < layout.items.length; i++) {\n const item = layout.items[i];\n if (item && item.y < viewportBottom && (item.y + item.height) > viewportTop) {\n visibleIndices.push(i);\n visibleItems.push(item);\n }\n }\n \n const startIndex = visibleIndices.length > 0 ? Math.min(...visibleIndices) : 0;\n const endIndex = visibleIndices.length > 0 ? Math.max(...visibleIndices) : 0;\n \n return {\n startIndex,\n endIndex,\n visibleItems\n };\n }\n\n // AICODE-NOTE: Get item position by index\n getItemPosition(itemIndex: number, items: MasonryItemData[]): MasonryItemLayout | null {\n const layout = this.calculateLayout(items);\n return layout.items[itemIndex] || null;\n }\n\n // AICODE-NOTE: Find item at position\n getItemAtPosition(x: number, y: number, items: MasonryItemData[]): number | null {\n const layout = this.calculateLayout(items);\n \n for (let i = 0; i < layout.items.length; i++) {\n const item = layout.items[i];\n if (item &&\n x >= item.x &&\n x <= item.x + item.width &&\n y >= item.y &&\n y <= item.y + item.height\n ) {\n return i;\n }\n }\n \n return null;\n }\n}\n\n// AICODE-NOTE: Factory function for masonry calculator\nexport function createMasonryCalculator(\n containerWidth: number,\n containerHeight: number,\n options: Partial<MasonryLayoutConfig> = {}\n): MasonryLayoutCalculator {\n const defaultConfig: MasonryLayoutConfig = {\n containerWidth,\n containerHeight,\n columnCount: 'auto',\n gap: 4,\n padding: 4,\n minColumnWidth: 200,\n maxColumnWidth: 400,\n ...options\n };\n \n return new MasonryLayoutCalculator(defaultConfig);\n}\n\n// AICODE-NOTE: Preset configurations for masonry layouts\nexport const MASONRY_PRESETS = {\n compact: {\n gap: 4,\n padding: 4,\n minColumnWidth: 160,\n maxColumnWidth: 250\n },\n comfortable: {\n gap: 8,\n padding: 8,\n minColumnWidth: 200,\n maxColumnWidth: 300\n },\n spacious: {\n gap: 16,\n padding: 16,\n minColumnWidth: 250,\n maxColumnWidth: 400\n }\n} as const; "],"mappings":"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"}