Archived
fix: keep navigation headings visible
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@jmfederico/pi-web": patch
|
||||
---
|
||||
|
||||
Keep left navigation section titles visible while project, workspace, and session lists scroll.
|
||||
@@ -44,27 +44,31 @@ export class ProjectList extends LitElement {
|
||||
return html`
|
||||
<section>
|
||||
<h2>${this.renderHeading()}</h2>
|
||||
${this.collapsed ? null : this.projects.map((project) => html`
|
||||
<div
|
||||
class=${`action-row ${this.selected?.id === project.id ? "selected" : ""}`}
|
||||
tabindex="0"
|
||||
title=${project.path}
|
||||
@click=${(event: MouseEvent) => { activateSelectableRow(event, () => this.onSelect?.(project)); }}
|
||||
@keydown=${(event: KeyboardEvent) => { activateSelectableRowFromKeyboard(event, () => this.onSelect?.(project)); }}
|
||||
>
|
||||
<div class="action-main">
|
||||
<span class="action-name">${project.name}</span><small>${this.renderActivity(project)}${project.path}</small>
|
||||
</div>
|
||||
<div class="action-menu">
|
||||
<button class="action-menu-toggle" title="Project actions" aria-label=${`Actions for ${project.name}`} @click=${(event: MouseEvent) => { event.stopPropagation(); this.toggleMenu(project.id, event.currentTarget); }}>⋯</button>
|
||||
${this.openMenuProjectId === project.id ? html`
|
||||
<div class="action-menu-panel" style=${this.menuStyle}>
|
||||
<button title="Close project" @click=${() => { this.close(project); }}>Close</button>
|
||||
${this.collapsed ? null : html`
|
||||
<div class="list-body">
|
||||
${this.projects.map((project) => html`
|
||||
<div
|
||||
class=${`action-row ${this.selected?.id === project.id ? "selected" : ""}`}
|
||||
tabindex="0"
|
||||
title=${project.path}
|
||||
@click=${(event: MouseEvent) => { activateSelectableRow(event, () => this.onSelect?.(project)); }}
|
||||
@keydown=${(event: KeyboardEvent) => { activateSelectableRowFromKeyboard(event, () => this.onSelect?.(project)); }}
|
||||
>
|
||||
<div class="action-main">
|
||||
<span class="action-name">${project.name}</span><small>${this.renderActivity(project)}${project.path}</small>
|
||||
</div>
|
||||
` : null}
|
||||
</div>
|
||||
<div class="action-menu">
|
||||
<button class="action-menu-toggle" title="Project actions" aria-label=${`Actions for ${project.name}`} @click=${(event: MouseEvent) => { event.stopPropagation(); this.toggleMenu(project.id, event.currentTarget); }}>⋯</button>
|
||||
${this.openMenuProjectId === project.id ? html`
|
||||
<div class="action-menu-panel" style=${this.menuStyle}>
|
||||
<button title="Close project" @click=${() => { this.close(project); }}>Close</button>
|
||||
</div>
|
||||
` : null}
|
||||
</div>
|
||||
</div>
|
||||
`)}
|
||||
</div>
|
||||
`)}
|
||||
`}
|
||||
</section>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -76,11 +76,15 @@ export class SessionList extends LitElement {
|
||||
return html`
|
||||
<section>
|
||||
${this.renderHeading(activeRows.length + archivedRows.length)}
|
||||
${this.collapsed ? null : activeRows.map((row) => this.renderSession(row, descendantCounts.get(row.session.id) ?? 0))}
|
||||
${this.collapsed ? null : archivedRows.length > 0 ? html`
|
||||
<h2 class="subheading"><button class="section-toggle" aria-expanded=${String(this.archivedExpanded)} @click=${() => { this.toggleArchived(); }}><span>${this.archivedExpanded ? "▾" : "▸"} Archived</span><small>${archivedRows.length}</small></button></h2>
|
||||
${this.archivedExpanded ? archivedRows.map((row) => this.renderSession(row, descendantCounts.get(row.session.id) ?? 0)) : null}
|
||||
` : null}
|
||||
${this.collapsed ? null : html`
|
||||
<div class="list-body">
|
||||
${activeRows.map((row) => this.renderSession(row, descendantCounts.get(row.session.id) ?? 0))}
|
||||
${archivedRows.length > 0 ? html`
|
||||
<h2 class="subheading"><button class="section-toggle" aria-expanded=${String(this.archivedExpanded)} @click=${() => { this.toggleArchived(); }}><span>${this.archivedExpanded ? "▾" : "▸"} Archived</span><small>${archivedRows.length}</small></button></h2>
|
||||
${this.archivedExpanded ? archivedRows.map((row) => this.renderSession(row, descendantCounts.get(row.session.id) ?? 0)) : null}
|
||||
` : null}
|
||||
</div>
|
||||
`}
|
||||
</section>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -49,24 +49,28 @@ export class WorkspaceList extends LitElement {
|
||||
return html`
|
||||
<section>
|
||||
<h2>${this.renderHeading()}</h2>
|
||||
${this.collapsed ? null : this.workspaces.map((workspace) => {
|
||||
const label = workspacePrimaryLabel(workspace);
|
||||
const items = this.workspaceLabelItems(workspace);
|
||||
return html`
|
||||
<div
|
||||
class=${`action-row workspace-row ${this.selected?.id === workspace.id ? "selected" : ""}`}
|
||||
tabindex="0"
|
||||
title=${label}
|
||||
@click=${(event: MouseEvent) => { activateSelectableRow(event, () => this.onSelect?.(workspace)); }}
|
||||
@keydown=${(event: KeyboardEvent) => { this.handleWorkspaceKeydown(event, workspace); }}
|
||||
>
|
||||
<div class="action-main">
|
||||
${this.renderWorkspaceMain(label, items, workspace)}
|
||||
</div>
|
||||
${this.renderWorkspaceMenu(label, items, workspace)}
|
||||
</div>
|
||||
`;
|
||||
})}
|
||||
${this.collapsed ? null : html`
|
||||
<div class="list-body">
|
||||
${this.workspaces.map((workspace) => {
|
||||
const label = workspacePrimaryLabel(workspace);
|
||||
const items = this.workspaceLabelItems(workspace);
|
||||
return html`
|
||||
<div
|
||||
class=${`action-row workspace-row ${this.selected?.id === workspace.id ? "selected" : ""}`}
|
||||
tabindex="0"
|
||||
title=${label}
|
||||
@click=${(event: MouseEvent) => { activateSelectableRow(event, () => this.onSelect?.(workspace)); }}
|
||||
@keydown=${(event: KeyboardEvent) => { this.handleWorkspaceKeydown(event, workspace); }}
|
||||
>
|
||||
<div class="action-main">
|
||||
${this.renderWorkspaceMain(label, items, workspace)}
|
||||
</div>
|
||||
${this.renderWorkspaceMenu(label, items, workspace)}
|
||||
</div>
|
||||
`;
|
||||
})}
|
||||
</div>
|
||||
`}
|
||||
</section>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -55,8 +55,8 @@ export const appStyles = css`
|
||||
aside { grid-column: 1; display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
|
||||
header { flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 12px; border-bottom: 1px solid var(--pi-border); }
|
||||
.header-actions { display: flex; align-items: center; gap: 8px; }
|
||||
project-list, workspace-list { flex: 0 0 auto; max-height: 26%; overflow: auto; border-bottom: 1px solid var(--pi-border-muted); }
|
||||
session-list { flex: 1 1 auto; min-height: 0; overflow: auto; }
|
||||
project-list, workspace-list { flex: 0 0 auto; max-height: 26%; min-height: 0; overflow: hidden; border-bottom: 1px solid var(--pi-border-muted); }
|
||||
session-list { flex: 1 1 auto; min-height: 0; overflow: hidden; }
|
||||
main { grid-column: 3; display: flex; flex-direction: column; min-width: 0; min-height: 0; }
|
||||
.context-bar { position: relative; flex: 0 0 auto; min-width: 0; display: none; align-items: center; gap: 0; padding: 6px 0; border-bottom: 1px solid var(--pi-border-muted); background: var(--pi-bg); }
|
||||
.context-bar::before, .context-bar::after { content: ""; position: absolute; top: 0; bottom: 0; z-index: 2; width: 20px; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
|
||||
@@ -135,7 +135,7 @@ export const appStyles = css`
|
||||
main.navigation-view .mobile-navigation-panel { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
|
||||
main.navigation-view .mobile-navigation-panel project-list,
|
||||
main.navigation-view .mobile-navigation-panel workspace-list,
|
||||
main.navigation-view .mobile-navigation-panel session-list { flex: 1 1 auto; max-height: none; min-height: 0; overflow: auto; }
|
||||
main.navigation-view .mobile-navigation-panel session-list { flex: 1 1 auto; max-height: none; min-height: 0; overflow: hidden; }
|
||||
main.navigation-view .mobile-navigation-panel project-list[collapsed],
|
||||
main.navigation-view .mobile-navigation-panel workspace-list[collapsed],
|
||||
main.navigation-view .mobile-navigation-panel session-list[collapsed] { flex: 0 0 auto; min-height: auto; overflow: hidden; }
|
||||
@@ -201,10 +201,11 @@ export const workspacePanelStyles = css`
|
||||
`;
|
||||
|
||||
export const listStyles = css`
|
||||
:host { display: block; color: var(--pi-text); font: 14px system-ui, sans-serif; }
|
||||
:host { display: flex; flex-direction: column; min-height: 0; overflow: hidden; color: var(--pi-text); font: 14px system-ui, sans-serif; }
|
||||
:host([collapsed]) { flex: 0 0 auto; min-height: auto; overflow: hidden; }
|
||||
section { padding: 10px; }
|
||||
h2 { display: flex; justify-content: space-between; align-items: center; gap: 8px; margin: 0 0 8px; color: var(--pi-muted); font-size: 12px; text-transform: uppercase; }
|
||||
section { box-sizing: border-box; flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; padding: 10px; }
|
||||
h2 { flex: 0 0 auto; display: flex; justify-content: space-between; align-items: center; gap: 8px; margin: 0 0 8px; color: var(--pi-muted); font-size: 12px; text-transform: uppercase; }
|
||||
.list-body { flex: 1 1 auto; min-height: 0; overflow: auto; }
|
||||
button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; cursor: pointer; }
|
||||
section > button { display: block; width: 100%; text-align: left; margin: 6px 0; }
|
||||
.subheading { margin-top: 14px; }
|
||||
|
||||
Reference in New Issue
Block a user