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:
1 parent
2a637e78ad
commit
e3c80b565c
1 file changed
+132
-10
+132
-10
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user