use crate::core::ElementMaybeSignal; use crate::{use_intersection_observer_with_options, UseIntersectionObserverOptions}; use default_struct_builder::DefaultBuilder; use leptos::*; use std::marker::PhantomData; /// Tracks the visibility of an element within the viewport. /// /// ## Demo /// /// [Link to Demo](https://github.com/Synphonyte/leptos-use/tree/main/examples/use_element_visibility) /// /// ## Usage /// /// ``` /// # use leptos::*; /// # use leptos::html::Div; /// # use leptos_use::use_element_visibility; /// # /// # #[component] /// # fn Demo(cx: Scope) -> impl IntoView { /// let el = create_node_ref::
(cx); /// /// let is_visible = use_element_visibility(cx, el); /// /// view! { cx, ///
///

{is_visible}

///
/// } /// # } /// ``` /// /// ## Server-Side Rendering /// /// Please refer to ["Functions with Target Elements"](https://leptos-use.rs/server_side_rendering.html#functions-with-target-elements) /// /// ## See also /// /// * [`use_intersection_observer`] pub fn use_element_visibility(cx: Scope, target: El) -> Signal where El: Clone, (Scope, El): Into>, T: Into + Clone + 'static, { use_element_visibility_with_options::( cx, target, UseElementVisibilityOptions::default(), ) } pub fn use_element_visibility_with_options( cx: Scope, target: El, options: UseElementVisibilityOptions, ) -> Signal where (Scope, El): Into>, T: Into + Clone + 'static, (Scope, ContainerEl): Into>, ContainerT: Into + Clone + 'static, { let (is_visible, set_visible) = create_signal(cx, false); use_intersection_observer_with_options( cx, (cx, target).into(), move |entries, _| { set_visible.set(entries[0].is_intersecting()); }, UseIntersectionObserverOptions::default().root(options.viewport), ); is_visible.into() } /// Options for [`use_element_visibility_with_options`]. #[derive(DefaultBuilder)] pub struct UseElementVisibilityOptions where (Scope, El): Into>, T: Into + Clone + 'static, { /// A `web_sys::Element` or `web_sys::Document` object which is an ancestor of the intended `target`, /// whose bounding rectangle will be considered the viewport. /// Any part of the target not visible in the visible area of the `root` is not considered visible. /// Defaults to `None` (which means the root `document` will be used). /// Please note that setting this to a `Some(document)` may not be supported by all browsers. /// See [Browser Compatibility](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/IntersectionObserver#browser_compatibility) viewport: Option, #[builder(skip)] _marker: PhantomData, } impl Default for UseElementVisibilityOptions { fn default() -> Self { Self { viewport: None, _marker: PhantomData, } } }