feat: add slider component

This commit is contained in:
luoxiao 2023-04-18 17:27:39 +08:00
parent 4ab30bf57e
commit 357c7c5862
5 changed files with 83 additions and 0 deletions

View file

@ -0,0 +1,9 @@
use leptos::*;
use melt_ui::*;
#[component]
pub fn DemoSlider(cx: Scope) -> impl IntoView {
view! { cx,
<Slider value=20.0/>
}
}

View file

@ -3,9 +3,12 @@ use melt_ui::*;
mod demo_button; mod demo_button;
mod demo_checkbox; mod demo_checkbox;
mod demo_modal; mod demo_modal;
mod demo_slider;
pub use demo_button::*; pub use demo_button::*;
pub use demo_checkbox::*; pub use demo_checkbox::*;
pub use demo_modal::*; pub use demo_modal::*;
pub use demo_slider::*;
#[component] #[component]
pub fn App(cx: Scope) -> impl IntoView { pub fn App(cx: Scope) -> impl IntoView {
@ -49,6 +52,8 @@ pub fn App(cx: Scope) -> impl IntoView {
<DemoModal/> <DemoModal/>
<hr /> <hr />
<DemoCheckout /> <DemoCheckout />
<hr />
<DemoSlider />
} }
} }

View file

@ -4,6 +4,7 @@ mod checkbox;
mod input; mod input;
mod modal; mod modal;
mod progress; mod progress;
mod slider;
mod space; mod space;
mod table; mod table;
mod teleport; mod teleport;
@ -15,6 +16,7 @@ pub use checkbox::*;
pub use input::*; pub use input::*;
pub use modal::*; pub use modal::*;
pub use progress::*; pub use progress::*;
pub use slider::*;
pub use space::*; pub use space::*;
pub use table::*; pub use table::*;
pub use theme::Theme; pub use theme::Theme;

42
src/slider/mod.rs Normal file
View file

@ -0,0 +1,42 @@
use crate::{theme::use_theme, utils::mount_style::mount_style, Theme};
use leptos::*;
use stylers::style_sheet_str;
#[component]
pub fn Slider(
cx: Scope,
#[prop(optional, into)] value: MaybeSignal<f64>,
#[prop(optional)] on_value: Option<SignalSetter<String>>,
#[prop(default = MaybeSignal::Static(100f64), into)] max: MaybeSignal<f64>,
) -> impl IntoView {
let theme = use_theme(cx, Theme::light);
let css_vars = create_memo(cx, move |_| {
let mut css_vars = String::new();
let theme = theme.get();
let bg_color = theme.common.color_primary;
css_vars.push_str(&format!("--background-color-fill: {bg_color};"));
css_vars
});
let percentage = create_memo(cx, move |_| {
if value.get() < 0.0 || max.get() <= 0.0 {
0f64
} else if value.get() >= max.get() {
100f64
} else {
value.get() / max.get() * 100.0
}
});
let class_name = mount_style("slider", || style_sheet_str!("./src/slider/slider.css"));
view! {cx, class=class_name,
<div class="melt-slider" style=move || css_vars.get()>
<div class="melt-slider-rail">
<div class="melt-slider-rail__fill" style=move || format!("width: {}%", percentage.get())></div>
</div>
<div class="melt-slider-handle" style=move || format!("left: {}%; transform: translateX(-{}%)", percentage.get(), percentage.get())>
</div>
</div>
}
}

25
src/slider/slider.css Normal file
View file

@ -0,0 +1,25 @@
.melt-slider {
position: relative;
padding: 6px 0;
cursor: pointer;
}
.melt-slider-rail {
height: 4px;
background-color: #e6e6e6;
border-radius: 2px;
}
.melt-slider-rail__fill {
width: 0%;
height: 4px;
background-color: var(--background-color-fill);
border-radius: 2px;
}
.melt-slider-handle {
position: absolute;
top: 0px;
width: 16px;
height: 16px;
border-radius: 50%;
background-color: white;
box-shadow: 0px 0px 4px #2224;
}