SearchResultItem.svelte

SearchResultItem.svelte

Module: Search Frontend
Path: src/lib/components/search/SearchResultItem.svelte

Presentational component for a single search result row. Renders type icon, title, highlighted snippet, and slug path breadcrumb. Contains no data-fetching logic -- all navigation is delegated to the parent via the onclick callback.

Props

Prop Type Required Default Description
result SearchResultItem yes -- The search result data to render. Type imported from $lib/types/search.
isFocused boolean yes -- Whether this item currently has keyboard focus. Drives the .focused CSS class and aria-selected attribute.
onclick () => void yes -- Click handler callback. The parent (SearchResults) passes a closure that navigates to the content or glossary entry.

Exports

Exported via the barrel src/lib/components/search/index.ts:

Name Kind Description
SearchResultItem component (default) Single result row

Methods

Method Parameters Returns Description
formatBreadcrumb(slugPath) slugPath: string string Converts a slash-separated slug path to a breadcrumb string. Example: "series-1/book-1/chapter-1/scene-1" becomes "series-1 > book-1 > chapter-1 > scene-1" (using the > right-pointing angle bracket character).

Rendered Layout

Each result item displays the following elements in a horizontal flex layout:

Type Icon

Result Type Icon Source
'content' FileText lucide-svelte
'glossary' BookOpen lucide-svelte

Text Content

  1. Title -- result.title rendered as semibold primary-color text. Truncated with ellipsis on overflow (single line, white-space: nowrap).

  2. Snippet -- result.snippet rendered via {@html} to display <mark> tags from the backend FTS5 snippet() function. Clamped to 2 lines via -webkit-line-clamp: 2. The <mark> tags are styled with a blue highlight background (--editor-find-highlight).

  3. Breadcrumb (content results only) -- result.slugPath formatted via formatBreadcrumb(). Shows the full content hierarchy path. Muted opacity, truncated with ellipsis. Only rendered when result.slugPath is present (content results have this field; glossary results do not).

Accessibility

Attribute Value Purpose
role "option" ARIA listbox option role (parent SearchResults has role="listbox")
aria-selected isFocused Indicates keyboard focus state
tabindex "0" Makes the item focusable

Snippet Security

The {@html result.snippet} usage is intentional and safe within the defined trust boundary:

Imports / Dependencies

Import Source Purpose
FileText, BookOpen lucide-svelte Type icons for content and glossary results
SearchResultItem (type) $lib/types/search TypeScript interface for the result data

Side Effects

None. This is a pure presentational component with no side effects, no store subscriptions, and no API calls.

Notes

The SearchResultItem TypeScript type is imported with type qualifier and aliased as SearchResultItemType in the parent SearchResults to avoid collision with the component name.