The complex logic and markup for rendering the repository tabs have been extracted from App.svelte into a new, reusable RepoTabs component. This refactoring significantly cleans up the main application view, improves separation of concerns, and makes the UI structure easier to maintain and extend. Corresponding CSS updates were applied to ensure the visual fidelity and responsiveness of the tab bar remain consistent across different states. - Encapsulates all tab rendering logic in src/lib/RepoTabs.svelte - Simplifies App.svelte by replacing large block of HTML with component usage - Updates styling for better alignment and modern aesthetics
78 lines
2.6 KiB
Svelte
78 lines
2.6 KiB
Svelte
<script lang="ts">
|
|
import { BookOpen, Database, Plus, X } from "@lucide/svelte";
|
|
|
|
interface RepositoryTabItem {
|
|
path: string;
|
|
name: string;
|
|
branch: string | null;
|
|
}
|
|
|
|
export let activeView: "management" | "repository" = "management";
|
|
export let repoTabs: RepositoryTabItem[] = [];
|
|
export let isBusy: boolean = false;
|
|
export let language: "en" | "de" = "en";
|
|
export let onOpenManagement: () => void = () => {};
|
|
export let isActive: (path: string) => boolean = () => false;
|
|
export let onSelect: (path: string) => void | Promise<void> = () => {};
|
|
export let onClose: (path: string, event: MouseEvent) => void | Promise<void> = () => {};
|
|
export let onContextMenu: (path: string, event: MouseEvent) => void = () => {};
|
|
export let onAdd: () => void | Promise<void> = () => {};
|
|
</script>
|
|
|
|
<header class="repo-tabbar" aria-label={language === "de" ? "Repository-Reiter" : "Repository tabs"}>
|
|
<button
|
|
class="repo-tab management"
|
|
class:active={activeView === "management"}
|
|
type="button"
|
|
onclick={onOpenManagement}
|
|
disabled={isBusy}
|
|
title={language === "de" ? "Repository-Verwaltung" : "Repository Management"}
|
|
>
|
|
<BookOpen size={14} aria-hidden="true" />
|
|
<span>{language === "de" ? "Repository-Verwaltung" : "Repository Management"}</span>
|
|
</button>
|
|
|
|
<div class="repo-tabs-scroll">
|
|
{#each repoTabs as repo (repo.path)}
|
|
<div
|
|
class="repo-tab-wrap"
|
|
class:active={isActive(repo.path)}
|
|
role="presentation"
|
|
oncontextmenu={(event) => onContextMenu(repo.path, event)}
|
|
>
|
|
<button
|
|
class="repo-tab"
|
|
type="button"
|
|
onclick={() => onSelect(repo.path)}
|
|
disabled={isBusy}
|
|
title={repo.path}
|
|
>
|
|
<Database size={15} aria-hidden="true" />
|
|
<span>{repo.name}</span>
|
|
</button>
|
|
<button
|
|
class="repo-tab-close"
|
|
type="button"
|
|
onclick={(event) => onClose(repo.path, event)}
|
|
disabled={isBusy}
|
|
aria-label={language === "de" ? `${repo.name} schließen` : `Close ${repo.name}`}
|
|
title={language === "de" ? "Repository-Tab schließen" : "Close repository tab"}
|
|
>
|
|
<X size={13} aria-hidden="true" />
|
|
</button>
|
|
</div>
|
|
{/each}
|
|
</div>
|
|
|
|
<button
|
|
class="repo-tab-add"
|
|
type="button"
|
|
onclick={onAdd}
|
|
disabled={isBusy}
|
|
title={language === "de" ? "Repository-Ordner öffnen" : "Open repository folder"}
|
|
aria-label={language === "de" ? "Repository-Ordner öffnen" : "Open repository folder"}
|
|
>
|
|
<Plus size={15} aria-hidden="true" />
|
|
</button>
|
|
</header>
|