From 50e5285fe1675593dc257570210bbeb218b56406 Mon Sep 17 00:00:00 2001 From: luoxiao Date: Sun, 23 Apr 2023 15:07:33 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20slider=20update=20value?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.toml | 2 +- examples/basic/src/demo_slider.rs | 6 ++++- src/slider/mod.rs | 37 ++++++++++++++++++++++++++----- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2e56d59..be25a6b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ license = "MIT" [dependencies] leptos = { version = "0.2.5", features = ["stable"] } stylers = "0.3.1" -web-sys = "0.3.61" +web-sys = { version = "0.3.61", features = ["DomRect"] } leptos_dom = { version = "0.2.5" } leptos-icons = { git = "https://github.com/Carlosted/leptos-icons.git", features = ["AiCloseOutlined", "AiCheckOutlined"] } wasm-bindgen = "0.2.84" diff --git a/examples/basic/src/demo_slider.rs b/examples/basic/src/demo_slider.rs index 560a568..77e3730 100644 --- a/examples/basic/src/demo_slider.rs +++ b/examples/basic/src/demo_slider.rs @@ -3,7 +3,11 @@ use melt_ui::*; #[component] pub fn DemoSlider(cx: Scope) -> impl IntoView { + let (value, set_value) = create_signal(cx, 0.0); + let on_value = SignalSetter::map(cx, move |value| { + set_value.set(value); + }); view! { cx, - + } } diff --git a/src/slider/mod.rs b/src/slider/mod.rs index aa37e7c..adffce3 100644 --- a/src/slider/mod.rs +++ b/src/slider/mod.rs @@ -5,12 +5,13 @@ use crate::{ }; use leptos::*; use stylers::style_sheet_str; +use wasm_bindgen::JsCast; #[component] pub fn Slider( cx: Scope, #[prop(optional, into)] value: MaybeSignal, - #[prop(optional)] on_value: Option>, + #[prop(optional)] on_value: Option>, #[prop(default = MaybeSignal::Static(100f64), into)] max: MaybeSignal, ) -> impl IntoView { let theme = use_theme(cx, Theme::light); @@ -34,24 +35,48 @@ pub fn Slider( }); let class_name = mount_style("slider", || style_sheet_str!("./src/slider/slider.css")); + let do_update_value = move |value| { + if let Some(on_value) = on_value { + on_value.set(value); + } + }; + let rail_ref = create_node_ref::(cx); + let (mouse_move_value, set_mouse_move_value) = create_signal::>(cx, None); let (is_mouse_move, set_mouse_move) = create_signal(cx, false); let on_mouse_down = move |_| { set_mouse_move.set(true); }; - let on_mouse_move = window_event_listener("mousemove", move |_| { + let on_mouse_up = window_event_listener("mouseup", move |_| { + set_mouse_move.set(false); + }); + on_cleanup(cx, on_mouse_up); + + let on_mouse_move = window_event_listener("mousemove", move |ev| { if is_mouse_move.get() { - rail_ref.on_load(cx, move |rail| { - // rail.get_bounding_client_rect(); - }); + if let Some(rail) = rail_ref.get() { + let ev = ev.unchecked_into::(); + let rect = rail.get_bounding_client_rect(); + let ev_x = f64::from(ev.x()); + if ev_x <= rect.x() { + set_mouse_move_value.set(Some(0.0)); + } else if ev_x >= rect.x() + rect.width() { + set_mouse_move_value.set(Some(max.get())); + } else { + set_mouse_move_value.set(Some(((ev_x - rect.x()) / rect.width()) * max.get())); + } + if let Some(value) = mouse_move_value.get() { + do_update_value(value); + } + }; } }); on_cleanup(cx, on_mouse_move); view! {cx, class=class_name,
-
+