use crate::{prelude::*, *};
use std::sync::Arc;
#[derive(Clone)]
pub struct SourceItem {
pub title: SharedString,
pub url: Option<SharedString>,
}
impl SourceItem {
pub fn new(title: impl Into<SharedString>) -> Self {
Self {
title: title.into(),
url: None,
}
}
pub fn url(mut self, url: impl Into<SharedString>) -> Self {
self.url = Some(url.into());
self
}
}
#[derive(IntoElement)]
pub struct Sources {
items: Vec<SourceItem>,
on_open: Option<Arc<dyn Fn(usize, &mut Window, &mut App) + Send + Sync + 'static>>,
style: StyleRefinement,
}
impl Sources {
pub fn new(items: Vec<SourceItem>) -> Self {
Self {
items,
on_open: None,
style: StyleRefinement::default(),
}
}
pub fn on_open<F>(mut self, f: F) -> Self
where
F: Fn(usize, &mut Window, &mut App) + Send + Sync + 'static,
{
self.on_open = Some(Arc::new(f));
self
}
}
impl Styled for Sources {
fn style(&mut self) -> &mut StyleRefinement {
&mut self.style
}
}
impl RenderOnce for Sources {
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_open = self.on_open;
div()
.flex()
.flex_row()
.flex_wrap()
.gap(px(6.0))
.children(self.items.into_iter().enumerate().map(|(ix, item)| {
let on_open = on_open.clone();
div()
.id(SharedString::from(format!("source-{ix}")))
.flex()
.flex_row()
.items_center()
.gap(px(4.0))
.px(px(8.0))
.py(px(4.0))
.rounded_full()
.border_1()
.border_color(border)
.text_xs()
.text_color(accent)
.cursor_pointer()
.child(format!("[{}]", ix + 1))
.child(item.title)
.on_click(move |_, window, cx| {
if let Some(ref cb) = on_open {
cb(ix, window, cx);
}
})
.into_any_element()
}))
.map(|mut this| {
this.style().refine(&user_style);
this
})
}
}