feat: WIP

This commit is contained in:
Aleksander Grygier 2026-04-01 14:14:13 +02:00
parent 7a13b4191a
commit ec6302960e
11 changed files with 160 additions and 104 deletions

View File

@ -35,7 +35,7 @@
{size} {size}
{disabled} {disabled}
{onclick} {onclick}
class="h-6 w-6 p-0 {className} flex" class="h-6 w-6 p-0 {className} flex hover:bg-transparent! data-[state=open]:bg-transparent!"
aria-label={ariaLabel || tooltip} aria-label={ariaLabel || tooltip}
> >
{@const IconComponent = icon} {@const IconComponent = icon}

View File

@ -7,10 +7,12 @@
Monitor, Monitor,
ChevronLeft, ChevronLeft,
ChevronRight, ChevronRight,
ListRestart ListRestart,
Sliders
} from '@lucide/svelte'; } from '@lucide/svelte';
import { ChatSettingsFooter, ChatSettingsFields } from '$lib/components/app'; import { ChatSettingsFooter, ChatSettingsFields } from '$lib/components/app';
import { ScrollArea } from '$lib/components/ui/scroll-area';
import { config, settingsStore } from '$lib/stores/settings.svelte'; import { config, settingsStore } from '$lib/stores/settings.svelte';
import { import {
SETTINGS_SECTION_TITLES, SETTINGS_SECTION_TITLES,
@ -40,7 +42,7 @@
}> = [ }> = [
{ {
title: SETTINGS_SECTION_TITLES.GENERAL, title: SETTINGS_SECTION_TITLES.GENERAL,
icon: Settings, icon: Sliders,
fields: [ fields: [
{ {
key: SETTINGS_KEYS.THEME, key: SETTINGS_KEYS.THEME,
@ -128,13 +130,18 @@
type: SettingsFieldType.CHECKBOX type: SettingsFieldType.CHECKBOX
}, },
{ {
key: SETTINGS_KEYS.AUTO_SHOW_SIDEBAR_ON_NEW_CHAT, key: SETTINGS_KEYS.SHOW_RAW_MODEL_NAMES,
label: 'Auto-show sidebar on new chat', label: 'Show raw model names',
type: SettingsFieldType.CHECKBOX type: SettingsFieldType.CHECKBOX
}, },
{ {
key: SETTINGS_KEYS.SHOW_RAW_MODEL_NAMES, key: SETTINGS_KEYS.ALWAYS_SHOW_AGENTIC_TURNS,
label: 'Show raw model names', label: 'Always show agentic turns in conversation',
type: SettingsFieldType.CHECKBOX
},
{
key: SETTINGS_KEYS.SHOW_TOOL_CALL_IN_PROGRESS,
label: 'Show tool call in progress',
type: SettingsFieldType.CHECKBOX type: SettingsFieldType.CHECKBOX
} }
] ]
@ -260,20 +267,10 @@
label: 'Agentic turns', label: 'Agentic turns',
type: SettingsFieldType.INPUT type: SettingsFieldType.INPUT
}, },
{
key: SETTINGS_KEYS.ALWAYS_SHOW_AGENTIC_TURNS,
label: 'Always show agentic turns in conversation',
type: SettingsFieldType.CHECKBOX
},
{ {
key: SETTINGS_KEYS.AGENTIC_MAX_TOOL_PREVIEW_LINES, key: SETTINGS_KEYS.AGENTIC_MAX_TOOL_PREVIEW_LINES,
label: 'Max lines per tool preview', label: 'Max lines per tool preview',
type: SettingsFieldType.INPUT type: SettingsFieldType.INPUT
},
{
key: SETTINGS_KEYS.SHOW_TOOL_CALL_IN_PROGRESS,
label: 'Show tool call in progress',
type: SettingsFieldType.CHECKBOX
} }
] ]
}, },
@ -433,17 +430,15 @@
</script> </script>
<div class="flex h-full flex-col {className} w-full"> <div class="flex h-full flex-col overflow-y-auto {className} w-full">
<div class="flex items-center gap-2 w-full md:absolute md:top-8"> <div class="flex flex-1 flex-col md:flex-row gap-4">
<Settings class="h-6 w-6" />
<h1 class="text-2xl font-semibold">Settings</h1>
</div>
<div class="flex flex-col overflow-hidden md:flex-row gap-4">
<!-- Desktop Sidebar --> <!-- Desktop Sidebar -->
<div class="hidden w-64 pt-8 mt-16 md:block"> <div class="hidden w-64 md:flex flex-col sticky top-0 self-start bg-background pt-8 pb-4">
<nav class="space-y-1 py-2"> <div class="flex items-center gap-2 pb-6">
<Settings class="h-6 w-6" />
<h1 class="text-2xl font-semibold">Settings</h1>
</div>
<nav class="space-y-1">
{#each settingSections as section (section.title)} {#each settingSections as section (section.title)}
<button <button
class="flex w-full cursor-pointer items-center gap-3 rounded-lg px-3 py-2 text-left text-sm transition-colors hover:bg-accent {activeSection === class="flex w-full cursor-pointer items-center gap-3 rounded-lg px-3 py-2 text-left text-sm transition-colors hover:bg-accent {activeSection ===
@ -461,8 +456,12 @@
</div> </div>
<!-- Mobile Header with Horizontal Scrollable Menu --> <!-- Mobile Header with Horizontal Scrollable Menu -->
<div class="flex flex-col pt-6 md:hidden"> <div class="flex flex-col md:hidden sticky top-0 z-10 bg-background">
<div class="border-b border-border/30 pt-4 md:py-4"> <div class="flex items-center gap-2 px-4 pt-6 pb-2">
<Settings class="h-6 w-6" />
<h1 class="text-2xl font-semibold">Settings</h1>
</div>
<div class="border-b border-border/30 py-2">
<!-- Horizontal Scrollable Category Menu with Navigation --> <!-- Horizontal Scrollable Category Menu with Navigation -->
<div class="relative flex items-center" style="scroll-padding: 1rem;"> <div class="relative flex items-center" style="scroll-padding: 1rem;">
<button <button
@ -512,8 +511,8 @@
</div> </div>
</div> </div>
<ScrollArea class="flex-1 max-w-5xl mx-auto"> <div class="flex-1 max-w-5xl mx-auto">
<div class="space-y-6 p-4 md:p-6 md:mt-20"> <div class="space-y-6 p-4 md:p-6 md:pt-22">
<div class="grid"> <div class="grid">
<div class="mb-6 flex hidden items-center gap-2 border-b border-border/30 pb-6 md:flex"> <div class="mb-6 flex hidden items-center gap-2 border-b border-border/30 pb-6 md:flex">
<currentSection.icon class="h-5 w-5" /> <currentSection.icon class="h-5 w-5" />
@ -537,7 +536,7 @@
<p class="text-xs text-muted-foreground">Settings are saved in browser's localStorage</p> <p class="text-xs text-muted-foreground">Settings are saved in browser's localStorage</p>
</div> </div>
</div> </div>
</ScrollArea> </div>
</div> </div>
</div> </div>

View File

@ -29,7 +29,7 @@
} }
</script> </script>
<div class="flex justify-between p-6"> <div class="flex justify-between border-t border-border/30 p-6">
<div class="flex gap-2"> <div class="flex gap-2">
<Button variant="outline" onclick={handleResetClick}> <Button variant="outline" onclick={handleResetClick}>
<RotateCcw class="h-3 w-3" /> <RotateCcw class="h-3 w-3" />
@ -38,7 +38,7 @@
</Button> </Button>
</div> </div>
<Button onclick={handleSave}>Save settings</Button> <Button class="sticky bottom-6 z-10" onclick={handleSave}>Save settings</Button>
</div> </div>
<AlertDialog.Root bind:open={showResetDialog}> <AlertDialog.Root bind:open={showResetDialog}>

View File

@ -108,10 +108,19 @@
} }
} }
let chatSidebarActions: { activateSearch?: () => void } | undefined = $state();
export function activateSearchMode() { export function activateSearchMode() {
isSearchModeActive = true; chatSidebarActions?.activateSearch?.();
} }
$effect(() => {
if (!sidebar.open) {
isSearchModeActive = false;
searchQuery = '';
}
});
export function editActiveConversation() { export function editActiveConversation() {
if (currentChatId) { if (currentChatId) {
const activeConversation = filteredConversations.find((conv) => conv.id === currentChatId); const activeConversation = filteredConversations.find((conv) => conv.id === currentChatId);
@ -148,7 +157,7 @@
<h1 class="inline-flex items-center gap-1 px-2 text-xl font-semibold">llama.cpp</h1> <h1 class="inline-flex items-center gap-1 px-2 text-xl font-semibold">llama.cpp</h1>
</a> </a>
<ChatSidebarActions {handleMobileSidebarItemClick} bind:isSearchModeActive bind:searchQuery /> <ChatSidebarActions bind:this={chatSidebarActions} {handleMobileSidebarItemClick} bind:isSearchModeActive bind:searchQuery />
</Sidebar.Header> </Sidebar.Header>
<Sidebar.Group class="mt-2 space-y-2 p-0 px-3"> <Sidebar.Group class="mt-2 space-y-2 p-0 px-3">

View File

@ -20,17 +20,25 @@
}: Props = $props(); }: Props = $props();
const importExportDialog = getImportExportDialogContext(); const importExportDialog = getImportExportDialogContext();
let searchInputRef = $state<HTMLInputElement | null>(null);
function handleSearchModeDeactivate() { function handleSearchModeDeactivate() {
isSearchModeActive = false; isSearchModeActive = false;
searchQuery = ''; searchQuery = '';
} }
export function activateSearch() {
isSearchModeActive = true;
// Focus after Svelte renders the input
queueMicrotask(() => searchInputRef?.focus());
}
</script> </script>
<div class="my-1 space-y-1"> <div class="my-1 space-y-1">
{#if isSearchModeActive} {#if isSearchModeActive}
<SearchInput <SearchInput
bind:value={searchQuery} bind:value={searchQuery}
bind:ref={searchInputRef}
onClose={handleSearchModeDeactivate} onClose={handleSearchModeDeactivate}
onKeyDown={(e) => e.key === 'Escape' && handleSearchModeDeactivate()} onKeyDown={(e) => e.key === 'Escape' && handleSearchModeDeactivate()}
placeholder="Search conversations..." placeholder="Search conversations..."
@ -54,9 +62,7 @@
<Button <Button
class="w-full justify-between px-2 backdrop-blur-none! hover:[&>kbd]:opacity-100" class="w-full justify-between px-2 backdrop-blur-none! hover:[&>kbd]:opacity-100"
onclick={() => { onclick={activateSearch}
isSearchModeActive = true;
}}
variant="ghost" variant="ghost"
> >
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">

View File

@ -84,22 +84,23 @@
} }
</script> </script>
<div class="flex items-center gap-2 absolute left-8 top-8">
<McpLogo class="h-6 w-6" />
<h1 class="text-2xl font-semibold">MCP Servers</h1>
</div>
<div class="flex items-start justify-end gap-4 py-4 sticky top-0 z-10 px-8 mt-4">
{#if !isAddingServer}
<Button variant="outline" size="sm" class="shrink-0" onclick={showAddServerForm}>
<Plus class="h-4 w-4" />
Add New Server
</Button>
{/if}
</div>
<div class="grid gap-5 md:space-y-4 {className}"> <div class="grid gap-5 md:space-y-4 {className}">
<div class="flex items-start justify-between gap-4">
<div class="flex items-center gap-2">
<McpLogo class="h-6 w-6" />
<h1 class="text-2xl font-semibold">MCP Servers</h1>
</div>
{#if !isAddingServer}
<Button variant="outline" size="sm" class="shrink-0" onclick={showAddServerForm}>
<Plus class="h-4 w-4" />
Add New Server
</Button>
{/if}
</div>
{#if isAddingServer} {#if isAddingServer}
<Card.Root class="bg-muted/30 p-4"> <Card.Root class="bg-muted/30 p-4">

View File

@ -66,7 +66,8 @@
<div <div
data-slot="sidebar-gap" data-slot="sidebar-gap"
class={cn( class={cn(
'relative w-[calc(var(--sidebar-width)+0.75rem)] bg-transparent transition-[width] duration-200 ease-linear', 'relative bg-transparent transition-[width] duration-200 ease-linear',
variant === 'floating' ? 'w-[calc(var(--sidebar-width)+0.75rem)]' : 'w-(--sidebar-width)',
'group-data-[collapsible=offcanvas]:w-0', 'group-data-[collapsible=offcanvas]:w-0',
'group-data-[side=right]:rotate-180', 'group-data-[side=right]:rotate-180',
variant === 'floating' || variant === 'inset' variant === 'floating' || variant === 'inset'
@ -78,25 +79,36 @@
<div <div
data-slot="sidebar-container" data-slot="sidebar-container"
class={cn( class={cn(
'fixed inset-y-0 z-999 hidden w-(--sidebar-width) transition-[left,right,width,opacity] duration-200 ease-linear md:z-0 md:flex', 'fixed inset-y-0 z-999 hidden w-(--sidebar-width) duration-200 ease-linear md:z-0 md:flex',
side === 'left' variant === 'floating'
? 'left-3 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-0.775)] group-data-[collapsible=offcanvas]:opacity-0' ? [
: 'right-1 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-0.775)] group-data-[collapsible=offcanvas]:opacity-0', 'transition-[left,right,width,opacity]',
// Adjust the padding for floating and inset variants. side === 'left'
variant === 'floating' || variant === 'inset' ? 'left-3 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-0.775)] group-data-[collapsible=offcanvas]:opacity-0'
: 'right-3 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-0.775)] group-data-[collapsible=offcanvas]:opacity-0',
'my-3 overflow-hidden rounded-2xl border border-sidebar-border shadow-md',
]
: [
'transition-[left,right,width] h-svh',
side === 'left'
? 'left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]'
: 'right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]',
],
// Adjust the padding for inset variant.
variant === 'inset'
? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]' ? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]'
: 'group-data-[collapsible=icon]:w-(--sidebar-width-icon)', : variant === 'floating'
// Add margin and rounded corners ? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]'
'my-3 overflow-hidden rounded-2xl border border-sidebar-border shadow-md', : 'group-data-[collapsible=icon]:w-(--sidebar-width-icon)',
className className
)} )}
style="height: calc(100dvh - 1.5rem);" style={variant === 'floating' ? 'height: calc(100dvh - 1.5rem);' : undefined}
{...restProps} {...restProps}
> >
<div <div
data-sidebar="sidebar" data-sidebar="sidebar"
data-slot="sidebar-inner" data-slot="sidebar-inner"
class="flex h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow-sm" class="flex h-full w-full flex-col bg-sidebar"
> >
{@render children?.()} {@render children?.()}
</div> </div>

View File

@ -21,7 +21,6 @@ export const SETTING_CONFIG_DEFAULT: Record<string, string | number | boolean |
disableAutoScroll: false, disableAutoScroll: false,
renderUserContentAsMarkdown: false, renderUserContentAsMarkdown: false,
alwaysShowSidebarOnDesktop: false, alwaysShowSidebarOnDesktop: false,
autoShowSidebarOnNewChat: true,
autoMicOnEmpty: false, autoMicOnEmpty: false,
fullHeightCodeBlocks: false, fullHeightCodeBlocks: false,
showRawModelNames: false, showRawModelNames: false,

View File

@ -22,7 +22,6 @@ export const SETTINGS_KEYS = {
RENDER_USER_CONTENT_AS_MARKDOWN: 'renderUserContentAsMarkdown', RENDER_USER_CONTENT_AS_MARKDOWN: 'renderUserContentAsMarkdown',
DISABLE_AUTO_SCROLL: 'disableAutoScroll', DISABLE_AUTO_SCROLL: 'disableAutoScroll',
ALWAYS_SHOW_SIDEBAR_ON_DESKTOP: 'alwaysShowSidebarOnDesktop', ALWAYS_SHOW_SIDEBAR_ON_DESKTOP: 'alwaysShowSidebarOnDesktop',
AUTO_SHOW_SIDEBAR_ON_NEW_CHAT: 'autoShowSidebarOnNewChat',
FULL_HEIGHT_CODE_BLOCKS: 'fullHeightCodeBlocks', FULL_HEIGHT_CODE_BLOCKS: 'fullHeightCodeBlocks',
SHOW_RAW_MODEL_NAMES: 'showRawModelNames', SHOW_RAW_MODEL_NAMES: 'showRawModelNames',
// Sampling // Sampling

View File

@ -191,12 +191,6 @@ export const SYNCABLE_PARAMETERS: SyncableParameter[] = [
type: SyncableParameterType.BOOLEAN, type: SyncableParameterType.BOOLEAN,
canSync: true canSync: true
}, },
{
key: 'autoShowSidebarOnNewChat',
serverKey: 'autoShowSidebarOnNewChat',
type: SyncableParameterType.BOOLEAN,
canSync: true
},
{ {
key: 'showRawModelNames', key: 'showRawModelNames',
serverKey: 'showRawModelNames', serverKey: 'showRawModelNames',

View File

@ -11,7 +11,7 @@
DialogConversationTitleUpdate, DialogConversationTitleUpdate,
DialogChatSettingsImportExport DialogChatSettingsImportExport
} from '$lib/components/app'; } from '$lib/components/app';
import { Settings } from '@lucide/svelte'; import { Settings, Search, SquarePen } from '@lucide/svelte';
import { Button } from '$lib/components/ui/button'; import { Button } from '$lib/components/ui/button';
import { isLoading } from '$lib/stores/chat.svelte'; import { isLoading } from '$lib/stores/chat.svelte';
import { conversationsStore, activeMessages } from '$lib/stores/conversations.svelte'; import { conversationsStore, activeMessages } from '$lib/stores/conversations.svelte';
@ -41,7 +41,6 @@
let isNewChatMode = $derived(page.url.searchParams.get('new_chat') === 'true'); let isNewChatMode = $derived(page.url.searchParams.get('new_chat') === 'true');
let showSidebarByDefault = $derived(activeMessages().length > 0 || isLoading()); let showSidebarByDefault = $derived(activeMessages().length > 0 || isLoading());
let alwaysShowSidebarOnDesktop = $derived(config().alwaysShowSidebarOnDesktop); let alwaysShowSidebarOnDesktop = $derived(config().alwaysShowSidebarOnDesktop);
let autoShowSidebarOnNewChat = $derived(config().autoShowSidebarOnNewChat);
let isMobile = new IsMobile(); let isMobile = new IsMobile();
let isDesktop = $derived(!isMobile.current); let isDesktop = $derived(!isMobile.current);
let sidebarOpen = $state(false); let sidebarOpen = $state(false);
@ -57,6 +56,8 @@
let titleUpdateResolve: ((value: boolean) => void) | null = null; let titleUpdateResolve: ((value: boolean) => void) | null = null;
let activePanel = $state<'chat' | 'settings' | 'mcp'>('chat'); let activePanel = $state<'chat' | 'settings' | 'mcp'>('chat');
let isMcpActive = $derived(page.route.id === '/settings/mcp');
let isSettingsActive = $derived(page.route.id === '/settings/chat');
// let chatSettingsInitialSection = $state<SettingsSectionTitle | undefined>(undefined); // let chatSettingsInitialSection = $state<SettingsSectionTitle | undefined>(undefined);
let chatSettingsRef: ChatSettings | undefined = $state(); let chatSettingsRef: ChatSettings | undefined = $state();
let importExportDialogOpen = $state(false); let importExportDialogOpen = $state(false);
@ -141,23 +142,7 @@
sidebarOpen = true; sidebarOpen = true;
return; return;
} }
// Don't auto-open or auto-close sidebar during navigation - user controls it manually
if (isHomeRoute && !isNewChatMode) {
// Auto-collapse sidebar when navigating to home route (but not in new chat mode)
sidebarOpen = false;
} else if (isHomeRoute && isNewChatMode) {
// Keep sidebar open in new chat mode
sidebarOpen = true;
} else if (isChatRoute) {
// On chat routes, only auto-show sidebar if setting is enabled
if (autoShowSidebarOnNewChat) {
sidebarOpen = true;
}
// If setting is disabled, don't change sidebar state - let user control it manually
} else {
// Other routes follow default behavior
sidebarOpen = showSidebarByDefault;
}
}); });
// Initialize server properties on app load (run once) // Initialize server properties on app load (run once)
@ -280,7 +265,7 @@
<Sidebar.Provider bind:open={sidebarOpen}> <Sidebar.Provider bind:open={sidebarOpen}>
<div class="flex h-screen w-full" style:height="{innerHeight}px"> <div class="flex h-screen w-full" style:height="{innerHeight}px">
<Sidebar.Root class="h-full"> <Sidebar.Root variant="floating" class="h-full">
<ChatSidebar bind:this={chatSidebar} /> <ChatSidebar bind:this={chatSidebar} />
</Sidebar.Root> </Sidebar.Root>
@ -293,28 +278,80 @@
/> />
{/if} {/if}
{#if !sidebarOpen} {#if isDesktop && !alwaysShowSidebarOnDesktop}
<div class="absolute bottom-3 left-3 z-[900] flex flex-col gap-1 p-2"> <!-- Desktop: icon strip, always rendered, transitions width/opacity -->
<aside class="hidden md:flex shrink-0 flex-col items-center justify-between overflow-hidden py-3 transition-[width,opacity] duration-200 ease-linear {sidebarOpen ? 'w-0 opacity-0 pointer-events-none' : 'w-[calc(var(--sidebar-width-icon)+1.5rem)] opacity-100'}">
<div class="mt-12 flex flex-col items-center gap-1">
<Button
variant="ghost"
size="icon-lg"
class="rounded-full"
href="?new_chat=true#/"
>
<SquarePen class="h-4 w-4" />
<span class="sr-only">New Chat</span>
</Button>
<Button
variant="ghost"
size="icon-lg"
class="rounded-full"
onclick={() => {
if (chatSidebar?.activateSearchMode) {
chatSidebar.activateSearchMode();
}
sidebarOpen = true;
}}
>
<Search class="h-4 w-4" />
<span class="sr-only">Search</span>
</Button>
</div>
<div class="flex flex-col items-center gap-1">
<Button
variant="ghost"
size="icon-lg"
href="#/settings/mcp"
class="rounded-full {isMcpActive ? 'bg-accent text-accent-foreground' : ''}"
>
<McpLogo class="h-4 w-4" />
<span class="sr-only">MCP Servers</span>
</Button>
<Button
variant="ghost"
size="icon-lg"
href="#/settings/chat"
class="rounded-full {isSettingsActive ? 'bg-accent text-accent-foreground' : ''}"
>
<Settings class="h-4 w-4" />
<span class="sr-only">Settings</span>
</Button>
</div>
</aside>
{/if}
{#if !sidebarOpen && !isDesktop}
<!-- Mobile quick-access buttons -->
<div class="absolute bottom-3 left-3 z-[900] flex flex-col gap-1 p-2 md:hidden">
<Button <Button
variant="ghost" variant="ghost"
size="icon" size="icon-lg"
class="h-8 w-8 {activePanel === 'mcp' ? 'bg-accent text-accent-foreground' : ''}" href="#/settings/mcp"
onclick={() => (activePanel = activePanel === 'mcp' ? 'chat' : 'mcp')} class={isMcpActive ? 'bg-accent text-accent-foreground' : ''}
> >
<McpLogo class="h-4 w-4" /> <McpLogo class="h-4 w-4" />
</Button> </Button>
<Button <Button
variant="ghost" variant="ghost"
size="icon" size="icon-lg"
class="h-8 w-8 {activePanel === 'settings' ? 'bg-accent text-accent-foreground' : ''}" href="#/settings/chat"
onclick={() => (activePanel = activePanel === 'settings' ? 'chat' : 'settings')} class={isSettingsActive ? 'bg-accent text-accent-foreground' : ''}
> >
<Settings class="h-4 w-4" /> <Settings class="h-4 w-4" />
</Button> </Button>
</div> </div>
{/if} {/if}
<Sidebar.Inset class="flex flex-1 flex-col overflow-hidden"> <Sidebar.Inset class="flex flex-1 flex-col overflow-auto">
{@render children?.()} {@render children?.()}
</Sidebar.Inset> </Sidebar.Inset>
</div> </div>