mirror of
https://github.com/ggml-org/llama.cpp.git
synced 2026-09-29 01:17:36 -05:00
ui : slide the configuration pane in as a fixed width drawer
The pane kept mounting and unmounting, so it popped into place and its content reflowed while the layout changed. It now stays in the DOM at zero width, its content box holds the open width, and the two fade with the drawer. Assisted-by: pi:llama.cpp/DeepSeek-V4.1-Flash
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
import type { ModelOption } from '$lib/types/models';
|
||||
import { getBackend } from '$lib/utils/api-base';
|
||||
import { getBackendCapabilities } from '$lib/utils/backend';
|
||||
import type { Snippet } from 'svelte';
|
||||
import { type Snippet, untrack } from 'svelte';
|
||||
import { SvelteMap, SvelteSet } from 'svelte/reactivity';
|
||||
import { toast } from 'svelte-sonner';
|
||||
|
||||
@@ -180,6 +180,24 @@
|
||||
return ordered;
|
||||
});
|
||||
let selected = $derived(allModels.find((option) => option.id === selectedId) ?? null);
|
||||
// the pane keeps a width of its own and stays in the DOM, so opening it slides a
|
||||
// fixed panel in rather than reflowing one into place. Each open remounts the
|
||||
// content, which is what reset the tabs when the pane used to unmount.
|
||||
let paneOption = $state<ModelOption | null>(null);
|
||||
let paneSession = $state(0);
|
||||
|
||||
$effect(() => {
|
||||
const id = selectedId;
|
||||
|
||||
if (!id) return;
|
||||
|
||||
// untracked: this effect writes the session counter, and reading it back here
|
||||
// would make the effect invalidate itself
|
||||
untrack(() => {
|
||||
paneOption = allModels.find((option) => option.id === id) ?? null;
|
||||
paneSession += 1;
|
||||
});
|
||||
});
|
||||
|
||||
// a caller can ask for one model to be revealed, the download rows do
|
||||
$effect(() => {
|
||||
@@ -234,17 +252,18 @@
|
||||
{#snippet toolbarEndRegion()}
|
||||
<!-- the pane takes the toolbar's width, so the calls to action leave with it -->
|
||||
<CollapsibleRegion axis="width" open={!selected}>
|
||||
<div class="flex items-center gap-2">
|
||||
<div
|
||||
class="flex items-center gap-2 transition-opacity duration-200 ease-[cubic-bezier(0.23,1,0.32,1)] {selected
|
||||
? 'opacity-0'
|
||||
: 'opacity-100'}"
|
||||
>
|
||||
{@render toolbarEnd?.()}
|
||||
</div>
|
||||
</CollapsibleRegion>
|
||||
{/snippet}
|
||||
|
||||
<div
|
||||
class={['grid min-h-0 flex-1', className]}
|
||||
style="grid-template-columns: minmax(0, 1fr){selected ? ' 30rem' : ''};"
|
||||
>
|
||||
<div class="min-h-0">
|
||||
<div class={['flex min-h-0 flex-1', className]}>
|
||||
<div class="min-h-0 min-w-0 flex-1">
|
||||
<ModelsManagerModelsTable
|
||||
bind:contextLimit
|
||||
bind:filter
|
||||
@@ -260,19 +279,31 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
{#if selected}
|
||||
<div class="min-h-0 overflow-hidden border-l border-border/40">
|
||||
{#key selected.id}
|
||||
<ModelsManagerModelConfiguration
|
||||
isCustomized={isCustomized(overrides[selected.id])}
|
||||
onClose={() => (selectedId = null)}
|
||||
onSave={(override) => saveOverride(selected, override)}
|
||||
onToggleLoad={() => void toggleLoad(selected)}
|
||||
onUseInNewChat={() => void useInNewChat(selected)}
|
||||
option={selected}
|
||||
override={overrides[selected.id]}
|
||||
/>
|
||||
{/key}
|
||||
<div
|
||||
class="invisible w-0 shrink-0 overflow-clip transition-[width,visibility] duration-200 ease-[cubic-bezier(0.23,1,0.32,1)] data-[open=true]:visible data-[open=true]:w-[30rem]"
|
||||
data-open={selected !== null}
|
||||
>
|
||||
<!-- the content box keeps the open width, so it never reflows with the drawer -->
|
||||
<div
|
||||
class="flex h-full min-h-0 w-[30rem] max-w-[30rem] flex-col border-l border-border/40 transition-opacity duration-200 ease-[cubic-bezier(0.23,1,0.32,1)] {selected
|
||||
? 'opacity-100'
|
||||
: 'opacity-0'}"
|
||||
>
|
||||
{#if paneOption}
|
||||
{@const shown = paneOption}
|
||||
|
||||
{#key paneSession}
|
||||
<ModelsManagerModelConfiguration
|
||||
isCustomized={isCustomized(overrides[shown.id])}
|
||||
onClose={() => (selectedId = null)}
|
||||
onSave={(override) => saveOverride(shown, override)}
|
||||
onToggleLoad={() => void toggleLoad(shown)}
|
||||
onUseInNewChat={() => void useInNewChat(shown)}
|
||||
option={shown}
|
||||
override={overrides[shown.id]}
|
||||
/>
|
||||
{/key}
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user