Files
dotter/resources/js/components/ui/sidebar/SidebarMenuButton.svelte
T
salam e687b4437b
linter / quality (push) Canceled after 0s
tests / ci (8.3) (push) Canceled after 0s
tests / ci (8.4) (push) Canceled after 0s
tests / ci (8.5) (push) Canceled after 0s
first commit
2026-10-06 18:53:03 +02:00

105 lines
3.9 KiB
Svelte

<script lang="ts">
import type { Snippet } from 'svelte';
import { getContext } from 'svelte';
import { cn } from '@/lib/utils';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { SIDEBAR_CONTEXT, type SidebarContext } from './context';
type Size = 'default' | 'lg';
type AsChildProps = {
class?: string;
[key: string]: any;
};
let {
asChild = false,
class: className = '',
isActive = false,
size = 'default',
tooltip,
children,
...rest
}: {
asChild?: boolean;
class?: string;
isActive?: boolean;
size?: Size;
tooltip?: string;
children?: Snippet<[AsChildProps]>;
[key: string]: unknown;
} = $props();
const { isMobile, state } = getContext<SidebarContext>(SIDEBAR_CONTEXT);
const base =
'peer/menu-button ring-sidebar-ring flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium 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! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0';
const sizeClasses: Record<Size, string> = {
default: 'h-8 text-sm',
lg: 'h-12 text-sm group-data-[collapsible=icon]:p-0!',
};
const classes = () => {
const activeClasses = isActive ? 'bg-sidebar-accent font-medium text-sidebar-accent-foreground' : '';
return cn(base, sizeClasses[size], activeClasses, className);
};
</script>
{#if tooltip}
<Tooltip disabled={$state !== 'collapsed' || $isMobile}>
<TooltipTrigger>
{#snippet child({ props: triggerProps })}
{#if asChild}
{@render children?.({
class: classes(),
'data-slot': 'sidebar-menu-button',
'data-sidebar': 'menu-button',
'data-size': size,
'data-active': isActive,
...rest,
...triggerProps,
})}
{:else}
<button
class={classes()}
type="button"
data-slot="sidebar-menu-button"
data-sidebar="menu-button"
data-size={size}
data-active={isActive}
{...rest}
{...triggerProps}
>
{@render children?.({})}
</button>
{/if}
{/snippet}
</TooltipTrigger>
<TooltipContent side="right" align="center">
{tooltip}
</TooltipContent>
</Tooltip>
{:else}
{#if asChild}
{@render children?.({
class: classes(),
'data-slot': 'sidebar-menu-button',
'data-sidebar': 'menu-button',
'data-size': size,
'data-active': isActive,
...rest,
})}
{:else}
<button
class={classes()}
type="button"
data-slot="sidebar-menu-button"
data-sidebar="menu-button"
data-size={size}
data-active={isActive}
{...rest}
>
{@render children?.({})}
</button>
{/if}
{/if}