From f71a07ab11493f94216e5ca1939cd1dbb0f40c06 Mon Sep 17 00:00:00 2001 From: Christoph Brandau Date: Thu, 17 Sep 2026 17:37:41 +0200 Subject: [PATCH] feat(branch-panel): add branch filtering, persistent view state, and UI polish - Add a text filter with highlight and clear (Esc to clear) that narrows visible branches and auto-opens folders while filtering. - Persist panel view state (local/remote open + collapsed folders) to localStorage under "gitlite.branchPanelView.v2" so folder open/collapse and section visibility survive reloads. - Reveal current branch action: clears filter, expands path to current branch, scrolls it into view and briefly flashes it. - Rework branch list rendering: unified folder/branch ids, scope-aware rows, tracking status computation (tracked/gone/local/remote-tracked), richer titles/tooltips, updated icons, and better context-menu positioning/behavior (separate showBranchMenuAt + open-from-button). - Prevent toggling folder collapse while filtering; folder rows are implicitly open when a filter is active. - Add slim, rounded custom scrollbars for the left sidebar in src/app.css. No external APIs changed; behavior is additive and intended to improve branch navigation and discoverability. --- src/app.css | 40 ++ src/lib/components/BranchPanel.svelte | 881 ++++++++++++++++++++------ 2 files changed, 719 insertions(+), 202 deletions(-) diff --git a/src/app.css b/src/app.css index a6b338a..5ebcbeb 100644 --- a/src/app.css +++ b/src/app.css @@ -9253,3 +9253,43 @@ section > header.page-header.page-header { .sidebar-tags-list { min-height: 0; overflow: auto; padding: 4px 0; } .left-sidebar .tags-panel .tag-create-form { grid-template-columns: auto minmax(0, 1fr) auto auto; margin: 4px 8px; } .left-sidebar .tags-panel .tag-create-form input[aria-label="Tag message"] { grid-column: 2 / -1; grid-row: 2; } + + +/* --- Sidebar scrollbars --------------------------------------------------- + Slim, rounded thumb that brightens while hovering a scroll area. + scrollbar-width/color are reset so WebKit uses the pseudo-element styling. + The panel lists are named explicitly so they win over any other rule. */ +.left-sidebar, +.left-sidebar *, +.left-sidebar .sidebar-tags-list, +.left-sidebar .sidebar-worktree-list, +.left-sidebar .stash-list, +.left-sidebar .explorer-list { + scrollbar-width: auto !important; + scrollbar-color: auto !important; +} +.left-sidebar ::-webkit-scrollbar, +.left-sidebar .sidebar-tags-list::-webkit-scrollbar, +.left-sidebar .sidebar-worktree-list::-webkit-scrollbar, +.left-sidebar .stash-list::-webkit-scrollbar, +.left-sidebar .explorer-list::-webkit-scrollbar { width: 8px !important; height: 8px !important; background: transparent; } +.left-sidebar ::-webkit-scrollbar-track, +.left-sidebar .sidebar-tags-list::-webkit-scrollbar-track, +.left-sidebar .sidebar-worktree-list::-webkit-scrollbar-track, +.left-sidebar .stash-list::-webkit-scrollbar-track, +.left-sidebar .explorer-list::-webkit-scrollbar-track { margin: 6px 0; background: transparent; } +.left-sidebar ::-webkit-scrollbar-corner { background: transparent; } +.left-sidebar ::-webkit-scrollbar-thumb, +.left-sidebar .sidebar-tags-list::-webkit-scrollbar-thumb, +.left-sidebar .sidebar-worktree-list::-webkit-scrollbar-thumb, +.left-sidebar .stash-list::-webkit-scrollbar-thumb, +.left-sidebar .explorer-list::-webkit-scrollbar-thumb { + min-height: 28px; + border: 2px solid transparent; + border-radius: 999px; + background-clip: padding-box; + background-color: color-mix(in srgb, var(--app-scrollbar-thumb) 55%, transparent); +} +.left-sidebar :hover::-webkit-scrollbar-thumb { background-color: var(--app-scrollbar-thumb); } +.left-sidebar ::-webkit-scrollbar-thumb:hover, +.left-sidebar ::-webkit-scrollbar-thumb:active { background-color: var(--app-scrollbar-thumb-hover); } diff --git a/src/lib/components/BranchPanel.svelte b/src/lib/components/BranchPanel.svelte index 2fadcdb..7f996f0 100644 --- a/src/lib/components/BranchPanel.svelte +++ b/src/lib/components/BranchPanel.svelte @@ -1,8 +1,31 @@ - + + +{#snippet branchRows(rows: BranchRow[])} + {#each rows as row (row.id)} + {#if row.kind === "folder"} + {@const open = isBranchFolderOpen(row.id)} + + {:else} + {@const tracking = trackingFor(row.branch)} + +
checkoutOnDoubleClick(event, row.branch)} + oncontextmenu={(event) => openBranchContextMenu(event, row.branch)} + title={branchTitle(row.branch)} + > + + + + {#each highlightParts(row.displayName) as part, index (index)} + {#if part.match}{part.text}{:else}{part.text}{/if} + {/each} + + + {#if tracking.kind === "tracked"} + + {:else if tracking.kind === "gone"} + + {:else if tracking.kind === "local"} + + {:else if tracking.kind === "remote-tracked"} + + {/if} + {#if row.branch.current} + HEAD + {/if} + + +
+ {/if} + {/each} +{/snippet}
@@ -387,165 +628,118 @@ {:else if !hasRepository}

Open a repository to list branches.

{:else} -
- {#if createOpen} -
-
+ +