use crate::{IntoElementMaybeSignal, UseElementBoundingOptions, UseElementBoundingReturn};
use leptos::prelude::*;
pub fn use_element_bounding<El, M>(
target: El,
) -> UseElementBoundingReturn<impl Fn() + Clone + Send + Sync>
where
El: IntoElementMaybeSignal<web_sys::Element, M>,
{
use_element_bounding_with_options(target, UseElementBoundingOptions::default())
}
pub fn use_element_bounding_with_options<El, M>(
target: El,
options: UseElementBoundingOptions,
) -> UseElementBoundingReturn<impl Fn() + Clone + Send + Sync>
where
El: IntoElementMaybeSignal<web_sys::Element, M>,
{
let (height, set_height) = signal(0.0);
let (width, set_width) = signal(0.0);
let (left, set_left) = signal(0.0);
let (right, set_right) = signal(0.0);
let (top, set_top) = signal(0.0);
let (bottom, set_bottom) = signal(0.0);
let (x, set_x) = signal(0.0);
let (y, set_y) = signal(0.0);
let update;
#[cfg(feature = "ssr")]
{
let _ = target;
let _ = options;
let _ = set_height;
let _ = set_width;
let _ = set_left;
let _ = set_right;
let _ = set_top;
let _ = set_bottom;
let _ = set_x;
let _ = set_y;
update = move || ();
}
#[cfg(not(feature = "ssr"))]
{
use crate::{
UseEventListenerOptions, sendwrap_fn, use_event_listener_with_options,
use_resize_observer, use_window,
};
use leptos::ev::{resize, scroll};
let UseElementBoundingOptions {
reset,
window_resize,
window_scroll,
immediate,
} = options;
let target = target.into_element_maybe_signal();
update = sendwrap_fn!(move || {
let el = target.get_untracked();
if let Some(el) = el {
let rect = el.get_bounding_client_rect();
set_height.set(rect.height());
set_width.set(rect.width());
set_left.set(rect.x());
set_right.set(rect.x() + rect.width());
set_top.set(rect.y());
set_bottom.set(rect.y() + rect.height());
set_x.set(rect.x());
set_y.set(rect.y());
} else if reset {
set_height.set(0.0);
set_width.set(0.0);
set_left.set(0.0);
set_right.set(0.0);
set_top.set(0.0);
set_bottom.set(0.0);
set_x.set(0.0);
set_y.set(0.0);
}
});
use_resize_observer(target, {
let update = update.clone();
move |_, _| {
update();
}
});
Effect::watch(
move || target.get(),
{
let update = update.clone();
move |_, _, _| {
update();
}
},
false,
);
if window_scroll {
let _ = use_event_listener_with_options(
use_window(),
scroll,
{
let update = update.clone();
move |_| update()
},
UseEventListenerOptions::default()
.capture(true)
.passive(true),
);
}
if window_resize {
let _ = use_event_listener_with_options(
use_window(),
resize,
{
let update = update.clone();
move |_| update()
},
UseEventListenerOptions::default().passive(true),
);
}
if immediate {
update();
}
}
UseElementBoundingReturn {
height: height.into(),
width: width.into(),
left: left.into(),
right: right.into(),
top: top.into(),
bottom: bottom.into(),
x: x.into(),
y: y.into(),
update,
}
}