feat(ui): enhance panel resizing and state persistence

This update introduces functionality for resizing various panels in the UI, including the left sidebar, branch panel, stash panel, and file history. It also adds state persistence for panel sizes and collapsed states using local storage, improving user experience by maintaining preferences across sessions.

- Implemented resizing functionality for multiple UI panels
- Added local storage support for panel dimensions and collapsed states
- Enhanced accessibility features for panel controls
This commit is contained in:
Christoph Brandau
2026-07-09 08:33:09 +02:00
parent adfb5f4158
commit 8627012d93
6 changed files with 749 additions and 75 deletions
+437 -21
View File
@@ -165,13 +165,33 @@
const AI_SETTINGS_KEY = "gitlite.aiSettings.v1";
const ANALYTICS_SETTINGS_KEY = "gitlite.analyticsSettings.v1";
const COMMIT_PANEL_HEIGHT_KEY = "gitlite.commitPanelHeight.v1";
const LEFT_SIDEBAR_WIDTH_KEY = "gitlite.leftSidebarWidth.v1";
const LEFT_BRANCH_PANEL_HEIGHT_KEY = "gitlite.leftBranchPanelHeight.v1";
const LEFT_STASH_PANEL_HEIGHT_KEY = "gitlite.leftStashPanelHeight.v1";
const BRANCH_PANEL_COLLAPSED_KEY = "gitlite.branchPanelCollapsed.v1";
const STASH_PANEL_COLLAPSED_KEY = "gitlite.stashPanelCollapsed.v2";
const EXPLORER_PANEL_COLLAPSED_KEY = "gitlite.explorerPanelCollapsed.v1";
const HISTORY_ASIDE_WIDTH_KEY = "gitlite.historyAsideWidth.v1";
const FILE_HISTORY_WIDTH_KEY = "gitlite.fileHistoryWidth.v1";
const COMMIT_PANEL_DEFAULT_HEIGHT = 220;
const COMMIT_PANEL_MIN_HEIGHT = COMMIT_PANEL_DEFAULT_HEIGHT;
const COMMIT_PANEL_MAX_HEIGHT = 640;
const LEFT_SIDEBAR_DEFAULT_WIDTH = 280;
const LEFT_SIDEBAR_MIN_WIDTH = 220;
const LEFT_SIDEBAR_MAX_WIDTH = 420;
const LEFT_BRANCH_PANEL_DEFAULT_HEIGHT = 260;
const LEFT_BRANCH_PANEL_MIN_HEIGHT = 180;
const LEFT_BRANCH_PANEL_MAX_HEIGHT = 560;
const LEFT_STASH_PANEL_DEFAULT_HEIGHT = 190;
const LEFT_STASH_PANEL_MIN_HEIGHT = 150;
const LEFT_STASH_PANEL_MAX_HEIGHT = 420;
const LEFT_EXPLORER_PANEL_MIN_HEIGHT = 220;
const HISTORY_ASIDE_DEFAULT_WIDTH = 620;
const HISTORY_ASIDE_MIN_WIDTH = 560;
const HISTORY_ASIDE_MAX_WIDTH = 920;
const FILE_HISTORY_DEFAULT_WIDTH = 300;
const FILE_HISTORY_MIN_WIDTH = 240;
const FILE_HISTORY_MAX_WIDTH = 520;
const ERROR_AUTO_HIDE_MS = 6000;
// ── State ──────────────────────────────────────────────────────────────────
@@ -292,10 +312,30 @@
let resizingCommitPanel = false;
let resizeStartY = 0;
let resizeStartHeight = 0;
let leftSidebarWidth = loadLeftSidebarWidth();
let resizingLeftSidebar = false;
let leftSidebarResizeStartX = 0;
let leftSidebarResizeStartWidth = 0;
let leftBranchPanelHeight = loadLeftBranchPanelHeight();
let resizingLeftBranchPanel = false;
let leftBranchResizeStartY = 0;
let leftBranchResizeStartHeight = 0;
let leftStashPanelHeight = loadLeftStashPanelHeight();
let resizingLeftStashPanel = false;
let leftStashResizeStartY = 0;
let leftStashResizeStartHeight = 0;
let branchPanelCollapsed = loadStoredBoolean(BRANCH_PANEL_COLLAPSED_KEY, false);
let stashPanelCollapsed = loadStoredBoolean(STASH_PANEL_COLLAPSED_KEY, false);
let explorerPanelCollapsed = loadStoredBoolean(EXPLORER_PANEL_COLLAPSED_KEY, false);
let historyAsideWidth = loadHistoryAsideWidth();
let resizingHistoryAside = false;
let historyResizeStartX = 0;
let historyResizeStartWidth = 0;
let fileHistoryWidth = loadFileHistoryWidth();
let resizingFileHistory = false;
let fileHistoryResizeStartX = 0;
let fileHistoryResizeStartWidth = 0;
let fileHistoryCollapsed = true;
// ── Derived ────────────────────────────────────────────────────────────────
@@ -345,6 +385,8 @@
$: favoriteRepoRows = favoriteRepoPaths
.map(repoRowFromPath)
.filter(repoMatchesSearch);
$: leftSidebarRows = buildLeftSidebarRows(branchPanelCollapsed, stashPanelCollapsed, explorerPanelCollapsed);
$: allLeftPanelsCollapsed = branchPanelCollapsed && stashPanelCollapsed && explorerPanelCollapsed;
// ── Lifecycle ──────────────────────────────────────────────────────────────
@@ -1024,6 +1066,25 @@
}
}
function loadStoredBoolean(key: string, fallback: boolean): boolean {
try {
const stored = localStorage.getItem(key);
if (stored === "true") return true;
if (stored === "false") return false;
} catch {
// Local storage is best-effort only; panel defaults are enough.
}
return fallback;
}
function persistStoredBoolean(key: string, value: boolean) {
try {
localStorage.setItem(key, String(value));
} catch {
// Local storage is best-effort only; toggles must keep working without it.
}
}
function clampCommitPanelHeight(value: number): number {
return Math.min(COMMIT_PANEL_MAX_HEIGHT, Math.max(COMMIT_PANEL_MIN_HEIGHT, Math.round(value)));
}
@@ -1046,6 +1107,72 @@
}
}
function clampLeftSidebarWidth(value: number): number {
return Math.min(LEFT_SIDEBAR_MAX_WIDTH, Math.max(LEFT_SIDEBAR_MIN_WIDTH, Math.round(value)));
}
function loadLeftSidebarWidth(): number {
try {
const stored = Number(localStorage.getItem(LEFT_SIDEBAR_WIDTH_KEY));
if (Number.isFinite(stored) && stored > 0) return clampLeftSidebarWidth(stored);
} catch {
// Fall through to the default below.
}
return LEFT_SIDEBAR_DEFAULT_WIDTH;
}
function persistLeftSidebarWidth(value: number) {
try {
localStorage.setItem(LEFT_SIDEBAR_WIDTH_KEY, String(value));
} catch {
// Local storage is best-effort only; resizing must keep working without it.
}
}
function clampLeftBranchPanelHeight(value: number): number {
return Math.min(LEFT_BRANCH_PANEL_MAX_HEIGHT, Math.max(LEFT_BRANCH_PANEL_MIN_HEIGHT, Math.round(value)));
}
function loadLeftBranchPanelHeight(): number {
try {
const stored = Number(localStorage.getItem(LEFT_BRANCH_PANEL_HEIGHT_KEY));
if (Number.isFinite(stored) && stored > 0) return clampLeftBranchPanelHeight(stored);
} catch {
// Fall through to the default below.
}
return LEFT_BRANCH_PANEL_DEFAULT_HEIGHT;
}
function persistLeftBranchPanelHeight(value: number) {
try {
localStorage.setItem(LEFT_BRANCH_PANEL_HEIGHT_KEY, String(value));
} catch {
// Local storage is best-effort only; resizing must keep working without it.
}
}
function clampLeftStashPanelHeight(value: number): number {
return Math.min(LEFT_STASH_PANEL_MAX_HEIGHT, Math.max(LEFT_STASH_PANEL_MIN_HEIGHT, Math.round(value)));
}
function loadLeftStashPanelHeight(): number {
try {
const stored = Number(localStorage.getItem(LEFT_STASH_PANEL_HEIGHT_KEY));
if (Number.isFinite(stored) && stored > 0) return clampLeftStashPanelHeight(stored);
} catch {
// Fall through to the default below.
}
return LEFT_STASH_PANEL_DEFAULT_HEIGHT;
}
function persistLeftStashPanelHeight(value: number) {
try {
localStorage.setItem(LEFT_STASH_PANEL_HEIGHT_KEY, String(value));
} catch {
// Local storage is best-effort only; resizing must keep working without it.
}
}
function clampHistoryAsideWidth(value: number): number {
return Math.min(HISTORY_ASIDE_MAX_WIDTH, Math.max(HISTORY_ASIDE_MIN_WIDTH, Math.round(value)));
}
@@ -1068,6 +1195,28 @@
}
}
function clampFileHistoryWidth(value: number): number {
return Math.min(FILE_HISTORY_MAX_WIDTH, Math.max(FILE_HISTORY_MIN_WIDTH, Math.round(value)));
}
function loadFileHistoryWidth(): number {
try {
const stored = Number(localStorage.getItem(FILE_HISTORY_WIDTH_KEY));
if (Number.isFinite(stored) && stored > 0) return clampFileHistoryWidth(stored);
} catch {
// Fall through to the default below.
}
return FILE_HISTORY_DEFAULT_WIDTH;
}
function persistFileHistoryWidth(value: number) {
try {
localStorage.setItem(FILE_HISTORY_WIDTH_KEY, String(value));
} catch {
// Local storage is best-effort only; resizing must keep working without it.
}
}
function startCommitPanelResize(event: PointerEvent) {
event.preventDefault();
resizingCommitPanel = true;
@@ -1096,6 +1245,131 @@
persistCommitPanelHeight(commitPanelHeight);
}
function startLeftSidebarResize(event: PointerEvent) {
event.preventDefault();
resizingLeftSidebar = true;
leftSidebarResizeStartX = event.clientX;
leftSidebarResizeStartWidth = leftSidebarWidth;
(event.currentTarget as HTMLElement).setPointerCapture(event.pointerId);
}
function onLeftSidebarResizeMove(event: PointerEvent) {
if (!resizingLeftSidebar) return;
leftSidebarWidth = clampLeftSidebarWidth(leftSidebarResizeStartWidth + (event.clientX - leftSidebarResizeStartX));
}
function endLeftSidebarResize(event: PointerEvent) {
if (!resizingLeftSidebar) return;
resizingLeftSidebar = false;
persistLeftSidebarWidth(leftSidebarWidth);
const target = event.currentTarget as HTMLElement;
if (target.hasPointerCapture(event.pointerId)) target.releasePointerCapture(event.pointerId);
}
function onLeftSidebarResizeKeydown(event: KeyboardEvent) {
if (event.key !== "ArrowLeft" && event.key !== "ArrowRight") return;
event.preventDefault();
leftSidebarWidth = clampLeftSidebarWidth(leftSidebarWidth + (event.key === "ArrowRight" ? 20 : -20));
persistLeftSidebarWidth(leftSidebarWidth);
}
function buildLeftSidebarRows(branchCollapsed: boolean, stashCollapsed: boolean, explorerCollapsed: boolean): string {
const branchRow = branchCollapsed
? "auto"
: `minmax(${LEFT_BRANCH_PANEL_MIN_HEIGHT}px, var(--branch-panel-height, ${LEFT_BRANCH_PANEL_DEFAULT_HEIGHT}px))`;
const branchHandleRow = branchCollapsed ? "0" : "14px";
const stashRow = stashCollapsed
? "auto"
: `minmax(${LEFT_STASH_PANEL_MIN_HEIGHT}px, var(--stash-panel-height, ${LEFT_STASH_PANEL_DEFAULT_HEIGHT}px))`;
const stashHandleRow = explorerCollapsed || (stashCollapsed && branchCollapsed) ? "0" : "14px";
const explorerRow = explorerCollapsed ? "auto" : `minmax(${LEFT_EXPLORER_PANEL_MIN_HEIGHT}px, 1fr)`;
return `${branchRow} ${branchHandleRow} ${stashRow} ${stashHandleRow} ${explorerRow}`;
}
function startLeftBranchPanelResize(event: PointerEvent) {
if (branchPanelCollapsed) return;
event.preventDefault();
resizingLeftBranchPanel = true;
leftBranchResizeStartY = event.clientY;
leftBranchResizeStartHeight = leftBranchPanelHeight;
(event.currentTarget as HTMLElement).setPointerCapture(event.pointerId);
}
function onLeftBranchPanelResizeMove(event: PointerEvent) {
if (!resizingLeftBranchPanel) return;
leftBranchPanelHeight = clampLeftBranchPanelHeight(leftBranchResizeStartHeight + (event.clientY - leftBranchResizeStartY));
}
function endLeftBranchPanelResize(event: PointerEvent) {
if (!resizingLeftBranchPanel) return;
resizingLeftBranchPanel = false;
persistLeftBranchPanelHeight(leftBranchPanelHeight);
const target = event.currentTarget as HTMLElement;
if (target.hasPointerCapture(event.pointerId)) target.releasePointerCapture(event.pointerId);
}
function onLeftBranchPanelResizeKeydown(event: KeyboardEvent) {
if (branchPanelCollapsed || (event.key !== "ArrowUp" && event.key !== "ArrowDown")) return;
event.preventDefault();
leftBranchPanelHeight = clampLeftBranchPanelHeight(leftBranchPanelHeight + (event.key === "ArrowDown" ? 20 : -20));
persistLeftBranchPanelHeight(leftBranchPanelHeight);
}
function startLeftStashPanelResize(event: PointerEvent) {
if (stashPanelCollapsed && branchPanelCollapsed) return;
event.preventDefault();
resizingLeftStashPanel = true;
leftStashResizeStartY = event.clientY;
leftStashResizeStartHeight = stashPanelCollapsed ? leftBranchPanelHeight : leftStashPanelHeight;
(event.currentTarget as HTMLElement).setPointerCapture(event.pointerId);
}
function onLeftStashPanelResizeMove(event: PointerEvent) {
if (!resizingLeftStashPanel) return;
if (stashPanelCollapsed) {
leftBranchPanelHeight = clampLeftBranchPanelHeight(leftStashResizeStartHeight + (event.clientY - leftStashResizeStartY));
} else {
leftStashPanelHeight = clampLeftStashPanelHeight(leftStashResizeStartHeight + (event.clientY - leftStashResizeStartY));
}
}
function endLeftStashPanelResize(event: PointerEvent) {
if (!resizingLeftStashPanel) return;
resizingLeftStashPanel = false;
if (stashPanelCollapsed) persistLeftBranchPanelHeight(leftBranchPanelHeight);
else persistLeftStashPanelHeight(leftStashPanelHeight);
const target = event.currentTarget as HTMLElement;
if (target.hasPointerCapture(event.pointerId)) target.releasePointerCapture(event.pointerId);
}
function onLeftStashPanelResizeKeydown(event: KeyboardEvent) {
if ((stashPanelCollapsed && branchPanelCollapsed) || (event.key !== "ArrowUp" && event.key !== "ArrowDown")) return;
event.preventDefault();
if (stashPanelCollapsed) {
leftBranchPanelHeight = clampLeftBranchPanelHeight(leftBranchPanelHeight + (event.key === "ArrowDown" ? 20 : -20));
persistLeftBranchPanelHeight(leftBranchPanelHeight);
} else {
leftStashPanelHeight = clampLeftStashPanelHeight(leftStashPanelHeight + (event.key === "ArrowDown" ? 20 : -20));
persistLeftStashPanelHeight(leftStashPanelHeight);
}
}
function toggleBranchPanelCollapsed() {
branchPanelCollapsed = !branchPanelCollapsed;
persistStoredBoolean(BRANCH_PANEL_COLLAPSED_KEY, branchPanelCollapsed);
}
function toggleStashPanelCollapsed() {
stashPanelCollapsed = !stashPanelCollapsed;
persistStoredBoolean(STASH_PANEL_COLLAPSED_KEY, stashPanelCollapsed);
}
function toggleExplorerPanelCollapsed() {
explorerPanelCollapsed = !explorerPanelCollapsed;
persistStoredBoolean(EXPLORER_PANEL_COLLAPSED_KEY, explorerPanelCollapsed);
}
function startHistoryAsideResize(event: PointerEvent) {
event.preventDefault();
resizingHistoryAside = true;
@@ -1124,6 +1398,43 @@
persistHistoryAsideWidth(historyAsideWidth);
}
function startFileHistoryResize(event: PointerEvent) {
if (fileHistoryCollapsed) return;
event.preventDefault();
resizingFileHistory = true;
fileHistoryResizeStartX = event.clientX;
fileHistoryResizeStartWidth = fileHistoryWidth;
(event.currentTarget as HTMLElement).setPointerCapture(event.pointerId);
}
function onFileHistoryResizeMove(event: PointerEvent) {
if (!resizingFileHistory) return;
fileHistoryWidth = clampFileHistoryWidth(fileHistoryResizeStartWidth + (fileHistoryResizeStartX - event.clientX));
}
function endFileHistoryResize(event: PointerEvent) {
if (!resizingFileHistory) return;
resizingFileHistory = false;
persistFileHistoryWidth(fileHistoryWidth);
const target = event.currentTarget as HTMLElement;
if (target.hasPointerCapture(event.pointerId)) target.releasePointerCapture(event.pointerId);
}
function onFileHistoryResizeKeydown(event: KeyboardEvent) {
if (fileHistoryCollapsed || (event.key !== "ArrowLeft" && event.key !== "ArrowRight")) return;
event.preventDefault();
fileHistoryWidth = clampFileHistoryWidth(fileHistoryWidth + (event.key === "ArrowLeft" ? 20 : -20));
persistFileHistoryWidth(fileHistoryWidth);
}
function toggleFileHistoryCollapsed() {
fileHistoryCollapsed = !fileHistoryCollapsed;
}
function revealFileHistory() {
fileHistoryCollapsed = false;
}
function rememberRecentRepo(path: string) {
recentRepoPaths = uniqueRepoPaths([path, ...recentRepoPaths]).slice(0, 40);
persistRepoLists();
@@ -2608,6 +2919,7 @@
if (!activeRepoPath || (selectedExplorerPath === node.path && selectedExplorerKind === node.kind)) return;
selectedExplorerPath = node.path;
selectedExplorerKind = node.kind;
revealFileHistory();
void loadSelectedFileHistory(node.path);
trackEvent("explorer_node_selected", {
kind: node.kind,
@@ -2620,6 +2932,7 @@
selectedExplorerPath = file.path;
selectedExplorerKind = "file";
expandedExplorerPaths = new Set([...expandedExplorerPaths, ...explorerParentFolders(file.path)]);
revealFileHistory();
void loadSelectedFileHistory(file.path);
trackEvent("explorer_file_selected", {
@@ -2633,6 +2946,7 @@
selectedExplorerPath = file.path;
selectedExplorerKind = "file";
expandedExplorerPaths = new Set([...expandedExplorerPaths, ...explorerParentFolders(file.path)]);
revealFileHistory();
void loadSelectedFileHistory(file.path);
trackEvent("explorer_file_selected", {
@@ -2645,6 +2959,7 @@
if (!activeRepoPath || node.kind !== "file") return;
selectedExplorerPath = node.path;
selectedExplorerKind = "file";
revealFileHistory();
void loadSelectedFileHistory(node.path);
try {
@@ -3231,10 +3546,22 @@
</section>
{:else}
<!-- Workspace -->
<section class="workspace" aria-label="Git workspace" style="--history-aside-width: {historyAsideWidth}px;">
<section
class="workspace"
aria-label="Git workspace"
style="--left-sidebar-width: {leftSidebarWidth}px; --history-aside-width: {historyAsideWidth}px; --file-history-width: {fileHistoryWidth}px;"
>
<!-- Left sidebar: branches + explorer -->
<aside class="left-sidebar" aria-label="Repository navigation">
<aside
class="left-sidebar"
class:branch-collapsed={branchPanelCollapsed}
class:stash-collapsed={stashPanelCollapsed}
class:explorer-collapsed={explorerPanelCollapsed}
class:all-collapsed={allLeftPanelsCollapsed}
aria-label="Repository navigation"
style="--branch-panel-height: {leftBranchPanelHeight}px; --stash-panel-height: {leftStashPanelHeight}px; grid-template-rows: {leftSidebarRows};"
>
<BranchPanel
{branches}
{localBranches}
@@ -3251,7 +3578,31 @@
onCreateTag={createNewTag}
onDeleteTag={deleteLocalTag}
onPushTag={pushLocalTag}
collapsed={branchPanelCollapsed}
onToggleCollapsed={toggleBranchPanelCollapsed}
/>
{#if !branchPanelCollapsed}
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
<div
class="panel-resize-handle left-panel-resize-handle branch-panel-resize-handle"
class:resizing={resizingLeftBranchPanel}
role="separator"
aria-orientation="horizontal"
aria-label="Resize branches panel height"
aria-valuenow={leftBranchPanelHeight}
aria-valuemin={LEFT_BRANCH_PANEL_MIN_HEIGHT}
aria-valuemax={LEFT_BRANCH_PANEL_MAX_HEIGHT}
tabindex="0"
onpointerdown={startLeftBranchPanelResize}
onpointermove={onLeftBranchPanelResizeMove}
onpointerup={endLeftBranchPanelResize}
onpointercancel={endLeftBranchPanelResize}
onkeydown={onLeftBranchPanelResizeKeydown}
></div>
{:else}
<span class="left-panel-resize-placeholder" aria-hidden="true"></span>
{/if}
<StashPanel
{stashes}
changedCount={changedFiles.length}
@@ -3261,7 +3612,31 @@
onApply={applyStashEntry}
onPop={popStashEntry}
onDrop={dropStashEntry}
collapsed={stashPanelCollapsed}
onToggleCollapsed={toggleStashPanelCollapsed}
/>
{#if !explorerPanelCollapsed && (!stashPanelCollapsed || !branchPanelCollapsed)}
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
<div
class="panel-resize-handle left-panel-resize-handle stash-panel-resize-handle"
class:resizing={resizingLeftStashPanel}
role="separator"
aria-orientation="horizontal"
aria-label={stashPanelCollapsed ? "Resize files panel space" : "Resize stash and explorer panels"}
aria-valuenow={stashPanelCollapsed ? leftBranchPanelHeight : leftStashPanelHeight}
aria-valuemin={stashPanelCollapsed ? LEFT_BRANCH_PANEL_MIN_HEIGHT : LEFT_STASH_PANEL_MIN_HEIGHT}
aria-valuemax={stashPanelCollapsed ? LEFT_BRANCH_PANEL_MAX_HEIGHT : LEFT_STASH_PANEL_MAX_HEIGHT}
tabindex="0"
onpointerdown={startLeftStashPanelResize}
onpointermove={onLeftStashPanelResizeMove}
onpointerup={endLeftStashPanelResize}
onpointercancel={endLeftStashPanelResize}
onkeydown={onLeftStashPanelResizeKeydown}
></div>
{:else}
<span class="left-panel-resize-placeholder" aria-hidden="true"></span>
{/if}
<ExplorerPanel
{repoFiles}
{expandedExplorerPaths}
@@ -3275,8 +3650,28 @@
onSelectNode={selectExplorerNode}
onOpenFile={openFileFromExplorer}
onBlame={openBlame}
collapsed={explorerPanelCollapsed}
onToggleCollapsed={toggleExplorerPanelCollapsed}
/>
</aside>
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
<div
class="left-sidebar-resize-handle"
class:resizing={resizingLeftSidebar}
role="separator"
aria-orientation="vertical"
aria-label="Resize navigation sidebar width"
aria-valuenow={leftSidebarWidth}
aria-valuemin={LEFT_SIDEBAR_MIN_WIDTH}
aria-valuemax={LEFT_SIDEBAR_MAX_WIDTH}
tabindex="0"
onpointerdown={startLeftSidebarResize}
onpointermove={onLeftSidebarResizeMove}
onpointerup={endLeftSidebarResize}
onpointercancel={endLeftSidebarResize}
onkeydown={onLeftSidebarResizeKeydown}
></div>
<!-- Center: summary + status + commit -->
<section class="main-panel" aria-label="Repository status">
@@ -3353,26 +3748,27 @@
</div>
</section>
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
<div
class="history-resize-handle"
class:resizing={resizingHistoryAside}
role="separator"
aria-orientation="vertical"
aria-label="Resize commit history width"
aria-valuenow={historyAsideWidth}
aria-valuemin={HISTORY_ASIDE_MIN_WIDTH}
aria-valuemax={HISTORY_ASIDE_MAX_WIDTH}
tabindex="0"
onpointerdown={startHistoryAsideResize}
onpointermove={onHistoryAsideResizeMove}
onpointerup={endHistoryAsideResize}
onpointercancel={endHistoryAsideResize}
onkeydown={onHistoryAsideResizeKeydown}
></div>
<!-- Right sidebar: commit graph + file history -->
<aside class="history-aside" aria-label="Commit history">
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
<div
class="history-resize-handle"
class:resizing={resizingHistoryAside}
role="separator"
aria-orientation="vertical"
aria-label="Resize history panel width"
aria-valuenow={historyAsideWidth}
aria-valuemin={HISTORY_ASIDE_MIN_WIDTH}
aria-valuemax={HISTORY_ASIDE_MAX_WIDTH}
tabindex="0"
onpointerdown={startHistoryAsideResize}
onpointermove={onHistoryAsideResizeMove}
onpointerup={endHistoryAsideResize}
onpointercancel={endHistoryAsideResize}
onkeydown={onHistoryAsideResizeKeydown}
></div>
<aside class="history-aside" class:file-history-collapsed={fileHistoryCollapsed} aria-label="Commit history">
<HistoryPanel
{commits}
{localBranchNames}
@@ -3392,6 +3788,24 @@
expandedCommitHashes = next;
}}
/>
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
<div
class="file-history-resize-handle"
class:resizing={resizingFileHistory}
role="separator"
aria-orientation="vertical"
aria-label="Resize file history width"
aria-valuenow={fileHistoryWidth}
aria-valuemin={FILE_HISTORY_MIN_WIDTH}
aria-valuemax={FILE_HISTORY_MAX_WIDTH}
tabindex={fileHistoryCollapsed ? -1 : 0}
onpointerdown={startFileHistoryResize}
onpointermove={onFileHistoryResizeMove}
onpointerup={endFileHistoryResize}
onpointercancel={endFileHistoryResize}
onkeydown={onFileHistoryResizeKeydown}
></div>
<FileHistoryPanel
{fileHistory}
{selectedExplorerPath}
@@ -3401,6 +3815,8 @@
isLoading={fileHistoryLoading}
onDiff={diffSelectedFileFromCommit}
onRestore={restoreSelectedFileFromCommit}
collapsed={fileHistoryCollapsed}
onToggleCollapsed={toggleFileHistoryCollapsed}
/>
</aside>
</section>