82 lines
3.9 KiB
Svelte
82 lines
3.9 KiB
Svelte
<script lang="ts">
|
|
import * as Collapsible from "$lib/components/ui/collapsible/index.js";
|
|
import * as Sidebar from "$lib/components/ui/sidebar/index.js";
|
|
import type { AppSidebarItem } from "$lib/core/constants";
|
|
import ChevronRight from "@lucide/svelte/icons/chevron-right";
|
|
import Icon from "./atoms/icon.svelte";
|
|
|
|
let { items }: { items: AppSidebarItem[] } = $props();
|
|
|
|
const sidebar = Sidebar.useSidebar();
|
|
</script>
|
|
|
|
<Sidebar.Group>
|
|
<Sidebar.Menu>
|
|
{#each items as mainItem (mainItem.title)}
|
|
<Collapsible.Root
|
|
open={mainItem.isActive}
|
|
class="group/collapsible"
|
|
>
|
|
<Sidebar.MenuItem>
|
|
<!-- Split the behavior: main button redirects, chevron expands -->
|
|
<div class="flex w-full items-center">
|
|
<!-- Main navigation button that redirects -->
|
|
<Sidebar.MenuButton class="flex-1 pr-1">
|
|
{#snippet child({ props })}
|
|
<a href={mainItem.url} {...props}>
|
|
{#if mainItem.icon}
|
|
<mainItem.icon />
|
|
{/if}
|
|
<span>{mainItem.title}</span>
|
|
</a>
|
|
{/snippet}
|
|
</Sidebar.MenuButton>
|
|
|
|
<!-- Chevron button that only toggles the collapsible content -->
|
|
{#if mainItem.items && sidebar.open}
|
|
<Collapsible.Trigger class="p-2">
|
|
{#snippet child({ props })}
|
|
<div
|
|
{...props}
|
|
class="bg-background hover:bg-accent flex cursor-pointer items-center justify-center rounded-sm p-1"
|
|
>
|
|
<Icon
|
|
icon={ChevronRight}
|
|
cls="w-4 h-4 transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90"
|
|
/>
|
|
<span class="sr-only"
|
|
>Toggle {mainItem.title} submenu</span
|
|
>
|
|
</div>
|
|
{/snippet}
|
|
</Collapsible.Trigger>
|
|
{/if}
|
|
</div>
|
|
|
|
<!-- Collapsible submenu content -->
|
|
<Collapsible.Content>
|
|
{#if mainItem.items}
|
|
<Sidebar.MenuSub>
|
|
{#each mainItem.items as subItem (subItem.title)}
|
|
<Sidebar.MenuSubItem>
|
|
<Sidebar.MenuSubButton>
|
|
{#snippet child({ props })}
|
|
<a
|
|
href={subItem.url}
|
|
{...props}
|
|
>
|
|
<span>{subItem.title}</span>
|
|
</a>
|
|
{/snippet}
|
|
</Sidebar.MenuSubButton>
|
|
</Sidebar.MenuSubItem>
|
|
{/each}
|
|
</Sidebar.MenuSub>
|
|
{/if}
|
|
</Collapsible.Content>
|
|
</Sidebar.MenuItem>
|
|
</Collapsible.Root>
|
|
{/each}
|
|
</Sidebar.Menu>
|
|
</Sidebar.Group>
|