Add clickable breadcrumbs that focus and expand corresponding sidebar paths with vault panel auto-expansion and improved collapsed state styling
This commit is contained in:
parent
fe30703a0d
commit
05dc436cea
@ -369,6 +369,61 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function focusPathInSidebar(vaultName, targetPath, options) {
|
||||
setPanelExpanded("vault", true);
|
||||
|
||||
const vaultItem = document.querySelector(`.vault-item[data-vault="${CSS.escape(vaultName)}"]`);
|
||||
if (!vaultItem) return;
|
||||
|
||||
document.querySelectorAll(".vault-item.focused").forEach((el) => el.classList.remove("focused"));
|
||||
vaultItem.classList.add("focused");
|
||||
|
||||
const vaultContainer = document.getElementById(`vault-children-${vaultName}`);
|
||||
if (!vaultContainer) return;
|
||||
|
||||
if (vaultContainer.classList.contains("collapsed")) {
|
||||
await toggleVault(vaultItem, vaultName, true);
|
||||
}
|
||||
|
||||
if (!targetPath) {
|
||||
scrollTreeItemIntoView(vaultItem, options && options.alignToTop);
|
||||
return;
|
||||
}
|
||||
|
||||
const segments = targetPath.split("/").filter(Boolean);
|
||||
let currentContainer = vaultContainer;
|
||||
let cumulativePath = "";
|
||||
|
||||
for (let index = 0; index < segments.length; index++) {
|
||||
cumulativePath += (cumulativePath ? "/" : "") + segments[index];
|
||||
|
||||
let targetItem = null;
|
||||
try {
|
||||
targetItem = currentContainer.querySelector(`.tree-item[data-vault="${CSS.escape(vaultName)}"][data-path="${CSS.escape(cumulativePath)}"]`);
|
||||
} catch (e) {
|
||||
targetItem = null;
|
||||
}
|
||||
|
||||
if (!targetItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isLastSegment = index === segments.length - 1;
|
||||
if (!isLastSegment) {
|
||||
const nextContainer = document.getElementById(`dir-${vaultName}-${cumulativePath}`);
|
||||
if (nextContainer && nextContainer.classList.contains("collapsed")) {
|
||||
targetItem.click();
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
}
|
||||
if (nextContainer) {
|
||||
currentContainer = nextContainer;
|
||||
}
|
||||
}
|
||||
|
||||
scrollTreeItemIntoView(targetItem, Boolean(options && options.alignToTop && isLastSegment));
|
||||
}
|
||||
}
|
||||
|
||||
async function loadDirectory(vaultName, dirPath, container) {
|
||||
const url = `/api/browse/${encodeURIComponent(vaultName)}?path=${encodeURIComponent(dirPath)}`;
|
||||
const data = await api(url);
|
||||
@ -613,16 +668,22 @@
|
||||
// Breadcrumb
|
||||
const parts = data.path.split("/");
|
||||
const breadcrumbEls = [];
|
||||
breadcrumbEls.push(makeBreadcrumbSpan(data.vault, () => {}));
|
||||
breadcrumbEls.push(makeBreadcrumbSpan(data.vault, () => {
|
||||
focusPathInSidebar(data.vault, "", { alignToTop: true });
|
||||
}));
|
||||
let accumulated = "";
|
||||
parts.forEach((part, i) => {
|
||||
breadcrumbEls.push(el("span", { class: "sep" }, [document.createTextNode(" / ")]));
|
||||
accumulated += (accumulated ? "/" : "") + part;
|
||||
const p = accumulated;
|
||||
if (i < parts.length - 1) {
|
||||
breadcrumbEls.push(makeBreadcrumbSpan(part, () => {}));
|
||||
breadcrumbEls.push(makeBreadcrumbSpan(part, () => {
|
||||
focusPathInSidebar(data.vault, p, { alignToTop: true });
|
||||
}));
|
||||
} else {
|
||||
breadcrumbEls.push(el("span", {}, [document.createTextNode(part.replace(/\.md$/i, ""))]));
|
||||
breadcrumbEls.push(makeBreadcrumbSpan(part.replace(/\.md$/i, ""), () => {
|
||||
focusPathInSidebar(data.vault, data.path, { alignToTop: false });
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -318,6 +318,18 @@ a:hover {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
max-height: none;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.sidebar.vault-collapsed .sidebar-tree {
|
||||
flex: 0 0 auto;
|
||||
min-height: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.sidebar.vault-collapsed .tag-resize-handle {
|
||||
border-top: none;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.sidebar.tag-collapsed .sidebar-tree {
|
||||
@ -577,6 +589,10 @@ a:hover {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sidebar.vault-collapsed .tag-panel-toggle {
|
||||
border-top: 1px solid var(--border);
|
||||
}
|
||||
|
||||
/* --- Sidebar resize handle (horizontal) --- */
|
||||
.sidebar-resize-handle {
|
||||
width: 5px;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user