Files
EvoBGP/web/src/lib/ui/app/layout/app-nav-links.svelte
T
Denozordec c263fd5c7e
CI / changes (push) Successful in 7s
CI / openapi (push) Has been skipped
CI / web (push) Successful in 29s
CI / go (push) Has been skipped
CI / docker-web (push) Successful in 1m22s
CI / docker-bird (push) Has been skipped
CI / bird2 (push) Has been skipped
CI / docker-go (push) Has been skipped
refactor: improve code consistency and formatting across components
- Standardized formatting in various Svelte components for better readability.
- Updated README.md and .prettierrc for consistent styling and improved documentation.
- Refactored class attributes in UI components to enhance clarity and maintainability.
- Adjusted layout files to ensure proper alignment and spacing in the application interface.
2026-05-20 00:37:00 +07:00

97 lines
2.7 KiB
Svelte

<script lang="ts">
import { resolve } from '$app/paths';
import { page } from '$app/state';
import { cn } from '$lib/utils.js';
import { buttonVariants } from '$lib/ui/core/button/index.js';
import { Separator } from '$lib/ui/core/separator/index.js';
import { Tooltip, TooltipContent, TooltipTrigger } from '$lib/ui/core/tooltip/index.js';
import { bottomNav, mainNav } from './nav.js';
type Props = {
collapsed?: boolean;
onNavigate?: () => void;
};
let { collapsed = false, onNavigate }: Props = $props();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const navHref = (href: string) => resolve(href as any);
function isActive(href: string) {
const pathname = page.url.pathname;
if (href === '/') return pathname === '/';
return pathname === href || pathname.startsWith(href + '/');
}
function linkClass(active: boolean, iconOnly: boolean) {
return cn(
buttonVariants({
variant: active ? 'secondary' : 'ghost',
size: iconOnly ? 'icon-sm' : 'sm'
}),
iconOnly
? 'flex w-full items-center justify-center no-underline'
: 'flex w-full items-center justify-start gap-2 no-underline',
active &&
(iconOnly
? 'ring-sidebar-primary/50 bg-sidebar-accent/90 text-sidebar-accent-foreground ring-1'
: 'border-l-sidebar-primary bg-sidebar-accent/80 text-sidebar-accent-foreground border-l-2 shadow-sm')
);
}
</script>
<nav class="flex flex-1 flex-col gap-0.5 overflow-y-auto p-2">
{#each mainNav as item (item.href)}
{@const Icon = item.icon}
{@const active = isActive(item.href)}
{#if collapsed}
<Tooltip>
<TooltipTrigger>
<a
href={navHref(item.href)}
class={linkClass(active, true)}
aria-current={active ? 'page' : undefined}
onclick={onNavigate}
>
<Icon class="size-4" />
</a>
</TooltipTrigger>
<TooltipContent side="right">{item.label}</TooltipContent>
</Tooltip>
{:else}
<a
href={navHref(item.href)}
class={linkClass(active, false)}
aria-current={active ? 'page' : undefined}
onclick={onNavigate}
>
<Icon class="size-4" />
{item.label}
</a>
{/if}
{/each}
</nav>
<div class="flex flex-col gap-0.5 p-2">
<Separator class="mb-2" />
{#each bottomNav as item (item.href)}
{@const Icon = item.icon}
{@const active = isActive(item.href)}
{#if collapsed}
<Tooltip>
<TooltipTrigger>
<a href={navHref(item.href)} class={linkClass(active, true)} onclick={onNavigate}>
<Icon class="size-4" />
</a>
</TooltipTrigger>
<TooltipContent side="right">{item.label}</TooltipContent>
</Tooltip>
{:else}
<a href={navHref(item.href)} class={linkClass(active, false)} onclick={onNavigate}>
<Icon class="size-4" />
{item.label}
</a>
{/if}
{/each}
</div>