consecuit_html/
callback.rs

1use std::{ops::Deref, rc::Rc};
2
3use consecuit::prelude::batch_updates;
4use js_sys::Function;
5use wasm_bindgen::{convert::FromWasmAbi, prelude::Closure, JsCast};
6
7/** A callback for HTML attributes like `onclick`, `oninput`, etc.
8
9Create one with `Callback::new`, and pass it to the prop builder. Like this:
10
11```
12let click_handler = Callback::new(move |ev: web_sys::MouseEvent| {
13    web_sys::console::log_1(
14        &"You clicked the button!".into()
15    );
16});
17
18cc_tree!(
19    <button {html_props().onclick(click_handler)}>"click me!"</button>
20)
21
22*/
23#[derive(Clone)]
24pub struct Callback<E: FromWasmAbi + 'static>(Rc<Closure<dyn Fn(E)>>);
25
26impl<E: FromWasmAbi + 'static> PartialEq for Callback<E> {
27    fn eq(&self, other: &Self) -> bool {
28        Rc::ptr_eq(&self.0, &other.0)
29    }
30}
31
32impl<E: FromWasmAbi + 'static> Callback<E> {
33    pub fn new<F: Fn(E) + 'static>(f: F) -> Self {
34        Self(Rc::new(Closure::wrap(Box::new(move |e: E| {
35            batch_updates(|| {
36                f(e);
37            })
38        }))))
39    }
40    pub fn as_websys_function(&self) -> &Function {
41        self.0.deref().as_ref().unchecked_ref()
42    }
43}