// Code generated by templ - DO NOT EDIT. // templ: version: v0.3.1020 package templates //lint:file-ignore SA4006 This context is only used if a nested component is present. import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" import ( "fmt" "html" "regexp" "bookhoard/internal/handlers" ) // CompletedProgressThreshold is the viewer_percentage at which a card // shows the completed check instead of a partial-progress bar — the // SAME 0.999 cut the filter_query.go status arms and the series-page // status filter use. const CompletedProgressThreshold = 0.999 // progressFillCSS renders the partial-progress bar width (gotcha #8: // quote-free style values only — templ double-escapes quotes into // literal text the CSS parser never sees). func progressFillCSS(pct float64) string { return fmt.Sprintf("width: %.1f%%; background-color: var(--accent);", pct*100) } // highlightQueryHTML escapes text FIRST and only then wraps // case-insensitive query matches in — the returned HTML is // safe by construction (escaped payload, marker tags we wrote), which // is what lets the search partial emit it via templ.Raw. func highlightQueryHTML(text, query string) string { if text == "" || query == "" { return html.EscapeString(text) } pattern := regexp.MustCompile(regexp.QuoteMeta(html.EscapeString(query))) markOpen := `` return pattern.ReplaceAllString(html.EscapeString(text), markOpen+"$0") } // searchCoverURL falls back to the placeholder the way BookCard does — // no inline onerror (CSP: hash-mode refuses native handler attributes). func searchCoverURL(item handlers.BookInfo) string { if item.CoverImagePath != "" { return item.CoverImagePath } return "/static/placeholder-book.svg" } // SearchResults is the header-search dropdown partial: compact result // rows swapped into #search-results by the htmx request the header // input fires (layout=dropdown on /api/media-items/search). Content is // server-rendered (rendering-ownership doctrine); web/src/search.ts // only owns open/close/keyboard state. func SearchResults(items []handlers.BookInfo, query string) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var1 := templ.GetChildren(ctx) if templ_7745c5c3_Var1 == nil { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var2 string templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(resultCountLabel(len(items), query)) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/search_results.templ`, Line: 54, Col: 40} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if len(items) == 0 { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
šŸ”

No results found

Try different keywords

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } for _, item := range items { templ_7745c5c3_Err = SearchResultRow(item, query).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "

Press ↑↓ to navigate, Enter to select

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } return nil }) } func SearchResultRow(item handlers.BookInfo, query string) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var3 := templ.GetChildren(ctx) if templ_7745c5c3_Var3 == nil { templ_7745c5c3_Var3 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
\"")") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = SearchProgressOverlay(item).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templ.Raw(highlightQueryHTML(item.Title, query)).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if item.Author != "" { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templ.Raw(highlightQueryHTML(item.Author, query)).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } if item.LibraryName != "" { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var7 string templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(item.LibraryName) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/search_results.templ`, Line: 92, Col: 85} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) } // SearchProgressOverlay is the cover overlay shared by the dropdown // rows and BookCard: a completed check at/above the 0.999 threshold, // a partial fill bar along the cover bottom while mid-read, nothing // when the viewer never opened the book. func SearchProgressOverlay(item handlers.BookInfo) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var8 := templ.GetChildren(ctx) if templ_7745c5c3_Var8 == nil { templ_7745c5c3_Var8 = templ.NopComponent } ctx = templ.ClearChildren(ctx) if item.ViewerPercentage != nil { if *item.ViewerPercentage >= CompletedProgressThreshold { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = Icon("check", "h-3 w-3").Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else if *item.ViewerPercentage > 0 { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } } return nil }) } func resultCountLabel(n int, query string) string { if n == 1 { return fmt.Sprintf("1 result for ā€œ%sā€", query) } return fmt.Sprintf("%d results for ā€œ%sā€", n, query) } var _ = templruntime.GeneratedTemplate