From 0dd5441754d158cfab45c6822ca9527a9dd39836 Mon Sep 17 00:00:00 2001 From: Christoph Brandau Date: Mon, 13 Jul 2026 00:09:28 +0200 Subject: [PATCH] feat(ui): enhance status panel actions and styling This update significantly refactors the visual layout and functionality of the working tree status panel. It introduces dedicated action groups for discarding changes, staging, and unstaging files, improving user interaction and clarity. - Added contextual action buttons (discard all/selected) to both staged and unstaged sections. - Updated CSS structure to accommodate new status action containers. - Improved handling of selected file counts within the panel headers. --- src/app.css | 40 +++++++++++ src/lib/components/StatusPanel.svelte | 98 +++++++++++---------------- 2 files changed, 80 insertions(+), 58 deletions(-) diff --git a/src/app.css b/src/app.css index 42cad09..16a86e1 100644 --- a/src/app.css +++ b/src/app.css @@ -6028,3 +6028,43 @@ input:focus, textarea:focus, select:focus { box-shadow: 0 0 0 3px color-mix(in s .ai-review-footer { align-items: stretch; flex-direction: column; } .ai-review-footer > div { justify-content: flex-end; } } + +/* Contextual status actions: global discard in the panel header, selection + actions beside their matching Stage/Unstage command. */ +.status-head-actions, +.status-lane-actions { + display: flex; + align-items: center; + justify-content: flex-end; + gap: 5px; + min-width: 0; +} +.status-head-actions { flex-wrap: wrap; } +.status-discard-all { + margin-left: 3px; + border-color: color-mix(in srgb, var(--code-delete-strong) 30%, var(--color-border)); + color: var(--code-delete-strong); + background: color-mix(in srgb, var(--code-delete-strong) 8%, transparent); +} +.status-discard-all:hover:not(:disabled) { + border-color: color-mix(in srgb, var(--code-delete-strong) 52%, var(--color-border)); + color: var(--code-delete-strong); + background: color-mix(in srgb, var(--code-delete-strong) 14%, transparent); +} +.status-lane-title { display: flex; align-items: center; gap: 7px; flex: 0 0 auto; } +.status-lane-actions { flex-wrap: wrap; } +.status-lane-actions .status-selection-count { + display: inline-flex; + width: auto; + min-width: 0; + height: 22px; + padding: 0 5px; + color: var(--color-ink-dim); + background: transparent; + font-size: 9.5px; +} + +@media (max-width: 760px) { + .status-lane-head { align-items: flex-start; flex-direction: column; } + .status-lane-actions { width: 100%; justify-content: flex-start; } +} diff --git a/src/lib/components/StatusPanel.svelte b/src/lib/components/StatusPanel.svelte index df88eb1..d861183 100644 --- a/src/lib/components/StatusPanel.svelte +++ b/src/lib/components/StatusPanel.svelte @@ -144,7 +144,6 @@ let hasUnstaged = $derived(changedFiles.some((f) => f.unstaged !== null)); let hasStaged = $derived(changedFiles.some((f) => f.staged !== null)); - let selectedCount = $derived(changedFiles.filter((f) => selectedStatusPaths.has(fileKey(f))).length); let selectedUnstagedCount = $derived(changedFiles.filter((f) => selectedStatusPaths.has(fileKey(f)) && f.unstaged !== null).length); let selectedStagedCount = $derived(changedFiles.filter((f) => selectedStatusPaths.has(fileKey(f)) && f.staged !== null).length); @@ -156,65 +155,22 @@ }); -
+
Workspace

Changes

-
+
{stagedCount} staged {unstagedCount} unstaged -
-
- - {#if hasRepository && changedFiles.length > 0} -
- - {#if selectedCount > 1} - {selectedCount} selected - - - {/if}
- {/if} +
{#if !hasRepository}
No repository loaded.
@@ -226,10 +182,23 @@
-
Unstaged{unstagedCount}
- +
Unstaged{unstagedCount}
+
+ {#if selectedUnstagedCount > 1} + {selectedUnstagedCount} selected + + {/if} + + {#if selectedUnstagedCount > 1} + + {/if} +
{#each changedFiles.filter((file) => file.unstaged !== null) as file (`unstaged:${fileKey(file)}`)} @@ -253,10 +222,23 @@
-
Staged{stagedCount}
- +
Staged{stagedCount}
+
+ {#if selectedStagedCount > 1} + {selectedStagedCount} selected + + {/if} + + {#if selectedStagedCount > 1} + + {/if} +
{#each changedFiles.filter((file) => file.staged !== null) as file (`staged:${fileKey(file)}`)}