@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,11 @@
1
+ import "./types-common-CB3kRek8.js";
2
+ import "./index-DSu19mq0.js";
3
+ import "./index-DmsyeHFr.js";
4
+ import { ActionContext, ActionResult, BreadcrumbProps, ColumnDefinition, ContextAction, ErrorBoundary$1 as ErrorBoundary, ErrorBoundaryProps, ErrorState, FileBrowser$1 as FileBrowser, FileBrowserContent, FileBrowserContentProps, FileBrowserEventHandlers, FileBrowserHeader, FileBrowserHeaderProps, FileBrowserItem, FileBrowserItemComponent, FileBrowserItemDetails, FileBrowserModel$1 as FileBrowserModel, FileBrowserProps, FileIcon, FileIconProps, FileMatchContext, FileSystemBridge$1 as FileSystemBridge, FileSystemListProvider$1 as FileSystemListProvider, FileSystemProvider$1 as FileSystemProvider, FileSystemTreeProvider$1 as FileSystemTreeProvider, FileViewerPlugin, FilterCriteria, FilterDefinition, GitProvider$1 as GitProvider, GitRepositoryProvider$1 as GitRepositoryProvider, IFileBrowserProvider, IconDefinition, ItemChange, KeyboardShortcut, ListView, ListViewProps, ListViewSettings, ListViewUIModel$1 as ListViewUIModel, LoadingState, NavigationButtons, NavigationButtonsProps, NavigationManagerModel$1 as NavigationManagerModel, NavigationState, PreviewData, ProviderCapabilities, ProviderConfiguration, ResolvedViewer, SelectionManagerModel$1 as SelectionManagerModel, SelectionState, SortCriteria, SortFieldDefinition, ThumbnailViewSettings, ThumbnailViewUIModel$1 as ThumbnailViewUIModel, ToolbarAction, ToolbarActionConfig, ToolbarManagerModel$1 as ToolbarManagerModel, TreeView, TreeViewProps, TreeViewSettings, TreeViewUIModel$1 as TreeViewUIModel, UIComponentProps, UploadFileEntry, UploadModel$1 as UploadModel, ViewModeCapabilities, ViewModeDefinition, ViewModeManagerModel$1 as ViewModeManagerModel, ViewModeSettings, ViewModeToggle, ViewModeToggleProps, ViewerConfig, ViewerHost$1 as ViewerHost, ViewerHostModel$1 as ViewerHostModel, ViewerHostProps, ViewerProps, ViewerRegistry$1 as ViewerRegistry, cn, globalViewerRegistry$1 as globalViewerRegistry, viewerConfigToPlugin$1 as viewerConfigToPlugin } from "./index-Ml_SgiKa.js";
5
+ import "./index-kHr9udZD.js";
6
+ import "./index-Bryv_GCG.js";
7
+ import "./index-BNmNIWBL.js";
8
+ import "./index-DzfY1Tok.js";
9
+ import "./index-CuQIjSXs.js";
10
+ import "./index-DxnJ8FYM.js";
11
+ export { ActionContext, ActionResult, BreadcrumbProps, ColumnDefinition, ContextAction, ErrorBoundary, ErrorBoundaryProps, ErrorState, FileBrowser, FileBrowserContent, FileBrowserContentProps, FileBrowserEventHandlers, FileBrowserHeader, FileBrowserHeaderProps, FileBrowserItem, FileBrowserItemComponent, FileBrowserItemDetails, FileBrowserModel, FileBrowserProps, TreeView as FileBrowserTreeView, TreeViewProps as FileBrowserTreeViewProps, FileIcon, FileIconProps as FileIconUIProps, FileMatchContext, FileSystemBridge, FileSystemListProvider, FileSystemProvider, FileSystemTreeProvider, FileViewerPlugin, FilterCriteria, FilterDefinition, GitProvider, GitRepositoryProvider, IFileBrowserProvider, IconDefinition, ItemChange, KeyboardShortcut, ListView, ListViewProps, ListViewSettings, ListViewUIModel, LoadingState, NavigationButtons, NavigationButtonsProps, NavigationManagerModel, NavigationState, PreviewData, ProviderCapabilities, ProviderConfiguration, ResolvedViewer, SelectionManagerModel, SelectionState, SortCriteria, SortFieldDefinition, ThumbnailViewSettings, ThumbnailViewUIModel, ToolbarAction, ToolbarActionConfig, ToolbarManagerModel, TreeViewSettings, TreeViewUIModel, UIComponentProps, UploadFileEntry, UploadModel, ViewModeCapabilities, ViewModeDefinition, ViewModeManagerModel, ViewModeSettings, ViewModeToggle, ViewModeToggleProps, ViewerConfig, ViewerHost, ViewerHostModel, ViewerHostProps, ViewerProps, ViewerRegistry, cn, globalViewerRegistry, viewerConfigToPlugin };
@@ -0,0 +1,9 @@
1
+ import { cn$1 as cn } from "./utils-B4fdKKsy.js";
2
+ import "./tree-Dd9Z0Aso.js";
3
+ import "./iconMap-V4B8P-Uh.js";
4
+ import "./FileBrowserContext-B6jixa2j.js";
5
+ import "./list-CxfT6hix.js";
6
+ import "./ExplorerLayout-CSIJd7N4.js";
7
+ import { ErrorBoundary, FileBrowser, FileBrowserContent_default, FileBrowserHeader_default, FileBrowserItem_default, FileBrowserModel, FileIcon_default, FileSystemBridge, FileSystemListProvider, FileSystemProvider, FileSystemTreeProvider, GitProvider, GitRepositoryProvider, ListViewUIModel, ListView_default, NavigationButtons_default, NavigationManagerModel, SelectionManagerModel, ThumbnailViewUIModel, ToolbarManagerModel, TreeViewUIModel, TreeView_default, UploadModel, ViewModeManagerModel, ViewModeToggle_default, ViewerHost, ViewerHostModel, ViewerRegistry, globalViewerRegistry, viewerConfigToPlugin } from "./file-browser-m5atC3kF.js";
8
+
9
+ export { ErrorBoundary, FileBrowser, FileBrowserContent_default as FileBrowserContent, FileBrowserHeader_default as FileBrowserHeader, FileBrowserItem_default as FileBrowserItemComponent, FileBrowserModel, TreeView_default as FileBrowserTreeView, FileIcon_default as FileIcon, FileSystemBridge, FileSystemListProvider, FileSystemProvider, FileSystemTreeProvider, GitProvider, GitRepositoryProvider, ListView_default as ListView, ListViewUIModel, NavigationButtons_default as NavigationButtons, NavigationManagerModel, SelectionManagerModel, ThumbnailViewUIModel, ToolbarManagerModel, TreeViewUIModel, UploadModel, ViewModeManagerModel, ViewModeToggle_default as ViewModeToggle, ViewerHost, ViewerHostModel, ViewerRegistry, cn, globalViewerRegistry, viewerConfigToPlugin };
@@ -0,0 +1,561 @@
1
+ import React, { useMemo, useState } from "react";
2
+ import { ArrowRightLeft, Check, ChevronDown, ChevronRight, Clock, FileEdit, FilePlus2, FileText, FileX2, GitBranch, GitCommit, Hash, Minus, Plus, Search, Shield, User } from "lucide-react";
3
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
+
5
+ //#region src/git/CommitGraph.tsx
6
+ const LANE_COLORS = [
7
+ "#3b82f6",
8
+ "#10b981",
9
+ "#f59e0b",
10
+ "#ef4444",
11
+ "#8b5cf6",
12
+ "#06b6d4",
13
+ "#ec4899",
14
+ "#14b8a6",
15
+ "#f97316",
16
+ "#6366f1"
17
+ ];
18
+ function laneColor(index) {
19
+ return LANE_COLORS[index % LANE_COLORS.length];
20
+ }
21
+ function computeGraphLayout(commits) {
22
+ const shaToRow = new Map();
23
+ commits.forEach((c, i) => shaToRow.set(c.sha, i));
24
+ const lanes = [];
25
+ const nodes = [];
26
+ function findLane(sha) {
27
+ const idx = lanes.indexOf(sha);
28
+ return idx >= 0 ? idx : -1;
29
+ }
30
+ function allocateLane(sha) {
31
+ for (let i = 0; i < lanes.length; i++) if (lanes[i] === null) {
32
+ lanes[i] = sha;
33
+ return i;
34
+ }
35
+ lanes.push(sha);
36
+ return lanes.length - 1;
37
+ }
38
+ for (let row = 0; row < commits.length; row++) {
39
+ const commit = commits[row];
40
+ let column = findLane(commit.sha);
41
+ if (column === -1) column = allocateLane(commit.sha);
42
+ lanes[column] = null;
43
+ const connections = [];
44
+ const parents = commit.parents;
45
+ for (let pi = 0; pi < parents.length; pi++) {
46
+ const parentSha = parents[pi];
47
+ const parentRow = shaToRow.get(parentSha) ?? -1;
48
+ let parentLane = findLane(parentSha);
49
+ if (parentLane === -1) if (pi === 0) {
50
+ lanes[column] = parentSha;
51
+ parentLane = column;
52
+ } else parentLane = allocateLane(parentSha);
53
+ connections.push({
54
+ toColumn: parentLane,
55
+ toRow: parentRow,
56
+ colorIndex: parentLane
57
+ });
58
+ }
59
+ nodes.push({
60
+ sha: commit.sha,
61
+ column,
62
+ connections
63
+ });
64
+ }
65
+ return nodes;
66
+ }
67
+ const ROW_HEIGHT = 40;
68
+ const COL_WIDTH = 14;
69
+ const NODE_RADIUS = 4;
70
+ const LEFT_PAD = 8;
71
+ const CommitGraph = ({ nodes, totalRows, headSha, className }) => {
72
+ if (nodes.length === 0) return null;
73
+ const headNode = headSha ? nodes.find((n) => n.sha === headSha) : void 0;
74
+ const headColumn = headNode?.column;
75
+ const maxColumn = Math.max(...nodes.map((n) => {
76
+ const connMax = n.connections.length > 0 ? Math.max(...n.connections.map((c) => c.toColumn)) : 0;
77
+ return Math.max(n.column, connMax);
78
+ }));
79
+ const width = LEFT_PAD + (maxColumn + 1) * COL_WIDTH + NODE_RADIUS + 2;
80
+ function x(col) {
81
+ return LEFT_PAD + col * COL_WIDTH + COL_WIDTH / 2;
82
+ }
83
+ function y(row) {
84
+ return row * ROW_HEIGHT + ROW_HEIGHT / 2;
85
+ }
86
+ return /* @__PURE__ */ jsxs("svg", {
87
+ className,
88
+ width,
89
+ height: totalRows * ROW_HEIGHT,
90
+ style: {
91
+ position: "absolute",
92
+ left: 0,
93
+ top: 0,
94
+ pointerEvents: "none"
95
+ },
96
+ children: [nodes.map((node, row) => node.connections.map((conn, ci) => {
97
+ const x1 = x(node.column);
98
+ const y1 = y(row);
99
+ const x2 = x(conn.toColumn);
100
+ const y2 = conn.toRow >= 0 ? y(conn.toRow) : totalRows * ROW_HEIGHT;
101
+ const color = laneColor(conn.colorIndex);
102
+ const isHeadLane = headColumn !== void 0 && node.column === headColumn && conn.toColumn === headColumn;
103
+ const sw = isHeadLane ? 2.5 : 2;
104
+ if (x1 === x2) return /* @__PURE__ */ jsx("line", {
105
+ x1,
106
+ y1,
107
+ x2,
108
+ y2,
109
+ stroke: color,
110
+ strokeWidth: sw,
111
+ strokeLinecap: "round",
112
+ opacity: headColumn !== void 0 && !isHeadLane ? .5 : 1
113
+ }, `${node.sha}-${ci}`);
114
+ const midY = y1 + ROW_HEIGHT * .6;
115
+ return /* @__PURE__ */ jsx("path", {
116
+ d: `M ${x1} ${y1} C ${x1} ${midY}, ${x2} ${midY}, ${x2} ${y2}`,
117
+ stroke: color,
118
+ strokeWidth: sw,
119
+ fill: "none",
120
+ strokeLinecap: "round",
121
+ opacity: headColumn !== void 0 && !isHeadLane ? .5 : 1
122
+ }, `${node.sha}-${ci}`);
123
+ })), nodes.map((node, row) => {
124
+ const isHead = node.sha === headSha;
125
+ const isOnHeadLane = headColumn !== void 0 && node.column === headColumn;
126
+ const dimmed = headColumn !== void 0 && !isOnHeadLane;
127
+ return /* @__PURE__ */ jsx("circle", {
128
+ cx: x(node.column),
129
+ cy: y(row),
130
+ r: isHead ? NODE_RADIUS + 1.5 : NODE_RADIUS,
131
+ fill: laneColor(node.column),
132
+ stroke: isHead ? laneColor(node.column) : "white",
133
+ strokeWidth: isHead ? 2.5 : 1.5,
134
+ opacity: dimmed ? .5 : 1
135
+ }, node.sha);
136
+ })]
137
+ });
138
+ };
139
+ /** Compute the width the graph will take, for adding left padding to commit rows */
140
+ function graphWidth(nodes) {
141
+ if (nodes.length === 0) return 0;
142
+ const maxColumn = Math.max(...nodes.map((n) => {
143
+ const connMax = n.connections.length > 0 ? Math.max(...n.connections.map((c) => c.toColumn)) : 0;
144
+ return Math.max(n.column, connMax);
145
+ }));
146
+ return LEFT_PAD + (maxColumn + 1) * COL_WIDTH + NODE_RADIUS + 2;
147
+ }
148
+
149
+ //#endregion
150
+ //#region src/git/CommitList.tsx
151
+ function formatRelativeTime(date) {
152
+ const now = Date.now();
153
+ const diffMs = now - new Date(date).getTime();
154
+ const seconds = Math.floor(diffMs / 1e3);
155
+ const minutes = Math.floor(seconds / 60);
156
+ const hours = Math.floor(minutes / 60);
157
+ const days = Math.floor(hours / 24);
158
+ const weeks = Math.floor(days / 7);
159
+ const months = Math.floor(days / 30);
160
+ if (seconds < 60) return "just now";
161
+ if (minutes < 60) return `${minutes}m ago`;
162
+ if (hours < 24) return `${hours}h ago`;
163
+ if (days < 7) return `${days}d ago`;
164
+ if (weeks < 5) return `${weeks}w ago`;
165
+ if (months < 12) return `${months}mo ago`;
166
+ return new Date(date).toLocaleDateString();
167
+ }
168
+ function shortSha(sha) {
169
+ return sha.slice(0, 7);
170
+ }
171
+ function firstLine(message) {
172
+ return message.split("\n")[0] ?? message;
173
+ }
174
+ function authorInitials(name) {
175
+ const parts = name.split(/\s+/);
176
+ if (parts.length >= 2) return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
177
+ return name.slice(0, 2).toUpperCase();
178
+ }
179
+ /** Deterministic color from a string (for avatar backgrounds). */
180
+ function authorColor(name) {
181
+ let hash = 0;
182
+ for (let i = 0; i < name.length; i++) hash = name.charCodeAt(i) + ((hash << 5) - hash);
183
+ const colors = [
184
+ "bg-blue-500",
185
+ "bg-emerald-500",
186
+ "bg-violet-500",
187
+ "bg-amber-500",
188
+ "bg-rose-500",
189
+ "bg-cyan-500",
190
+ "bg-pink-500",
191
+ "bg-teal-500"
192
+ ];
193
+ return colors[Math.abs(hash) % colors.length];
194
+ }
195
+ function CommitRow({ commit, isHead, changedFileCount, isSelected, onSelect }) {
196
+ const [expanded, setExpanded] = useState(false);
197
+ const message = firstLine(commit.message);
198
+ const hasFullBody = commit.message.includes("\n");
199
+ return /* @__PURE__ */ jsxs("div", {
200
+ className: `group border-b border-gray-100 dark:border-gray-800 transition-colors ${isSelected ? "bg-blue-50 dark:bg-blue-900/20" : "hover:bg-gray-50 dark:hover:bg-gray-800/50"}`,
201
+ children: [/* @__PURE__ */ jsxs("button", {
202
+ onClick: onSelect,
203
+ className: "flex items-center gap-2.5 w-full px-3 py-2 text-left",
204
+ children: [
205
+ /* @__PURE__ */ jsx("button", {
206
+ onClick: (e) => {
207
+ e.stopPropagation();
208
+ setExpanded(!expanded);
209
+ },
210
+ className: "w-4 h-4 flex items-center justify-center text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 flex-shrink-0",
211
+ children: expanded ? /* @__PURE__ */ jsx(ChevronDown, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "h-3 w-3" })
212
+ }),
213
+ /* @__PURE__ */ jsx("div", {
214
+ className: `w-6 h-6 rounded-full flex items-center justify-center text-[9px] font-bold text-white flex-shrink-0 ${authorColor(commit.author.name)}`,
215
+ children: authorInitials(commit.author.name)
216
+ }),
217
+ /* @__PURE__ */ jsxs("div", {
218
+ className: "flex-1 min-w-0",
219
+ children: [/* @__PURE__ */ jsxs("div", {
220
+ className: "flex items-center gap-2",
221
+ children: [/* @__PURE__ */ jsx("span", {
222
+ className: "text-xs font-medium truncate",
223
+ children: message
224
+ }), isHead && /* @__PURE__ */ jsx("span", {
225
+ className: "px-1.5 py-0.5 text-[9px] font-bold bg-yellow-100 text-yellow-800 dark:bg-yellow-900/40 dark:text-yellow-300 rounded flex-shrink-0",
226
+ children: "HEAD"
227
+ })]
228
+ }), /* @__PURE__ */ jsxs("div", {
229
+ className: "flex items-center gap-2 mt-0.5",
230
+ children: [/* @__PURE__ */ jsx("span", {
231
+ className: "text-[10px] text-gray-500 dark:text-gray-400",
232
+ children: commit.author.name
233
+ }), /* @__PURE__ */ jsx("span", {
234
+ className: "text-[10px] text-gray-400 dark:text-gray-500",
235
+ children: formatRelativeTime(commit.author.date)
236
+ })]
237
+ })]
238
+ }),
239
+ /* @__PURE__ */ jsx("code", {
240
+ className: "text-[10px] font-mono text-gray-400 dark:text-gray-500 bg-gray-100 dark:bg-gray-800 px-1.5 py-0.5 rounded flex-shrink-0",
241
+ children: shortSha(commit.sha)
242
+ })
243
+ ]
244
+ }), expanded && /* @__PURE__ */ jsxs("div", {
245
+ className: "px-3 pb-3 pl-[52px] space-y-2",
246
+ children: [hasFullBody && /* @__PURE__ */ jsx("div", {
247
+ className: "text-xs text-gray-600 dark:text-gray-300 whitespace-pre-wrap bg-gray-50 dark:bg-gray-800/50 rounded p-2 border border-gray-100 dark:border-gray-700",
248
+ children: commit.message
249
+ }), /* @__PURE__ */ jsxs("div", {
250
+ className: "flex flex-wrap gap-x-4 gap-y-1 text-[10px] text-gray-500 dark:text-gray-400",
251
+ children: [
252
+ /* @__PURE__ */ jsxs("div", {
253
+ className: "flex items-center gap-1",
254
+ children: [
255
+ /* @__PURE__ */ jsx(User, { className: "h-3 w-3" }),
256
+ /* @__PURE__ */ jsx("span", { children: commit.author.name }),
257
+ /* @__PURE__ */ jsxs("span", {
258
+ className: "text-gray-400 dark:text-gray-500",
259
+ children: [
260
+ "<",
261
+ commit.author.email,
262
+ ">"
263
+ ]
264
+ })
265
+ ]
266
+ }),
267
+ /* @__PURE__ */ jsxs("div", {
268
+ className: "flex items-center gap-1",
269
+ children: [/* @__PURE__ */ jsx(Clock, { className: "h-3 w-3" }), /* @__PURE__ */ jsx("span", { children: new Date(commit.author.date).toLocaleString() })]
270
+ }),
271
+ /* @__PURE__ */ jsxs("div", {
272
+ className: "flex items-center gap-1",
273
+ children: [/* @__PURE__ */ jsx(Hash, { className: "h-3 w-3" }), /* @__PURE__ */ jsx("code", {
274
+ className: "font-mono",
275
+ children: commit.sha
276
+ })]
277
+ }),
278
+ commit.parents.length > 0 && /* @__PURE__ */ jsxs("div", {
279
+ className: "flex items-center gap-1",
280
+ children: [/* @__PURE__ */ jsx(GitCommit, { className: "h-3 w-3" }), /* @__PURE__ */ jsxs("span", { children: [
281
+ commit.parents.length === 1 ? "Parent" : "Parents",
282
+ ":",
283
+ " ",
284
+ commit.parents.map((p) => shortSha(p)).join(", ")
285
+ ] })]
286
+ }),
287
+ changedFileCount !== void 0 && /* @__PURE__ */ jsxs("div", {
288
+ className: "flex items-center gap-1",
289
+ children: [/* @__PURE__ */ jsx(FileText, { className: "h-3 w-3" }), /* @__PURE__ */ jsxs("span", { children: [
290
+ changedFileCount,
291
+ " file",
292
+ changedFileCount !== 1 ? "s" : "",
293
+ " changed"
294
+ ] })]
295
+ })
296
+ ]
297
+ })]
298
+ })]
299
+ });
300
+ }
301
+ const CommitList = ({ commits, headSha, changedFileCounts, onSelectCommit, selectedSha, showGraph = true, className }) => {
302
+ const graphNodes = useMemo(() => showGraph ? computeGraphLayout(commits) : [], [commits, showGraph]);
303
+ const gWidth = showGraph ? graphWidth(graphNodes) : 0;
304
+ if (commits.length === 0) return /* @__PURE__ */ jsx("div", {
305
+ className: `flex items-center justify-center py-8 text-xs text-gray-400 ${className ?? ""}`,
306
+ children: "No commits found"
307
+ });
308
+ return /* @__PURE__ */ jsx("div", {
309
+ className: `overflow-auto ${className ?? ""}`,
310
+ children: /* @__PURE__ */ jsxs("div", {
311
+ className: "relative",
312
+ style: { minWidth: gWidth + 200 },
313
+ children: [showGraph && graphNodes.length > 0 && /* @__PURE__ */ jsx(CommitGraph, {
314
+ nodes: graphNodes,
315
+ totalRows: commits.length,
316
+ headSha
317
+ }), /* @__PURE__ */ jsx("div", {
318
+ style: { paddingLeft: gWidth },
319
+ children: commits.map((commit) => /* @__PURE__ */ jsx(CommitRow, {
320
+ commit,
321
+ isHead: commit.sha === headSha,
322
+ changedFileCount: changedFileCounts?.[commit.sha],
323
+ isSelected: commit.sha === selectedSha,
324
+ onSelect: () => onSelectCommit?.(commit)
325
+ }, commit.sha))
326
+ })]
327
+ })
328
+ });
329
+ };
330
+
331
+ //#endregion
332
+ //#region src/git/DiffViewer.tsx
333
+ function statusIcon(status) {
334
+ switch (status) {
335
+ case "added": return /* @__PURE__ */ jsx(FilePlus2, { className: "h-3.5 w-3.5 text-green-500" });
336
+ case "deleted": return /* @__PURE__ */ jsx(FileX2, { className: "h-3.5 w-3.5 text-red-500" });
337
+ case "modified": return /* @__PURE__ */ jsx(FileEdit, { className: "h-3.5 w-3.5 text-yellow-500" });
338
+ case "renamed": return /* @__PURE__ */ jsx(ArrowRightLeft, { className: "h-3.5 w-3.5 text-blue-500" });
339
+ }
340
+ }
341
+ function statusLabel(status) {
342
+ switch (status) {
343
+ case "added": return "Added";
344
+ case "deleted": return "Deleted";
345
+ case "modified": return "Modified";
346
+ case "renamed": return "Renamed";
347
+ }
348
+ }
349
+ function statusBadgeClass(status) {
350
+ switch (status) {
351
+ case "added": return "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400";
352
+ case "deleted": return "bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400";
353
+ case "modified": return "bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400";
354
+ case "renamed": return "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400";
355
+ }
356
+ }
357
+ function parsePatch(patch) {
358
+ const lines = patch.split("\n");
359
+ return lines.map((line) => {
360
+ if (line.startsWith("@@")) return {
361
+ type: "header",
362
+ content: line
363
+ };
364
+ else if (line.startsWith("+")) return {
365
+ type: "addition",
366
+ content: line
367
+ };
368
+ else if (line.startsWith("-")) return {
369
+ type: "deletion",
370
+ content: line
371
+ };
372
+ return {
373
+ type: "context",
374
+ content: line
375
+ };
376
+ });
377
+ }
378
+ function lineClassName(type) {
379
+ switch (type) {
380
+ case "addition": return "bg-green-50 dark:bg-green-900/20 text-green-800 dark:text-green-300";
381
+ case "deletion": return "bg-red-50 dark:bg-red-900/20 text-red-800 dark:text-red-300";
382
+ case "header": return "bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400 font-medium";
383
+ default: return "text-gray-700 dark:text-gray-300";
384
+ }
385
+ }
386
+ function FileDiffSection({ entry, defaultExpanded = false }) {
387
+ const [expanded, setExpanded] = useState(defaultExpanded);
388
+ const patchLines = entry.patch ? parsePatch(entry.patch) : [];
389
+ return /* @__PURE__ */ jsxs("div", {
390
+ className: "border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden",
391
+ children: [/* @__PURE__ */ jsxs("button", {
392
+ onClick: () => setExpanded(!expanded),
393
+ className: "flex items-center gap-2 w-full px-3 py-2 bg-gray-50 dark:bg-gray-800 hover:bg-gray-100 dark:hover:bg-gray-700/50 transition-colors text-left",
394
+ children: [
395
+ /* @__PURE__ */ jsx("span", {
396
+ className: "flex-shrink-0 text-gray-400",
397
+ children: expanded ? /* @__PURE__ */ jsx(ChevronDown, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "h-3.5 w-3.5" })
398
+ }),
399
+ statusIcon(entry.status),
400
+ /* @__PURE__ */ jsx("span", {
401
+ className: "text-xs font-mono truncate flex-1",
402
+ children: entry.previousPath && entry.status === "renamed" ? /* @__PURE__ */ jsxs(Fragment, { children: [
403
+ /* @__PURE__ */ jsx("span", {
404
+ className: "text-gray-400",
405
+ children: entry.previousPath
406
+ }),
407
+ /* @__PURE__ */ jsx("span", {
408
+ className: "text-gray-500 mx-1",
409
+ children: "→"
410
+ }),
411
+ /* @__PURE__ */ jsx("span", { children: entry.path })
412
+ ] }) : entry.path
413
+ }),
414
+ /* @__PURE__ */ jsx("span", {
415
+ className: `px-1.5 py-0.5 text-[9px] font-medium rounded flex-shrink-0 ${statusBadgeClass(entry.status)}`,
416
+ children: statusLabel(entry.status)
417
+ }),
418
+ /* @__PURE__ */ jsxs("div", {
419
+ className: "flex items-center gap-1.5 flex-shrink-0 text-[10px]",
420
+ children: [entry.additions > 0 && /* @__PURE__ */ jsxs("span", {
421
+ className: "flex items-center gap-0.5 text-green-600 dark:text-green-400",
422
+ children: [/* @__PURE__ */ jsx(Plus, { className: "h-2.5 w-2.5" }), entry.additions]
423
+ }), entry.deletions > 0 && /* @__PURE__ */ jsxs("span", {
424
+ className: "flex items-center gap-0.5 text-red-600 dark:text-red-400",
425
+ children: [/* @__PURE__ */ jsx(Minus, { className: "h-2.5 w-2.5" }), entry.deletions]
426
+ })]
427
+ })
428
+ ]
429
+ }), expanded && /* @__PURE__ */ jsx("div", {
430
+ className: "overflow-x-auto",
431
+ children: patchLines.length > 0 ? /* @__PURE__ */ jsx("pre", {
432
+ className: "text-[11px] leading-[1.6] font-mono",
433
+ children: patchLines.map((line, i) => /* @__PURE__ */ jsx("div", {
434
+ className: `px-3 ${lineClassName(line.type)}`,
435
+ children: line.content
436
+ }, i))
437
+ }) : /* @__PURE__ */ jsx("div", {
438
+ className: "px-3 py-4 text-center text-xs text-gray-400 italic",
439
+ children: "No diff content available"
440
+ })
441
+ })]
442
+ });
443
+ }
444
+ const DiffViewer = ({ entries, className }) => {
445
+ if (entries.length === 0) return /* @__PURE__ */ jsx("div", {
446
+ className: `flex items-center justify-center py-8 text-xs text-gray-400 ${className ?? ""}`,
447
+ children: "No changes to display"
448
+ });
449
+ const totalAdditions = entries.reduce((sum, e) => sum + e.additions, 0);
450
+ const totalDeletions = entries.reduce((sum, e) => sum + e.deletions, 0);
451
+ return /* @__PURE__ */ jsxs("div", {
452
+ className: `space-y-2 ${className ?? ""}`,
453
+ children: [/* @__PURE__ */ jsxs("div", {
454
+ className: "flex items-center gap-3 px-3 py-2 bg-gray-50 dark:bg-gray-800 rounded-lg text-xs text-gray-600 dark:text-gray-300",
455
+ children: [
456
+ /* @__PURE__ */ jsxs("div", {
457
+ className: "flex items-center gap-1",
458
+ children: [
459
+ /* @__PURE__ */ jsx(FileText, { className: "h-3.5 w-3.5 text-gray-400" }),
460
+ /* @__PURE__ */ jsx("span", {
461
+ className: "font-medium",
462
+ children: entries.length
463
+ }),
464
+ /* @__PURE__ */ jsxs("span", { children: [
465
+ "file",
466
+ entries.length !== 1 ? "s" : "",
467
+ " changed"
468
+ ] })
469
+ ]
470
+ }),
471
+ /* @__PURE__ */ jsxs("div", {
472
+ className: "flex items-center gap-1 text-green-600 dark:text-green-400",
473
+ children: [/* @__PURE__ */ jsx(Plus, { className: "h-3 w-3" }), /* @__PURE__ */ jsx("span", { children: totalAdditions })]
474
+ }),
475
+ /* @__PURE__ */ jsxs("div", {
476
+ className: "flex items-center gap-1 text-red-600 dark:text-red-400",
477
+ children: [/* @__PURE__ */ jsx(Minus, { className: "h-3 w-3" }), /* @__PURE__ */ jsx("span", { children: totalDeletions })]
478
+ })
479
+ ]
480
+ }), entries.map((entry) => /* @__PURE__ */ jsx(FileDiffSection, {
481
+ entry,
482
+ defaultExpanded: entries.length <= 5
483
+ }, entry.path))]
484
+ });
485
+ };
486
+
487
+ //#endregion
488
+ //#region src/git/BranchList.tsx
489
+ const BranchList = ({ branches, currentBranch, onSelectBranch, className }) => {
490
+ const [search, setSearch] = useState("");
491
+ const filtered = useMemo(() => {
492
+ if (!search) return branches;
493
+ const lower = search.toLowerCase();
494
+ return branches.filter((b) => b.name.toLowerCase().includes(lower));
495
+ }, [branches, search]);
496
+ const sorted = useMemo(() => {
497
+ return [...filtered].sort((a, b) => {
498
+ if (a.isDefault && !b.isDefault) return -1;
499
+ if (!a.isDefault && b.isDefault) return 1;
500
+ if (a.name === currentBranch && b.name !== currentBranch) return -1;
501
+ if (a.name !== currentBranch && b.name === currentBranch) return 1;
502
+ return a.name.localeCompare(b.name);
503
+ });
504
+ }, [filtered, currentBranch]);
505
+ return /* @__PURE__ */ jsxs("div", {
506
+ className: `flex flex-col h-full ${className ?? ""}`,
507
+ children: [/* @__PURE__ */ jsx("div", {
508
+ className: "px-2 py-2 border-b border-gray-200 dark:border-gray-700 flex-shrink-0",
509
+ children: /* @__PURE__ */ jsxs("div", {
510
+ className: "relative",
511
+ children: [/* @__PURE__ */ jsx(Search, { className: "absolute left-2 top-1/2 -translate-y-1/2 h-3 w-3 text-gray-400" }), /* @__PURE__ */ jsx("input", {
512
+ type: "text",
513
+ placeholder: "Filter branches...",
514
+ value: search,
515
+ onChange: (e) => setSearch(e.target.value),
516
+ className: "w-full pl-7 pr-2 py-1.5 text-xs rounded-md border border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-900 focus:outline-none focus:ring-1 focus:ring-blue-500 placeholder-gray-400"
517
+ })]
518
+ })
519
+ }), /* @__PURE__ */ jsx("div", {
520
+ className: "flex-1 overflow-auto",
521
+ children: sorted.length === 0 ? /* @__PURE__ */ jsx("div", {
522
+ className: "px-3 py-6 text-center text-xs text-gray-400",
523
+ children: search ? "No matching branches" : "No branches found"
524
+ }) : sorted.map((branch) => {
525
+ const isCurrent = branch.name === currentBranch;
526
+ return /* @__PURE__ */ jsxs("button", {
527
+ onClick: () => onSelectBranch?.(branch),
528
+ className: `flex items-center gap-2 w-full px-3 py-2 text-left transition-colors border-b border-gray-50 dark:border-gray-800/50 ${isCurrent ? "bg-blue-50 dark:bg-blue-900/20" : "hover:bg-gray-50 dark:hover:bg-gray-800/50"}`,
529
+ children: [
530
+ /* @__PURE__ */ jsx("span", {
531
+ className: "w-4 flex-shrink-0 flex items-center justify-center",
532
+ children: isCurrent ? /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5 text-blue-500" }) : /* @__PURE__ */ jsx(GitBranch, { className: "h-3.5 w-3.5 text-gray-400" })
533
+ }),
534
+ /* @__PURE__ */ jsx("span", {
535
+ className: `text-xs truncate flex-1 ${isCurrent ? "font-semibold text-blue-700 dark:text-blue-300" : "text-gray-700 dark:text-gray-300"}`,
536
+ children: branch.name
537
+ }),
538
+ /* @__PURE__ */ jsxs("div", {
539
+ className: "flex items-center gap-1 flex-shrink-0",
540
+ children: [branch.isDefault && /* @__PURE__ */ jsx("span", {
541
+ className: "px-1.5 py-0.5 text-[9px] font-medium bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400 rounded",
542
+ children: "default"
543
+ }), branch.isProtected && /* @__PURE__ */ jsxs("span", {
544
+ className: "flex items-center gap-0.5 px-1.5 py-0.5 text-[9px] font-medium bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400 rounded",
545
+ children: [/* @__PURE__ */ jsx(Shield, { className: "h-2.5 w-2.5" }), "protected"]
546
+ })]
547
+ }),
548
+ /* @__PURE__ */ jsx("code", {
549
+ className: "text-[10px] font-mono text-gray-400 dark:text-gray-500 flex-shrink-0",
550
+ children: branch.sha.slice(0, 7)
551
+ })
552
+ ]
553
+ }, branch.name);
554
+ })
555
+ })]
556
+ });
557
+ };
558
+
559
+ //#endregion
560
+ export { BranchList, CommitGraph, CommitList, DiffViewer, computeGraphLayout, graphWidth };
561
+ //# sourceMappingURL=git-B55e6LL-.js.map