Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a92202302a | ||
|
|
44c67fcee7 | ||
|
|
d8d26d181a | ||
|
|
aec7f4cae6 |
+26
-19
@@ -300,8 +300,8 @@ function renderEmpty(filtering: boolean, onSpawn: () => void): HTMLElement {
|
||||
|
||||
/**
|
||||
* The global app header (full width, above the sidebar/content split): brand +
|
||||
* the app-level actions (spawn, theme toggle). Kept out of the sidebar so these
|
||||
* stay put and reachable regardless of which pane is showing.
|
||||
* session tally. App-level actions (help, theme, spawn) live pinned to the
|
||||
* sidebar's foot instead — see {@link renderSidebar}.
|
||||
*/
|
||||
export function renderTopbar(store: CatalogStore, onToggleSidebar?: () => void): HTMLElement {
|
||||
const header = document.createElement("header");
|
||||
@@ -340,23 +340,6 @@ export function renderTopbar(store: CatalogStore, onToggleSidebar?: () => void):
|
||||
kit.title = "Open the design kit (DEV)";
|
||||
actions.appendChild(kit);
|
||||
}
|
||||
const helpBtn = document.createElement("button");
|
||||
helpBtn.type = "button";
|
||||
helpBtn.className = "btn btn-ghost btn-icon help-btn";
|
||||
helpBtn.textContent = "?";
|
||||
helpBtn.title = "Keyboard shortcuts (?)";
|
||||
helpBtn.setAttribute("aria-label", "Keyboard shortcuts");
|
||||
helpBtn.addEventListener("click", () => toggleHelp());
|
||||
actions.appendChild(helpBtn);
|
||||
actions.appendChild(createThemeToggle());
|
||||
const spawnBtn = document.createElement("button");
|
||||
spawnBtn.type = "button";
|
||||
spawnBtn.className = "btn btn-primary spawn-btn";
|
||||
spawnBtn.textContent = "+ Spawn";
|
||||
// The keyboard pair sits right here in the tooltip (#67).
|
||||
spawnBtn.title = "Draft pane: n — fast-forward spawn: N";
|
||||
spawnBtn.addEventListener("click", () => requestOpenSpawn());
|
||||
actions.appendChild(spawnBtn);
|
||||
return header;
|
||||
}
|
||||
|
||||
@@ -425,6 +408,30 @@ export function renderSidebar(store: CatalogStore, opts: SidebarOptions = {}): S
|
||||
treeHost.className = "tree";
|
||||
el.appendChild(treeHost);
|
||||
|
||||
// App-level actions (help, theme, spawn) live pinned to the sidebar's foot
|
||||
// rather than the sidebar's own scrolling content, so they stay reachable
|
||||
// regardless of tree scroll position.
|
||||
const footer = document.createElement("div");
|
||||
footer.className = "sidebar-footer";
|
||||
const helpBtn = document.createElement("button");
|
||||
helpBtn.type = "button";
|
||||
helpBtn.className = "btn btn-ghost btn-icon help-btn";
|
||||
helpBtn.textContent = "?";
|
||||
helpBtn.title = "Keyboard shortcuts (?)";
|
||||
helpBtn.setAttribute("aria-label", "Keyboard shortcuts");
|
||||
helpBtn.addEventListener("click", () => toggleHelp());
|
||||
footer.appendChild(helpBtn);
|
||||
footer.appendChild(createThemeToggle());
|
||||
const spawnBtn = document.createElement("button");
|
||||
spawnBtn.type = "button";
|
||||
spawnBtn.className = "btn btn-primary spawn-btn";
|
||||
spawnBtn.textContent = "+ Spawn";
|
||||
// The keyboard pair sits right here in the tooltip (#67).
|
||||
spawnBtn.title = "Draft pane: n — fast-forward spawn: N";
|
||||
spawnBtn.addEventListener("click", () => requestOpenSpawn());
|
||||
footer.appendChild(spawnBtn);
|
||||
el.appendChild(footer);
|
||||
|
||||
// Drag a session row into the canvas (issue #32). Delegated so it survives
|
||||
// tree re-renders; the controller handles drag-vs-tap (tap still navigates).
|
||||
treeHost.addEventListener("pointerdown", (e) => {
|
||||
|
||||
+19
-7
@@ -484,14 +484,27 @@ textarea {
|
||||
}
|
||||
}
|
||||
|
||||
/* Sidebar's own slim header: just the session search (app-level actions live
|
||||
in the global top bar). */
|
||||
/* Sidebar's own slim header: just the session search. */
|
||||
/* The search input IS the header — it spans edge to edge, flush, with just a
|
||||
bottom rule for separation. No wrapper padding, no boxed border/radius. */
|
||||
.sidebar-search {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
/* App-level actions (help, theme, spawn), pinned to the sidebar's foot. */
|
||||
.sidebar-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--sp-2);
|
||||
flex: 0 0 auto;
|
||||
padding: var(--sp-2) var(--sp-3);
|
||||
border-top: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.sidebar-footer .spawn-btn {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.sidebar-search .search {
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
@@ -761,7 +774,7 @@ textarea {
|
||||
|
||||
.tree-leaf:focus-visible {
|
||||
outline: none;
|
||||
box-shadow: inset 0 0 0 1px var(--accent-ring);
|
||||
background: color-mix(in oklab, var(--accent) 16%, var(--surface-2));
|
||||
}
|
||||
|
||||
/* Where the keyboard walk (j/k) is standing. Distinct from `.is-active`: this
|
||||
@@ -2353,10 +2366,9 @@ input.leaf-rename:focus {
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
}
|
||||
/* focused pane: accent ring, full strength */
|
||||
.mv-pane.is-focused {
|
||||
border-color: var(--accent);
|
||||
box-shadow: inset 0 0 0 1px var(--accent);
|
||||
/* focused pane: titlebar tints instead of a ring, full strength */
|
||||
.mv-pane.is-focused .attach-header {
|
||||
background: color-mix(in oklab, var(--accent) 14%, var(--surface));
|
||||
}
|
||||
/* unfocused panes recede so the eye finds the live one */
|
||||
.mv-pane:not(.is-focused) {
|
||||
|
||||
Reference in New Issue
Block a user