From 22d459f47571a9f80b76c51eb59eb3368d03a7d4 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Fri, 19 Dec 2025 00:39:59 -0800 Subject: [PATCH] add selection mode store and components for bulk actions --- .../collection/BulkDeleteConfirmModal.svelte | 60 +++++++++++++ .../SelectableCollectionCard.svelte | 82 +++++++++++++++++ .../collection/SelectableCollectionRow.svelte | 80 +++++++++++++++++ src/lib/stores/selectionMode.svelte.ts | 87 +++++++++++++++++++ 4 files changed, 309 insertions(+) create mode 100644 src/lib/components/collection/BulkDeleteConfirmModal.svelte create mode 100644 src/lib/components/collection/SelectableCollectionCard.svelte create mode 100644 src/lib/components/collection/SelectableCollectionRow.svelte create mode 100644 src/lib/stores/selectionMode.svelte.ts diff --git a/src/lib/components/collection/BulkDeleteConfirmModal.svelte b/src/lib/components/collection/BulkDeleteConfirmModal.svelte new file mode 100644 index 00000000..2d8913ce --- /dev/null +++ b/src/lib/components/collection/BulkDeleteConfirmModal.svelte @@ -0,0 +1,60 @@ + + + + {#snippet children()} + + +

+ Are you sure you want to remove {count} + {itemLabel} from your collection? This action cannot be undone. +

+
+ + {/snippet} +
+ + diff --git a/src/lib/components/collection/SelectableCollectionCard.svelte b/src/lib/components/collection/SelectableCollectionCard.svelte new file mode 100644 index 00000000..d2ce6fb0 --- /dev/null +++ b/src/lib/components/collection/SelectableCollectionCard.svelte @@ -0,0 +1,82 @@ + + +
+ {#if selectionMode?.isActive} + + +
+ +
+ {/if} + + +
+ {@render children()} +
+
+ + diff --git a/src/lib/components/collection/SelectableCollectionRow.svelte b/src/lib/components/collection/SelectableCollectionRow.svelte new file mode 100644 index 00000000..2667c59c --- /dev/null +++ b/src/lib/components/collection/SelectableCollectionRow.svelte @@ -0,0 +1,80 @@ + + +
+ {#if selectionMode?.isActive} + + +
+ +
+ {/if} + + +
+ {@render children()} +
+
+ + diff --git a/src/lib/stores/selectionMode.svelte.ts b/src/lib/stores/selectionMode.svelte.ts new file mode 100644 index 00000000..8c2d36fa --- /dev/null +++ b/src/lib/stores/selectionMode.svelte.ts @@ -0,0 +1,87 @@ +/** + * Selection mode store for collection bulk operations. + * Used to manage multi-select state across collection pages. + */ + +export type EntityType = 'characters' | 'weapons' | 'summons' | 'artifacts' + +export interface SelectionModeContext { + readonly isActive: boolean + readonly entityType: EntityType | null + readonly selectedIds: Set + readonly selectedCount: number + enter: (type: EntityType) => void + exit: () => void + toggle: (id: string) => void + selectAll: (ids: string[]) => void + clearSelection: () => void + isSelected: (id: string) => boolean +} + +/** + * Creates a selection mode context for managing bulk selection state. + * Should be created in the collection layout and provided via Svelte context. + */ +export function createSelectionModeContext(): SelectionModeContext { + let isActive = $state(false) + let entityType = $state(null) + let selectedIds = $state>(new Set()) + + return { + get isActive() { + return isActive + }, + get entityType() { + return entityType + }, + get selectedIds() { + return selectedIds + }, + get selectedCount() { + return selectedIds.size + }, + + enter(type: EntityType) { + isActive = true + entityType = type + selectedIds = new Set() + }, + + exit() { + isActive = false + entityType = null + selectedIds = new Set() + }, + + toggle(id: string) { + const newSet = new Set(selectedIds) + if (newSet.has(id)) { + newSet.delete(id) + } else { + newSet.add(id) + } + selectedIds = newSet + }, + + selectAll(ids: string[]) { + selectedIds = new Set(ids) + }, + + clearSelection() { + selectedIds = new Set() + }, + + isSelected(id: string) { + return selectedIds.has(id) + } + } +} + +export const SELECTION_MODE_KEY = Symbol('selection-mode') + +/** Context key for child pages to provide their loaded item IDs to the layout */ +export const LOADED_IDS_KEY = Symbol('loaded-ids') + +export interface LoadedIdsContext { + setIds: (ids: string[]) => void +}