1use std::rc::Rc;
2
3use gpui::ClickEvent;
4use ui::{prelude::*, IconButtonShape};
5
6use crate::context::{Context, ContextKind};
7
8#[derive(IntoElement)]
9pub struct ContextPill {
10 context: Context,
11 on_remove: Option<Rc<dyn Fn(&ClickEvent, &mut WindowContext)>>,
12}
13
14impl ContextPill {
15 pub fn new(context: Context) -> Self {
16 Self {
17 context,
18 on_remove: None,
19 }
20 }
21
22 pub fn on_remove(mut self, on_remove: Rc<dyn Fn(&ClickEvent, &mut WindowContext)>) -> Self {
23 self.on_remove = Some(on_remove);
24 self
25 }
26}
27
28impl RenderOnce for ContextPill {
29 fn render(self, cx: &mut WindowContext) -> impl IntoElement {
30 let padding_right = if self.on_remove.is_some() {
31 px(2.)
32 } else {
33 px(4.)
34 };
35 let icon = match self.context.kind {
36 ContextKind::File => IconName::File,
37 ContextKind::Directory => IconName::Folder,
38 ContextKind::FetchedUrl => IconName::Globe,
39 ContextKind::Thread => IconName::MessageCircle,
40 };
41
42 h_flex()
43 .gap_1()
44 .pl_1()
45 .pr(padding_right)
46 .pb(px(1.))
47 .border_1()
48 .border_color(cx.theme().colors().border.opacity(0.5))
49 .bg(cx.theme().colors().element_background)
50 .rounded_md()
51 .child(Icon::new(icon).size(IconSize::XSmall).color(Color::Muted))
52 .child(Label::new(self.context.name.clone()).size(LabelSize::Small))
53 .when_some(self.on_remove, |parent, on_remove| {
54 parent.child(
55 IconButton::new(("remove", self.context.id.0), IconName::Close)
56 .shape(IconButtonShape::Square)
57 .icon_size(IconSize::XSmall)
58 .on_click({
59 let on_remove = on_remove.clone();
60 move |event, cx| on_remove(event, cx)
61 }),
62 )
63 })
64 }
65}