mirror of
https://github.com/adoyle0/thaw.git
synced 2025-01-22 22:09:22 -05:00
✨ feat: slider update value
This commit is contained in:
parent
4763bd67e6
commit
50e5285fe1
3 changed files with 37 additions and 8 deletions
|
@ -15,7 +15,7 @@ license = "MIT"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
leptos = { version = "0.2.5", features = ["stable"] }
|
leptos = { version = "0.2.5", features = ["stable"] }
|
||||||
stylers = "0.3.1"
|
stylers = "0.3.1"
|
||||||
web-sys = "0.3.61"
|
web-sys = { version = "0.3.61", features = ["DomRect"] }
|
||||||
leptos_dom = { version = "0.2.5" }
|
leptos_dom = { version = "0.2.5" }
|
||||||
leptos-icons = { git = "https://github.com/Carlosted/leptos-icons.git", features = ["AiCloseOutlined", "AiCheckOutlined"] }
|
leptos-icons = { git = "https://github.com/Carlosted/leptos-icons.git", features = ["AiCloseOutlined", "AiCheckOutlined"] }
|
||||||
wasm-bindgen = "0.2.84"
|
wasm-bindgen = "0.2.84"
|
||||||
|
|
|
@ -3,7 +3,11 @@ use melt_ui::*;
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn DemoSlider(cx: Scope) -> impl IntoView {
|
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,
|
view! { cx,
|
||||||
<Slider value=20.0/>
|
<Slider value=value on_value=on_value/>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,13 @@ use crate::{
|
||||||
};
|
};
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use stylers::style_sheet_str;
|
use stylers::style_sheet_str;
|
||||||
|
use wasm_bindgen::JsCast;
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn Slider(
|
pub fn Slider(
|
||||||
cx: Scope,
|
cx: Scope,
|
||||||
#[prop(optional, into)] value: MaybeSignal<f64>,
|
#[prop(optional, into)] value: MaybeSignal<f64>,
|
||||||
#[prop(optional)] on_value: Option<SignalSetter<String>>,
|
#[prop(optional)] on_value: Option<SignalSetter<f64>>,
|
||||||
#[prop(default = MaybeSignal::Static(100f64), into)] max: MaybeSignal<f64>,
|
#[prop(default = MaybeSignal::Static(100f64), into)] max: MaybeSignal<f64>,
|
||||||
) -> impl IntoView {
|
) -> impl IntoView {
|
||||||
let theme = use_theme(cx, Theme::light);
|
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 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::<html::Div>(cx);
|
let rail_ref = create_node_ref::<html::Div>(cx);
|
||||||
|
let (mouse_move_value, set_mouse_move_value) = create_signal::<Option<f64>>(cx, None);
|
||||||
let (is_mouse_move, set_mouse_move) = create_signal(cx, false);
|
let (is_mouse_move, set_mouse_move) = create_signal(cx, false);
|
||||||
let on_mouse_down = move |_| {
|
let on_mouse_down = move |_| {
|
||||||
set_mouse_move.set(true);
|
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() {
|
if is_mouse_move.get() {
|
||||||
rail_ref.on_load(cx, move |rail| {
|
if let Some(rail) = rail_ref.get() {
|
||||||
// rail.get_bounding_client_rect();
|
let ev = ev.unchecked_into::<web_sys::MouseEvent>();
|
||||||
});
|
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);
|
on_cleanup(cx, on_mouse_move);
|
||||||
|
|
||||||
view! {cx, class=class_name,
|
view! {cx, class=class_name,
|
||||||
<div class="melt-slider" style=move || css_vars.get()>
|
<div class="melt-slider" style=move || css_vars.get()>
|
||||||
<div class="melt-slider-rail">
|
<div class="melt-slider-rail" ref=rail_ref>
|
||||||
<div class="melt-slider-rail__fill" style=move || format!("width: {}%", percentage.get())></div>
|
<div class="melt-slider-rail__fill" style=move || format!("width: {}%", percentage.get())></div>
|
||||||
</div>
|
</div>
|
||||||
<div on:mousedown=on_mouse_down class="melt-slider-handle" style=move || format!("left: {}%; transform: translateX(-{}%)", percentage.get(), percentage.get())>
|
<div on:mousedown=on_mouse_down class="melt-slider-handle" style=move || format!("left: {}%; transform: translateX(-{}%)", percentage.get(), percentage.get())>
|
||||||
|
|
Loading…
Add table
Reference in a new issue