Skip to main content

yew_autocomplete/view/
mod.rs

1mod bulma;
2mod plain;
3mod render_html;
4
5use std::rc::Rc;
6
7use web_sys::{KeyboardEvent, MouseEvent};
8use yew::{classes, html, Callback, Html};
9
10pub use bulma::Bulma;
11pub use plain::Plain;
12pub use render_html::RenderHtml;
13
14#[derive(Clone, PartialEq)]
15pub struct InputCallbacks {
16    pub on_input: Callback<String>,
17    pub on_keydown: Callback<KeyboardEvent>,
18    pub resolve: Callback<MouseEvent>, // TODO: make this more generic
19    pub select_item: Callback<usize>,
20}
21
22#[derive(Clone, PartialEq)]
23pub struct Context<Item: Clone + PartialEq> {
24    pub value: String,
25    pub callbacks: InputCallbacks,
26    pub items: Rc<Vec<Item>>,
27    pub highlighted: Option<usize>,
28    pub selected_items: Rc<Vec<Item>>,
29    pub auto: bool,
30}
31
32pub(in crate::view) fn render_items<I: Clone + PartialEq + RenderHtml>(
33    ctx: &Context<I>,
34    additional_item_classes: &[&'static str],
35    additional_highlighted_classes: &[&'static str],
36) -> Vec<Html> {
37    ctx.items
38        .iter()
39        .enumerate()
40        .map(|(index, value)| {
41            let select_item = ctx.callbacks.select_item.clone();
42            let onclick = Callback::from(move |e: MouseEvent| {
43                e.prevent_default();
44                select_item.emit(index);
45            });
46
47            let mut classes = vec!["autocomplete-item"];
48            classes.extend(additional_item_classes);
49
50            if ctx.highlighted.iter().any(|h| *h == index) {
51                classes.push("highlighted");
52                classes.extend(additional_highlighted_classes);
53            }
54
55            html! { <a class={classes!(classes)} {onclick}>{value.render()}</a>}
56        })
57        .collect::<Vec<_>>()
58}