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("Click me").action(move || println!("Button1 clicked!"));
19/// let button2 = button("Click me").action(move || println!("Button2 clicked!"));
20/// // Apply styles for the button
21/// let styled = button("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/// ```
35pub fn button<V: IntoView + 'static>(child: V) -> Button {
36    Button::new(child)
37}
38
39/// A simple Button view. See [`button`].
40pub struct Button {
41    id: ViewId,
42}
43
44impl View for Button {
45    fn id(&self) -> ViewId {
46        self.id
47    }
48}
49
50impl Button {
51    /// Create new [Button].
52    /// ### Examples
53    /// ```rust
54    /// # use floem::views::button;
55    /// # use floem::prelude::{*, palette::css};
56    /// # use floem::views::Decorators;
57    /// # use floem::style::CursorStyle;
58    /// // Basic usage
59    /// let button1 = button("Click me").action(move || println!("Button1 clicked!"));
60    /// let button2 = button("Click me").action(move || println!("Button2 clicked!"));
61    /// // Apply styles for the button
62    /// let styled = button("Click me")
63    ///     .action(|| println!("Styled button clicked!"))
64    ///     .style(|s| s
65    ///         .border(1.0)
66    ///         .border_radius(10.0)
67    ///         .padding(10.0)
68    ///         .background(css::YELLOW_GREEN)
69    ///         .color(css::DARK_GREEN)
70    ///         .cursor(CursorStyle::Pointer)
71    ///         .active(|s| s.color(css::WHITE).background(css::RED))
72    ///         .hover(|s| s.background(Color::from_rgb8(244, 67, 54)))
73    ///         .focus_visible(|s| s.border(2.).border_color(css::BLUE))
74    ///     );
75    /// ```
76    /// ### Reactivity
77    /// Button's label is not reactive.
78    pub fn new(child: impl IntoView) -> Self {
79        let id = ViewId::new();
80        id.add_child(Box::new(child.into_view()));
81        Button { id }.class(ButtonClass)
82    }
83}
84
85/// A trait that adds a `button` method to any type that implements `IntoView`.
86pub trait ButtonExt {
87    /// Create a [Button] from the parent.
88    fn button(self) -> Button;
89}
90impl<T: IntoView + 'static> ButtonExt for T {
91    fn button(self) -> Button {
92        button(self)
93    }
94}