1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use crate::{icons::ICON_X, prelude::*};
use std::sync::Arc;
/// A visual indicator such as a tag.
pub struct Chip {
on_close: Option<Arc<dyn Fn(&mut EventContext) + Send + Sync>>,
has_close: Signal<bool>,
}
impl Chip {
/// Creates a new [Chip] view with the provided text.
///
/// # Example
/// ```
/// # use vizia_core::prelude::*;
/// #
/// # let cx = &mut Context::default();
/// #
/// Chip::new(cx, "Chip");
/// ```
pub fn new<T>(cx: &mut Context, text: impl Res<T> + Clone + 'static) -> Handle<Self>
where
T: ToStringLocalized + 'static,
{
let has_close = Signal::new(false);
Self { on_close: None, has_close }
.build(cx, move |cx| {
Label::new(cx, text).height(Stretch(1.0)).alignment(Alignment::Left);
Binding::new(cx, has_close, move |cx| {
if has_close.get() {
let on_close = cx.data::<Chip>().on_close.clone().unwrap();
Button::new(cx, |cx| Svg::new(cx, ICON_X))
.class("close-icon")
.height(Pixels(16.0))
.width(Pixels(16.0))
.alignment(Alignment::Center)
.on_press(move |cx| (on_close)(cx));
}
});
})
.toggle_class("close", has_close)
.layout_type(LayoutType::Row)
}
}
impl View for Chip {
fn element(&self) -> Option<&'static str> {
Some("chip")
}
}
/// Used in conjunction with the `variant` modifier for selecting the style variant of a chip.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ChipVariant {
/// A filled chip.
Filled,
/// A chip with no fill and just a border.
Outline,
}
impl_res_simple!(ChipVariant);
impl Handle<'_, Chip> {
/// Set the callback triggered when the close button of the chip is pressed.
/// The chip close button is not displayed by default. Setting this callback causes the close button to be displayed.
pub fn on_close(self, callback: impl 'static + Fn(&mut EventContext) + Send + Sync) -> Self {
self.modify(|chip: &mut Chip| {
chip.on_close = Some(Arc::new(callback));
chip.has_close.set(true);
})
}
/// Selects the style variant to be used by the chip. Accepts a value or signal of type [ChipVariant].
///
/// # Example
/// ```
/// # use vizia_core::prelude::*;
/// #
/// #
/// # let cx = &mut Context::default();
/// #
/// Chip::new(cx, "Chip")
/// .variant(ChipVariant::Filled);
/// ```
pub fn variant<U: Into<ChipVariant> + Clone + 'static>(
self,
variant: impl Res<U> + 'static,
) -> Self {
let variant = variant.to_signal(self.cx);
self.bind(variant, move |handle| {
let variant = variant.get();
let variant = variant.into();
match variant {
ChipVariant::Filled => {
handle.toggle_class("outline", false);
}
ChipVariant::Outline => {
handle.toggle_class("outline", true);
}
}
})
}
}