floem/views/
button.rs

1#![deny(missing_docs)]
2use crate::{IntoView, View, ViewId, style_class, views::Decorators};
3
4style_class!(
5    /// The style class that is applied to buttons.
6    pub ButtonClass
7);
8
9/// Creates a new simple [Button] view with the default [ButtonClass] style.
10///
11/// ### Examples
12/// ```rust
13/// # use floem::views::Button;
14/// # use floem::prelude::{*, palette::css};
15/// # use floem::views::Decorators;
16/// # use floem::style::CursorStyle;
17/// // Basic usage
18/// let button1 = Button::new("Click me").action(move || println!("Button1 clicked!"));
19/// let button2 = Button::new("Click me").action(move || println!("Button2 clicked!"));
20/// // Apply styles for the button
21/// let styled = Button::new("Click me")
22///     .action(|| println!("Styled button clicked!"))
23///     .style(|s| s
24///         .border(1.0)
25///         .border_radius(10.0)
26///         .padding(10.0)
27///         .background(css::YELLOW_GREEN)
28///         .color(css::DARK_GREEN)
29///         .cursor(CursorStyle::Pointer)
30///         .active(|s| s.color(css::WHITE).background(css::RED))
31///         .hover(|s| s.background(Color::from_rgb8(244, 67, 54)))
32///         .focus_visible(|s| s.border(2.).border_color(css::BLUE))
33///     );
34/// ```
35#[deprecated(since = "0.2.0", note = "Use Button::new() instead")]
36pub fn button<V: IntoView + 'static>(child: V) -> Button {
37    Button::new(child)
38}
39
40/// A simple Button view. See [`button`].
41pub struct Button {
42    id: ViewId,
43}
44
45impl View for Button {
46    fn id(&self) -> ViewId {
47        self.id
48    }
49}
50
51impl Button {
52    /// Creates a new [Button] with the given child view.
53    ///
54    /// ### Examples
55    /// ```rust
56    /// # use floem::views::Button;
57    /// # use floem::prelude::{*, palette::css};
58    /// # use floem::views::Decorators;
59    /// # use floem::style::CursorStyle;
60    /// // Basic usage
61    /// let button1 = Button::new("Click me").action(move || println!("Button1 clicked!"));
62    /// let button2 = Button::new("Click me").action(move || println!("Button2 clicked!"));
63    /// // Apply styles for the button
64    /// let styled = Button::new("Click me")
65    ///     .action(|| println!("Styled button clicked!"))
66    ///     .style(|s| s
67    ///         .border(1.0)
68    ///         .border_radius(10.0)
69    ///         .padding(10.0)
70    ///         .background(css::YELLOW_GREEN)
71    ///         .color(css::DARK_GREEN)
72    ///         .cursor(CursorStyle::Pointer)
73    ///         .active(|s| s.color(css::WHITE).background(css::RED))
74    ///         .hover(|s| s.background(Color::from_rgb8(244, 67, 54)))
75    ///         .focus_visible(|s| s.border(2.).border_color(css::BLUE))
76    ///     );
77    /// ```
78    ///
79    /// ### Reactivity
80    /// Button's label is not reactive. For reactive content, pass a reactive view as the child.
81    pub fn new(child: impl IntoView) -> Self {
82        let id = ViewId::new();
83        id.add_child(Box::new(child.into_view()));
84        Button { id }.class(ButtonClass)
85    }
86}
87
88/// A trait that adds a `button` method to any type that implements `IntoView`.
89pub trait ButtonExt {
90    /// Create a [Button] from the parent.
91    fn button(self) -> Button;
92}
93impl<T: IntoView + 'static> ButtonExt for T {
94    fn button(self) -> Button {
95        Button::new(self)
96    }
97}