Skip to main content

dioxus_docs_kit/components/blog/
search_modal.rs

1use dioxus::prelude::*;
2
3use crate::BlogContext;
4use crate::blog::registry::BlogRegistry;
5use crate::components::search_shell::{SearchHit, SearchModalShell};
6use crate::search::{MAX_RESULTS, SNIPPET_WINDOW, build_snippet, split_terms};
7
8/// Blog search modal triggered by Cmd/Ctrl+K or the search button.
9#[component]
10pub fn BlogSearchModal() -> Element {
11    let ctx = use_context::<BlogContext>();
12    let registry = use_context::<&'static BlogRegistry>();
13
14    let search = use_callback(move |query: String| {
15        let terms = split_terms(&query);
16        registry
17            .search_posts(&query)
18            .into_iter()
19            // Cap before building hits: snippet extraction is the expensive part.
20            .take(MAX_RESULTS)
21            .map(|entry| SearchHit {
22                target: entry.slug.clone(),
23                title: entry.title.clone(),
24                context: None,
25                badge: None,
26                meta: entry.date.clone(),
27                tags: entry.tags.clone(),
28                snippet: build_snippet(&entry.body, &terms, SNIPPET_WINDOW),
29            })
30            .collect()
31    });
32
33    let on_select = use_callback(move |slug: String| (ctx.navigate)(slug));
34
35    rsx! {
36        SearchModalShell {
37            placeholder: "Search posts...",
38            search,
39            on_select,
40        }
41    }
42}