feat(status-panel): add loading overlay for ongoing operations

This update introduces a loading overlay in the StatusPanel component
to indicate ongoing operations. The overlay displays a spinner and
the current operation status, enhancing user experience during
long-running tasks.

- Added a loading overlay with a spinner for busy states
- Included operation status text to inform users of current actions
- Improved visual feedback for ongoing processes in the UI
This commit is contained in:
Christoph Brandau
2026-07-09 15:20:52 +02:00
parent f79f3dc1ec
commit 0877d5a568
2 changed files with 50 additions and 2 deletions
+49 -2
View File
@@ -1,5 +1,5 @@
<script lang="ts">
import { Check, FileDiff, RotateCcw, Undo2 } from "@lucide/svelte";
import { Check, FileDiff, LoaderCircle, RotateCcw, Undo2 } from "@lucide/svelte";
import type { FileStatusKind, GitFileStatus, GitStatus } from "../types";
interface Props {
@@ -8,6 +8,7 @@
unstagedCount: number;
hasRepository: boolean;
isBusy: boolean;
operation: string;
status: GitStatus | null;
selectedFilePath: string;
onSelectFile: (file: GitFileStatus) => void;
@@ -25,6 +26,7 @@
unstagedCount = 0,
hasRepository = false,
isBusy = false,
operation = "",
status = null,
selectedFilePath = "",
onSelectFile = () => {},
@@ -136,7 +138,7 @@
});
</script>
<section class="panel grid grid-rows-[auto_auto_1fr] overflow-hidden" aria-label="Working tree status">
<section class="panel relative grid grid-rows-[auto_auto_1fr] overflow-hidden" aria-label="Working tree status">
<div class="section-head">
<div>
<span class="eyebrow">Working tree</span>
@@ -278,4 +280,49 @@
{/each}
</div>
{/if}
{#if isBusy && hasRepository}
<div class="status-panel-overlay" role="status" aria-live="polite">
<div class="status-panel-overlay-card">
<LoaderCircle class="spin" size={22} aria-hidden="true" />
<span>{operation || "Working"}</span>
</div>
</div>
{/if}
</section>
<style>
.status-panel-overlay {
position: absolute;
inset: 0;
z-index: 20;
display: grid;
place-items: center;
background: rgba(8, 9, 16, 0.5);
backdrop-filter: blur(3px);
animation: status-panel-overlay-in 120ms ease;
}
.status-panel-overlay-card {
display: flex;
align-items: center;
gap: 10px;
padding: 12px 20px;
border: 1px solid var(--color-border);
border-radius: 10px;
background: var(--color-surface-raised);
color: var(--color-ink);
font-size: 13px;
font-weight: 600;
box-shadow: 0 18px 44px rgba(0, 0, 0, 0.38);
}
@keyframes status-panel-overlay-in {
from { opacity: 0; }
to { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
.status-panel-overlay { animation: none; }
}
</style>