1use crate::{bool_to_option, to_option_string};
2use gloo::events::EventListener;
3use wasm_bindgen::prelude::*;
4use wasm_bindgen::JsCast;
5use web_sys::{CustomEvent, Element};
6use yew::prelude::*;
7
8#[wasm_bindgen(module = "/build/mwc-slider.js")]
9extern "C" {
10 #[derive(Debug)]
11 type Slider;
12
13 #[wasm_bindgen(getter, static_method_of = Slider)]
15 fn _dummy_loader() -> JsValue;
16}
17
18loader_hack!(Slider);
20
21pub struct MatSlider {
25 node_ref: NodeRef,
26 input_listener: Option<EventListener>,
27 change_listener: Option<EventListener>,
28}
29
30#[derive(Debug, Properties, PartialEq, Clone)]
37pub struct SliderProps {
38 #[prop_or(0)]
39 pub value: u32,
40 #[prop_or(0)]
41 pub min: u32,
42 #[prop_or(100)]
43 pub max: u32,
44 #[prop_or(1)]
45 pub step: u32,
46 #[prop_or(false)]
47 pub pin: bool,
48 #[prop_or(false)]
49 pub markers: bool,
50 #[prop_or_default]
54 pub oninput: Callback<CustomEvent>,
55 #[prop_or_default]
59 pub onchange: Callback<CustomEvent>,
60}
61
62impl Component for MatSlider {
63 type Message = ();
64 type Properties = SliderProps;
65
66 fn create(_: &Context<Self>) -> Self {
67 Slider::ensure_loaded();
68 Self {
69 node_ref: NodeRef::default(),
70 input_listener: None,
71 change_listener: None,
72 }
73 }
74
75 fn view(&self, ctx: &Context<Self>) -> Html {
76 let props = ctx.props();
77 html! {
78 <mwc-slider
79 value={to_option_string(props.value)}
80 min={to_option_string(props.min)}
81 max={to_option_string(props.max)}
82 step={to_option_string(props.step)}
83 pin={bool_to_option(props.pin)}
84 markers={bool_to_option(props.markers)}
85 ref={self.node_ref.clone()}
86 ></mwc-slider>
87 }
88 }
89
90 fn rendered(&mut self, ctx: &Context<Self>, _first_render: bool) {
91 let props = ctx.props();
92 let element = self.node_ref.cast::<Element>().unwrap();
93 if self.input_listener.is_none() {
94 let oninput = props.oninput.clone();
95 self.input_listener = Some(EventListener::new(&element, "input", move |event| {
96 oninput.emit(JsValue::from(event).unchecked_into::<CustomEvent>())
97 }));
98 };
99
100 if self.change_listener.is_none() {
101 let onchange = props.onchange.clone();
102 self.change_listener = Some(EventListener::new(&element, "change", move |event| {
103 onchange.emit(JsValue::from(event).unchecked_into::<CustomEvent>())
104 }));
105 }
106 }
107}