aboutsummaryrefslogtreecommitdiff
path: root/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar
diff options
context:
space:
mode:
authorMitja Felicijan <mitja.felicijan@gmail.com>2026-02-12 20:57:17 +0100
committerMitja Felicijan <mitja.felicijan@gmail.com>2026-02-12 20:57:17 +0100
commitb333b06772c89d96aacb5490d6a219fba7c09cc6 (patch)
tree211df60083a5946baa2ed61d33d8121b7e251b06 /llama.cpp/tools/server/webui/src/lib/components/ui/sidebar
downloadllmnpc-b333b06772c89d96aacb5490d6a219fba7c09cc6.tar.gz
Engage!
Diffstat (limited to 'llama.cpp/tools/server/webui/src/lib/components/ui/sidebar')
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/constants.ts6
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/context.svelte.ts79
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/index.ts75
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-content.svelte24
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-footer.svelte21
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-group-action.svelte36
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-group-content.svelte21
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-group-label.svelte34
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-group.svelte21
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-header.svelte21
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-input.svelte21
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-inset.svelte24
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-action.svelte43
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte29
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-button.svelte106
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-item.svelte21
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte36
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte43
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte21
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte25
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu.svelte21
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-provider.svelte50
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-rail.svelte36
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-separator.svelte19
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-trigger.svelte35
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar.svelte101
26 files changed, 969 insertions, 0 deletions
diff --git a/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/constants.ts b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/constants.ts
new file mode 100644
index 0000000..c7e827b
--- /dev/null
+++ b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/constants.ts
@@ -0,0 +1,6 @@
1export const SIDEBAR_COOKIE_NAME = 'sidebar:state';
2export const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
3export const SIDEBAR_WIDTH = '18rem';
4export const SIDEBAR_WIDTH_MOBILE = '18rem';
5export const SIDEBAR_WIDTH_ICON = '3rem';
6export const SIDEBAR_KEYBOARD_SHORTCUT = 'b';
diff --git a/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/context.svelte.ts b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/context.svelte.ts
new file mode 100644
index 0000000..6fa2aa3
--- /dev/null
+++ b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/context.svelte.ts
@@ -0,0 +1,79 @@
1import { IsMobile } from '$lib/hooks/is-mobile.svelte.js';
2import { getContext, setContext } from 'svelte';
3import { SIDEBAR_KEYBOARD_SHORTCUT } from './constants.js';
4
5type Getter<T> = () => T;
6
7export type SidebarStateProps = {
8 /**
9 * A getter function that returns the current open state of the sidebar.
10 * We use a getter function here to support `bind:open` on the `Sidebar.Provider`
11 * component.
12 */
13 open: Getter<boolean>;
14
15 /**
16 * A function that sets the open state of the sidebar. To support `bind:open`, we need
17 * a source of truth for changing the open state to ensure it will be synced throughout
18 * the sub-components and any `bind:` references.
19 */
20 setOpen: (open: boolean) => void;
21};
22
23class SidebarState {
24 readonly props: SidebarStateProps;
25 open = $derived.by(() => this.props.open());
26 openMobile = $state(false);
27 setOpen: SidebarStateProps['setOpen'];
28 #isMobile: IsMobile;
29 state = $derived.by(() => (this.open ? 'expanded' : 'collapsed'));
30
31 constructor(props: SidebarStateProps) {
32 this.setOpen = props.setOpen;
33 this.#isMobile = new IsMobile();
34 this.props = props;
35 }
36
37 // Convenience getter for checking if the sidebar is mobile
38 // without this, we would need to use `sidebar.isMobile.current` everywhere
39 get isMobile() {
40 return this.#isMobile.current;
41 }
42
43 // Event handler to apply to the `<svelte:window>`
44 handleShortcutKeydown = (e: KeyboardEvent) => {
45 if (e.key === SIDEBAR_KEYBOARD_SHORTCUT && (e.metaKey || e.ctrlKey)) {
46 e.preventDefault();
47 this.toggle();
48 }
49 };
50
51 setOpenMobile = (value: boolean) => {
52 this.openMobile = value;
53 };
54
55 toggle = () => {
56 return this.#isMobile.current ? (this.openMobile = !this.openMobile) : this.setOpen(!this.open);
57 };
58}
59
60const SYMBOL_KEY = 'scn-sidebar';
61
62/**
63 * Instantiates a new `SidebarState` instance and sets it in the context.
64 *
65 * @param props The constructor props for the `SidebarState` class.
66 * @returns The `SidebarState` instance.
67 */
68export function setSidebar(props: SidebarStateProps): SidebarState {
69 return setContext(Symbol.for(SYMBOL_KEY), new SidebarState(props));
70}
71
72/**
73 * Retrieves the `SidebarState` instance from the context. This is a class instance,
74 * so you cannot destructure it.
75 * @returns The `SidebarState` instance.
76 */
77export function useSidebar(): SidebarState {
78 return getContext(Symbol.for(SYMBOL_KEY));
79}
diff --git a/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/index.ts b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/index.ts
new file mode 100644
index 0000000..280e640
--- /dev/null
+++ b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/index.ts
@@ -0,0 +1,75 @@
1import { useSidebar } from './context.svelte.js';
2import Content from './sidebar-content.svelte';
3import Footer from './sidebar-footer.svelte';
4import GroupAction from './sidebar-group-action.svelte';
5import GroupContent from './sidebar-group-content.svelte';
6import GroupLabel from './sidebar-group-label.svelte';
7import Group from './sidebar-group.svelte';
8import Header from './sidebar-header.svelte';
9import Input from './sidebar-input.svelte';
10import Inset from './sidebar-inset.svelte';
11import MenuAction from './sidebar-menu-action.svelte';
12import MenuBadge from './sidebar-menu-badge.svelte';
13import MenuButton from './sidebar-menu-button.svelte';
14import MenuItem from './sidebar-menu-item.svelte';
15import MenuSkeleton from './sidebar-menu-skeleton.svelte';
16import MenuSubButton from './sidebar-menu-sub-button.svelte';
17import MenuSubItem from './sidebar-menu-sub-item.svelte';
18import MenuSub from './sidebar-menu-sub.svelte';
19import Menu from './sidebar-menu.svelte';
20import Provider from './sidebar-provider.svelte';
21import Rail from './sidebar-rail.svelte';
22import Separator from './sidebar-separator.svelte';
23import Trigger from './sidebar-trigger.svelte';
24import Root from './sidebar.svelte';
25
26export {
27 Content,
28 Footer,
29 Group,
30 GroupAction,
31 GroupContent,
32 GroupLabel,
33 Header,
34 Input,
35 Inset,
36 Menu,
37 MenuAction,
38 MenuBadge,
39 MenuButton,
40 MenuItem,
41 MenuSkeleton,
42 MenuSub,
43 MenuSubButton,
44 MenuSubItem,
45 Provider,
46 Rail,
47 Root,
48 Separator,
49 //
50 Root as Sidebar,
51 Content as SidebarContent,
52 Footer as SidebarFooter,
53 Group as SidebarGroup,
54 GroupAction as SidebarGroupAction,
55 GroupContent as SidebarGroupContent,
56 GroupLabel as SidebarGroupLabel,
57 Header as SidebarHeader,
58 Input as SidebarInput,
59 Inset as SidebarInset,
60 Menu as SidebarMenu,
61 MenuAction as SidebarMenuAction,
62 MenuBadge as SidebarMenuBadge,
63 MenuButton as SidebarMenuButton,
64 MenuItem as SidebarMenuItem,
65 MenuSkeleton as SidebarMenuSkeleton,
66 MenuSub as SidebarMenuSub,
67 MenuSubButton as SidebarMenuSubButton,
68 MenuSubItem as SidebarMenuSubItem,
69 Provider as SidebarProvider,
70 Rail as SidebarRail,
71 Separator as SidebarSeparator,
72 Trigger as SidebarTrigger,
73 Trigger,
74 useSidebar
75};
diff --git a/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-content.svelte b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-content.svelte
new file mode 100644
index 0000000..0e5f75e
--- /dev/null
+++ b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-content.svelte
@@ -0,0 +1,24 @@
1<script lang="ts">
2 import type { HTMLAttributes } from 'svelte/elements';
3 import { cn, type WithElementRef } from '$lib/components/ui/utils.js';
4
5 let {
6 ref = $bindable(null),
7 class: className,
8 children,
9 ...restProps
10 }: WithElementRef<HTMLAttributes<HTMLElement>> = $props();
11</script>
12
13<div
14 bind:this={ref}
15 data-slot="sidebar-content"
16 data-sidebar="content"
17 class={cn(
18 'flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden',
19 className
20 )}
21 {...restProps}
22>
23 {@render children?.()}
24</div>
diff --git a/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-footer.svelte b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-footer.svelte
new file mode 100644
index 0000000..67be0a4
--- /dev/null
+++ b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-footer.svelte
@@ -0,0 +1,21 @@
1<script lang="ts">
2 import type { HTMLAttributes } from 'svelte/elements';
3 import { cn, type WithElementRef } from '$lib/components/ui/utils.js';
4
5 let {
6 ref = $bindable(null),
7 class: className,
8 children,
9 ...restProps
10 }: WithElementRef<HTMLAttributes<HTMLElement>> = $props();
11</script>
12
13<div
14 bind:this={ref}
15 data-slot="sidebar-footer"
16 data-sidebar="footer"
17 class={cn('flex flex-col gap-2 p-2', className)}
18 {...restProps}
19>
20 {@render children?.()}
21</div>
diff --git a/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-group-action.svelte b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-group-action.svelte
new file mode 100644
index 0000000..027a711
--- /dev/null
+++ b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-group-action.svelte
@@ -0,0 +1,36 @@
1<script lang="ts">
2 import { cn, type WithElementRef } from '$lib/components/ui/utils.js';
3 import type { Snippet } from 'svelte';
4 import type { HTMLButtonAttributes } from 'svelte/elements';
5
6 let {
7 ref = $bindable(null),
8 class: className,
9 children,
10 child,
11 ...restProps
12 }: WithElementRef<HTMLButtonAttributes> & {
13 child?: Snippet<[{ props: Record<string, unknown> }]>;
14 } = $props();
15
16 const mergedProps = $derived({
17 class: cn(
18 'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground outline-hidden absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
19 // Increases the hit area of the button on mobile.
20 'after:absolute after:-inset-2 md:after:hidden',
21 'group-data-[collapsible=icon]:hidden',
22 className
23 ),
24 'data-slot': 'sidebar-group-action',
25 'data-sidebar': 'group-action',
26 ...restProps
27 });
28</script>
29
30{#if child}
31 {@render child({ props: mergedProps })}
32{:else}
33 <button bind:this={ref} {...mergedProps}>
34 {@render children?.()}
35 </button>
36{/if}
diff --git a/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-group-content.svelte b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-group-content.svelte
new file mode 100644
index 0000000..9e018fb
--- /dev/null
+++ b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-group-content.svelte
@@ -0,0 +1,21 @@
1<script lang="ts">
2 import { cn, type WithElementRef } from '$lib/components/ui/utils.js';
3 import type { HTMLAttributes } from 'svelte/elements';
4
5 let {
6 ref = $bindable(null),
7 class: className,
8 children,
9 ...restProps
10 }: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
11</script>
12
13<div
14 bind:this={ref}
15 data-slot="sidebar-group-content"
16 data-sidebar="group-content"
17 class={cn('w-full text-sm', className)}
18 {...restProps}
19>
20 {@render children?.()}
21</div>
diff --git a/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-group-label.svelte b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-group-label.svelte
new file mode 100644
index 0000000..79f47d7
--- /dev/null
+++ b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-group-label.svelte
@@ -0,0 +1,34 @@
1<script lang="ts">
2 import { cn, type WithElementRef } from '$lib/components/ui/utils.js';
3 import type { Snippet } from 'svelte';
4 import type { HTMLAttributes } from 'svelte/elements';
5
6 let {
7 ref = $bindable(null),
8 children,
9 child,
10 class: className,
11 ...restProps
12 }: WithElementRef<HTMLAttributes<HTMLElement>> & {
13 child?: Snippet<[{ props: Record<string, unknown> }]>;
14 } = $props();
15
16 const mergedProps = $derived({
17 class: cn(
18 'text-sidebar-foreground/70 ring-sidebar-ring outline-hidden flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
19 'group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0',
20 className
21 ),
22 'data-slot': 'sidebar-group-label',
23 'data-sidebar': 'group-label',
24 ...restProps
25 });
26</script>
27
28{#if child}
29 {@render child({ props: mergedProps })}
30{:else}
31 <div bind:this={ref} {...mergedProps}>
32 {@render children?.()}
33 </div>
34{/if}
diff --git a/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-group.svelte b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-group.svelte
new file mode 100644
index 0000000..eed5ace
--- /dev/null
+++ b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-group.svelte
@@ -0,0 +1,21 @@
1<script lang="ts">
2 import type { HTMLAttributes } from 'svelte/elements';
3 import { cn, type WithElementRef } from '$lib/components/ui/utils.js';
4
5 let {
6 ref = $bindable(null),
7 class: className,
8 children,
9 ...restProps
10 }: WithElementRef<HTMLAttributes<HTMLElement>> = $props();
11</script>
12
13<div
14 bind:this={ref}
15 data-slot="sidebar-group"
16 data-sidebar="group"
17 class={cn('relative flex w-full min-w-0 flex-col p-2', className)}
18 {...restProps}
19>
20 {@render children?.()}
21</div>
diff --git a/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-header.svelte b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-header.svelte
new file mode 100644
index 0000000..0651550
--- /dev/null
+++ b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-header.svelte
@@ -0,0 +1,21 @@
1<script lang="ts">
2 import type { HTMLAttributes } from 'svelte/elements';
3 import { cn, type WithElementRef } from '$lib/components/ui/utils.js';
4
5 let {
6 ref = $bindable(null),
7 class: className,
8 children,
9 ...restProps
10 }: WithElementRef<HTMLAttributes<HTMLElement>> = $props();
11</script>
12
13<div
14 bind:this={ref}
15 data-slot="sidebar-header"
16 data-sidebar="header"
17 class={cn('flex flex-col gap-2 p-2', className)}
18 {...restProps}
19>
20 {@render children?.()}
21</div>
diff --git a/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-input.svelte b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-input.svelte
new file mode 100644
index 0000000..fa57473
--- /dev/null
+++ b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-input.svelte
@@ -0,0 +1,21 @@
1<script lang="ts">
2 import type { ComponentProps } from 'svelte';
3 import { Input } from '$lib/components/ui/input/index.js';
4 import { cn } from '$lib/components/ui/utils.js';
5
6 let {
7 ref = $bindable(null),
8 value = $bindable(''),
9 class: className,
10 ...restProps
11 }: ComponentProps<typeof Input> = $props();
12</script>
13
14<Input
15 bind:ref
16 bind:value
17 data-slot="sidebar-input"
18 data-sidebar="input"
19 class={cn('h-8 w-full bg-background shadow-none', className)}
20 {...restProps}
21/>
diff --git a/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-inset.svelte b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-inset.svelte
new file mode 100644
index 0000000..f55d2f4
--- /dev/null
+++ b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-inset.svelte
@@ -0,0 +1,24 @@
1<script lang="ts">
2 import { cn, type WithElementRef } from '$lib/components/ui/utils.js';
3 import type { HTMLAttributes } from 'svelte/elements';
4
5 let {
6 ref = $bindable(null),
7 class: className,
8 children,
9 ...restProps
10 }: WithElementRef<HTMLAttributes<HTMLElement>> = $props();
11</script>
12
13<main
14 bind:this={ref}
15 data-slot="sidebar-inset"
16 class={cn(
17 'relative flex w-full flex-1 flex-col',
18 'md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2',
19 className
20 )}
21 {...restProps}
22>
23 {@render children?.()}
24</main>
diff --git a/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-action.svelte b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-action.svelte
new file mode 100644
index 0000000..ded1ffd
--- /dev/null
+++ b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-action.svelte
@@ -0,0 +1,43 @@
1<script lang="ts">
2 import { cn, type WithElementRef } from '$lib/components/ui/utils.js';
3 import type { Snippet } from 'svelte';
4 import type { HTMLButtonAttributes } from 'svelte/elements';
5
6 let {
7 ref = $bindable(null),
8 class: className,
9 showOnHover = false,
10 children,
11 child,
12 ...restProps
13 }: WithElementRef<HTMLButtonAttributes> & {
14 child?: Snippet<[{ props: Record<string, unknown> }]>;
15 showOnHover?: boolean;
16 } = $props();
17
18 const mergedProps = $derived({
19 class: cn(
20 'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground outline-hidden absolute right-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
21 // Increases the hit area of the button on mobile.
22 'after:absolute after:-inset-2 md:after:hidden',
23 'peer-data-[size=sm]/menu-button:top-1',
24 'peer-data-[size=default]/menu-button:top-1.5',
25 'peer-data-[size=lg]/menu-button:top-2.5',
26 'group-data-[collapsible=icon]:hidden',
27 showOnHover &&
28 'peer-data-[active=true]/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 md:opacity-0',
29 className
30 ),
31 'data-slot': 'sidebar-menu-action',
32 'data-sidebar': 'menu-action',
33 ...restProps
34 });
35</script>
36
37{#if child}
38 {@render child({ props: mergedProps })}
39{:else}
40 <button bind:this={ref} {...mergedProps}>
41 {@render children?.()}
42 </button>
43{/if}
diff --git a/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte
new file mode 100644
index 0000000..f4525a1
--- /dev/null
+++ b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte
@@ -0,0 +1,29 @@
1<script lang="ts">
2 import { cn, type WithElementRef } from '$lib/components/ui/utils.js';
3 import type { HTMLAttributes } from 'svelte/elements';
4
5 let {
6 ref = $bindable(null),
7 class: className,
8 children,
9 ...restProps
10 }: WithElementRef<HTMLAttributes<HTMLElement>> = $props();
11</script>
12
13<div
14 bind:this={ref}
15 data-slot="sidebar-menu-badge"
16 data-sidebar="menu-badge"
17 class={cn(
18 'pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium text-sidebar-foreground tabular-nums select-none',
19 'peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground',
20 'peer-data-[size=sm]/menu-button:top-1',
21 'peer-data-[size=default]/menu-button:top-1.5',
22 'peer-data-[size=lg]/menu-button:top-2.5',
23 'group-data-[collapsible=icon]:hidden',
24 className
25 )}
26 {...restProps}
27>
28 {@render children?.()}
29</div>
diff --git a/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-button.svelte b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-button.svelte
new file mode 100644
index 0000000..2ce0305
--- /dev/null
+++ b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-button.svelte
@@ -0,0 +1,106 @@
1<script lang="ts" module>
2 import { tv, type VariantProps } from 'tailwind-variants';
3
4 export const sidebarMenuButtonVariants = tv({
5 base: 'peer/menu-button outline-hidden ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground group-has-data-[sidebar=menu-action]/menu-item:pr-8 data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm transition-[width,height,padding] focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:font-medium [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',
6 variants: {
7 variant: {
8 default: 'hover:bg-sidebar-accent hover:text-sidebar-accent-foreground',
9 outline:
10 'bg-background hover:bg-sidebar-accent hover:text-sidebar-accent-foreground shadow-[0_0_0_1px_var(--sidebar-border)] hover:shadow-[0_0_0_1px_var(--sidebar-accent)]'
11 },
12 size: {
13 default: 'h-8 text-sm',
14 sm: 'h-7 text-xs',
15 lg: 'group-data-[collapsible=icon]:p-0! h-12 text-sm'
16 }
17 },
18 defaultVariants: {
19 variant: 'default',
20 size: 'default'
21 }
22 });
23
24 export type SidebarMenuButtonVariant = VariantProps<typeof sidebarMenuButtonVariants>['variant'];
25 export type SidebarMenuButtonSize = VariantProps<typeof sidebarMenuButtonVariants>['size'];
26</script>
27
28<script lang="ts">
29 import * as Tooltip from '$lib/components/ui/tooltip/index.js';
30 import {
31 cn,
32 type WithElementRef,
33 type WithoutChildrenOrChild
34 } from '$lib/components/ui/utils.js';
35 import { mergeProps } from 'bits-ui';
36 import type { ComponentProps, Snippet } from 'svelte';
37 import type { HTMLAttributes } from 'svelte/elements';
38 import { useSidebar } from './context.svelte.js';
39
40 let {
41 ref = $bindable(null),
42 class: className,
43 children,
44 child,
45 variant = 'default',
46 size = 'default',
47 isActive = false,
48 tooltipContent,
49 tooltipContentProps,
50 ...restProps
51 }: WithElementRef<HTMLAttributes<HTMLButtonElement>, HTMLButtonElement> & {
52 isActive?: boolean;
53 variant?: SidebarMenuButtonVariant;
54 size?: SidebarMenuButtonSize;
55 tooltipContent?: Snippet | string;
56 tooltipContentProps?: WithoutChildrenOrChild<ComponentProps<typeof Tooltip.Content>>;
57 child?: Snippet<[{ props: Record<string, unknown> }]>;
58 } = $props();
59
60 const sidebar = useSidebar();
61
62 const buttonProps = $derived({
63 class: cn(sidebarMenuButtonVariants({ variant, size }), className),
64 'data-slot': 'sidebar-menu-button',
65 'data-sidebar': 'menu-button',
66 'data-size': size,
67 'data-active': isActive,
68 ...restProps
69 });
70</script>
71
72{#snippet Button({ props }: { props?: Record<string, unknown> })}
73 {@const mergedProps = mergeProps(buttonProps, props)}
74 {#if child}
75 {@render child({ props: mergedProps })}
76 {:else}
77 <button bind:this={ref} {...mergedProps}>
78 {@render children?.()}
79 </button>
80 {/if}
81{/snippet}
82
83{#if !tooltipContent}
84 {@render Button({})}
85{:else}
86 <Tooltip.Root>
87 <Tooltip.Trigger>
88 {#snippet child({ props })}
89 {@render Button({ props })}
90 {/snippet}
91 </Tooltip.Trigger>
92
93 <Tooltip.Content
94 side="right"
95 align="center"
96 hidden={sidebar.state !== 'collapsed' || sidebar.isMobile}
97 {...tooltipContentProps}
98 >
99 {#if typeof tooltipContent === 'string'}
100 {tooltipContent}
101 {:else if tooltipContent}
102 {@render tooltipContent()}
103 {/if}
104 </Tooltip.Content>
105 </Tooltip.Root>
106{/if}
diff --git a/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-item.svelte b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-item.svelte
new file mode 100644
index 0000000..5adbedd
--- /dev/null
+++ b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-item.svelte
@@ -0,0 +1,21 @@
1<script lang="ts">
2 import { cn, type WithElementRef } from '$lib/components/ui/utils.js';
3 import type { HTMLAttributes } from 'svelte/elements';
4
5 let {
6 ref = $bindable(null),
7 class: className,
8 children,
9 ...restProps
10 }: WithElementRef<HTMLAttributes<HTMLLIElement>, HTMLLIElement> = $props();
11</script>
12
13<li
14 bind:this={ref}
15 data-slot="sidebar-menu-item"
16 data-sidebar="menu-item"
17 class={cn('group/menu-item relative', className)}
18 {...restProps}
19>
20 {@render children?.()}
21</li>
diff --git a/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte
new file mode 100644
index 0000000..2b2acd6
--- /dev/null
+++ b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte
@@ -0,0 +1,36 @@
1<script lang="ts">
2 import { cn, type WithElementRef } from '$lib/components/ui/utils.js';
3 import { Skeleton } from '$lib/components/ui/skeleton/index.js';
4 import type { HTMLAttributes } from 'svelte/elements';
5
6 let {
7 ref = $bindable(null),
8 class: className,
9 showIcon = false,
10 children,
11 ...restProps
12 }: WithElementRef<HTMLAttributes<HTMLElement>> & {
13 showIcon?: boolean;
14 } = $props();
15
16 // Random width between 50% and 90%
17 const width = `${Math.floor(Math.random() * 40) + 50}%`;
18</script>
19
20<div
21 bind:this={ref}
22 data-slot="sidebar-menu-skeleton"
23 data-sidebar="menu-skeleton"
24 class={cn('flex h-8 items-center gap-2 rounded-md px-2', className)}
25 {...restProps}
26>
27 {#if showIcon}
28 <Skeleton class="size-4 rounded-md" data-sidebar="menu-skeleton-icon" />
29 {/if}
30 <Skeleton
31 class="h-4 max-w-(--skeleton-width) flex-1"
32 data-sidebar="menu-skeleton-text"
33 style="--skeleton-width: {width};"
34 />
35 {@render children?.()}
36</div>
diff --git a/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte
new file mode 100644
index 0000000..dabfe0f
--- /dev/null
+++ b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte
@@ -0,0 +1,43 @@
1<script lang="ts">
2 import { cn, type WithElementRef } from '$lib/components/ui/utils.js';
3 import type { Snippet } from 'svelte';
4 import type { HTMLAnchorAttributes } from 'svelte/elements';
5
6 let {
7 ref = $bindable(null),
8 children,
9 child,
10 class: className,
11 size = 'md',
12 isActive = false,
13 ...restProps
14 }: WithElementRef<HTMLAnchorAttributes> & {
15 child?: Snippet<[{ props: Record<string, unknown> }]>;
16 size?: 'sm' | 'md';
17 isActive?: boolean;
18 } = $props();
19
20 const mergedProps = $derived({
21 class: cn(
22 'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground outline-hidden flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',
23 'data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground',
24 size === 'sm' && 'text-xs',
25 size === 'md' && 'text-sm',
26 'group-data-[collapsible=icon]:hidden',
27 className
28 ),
29 'data-slot': 'sidebar-menu-sub-button',
30 'data-sidebar': 'menu-sub-button',
31 'data-size': size,
32 'data-active': isActive,
33 ...restProps
34 });
35</script>
36
37{#if child}
38 {@render child({ props: mergedProps })}
39{:else}
40 <a bind:this={ref} {...mergedProps}>
41 {@render children?.()}
42 </a>
43{/if}
diff --git a/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte
new file mode 100644
index 0000000..cca870e
--- /dev/null
+++ b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte
@@ -0,0 +1,21 @@
1<script lang="ts">
2 import { cn, type WithElementRef } from '$lib/components/ui/utils.js';
3 import type { HTMLAttributes } from 'svelte/elements';
4
5 let {
6 ref = $bindable(null),
7 children,
8 class: className,
9 ...restProps
10 }: WithElementRef<HTMLAttributes<HTMLLIElement>> = $props();
11</script>
12
13<li
14 bind:this={ref}
15 data-slot="sidebar-menu-sub-item"
16 data-sidebar="menu-sub-item"
17 class={cn('group/menu-sub-item relative', className)}
18 {...restProps}
19>
20 {@render children?.()}
21</li>
diff --git a/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte
new file mode 100644
index 0000000..5458ced
--- /dev/null
+++ b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte
@@ -0,0 +1,25 @@
1<script lang="ts">
2 import { cn, type WithElementRef } from '$lib/components/ui/utils.js';
3 import type { HTMLAttributes } from 'svelte/elements';
4
5 let {
6 ref = $bindable(null),
7 class: className,
8 children,
9 ...restProps
10 }: WithElementRef<HTMLAttributes<HTMLUListElement>> = $props();
11</script>
12
13<ul
14 bind:this={ref}
15 data-slot="sidebar-menu-sub"
16 data-sidebar="menu-sub"
17 class={cn(
18 'mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5',
19 'group-data-[collapsible=icon]:hidden',
20 className
21 )}
22 {...restProps}
23>
24 {@render children?.()}
25</ul>
diff --git a/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu.svelte b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu.svelte
new file mode 100644
index 0000000..fee96ed
--- /dev/null
+++ b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu.svelte
@@ -0,0 +1,21 @@
1<script lang="ts">
2 import { cn, type WithElementRef } from '$lib/components/ui/utils.js';
3 import type { HTMLAttributes } from 'svelte/elements';
4
5 let {
6 ref = $bindable(null),
7 class: className,
8 children,
9 ...restProps
10 }: WithElementRef<HTMLAttributes<HTMLUListElement>, HTMLUListElement> = $props();
11</script>
12
13<ul
14 bind:this={ref}
15 data-slot="sidebar-menu"
16 data-sidebar="menu"
17 class={cn('flex w-full min-w-0 flex-col gap-1', className)}
18 {...restProps}
19>
20 {@render children?.()}
21</ul>
diff --git a/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-provider.svelte b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-provider.svelte
new file mode 100644
index 0000000..364235a
--- /dev/null
+++ b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-provider.svelte
@@ -0,0 +1,50 @@
1<script lang="ts">
2 import { cn, type WithElementRef } from '$lib/components/ui/utils.js';
3 import type { HTMLAttributes } from 'svelte/elements';
4 import {
5 SIDEBAR_COOKIE_MAX_AGE,
6 SIDEBAR_COOKIE_NAME,
7 SIDEBAR_WIDTH,
8 SIDEBAR_WIDTH_ICON
9 } from './constants.js';
10 import { setSidebar } from './context.svelte.js';
11
12 let {
13 ref = $bindable(null),
14 open = $bindable(true),
15 onOpenChange = () => {},
16 class: className,
17 style,
18 children,
19 ...restProps
20 }: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
21 open?: boolean;
22 onOpenChange?: (open: boolean) => void;
23 } = $props();
24
25 const sidebar = setSidebar({
26 open: () => open,
27 setOpen: (value: boolean) => {
28 open = value;
29 onOpenChange(value);
30
31 // This sets the cookie to keep the sidebar state.
32 document.cookie = `${SIDEBAR_COOKIE_NAME}=${open}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
33 }
34 });
35</script>
36
37<svelte:window onkeydown={sidebar.handleShortcutKeydown} />
38
39<div
40 data-slot="sidebar-wrapper"
41 style="--sidebar-width: {SIDEBAR_WIDTH}; --sidebar-width-icon: {SIDEBAR_WIDTH_ICON}; {style}"
42 class={cn(
43 'group/sidebar-wrapper flex min-h-svh w-full has-data-[variant=inset]:bg-sidebar',
44 className
45 )}
46 bind:this={ref}
47 {...restProps}
48>
49 {@render children?.()}
50</div>
diff --git a/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-rail.svelte b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-rail.svelte
new file mode 100644
index 0000000..cde9307
--- /dev/null
+++ b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-rail.svelte
@@ -0,0 +1,36 @@
1<script lang="ts">
2 import { cn, type WithElementRef } from '$lib/components/ui/utils.js';
3 import type { HTMLAttributes } from 'svelte/elements';
4 import { useSidebar } from './context.svelte.js';
5
6 let {
7 ref = $bindable(null),
8 class: className,
9 children,
10 ...restProps
11 }: WithElementRef<HTMLAttributes<HTMLButtonElement>, HTMLButtonElement> = $props();
12
13 const sidebar = useSidebar();
14</script>
15
16<button
17 bind:this={ref}
18 data-sidebar="rail"
19 data-slot="sidebar-rail"
20 aria-label="Toggle Sidebar"
21 tabIndex={-1}
22 onclick={sidebar.toggle}
23 title="Toggle Sidebar"
24 class={cn(
25 'absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-[calc(1/2*100%-1px)] after:w-[2px] hover:after:bg-sidebar-border sm:flex',
26 'in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize',
27 '[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize',
28 'group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full hover:group-data-[collapsible=offcanvas]:bg-sidebar',
29 '[[data-side=left][data-collapsible=offcanvas]_&]:-right-2',
30 '[[data-side=right][data-collapsible=offcanvas]_&]:-left-2',
31 className
32 )}
33 {...restProps}
34>
35 {@render children?.()}
36</button>
diff --git a/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-separator.svelte b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-separator.svelte
new file mode 100644
index 0000000..8fc2065
--- /dev/null
+++ b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-separator.svelte
@@ -0,0 +1,19 @@
1<script lang="ts">
2 import { Separator } from '$lib/components/ui/separator/index.js';
3 import { cn } from '$lib/components/ui/utils.js';
4 import type { ComponentProps } from 'svelte';
5
6 let {
7 ref = $bindable(null),
8 class: className,
9 ...restProps
10 }: ComponentProps<typeof Separator> = $props();
11</script>
12
13<Separator
14 bind:ref
15 data-slot="sidebar-separator"
16 data-sidebar="separator"
17 class={cn('bg-sidebar-border', className)}
18 {...restProps}
19/>
diff --git a/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-trigger.svelte b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-trigger.svelte
new file mode 100644
index 0000000..29d3a9c
--- /dev/null
+++ b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-trigger.svelte
@@ -0,0 +1,35 @@
1<script lang="ts">
2 import { Button } from '$lib/components/ui/button/index.js';
3 import { cn } from '$lib/components/ui/utils.js';
4 import PanelLeftIcon from '@lucide/svelte/icons/panel-left';
5 import type { ComponentProps } from 'svelte';
6 import { useSidebar } from './context.svelte.js';
7
8 let {
9 ref = $bindable(null),
10 class: className,
11 onclick,
12 ...restProps
13 }: ComponentProps<typeof Button> & {
14 onclick?: (e: MouseEvent) => void;
15 } = $props();
16
17 const sidebar = useSidebar();
18</script>
19
20<Button
21 data-sidebar="trigger"
22 data-slot="sidebar-trigger"
23 variant="ghost"
24 size="icon"
25 class={cn('size-7', className)}
26 type="button"
27 onclick={(e) => {
28 onclick?.(e);
29 sidebar.toggle();
30 }}
31 {...restProps}
32>
33 <PanelLeftIcon />
34 <span class="sr-only">Toggle Sidebar</span>
35</Button>
diff --git a/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar.svelte b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar.svelte
new file mode 100644
index 0000000..e2c4a75
--- /dev/null
+++ b/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar.svelte
@@ -0,0 +1,101 @@
1<script lang="ts">
2 import * as Sheet from '$lib/components/ui/sheet/index.js';
3 import { cn, type WithElementRef } from '$lib/components/ui/utils.js';
4 import type { HTMLAttributes } from 'svelte/elements';
5 import { SIDEBAR_WIDTH_MOBILE } from './constants.js';
6 import { useSidebar } from './context.svelte.js';
7
8 let {
9 ref = $bindable(null),
10 side = 'left',
11 variant = 'sidebar',
12 collapsible = 'offcanvas',
13 class: className,
14 children,
15 ...restProps
16 }: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
17 side?: 'left' | 'right';
18 variant?: 'sidebar' | 'floating' | 'inset';
19 collapsible?: 'offcanvas' | 'icon' | 'none';
20 } = $props();
21
22 const sidebar = useSidebar();
23</script>
24
25{#if collapsible === 'none'}
26 <div
27 class={cn(
28 'flex h-full w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground',
29 className
30 )}
31 bind:this={ref}
32 {...restProps}
33 >
34 {@render children?.()}
35 </div>
36{:else if sidebar.isMobile}
37 <Sheet.Root bind:open={() => sidebar.openMobile, (v) => sidebar.setOpenMobile(v)} {...restProps}>
38 <Sheet.Content
39 data-sidebar="sidebar"
40 data-slot="sidebar"
41 data-mobile="true"
42 class="z-99999 w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground sm:z-99 [&>button]:hidden"
43 style="--sidebar-width: {SIDEBAR_WIDTH_MOBILE};"
44 {side}
45 >
46 <Sheet.Header class="sr-only">
47 <Sheet.Title>Sidebar</Sheet.Title>
48 <Sheet.Description>Displays the mobile sidebar.</Sheet.Description>
49 </Sheet.Header>
50 <div class="flex h-full w-full flex-col">
51 {@render children?.()}
52 </div>
53 </Sheet.Content>
54 </Sheet.Root>
55{:else}
56 <div
57 bind:this={ref}
58 class="group peer hidden text-sidebar-foreground md:block"
59 data-state={sidebar.state}
60 data-collapsible={sidebar.state === 'collapsed' ? collapsible : ''}
61 data-variant={variant}
62 data-side={side}
63 data-slot="sidebar"
64 >
65 <!-- This is what handles the sidebar gap on desktop -->
66 <div
67 data-slot="sidebar-gap"
68 class={cn(
69 'relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear',
70 'group-data-[collapsible=offcanvas]:w-0',
71 'group-data-[side=right]:rotate-180',
72 variant === 'floating' || variant === 'inset'
73 ? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]'
74 : 'group-data-[collapsible=icon]:w-(--sidebar-width-icon)'
75 )}
76 ></div>
77 <div
78 data-slot="sidebar-container"
79 class={cn(
80 'fixed inset-y-0 z-999 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:z-0 md:flex',
81 side === 'left'
82 ? 'left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]'
83 : 'right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]',
84 // Adjust the padding for floating and inset variants.
85 variant === 'floating' || variant === 'inset'
86 ? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]'
87 : 'group-data-[collapsible=icon]:w-(--sidebar-width-icon)',
88 className
89 )}
90 {...restProps}
91 >
92 <div
93 data-sidebar="sidebar"
94 data-slot="sidebar-inner"
95 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"
96 >
97 {@render children?.()}
98 </div>
99 </div>
100 </div>
101{/if}