feat(editor): resizable outline panel (#161)

Add a drag handle to resize the outline panel and persist its width in
vault state (outline_width). Outline text now scales with the editor
font size.

Reviewed-on: https://codeberg.org/ArkHost/HelixNotes/pulls/161
This commit is contained in:
mf
2026-06-24 21:01:43 +02:00
committed by ArkHost
parent 16805c96aa
commit f98b3415bc
5 changed files with 26 additions and 4 deletions
+4
View File
@@ -14,6 +14,7 @@
import {
sidebarWidth,
notelistWidth,
outlineWidth,
sidebarCollapsed,
notelistCollapsed,
collapsedNotebooks,
@@ -201,6 +202,7 @@
last_open_note: $activeNotePath,
sidebar_width: $sidebarWidth,
notelist_width: $notelistWidth,
outline_width: $outlineWidth,
sidebar_collapsed: $sidebarCollapsed,
notelist_collapsed: $notelistCollapsed,
collapsed_notebooks: $collapsedNotebooks,
@@ -534,6 +536,7 @@
$effect(() => {
$sidebarCollapsed;
$notelistCollapsed;
$outlineWidth;
persistState();
});
@@ -573,6 +576,7 @@
const state = await loadVaultState();
$sidebarWidth = state.sidebar_width;
$notelistWidth = state.notelist_width;
if (typeof state.outline_width === 'number') $outlineWidth = state.outline_width;
$sidebarCollapsed = state.sidebar_collapsed;
$notelistCollapsed = state.notelist_collapsed ?? false;
$collapsedNotebooks = state.collapsed_notebooks ?? [];
+10 -4
View File
@@ -39,7 +39,7 @@
import { readFile } from '@tauri-apps/plugin-fs';
import { openFile, openUrl, copyFileTo, copyImageToClipboard as copyImageToClipboardCmd, writeBytesTo, copyPngToClipboard } from '$lib/api';
import { save as saveDialog } from '@tauri-apps/plugin-dialog';
import { activeNote, activeNotePath, appConfig, editorDirty, sourceMode, focusMode, readOnly, quickAccessPaths, notes, navHistory, canGoBack, canGoForward, viewerNote, notebooks } from '$lib/stores/app';
import { activeNote, activeNotePath, appConfig, editorDirty, sourceMode, focusMode, readOnly, quickAccessPaths, notes, navHistory, canGoBack, canGoForward, viewerNote, notebooks, outlineWidth } from '$lib/stores/app';
import { saveNote, saveImage, saveAttachment, readClipboardImage, addQuickAccess, removeQuickAccess, getQuickAccess, getNoteVersions, getNoteVersionContent, createVersion, aiAsk, getAllNoteTitles, readNote, renameNote } from '$lib/api';
import type { VersionEntry, AiStreamEvent, NoteTitleEntry } from '$lib/types';
import { listen } from '@tauri-apps/api/event';
@@ -50,6 +50,7 @@
import GraphView from './GraphView.svelte';
import TagSuggestInput from './TagSuggestInput.svelte';
import { isMobile, isAndroid } from '$lib/platform';
import ResizeHandle from './ResizeHandle.svelte';
const modKey = navigator.platform.startsWith('Mac') ? '⌘' : 'Ctrl';
@@ -178,6 +179,10 @@
outlineHeadings = headings;
}
function handleOutlineResize(delta: number) {
$outlineWidth = Math.max(160, Math.min(500, $outlineWidth - delta));
}
function scrollToHeading(pos: number) {
if (!editor) return;
editor.commands.setTextSelection(pos + 1);
@@ -5502,7 +5507,8 @@
</div>
{/if}
{#if showOutline}
<div class="outline-panel">
<ResizeHandle onResize={handleOutlineResize} />
<div class="outline-panel" style="width: {$outlineWidth}px">
<div class="outline-header">
<h3>Outline</h3>
<button class="outline-close" onclick={() => { showOutline = false; }}>
@@ -7475,7 +7481,7 @@
.outline-empty {
padding: 16px 14px;
font-size: 12px;
font-size: var(--editor-font-size, 14px);
color: var(--text-tertiary);
line-height: 1.5;
}
@@ -7493,7 +7499,7 @@
background: none;
border: none;
padding: 4px 14px;
font-size: 12px;
font-size: var(--editor-font-size, 14px);
color: var(--text-secondary);
cursor: pointer;
white-space: nowrap;
+4
View File
@@ -26,6 +26,7 @@ export const sidebarCollapsed = writable(false);
export const notelistCollapsed = writable(false);
export const sidebarWidth = writable(220);
export const notelistWidth = writable(280);
export const outlineWidth = writable(220);
export const searchQuery = writable("");
export const showCommandPalette = writable(false);
export const showSearch = writable(false);
@@ -227,6 +228,7 @@ export const vaultState = derived(
activeNotePath,
sidebarWidth,
notelistWidth,
outlineWidth,
sidebarCollapsed,
notelistCollapsed,
collapsedNotebooks,
@@ -238,6 +240,7 @@ export const vaultState = derived(
$activeNotePath,
$sidebarWidth,
$notelistWidth,
$outlineWidth,
$sidebarCollapsed,
$notelistCollapsed,
$collapsedNotebooks,
@@ -249,6 +252,7 @@ export const vaultState = derived(
last_open_note: $activeNotePath,
sidebar_width: $sidebarWidth,
notelist_width: $notelistWidth,
outline_width: $outlineWidth,
sidebar_collapsed: $sidebarCollapsed,
notelist_collapsed: $notelistCollapsed,
collapsed_notebooks: $collapsedNotebooks,
+1
View File
@@ -129,6 +129,7 @@ export interface VaultState {
last_open_note: string | null;
sidebar_width: number;
notelist_width: number;
outline_width?: number;
sidebar_collapsed: boolean;
notelist_collapsed: boolean;
collapsed_notebooks: string[];