use crate::{prelude::*, *};
use std::sync::Arc;
#[derive(IntoElement)]
pub struct Suggestion {
items: Vec<SharedString>,
on_pick:
Option<Arc<dyn Fn(usize, &SharedString, &mut Window, &mut App) + Send + Sync + 'static>>,
style: StyleRefinement,
}
impl Suggestion {
pub fn new(items: Vec<SharedString>) -> Self {
Self {
items,
on_pick: None,
style: StyleRefinement::default(),
}
}
pub fn on_pick<F>(mut self, f: F) -> Self
where
F: Fn(usize, &SharedString, &mut Window, &mut App) + Send + Sync + 'static,
{
self.on_pick = Some(Arc::new(f));
self
}
}
impl Styled for Suggestion {
fn style(&mut self) -> &mut StyleRefinement {
&mut self.style
}
}
impl RenderOnce for Suggestion {
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
let theme = cx.theme();
let border = theme.tokens.border.color;
let accent = theme.tokens.accent.color;
let user_style = self.style;
let on_pick = self.on_pick;
div()
.flex()
.flex_row()
.flex_wrap()
.gap(px(6.0))
.children(self.items.into_iter().enumerate().map(|(ix, text)| {
let on_pick = on_pick.clone();
let label = text.clone();
div()
.id(SharedString::from(format!("suggestion-{ix}")))
.px(px(10.0))
.py(px(6.0))
.rounded_full()
.border_1()
.border_color(border)
.text_xs()
.text_color(accent)
.cursor_pointer()
.hover(|this| this.bg(accent.opacity(0.1)))
.child(text)
.on_click(move |_, window, cx| {
if let Some(ref cb) = on_pick {
cb(ix, &label, window, cx);
}
})
.into_any_element()
}))
.map(|mut this| {
this.style().refine(&user_style);
this
})
}
}