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`
|
return html`
|
||||||
<section>
|
<section>
|
||||||
<h2>${this.renderHeading()}</h2>
|
<h2>${this.renderHeading()}</h2>
|
||||||
${this.collapsed ? null : this.projects.map((project) => html`
|
${this.collapsed ? null : html`
|
||||||
<div
|
<div class="list-body">
|
||||||
class=${`action-row ${this.selected?.id === project.id ? "selected" : ""}`}
|
${this.projects.map((project) => html`
|
||||||
tabindex="0"
|
<div
|
||||||
title=${project.path}
|
class=${`action-row ${this.selected?.id === project.id ? "selected" : ""}`}
|
||||||
@click=${(event: MouseEvent) => { activateSelectableRow(event, () => this.onSelect?.(project)); }}
|
tabindex="0"
|
||||||
@keydown=${(event: KeyboardEvent) => { activateSelectableRowFromKeyboard(event, () => this.onSelect?.(project)); }}
|
title=${project.path}
|
||||||
>
|
@click=${(event: MouseEvent) => { activateSelectableRow(event, () => this.onSelect?.(project)); }}
|
||||||
<div class="action-main">
|
@keydown=${(event: KeyboardEvent) => { activateSelectableRowFromKeyboard(event, () => this.onSelect?.(project)); }}
|
||||||
<span class="action-name">${project.name}</span><small>${this.renderActivity(project)}${project.path}</small>
|
>
|
||||||
</div>
|
<div class="action-main">
|
||||||
<div class="action-menu">
|
<span class="action-name">${project.name}</span><small>${this.renderActivity(project)}${project.path}</small>
|
||||||
<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>
|
</div>
|
||||||
` : null}
|
<div class="action-menu">
|
||||||
</div>
|
<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>
|
</div>
|
||||||
`)}
|
`}
|
||||||
</section>
|
</section>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,11 +76,15 @@ export class SessionList extends LitElement {
|
|||||||
return html`
|
return html`
|
||||||
<section>
|
<section>
|
||||||
${this.renderHeading(activeRows.length + archivedRows.length)}
|
${this.renderHeading(activeRows.length + archivedRows.length)}
|
||||||
${this.collapsed ? null : activeRows.map((row) => this.renderSession(row, descendantCounts.get(row.session.id) ?? 0))}
|
${this.collapsed ? null : html`
|
||||||
${this.collapsed ? null : archivedRows.length > 0 ? html`
|
<div class="list-body">
|
||||||
<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>
|
${activeRows.map((row) => this.renderSession(row, descendantCounts.get(row.session.id) ?? 0))}
|
||||||
${this.archivedExpanded ? archivedRows.map((row) => this.renderSession(row, descendantCounts.get(row.session.id) ?? 0)) : null}
|
${archivedRows.length > 0 ? html`
|
||||||
` : null}
|
<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>
|
</section>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,24 +49,28 @@ export class WorkspaceList extends LitElement {
|
|||||||
return html`
|
return html`
|
||||||
<section>
|
<section>
|
||||||
<h2>${this.renderHeading()}</h2>
|
<h2>${this.renderHeading()}</h2>
|
||||||
${this.collapsed ? null : this.workspaces.map((workspace) => {
|
${this.collapsed ? null : html`
|
||||||
const label = workspacePrimaryLabel(workspace);
|
<div class="list-body">
|
||||||
const items = this.workspaceLabelItems(workspace);
|
${this.workspaces.map((workspace) => {
|
||||||
return html`
|
const label = workspacePrimaryLabel(workspace);
|
||||||
<div
|
const items = this.workspaceLabelItems(workspace);
|
||||||
class=${`action-row workspace-row ${this.selected?.id === workspace.id ? "selected" : ""}`}
|
return html`
|
||||||
tabindex="0"
|
<div
|
||||||
title=${label}
|
class=${`action-row workspace-row ${this.selected?.id === workspace.id ? "selected" : ""}`}
|
||||||
@click=${(event: MouseEvent) => { activateSelectableRow(event, () => this.onSelect?.(workspace)); }}
|
tabindex="0"
|
||||||
@keydown=${(event: KeyboardEvent) => { this.handleWorkspaceKeydown(event, workspace); }}
|
title=${label}
|
||||||
>
|
@click=${(event: MouseEvent) => { activateSelectableRow(event, () => this.onSelect?.(workspace)); }}
|
||||||
<div class="action-main">
|
@keydown=${(event: KeyboardEvent) => { this.handleWorkspaceKeydown(event, workspace); }}
|
||||||
${this.renderWorkspaceMain(label, items, workspace)}
|
>
|
||||||
</div>
|
<div class="action-main">
|
||||||
${this.renderWorkspaceMenu(label, items, workspace)}
|
${this.renderWorkspaceMain(label, items, workspace)}
|
||||||
</div>
|
</div>
|
||||||
`;
|
${this.renderWorkspaceMenu(label, items, workspace)}
|
||||||
})}
|
</div>
|
||||||
|
`;
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
`}
|
||||||
</section>
|
</section>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,8 +55,8 @@ export const appStyles = css`
|
|||||||
aside { grid-column: 1; display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
|
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 { 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; }
|
.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); }
|
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: auto; }
|
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; }
|
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 { 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; }
|
.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 { 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 project-list,
|
||||||
main.navigation-view .mobile-navigation-panel workspace-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 project-list[collapsed],
|
||||||
main.navigation-view .mobile-navigation-panel workspace-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; }
|
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`
|
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; }
|
:host([collapsed]) { flex: 0 0 auto; min-height: auto; overflow: hidden; }
|
||||||
section { padding: 10px; }
|
section { box-sizing: border-box; flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; 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; }
|
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; }
|
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; }
|
section > button { display: block; width: 100%; text-align: left; margin: 6px 0; }
|
||||||
.subheading { margin-top: 14px; }
|
.subheading { margin-top: 14px; }
|
||||||
|
|||||||
Reference in New Issue
Block a user