aboutsummaryrefslogtreecommitdiff
path: root/llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-button.svelte
diff options
context:
space:
mode:
Diffstat (limited to 'llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-button.svelte')
-rw-r--r--llama.cpp/tools/server/webui/src/lib/components/ui/sidebar/sidebar-menu-button.svelte106
1 files changed, 106 insertions, 0 deletions
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}