@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,38 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { observer } from 'mobx-react-lite';
|
|
3
|
+
import { Play, Music } from 'lucide-react';
|
|
4
|
+
import type { MediaBrowserModel } from './MediaBrowserModel';
|
|
5
|
+
import type { MediaItem } from './types';
|
|
6
|
+
|
|
7
|
+
export interface MediaTimelineProps {
|
|
8
|
+
model: MediaBrowserModel;
|
|
9
|
+
className?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const TimelineThumbnail = ({ item, onClick }: { item: MediaItem; onClick: () => void }) => (
|
|
13
|
+
<button onClick={onClick} className="relative aspect-square rounded-lg overflow-hidden cursor-pointer group">
|
|
14
|
+
{item.thumbnail || item.mediaType === 'photo' ? (
|
|
15
|
+
<img src={item.thumbnail ?? item.url} alt={item.title} className="w-full h-full object-cover" />
|
|
16
|
+
) : (
|
|
17
|
+
<div className="w-full h-full bg-gray-100 flex items-center justify-center">
|
|
18
|
+
{item.mediaType === 'video' ? <Play size={24} className="text-gray-400" /> : <Music size={24} className="text-gray-400" />}
|
|
19
|
+
</div>
|
|
20
|
+
)}
|
|
21
|
+
<div className="absolute inset-0 bg-black/0 group-hover:bg-black/10 transition-colors" />
|
|
22
|
+
</button>
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
export const MediaTimeline = observer<MediaTimelineProps>(({ model, className = '' }) => (
|
|
26
|
+
<div className={`space-y-6 p-4 ${className}`}>
|
|
27
|
+
{Array.from(model.groupedByDate.entries()).map(([date, items]) => (
|
|
28
|
+
<div key={date}>
|
|
29
|
+
<h3 className="text-sm font-semibold text-gray-700 mb-2 sticky top-0 bg-white/90 backdrop-blur-sm py-1">{date}</h3>
|
|
30
|
+
<div className="grid grid-cols-4 sm:grid-cols-6 md:grid-cols-8 gap-1">
|
|
31
|
+
{items.map(item => (
|
|
32
|
+
<TimelineThumbnail key={item.id} item={item} onClick={() => model.openPreview(item)} />
|
|
33
|
+
))}
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
))}
|
|
37
|
+
</div>
|
|
38
|
+
));
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { IMediaProvider, MediaItem, MediaType } from './types';
|
|
2
|
+
|
|
3
|
+
const ALBUMS = ['Vacation 2024', 'Family', 'Nature', 'City Lights', 'Concerts'];
|
|
4
|
+
const MEDIA_TYPES: MediaType[] = ['photo', 'video', 'audio'];
|
|
5
|
+
|
|
6
|
+
function generateMediaItems(count = 60): MediaItem[] {
|
|
7
|
+
const items: MediaItem[] = [];
|
|
8
|
+
const now = Date.now();
|
|
9
|
+
for (let i = 0; i < count; i++) {
|
|
10
|
+
const mediaType = MEDIA_TYPES[i % 3];
|
|
11
|
+
const date = new Date(now - i * 86400000 * Math.random() * 30);
|
|
12
|
+
items.push({
|
|
13
|
+
id: `media-${i}`,
|
|
14
|
+
type: 'media',
|
|
15
|
+
title: `${mediaType === 'photo' ? 'IMG' : mediaType === 'video' ? 'VID' : 'AUD'}_${String(i).padStart(4, '0')}`,
|
|
16
|
+
mediaType,
|
|
17
|
+
url: `https://picsum.photos/seed/${i}/800/600`,
|
|
18
|
+
thumbnail: `https://picsum.photos/seed/${i}/200/200`,
|
|
19
|
+
mimeType: mediaType === 'photo' ? 'image/jpeg' : mediaType === 'video' ? 'video/mp4' : 'audio/mpeg',
|
|
20
|
+
width: mediaType !== 'audio' ? 800 + (i % 5) * 100 : undefined,
|
|
21
|
+
height: mediaType !== 'audio' ? 600 + (i % 3) * 100 : undefined,
|
|
22
|
+
duration: mediaType !== 'photo' ? 30 + i * 5 : undefined,
|
|
23
|
+
album: ALBUMS[i % ALBUMS.length],
|
|
24
|
+
artist: mediaType === 'audio' ? `Artist ${i % 10}` : undefined,
|
|
25
|
+
createdAt: date,
|
|
26
|
+
updatedAt: date,
|
|
27
|
+
tags: [`tag${i % 5}`],
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
return items;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export class MockMediaProvider implements IMediaProvider {
|
|
34
|
+
private items = generateMediaItems();
|
|
35
|
+
|
|
36
|
+
async listItems() { return this.items; }
|
|
37
|
+
|
|
38
|
+
async getItem(id: string) { return this.items.find(i => i.id === id) ?? null; }
|
|
39
|
+
|
|
40
|
+
async createItem(item: Omit<MediaItem, 'id' | 'createdAt' | 'updatedAt'>) {
|
|
41
|
+
const now = new Date();
|
|
42
|
+
const created: MediaItem = { ...item, id: `media-${Date.now()}`, createdAt: now, updatedAt: now } as MediaItem;
|
|
43
|
+
this.items.push(created);
|
|
44
|
+
return created;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async updateItem(id: string, updates: Partial<MediaItem>) {
|
|
48
|
+
const idx = this.items.findIndex(i => i.id === id);
|
|
49
|
+
if (idx === -1) throw new Error('Not found');
|
|
50
|
+
this.items[idx] = { ...this.items[idx], ...updates, updatedAt: new Date() };
|
|
51
|
+
return this.items[idx];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async deleteItem(id: string) {
|
|
55
|
+
this.items = this.items.filter(i => i.id !== id);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async search(query: string) {
|
|
59
|
+
const q = query.toLowerCase();
|
|
60
|
+
return this.items.filter(i => i.title.toLowerCase().includes(q));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async getAlbums() { return ALBUMS; }
|
|
64
|
+
|
|
65
|
+
async getByAlbum(album: string) { return this.items.filter(i => i.album === album); }
|
|
66
|
+
|
|
67
|
+
async getByDateRange(start: Date, end: Date) {
|
|
68
|
+
return this.items.filter(i => i.createdAt >= start && i.createdAt <= end);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Types
|
|
2
|
+
export type { ObjectType, ObjectMetadata, IObjectProvider } from '../types-common';
|
|
3
|
+
export type { MediaType, MediaItem, IMediaProvider } from './types';
|
|
4
|
+
|
|
5
|
+
// Model
|
|
6
|
+
export { MediaBrowserModel } from './MediaBrowserModel';
|
|
7
|
+
export type { MediaViewMode, MediaSortBy } from './MediaBrowserModel';
|
|
8
|
+
|
|
9
|
+
// Components
|
|
10
|
+
export { MediaBrowser, type MediaBrowserProps } from './MediaBrowser';
|
|
11
|
+
export { MediaGrid, type MediaGridProps } from './MediaGrid';
|
|
12
|
+
export { MediaList, type MediaListProps } from './MediaList';
|
|
13
|
+
export { MediaTimeline, type MediaTimelineProps } from './MediaTimeline';
|
|
14
|
+
export { MediaPreview, type MediaPreviewProps } from './MediaPreview';
|
|
15
|
+
export { AlbumSidebar, type AlbumSidebarProps } from './AlbumSidebar';
|
|
16
|
+
|
|
17
|
+
// Mock Provider
|
|
18
|
+
export { MockMediaProvider } from './MockMediaProvider';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ObjectMetadata, IObjectProvider } from '../types-common';
|
|
2
|
+
|
|
3
|
+
export type MediaType = 'photo' | 'video' | 'audio';
|
|
4
|
+
|
|
5
|
+
export interface MediaItem extends ObjectMetadata {
|
|
6
|
+
type: 'media';
|
|
7
|
+
mediaType: MediaType;
|
|
8
|
+
url: string;
|
|
9
|
+
mimeType: string;
|
|
10
|
+
width?: number;
|
|
11
|
+
height?: number;
|
|
12
|
+
duration?: number;
|
|
13
|
+
album?: string;
|
|
14
|
+
artist?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface IMediaProvider extends IObjectProvider<MediaItem> {
|
|
18
|
+
getAlbums(): Promise<string[]>;
|
|
19
|
+
getByAlbum(album: string): Promise<MediaItem[]>;
|
|
20
|
+
getByDateRange(start: Date, end: Date): Promise<MediaItem[]>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
/* === Spacing Scale === */
|
|
3
|
+
--fb-space-xxs: 2px;
|
|
4
|
+
--fb-space-xs: 4px;
|
|
5
|
+
--fb-space-sm: 8px;
|
|
6
|
+
--fb-space-md: 12px;
|
|
7
|
+
--fb-space-lg: 16px;
|
|
8
|
+
--fb-space-xl: 24px;
|
|
9
|
+
--fb-space-xxl: 32px;
|
|
10
|
+
|
|
11
|
+
/* === Typography === */
|
|
12
|
+
--fb-font-xs: 0.75rem; /* 12px */
|
|
13
|
+
--fb-font-sm: 0.8125rem; /* 13px */
|
|
14
|
+
--fb-font-md: 0.875rem; /* 14px */
|
|
15
|
+
--fb-font-lg: 1rem; /* 16px */
|
|
16
|
+
|
|
17
|
+
/* === Row Heights === */
|
|
18
|
+
--fb-row-height: 32px;
|
|
19
|
+
--fb-row-height-compact: 28px;
|
|
20
|
+
--fb-row-height-comfortable: 36px;
|
|
21
|
+
|
|
22
|
+
/* === Icon Sizes === */
|
|
23
|
+
--fb-icon-sm: 16px;
|
|
24
|
+
--fb-icon-md: 20px;
|
|
25
|
+
--fb-icon-lg: 24px;
|
|
26
|
+
--fb-icon-xl: 48px;
|
|
27
|
+
--fb-icon-xxl: 64px;
|
|
28
|
+
|
|
29
|
+
/* === Layout === */
|
|
30
|
+
--fb-sidebar-width: 260px;
|
|
31
|
+
--fb-sidebar-collapsed: 0px;
|
|
32
|
+
--fb-toolbar-height: 40px;
|
|
33
|
+
--fb-header-height: 48px;
|
|
34
|
+
|
|
35
|
+
/* === Border Radius === */
|
|
36
|
+
--fb-radius-sm: 4px;
|
|
37
|
+
--fb-radius-md: 6px;
|
|
38
|
+
--fb-radius-lg: 8px;
|
|
39
|
+
|
|
40
|
+
/* === Transitions === */
|
|
41
|
+
--fb-transition-fast: 150ms ease-in-out;
|
|
42
|
+
--fb-transition-normal: 250ms ease-in-out;
|
|
43
|
+
|
|
44
|
+
/* === Z-index Layers === */
|
|
45
|
+
--fb-z-sticky: 20;
|
|
46
|
+
--fb-z-dropdown: 30;
|
|
47
|
+
--fb-z-modal: 50;
|
|
48
|
+
--fb-z-context-menu: 100;
|
|
49
|
+
|
|
50
|
+
/* === File Icon Colors === */
|
|
51
|
+
--fb-icon-folder: #3b82f6;
|
|
52
|
+
--fb-icon-image: #10b981;
|
|
53
|
+
--fb-icon-video: #f97316;
|
|
54
|
+
--fb-icon-audio: #8b5cf6;
|
|
55
|
+
--fb-icon-code: #3b82f6;
|
|
56
|
+
--fb-icon-archive: #f59e0b;
|
|
57
|
+
--fb-icon-text: #6b7280;
|
|
58
|
+
--fb-icon-pdf: #ef4444;
|
|
59
|
+
--fb-icon-default: #6b7280;
|
|
60
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# TreeComponent Development Summary
|
|
2
|
+
|
|
3
|
+
## Project Overview
|
|
4
|
+
This is a monorepo project developing a comprehensive TreeComponent with MobX state management to replace existing FileBrowser components. The project uses **shadcn-like UI** design principles with Tailwind CSS and Lucide React icons.
|
|
5
|
+
|
|
6
|
+
## Architecture Summary
|
|
7
|
+
|
|
8
|
+
### Project Structure
|
|
9
|
+
```
|
|
10
|
+
/Users/andrew/gits/static-generator/last-static-generator-monorepo/
|
|
11
|
+
├── packages/fs-ui/src/TreeComponent/ # Main TreeComponent package
|
|
12
|
+
│ ├── components/ # React components
|
|
13
|
+
│ │ ├── TreeComponent.tsx # Main component
|
|
14
|
+
│ │ ├── TreeNodeList.tsx # Tree view (ARIA compliant)
|
|
15
|
+
│ │ ├── TreeTable.tsx # Table view
|
|
16
|
+
│ │ ├── TreeNode.tsx # Individual node
|
|
17
|
+
│ │ └── TreeContextMenu.tsx # Context menu
|
|
18
|
+
│ ├── models/ # MobX state management
|
|
19
|
+
│ │ ├── TreeModel.ts # Main state model
|
|
20
|
+
│ │ ├── TreeNode.ts # Node data model
|
|
21
|
+
│ │ └── SelectionManager.ts # Selection logic
|
|
22
|
+
│ ├── providers/ # Data providers
|
|
23
|
+
│ │ ├── TreeProvider.ts # Interface
|
|
24
|
+
│ │ ├── TestTreeProvider.ts # Testing/simulation
|
|
25
|
+
│ │ └── SimpleTreeProvider.ts # Production ready
|
|
26
|
+
│ ├── utils/ # Utilities
|
|
27
|
+
│ │ ├── SelectionTheme.ts # Theme utilities
|
|
28
|
+
│ │ └── keyboard.ts # Keyboard handling
|
|
29
|
+
│ └── index.ts # Main exports
|
|
30
|
+
└── apps/web/app/(fixed)/tree-samples/page.tsx # Demo page
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Key Technical Details
|
|
34
|
+
- **State Management**: MobX observables with reactive patterns
|
|
35
|
+
- **UI Framework**: React 18+ with TypeScript
|
|
36
|
+
- **Styling**: Tailwind CSS with shadcn-like components
|
|
37
|
+
- **Icons**: Lucide React
|
|
38
|
+
- **Testing**: Jest + @testing-library/react (infrastructure ready)
|
|
39
|
+
- **Build**: Turbo monorepo setup
|
|
40
|
+
|
|
41
|
+
### Architecture Components
|
|
42
|
+
|
|
43
|
+
1. **TreeModel**: Central MobX state management
|
|
44
|
+
- Observable nodes, selection, expansion state
|
|
45
|
+
- Provider integration
|
|
46
|
+
- Event handling
|
|
47
|
+
|
|
48
|
+
2. **TreeProvider Interface**: Data abstraction layer
|
|
49
|
+
- Async data loading support
|
|
50
|
+
- Context menu configuration
|
|
51
|
+
- Node CRUD operations
|
|
52
|
+
|
|
53
|
+
3. **Components**: Modular React components
|
|
54
|
+
- TreeComponent (main container)
|
|
55
|
+
- TreeNodeList (tree view with ARIA)
|
|
56
|
+
- TreeTable (table view)
|
|
57
|
+
- TreeNode (individual items)
|
|
58
|
+
- TreeContextMenu (right-click menus)
|
|
59
|
+
|
|
60
|
+
## Task Completion Status
|
|
61
|
+
|
|
62
|
+
### ✅ Completed Phases (100%)
|
|
63
|
+
- **Phase 1**: Planning & Setup (4/4 tasks)
|
|
64
|
+
- **Phase 2**: Core Models (3/3 tasks)
|
|
65
|
+
- **Phase 3**: Basic Components (4/4 tasks)
|
|
66
|
+
- **Phase 4**: Advanced Features (4/4 tasks)
|
|
67
|
+
- **Phase 5**: UI Polish (3/3 tasks)
|
|
68
|
+
- **Phase 6**: Accessibility & Polish (4/4 tasks)
|
|
69
|
+
- **Phase 9**: Documentation & Export (4/4 tasks)
|
|
70
|
+
|
|
71
|
+
### 🟡 Phase 7: Testing & Documentation (2/3 tasks)
|
|
72
|
+
- ✅ 7.1: SimpleTreeProvider implementation
|
|
73
|
+
- ✅ 7.2: Complete working example
|
|
74
|
+
- ✅ 7.3: Testing infrastructure setup (Jest ready)
|
|
75
|
+
- ⏳ 7.3: Need actual test implementations
|
|
76
|
+
|
|
77
|
+
### 📅 Phase 8: Advanced Features (future)
|
|
78
|
+
- Multi-column table support
|
|
79
|
+
- Advanced keyboard shortcuts
|
|
80
|
+
- Performance optimizations
|
|
81
|
+
|
|
82
|
+
## Current Production-Ready Features
|
|
83
|
+
|
|
84
|
+
### ✅ Implemented
|
|
85
|
+
- MobX reactive state management
|
|
86
|
+
- Multi-selection with Ctrl+click
|
|
87
|
+
- Complete keyboard navigation (arrows, Home/End, Space/Enter, Ctrl+A, Escape)
|
|
88
|
+
- Context menus (single/multi-node)
|
|
89
|
+
- Lazy loading with async data support
|
|
90
|
+
- ARIA accessibility compliance
|
|
91
|
+
- Professional UI styling
|
|
92
|
+
- Two provider implementations (Test + Simple)
|
|
93
|
+
- Interactive demo page with provider switching
|
|
94
|
+
- Working build system and exports
|
|
95
|
+
|
|
96
|
+
### 🎯 UI Design Principles
|
|
97
|
+
- **shadcn-like UI**: Clean, modern, accessible components
|
|
98
|
+
- **Tailwind CSS**: Utility-first styling
|
|
99
|
+
- **Lucide React**: Consistent iconography
|
|
100
|
+
- **Professional aesthetics**: Production-ready visual design
|
|
101
|
+
|
|
102
|
+
## Current Priority Focus: Interactive Demo Features
|
|
103
|
+
|
|
104
|
+
### 🔴 HIGHEST PRIORITY: Interactive Demos
|
|
105
|
+
1. **3-State Checkbox Demo**: Complete interactive demo showcasing tri-state checkboxes with parent-child selection logic
|
|
106
|
+
2. **Custom Popup Menu Demo**: Showcase flexible context menu system with different menus per node type
|
|
107
|
+
3. **Custom Icons Demo**: Display rich variety of custom icons for different file types and folders
|
|
108
|
+
|
|
109
|
+
### 🟡 HIGH PRIORITY: Core Functionality Fixes
|
|
110
|
+
4. **Selection state rendering**: Fix remaining selection visual feedback issues
|
|
111
|
+
5. **Page layout**: Fix 100vh layout without scrollbars
|
|
112
|
+
6. **Custom theme colors**: Ensure custom color themes apply correctly
|
|
113
|
+
|
|
114
|
+
### 🟢 COMPLETED CRITICAL FIXES
|
|
115
|
+
- ✅ **Children visibility**: Fixed collapse/expand hiding children properly
|
|
116
|
+
- ✅ **Animation system**: Smooth height-based transitions working
|
|
117
|
+
- ✅ **CSS variables**: Removed, using direct color values
|
|
118
|
+
|
|
119
|
+
### 🔵 MEDIUM PRIORITY: Enhancement Features
|
|
120
|
+
7. **Table view consistency**: Tree and table views should look similar for single column
|
|
121
|
+
8. **Collapsible demo groups**: Organize demo controls into collapsible sections
|
|
122
|
+
9. **File explorer demo**: Rich file tree with metadata columns
|
|
123
|
+
10. **Performance demos**: Large tree virtualization examples
|
|
124
|
+
|
|
125
|
+
### 🔵 LOW PRIORITY: Development Tools
|
|
126
|
+
11. **Debug logging**: Enhanced logging for development debugging
|
|
127
|
+
12. **Documentation**: Complete API documentation and examples
|
|
128
|
+
|
|
129
|
+
## Key Implementation Notes
|
|
130
|
+
|
|
131
|
+
### Component Integration
|
|
132
|
+
- TreeComponent accepts provider and configuration props
|
|
133
|
+
- Automatic MobX reactivity handles re-renders
|
|
134
|
+
- ARIA attributes for accessibility compliance
|
|
135
|
+
- Keyboard event handling with proper focus management
|
|
136
|
+
|
|
137
|
+
## Demo Page Location
|
|
138
|
+
- **URL**: `/tree-samples` (fixed layout group)
|
|
139
|
+
- **File**: `apps/web/app/(fixed)/tree-samples/page.tsx`
|
|
140
|
+
- **Features**: Provider switching, theme controls, interaction demos
|
|
141
|
+
|
|
142
|
+
## Next Session Priorities
|
|
143
|
+
1. **🔴 Implement 3-State Checkbox Demo** (Task 12.1) - Interactive tri-state checkbox showcase
|
|
144
|
+
2. **🟡 Create Custom Popup Menu Demo** (Task 12.2) - Different context menus per node type
|
|
145
|
+
3. **🟡 Build Custom Icons Demo** (Task 12.3) - Rich file type icons and custom folder icons
|
|
146
|
+
4. **🟠 Fix remaining core issues** (Task 12.4) - Selection rendering, layout, themes
|
|
147
|
+
5. **🔵 Enhance demo organization** - Collapsible sections, better UX
|
|
148
|
+
|
|
149
|
+
## Build Commands
|
|
150
|
+
```bash
|
|
151
|
+
# Install dependencies
|
|
152
|
+
pnpm install
|
|
153
|
+
|
|
154
|
+
# Run development server
|
|
155
|
+
pnpm dev
|
|
156
|
+
|
|
157
|
+
# Run tests (infrastructure ready)
|
|
158
|
+
pnpm test
|
|
159
|
+
|
|
160
|
+
# Build for production
|
|
161
|
+
pnpm build
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Important Notes for Fresh Sessions
|
|
165
|
+
- TreeComponent is **production-ready** but has critical bugs to fix
|
|
166
|
+
- Test infrastructure is set up but needs actual test implementations
|
|
167
|
+
- UI follows **shadcn design principles** - maintain this consistency
|
|
168
|
+
- All state management uses **MobX observables** - follow established patterns
|
|
169
|
+
- Focus on **accessibility compliance** - ARIA attributes are implemented
|
|
170
|
+
- Demo page showcases all features - use for testing and validation
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
describe("TreeModel Tests", () => {
|
|
2
|
+
test("should work with Jest", () => {
|
|
3
|
+
expect(true).toBe(true);
|
|
4
|
+
});
|
|
5
|
+
|
|
6
|
+
test("should handle async", async () => {
|
|
7
|
+
const result = await Promise.resolve(42);
|
|
8
|
+
expect(result).toBe(42);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test("should use mocks", () => {
|
|
12
|
+
const mock = jest.fn();
|
|
13
|
+
mock("hello");
|
|
14
|
+
expect(mock).toHaveBeenCalledWith("hello");
|
|
15
|
+
});
|
|
16
|
+
});
|