1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
use leptos_reactive::{
create_rw_signal, RwSignal, Scope
};
/// Contains a shared reference to a DOM node creating while using the [view](leptos::view)
/// macro to create your UI.
///
/// ```
/// # use leptos::*;
/// #[component]
/// pub fn MyComponent(cx: Scope) -> Element {
/// let input_ref = NodeRef::new(cx);
///
/// let on_click = move |_| {
/// let node = input_ref
/// .get()
/// .expect("input_ref should be loaded by now")
/// .unchecked_into::<web_sys::HtmlInputElement>();
/// log!("value is {:?}", node.value())
/// };
///
/// view! {
/// cx,
/// <div>
/// // `node_ref` loads the input
/// <input _ref=input_ref type="text"/>
/// // the button consumes it
/// <button on:click=on_click>"Click me"</button>
/// </div>
/// }
/// }
/// ```
#[derive(Copy, Clone, PartialEq)]
pub struct NodeRef(RwSignal<Option<web_sys::Element>>);
impl NodeRef {
/// Creates an empty reference.
pub fn new(cx: Scope) -> Self {
Self(create_rw_signal(cx, None))
}
/// Gets the element that is currently stored in the reference.
///
/// This tracks reactively, so that node references can be used in effects.
/// Initially, the value will be `None`, but once it is loaded the effect
/// will rerun and its value will be `Some(Element)`.
pub fn get(&self) -> Option<web_sys::Element> {
self.0.get()
}
#[doc(hidden)]
/// Loads an element into the reference. This tracks reactively,
/// so that effects that use the node reference will rerun once it is loaded,
/// i.e., effects can be forward-declared.
pub fn load(&self, node: &web_sys::Element) {
self.0.set(Some(node.clone()))
}
}
cfg_if::cfg_if! {
if #[cfg(not(feature = "stable"))] {
impl FnOnce<()> for NodeRef {
type Output = Option<web_sys::Element>;
extern "rust-call" fn call_once(self, _args: ()) -> Self::Output {
self.get()
}
}
impl FnMut<()> for NodeRef {
extern "rust-call" fn call_mut(&mut self, _args: ()) -> Self::Output {
self.get()
}
}
impl Fn<()> for NodeRef {
extern "rust-call" fn call(&self, _args: ()) -> Self::Output {
self.get()
}
}
}
}