diff --git a/frontend/app.js b/frontend/app.js index ed9e767..8cebaa3 100644 --- a/frontend/app.js +++ b/frontend/app.js @@ -368,7 +368,7 @@ const currentTop = scrollContainer.scrollTop; const offsetTop = element.offsetTop; const targetTop = alignToTop - ? Math.max(0, offsetTop - 8) + ? Math.max(0, offsetTop - 60) : Math.max(0, currentTop + (elementRect.top - containerRect.top) - (containerRect.height * 0.35)); scrollContainer.scrollTo({ @@ -502,6 +502,8 @@ } if (!targetPath) { + // Clear any previous path selection + document.querySelectorAll(".tree-item.path-selected").forEach((el) => el.classList.remove("path-selected")); scrollTreeItemIntoView(vaultItem, options && options.alignToTop); return; } @@ -509,6 +511,7 @@ const segments = targetPath.split("/").filter(Boolean); let currentContainer = vaultContainer; let cumulativePath = ""; + let lastTargetItem = null; for (let index = 0; index < segments.length; index++) { cumulativePath += (cumulativePath ? "/" : "") + segments[index]; @@ -524,6 +527,8 @@ return; } + lastTargetItem = targetItem; + const isLastSegment = index === segments.length - 1; if (!isLastSegment) { const nextContainer = document.getElementById(`dir-${vaultName}-${cumulativePath}`); @@ -535,9 +540,15 @@ currentContainer = nextContainer; } } - - scrollTreeItemIntoView(targetItem, Boolean(options && options.alignToTop && isLastSegment)); } + + // Clear previous path selections and highlight the final target + document.querySelectorAll(".tree-item.path-selected").forEach((el) => el.classList.remove("path-selected")); + if (lastTargetItem) { + lastTargetItem.classList.add("path-selected"); + } + + scrollTreeItemIntoView(lastTargetItem, options && options.alignToTop); } async function loadDirectory(vaultName, dirPath, container) { diff --git a/frontend/style.css b/frontend/style.css index acd4119..b0ec2ab 100644 --- a/frontend/style.css +++ b/frontend/style.css @@ -637,6 +637,17 @@ select { color: var(--text-primary); box-shadow: inset 2px 0 0 var(--accent); } +.tree-item.path-selected { + background: color-mix(in srgb, var(--accent) 20%, transparent); + color: var(--accent); + box-shadow: inset 0 0 0 2px var(--accent), inset 2px 0 0 var(--accent); + border-radius: 6px; + animation: pathPulse 1.5s ease-out; +} +@keyframes pathPulse { + 0% { background: color-mix(in srgb, var(--accent) 40%, transparent); } + 100% { background: color-mix(in srgb, var(--accent) 20%, transparent); } +} .tree-item.filtered-out { display: none; } @@ -1758,7 +1769,6 @@ body.resizing-v { #vault-panel-content { max-height: none; } - #tag-panel-content { max-height: none; }