dioxus_material/
button.rs

1use crate::{use_theme, Ripple};
2use dioxus::prelude::*;
3
4/// Filled button component.
5///
6/// Buttons let people take action and make choices with one tap.
7///
8/// [material.io](https://m3.material.io/components/buttons)
9///
10/// ## Panics
11/// This component requires access to a [`Theme`](crate::Theme).
12///
13/// ## Examples
14/// ```rust
15/// use dioxus::prelude::*;
16/// use dioxus_material::{Button, Theme};
17///
18/// fn app() -> Element {
19///    rsx!(Theme {
20///         Button { onpress: |_| log::info!("clicked!"), "Click me!" } }
21///    )
22/// }
23/// ```
24#[component]
25pub fn Button(
26    /// Handler for button press events.
27    onpress: EventHandler<Event<MouseData>>,
28
29    /// Label child element.
30    children: Element,
31
32    /// Background color of the container (optional).
33    background_color: Option<String>,
34
35    /// Border radius of the container (optional).
36    border_radius: Option<String>,
37
38    /// Height of the container (optional).
39    height: Option<String>,
40) -> Element {
41    let theme = use_theme();
42    let background_color = background_color.as_deref().unwrap_or(&theme.primary_color);
43    let border_radius = border_radius
44        .as_deref()
45        .unwrap_or(&theme.border_radius_medium);
46    let height = height.as_deref().unwrap_or("50px");
47
48    rsx!(
49        div {
50            display: "inline-block",
51            position: "relative",
52            height: "{height}",
53            line_height: "{height}",
54            color: "#fff",
55            background: "{background_color}",
56            border_radius: "{border_radius}",
57            overflow: "hidden",
58            cursor: "pointer",
59            Ripple { onclick: move |event| onpress.call(event),
60                div {
61                    position: "relative",
62                    z_index: 9,
63                    padding: "0 25px",
64                    font_family: "sans-serif",
65                    user_select: "none",
66                    webkit_user_select: "none",
67                    {children}
68                }
69            }
70        }
71    )
72}
73
74#[component]
75pub fn TextButton(
76    /// Handler for button press events.
77    onpress: EventHandler<Event<MouseData>>,
78
79    /// Label child element.
80    children: Element,
81
82    /// Border radiusof the container (optional).
83    border_radius: Option<String>,
84
85    /// Text color (optional).
86    color: Option<String>,
87
88    /// Height of the container (optional).
89    height: Option<String>,
90) -> Element {
91    let theme = use_theme();
92    let color = color.as_deref().unwrap_or(&theme.primary_color);
93    let border_radius = border_radius
94        .as_deref()
95        .unwrap_or(&theme.border_radius_medium);
96    let height = height.as_deref().unwrap_or("40px");
97
98    rsx!(
99        div {
100            display: "inline-block",
101            position: "relative",
102            height: "{height}",
103            line_height: "{height}",
104            border_radius: "{border_radius}",
105            color: "{color}",
106            font_weight: "bold",
107            overflow: "hidden",
108            cursor: "pointer",
109            Ripple { onclick: move |event| onpress.call(event),
110                div {
111                    position: "relative",
112                    z_index: 9,
113                    padding: "0 25px",
114                    font_family: "sans-serif",
115                    user_select: "none",
116                    webkit_user_select: "none",
117                    {children}
118                }
119            }
120        }
121    )
122}