80 lines
3.0 KiB
Plaintext
80 lines
3.0 KiB
Plaintext
component Sidebar {
|
|
props {
|
|
@event toggle = function
|
|
@event open = function
|
|
@event close = function
|
|
@event select = function
|
|
size = "default"
|
|
color = "primary"
|
|
label = "Sidebar"
|
|
items = []
|
|
active = ""
|
|
orientation = "horizontal"
|
|
mobileLabel = "Open navigation"
|
|
class = ""
|
|
}
|
|
|
|
state mobileOpen = false
|
|
|
|
functions {
|
|
function toggleSidebar() {
|
|
mobileOpen = !mobileOpen
|
|
$emit("toggle", { open: mobileOpen })
|
|
$emit(mobileOpen ? "open" : "close", { source: "mobile" })
|
|
}
|
|
|
|
function closeSidebar() {
|
|
mobileOpen = false
|
|
$emit("close", { source: "mobile" })
|
|
}
|
|
|
|
function selectItem(item, level) {
|
|
mobileOpen = false
|
|
$emit("select", { item: item, value: item.value || "", level: level })
|
|
}
|
|
}
|
|
|
|
view {
|
|
<div class="wire-sidebar-shell wire-next--color-{color} wire-next--size-{size} {mobileOpen ? 'is-open' : ''} {class}">
|
|
<button type="button" class="wire-sidebar-toggle" aria-label="{mobileLabel}" aria-expanded="{mobileOpen}" @click="toggleSidebar()">
|
|
<span class="icon-[lucide--panel-left-open]" aria-hidden="true"></span>
|
|
<span>{label}</span>
|
|
</button>
|
|
<button type="button" class="wire-sidebar-backdrop" aria-label="Close navigation" @click="closeSidebar()"></button>
|
|
<nav class="wire-next wire-next--sidebar wire-next--{orientation} wire-sidebar-panel" aria-label="{label}">
|
|
<div class="wire-sidebar-panel__head">
|
|
<strong>{label}</strong>
|
|
<button type="button" aria-label="Close navigation" @click="closeSidebar()"><span class="icon-[lucide--x]" aria-hidden="true"></span></button>
|
|
</div>
|
|
<div class="wire-sidebar-items">
|
|
{#each items as item}
|
|
{#if item.children && item.children.length}
|
|
<details class="wire-sidebar-group" name="wire-sidebar-group">
|
|
<summary>
|
|
{#if item.icon}<span class="{item.icon}" aria-hidden="true"></span>{/if}
|
|
<span>{item.label}</span>
|
|
<span class="icon-[lucide--chevron-down]" aria-hidden="true"></span>
|
|
</summary>
|
|
<div class="wire-sidebar-group__children">
|
|
{#each item.children as child}
|
|
<a href="{child.href || '#'}" aria-current="{child.value === active ? 'page' : ''}" @click="selectItem(child, 2)">
|
|
{#if child.icon}<span class="{child.icon}" aria-hidden="true"></span>{/if}
|
|
<span>{child.label}</span>
|
|
</a>
|
|
{/each}
|
|
</div>
|
|
</details>
|
|
{:else}
|
|
<a href="{item.href || '#'}" aria-current="{item.value === active ? 'page' : ''}" @click="selectItem(item, 1)">
|
|
{#if item.icon}<span class="{item.icon}" aria-hidden="true"></span>{/if}
|
|
<span>{item.label}</span>
|
|
</a>
|
|
{/if}
|
|
{/each}
|
|
</div>
|
|
<slot />
|
|
</nav>
|
|
</div>
|
|
}
|
|
}
|