Skip to content

Commit

Permalink
Simplify Button and create TextButton
Browse files Browse the repository at this point in the history
  • Loading branch information
matthunz committed Oct 21, 2023
1 parent 03b715d commit cfb1654
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 71 deletions.
3 changes: 2 additions & 1 deletion examples/button.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use dioxus::prelude::*;
use dioxus_material::Button;
use dioxus_material::{Button, TextButton};

fn app(cx: Scope) -> Element {
render!(
Button { onclick: |_| log::info!("clicked!"), "Click me!" }
TextButton { onclick: |_| log::info!("clicked!"), "Click me!" }
)
}

Expand Down
105 changes: 46 additions & 59 deletions src/button.rs
Original file line number Diff line number Diff line change
@@ -1,41 +1,12 @@
use dioxus::prelude::*;
use dioxus_resize_observer::use_size;
use dioxus_spring::{use_animated, use_spring_signal};
use dioxus_use_mounted::use_mounted;
use std::time::Duration;
use crate::Ripple;

#[derive(Props)]
pub struct ButtonProps<'a> {
#[component]
pub fn Button<'a>(
cx: Scope<'a>,
onclick: EventHandler<'a, Event<MouseData>>,
children: Element<'a>,
}

#[component]
pub fn Button<'a>(cx: Scope<'a, ButtonProps<'a>>) -> Element<'a> {
let is_pressed = use_state(cx, || false);

let container_ref = use_mounted(cx);
let content_rect = use_size(cx, container_ref);
let size = content_rect.width().max(content_rect.height()) * 1.2;

let (spring_ref, value_ref) = use_spring_signal(cx, [0f32; 2]);
let animated_ref = use_mounted(cx);
use_animated(cx, animated_ref, value_ref, |[size, opacity]| {
format!(
r"
width: {size}px;
height: {size}px;
opacity: {opacity};
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
background: rgba(255, 255, 255, 0.5);
"
)
});

) -> Element<'a> {
render!(
div {
display: "inline-block",
Expand All @@ -47,32 +18,48 @@ pub fn Button<'a>(cx: Scope<'a, ButtonProps<'a>>) -> Element<'a> {
border_radius: "25px",
overflow: "hidden",
cursor: "pointer",
onmounted: move |event| container_ref.onmounted(event),
onmousedown: move |_| {
spring_ref.animate([size as _, 1.], Duration::from_millis(200));
is_pressed.set(true)
},
onmouseup: move |event| {
if **is_pressed {
spring_ref.queue([size as _, 0.], Duration::from_millis(200));
spring_ref.queue([0., 0.], Duration::from_millis(0));
cx.props.onclick.call(event);
is_pressed.set(false)
Ripple { onclick: move |event| onclick.call(event),
div {
position: "relative",
z_index: 9,
padding: "0 25px",
font_family: "sans-serif",
user_select: "none",
webkit_user_select: "none",
children
}
}
}
)
}

#[component]
pub fn TextButton<'a>(
cx: Scope<'a>,
onclick: EventHandler<'a, Event<MouseData>>,
children: Element<'a>,
) -> Element<'a> {
render!(
div {
display: "inline-block",
position: "relative",
height: "40px",
line_height: "40px",
border_radius: "25px",
color: "#416529",
font_weight: "bold",
overflow: "hidden",
cursor: "pointer",
Ripple { onclick: move |event| onclick.call(event),
div {
position: "relative",
z_index: 9,
padding: "0 25px",
font_family: "sans-serif",
user_select: "none",
webkit_user_select: "none",
children
}
},
onmouseleave: move |_| {
spring_ref.animate([0., 0.], Duration::from_millis(200));
is_pressed.set(false)
},
div { onmounted: move |event| animated_ref.onmounted(event) }
div {
position: "relative",
z_index: 9,
padding: "0 25px",
font_family: "sans-serif",
user_select: "none",
webkit_user_select: "none",
&cx.props.children
}
}
)
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
mod button;
pub use button::Button;
pub use button::{Button, TextButton};

mod ripple;
pub use ripple::Ripple;
Expand Down
20 changes: 10 additions & 10 deletions src/ripple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@ use dioxus_spring::{use_animated, use_spring_signal};
use dioxus_use_mounted::use_mounted;
use std::time::Duration;

#[derive(Props)]
pub struct RippleProps<'a> {
#[component]
pub fn Ripple<'a>(
cx: Scope<'a>,
onclick: EventHandler<'a, Event<MouseData>>,
children: Element<'a>,
}

#[component]
pub fn Ripple<'a>(cx: Scope<'a, RippleProps<'a>>) -> Element<'a> {
) -> Element<'a> {
let is_pressed = use_state(cx, || false);

let container_ref = use_mounted(cx);
Expand Down Expand Up @@ -52,16 +50,18 @@ pub fn Ripple<'a>(cx: Scope<'a, RippleProps<'a>>) -> Element<'a> {
if **is_pressed {
spring_ref.queue([size as _, 0.], Duration::from_millis(200));
spring_ref.queue([0., 0.], Duration::from_millis(0));
cx.props.onclick.call(event);
onclick.call(event);
is_pressed.set(false)
}
},
onmouseleave: move |_| {
spring_ref.animate([0., 0.], Duration::from_millis(200));
is_pressed.set(false)
if **is_pressed {
spring_ref.animate([0., 0.], Duration::from_millis(200));
is_pressed.set(false)
}
},
div { onmounted: move |event| animated_ref.onmounted(event) }
div { position: "relative", z_index: 9, user_select: "none", webkit_user_select: "none", &cx.props.children }
div { position: "relative", z_index: 9, user_select: "none", webkit_user_select: "none", children }
}
)
}

0 comments on commit cfb1654

Please sign in to comment.