feat(search): render title highlights and transcription snippets in DocumentList

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-15 18:34:14 +02:00
committed by marcel
parent 6cffd36b22
commit 60dc73ba04
2 changed files with 100 additions and 3 deletions

View File

@@ -4,6 +4,8 @@ import { m } from '$lib/paraglide/messages.js';
import { formatDate } from '$lib/utils/date';
import { groupDocuments } from '$lib/utils/groupDocuments';
import GroupDivider from '$lib/components/GroupDivider.svelte';
import { applyOffsets } from '$lib/search';
import type { components } from '$lib/generated/api';
let {
documents,
@@ -11,7 +13,8 @@ let {
error,
total = 0,
q = '',
sort
sort,
matchData = {}
}: {
documents: {
id: string;
@@ -28,6 +31,7 @@ let {
total?: number;
q?: string;
sort?: string;
matchData?: Record<string, components['schemas']['SearchMatchData']>;
} = $props();
const fallbackLabel = $derived(
@@ -75,6 +79,10 @@ const showDividers = $derived(groupedDocuments.length >= 2);
{/if}
<ul class="divide-y divide-line-2">
{#each group.documents as doc (doc.id)}
{@const titleText = doc.title || doc.originalFilename}
{@const titleOffsets = matchData?.[doc.id]?.titleOffsets ?? []}
{@const titleSegments = applyOffsets(titleText, titleOffsets)}
{@const snippet = matchData?.[doc.id]?.transcriptionSnippet}
<li class="group transition-colors duration-200 hover:bg-muted/50">
<a href="/documents/{doc.id}" class="block p-6">
<div class="flex flex-col gap-6 sm:flex-row">
@@ -82,7 +90,11 @@ const showDividers = $derived(groupedDocuments.length >= 2);
<div class="flex-1">
<div class="mb-2 flex items-baseline justify-between">
<h3 class="font-serif text-xl font-medium text-ink group-hover:underline">
{doc.title || doc.originalFilename}
{#each titleSegments as seg, i (i)}
{#if seg.highlight}<mark class="bg-accent/20 text-inherit not-italic"
>{seg.text}</mark
>{:else}{seg.text}{/if}
{/each}
</h3>
</div>
@@ -110,6 +122,15 @@ const showDividers = $derived(groupedDocuments.length >= 2);
{/if}
</div>
{#if snippet}
<p
data-testid="search-snippet"
class="mb-4 line-clamp-2 font-sans text-sm text-ink-2"
>
<span class="sr-only">Fundstelle: </span>{snippet}
</p>
{/if}
<!-- Sender/Receiver Info -->
<div class="grid grid-cols-1 gap-4 font-serif text-sm sm:grid-cols-2">
<div class="flex items-baseline">