feat(ui): resizable/hideable meetings-list and summary panes

Left (meetings list) and right (summary) panes gain drag-to-resize via
Splitter and a collapse/expand toggle (thin rail + panel icon), sizes
and collapsed state persisted via the layout store.
This commit is contained in:
iamdoubz committed 2026-07-11 00:12:44 -05:00
1 parent 2a637e78ad
commit e3c80b565c
1 file changed
+132 -10
+132 -10
View File
@@ -14,7 +14,19 @@
import { api, type NoteTemplate } from "./lib/api";
import { onMount } from "svelte";
import ThemeToggle from "./lib/components/ThemeToggle.svelte";
import { Circle, Square, Trash2, Settings as SettingsIcon, AlertTriangle } from "@lucide/svelte";
import Splitter from "./lib/components/Splitter.svelte";
import { layout, clamp } from "./lib/stores/layout.svelte";
import {
Circle,
Square,
Trash2,
Settings as SettingsIcon,
AlertTriangle,
PanelLeftClose,
PanelLeftOpen,
PanelRightClose,
PanelRightOpen,
} from "@lucide/svelte";
let showSettings = $state(false);
let showConsent = $state(false);
@@ -291,10 +303,89 @@
</div>
{/if}
<main class="panes">
<aside class="left"><MeetingsList /></aside>
<main
class="panes"
style="grid-template-columns: {layout.leftCollapsed
? 'auto'
: layout.leftWidth + 'px'} auto 1fr auto {layout.rightCollapsed
? 'auto'
: layout.rightWidth + 'px'};"
>
<aside class="side left" class:collapsed={layout.leftCollapsed}>
{#if layout.leftCollapsed}
<button
class="pane-toggle"
onclick={() => {
layout.leftCollapsed = false;
layout.persist();
}}
title="Show meetings list"
aria-label="Show meetings list"
>
<PanelLeftOpen size={16} aria-hidden="true" />
</button>
{:else}
<button
class="pane-toggle inline"
onclick={() => {
layout.leftCollapsed = true;
layout.persist();
}}
title="Hide meetings list"
aria-label="Hide meetings list"
>
<PanelLeftClose size={14} aria-hidden="true" />
</button>
<div class="side-content"><MeetingsList /></div>
{/if}
</aside>
{#if !layout.leftCollapsed}
<Splitter
label="Resize meetings list"
onResize={(d) => (layout.leftWidth = clamp(layout.leftWidth + d, 200, 480))}
onResizeEnd={() => layout.persist()}
/>
{:else}
<span></span>
{/if}
<section class="center"><TranscriptNotes /></section>
<aside class="right"><SummaryPanel /></aside>
{#if !layout.rightCollapsed}
<Splitter
label="Resize summary panel"
onResize={(d) => (layout.rightWidth = clamp(layout.rightWidth - d, 240, 560))}
onResizeEnd={() => layout.persist()}
/>
{:else}
<span></span>
{/if}
<aside class="side right" class:collapsed={layout.rightCollapsed}>
{#if layout.rightCollapsed}
<button
class="pane-toggle"
onclick={() => {
layout.rightCollapsed = false;
layout.persist();
}}
title="Show summary panel"
aria-label="Show summary panel"
>
<PanelRightOpen size={16} aria-hidden="true" />
</button>
{:else}
<button
class="pane-toggle inline"
onclick={() => {
layout.rightCollapsed = true;
layout.persist();
}}
title="Hide summary panel"
aria-label="Hide summary panel"
>
<PanelRightClose size={14} aria-hidden="true" />
</button>
<div class="side-content"><SummaryPanel /></div>
{/if}
</aside>
</main>
</div>
@@ -592,25 +683,56 @@
}
.panes {
display: grid;
grid-template-columns: 260px 1fr 320px;
/* grid-template-columns set inline — depends on collapse/resize state (FR-UX-1). */
flex: 1;
min-height: 0;
}
.left,
.right {
.side {
display: flex;
flex-direction: column;
min-height: 0;
border-color: var(--border);
overflow: auto;
background: var(--bg-subtle);
}
.left {
.side.left {
border-right: 1px solid var(--border);
}
.right {
.side.right {
border-left: 1px solid var(--border);
}
.side.collapsed {
align-items: center;
padding-top: 0.4rem;
}
.side-content {
flex: 1;
min-height: 0;
overflow: auto;
}
.pane-toggle {
display: flex;
align-items: center;
justify-content: center;
flex: none;
background: none;
border: none;
color: var(--muted);
cursor: pointer;
padding: 0.4rem;
border-radius: var(--radius-sm);
}
.pane-toggle:hover {
background: var(--bg-hover);
color: var(--fg);
}
.pane-toggle.inline {
align-self: flex-end;
margin: 0.3rem 0.3rem 0;
}
.center {
overflow: auto;
background: var(--bg);
min-width: 0;
}
.vault-overlay {
position: fixed;