Compare commits

..
1 Commits
Author SHA1 Message Date
Christoph 624e912f2b refactor(repo-toolbar): use single openMenu state for menus
Consolidates the previous historyOpen and syncOpen booleans into a single
union-typed openMenu ("history" | "sync" | null). Menu toggles, outside-click
handler, Escape key handling and menu-item clicks now set/clear openMenu,
and aria-expanded / class bindings were updated to reference openMenu.

No user-facing behavior changes intended beyond ensuring only one menu can be
open at a time and simplifying the event-handling logic.
2026-09-24 22:12:18 +02:00
+15 -16
View File
@@ -49,8 +49,7 @@
export let onOpenSubmodules: () => void = () => {}; export let onOpenSubmodules: () => void = () => {};
export let onOpenLfs: () => void = () => {}; export let onOpenLfs: () => void = () => {};
let historyOpen = false; let openMenu: "history" | "sync" | null = null;
let syncOpen = false;
let toolbarElement: HTMLDivElement; let toolbarElement: HTMLDivElement;
$: isGerman = language === "de"; $: isGerman = language === "de";
@@ -65,18 +64,18 @@
: "Push"; : "Push";
function runHistoryAction(action: () => void) { function runHistoryAction(action: () => void) {
historyOpen = false; openMenu = null;
action(); action();
} }
function handleWindowClick(event: MouseEvent) { function handleWindowClick(event: MouseEvent) {
if (toolbarElement && !toolbarElement.contains(event.target as Node)) { historyOpen = false; syncOpen = false; } if (toolbarElement && !toolbarElement.contains(event.target as Node)) openMenu = null;
} }
function handleWindowKeydown(event: KeyboardEvent) { function handleWindowKeydown(event: KeyboardEvent) {
if (event.key === "Escape" && historyOpen) { if (event.key === "Escape" && openMenu) {
event.stopPropagation(); event.stopPropagation();
historyOpen = false; openMenu = null;
} }
} }
</script> </script>
@@ -144,15 +143,15 @@
{/if} {/if}
</button> </button>
<div class="repo-history-wrap"> <div class="repo-history-wrap">
<button class="repo-action" type="button" onclick={() => { syncOpen = !syncOpen; historyOpen = false; }} disabled={!hasRepository || isBusy} aria-label={isGerman ? "Sync-Optionen" : "Sync options"} aria-haspopup="menu"> <button class="repo-action" type="button" onclick={() => { openMenu = openMenu === "sync" ? null : "sync"; }} disabled={!hasRepository || isBusy} aria-label={isGerman ? "Sync-Optionen" : "Sync options"} aria-haspopup="menu" aria-expanded={openMenu === "sync"}>
<ChevronDown size={14} aria-hidden="true" /> <ChevronDown size={14} aria-hidden="true" />
</button> </button>
{#if syncOpen} {#if openMenu === "sync"}
<div class="repo-history-menu" role="menu"> <div class="repo-history-menu" role="menu">
<button type="button" role="menuitem" onclick={() => { syncOpen = false; onFetchPrune(); }}><CloudDownload size={15} /><span><strong>Fetch + Prune</strong><small>{isGerman ? "Veraltete Remote-Branches entfernen" : "Remove stale remote branches"}</small></span></button> <button type="button" role="menuitem" onclick={() => { openMenu = null; onFetchPrune(); }}><CloudDownload size={15} /><span><strong>Fetch + Prune</strong><small>{isGerman ? "Veraltete Remote-Branches entfernen" : "Remove stale remote branches"}</small></span></button>
<button type="button" role="menuitem" onclick={() => { syncOpen = false; onForcePush(); }}><Upload size={15} /><span><strong>Force with lease</strong><small>{isGerman ? "Sicheres Pushen nach Rebase" : "Safe push after rebase"}</small></span></button> <button type="button" role="menuitem" onclick={() => { openMenu = null; onForcePush(); }}><Upload size={15} /><span><strong>Force with lease</strong><small>{isGerman ? "Sicheres Pushen nach Rebase" : "Safe push after rebase"}</small></span></button>
<button type="button" role="menuitem" onclick={() => { syncOpen = false; onSyncOptions(); }}><Settings2 size={15} /><span><strong>{isGerman ? "Remotes & Strategien" : "Remotes & strategies"}</strong><small>{isGerman ? "Upstream, Pull und Remote verwalten" : "Manage upstream, pull and remotes"}</small></span></button> <button type="button" role="menuitem" onclick={() => { openMenu = null; onSyncOptions(); }}><Settings2 size={15} /><span><strong>{isGerman ? "Remotes & Strategien" : "Remotes & strategies"}</strong><small>{isGerman ? "Upstream, Pull und Remote verwalten" : "Manage upstream, pull and remotes"}</small></span></button>
<button type="button" role="menuitem" onclick={() => { syncOpen = false; onOpenLfs(); }}><Box size={15} /><span><strong>Git LFS</strong><small>{isGerman ? "Große Dateien und LFS-Installation verwalten" : "Manage large files and LFS installation"}</small></span></button> <button type="button" role="menuitem" onclick={() => { openMenu = null; onOpenLfs(); }}><Box size={15} /><span><strong>Git LFS</strong><small>{isGerman ? "Große Dateien und LFS-Installation verwalten" : "Manage large files and LFS installation"}</small></span></button>
</div> </div>
{/if} {/if}
</div> </div>
@@ -187,12 +186,12 @@
<div class="repo-history-wrap"> <div class="repo-history-wrap">
<button <button
class="repo-action history-trigger" class="repo-action history-trigger"
class:active={historyOpen} class:active={openMenu === "history"}
type="button" type="button"
onclick={() => { historyOpen = !historyOpen; }} onclick={() => { openMenu = openMenu === "history" ? null : "history"; }}
disabled={!hasRepository || isBusy} disabled={!hasRepository || isBusy}
aria-haspopup="menu" aria-haspopup="menu"
aria-expanded={historyOpen} aria-expanded={openMenu === "history"}
title={isGerman ? "Verlauf und Rebase" : "History and rebase"} title={isGerman ? "Verlauf und Rebase" : "History and rebase"}
> >
<History size={15} aria-hidden="true" /> <History size={15} aria-hidden="true" />
@@ -200,7 +199,7 @@
<ChevronDown class="history-chevron" size={13} aria-hidden="true" /> <ChevronDown class="history-chevron" size={13} aria-hidden="true" />
</button> </button>
{#if historyOpen} {#if openMenu === "history"}
<div class="repo-history-menu" role="menu"> <div class="repo-history-menu" role="menu">
<button type="button" role="menuitem" onclick={() => runHistoryAction(onReflog)}> <button type="button" role="menuitem" onclick={() => runHistoryAction(onReflog)}>
<History size={15} aria-hidden="true" /> <History size={15} aria-hidden="true" />