& so it begins
This commit is contained in:
81
apps/main/src/lib/components/nav-main.svelte
Normal file
81
apps/main/src/lib/components/nav-main.svelte
Normal file
@@ -0,0 +1,81 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user