@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.
Files changed (244) hide show
  1. package/dist/ExplorerLayout-CSIJd7N4.js +105 -0
  2. package/dist/ExplorerLayout-CSIJd7N4.js.map +1 -0
  3. package/dist/FileBrowserContext-B6jixa2j.js +11 -0
  4. package/dist/FileBrowserContext-B6jixa2j.js.map +1 -0
  5. package/dist/calendar-DSlrbHoj.js +761 -0
  6. package/dist/calendar-DSlrbHoj.js.map +1 -0
  7. package/dist/calendar.d.ts +3 -0
  8. package/dist/calendar.js +3 -0
  9. package/dist/contacts-DQXTZzHc.js +539 -0
  10. package/dist/contacts-DQXTZzHc.js.map +1 -0
  11. package/dist/contacts.d.ts +3 -0
  12. package/dist/contacts.js +3 -0
  13. package/dist/file-browser-m5atC3kF.js +6755 -0
  14. package/dist/file-browser-m5atC3kF.js.map +1 -0
  15. package/dist/file-browser.d.ts +11 -0
  16. package/dist/file-browser.js +9 -0
  17. package/dist/git-B55e6LL-.js +561 -0
  18. package/dist/git-B55e6LL-.js.map +1 -0
  19. package/dist/git.d.ts +2 -0
  20. package/dist/git.js +3 -0
  21. package/dist/iconMap-V4B8P-Uh.js +206 -0
  22. package/dist/iconMap-V4B8P-Uh.js.map +1 -0
  23. package/dist/icons-CIsIOZXR.js +0 -0
  24. package/dist/icons.d.ts +2 -0
  25. package/dist/icons.js +4 -0
  26. package/dist/index-BNmNIWBL.d.ts +71 -0
  27. package/dist/index-BNmNIWBL.d.ts.map +1 -0
  28. package/dist/index-Bryv_GCG.d.ts +1481 -0
  29. package/dist/index-Bryv_GCG.d.ts.map +1 -0
  30. package/dist/index-CuQIjSXs.d.ts +134 -0
  31. package/dist/index-CuQIjSXs.d.ts.map +1 -0
  32. package/dist/index-DSu19mq0.d.ts +153 -0
  33. package/dist/index-DSu19mq0.d.ts.map +1 -0
  34. package/dist/index-DmsyeHFr.d.ts +149 -0
  35. package/dist/index-DmsyeHFr.d.ts.map +1 -0
  36. package/dist/index-DxnJ8FYM.d.ts +17 -0
  37. package/dist/index-DxnJ8FYM.d.ts.map +1 -0
  38. package/dist/index-DzfY1Tok.d.ts +32 -0
  39. package/dist/index-DzfY1Tok.d.ts.map +1 -0
  40. package/dist/index-Ml_SgiKa.d.ts +1847 -0
  41. package/dist/index-Ml_SgiKa.d.ts.map +1 -0
  42. package/dist/index-kHr9udZD.d.ts +1025 -0
  43. package/dist/index-kHr9udZD.d.ts.map +1 -0
  44. package/dist/index.d.ts +11 -0
  45. package/dist/index.js +15 -0
  46. package/dist/layout-Ca_4r8ka.js +89 -0
  47. package/dist/layout-Ca_4r8ka.js.map +1 -0
  48. package/dist/layout.d.ts +2 -0
  49. package/dist/layout.js +5 -0
  50. package/dist/list-CxfT6hix.js +6831 -0
  51. package/dist/list-CxfT6hix.js.map +1 -0
  52. package/dist/list.d.ts +2 -0
  53. package/dist/list.js +5 -0
  54. package/dist/media-DZ292aKK.js +557 -0
  55. package/dist/media-DZ292aKK.js.map +1 -0
  56. package/dist/media.d.ts +3 -0
  57. package/dist/media.js +3 -0
  58. package/dist/tree-Dd9Z0Aso.js +3351 -0
  59. package/dist/tree-Dd9Z0Aso.js.map +1 -0
  60. package/dist/tree.d.ts +2 -0
  61. package/dist/tree.js +6 -0
  62. package/dist/types-common-CB3kRek8.d.ts +26 -0
  63. package/dist/types-common-CB3kRek8.d.ts.map +1 -0
  64. package/dist/utils-B4fdKKsy.js +3 -0
  65. package/package.json +109 -0
  66. package/src/calendar/AgendaView.tsx +37 -0
  67. package/src/calendar/CalendarBrowser.tsx +90 -0
  68. package/src/calendar/CalendarModel.ts +142 -0
  69. package/src/calendar/CalendarSidebar.tsx +81 -0
  70. package/src/calendar/DayView.tsx +76 -0
  71. package/src/calendar/EventCard.tsx +51 -0
  72. package/src/calendar/MockCalendarProvider.ts +98 -0
  73. package/src/calendar/MonthView.tsx +77 -0
  74. package/src/calendar/WeekView.tsx +129 -0
  75. package/src/calendar/index.ts +18 -0
  76. package/src/calendar/types.ts +25 -0
  77. package/src/contacts/ContactAvatar.tsx +35 -0
  78. package/src/contacts/ContactBrowser.tsx +56 -0
  79. package/src/contacts/ContactCard.tsx +37 -0
  80. package/src/contacts/ContactDetail.tsx +63 -0
  81. package/src/contacts/ContactGroupSidebar.tsx +40 -0
  82. package/src/contacts/ContactList.tsx +32 -0
  83. package/src/contacts/ContactListModel.ts +120 -0
  84. package/src/contacts/MockContactProvider.ts +77 -0
  85. package/src/contacts/index.ts +17 -0
  86. package/src/contacts/types.ts +26 -0
  87. package/src/demos/CalendarBrowserDemo.tsx +15 -0
  88. package/src/demos/ContactBrowserDemo.tsx +15 -0
  89. package/src/demos/MediaBrowserDemo.tsx +15 -0
  90. package/src/file-browser/adapters/DocumentViewerAdapter.ts +371 -0
  91. package/src/file-browser/adapters/FileSystemBridge.ts +168 -0
  92. package/src/file-browser/adapters/GitBrowserAdapter.ts +546 -0
  93. package/src/file-browser/adapters/README.md +504 -0
  94. package/src/file-browser/adapters/index.ts +27 -0
  95. package/src/file-browser/adapters/types.ts +70 -0
  96. package/src/file-browser/architecture.md +645 -0
  97. package/src/file-browser/components/CreateItemDialog.tsx +71 -0
  98. package/src/file-browser/components/DeleteConfirmDialog.tsx +58 -0
  99. package/src/file-browser/components/FileBrowser.tsx +473 -0
  100. package/src/file-browser/components/FileBrowserContent.tsx +209 -0
  101. package/src/file-browser/components/FileBrowserHeader.tsx +151 -0
  102. package/src/file-browser/components/FileBrowserToolbar.tsx +145 -0
  103. package/src/file-browser/components/LeftPanel/LeftPanel.tsx +103 -0
  104. package/src/file-browser/components/LeftPanel/LeftPanelTabs.tsx +70 -0
  105. package/src/file-browser/components/LeftPanel/TreeNavigationView.tsx +256 -0
  106. package/src/file-browser/components/PreviewPane.tsx +146 -0
  107. package/src/file-browser/components/RightPanel/FilePreview.tsx +219 -0
  108. package/src/file-browser/components/RightPanel/RightPanel.tsx +186 -0
  109. package/src/file-browser/components/RightPanel/RightPanelToolbar.tsx +113 -0
  110. package/src/file-browser/components/UploadProgress.tsx +123 -0
  111. package/src/file-browser/components/ViewerHost.tsx +208 -0
  112. package/src/file-browser/components/mobile/MobileNavigation.tsx +227 -0
  113. package/src/file-browser/components/navigation/NavigationButtons.tsx +171 -0
  114. package/src/file-browser/components/shared/ErrorBoundary.tsx +116 -0
  115. package/src/file-browser/components/shared/FileBrowserItem.tsx +195 -0
  116. package/src/file-browser/components/shared/FileIcon.tsx +169 -0
  117. package/src/file-browser/components/toolbar/ViewModeToggle.tsx +200 -0
  118. package/src/file-browser/components/views/ListView/ListView.tsx +484 -0
  119. package/src/file-browser/components/views/ThumbnailView/ThumbnailView.tsx +323 -0
  120. package/src/file-browser/components/views/TreeView/TreeNode.tsx +186 -0
  121. package/src/file-browser/components/views/TreeView/TreeNodeList.tsx +191 -0
  122. package/src/file-browser/components/views/TreeView/TreeView.tsx +200 -0
  123. package/src/file-browser/components/views/TreemapView/TreemapView.tsx +339 -0
  124. package/src/file-browser/context/FileBrowserContext.tsx +13 -0
  125. package/src/file-browser/examples/BasicUsage.tsx +20 -0
  126. package/src/file-browser/index.ts +98 -0
  127. package/src/file-browser/models/FileBrowserModel.ts +623 -0
  128. package/src/file-browser/models/LeftPanelManagerModel.ts +105 -0
  129. package/src/file-browser/models/NavigationManagerModel.ts +312 -0
  130. package/src/file-browser/models/ResponsiveLayoutManagerModel.ts +437 -0
  131. package/src/file-browser/models/RightPanelManagerModel.ts +190 -0
  132. package/src/file-browser/models/SelectionManagerModel.ts +252 -0
  133. package/src/file-browser/models/ToolbarManagerModel.ts +144 -0
  134. package/src/file-browser/models/UploadModel.ts +147 -0
  135. package/src/file-browser/models/ViewModeManagerModel.ts +185 -0
  136. package/src/file-browser/models/ViewerHostModel.ts +44 -0
  137. package/src/file-browser/models/ui/ListViewUIModel.ts +265 -0
  138. package/src/file-browser/models/ui/PreviewUIModel.ts +297 -0
  139. package/src/file-browser/models/ui/ThumbnailViewUIModel.ts +254 -0
  140. package/src/file-browser/models/ui/TreeViewUIModel.ts +128 -0
  141. package/src/file-browser/models/ui/TreemapViewUIModel.ts +350 -0
  142. package/src/file-browser/providers/FileSystemListProvider.ts +552 -0
  143. package/src/file-browser/providers/FileSystemProvider.ts +401 -0
  144. package/src/file-browser/providers/FileSystemTreeProvider.ts +231 -0
  145. package/src/file-browser/providers/GitProvider.ts +337 -0
  146. package/src/file-browser/providers/GitRepositoryProvider.ts +376 -0
  147. package/src/file-browser/providers/IFileBrowserProvider.ts +56 -0
  148. package/src/file-browser/providers/MemoryProvider.ts +303 -0
  149. package/src/file-browser/providers/index.ts +4 -0
  150. package/src/file-browser/registry/ViewerRegistry.ts +551 -0
  151. package/src/file-browser/registry/types.ts +144 -0
  152. package/src/file-browser/scripts/performanceBenchmark.ts +553 -0
  153. package/src/file-browser/services/ThumbnailCacheService.ts +128 -0
  154. package/src/file-browser/tasks.md +537 -0
  155. package/src/file-browser/types/FileBrowserTypes.ts +126 -0
  156. package/src/file-browser/types/ProviderTypes.ts +155 -0
  157. package/src/file-browser/types/UITypes.ts +235 -0
  158. package/src/file-browser/types/ViewModeTypes.ts +150 -0
  159. package/src/file-browser/utils/gestures.ts +327 -0
  160. package/src/file-browser/utils/performance.ts +563 -0
  161. package/src/file-browser/viewers/ImageViewer.tsx +163 -0
  162. package/src/file-browser/viewers/ImageViewerModel.ts +79 -0
  163. package/src/file-browser/viewers/TextViewer.tsx +95 -0
  164. package/src/file-browser/viewers/UnsupportedFileViewer.tsx +57 -0
  165. package/src/file-browser/viewers/index.ts +61 -0
  166. package/src/git/BranchList.tsx +128 -0
  167. package/src/git/CommitGraph.tsx +239 -0
  168. package/src/git/CommitList.tsx +258 -0
  169. package/src/git/DiffViewer.tsx +219 -0
  170. package/src/git/index.ts +4 -0
  171. package/src/icons/iconMap.ts +146 -0
  172. package/src/icons/index.ts +9 -0
  173. package/src/index.ts +13 -0
  174. package/src/layout/README.md +307 -0
  175. package/src/layout/components/ExplorerLayout/ExplorerLayout.tsx +178 -0
  176. package/src/layout/examples/SimpleExample.tsx +60 -0
  177. package/src/layout/index.ts +6 -0
  178. package/src/lib/utils.ts +1 -0
  179. package/src/list/README.md +303 -0
  180. package/src/list/architecture.md +807 -0
  181. package/src/list/components/CalculatedGridView.tsx +252 -0
  182. package/src/list/components/DragPreview.tsx +102 -0
  183. package/src/list/components/ListContextMenu.tsx +274 -0
  184. package/src/list/components/ListItem.tsx +761 -0
  185. package/src/list/components/ListItems.tsx +919 -0
  186. package/src/list/components/MasonryView.tsx +241 -0
  187. package/src/list/components/SearchFilter.tsx +44 -0
  188. package/src/list/components/TreemapView.tsx +709 -0
  189. package/src/list/components/ViewSizeControls.tsx +205 -0
  190. package/src/list/components/ViewTypeSelector.tsx +312 -0
  191. package/src/list/components/VirtualizedDetailsView.tsx +231 -0
  192. package/src/list/components/VirtualizedGrid.tsx +164 -0
  193. package/src/list/components/VirtualizedList.tsx +154 -0
  194. package/src/list/components/VirtualizedMasonryView.tsx +344 -0
  195. package/src/list/components/shared/EmptyState.tsx +103 -0
  196. package/src/list/components/shared/ErrorBoundary.tsx +123 -0
  197. package/src/list/components/shared/ErrorDisplay.tsx +100 -0
  198. package/src/list/components/shared/ListLoader.tsx +146 -0
  199. package/src/list/components/shared/LoadingIndicator.tsx +80 -0
  200. package/src/list/index.ts +92 -0
  201. package/src/list/models/ListItemsModel.ts +1301 -0
  202. package/src/list/models/TreemapModel.ts +204 -0
  203. package/src/list/providers/ListItemsProvider.ts +313 -0
  204. package/src/list/providers/TestListProvider.ts +604 -0
  205. package/src/list/tasks.md +937 -0
  206. package/src/list/types/ListTypes.ts +178 -0
  207. package/src/list/utils/BenchmarkLogger.ts +243 -0
  208. package/src/list/utils/DragDropManager.ts +320 -0
  209. package/src/list/utils/GridLayoutCalculator.ts +290 -0
  210. package/src/list/utils/ListAccessibility.ts +367 -0
  211. package/src/list/utils/ListKeyboard.ts +414 -0
  212. package/src/list/utils/MasonryLayoutCalculator.ts +302 -0
  213. package/src/list/utils/MasonryLayoutEngine.ts +401 -0
  214. package/src/list/utils/__tests__/MasonryLayoutEngine.test.ts +157 -0
  215. package/src/list/utils/__tests__/VirtualizedMasonryView.test.tsx +251 -0
  216. package/src/media/AlbumSidebar.tsx +48 -0
  217. package/src/media/MediaBrowser.tsx +92 -0
  218. package/src/media/MediaBrowserModel.ts +138 -0
  219. package/src/media/MediaGrid.tsx +50 -0
  220. package/src/media/MediaList.tsx +49 -0
  221. package/src/media/MediaPreview.tsx +63 -0
  222. package/src/media/MediaTimeline.tsx +38 -0
  223. package/src/media/MockMediaProvider.ts +70 -0
  224. package/src/media/index.ts +18 -0
  225. package/src/media/types.ts +21 -0
  226. package/src/styles/variables.css +60 -0
  227. package/src/tree/DEVELOPMENT_SUMMARY.md +170 -0
  228. package/src/tree/__tests__/TreeModel.test.ts +16 -0
  229. package/src/tree/architecture.md +530 -0
  230. package/src/tree/components/Tree.tsx +283 -0
  231. package/src/tree/components/TreeCheckbox.tsx +147 -0
  232. package/src/tree/components/TreeContextMenu.tsx +139 -0
  233. package/src/tree/components/TreeNodeList.tsx +329 -0
  234. package/src/tree/components/TreeTable.tsx +382 -0
  235. package/src/tree/index.ts +58 -0
  236. package/src/tree/models/TreeModel.ts +839 -0
  237. package/src/tree/providers/SimpleTreeProvider.ts +463 -0
  238. package/src/tree/providers/TestTreeProvider.ts +946 -0
  239. package/src/tree/providers/TreeProvider.ts +308 -0
  240. package/src/tree/tasks.md +2046 -0
  241. package/src/tree/types/TreeTypes.ts +279 -0
  242. package/src/tree/utils/SelectionTheme.ts +150 -0
  243. package/src/tree/utils/logger.ts +203 -0
  244. package/src/types-common.ts +21 -0
@@ -0,0 +1,504 @@
1
+ # FileBrowser Adapter System
2
+
3
+ This directory contains example adapters demonstrating how to integrate external systems with the FileBrowser's dual-panel coordination system.
4
+
5
+ ## Overview
6
+
7
+ The FileBrowser adapter system provides a standardized way to:
8
+ - Extend FileBrowser functionality with domain-specific features
9
+ - Maintain selection and navigation coordination between external systems and FileBrowser panels
10
+ - Implement reactive patterns using MobX for seamless state synchronization
11
+ - Handle complex multi-panel interactions and state management
12
+
13
+ ## Architecture
14
+
15
+ ### Coordination Pattern
16
+
17
+ The core coordination pattern follows these principles:
18
+
19
+ ```typescript
20
+ // 1. Listen to FileBrowser state changes via MobX reactions
21
+ const selectionDisposer = reaction(
22
+ () => ({
23
+ selectedItems: Array.from(fileBrowserModel.selectionManager.selectedItems.keys()),
24
+ focusedItem: fileBrowserModel.selectionManager.focusedItem
25
+ }),
26
+ ({ focusedItem }) => {
27
+ // React to selection changes
28
+ this.handleSelectionChange(focusedItem);
29
+ }
30
+ );
31
+
32
+ // 2. Update external system state based on FileBrowser changes
33
+ private async handleSelectionChange(item: FileBrowserItem | null) {
34
+ if (!item) return;
35
+
36
+ // Update external system
37
+ await this.updateExternalSystem(item);
38
+ }
39
+
40
+ // 3. Coordinate back to FileBrowser when external system changes
41
+ public selectFromExternalSystem(externalItem: any) {
42
+ // Convert external item to FileBrowser item
43
+ const fileBrowserItem = this.convertToFileBrowserItem(externalItem);
44
+
45
+ // Use coordination methods
46
+ this.fileBrowserModel.selectionManager.selectItem(fileBrowserItem.id);
47
+ }
48
+ ```
49
+
50
+ ### Key Coordination Points
51
+
52
+ 1. **Selection Coordination**: Synchronize selection between FileBrowser and external systems
53
+ 2. **Navigation Coordination**: Coordinate navigation events across panels
54
+ 3. **State Management**: Maintain consistent state between systems
55
+ 4. **Error Handling**: Provide graceful error handling with proper user feedback
56
+
57
+ ## Example Adapters
58
+
59
+ ### DocumentViewerAdapter
60
+
61
+ Demonstrates integration with a document viewing system:
62
+
63
+ ```typescript
64
+ import { DocumentViewerAdapter } from './DocumentViewerAdapter';
65
+
66
+ // Initialize adapter
67
+ const documentViewer = new DocumentViewerAdapter(fileBrowserModel, {
68
+ supportedFileTypes: ['.pdf', '.doc', '.docx', '.txt', '.md'],
69
+ previewEnabled: true,
70
+ maxFileSize: 50 * 1024 * 1024, // 50MB
71
+ enableCoordination: true
72
+ });
73
+
74
+ // Document will automatically load when files are selected in FileBrowser
75
+ // Navigation will automatically clear stale document state
76
+ ```
77
+
78
+ **Key Features:**
79
+ - Automatic document loading on file selection
80
+ - Preview generation and caching
81
+ - File type validation and size constraints
82
+ - Navigation-aware state management
83
+ - Bidirectional coordination with FileBrowser
84
+
85
+ ### GitBrowserAdapter
86
+
87
+ Demonstrates integration with Git repository functionality:
88
+
89
+ ```typescript
90
+ import { GitBrowserAdapter } from './GitBrowserAdapter';
91
+
92
+ // Initialize adapter
93
+ const gitBrowser = new GitBrowserAdapter(fileBrowserModel, {
94
+ repositoryPath: '/path/to/repo',
95
+ autoFetch: false,
96
+ statusRefreshInterval: 5000,
97
+ enableCoordination: true
98
+ });
99
+
100
+ // Load repository
101
+ await gitBrowser.loadRepository('/path/to/repo');
102
+
103
+ // Git status will automatically update based on FileBrowser navigation
104
+ // Branch switching will coordinate with FileBrowser content updates
105
+ ```
106
+
107
+ **Key Features:**
108
+ - Git repository integration
109
+ - Branch and commit coordination
110
+ - File status overlay
111
+ - Left panel mode integration
112
+ - Automatic status refresh
113
+
114
+ ## Creating Custom Adapters
115
+
116
+ ### Step 1: Define Your Adapter Interface
117
+
118
+ ```typescript
119
+ export interface MyAdapterOptions {
120
+ // Configuration options
121
+ enableCoordination?: boolean;
122
+ // ... other options
123
+ }
124
+
125
+ export class MyAdapter {
126
+ private fileBrowserModel: FileBrowserModel;
127
+ private options: Required<MyAdapterOptions>;
128
+ private disposers: Array<() => void> = [];
129
+
130
+ constructor(fileBrowserModel: FileBrowserModel, options: MyAdapterOptions = {}) {
131
+ this.fileBrowserModel = fileBrowserModel;
132
+ this.options = {
133
+ enableCoordination: true,
134
+ ...options
135
+ };
136
+
137
+ makeAutoObservable(this);
138
+
139
+ if (this.options.enableCoordination) {
140
+ this.setupCoordination();
141
+ }
142
+ }
143
+ }
144
+ ```
145
+
146
+ ### Step 2: Setup Coordination Reactions
147
+
148
+ ```typescript
149
+ private setupCoordination() {
150
+ // Listen for selection changes
151
+ const selectionDisposer = reaction(
152
+ () => ({
153
+ focusedItem: this.fileBrowserModel.selectionManager.focusedItem
154
+ }),
155
+ ({ focusedItem }) => {
156
+ this.handleSelectionChange(focusedItem);
157
+ },
158
+ { fireImmediately: true }
159
+ );
160
+
161
+ // Listen for navigation changes
162
+ const navigationDisposer = reaction(
163
+ () => this.fileBrowserModel.navigationManager.currentPath,
164
+ (currentPath) => {
165
+ this.handleNavigationChange(currentPath || '/');
166
+ }
167
+ );
168
+
169
+ this.disposers.push(selectionDisposer, navigationDisposer);
170
+ }
171
+ ```
172
+
173
+ ### Step 3: Implement Coordination Handlers
174
+
175
+ ```typescript
176
+ private async handleSelectionChange(item: FileBrowserItem | null) {
177
+ if (!item) {
178
+ this.clearExternalState();
179
+ return;
180
+ }
181
+
182
+ // Update external system based on selection
183
+ try {
184
+ await this.updateExternalSystem(item);
185
+ this.logInfo(`Updated external system for: ${item.name}`);
186
+ } catch (error) {
187
+ this.logError('Failed to update external system', error);
188
+ }
189
+ }
190
+
191
+ private async handleNavigationChange(currentPath: string) {
192
+ // React to navigation changes
193
+ await this.refreshExternalSystemForPath(currentPath);
194
+ }
195
+ ```
196
+
197
+ ### Step 4: Provide Public APIs
198
+
199
+ ```typescript
200
+ // Public methods for external control
201
+ public async loadItem(item: FileBrowserItem): Promise<void> {
202
+ // Use coordination to load item
203
+ this.fileBrowserModel.selectionManager.selectItem(item.id);
204
+ }
205
+
206
+ public navigateToItem(item: FileBrowserItem): void {
207
+ // Use navigation coordination
208
+ const directoryPath = this.getDirectoryPath(item.path);
209
+ this.fileBrowserModel.navigationManager.navigateToWithCoordination(
210
+ directoryPath,
211
+ 'breadcrumb'
212
+ );
213
+ }
214
+ ```
215
+
216
+ ### Step 5: Implement Cleanup
217
+
218
+ ```typescript
219
+ dispose(): void {
220
+ // Clean up all reactions
221
+ this.disposers.forEach(dispose => dispose());
222
+ this.disposers = [];
223
+
224
+ // Clean up external resources
225
+ this.cleanupExternalSystem();
226
+
227
+ this.logInfo('Adapter disposed');
228
+ }
229
+ ```
230
+
231
+ ## Best Practices
232
+
233
+ ### 1. Reactive State Management
234
+
235
+ - Use MobX `reaction` for listening to FileBrowser state changes
236
+ - Use `makeAutoObservable` for adapter state
237
+ - Avoid direct state mutations, use actions instead
238
+
239
+ ### 2. Error Handling
240
+
241
+ ```typescript
242
+ private async handleCoordinatedOperation(operation: () => Promise<void>) {
243
+ try {
244
+ await operation();
245
+ } catch (error) {
246
+ this.setError(`Operation failed: ${error}`);
247
+ // Optionally notify user through FileBrowser error system
248
+ }
249
+ }
250
+ ```
251
+
252
+ ### 3. Performance Optimization
253
+
254
+ ```typescript
255
+ // Use caching for expensive operations
256
+ private cache = new Map<string, any>();
257
+
258
+ private async getExpensiveData(key: string): Promise<any> {
259
+ if (this.cache.has(key)) {
260
+ return this.cache.get(key);
261
+ }
262
+
263
+ const data = await this.computeExpensiveData(key);
264
+ this.cache.set(key, data);
265
+ return data;
266
+ }
267
+ ```
268
+
269
+ ### 4. Logging and Debugging
270
+
271
+ ```typescript
272
+ private logInfo(message: string, data?: any): void {
273
+ this.fileBrowserModel.logger?.info(`[MyAdapter] ${message}`, data);
274
+ }
275
+
276
+ private logError(message: string, error: any): void {
277
+ this.fileBrowserModel.logger?.error(`[MyAdapter] ${message}`, error);
278
+ }
279
+ ```
280
+
281
+ ### 5. Configuration Management
282
+
283
+ ```typescript
284
+ // Provide sensible defaults
285
+ private readonly defaultOptions: Required<MyAdapterOptions> = {
286
+ enableCoordination: true,
287
+ cacheSize: 100,
288
+ refreshInterval: 5000
289
+ };
290
+
291
+ constructor(fileBrowserModel: FileBrowserModel, options: MyAdapterOptions = {}) {
292
+ this.options = { ...this.defaultOptions, ...options };
293
+ }
294
+ ```
295
+
296
+ ## Migration Guide
297
+
298
+ ### From Single-Panel to Dual-Panel
299
+
300
+ If you have existing FileBrowser integrations that need to be migrated to the dual-panel coordination system:
301
+
302
+ #### 1. Update Event Handling
303
+
304
+ **Before (single-panel):**
305
+ ```typescript
306
+ // Direct event handling
307
+ onItemClick(item: FileBrowserItem) {
308
+ this.externalSystem.loadItem(item);
309
+ }
310
+ ```
311
+
312
+ **After (dual-panel coordination):**
313
+ ```typescript
314
+ // Coordination-based handling
315
+ private setupCoordination() {
316
+ reaction(
317
+ () => this.fileBrowserModel.selectionManager.focusedItem,
318
+ (item) => {
319
+ if (item) {
320
+ this.externalSystem.loadItem(item);
321
+ }
322
+ }
323
+ );
324
+ }
325
+ ```
326
+
327
+ #### 2. Update Navigation Handling
328
+
329
+ **Before:**
330
+ ```typescript
331
+ // Direct navigation
332
+ onNavigate(path: string) {
333
+ this.externalSystem.updatePath(path);
334
+ }
335
+ ```
336
+
337
+ **After:**
338
+ ```typescript
339
+ // Coordination-based navigation
340
+ private setupCoordination() {
341
+ reaction(
342
+ () => this.fileBrowserModel.navigationManager.currentPath,
343
+ (path) => {
344
+ if (path) {
345
+ this.externalSystem.updatePath(path);
346
+ }
347
+ }
348
+ );
349
+ }
350
+ ```
351
+
352
+ #### 3. Update State Management
353
+
354
+ **Before:**
355
+ ```typescript
356
+ // Manual state tracking
357
+ private selectedItem: FileBrowserItem | null = null;
358
+
359
+ setSelectedItem(item: FileBrowserItem) {
360
+ this.selectedItem = item;
361
+ this.updateUI();
362
+ }
363
+ ```
364
+
365
+ **After:**
366
+ ```typescript
367
+ // MobX reactive state
368
+ @observable
369
+ selectedItem: FileBrowserItem | null = null;
370
+
371
+ // Automatic updates via reactions
372
+ private setupCoordination() {
373
+ reaction(
374
+ () => this.fileBrowserModel.selectionManager.focusedItem,
375
+ (item) => {
376
+ this.selectedItem = item;
377
+ // UI updates automatically via MobX
378
+ }
379
+ );
380
+ }
381
+ ```
382
+
383
+ ## Performance Considerations
384
+
385
+ ### Large Datasets
386
+
387
+ When working with large datasets:
388
+
389
+ 1. **Implement Virtualization**: Only load/render visible items
390
+ 2. **Use Pagination**: Break large datasets into manageable chunks
391
+ 3. **Cache Strategically**: Cache frequently accessed data with appropriate TTL
392
+ 4. **Debounce Updates**: Avoid excessive updates during rapid changes
393
+
394
+ ```typescript
395
+ // Example: Debounced status updates
396
+ private debouncedStatusUpdate = debounce(async () => {
397
+ await this.refreshStatus();
398
+ }, 500);
399
+
400
+ private handleNavigationChange(path: string) {
401
+ this.debouncedStatusUpdate();
402
+ }
403
+ ```
404
+
405
+ ### Memory Management
406
+
407
+ ```typescript
408
+ // Clean up resources properly
409
+ dispose(): void {
410
+ // Dispose reactions
411
+ this.disposers.forEach(dispose => dispose());
412
+
413
+ // Clear caches
414
+ this.cache.clear();
415
+
416
+ // Cancel pending operations
417
+ this.cancelPendingOperations();
418
+
419
+ // Clear timers
420
+ if (this.refreshTimer) {
421
+ clearInterval(this.refreshTimer);
422
+ }
423
+ }
424
+ ```
425
+
426
+ ## Testing
427
+
428
+ ### Unit Testing Adapters
429
+
430
+ ```typescript
431
+ import { DocumentViewerAdapter } from './DocumentViewerAdapter';
432
+
433
+ describe('DocumentViewerAdapter', () => {
434
+ let adapter: DocumentViewerAdapter;
435
+ let mockFileBrowserModel: jest.Mocked<FileBrowserModel>;
436
+
437
+ beforeEach(() => {
438
+ mockFileBrowserModel = createMockFileBrowserModel();
439
+ adapter = new DocumentViewerAdapter(mockFileBrowserModel);
440
+ });
441
+
442
+ afterEach(() => {
443
+ adapter.dispose();
444
+ });
445
+
446
+ it('should load document when file is selected', async () => {
447
+ const testFile = createTestFile('test.pdf');
448
+
449
+ // Simulate selection change
450
+ mockFileBrowserModel.selectionManager.focusedItem = testFile;
451
+
452
+ // Wait for coordination
453
+ await waitForReaction();
454
+
455
+ expect(adapter.currentDocument).toBeTruthy();
456
+ expect(adapter.currentDocument?.fileName).toBe('test.pdf');
457
+ });
458
+ });
459
+ ```
460
+
461
+ ### Integration Testing
462
+
463
+ ```typescript
464
+ describe('Adapter Coordination', () => {
465
+ it('should maintain coordination between adapters', async () => {
466
+ const documentAdapter = new DocumentViewerAdapter(fileBrowserModel);
467
+ const gitAdapter = new GitBrowserAdapter(fileBrowserModel);
468
+
469
+ // Select a file
470
+ fileBrowserModel.selectionManager.selectItem('file1');
471
+
472
+ // Both adapters should react
473
+ await waitForReactions();
474
+
475
+ expect(documentAdapter.currentDocument).toBeTruthy();
476
+ expect(gitAdapter.getFileStatus('file1')).toBeTruthy();
477
+ });
478
+ });
479
+ ```
480
+
481
+ ## Troubleshooting
482
+
483
+ ### Common Issues
484
+
485
+ 1. **Infinite Loops**: Use coordination flags to prevent circular updates
486
+ 2. **Memory Leaks**: Always dispose reactions and clear caches
487
+ 3. **Performance Issues**: Implement debouncing and caching
488
+ 4. **Type Errors**: Ensure proper TypeScript interfaces for coordination
489
+
490
+ ### Debugging Tips
491
+
492
+ ```typescript
493
+ // Enable detailed logging
494
+ private logInfo(message: string, data?: any): void {
495
+ if (process.env.NODE_ENV === 'development') {
496
+ console.log(`[${this.constructor.name}] ${message}`, data);
497
+ }
498
+ this.fileBrowserModel.logger?.info(`[${this.constructor.name}] ${message}`, data);
499
+ }
500
+ ```
501
+
502
+ ## Examples
503
+
504
+ See the `/examples` directory for complete working examples of various adapter patterns and integration scenarios.
@@ -0,0 +1,27 @@
1
+ // Adapter implementations
2
+ export { DocumentViewerAdapter } from './DocumentViewerAdapter';
3
+ export type {
4
+ DocumentViewerOptions,
5
+ DocumentInfo
6
+ } from './DocumentViewerAdapter';
7
+
8
+ export { GitBrowserAdapter } from './GitBrowserAdapter';
9
+ export type {
10
+ GitBrowserOptions,
11
+ GitFileStatus,
12
+ GitCommit,
13
+ GitBranch,
14
+ GitRepositoryInfo
15
+ } from './GitBrowserAdapter';
16
+
17
+ // Base adapter patterns and utilities
18
+ export type { AdapterBase, AdapterOptions, AdapterStats, AdapterDisposer } from './types';
19
+ export { BaseAdapter } from './types';
20
+
21
+ /**
22
+ * Re-export core FileBrowser types for adapter development
23
+ */
24
+ export type { FileBrowserItem } from '../types/FileBrowserTypes';
25
+ export type { FileBrowserModel } from '../models/FileBrowserModel';
26
+ export type { SelectionManagerModel } from '../models/SelectionManagerModel';
27
+ export type { NavigationManagerModel } from '../models/NavigationManagerModel';
@@ -0,0 +1,70 @@
1
+ import { FileBrowserModel } from '../models/FileBrowserModel';
2
+ import { FileBrowserItem } from '../types/FileBrowserTypes';
3
+
4
+ /**
5
+ * Base adapter options that all adapters should support
6
+ */
7
+ export interface AdapterOptions {
8
+ enableCoordination?: boolean;
9
+ enableLogging?: boolean;
10
+ }
11
+
12
+ /**
13
+ * Base adapter interface that all adapters should implement
14
+ */
15
+ export interface AdapterBase {
16
+ // Core adapter lifecycle
17
+ dispose(): void;
18
+
19
+ // Coordination methods
20
+ handleSelectionChange(item: FileBrowserItem | null): void | Promise<void>;
21
+ handleNavigationChange(path: string): void | Promise<void>;
22
+
23
+ // Status methods
24
+ readonly isLoading: boolean;
25
+ readonly error: string | null;
26
+ }
27
+
28
+ /**
29
+ * Common coordination patterns for adapters
30
+ */
31
+ export abstract class BaseAdapter implements AdapterBase {
32
+ protected fileBrowserModel: FileBrowserModel;
33
+ protected disposers: Array<() => void> = [];
34
+
35
+ abstract isLoading: boolean;
36
+ abstract error: string | null;
37
+
38
+ constructor(fileBrowserModel: FileBrowserModel) {
39
+ this.fileBrowserModel = fileBrowserModel;
40
+ }
41
+
42
+ abstract handleSelectionChange(item: FileBrowserItem | null): void | Promise<void>;
43
+ abstract handleNavigationChange(path: string): void | Promise<void>;
44
+
45
+ protected logInfo(message: string, data?: any): void {
46
+ this.fileBrowserModel.logger?.info(`[${this.constructor.name}] ${message}`, data);
47
+ }
48
+
49
+ protected logError(message: string, error: any): void {
50
+ this.fileBrowserModel.logger?.error(`[${this.constructor.name}] ${message}`, error);
51
+ }
52
+
53
+ dispose(): void {
54
+ this.disposers.forEach(dispose => dispose());
55
+ this.disposers = [];
56
+ this.logInfo('Adapter disposed');
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Utility types for adapter development
62
+ */
63
+ export type AdapterDisposer = () => void;
64
+
65
+ export interface AdapterStats {
66
+ isLoaded: boolean;
67
+ hasError: boolean;
68
+ cacheSize?: number;
69
+ [key: string]: any;
70
+ }