@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,463 @@
1
+ /**
2
+ * SimpleTreeProvider - Straightforward implementation for static tree data
3
+ *
4
+ * This provider is designed for simple use cases where you have static
5
+ * tree data that doesn't require complex loading, error simulation, or
6
+ * dynamic generation. It's perfect for:
7
+ * - Static file trees
8
+ * - Simple navigation trees
9
+ * - Documentation structures
10
+ * - Basic hierarchical data display
11
+ */
12
+
13
+ import { makeAutoObservable } from 'mobx';
14
+ import type { TreeProvider, TreeSelectionInfo } from './TreeProvider';
15
+ import type { TreeNodeData, TreeLoadResult, TreeLoadOptions, TreeContextMenuItem, TreeSelectionTheme } from '../types/TreeTypes';
16
+ import { DEFAULT_SELECTION_THEME } from '../utils/SelectionTheme';
17
+
18
+ export interface SimpleTreeProviderOptions {
19
+ /** Whether to enable multi-select functionality */
20
+ enableMultiSelect?: boolean;
21
+ /** Whether to enable drag and drop */
22
+ enableDragDrop?: boolean;
23
+ /** Static tree data to display */
24
+ data?: TreeNodeData[];
25
+ /** Custom context menu items */
26
+ contextMenuItems?: TreeContextMenuItem[];
27
+ /** Callback when nodes are selected */
28
+ onSelectionChange?: (selectionInfo: TreeSelectionInfo) => void;
29
+ /** Callback when context menu actions are triggered */
30
+ onContextMenuAction?: (actionId: string, nodes: TreeNodeData[]) => void;
31
+ }
32
+
33
+ export class SimpleTreeProvider implements TreeProvider {
34
+ // Provider metadata (required)
35
+ readonly id = 'simple-tree-provider';
36
+ readonly name = 'Simple Tree Provider';
37
+ readonly version = '1.0.0';
38
+
39
+ // Configuration (required)
40
+ isMultiSelectEnabled = true;
41
+ readonly isDragDropEnabled = false;
42
+ readonly isVirtualizationEnabled = false;
43
+ readonly isTableViewEnabled = false;
44
+ useCheckboxSelection = false;
45
+ readonly allowPartialSelection = true;
46
+ readonly config = {};
47
+
48
+ // Observable selection theme
49
+ selectionTheme: TreeSelectionTheme = {
50
+ ...DEFAULT_SELECTION_THEME,
51
+ colorScheme: 'primary',
52
+ intensity: 'prominent',
53
+ focusStyle: 'ring',
54
+ animated: true,
55
+ persistSelection: true
56
+ };
57
+
58
+ // Data
59
+ private nodes: TreeNodeData[] = [];
60
+ private contextMenuItems: TreeContextMenuItem[] = [];
61
+
62
+ // Callbacks (optional)
63
+ onSelectionChange?: (selectionInfo: TreeSelectionInfo) => void;
64
+ onNodeExpansion?: (node: TreeNodeData, isExpanded: boolean) => void;
65
+ onNodeFocus?: (node: TreeNodeData | null) => void;
66
+ onContextMenuAction?: (actionId: string, nodes: TreeNodeData[]) => void;
67
+
68
+ constructor(options: SimpleTreeProviderOptions = {}) {
69
+ this.nodes = options.data ?? this.createDefaultData();
70
+ this.contextMenuItems = options.contextMenuItems ?? this.createDefaultContextMenu();
71
+ this.onSelectionChange = options.onSelectionChange;
72
+ this.onContextMenuAction = options.onContextMenuAction;
73
+ makeAutoObservable(this, {
74
+ id: false,
75
+ name: false,
76
+ version: false,
77
+ isDragDropEnabled: false,
78
+ isVirtualizationEnabled: false,
79
+ isTableViewEnabled: false,
80
+ config: false,
81
+ // Make isMultiSelectEnabled and useCheckboxSelection observable
82
+ // isMultiSelectEnabled: true (default - observable)
83
+ // useCheckboxSelection: true (default - observable)
84
+ });
85
+ }
86
+
87
+ /**
88
+ * Load root nodes
89
+ */
90
+ async loadNodes(options?: TreeLoadOptions): Promise<TreeLoadResult> {
91
+ // Simple provider returns static data immediately
92
+ return {
93
+ nodes: this.nodes,
94
+ hasMore: false,
95
+ totalCount: this.nodes.length
96
+ };
97
+ }
98
+
99
+ /**
100
+ * Load children for a specific node
101
+ */
102
+ async loadChildren(node: TreeNodeData, options?: TreeLoadOptions): Promise<TreeLoadResult> {
103
+ // Children are already loaded in the static data structure
104
+ const children = node.children || [];
105
+
106
+ return {
107
+ nodes: children,
108
+ hasMore: false,
109
+ totalCount: children.length
110
+ };
111
+ }
112
+
113
+ /**
114
+ * Refresh/reload nodes
115
+ */
116
+ async refresh(path?: string): Promise<TreeLoadResult> {
117
+ // For static provider, refresh just returns current data
118
+ if (path) {
119
+ // Find specific node to refresh
120
+ const node = this.findNodeByPath(path);
121
+ if (node) {
122
+ return this.loadChildren(node);
123
+ }
124
+ }
125
+
126
+ // Refresh all data
127
+ return this.loadNodes();
128
+ }
129
+
130
+ /**
131
+ * Get context menu for a single node
132
+ */
133
+ getNodeContextMenu(node: TreeNodeData): TreeContextMenuItem[] {
134
+ return this.contextMenuItems.filter(item => {
135
+ // Show different items based on node type
136
+ if (item.id === 'expand' || item.id === 'collapse') {
137
+ return node.hasChildren || (node.children && node.children.length > 0);
138
+ }
139
+ if (item.id === 'open') {
140
+ return node.type === 'file';
141
+ }
142
+ return true; // Show other items for all nodes
143
+ });
144
+ }
145
+
146
+ /**
147
+ * Get context menu for multiple selected nodes
148
+ */
149
+ getMultiNodeContextMenu(nodes: TreeNodeData[]): TreeContextMenuItem[] {
150
+ return this.contextMenuItems.filter(item => {
151
+ // Only show actions that work on multiple items
152
+ return ['delete', 'copy', 'cut', 'properties'].includes(item.id);
153
+ });
154
+ }
155
+
156
+ /**
157
+ * Get selection theme configuration
158
+ */
159
+ getSelectionTheme(): TreeSelectionTheme {
160
+ return this.selectionTheme;
161
+ }
162
+
163
+ /**
164
+ * Update the static data
165
+ */
166
+ setData(data: TreeNodeData[]): void {
167
+ this.nodes = data;
168
+ }
169
+
170
+ /**
171
+ * Get current data
172
+ */
173
+ getData(): TreeNodeData[] {
174
+ return this.nodes;
175
+ }
176
+
177
+ /**
178
+ * Add a new node to the tree
179
+ */
180
+ addNode(parentPath: string | null, newNode: TreeNodeData): boolean {
181
+ if (parentPath === null) {
182
+ // Add to root
183
+ this.nodes.push(newNode);
184
+ return true;
185
+ }
186
+
187
+ // Find parent and add to its children
188
+ const parent = this.findNodeByPath(parentPath);
189
+ if (parent) {
190
+ if (!parent.children) {
191
+ parent.children = [];
192
+ }
193
+ parent.children.push(newNode);
194
+ parent.hasChildren = true;
195
+ return true;
196
+ }
197
+
198
+ return false;
199
+ }
200
+
201
+ /**
202
+ * Remove a node from the tree
203
+ */
204
+ removeNode(nodePath: string): boolean {
205
+ // Try to remove from root level
206
+ const rootIndex = this.nodes.findIndex(node => node.path === nodePath);
207
+ if (rootIndex >= 0) {
208
+ this.nodes.splice(rootIndex, 1);
209
+ return true;
210
+ }
211
+
212
+ // Find and remove from children
213
+ return this.removeNodeFromChildren(this.nodes, nodePath);
214
+ }
215
+
216
+ /**
217
+ * Find a node by its path
218
+ */
219
+ findNodeByPath(path: string): TreeNodeData | null {
220
+ const searchNodes = (nodes: TreeNodeData[]): TreeNodeData | null => {
221
+ for (const node of nodes) {
222
+ if (node.path === path) {
223
+ return node;
224
+ }
225
+ if (node.children) {
226
+ const found = searchNodes(node.children);
227
+ if (found) return found;
228
+ }
229
+ }
230
+ return null;
231
+ };
232
+
233
+ return searchNodes(this.nodes);
234
+ }
235
+
236
+ /**
237
+ * Create default sample data
238
+ */
239
+ private createDefaultData(): TreeNodeData[] {
240
+ return [
241
+ {
242
+ id: 'documents',
243
+ name: 'Documents',
244
+ path: '/documents',
245
+ type: 'directory',
246
+ hasChildren: true,
247
+ children: [
248
+ {
249
+ id: 'reports',
250
+ name: 'Reports',
251
+ path: '/documents/reports',
252
+ type: 'directory',
253
+ hasChildren: true,
254
+ children: [
255
+ {
256
+ id: 'quarterly-report',
257
+ name: 'Quarterly Report.pdf',
258
+ path: '/documents/reports/quarterly-report.pdf',
259
+ type: 'file',
260
+ size: 1024000,
261
+ lastModified: new Date('2024-01-15')
262
+ },
263
+ {
264
+ id: 'annual-report',
265
+ name: 'Annual Report.pdf',
266
+ path: '/documents/reports/annual-report.pdf',
267
+ type: 'file',
268
+ size: 2048000,
269
+ lastModified: new Date('2024-01-10')
270
+ }
271
+ ]
272
+ },
273
+ {
274
+ id: 'presentations',
275
+ name: 'Presentations',
276
+ path: '/documents/presentations',
277
+ type: 'directory',
278
+ hasChildren: true,
279
+ children: [
280
+ {
281
+ id: 'product-demo',
282
+ name: 'Product Demo.pptx',
283
+ path: '/documents/presentations/product-demo.pptx',
284
+ type: 'file',
285
+ size: 5120000,
286
+ lastModified: new Date('2024-01-20')
287
+ }
288
+ ]
289
+ },
290
+ {
291
+ id: 'readme',
292
+ name: 'README.md',
293
+ path: '/documents/readme.md',
294
+ type: 'file',
295
+ size: 2048,
296
+ lastModified: new Date('2024-01-25')
297
+ }
298
+ ]
299
+ },
300
+ {
301
+ id: 'projects',
302
+ name: 'Projects',
303
+ path: '/projects',
304
+ type: 'directory',
305
+ hasChildren: true,
306
+ children: [
307
+ {
308
+ id: 'web-app',
309
+ name: 'Web Application',
310
+ path: '/projects/web-app',
311
+ type: 'directory',
312
+ hasChildren: true,
313
+ children: [
314
+ {
315
+ id: 'src',
316
+ name: 'src',
317
+ path: '/projects/web-app/src',
318
+ type: 'directory',
319
+ hasChildren: true,
320
+ children: [
321
+ {
322
+ id: 'app-ts',
323
+ name: 'app.ts',
324
+ path: '/projects/web-app/src/app.ts',
325
+ type: 'file',
326
+ size: 4096,
327
+ lastModified: new Date('2024-01-24')
328
+ },
329
+ {
330
+ id: 'components',
331
+ name: 'components',
332
+ path: '/projects/web-app/src/components',
333
+ type: 'directory',
334
+ hasChildren: false,
335
+ children: []
336
+ }
337
+ ]
338
+ },
339
+ {
340
+ id: 'package-json',
341
+ name: 'package.json',
342
+ path: '/projects/web-app/package.json',
343
+ type: 'file',
344
+ size: 1024,
345
+ lastModified: new Date('2024-01-23')
346
+ }
347
+ ]
348
+ }
349
+ ]
350
+ },
351
+ {
352
+ id: 'downloads',
353
+ name: 'Downloads',
354
+ path: '/downloads',
355
+ type: 'directory',
356
+ hasChildren: false,
357
+ children: []
358
+ }
359
+ ];
360
+ }
361
+
362
+ /**
363
+ * Create default context menu items
364
+ */
365
+ private createDefaultContextMenu(): TreeContextMenuItem[] {
366
+ return [
367
+ {
368
+ id: 'open',
369
+ label: 'Open',
370
+ icon: 'file-text',
371
+ handler: (node) => this.onContextMenuAction?.('open', [node])
372
+ },
373
+ {
374
+ id: 'expand',
375
+ label: 'Expand',
376
+ icon: 'chevron-down',
377
+ handler: (node) => this.onContextMenuAction?.('expand', [node])
378
+ },
379
+ {
380
+ id: 'collapse',
381
+ label: 'Collapse',
382
+ icon: 'chevron-right',
383
+ handler: (node) => this.onContextMenuAction?.('collapse', [node])
384
+ },
385
+ {
386
+ id: 'separator-1',
387
+ label: '',
388
+ type: 'separator'
389
+ },
390
+ {
391
+ id: 'copy',
392
+ label: 'Copy',
393
+ icon: 'copy',
394
+ handler: (node) => this.onContextMenuAction?.('copy', [node])
395
+ },
396
+ {
397
+ id: 'cut',
398
+ label: 'Cut',
399
+ icon: 'scissors',
400
+ handler: (node) => this.onContextMenuAction?.('cut', [node])
401
+ },
402
+ {
403
+ id: 'delete',
404
+ label: 'Delete',
405
+ icon: 'trash-2',
406
+ handler: (node) => this.onContextMenuAction?.('delete', [node])
407
+ },
408
+ {
409
+ id: 'separator-2',
410
+ label: '',
411
+ type: 'separator'
412
+ },
413
+ {
414
+ id: 'properties',
415
+ label: 'Properties',
416
+ icon: 'info',
417
+ handler: (node) => this.onContextMenuAction?.('properties', [node])
418
+ }
419
+ ];
420
+ }
421
+
422
+ /**
423
+ * Helper method to remove node from children recursively
424
+ */
425
+ private removeNodeFromChildren(nodes: TreeNodeData[], targetPath: string): boolean {
426
+ for (const node of nodes) {
427
+ if (node.children) {
428
+ const childIndex = node.children.findIndex(child => child.path === targetPath);
429
+ if (childIndex >= 0) {
430
+ node.children.splice(childIndex, 1);
431
+ node.hasChildren = node.children.length > 0;
432
+ return true;
433
+ }
434
+
435
+ if (this.removeNodeFromChildren(node.children, targetPath)) {
436
+ return true;
437
+ }
438
+ }
439
+ }
440
+ return false;
441
+ }
442
+
443
+ /**
444
+ * Update selection theme reactively
445
+ */
446
+ updateSelectionTheme = (theme: Partial<TreeSelectionTheme>) => {
447
+ this.selectionTheme = { ...this.selectionTheme, ...theme };
448
+ };
449
+
450
+ /**
451
+ * Update multi-select setting
452
+ */
453
+ setMultiSelectEnabled = (enabled: boolean) => {
454
+ this.isMultiSelectEnabled = enabled;
455
+ };
456
+
457
+ /**
458
+ * Update checkbox selection setting
459
+ */
460
+ setCheckboxSelection = (enabled: boolean) => {
461
+ this.useCheckboxSelection = enabled;
462
+ };
463
+ }