refactor: header user menu with bits-ui dropdown, collapsible sidebar boards
- Replace manual click-outside menu with DropdownMenu from bits-ui - Add collapsible boards section in sidebar with chevron toggle - Add max-height scroll for boards list
This commit is contained in:
@@ -19,6 +19,8 @@
|
||||
|
||||
let { boards, isAdmin, collapsed }: Props = $props();
|
||||
|
||||
let boardsExpanded = $state(true);
|
||||
|
||||
function isActive(path: string): boolean {
|
||||
return $page.url.pathname.startsWith(path);
|
||||
}
|
||||
@@ -158,36 +160,54 @@
|
||||
{#if boards.length > 0}
|
||||
<div class="mb-3">
|
||||
{#if !collapsed}
|
||||
<p
|
||||
class="mb-1 px-2 text-xs font-medium uppercase tracking-wider text-sidebar-foreground/50"
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => (boardsExpanded = !boardsExpanded)}
|
||||
class="mb-1 flex w-full items-center justify-between px-2 text-xs font-medium uppercase tracking-wider text-sidebar-foreground/50 transition-colors hover:text-sidebar-foreground/80"
|
||||
>
|
||||
{$t('nav.boards')}
|
||||
</p>
|
||||
<span>{$t('nav.boards')}</span>
|
||||
<svg
|
||||
class="h-3 w-3 transition-transform duration-200"
|
||||
class:rotate-180={boardsExpanded}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<polyline points="6 9 12 15 18 9" />
|
||||
</svg>
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
{#each boards as board (board.id)}
|
||||
<a
|
||||
href="/boards/{board.id}"
|
||||
class="flex items-center gap-2 rounded-md px-2 py-1.5 text-sm transition-colors {isActive(`/boards/${board.id}`)
|
||||
? 'bg-sidebar-accent text-sidebar-accent-foreground'
|
||||
: 'text-sidebar-foreground hover:bg-sidebar-accent/50'}"
|
||||
title={collapsed ? board.name : undefined}
|
||||
onclick={() => ui.closeMobileSidebar()}
|
||||
>
|
||||
{#if board.icon}
|
||||
<span class="shrink-0"><DynamicIcon name={board.icon} size={18} /></span>
|
||||
{:else}
|
||||
<span
|
||||
class="flex h-5 w-5 shrink-0 items-center justify-center rounded bg-sidebar-accent text-[10px] font-medium text-sidebar-foreground"
|
||||
{#if boardsExpanded || collapsed}
|
||||
<div class="max-h-48 overflow-y-auto">
|
||||
{#each boards as board (board.id)}
|
||||
<a
|
||||
href="/boards/{board.id}"
|
||||
class="flex items-center gap-2 rounded-md px-2 py-1.5 text-sm transition-colors {isActive(`/boards/${board.id}`)
|
||||
? 'bg-sidebar-accent text-sidebar-accent-foreground'
|
||||
: 'text-sidebar-foreground hover:bg-sidebar-accent/50'}"
|
||||
title={collapsed ? board.name : undefined}
|
||||
onclick={() => ui.closeMobileSidebar()}
|
||||
>
|
||||
{board.name.charAt(0).toUpperCase()}
|
||||
</span>
|
||||
{/if}
|
||||
{#if !collapsed}
|
||||
<span class="truncate">{board.name}</span>
|
||||
{/if}
|
||||
</a>
|
||||
{/each}
|
||||
{#if board.icon}
|
||||
<span class="shrink-0"><DynamicIcon name={board.icon} size={18} /></span>
|
||||
{:else}
|
||||
<span
|
||||
class="flex h-5 w-5 shrink-0 items-center justify-center rounded bg-sidebar-accent text-[10px] font-medium text-sidebar-foreground"
|
||||
>
|
||||
{board.name.charAt(0).toUpperCase()}
|
||||
</span>
|
||||
{/if}
|
||||
{#if !collapsed}
|
||||
<span class="truncate">{board.name}</span>
|
||||
{/if}
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user