Files
familienarchiv/frontend/src/lib/document/BulkSelectionBar.svelte
Marcel e7f8aa5894 refactor: move document domain core to lib/document/
Moves ~25 components, utils (search, filename, groupDocuments,
documentStatusLabel, validateFile), bulkSelection store, and
TranscriptionSection sub-component. Fixes broken relative imports.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 13:56:36 +02:00

75 lines
2.4 KiB
Svelte

<script lang="ts">
import { goto } from '$app/navigation';
import { m } from '$lib/paraglide/messages.js';
import { bulkSelectionStore } from '$lib/document/bulkSelection.svelte';
let { canWrite }: { canWrite: boolean } = $props();
const count = $derived(bulkSelectionStore.size);
const visible = $derived(canWrite && count > 0);
function openBulkEdit() {
goto('/documents/bulk-edit');
}
function clearAll() {
bulkSelectionStore.clear();
}
// Escape clears the selection — keyboard escape hatch when the user has
// drilled into a 50-row selection and wants to bail without Tab-ing through
// the whole footer (WCAG 2.1.1). Bails when an open dialog, expanded menu,
// or popover is in front so we don't steal Esc from NotificationBell,
// ConfirmDialog, HelpPopover, etc.
function onEscape(e: KeyboardEvent) {
if (e.key !== 'Escape' || !visible) return;
if (e.defaultPrevented) return;
const overlay = document.querySelector(
'dialog[open], [aria-expanded="true"], [role="menu"]:not([hidden]), [role="dialog"]:not([hidden])'
);
if (overlay) return;
clearAll();
}
</script>
<svelte:window onkeydown={onEscape} />
{#if visible}
<div
data-testid="bulk-selection-bar"
class="fixed right-0 bottom-0 left-0 z-30 flex items-center justify-between gap-3 border-t border-line bg-surface px-4 py-3 pb-[max(0.75rem,env(safe-area-inset-bottom))] shadow-[0_-2px_8px_rgba(0,0,0,0.06)] sm:px-6"
>
<div class="flex items-baseline gap-3">
<span
class="font-sans text-sm font-medium text-ink"
data-testid="bulk-selection-count"
aria-live="polite"
aria-atomic="true"
>
{count === 1 ? m.bulk_edit_n_selected_one() : m.bulk_edit_n_selected_other({ count })}
</span>
<span class="hidden font-sans text-xs text-ink-3 sm:inline">
{m.bulk_edit_clear_hint_keyboard()}
</span>
</div>
<div class="flex items-center gap-2">
<button
type="button"
onclick={clearAll}
class="inline-flex min-h-[44px] items-center px-4 py-2 font-sans text-sm font-medium text-ink-2 transition-colors hover:text-ink"
data-testid="bulk-clear-all"
>
{m.bulk_edit_clear_selection()}
</button>
<button
type="button"
onclick={openBulkEdit}
class="inline-flex min-h-[44px] items-center bg-primary px-5 py-2 font-sans text-xs font-bold tracking-widest text-primary-fg uppercase transition-colors hover:bg-primary/90"
data-testid="bulk-edit-open"
>
{m.bulk_edit_button()}
</button>
</div>
</div>
{/if}