Dead imports and locals removed, each blocks keyed, `any` narrowed to unknown. Two context setters kept their calls and lost only the unused binding; the settings redirect no longer awaits a parent whose data it discards. A leading underscore now marks a binding that only holds a position.
82 lines
3.1 KiB
Svelte
82 lines
3.1 KiB
Svelte
<script lang="ts">
|
|
import * as DropdownMenu from '$lib/components/ui/dropdown-menu/index.js';
|
|
import * as Sidebar from '$lib/components/ui/sidebar/index.js';
|
|
import { useSidebar } from '$lib/components/ui/sidebar/index.js';
|
|
import { Badge } from '$lib/components/ui/badge/index.js';
|
|
import { getLibraryState } from '$lib/state/library.svelte';
|
|
import { LIBRARY_ICONS } from '$lib/components/ui/icon-picker/index.js';
|
|
import ChevronsUpDownIcon from '@lucide/svelte/icons/chevrons-up-down';
|
|
import PlusIcon from '@lucide/svelte/icons/plus';
|
|
import LibraryCreateForm from '../forms/library-create-form.svelte';
|
|
|
|
const libraryState = getLibraryState();
|
|
const sidebar = useSidebar();
|
|
|
|
const activeIcon = $derived(
|
|
LIBRARY_ICONS[libraryState.activeLibrary?.icon ?? 'library'] ?? LIBRARY_ICONS['library']
|
|
);
|
|
</script>
|
|
|
|
<Sidebar.Menu>
|
|
<Sidebar.MenuItem>
|
|
<DropdownMenu.Root>
|
|
<DropdownMenu.Trigger>
|
|
{#snippet child({ props })}
|
|
<Sidebar.MenuButton
|
|
{...props}
|
|
size="lg"
|
|
class="ml-2 data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
|
|
>
|
|
{@const ActiveIcon = activeIcon.component}
|
|
<div
|
|
class="flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground"
|
|
>
|
|
<ActiveIcon class="size-4" />
|
|
</div>
|
|
<div class="grid flex-1 text-left text-sm leading-tight">
|
|
<span class="ml-1 truncate font-semibold">
|
|
{libraryState.activeLibrary!.name}
|
|
</span>
|
|
<span class="ml-1 truncate font-mono text-xs text-muted-foreground tabular-nums">
|
|
{libraryState.activeLibrary!.total ?? 0} books
|
|
</span>
|
|
</div>
|
|
<ChevronsUpDownIcon class="mr-2 ml-auto" />
|
|
</Sidebar.MenuButton>
|
|
{/snippet}
|
|
</DropdownMenu.Trigger>
|
|
<DropdownMenu.Content
|
|
class="w-(--bits-dropdown-menu-anchor-width) min-w-56 rounded-lg"
|
|
align="start"
|
|
side={sidebar.isMobile ? 'bottom' : 'right'}
|
|
sideOffset={4}
|
|
>
|
|
<DropdownMenu.Label class="text-xs text-muted-foreground">Libraries</DropdownMenu.Label>
|
|
{#each libraryState.libraries as library (library.name)}
|
|
{@const LibraryIcon = (
|
|
LIBRARY_ICONS[library.icon ?? 'library'] ?? LIBRARY_ICONS['library']
|
|
).component}
|
|
<DropdownMenu.Item onSelect={() => libraryState.setActive(library.id)} class="gap-2 p-2">
|
|
<div class="flex size-6 items-center justify-center rounded-md border">
|
|
<LibraryIcon class="size-3.5 shrink-0" />
|
|
</div>
|
|
{library.name}
|
|
<Badge variant="outline" class="ml-auto font-semibold">
|
|
{library.total ?? 0}
|
|
</Badge>
|
|
</DropdownMenu.Item>
|
|
{/each}
|
|
<DropdownMenu.Separator />
|
|
<DropdownMenu.Item onclick={() => libraryState.openLibraryCreateDialog()} class="gap-2 p-2">
|
|
<div class="flex size-6 items-center justify-center rounded-md border bg-transparent">
|
|
<PlusIcon class="size-4" />
|
|
</div>
|
|
<div class="font-medium text-muted-foreground">Add library</div>
|
|
</DropdownMenu.Item>
|
|
</DropdownMenu.Content>
|
|
</DropdownMenu.Root>
|
|
</Sidebar.MenuItem>
|
|
</Sidebar.Menu>
|
|
|
|
<LibraryCreateForm bind:open={libraryState.createDialogOpen} />
|