You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/web/routes/active/_components/Sidebar.svelte

189 lines
3.6 KiB

<script lang="ts">
import { page } from '$app/state';
import type { NavSection } from '../_data/nav';
let { nav }: { nav: readonly NavSection[] } = $props();
const currentPath = $derived(page.url.pathname.replace(/\/$/, ''));
function isActive(href: string): boolean {
const normalized = href.replace(/\/$/, '');
return currentPath === normalized;
}
</script>
<nav class="sidebar" aria-label="Documentation">
{#each nav as section (section.title)}
<div class="section">
<h3 class="section-title">{section.title}</h3>
<ul>
{#each section.items as item (item.href)}
<li>
<a
href={item.href}
class="link"
class:active={isActive(item.href)}
aria-current={isActive(item.href) ? 'page' : undefined}
>
<span class="link-label">
<span>{item.label}</span>
{#if item.alias}
<span class="alias">{item.alias}</span>
{/if}
</span>
{#if item.tag}
<span class="badge" data-tag={item.tag}>{item.tag}</span>
{/if}
</a>
</li>
{/each}
</ul>
</div>
{/each}
</nav>
<style>
.sidebar {
padding: 1.25rem 0.65rem 3rem;
font-size: 0.875rem;
}
.section {
margin-bottom: 1.5rem;
}
.section + .section {
padding-top: 1rem;
border-top: 1px dashed var(--c-border);
}
.section-title {
font-size: 0.7rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.09em;
color: var(--c-fg-subtle);
margin: 0 0 0.55rem;
padding: 0 0.75rem;
}
ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 1px;
}
.link {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
gap: 0.5rem;
padding: 0.4rem 0.75rem;
border-radius: var(--r-md);
color: var(--c-fg-muted);
font-weight: 500;
line-height: 1.4;
transition:
background-color 120ms var(--ease),
color 120ms var(--ease);
}
.link::before {
content: '';
position: absolute;
left: 0;
top: 50%;
width: 2px;
height: 0;
background: var(--c-accent);
border-radius: 2px;
transform: translateY(-50%);
transition: height 180ms var(--ease);
}
.link.active::before {
height: 60%;
}
.link-label {
display: inline-flex;
align-items: baseline;
gap: 0.4rem;
min-width: 0;
}
.alias {
font-family: var(--font-mono);
font-size: 0.7rem;
font-weight: 500;
color: var(--c-fg-subtle);
}
.link.active .alias {
color: var(--c-accent);
opacity: 0.8;
}
.link:hover {
background: var(--c-bg-muted);
color: var(--c-fg);
text-decoration: none;
}
.link.active {
background: var(--c-accent-muted);
color: var(--c-accent-emphasized);
font-weight: 600;
}
:global([data-theme='dark']) .link.active {
background: var(--c-accent-subtle);
color: var(--c-fg);
}
:global([data-theme='dark']) .link.active .alias {
color: var(--c-accent-emphasized);
opacity: 1;
}
.badge {
font-size: 0.65rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.04em;
padding: 0.05em 0.4em;
border-radius: var(--r-sm);
background: var(--c-bg-muted);
color: var(--c-fg-subtle);
border: 1px solid var(--c-border);
}
.badge[data-tag='new'] {
background: var(--c-accent-muted);
color: var(--c-accent-emphasized);
border-color: var(--c-accent-subtle);
}
.badge[data-tag='beta'] {
background: #fef3c7;
color: #92400e;
border-color: #fde68a;
}
:global([data-theme='dark']) .badge[data-tag='beta'] {
background: #422006;
color: #fbbf24;
border-color: #78350f;
}
.badge[data-tag='stub'] {
background: var(--c-bg-muted);
color: var(--c-fg-subtle);
border-color: var(--c-border);
}
</style>

Powered by TurnKey Linux.