@anymux/ui-kit 0.1.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.
- package/dist/ExplorerLayout-CSIJd7N4.js +105 -0
- package/dist/ExplorerLayout-CSIJd7N4.js.map +1 -0
- package/dist/FileBrowserContext-B6jixa2j.js +11 -0
- package/dist/FileBrowserContext-B6jixa2j.js.map +1 -0
- package/dist/calendar-DSlrbHoj.js +761 -0
- package/dist/calendar-DSlrbHoj.js.map +1 -0
- package/dist/calendar.d.ts +3 -0
- package/dist/calendar.js +3 -0
- package/dist/contacts-DQXTZzHc.js +539 -0
- package/dist/contacts-DQXTZzHc.js.map +1 -0
- package/dist/contacts.d.ts +3 -0
- package/dist/contacts.js +3 -0
- package/dist/file-browser-m5atC3kF.js +6755 -0
- package/dist/file-browser-m5atC3kF.js.map +1 -0
- package/dist/file-browser.d.ts +11 -0
- package/dist/file-browser.js +9 -0
- package/dist/git-B55e6LL-.js +561 -0
- package/dist/git-B55e6LL-.js.map +1 -0
- package/dist/git.d.ts +2 -0
- package/dist/git.js +3 -0
- package/dist/iconMap-V4B8P-Uh.js +206 -0
- package/dist/iconMap-V4B8P-Uh.js.map +1 -0
- package/dist/icons-CIsIOZXR.js +0 -0
- package/dist/icons.d.ts +2 -0
- package/dist/icons.js +4 -0
- package/dist/index-BNmNIWBL.d.ts +71 -0
- package/dist/index-BNmNIWBL.d.ts.map +1 -0
- package/dist/index-Bryv_GCG.d.ts +1481 -0
- package/dist/index-Bryv_GCG.d.ts.map +1 -0
- package/dist/index-CuQIjSXs.d.ts +134 -0
- package/dist/index-CuQIjSXs.d.ts.map +1 -0
- package/dist/index-DSu19mq0.d.ts +153 -0
- package/dist/index-DSu19mq0.d.ts.map +1 -0
- package/dist/index-DmsyeHFr.d.ts +149 -0
- package/dist/index-DmsyeHFr.d.ts.map +1 -0
- package/dist/index-DxnJ8FYM.d.ts +17 -0
- package/dist/index-DxnJ8FYM.d.ts.map +1 -0
- package/dist/index-DzfY1Tok.d.ts +32 -0
- package/dist/index-DzfY1Tok.d.ts.map +1 -0
- package/dist/index-Ml_SgiKa.d.ts +1847 -0
- package/dist/index-Ml_SgiKa.d.ts.map +1 -0
- package/dist/index-kHr9udZD.d.ts +1025 -0
- package/dist/index-kHr9udZD.d.ts.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +15 -0
- package/dist/layout-Ca_4r8ka.js +89 -0
- package/dist/layout-Ca_4r8ka.js.map +1 -0
- package/dist/layout.d.ts +2 -0
- package/dist/layout.js +5 -0
- package/dist/list-CxfT6hix.js +6831 -0
- package/dist/list-CxfT6hix.js.map +1 -0
- package/dist/list.d.ts +2 -0
- package/dist/list.js +5 -0
- package/dist/media-DZ292aKK.js +557 -0
- package/dist/media-DZ292aKK.js.map +1 -0
- package/dist/media.d.ts +3 -0
- package/dist/media.js +3 -0
- package/dist/tree-Dd9Z0Aso.js +3351 -0
- package/dist/tree-Dd9Z0Aso.js.map +1 -0
- package/dist/tree.d.ts +2 -0
- package/dist/tree.js +6 -0
- package/dist/types-common-CB3kRek8.d.ts +26 -0
- package/dist/types-common-CB3kRek8.d.ts.map +1 -0
- package/dist/utils-B4fdKKsy.js +3 -0
- package/package.json +109 -0
- package/src/calendar/AgendaView.tsx +37 -0
- package/src/calendar/CalendarBrowser.tsx +90 -0
- package/src/calendar/CalendarModel.ts +142 -0
- package/src/calendar/CalendarSidebar.tsx +81 -0
- package/src/calendar/DayView.tsx +76 -0
- package/src/calendar/EventCard.tsx +51 -0
- package/src/calendar/MockCalendarProvider.ts +98 -0
- package/src/calendar/MonthView.tsx +77 -0
- package/src/calendar/WeekView.tsx +129 -0
- package/src/calendar/index.ts +18 -0
- package/src/calendar/types.ts +25 -0
- package/src/contacts/ContactAvatar.tsx +35 -0
- package/src/contacts/ContactBrowser.tsx +56 -0
- package/src/contacts/ContactCard.tsx +37 -0
- package/src/contacts/ContactDetail.tsx +63 -0
- package/src/contacts/ContactGroupSidebar.tsx +40 -0
- package/src/contacts/ContactList.tsx +32 -0
- package/src/contacts/ContactListModel.ts +120 -0
- package/src/contacts/MockContactProvider.ts +77 -0
- package/src/contacts/index.ts +17 -0
- package/src/contacts/types.ts +26 -0
- package/src/demos/CalendarBrowserDemo.tsx +15 -0
- package/src/demos/ContactBrowserDemo.tsx +15 -0
- package/src/demos/MediaBrowserDemo.tsx +15 -0
- package/src/file-browser/adapters/DocumentViewerAdapter.ts +371 -0
- package/src/file-browser/adapters/FileSystemBridge.ts +168 -0
- package/src/file-browser/adapters/GitBrowserAdapter.ts +546 -0
- package/src/file-browser/adapters/README.md +504 -0
- package/src/file-browser/adapters/index.ts +27 -0
- package/src/file-browser/adapters/types.ts +70 -0
- package/src/file-browser/architecture.md +645 -0
- package/src/file-browser/components/CreateItemDialog.tsx +71 -0
- package/src/file-browser/components/DeleteConfirmDialog.tsx +58 -0
- package/src/file-browser/components/FileBrowser.tsx +473 -0
- package/src/file-browser/components/FileBrowserContent.tsx +209 -0
- package/src/file-browser/components/FileBrowserHeader.tsx +151 -0
- package/src/file-browser/components/FileBrowserToolbar.tsx +145 -0
- package/src/file-browser/components/LeftPanel/LeftPanel.tsx +103 -0
- package/src/file-browser/components/LeftPanel/LeftPanelTabs.tsx +70 -0
- package/src/file-browser/components/LeftPanel/TreeNavigationView.tsx +256 -0
- package/src/file-browser/components/PreviewPane.tsx +146 -0
- package/src/file-browser/components/RightPanel/FilePreview.tsx +219 -0
- package/src/file-browser/components/RightPanel/RightPanel.tsx +186 -0
- package/src/file-browser/components/RightPanel/RightPanelToolbar.tsx +113 -0
- package/src/file-browser/components/UploadProgress.tsx +123 -0
- package/src/file-browser/components/ViewerHost.tsx +208 -0
- package/src/file-browser/components/mobile/MobileNavigation.tsx +227 -0
- package/src/file-browser/components/navigation/NavigationButtons.tsx +171 -0
- package/src/file-browser/components/shared/ErrorBoundary.tsx +116 -0
- package/src/file-browser/components/shared/FileBrowserItem.tsx +195 -0
- package/src/file-browser/components/shared/FileIcon.tsx +169 -0
- package/src/file-browser/components/toolbar/ViewModeToggle.tsx +200 -0
- package/src/file-browser/components/views/ListView/ListView.tsx +484 -0
- package/src/file-browser/components/views/ThumbnailView/ThumbnailView.tsx +323 -0
- package/src/file-browser/components/views/TreeView/TreeNode.tsx +186 -0
- package/src/file-browser/components/views/TreeView/TreeNodeList.tsx +191 -0
- package/src/file-browser/components/views/TreeView/TreeView.tsx +200 -0
- package/src/file-browser/components/views/TreemapView/TreemapView.tsx +339 -0
- package/src/file-browser/context/FileBrowserContext.tsx +13 -0
- package/src/file-browser/examples/BasicUsage.tsx +20 -0
- package/src/file-browser/index.ts +98 -0
- package/src/file-browser/models/FileBrowserModel.ts +623 -0
- package/src/file-browser/models/LeftPanelManagerModel.ts +105 -0
- package/src/file-browser/models/NavigationManagerModel.ts +312 -0
- package/src/file-browser/models/ResponsiveLayoutManagerModel.ts +437 -0
- package/src/file-browser/models/RightPanelManagerModel.ts +190 -0
- package/src/file-browser/models/SelectionManagerModel.ts +252 -0
- package/src/file-browser/models/ToolbarManagerModel.ts +144 -0
- package/src/file-browser/models/UploadModel.ts +147 -0
- package/src/file-browser/models/ViewModeManagerModel.ts +185 -0
- package/src/file-browser/models/ViewerHostModel.ts +44 -0
- package/src/file-browser/models/ui/ListViewUIModel.ts +265 -0
- package/src/file-browser/models/ui/PreviewUIModel.ts +297 -0
- package/src/file-browser/models/ui/ThumbnailViewUIModel.ts +254 -0
- package/src/file-browser/models/ui/TreeViewUIModel.ts +128 -0
- package/src/file-browser/models/ui/TreemapViewUIModel.ts +350 -0
- package/src/file-browser/providers/FileSystemListProvider.ts +552 -0
- package/src/file-browser/providers/FileSystemProvider.ts +401 -0
- package/src/file-browser/providers/FileSystemTreeProvider.ts +231 -0
- package/src/file-browser/providers/GitProvider.ts +337 -0
- package/src/file-browser/providers/GitRepositoryProvider.ts +376 -0
- package/src/file-browser/providers/IFileBrowserProvider.ts +56 -0
- package/src/file-browser/providers/MemoryProvider.ts +303 -0
- package/src/file-browser/providers/index.ts +4 -0
- package/src/file-browser/registry/ViewerRegistry.ts +551 -0
- package/src/file-browser/registry/types.ts +144 -0
- package/src/file-browser/scripts/performanceBenchmark.ts +553 -0
- package/src/file-browser/services/ThumbnailCacheService.ts +128 -0
- package/src/file-browser/tasks.md +537 -0
- package/src/file-browser/types/FileBrowserTypes.ts +126 -0
- package/src/file-browser/types/ProviderTypes.ts +155 -0
- package/src/file-browser/types/UITypes.ts +235 -0
- package/src/file-browser/types/ViewModeTypes.ts +150 -0
- package/src/file-browser/utils/gestures.ts +327 -0
- package/src/file-browser/utils/performance.ts +563 -0
- package/src/file-browser/viewers/ImageViewer.tsx +163 -0
- package/src/file-browser/viewers/ImageViewerModel.ts +79 -0
- package/src/file-browser/viewers/TextViewer.tsx +95 -0
- package/src/file-browser/viewers/UnsupportedFileViewer.tsx +57 -0
- package/src/file-browser/viewers/index.ts +61 -0
- package/src/git/BranchList.tsx +128 -0
- package/src/git/CommitGraph.tsx +239 -0
- package/src/git/CommitList.tsx +258 -0
- package/src/git/DiffViewer.tsx +219 -0
- package/src/git/index.ts +4 -0
- package/src/icons/iconMap.ts +146 -0
- package/src/icons/index.ts +9 -0
- package/src/index.ts +13 -0
- package/src/layout/README.md +307 -0
- package/src/layout/components/ExplorerLayout/ExplorerLayout.tsx +178 -0
- package/src/layout/examples/SimpleExample.tsx +60 -0
- package/src/layout/index.ts +6 -0
- package/src/lib/utils.ts +1 -0
- package/src/list/README.md +303 -0
- package/src/list/architecture.md +807 -0
- package/src/list/components/CalculatedGridView.tsx +252 -0
- package/src/list/components/DragPreview.tsx +102 -0
- package/src/list/components/ListContextMenu.tsx +274 -0
- package/src/list/components/ListItem.tsx +761 -0
- package/src/list/components/ListItems.tsx +919 -0
- package/src/list/components/MasonryView.tsx +241 -0
- package/src/list/components/SearchFilter.tsx +44 -0
- package/src/list/components/TreemapView.tsx +709 -0
- package/src/list/components/ViewSizeControls.tsx +205 -0
- package/src/list/components/ViewTypeSelector.tsx +312 -0
- package/src/list/components/VirtualizedDetailsView.tsx +231 -0
- package/src/list/components/VirtualizedGrid.tsx +164 -0
- package/src/list/components/VirtualizedList.tsx +154 -0
- package/src/list/components/VirtualizedMasonryView.tsx +344 -0
- package/src/list/components/shared/EmptyState.tsx +103 -0
- package/src/list/components/shared/ErrorBoundary.tsx +123 -0
- package/src/list/components/shared/ErrorDisplay.tsx +100 -0
- package/src/list/components/shared/ListLoader.tsx +146 -0
- package/src/list/components/shared/LoadingIndicator.tsx +80 -0
- package/src/list/index.ts +92 -0
- package/src/list/models/ListItemsModel.ts +1301 -0
- package/src/list/models/TreemapModel.ts +204 -0
- package/src/list/providers/ListItemsProvider.ts +313 -0
- package/src/list/providers/TestListProvider.ts +604 -0
- package/src/list/tasks.md +937 -0
- package/src/list/types/ListTypes.ts +178 -0
- package/src/list/utils/BenchmarkLogger.ts +243 -0
- package/src/list/utils/DragDropManager.ts +320 -0
- package/src/list/utils/GridLayoutCalculator.ts +290 -0
- package/src/list/utils/ListAccessibility.ts +367 -0
- package/src/list/utils/ListKeyboard.ts +414 -0
- package/src/list/utils/MasonryLayoutCalculator.ts +302 -0
- package/src/list/utils/MasonryLayoutEngine.ts +401 -0
- package/src/list/utils/__tests__/MasonryLayoutEngine.test.ts +157 -0
- package/src/list/utils/__tests__/VirtualizedMasonryView.test.tsx +251 -0
- package/src/media/AlbumSidebar.tsx +48 -0
- package/src/media/MediaBrowser.tsx +92 -0
- package/src/media/MediaBrowserModel.ts +138 -0
- package/src/media/MediaGrid.tsx +50 -0
- package/src/media/MediaList.tsx +49 -0
- package/src/media/MediaPreview.tsx +63 -0
- package/src/media/MediaTimeline.tsx +38 -0
- package/src/media/MockMediaProvider.ts +70 -0
- package/src/media/index.ts +18 -0
- package/src/media/types.ts +21 -0
- package/src/styles/variables.css +60 -0
- package/src/tree/DEVELOPMENT_SUMMARY.md +170 -0
- package/src/tree/__tests__/TreeModel.test.ts +16 -0
- package/src/tree/architecture.md +530 -0
- package/src/tree/components/Tree.tsx +283 -0
- package/src/tree/components/TreeCheckbox.tsx +147 -0
- package/src/tree/components/TreeContextMenu.tsx +139 -0
- package/src/tree/components/TreeNodeList.tsx +329 -0
- package/src/tree/components/TreeTable.tsx +382 -0
- package/src/tree/index.ts +58 -0
- package/src/tree/models/TreeModel.ts +839 -0
- package/src/tree/providers/SimpleTreeProvider.ts +463 -0
- package/src/tree/providers/TestTreeProvider.ts +946 -0
- package/src/tree/providers/TreeProvider.ts +308 -0
- package/src/tree/tasks.md +2046 -0
- package/src/tree/types/TreeTypes.ts +279 -0
- package/src/tree/utils/SelectionTheme.ts +150 -0
- package/src/tree/utils/logger.ts +203 -0
- package/src/types-common.ts +21 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { makeAutoObservable } from 'mobx';
|
|
2
|
+
import type { ListItemData } from '../types/ListTypes';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Extension category color map.
|
|
6
|
+
* Maps file extensions to RGBA colors for the cushion treemap renderer.
|
|
7
|
+
*/
|
|
8
|
+
export const EXTENSION_CATEGORIES: Record<string, [number, number, number, number]> = {
|
|
9
|
+
// JavaScript/TypeScript — blue
|
|
10
|
+
js: [49, 120, 198, 255],
|
|
11
|
+
jsx: [49, 120, 198, 255],
|
|
12
|
+
ts: [49, 120, 198, 255],
|
|
13
|
+
tsx: [49, 120, 198, 255],
|
|
14
|
+
mjs: [49, 120, 198, 255],
|
|
15
|
+
cjs: [49, 120, 198, 255],
|
|
16
|
+
// Styles — teal
|
|
17
|
+
css: [21, 114, 182, 255],
|
|
18
|
+
scss: [21, 114, 182, 255],
|
|
19
|
+
less: [21, 114, 182, 255],
|
|
20
|
+
sass: [21, 114, 182, 255],
|
|
21
|
+
// Markup — orange
|
|
22
|
+
html: [227, 79, 38, 255],
|
|
23
|
+
xml: [227, 79, 38, 255],
|
|
24
|
+
svg: [227, 79, 38, 255],
|
|
25
|
+
vue: [227, 79, 38, 255],
|
|
26
|
+
// Data — gray
|
|
27
|
+
json: [107, 114, 128, 255],
|
|
28
|
+
yaml: [107, 114, 128, 255],
|
|
29
|
+
yml: [107, 114, 128, 255],
|
|
30
|
+
toml: [107, 114, 128, 255],
|
|
31
|
+
env: [107, 114, 128, 255],
|
|
32
|
+
// Images — green
|
|
33
|
+
png: [16, 185, 129, 255],
|
|
34
|
+
jpg: [16, 185, 129, 255],
|
|
35
|
+
jpeg: [16, 185, 129, 255],
|
|
36
|
+
gif: [16, 185, 129, 255],
|
|
37
|
+
webp: [16, 185, 129, 255],
|
|
38
|
+
avif: [16, 185, 129, 255],
|
|
39
|
+
ico: [16, 185, 129, 255],
|
|
40
|
+
// Documents — purple
|
|
41
|
+
md: [139, 92, 246, 255],
|
|
42
|
+
txt: [139, 92, 246, 255],
|
|
43
|
+
pdf: [139, 92, 246, 255],
|
|
44
|
+
doc: [139, 92, 246, 255],
|
|
45
|
+
docx: [139, 92, 246, 255],
|
|
46
|
+
// Archives — amber
|
|
47
|
+
zip: [245, 158, 11, 255],
|
|
48
|
+
tar: [245, 158, 11, 255],
|
|
49
|
+
gz: [245, 158, 11, 255],
|
|
50
|
+
br: [245, 158, 11, 255],
|
|
51
|
+
rar: [245, 158, 11, 255],
|
|
52
|
+
'7z': [245, 158, 11, 255],
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/** Default color for directories — lighter blue */
|
|
56
|
+
const DIRECTORY_COLOR: [number, number, number, number] = [96, 165, 250, 255];
|
|
57
|
+
|
|
58
|
+
/** Default color for unknown file types — neutral gray */
|
|
59
|
+
const OTHER_COLOR: [number, number, number, number] = [156, 163, 175, 255];
|
|
60
|
+
|
|
61
|
+
/** Color scheme category labels and CSS hex colors for the legend */
|
|
62
|
+
export const EXTENSION_LEGEND: Array<{ label: string; color: string }> = [
|
|
63
|
+
{ label: 'JS/TS', color: '#3178C6' },
|
|
64
|
+
{ label: 'Styles', color: '#1572B6' },
|
|
65
|
+
{ label: 'Markup', color: '#E34F26' },
|
|
66
|
+
{ label: 'Data', color: '#6B7280' },
|
|
67
|
+
{ label: 'Images', color: '#10B981' },
|
|
68
|
+
{ label: 'Docs', color: '#8B5CF6' },
|
|
69
|
+
{ label: 'Archives', color: '#F59E0B' },
|
|
70
|
+
{ label: 'Folders', color: '#60A5FA' },
|
|
71
|
+
{ label: 'Other', color: '#9CA3AF' },
|
|
72
|
+
];
|
|
73
|
+
|
|
74
|
+
export type ColorScheme = 'extension' | 'size' | 'type';
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Get the RGBA color for a file extension (used by the cushion treemap renderer).
|
|
78
|
+
*/
|
|
79
|
+
export function getColorForExtension(name: string, isDirectory: boolean): [number, number, number, number] {
|
|
80
|
+
if (isDirectory) return DIRECTORY_COLOR;
|
|
81
|
+
const ext = name.split('.').pop()?.toLowerCase() ?? '';
|
|
82
|
+
return EXTENSION_CATEGORIES[ext] ?? OTHER_COLOR;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Get the CSS hex color string for an extension (used by overlays/tooltips).
|
|
87
|
+
*/
|
|
88
|
+
export function getHexColorForExtension(name: string, isDirectory: boolean): string {
|
|
89
|
+
const [r, g, b] = getColorForExtension(name, isDirectory);
|
|
90
|
+
return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Format bytes to a human-readable string.
|
|
95
|
+
*/
|
|
96
|
+
export function formatBytes(bytes: number): string {
|
|
97
|
+
if (bytes === 0) return '0 B';
|
|
98
|
+
const units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
99
|
+
const k = 1024;
|
|
100
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
101
|
+
const value = bytes / Math.pow(k, i);
|
|
102
|
+
return `${value < 10 ? value.toFixed(1) : Math.round(value)} ${units[i]}`;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Phase 1 TreemapModel — works with items already loaded in ListItemsModel.
|
|
107
|
+
*
|
|
108
|
+
* No worker scanning, no async. Computes layout from the flat items list,
|
|
109
|
+
* using file `size` for proportional rectangles (directories get size=1).
|
|
110
|
+
*/
|
|
111
|
+
export class TreemapModel {
|
|
112
|
+
// === Observable state ===
|
|
113
|
+
|
|
114
|
+
/** Current zoom path within the treemap */
|
|
115
|
+
zoomPath: string = '';
|
|
116
|
+
|
|
117
|
+
/** Path of the hovered tile (for tooltip) */
|
|
118
|
+
hoveredPath: string | null = null;
|
|
119
|
+
|
|
120
|
+
/** Active color scheme */
|
|
121
|
+
colorScheme: ColorScheme = 'extension';
|
|
122
|
+
|
|
123
|
+
/** Whether to show file name labels on tiles */
|
|
124
|
+
showLabels: boolean = true;
|
|
125
|
+
|
|
126
|
+
/** Whether to show size labels on tiles */
|
|
127
|
+
showSizes: boolean = true;
|
|
128
|
+
|
|
129
|
+
/** Highlighted extension category label (e.g. 'JS/TS') for legend filtering */
|
|
130
|
+
highlightedExtension: string | null = null;
|
|
131
|
+
|
|
132
|
+
constructor() {
|
|
133
|
+
makeAutoObservable(this);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// === Actions ===
|
|
137
|
+
|
|
138
|
+
zoomIn(path: string): void {
|
|
139
|
+
this.zoomPath = path;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
zoomOut(): void {
|
|
143
|
+
if (!this.zoomPath) return;
|
|
144
|
+
const parts = this.zoomPath.split('/');
|
|
145
|
+
parts.pop();
|
|
146
|
+
this.zoomPath = parts.join('/');
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
resetZoom(): void {
|
|
150
|
+
this.zoomPath = '';
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
setHoveredPath(path: string | null): void {
|
|
154
|
+
this.hoveredPath = path;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
setColorScheme(scheme: ColorScheme): void {
|
|
158
|
+
this.colorScheme = scheme;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
toggleLabels(): void {
|
|
162
|
+
this.showLabels = !this.showLabels;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
toggleSizes(): void {
|
|
166
|
+
this.showSizes = !this.showSizes;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
setHighlightedExtension(ext: string | null): void {
|
|
170
|
+
this.highlightedExtension = this.highlightedExtension === ext ? null : ext;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// === Computed helpers ===
|
|
174
|
+
|
|
175
|
+
get breadcrumbs(): Array<{ name: string; path: string }> {
|
|
176
|
+
if (!this.zoomPath) return [];
|
|
177
|
+
const parts = this.zoomPath.split('/').filter(Boolean);
|
|
178
|
+
const result: Array<{ name: string; path: string }> = [];
|
|
179
|
+
for (let i = 0; i < parts.length; i++) {
|
|
180
|
+
result.push({
|
|
181
|
+
name: parts[i]!,
|
|
182
|
+
path: parts.slice(0, i + 1).join('/')
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
return result;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Get the RGBA color for a node based on the current color scheme.
|
|
190
|
+
*/
|
|
191
|
+
getNodeColor(item: ListItemData): [number, number, number, number] {
|
|
192
|
+
switch (this.colorScheme) {
|
|
193
|
+
case 'extension':
|
|
194
|
+
return getColorForExtension(item.name, !!item.isDirectory);
|
|
195
|
+
case 'type':
|
|
196
|
+
return item.isDirectory ? DIRECTORY_COLOR : [16, 185, 129, 255];
|
|
197
|
+
case 'size':
|
|
198
|
+
// Placeholder — would need maxSize context. Just use extension for now.
|
|
199
|
+
return getColorForExtension(item.name, !!item.isDirectory);
|
|
200
|
+
default:
|
|
201
|
+
return OTHER_COLOR;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ListItemData,
|
|
3
|
+
ListLoadOptions,
|
|
4
|
+
ListLoadResult,
|
|
5
|
+
ListSelectionInfo,
|
|
6
|
+
ListViewType as BaseListViewType,
|
|
7
|
+
ListDragDropInfo,
|
|
8
|
+
ListContextMenuItem,
|
|
9
|
+
VirtualizationConfig
|
|
10
|
+
} from '../types/ListTypes';
|
|
11
|
+
|
|
12
|
+
export interface ListItemsProviderListener {
|
|
13
|
+
onItemsCountChanged(count: number): void;
|
|
14
|
+
onItemChanged(itemIndex: number): void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// AICODE-NOTE: Extended view type with additional properties for different view modes
|
|
18
|
+
export interface ListViewType extends BaseListViewType {
|
|
19
|
+
// Inherits all properties from base type
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// AICODE-NOTE: Built-in view types with extended properties
|
|
23
|
+
export const LIST_VIEW_TYPE: ListViewType = {
|
|
24
|
+
id: "list",
|
|
25
|
+
name: "List",
|
|
26
|
+
icon: "list",
|
|
27
|
+
itemsPerRow: 1,
|
|
28
|
+
showDetails: false
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const GRID_VIEW_TYPE: ListViewType = {
|
|
32
|
+
id: "grid",
|
|
33
|
+
name: "Grid",
|
|
34
|
+
icon: "grid",
|
|
35
|
+
itemsPerRow: 'auto',
|
|
36
|
+
showThumbnails: true,
|
|
37
|
+
thumbnailSizes: ['small', 'medium', 'large', 'extra-large']
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const DETAILS_VIEW_TYPE: ListViewType = {
|
|
41
|
+
id: "details",
|
|
42
|
+
name: "Details",
|
|
43
|
+
icon: "table",
|
|
44
|
+
itemsPerRow: 1,
|
|
45
|
+
showDetails: true,
|
|
46
|
+
columns: ['name', 'size', 'modified', 'type']
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const MASONRY_HORIZONTAL_VIEW_TYPE: ListViewType = {
|
|
50
|
+
id: "masonry-horizontal",
|
|
51
|
+
name: "Masonry Horizontal",
|
|
52
|
+
icon: "layout-grid",
|
|
53
|
+
itemsPerRow: 'auto',
|
|
54
|
+
showThumbnails: true,
|
|
55
|
+
thumbnailSizes: ['small', 'medium', 'large', 'extra-large']
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const MASONRY_VERTICAL_VIEW_TYPE: ListViewType = {
|
|
59
|
+
id: "masonry-vertical",
|
|
60
|
+
name: "Masonry Vertical",
|
|
61
|
+
icon: "columns",
|
|
62
|
+
itemsPerRow: 'auto',
|
|
63
|
+
showThumbnails: true,
|
|
64
|
+
thumbnailSizes: ['small', 'medium', 'large', 'extra-large']
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const TREEMAP_VIEW_TYPE: ListViewType = {
|
|
68
|
+
id: "treemap",
|
|
69
|
+
name: "Treemap",
|
|
70
|
+
icon: "square-stack",
|
|
71
|
+
itemsPerRow: 'auto',
|
|
72
|
+
showDetails: false
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/** Recursive tree node for treemap view */
|
|
76
|
+
export interface TreemapNodeData {
|
|
77
|
+
name: string;
|
|
78
|
+
path: string;
|
|
79
|
+
size?: number;
|
|
80
|
+
isDirectory: boolean;
|
|
81
|
+
children?: TreemapNodeData[];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Progress info reported during recursive directory scan */
|
|
85
|
+
export interface TreemapScanProgress {
|
|
86
|
+
directoriesScanned: number;
|
|
87
|
+
filesFound: number;
|
|
88
|
+
totalSize: number;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// AICODE-NOTE: Core provider interface with essential methods for MVP
|
|
92
|
+
export interface ListItemsProvider {
|
|
93
|
+
// =====================
|
|
94
|
+
// Basic Configuration
|
|
95
|
+
// =====================
|
|
96
|
+
|
|
97
|
+
/** Provider identifier */
|
|
98
|
+
readonly id: string;
|
|
99
|
+
|
|
100
|
+
/** Human-readable name */
|
|
101
|
+
readonly name: string;
|
|
102
|
+
|
|
103
|
+
/** Supported view types for this provider */
|
|
104
|
+
readonly supportedViewTypes: ListViewType[];
|
|
105
|
+
|
|
106
|
+
/** Whether multi-selection is enabled */
|
|
107
|
+
readonly isMultiSelectEnabled: boolean;
|
|
108
|
+
|
|
109
|
+
/** Whether virtualization is enabled */
|
|
110
|
+
readonly isVirtualizationEnabled: boolean;
|
|
111
|
+
|
|
112
|
+
// =====================
|
|
113
|
+
// Data Loading Methods
|
|
114
|
+
// =====================
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Load items from the data source
|
|
118
|
+
* @param options Loading options for filtering, sorting, pagination
|
|
119
|
+
* @returns Promise resolving to loaded items
|
|
120
|
+
*/
|
|
121
|
+
loadItems(options?: ListLoadOptions): Promise<ListLoadResult>;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Get total count of items (for virtualization)
|
|
125
|
+
* @returns Promise resolving to total item count
|
|
126
|
+
*/
|
|
127
|
+
getItemCount(): Promise<number>;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Load a specific range of items (for virtualization)
|
|
131
|
+
* @param start Starting index
|
|
132
|
+
* @param end Ending index
|
|
133
|
+
* @returns Promise resolving to items in range
|
|
134
|
+
*/
|
|
135
|
+
loadItemRange?(start: number, end: number): Promise<ListLoadResult>;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Refresh/reload items
|
|
139
|
+
* @returns Promise resolving to refreshed items
|
|
140
|
+
*/
|
|
141
|
+
refresh?(): Promise<ListLoadResult>;
|
|
142
|
+
|
|
143
|
+
// =====================
|
|
144
|
+
// View Configuration
|
|
145
|
+
// =====================
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Get item height for a specific view type (for virtualization)
|
|
149
|
+
* @param viewType The view type to get height for
|
|
150
|
+
* @returns Fixed height in pixels
|
|
151
|
+
*/
|
|
152
|
+
getItemHeight(viewType: ListViewType): number;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Get item width for grid-based view types
|
|
156
|
+
* @param viewType The view type to get width for
|
|
157
|
+
* @returns Fixed width in pixels
|
|
158
|
+
*/
|
|
159
|
+
getItemWidth?(viewType: ListViewType): number;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Get virtualization configuration
|
|
163
|
+
* @returns Virtualization config object
|
|
164
|
+
*/
|
|
165
|
+
getVirtualizationConfig?(): VirtualizationConfig;
|
|
166
|
+
|
|
167
|
+
// =====================
|
|
168
|
+
// Event Callbacks
|
|
169
|
+
// =====================
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Called when selection changes
|
|
173
|
+
* @param selectionInfo Information about the selection change
|
|
174
|
+
*/
|
|
175
|
+
onSelectionChange?(selectionInfo: ListSelectionInfo): void;
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Called when view type changes
|
|
179
|
+
* @param viewType New view type
|
|
180
|
+
*/
|
|
181
|
+
onViewTypeChange?(viewType: ListViewType): void;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Called when an item is double-clicked
|
|
185
|
+
* @param item The item that was double-clicked
|
|
186
|
+
*/
|
|
187
|
+
onItemDoubleClick?(item: ListItemData): void;
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Called when keyboard navigation requests going up one level (Escape key).
|
|
191
|
+
* Providers that support hierarchical navigation should implement this.
|
|
192
|
+
*/
|
|
193
|
+
onNavigateUp?(): void;
|
|
194
|
+
|
|
195
|
+
// =====================
|
|
196
|
+
// Legacy Listener Support
|
|
197
|
+
// =====================
|
|
198
|
+
|
|
199
|
+
addListener(listener: ListItemsProviderListener): void;
|
|
200
|
+
removeListener(listener: ListItemsProviderListener): void;
|
|
201
|
+
|
|
202
|
+
// =====================
|
|
203
|
+
// Item Rendering
|
|
204
|
+
// =====================
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Get custom icon for an item
|
|
208
|
+
* @param item Target item
|
|
209
|
+
* @returns Icon identifier or React component
|
|
210
|
+
*/
|
|
211
|
+
getItemIcon?(item: ListItemData): string | React.ComponentType<any>;
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Resolve a thumbnail URL for an item. Providers with async thumbnail
|
|
215
|
+
* loading return blob URLs from an observable cache — MobX observer
|
|
216
|
+
* components re-render when the URL becomes available.
|
|
217
|
+
*/
|
|
218
|
+
resolveThumbnailUrl?(item: ListItemData): string | undefined;
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Get measured aspect ratio (width/height) for an item by path.
|
|
222
|
+
* Used by masonry layout to size items correctly instead of using
|
|
223
|
+
* deterministic random fallback ratios.
|
|
224
|
+
*/
|
|
225
|
+
getAspectRatio?(path: string): number | undefined;
|
|
226
|
+
|
|
227
|
+
// =====================
|
|
228
|
+
// Treemap Data (recursive directory scan)
|
|
229
|
+
// =====================
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Load recursive directory data for treemap view.
|
|
233
|
+
* Returns a nested tree of items including subfolder contents.
|
|
234
|
+
* @param onProgress Optional callback reporting scan progress
|
|
235
|
+
*/
|
|
236
|
+
loadTreemapData?(onProgress?: (progress: TreemapScanProgress) => void): Promise<TreemapNodeData[]>;
|
|
237
|
+
|
|
238
|
+
// =====================
|
|
239
|
+
// Context Menu Support (for future phases)
|
|
240
|
+
// =====================
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Get context menu items for a specific item
|
|
244
|
+
* @param item Target item
|
|
245
|
+
* @returns Array of context menu items
|
|
246
|
+
*/
|
|
247
|
+
getItemContextMenu?(item: ListItemData): ListContextMenuItem[];
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Get context menu items for multiple selected items
|
|
251
|
+
* @param items Selected items
|
|
252
|
+
* @returns Array of context menu items
|
|
253
|
+
*/
|
|
254
|
+
getMultiItemContextMenu?(items: ListItemData[]): ListContextMenuItem[];
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Get context menu items for empty space (no item right-clicked)
|
|
258
|
+
* @returns Array of context menu items
|
|
259
|
+
*/
|
|
260
|
+
getEmptySpaceContextMenu?(): ListContextMenuItem[];
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Called when a context menu action is selected
|
|
264
|
+
* @param menuItemId Menu item identifier
|
|
265
|
+
* @param items Items the action applies to (empty array for empty-space actions)
|
|
266
|
+
*/
|
|
267
|
+
onContextMenuAction?(menuItemId: string, items: ListItemData[]): void;
|
|
268
|
+
|
|
269
|
+
// =====================
|
|
270
|
+
// Drag and Drop Support
|
|
271
|
+
// =====================
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Whether drag and drop is enabled
|
|
275
|
+
*/
|
|
276
|
+
readonly isDragDropEnabled?: boolean;
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Check if an item can be dragged
|
|
280
|
+
* @param item Item to check
|
|
281
|
+
* @returns Whether the item can be dragged
|
|
282
|
+
*/
|
|
283
|
+
canDragItem?(item: ListItemData): boolean;
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Check if items can be dropped on a target
|
|
287
|
+
* @param draggedItems Items being dragged
|
|
288
|
+
* @param targetItem Target item (null for empty space)
|
|
289
|
+
* @param position Drop position relative to target
|
|
290
|
+
* @returns Whether the drop is allowed
|
|
291
|
+
*/
|
|
292
|
+
canDropItems?(draggedItems: ListItemData[], targetItem: ListItemData | null, position: 'before' | 'after' | 'inside'): boolean;
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Called when drag operation starts
|
|
296
|
+
* @param draggedItems Items being dragged
|
|
297
|
+
* @param event Original drag event
|
|
298
|
+
*/
|
|
299
|
+
onDragStart?(draggedItems: ListItemData[], event: DragEvent): void;
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Called when items are dropped
|
|
303
|
+
* @param dragDropInfo Information about the drag and drop operation
|
|
304
|
+
*/
|
|
305
|
+
onDrop?(dragDropInfo: ListDragDropInfo): void;
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Called when drag operation ends (whether successful or not)
|
|
309
|
+
* @param draggedItems Items that were being dragged
|
|
310
|
+
* @param success Whether the drop was successful
|
|
311
|
+
*/
|
|
312
|
+
onDragEnd?(draggedItems: ListItemData[], success: boolean): void;
|
|
313
|
+
}
|