@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,307 @@
1
+ # ExplorerLayout Component
2
+
3
+ A fully-typed, responsive layout component designed for editor-style interfaces like file browsers, code editors, and similar applications.
4
+
5
+ ## Features
6
+
7
+ - **Fully Responsive**: Automatically adapts to different screen sizes with configurable breakpoints
8
+ - **Flexible Configuration**: Config-object API for easy customization of all sections
9
+ - **Smooth Transitions**: CSS transitions for sidebar width changes and responsive behavior
10
+ - **Mobile-First**: Mobile overlay behavior with hamburger toggle on small screens
11
+ - **TypeScript**: Fully typed with comprehensive type definitions
12
+ - **Tailwind Integration**: Uses Tailwind CSS classes with conditional styling
13
+
14
+ ## API
15
+
16
+ ### `ExplorerSections` Configuration Object
17
+
18
+ ```typescript
19
+ interface ExplorerSections {
20
+ header?: ReactNode;
21
+ footer?: ReactNode;
22
+ sidebar?: {
23
+ content: ReactNode;
24
+ toolbar?: ReactNode;
25
+ width?: number; // px, default 224
26
+ };
27
+ main: {
28
+ content: ReactNode;
29
+ toolbar?: ReactNode;
30
+ };
31
+ responsive?: {
32
+ breakpoint?: number; // px, default 768
33
+ sidebarCollapsed?: boolean;
34
+ };
35
+ }
36
+ ```
37
+
38
+ ### `ExplorerLayoutProps`
39
+
40
+ ```typescript
41
+ interface ExplorerLayoutProps {
42
+ sections: ExplorerSections;
43
+ className?: string;
44
+ }
45
+ ```
46
+
47
+ ## Layout Structure
48
+
49
+ ```
50
+ ┌─────────────────────────────────────┐
51
+ │ Header │ (optional)
52
+ ├──────────┬──────────────────────────┤
53
+ │ │ Main Toolbar │ (optional)
54
+ │ Sidebar ├──────────────────────────┤
55
+ │ Toolbar │ │
56
+ ├──────────┤ Main Content │ (required)
57
+ │ │ │
58
+ │ Sidebar │ │
59
+ │ Content │ │
60
+ │ │ │
61
+ ├──────────┴──────────────────────────┤
62
+ │ Footer │ (optional)
63
+ └─────────────────────────────────────┘
64
+ ```
65
+
66
+ ## Responsive Behavior
67
+
68
+ - **Desktop (≥ breakpoint)**: Two-column layout with fixed sidebar
69
+ - **Mobile (< breakpoint)**: Single column with overlay sidebar
70
+ - **Mobile Toggle**: ☰ button appears in top-left corner for sidebar toggle
71
+ - **Backdrop**: Click outside sidebar to close on mobile
72
+
73
+ ## Basic Usage
74
+
75
+ ```tsx
76
+ import { ExplorerLayout, type ExplorerSections } from '@anymux/fs-ui';
77
+ import { useState } from 'react';
78
+
79
+ const sections: ExplorerSections = {
80
+ header: <div className="p-4">My App Header</div>,
81
+ sidebar: {
82
+ content: <div className="p-4">Navigation content</div>,
83
+ toolbar: <div className="p-2">Sidebar toolbar</div>,
84
+ width: 280,
85
+ },
86
+ main: {
87
+ content: <div className="p-4">Main content area</div>,
88
+ toolbar: <div className="p-2">Main toolbar</div>,
89
+ },
90
+ footer: <div className="p-2">Status bar</div>,
91
+ };
92
+
93
+ // With internal collapse state (automatic)
94
+ export const MyApp = () => (
95
+ <div className="h-screen">
96
+ <ExplorerLayout sections={sections} />
97
+ </div>
98
+ );
99
+
100
+ // With external collapse state (controlled)
101
+ export const MyControlledApp = () => {
102
+ const [collapsed, setCollapsed] = useState(false);
103
+
104
+ return (
105
+ <div className="h-screen">
106
+ <ExplorerLayout
107
+ sections={sections}
108
+ isSidebarCollapsed={collapsed}
109
+ setSidebarCollapsed={setCollapsed}
110
+ />
111
+ </div>
112
+ );
113
+ };
114
+ ```
115
+
116
+ ## Advanced Examples
117
+
118
+ ### Code Editor Layout
119
+
120
+ ```tsx
121
+ const editorSections: ExplorerSections = {
122
+ header: (
123
+ <div className="p-4 flex items-center justify-between border-b">
124
+ <h1 className="text-lg font-semibold">Code Editor</h1>
125
+ <div className="flex gap-2">
126
+ <Button size="sm">File</Button>
127
+ <Button size="sm">Edit</Button>
128
+ <Button size="sm">View</Button>
129
+ </div>
130
+ </div>
131
+ ),
132
+ sidebar: {
133
+ content: <FileExplorer />,
134
+ toolbar: (
135
+ <div className="p-2 flex items-center justify-between">
136
+ <span className="text-sm font-medium">Explorer</span>
137
+ <Button variant="ghost" size="sm">+</Button>
138
+ </div>
139
+ ),
140
+ width: 320,
141
+ },
142
+ main: {
143
+ content: <CodeEditor />,
144
+ toolbar: (
145
+ <div className="p-2 flex items-center justify-between">
146
+ <span className="text-sm">src/App.tsx</span>
147
+ <div className="flex gap-1">
148
+ <Button variant="ghost" size="sm">Save</Button>
149
+ <Button variant="ghost" size="sm">Format</Button>
150
+ </div>
151
+ </div>
152
+ ),
153
+ },
154
+ footer: (
155
+ <div className="p-2 flex items-center justify-between text-xs bg-muted">
156
+ <span>Ln 42, Col 15</span>
157
+ <span>TypeScript • UTF-8</span>
158
+ </div>
159
+ ),
160
+ responsive: {
161
+ breakpoint: 768,
162
+ },
163
+ };
164
+ ```
165
+
166
+ ### Minimal Layout (No Header/Footer)
167
+
168
+ ```tsx
169
+ const minimalSections: ExplorerSections = {
170
+ sidebar: {
171
+ content: <NavigationMenu />,
172
+ width: 240,
173
+ },
174
+ main: {
175
+ content: <MainContent />,
176
+ },
177
+ responsive: {
178
+ breakpoint: 640,
179
+ sidebarCollapsed: false,
180
+ },
181
+ };
182
+ ```
183
+
184
+ ### No Sidebar Layout
185
+
186
+ ```tsx
187
+ const noSidebarSections: ExplorerSections = {
188
+ header: <AppHeader />,
189
+ main: {
190
+ content: <FullWidthContent />,
191
+ toolbar: <ContentToolbar />,
192
+ },
193
+ footer: <AppFooter />,
194
+ };
195
+ ```
196
+
197
+ ## Styling Guidelines
198
+
199
+ ### Full Height Containers
200
+
201
+ Always ensure the parent container has full height:
202
+
203
+ ```tsx
204
+ // ✅ Correct
205
+ <div className="h-screen">
206
+ <ExplorerLayout sections={sections} />
207
+ </div>
208
+
209
+ // ❌ Incorrect - layout won't fill screen
210
+ <div>
211
+ <ExplorerLayout sections={sections} />
212
+ </div>
213
+ ```
214
+
215
+ ### Content Overflow
216
+
217
+ For scrollable content areas, use `overflow-auto` or `overflow-hidden`:
218
+
219
+ ```tsx
220
+ const sections: ExplorerSections = {
221
+ sidebar: {
222
+ content: (
223
+ <div className="h-full overflow-auto p-4">
224
+ {/* Long list of items */}
225
+ </div>
226
+ ),
227
+ },
228
+ main: {
229
+ content: (
230
+ <div className="h-full overflow-auto p-4">
231
+ {/* Scrollable main content */}
232
+ </div>
233
+ ),
234
+ },
235
+ };
236
+ ```
237
+
238
+ ## Configuration Tips
239
+
240
+ ### Responsive Breakpoints
241
+
242
+ Choose breakpoints based on your content:
243
+
244
+ - **Small layouts**: 640px (mobile-first)
245
+ - **Standard layouts**: 768px (tablet breakpoint)
246
+ - **Wide layouts**: 1024px (desktop-first)
247
+
248
+ ### Sidebar Widths
249
+
250
+ Recommended sidebar widths:
251
+
252
+ - **Navigation only**: 200-240px
253
+ - **File explorer**: 280-320px
254
+ - **Tool panels**: 320-400px
255
+ - **Wide content**: 400-500px
256
+
257
+ ### Performance Considerations
258
+
259
+ - Use `React.memo()` for expensive sidebar/main content
260
+ - Implement virtualization for large lists
261
+ - Minimize re-renders by memoizing section configurations
262
+
263
+ ## Testing
264
+
265
+ The component includes a comprehensive demo at:
266
+ `/explorer-layout-samples`
267
+
268
+ Test different:
269
+ - Screen sizes and responsive behavior
270
+ - Section combinations (with/without header, footer, sidebar)
271
+ - Content types and overflow scenarios
272
+ - Mobile overlay functionality
273
+
274
+ ## Migration from FileBrowser
275
+
276
+ If migrating from the FileBrowser component:
277
+
278
+ ```tsx
279
+ // Before (FileBrowser pattern)
280
+ <div className="flex h-full">
281
+ <div className="w-80 border-r">
282
+ <SidebarContent />
283
+ </div>
284
+ <div className="flex-1">
285
+ <MainContent />
286
+ </div>
287
+ </div>
288
+
289
+ // After (ExplorerLayout)
290
+ const sections: ExplorerSections = {
291
+ sidebar: {
292
+ content: <SidebarContent />,
293
+ width: 320,
294
+ },
295
+ main: {
296
+ content: <MainContent />,
297
+ },
298
+ };
299
+
300
+ <ExplorerLayout sections={sections} />
301
+ ```
302
+
303
+ ## Browser Support
304
+
305
+ - Modern browsers with CSS Grid and Flexbox support
306
+ - Mobile browsers with touch events
307
+ - Responsive design works on all screen sizes
@@ -0,0 +1,178 @@
1
+ import React, { ReactNode, useState, useEffect, useCallback } from 'react';
2
+ import { observer } from 'mobx-react-lite';
3
+ import { cn } from '../../../lib/utils';
4
+ import { Button } from '@anymux/ui/components/button';
5
+ import { ChevronLeft, ChevronRight, PanelLeftClose, PanelLeft } from 'lucide-react';
6
+
7
+ export interface ExplorerSections {
8
+ header?: ReactNode;
9
+ footer?: ReactNode;
10
+ sidebar?: {
11
+ content: ReactNode;
12
+ toolbar?: ReactNode;
13
+ width?: number; // px, default 280
14
+ };
15
+ main: {
16
+ content: ReactNode;
17
+ toolbar?: ReactNode;
18
+ };
19
+ }
20
+
21
+ export interface ExplorerLayoutProps {
22
+ sections: ExplorerSections;
23
+ className?: string;
24
+ isSidebarCollapsed?: boolean;
25
+ setSidebarCollapsed?: (collapsed: boolean) => void;
26
+ }
27
+
28
+ const MOBILE_BREAKPOINT = 768;
29
+
30
+ export const ExplorerLayout: React.FC<ExplorerLayoutProps> = observer(({
31
+ sections,
32
+ className,
33
+ isSidebarCollapsed: externalCollapsed,
34
+ setSidebarCollapsed: externalSetCollapsed
35
+ }) => {
36
+ const [internalCollapsed, setInternalCollapsed] = useState(false);
37
+ const [isMobile, setIsMobile] = useState(false);
38
+ const [mobileOpen, setMobileOpen] = useState(false);
39
+
40
+ const isCollapsed = externalCollapsed ?? internalCollapsed;
41
+ const setCollapsed = externalSetCollapsed ?? setInternalCollapsed;
42
+
43
+ const sidebarWidth = sections.sidebar?.width ?? 280;
44
+
45
+ useEffect(() => {
46
+ const checkMobile = () => {
47
+ const mobile = window.innerWidth < MOBILE_BREAKPOINT;
48
+ setIsMobile(mobile);
49
+ if (mobile) {
50
+ setMobileOpen(false);
51
+ }
52
+ };
53
+ checkMobile();
54
+ window.addEventListener('resize', checkMobile);
55
+ return () => window.removeEventListener('resize', checkMobile);
56
+ }, []);
57
+
58
+ const handleOverlayClick = useCallback(() => {
59
+ setMobileOpen(false);
60
+ }, []);
61
+
62
+ const showSidebar = sections.sidebar && (isMobile ? mobileOpen : !isCollapsed);
63
+
64
+ return (
65
+ <div className={cn("flex flex-col h-full w-full bg-background", className)}>
66
+ {/* Header Section */}
67
+ {sections.header && (
68
+ <div className="flex-shrink-0 border-b bg-background">
69
+ {sections.header}
70
+ </div>
71
+ )}
72
+
73
+ {/* Main content - dual panel layout */}
74
+ <div className="flex flex-1 min-h-0 relative">
75
+ {/* Mobile overlay */}
76
+ {isMobile && mobileOpen && (
77
+ <div
78
+ className="absolute inset-0 bg-black/30 z-30"
79
+ onClick={handleOverlayClick}
80
+ />
81
+ )}
82
+
83
+ {/* Left Panel - Sidebar */}
84
+ {sections.sidebar && (isMobile ? mobileOpen : true) && (
85
+ <div
86
+ className={cn(
87
+ "bg-background flex flex-col flex-shrink-0 transition-all duration-200 ease-in-out",
88
+ isMobile
89
+ ? "absolute inset-y-0 left-0 z-40 border-r shadow-lg"
90
+ : cn(
91
+ "border-r relative",
92
+ isCollapsed && "overflow-hidden"
93
+ )
94
+ )}
95
+ style={{
96
+ width: isMobile
97
+ ? Math.min(sidebarWidth, 300)
98
+ : (isCollapsed ? 0 : sidebarWidth)
99
+ }}
100
+ >
101
+ {/* Sidebar Toolbar */}
102
+ {!isCollapsed && (
103
+ <div className="px-2 border-b bg-muted/10 flex-shrink-0 flex items-center h-10 gap-1">
104
+ <div className="flex-1 min-w-0">
105
+ {sections.sidebar.toolbar}
106
+ </div>
107
+ <Button
108
+ variant="ghost"
109
+ size="icon"
110
+ className="h-6 w-6 flex-shrink-0"
111
+ onClick={() => {
112
+ if (isMobile) {
113
+ setMobileOpen(false);
114
+ } else {
115
+ setCollapsed(true);
116
+ }
117
+ }}
118
+ title="Collapse sidebar"
119
+ >
120
+ <PanelLeftClose className="h-4 w-4" />
121
+ </Button>
122
+ </div>
123
+ )}
124
+
125
+ {/* Sidebar Content */}
126
+ <div className="flex-1 min-h-0 overflow-auto">
127
+ {sections.sidebar.content}
128
+ </div>
129
+ </div>
130
+ )}
131
+
132
+ {/* Right Panel - Main Content */}
133
+ <div className="flex-1 flex flex-col min-w-0">
134
+ {/* Main Toolbar */}
135
+ {sections.main.toolbar && (
136
+ <div className="px-2 border-b bg-muted/10 flex items-center justify-between flex-shrink-0 h-10">
137
+ <div className="flex items-center gap-2 flex-1 min-w-0">
138
+ {/* Mobile sidebar toggle + collapsed sidebar toggle */}
139
+ {sections.sidebar && (isMobile || isCollapsed) && !(isMobile && mobileOpen) && (
140
+ <Button
141
+ variant="ghost"
142
+ size="icon"
143
+ className="h-6 w-6 flex-shrink-0"
144
+ onClick={() => {
145
+ if (isMobile) {
146
+ setMobileOpen(true);
147
+ } else {
148
+ setCollapsed(false);
149
+ }
150
+ }}
151
+ title="Show sidebar"
152
+ >
153
+ <PanelLeft className="h-4 w-4" />
154
+ </Button>
155
+ )}
156
+ {sections.main.toolbar}
157
+ </div>
158
+ </div>
159
+ )}
160
+
161
+ {/* Main Content */}
162
+ <div className="flex-1 min-h-0 overflow-hidden">
163
+ {sections.main.content}
164
+ </div>
165
+ </div>
166
+ </div>
167
+
168
+ {/* Footer Section */}
169
+ {sections.footer && (
170
+ <div className="flex-shrink-0 border-t bg-background">
171
+ {sections.footer}
172
+ </div>
173
+ )}
174
+ </div>
175
+ );
176
+ });
177
+
178
+ ExplorerLayout.displayName = 'ExplorerLayout';
@@ -0,0 +1,60 @@
1
+ import React from 'react';
2
+ import { ExplorerLayout, type ExplorerSections } from '../';
3
+ import { Button } from '@anymux/ui/components/button';
4
+
5
+ // AICODE-NOTE: Minimal example showing ExplorerLayout basic usage
6
+ export const SimpleExample: React.FC = () => {
7
+ const sections: ExplorerSections = {
8
+ header: (
9
+ <div className="p-4 flex items-center justify-between border-b">
10
+ <h1 className="text-lg font-semibold">My App</h1>
11
+ <Button variant="outline" size="sm">Settings</Button>
12
+ </div>
13
+ ),
14
+ sidebar: {
15
+ content: (
16
+ <div className="p-4">
17
+ <h3 className="font-medium mb-2">Navigation</h3>
18
+ <div className="space-y-1">
19
+ <div className="p-2 rounded hover:bg-muted cursor-pointer">📁 Files</div>
20
+ <div className="p-2 rounded hover:bg-muted cursor-pointer">🔍 Search</div>
21
+ <div className="p-2 rounded hover:bg-muted cursor-pointer">⚙️ Settings</div>
22
+ </div>
23
+ </div>
24
+ ),
25
+ toolbar: (
26
+ <div className="p-2 border-b">
27
+ <span className="text-sm font-medium">Explorer</span>
28
+ </div>
29
+ ),
30
+ width: 240,
31
+ },
32
+ main: {
33
+ content: (
34
+ <div className="p-8 text-center">
35
+ <h2 className="text-xl font-semibold mb-4">Welcome to ExplorerLayout</h2>
36
+ <p className="text-muted-foreground">
37
+ This is the main content area. It automatically adapts to different screen sizes.
38
+ </p>
39
+ </div>
40
+ ),
41
+ toolbar: (
42
+ <div className="p-2 border-b flex items-center justify-between">
43
+ <span className="text-sm font-medium">Main Content</span>
44
+ <Button variant="ghost" size="sm">Action</Button>
45
+ </div>
46
+ ),
47
+ },
48
+ footer: (
49
+ <div className="p-2 border-t text-center text-sm text-muted-foreground">
50
+ Ready
51
+ </div>
52
+ ),
53
+ };
54
+
55
+ return (
56
+ <div className="h-screen w-screen">
57
+ <ExplorerLayout sections={sections} />
58
+ </div>
59
+ );
60
+ };
@@ -0,0 +1,6 @@
1
+ // AICODE-NOTE: Main exports for EditorLayout module
2
+ export { ExplorerLayout } from './components/ExplorerLayout/ExplorerLayout';
3
+ export type { ExplorerLayoutProps, ExplorerSections } from './components/ExplorerLayout/ExplorerLayout';
4
+
5
+ // Examples
6
+ export { SimpleExample as ExplorerLayoutSimpleExample } from './examples/SimpleExample';
@@ -0,0 +1 @@
1
+ export { cn } from '@anymux/ui/lib/utils';