diff --git a/crates/yew-hooks/Cargo.toml b/crates/yew-hooks/Cargo.toml index 290f2f1..27d40fa 100644 --- a/crates/yew-hooks/Cargo.toml +++ b/crates/yew-hooks/Cargo.toml @@ -27,31 +27,33 @@ js-sys = "0.3" version = "0.3" features = [ "BeforeUnloadEvent", - "Element", - "UrlSearchParams", - "WebSocket", - "MessageEvent", - "CloseEvent", "BinaryType", - "DomRectReadOnly", - "Navigator", - "Geolocation", + "Blob", + "CloseEvent", "Coordinates", - "Position", - "PositionError", - "PositionOptions", - "File", "DataTransfer", "DataTransferItem", "DataTransferItemList", + "DomRectReadOnly", + "Element", + "File", + "Geolocation", + "HtmlCollection", + "HtmlLinkElement", "HtmlMediaElement", + "IntersectionObserver", + "IntersectionObserverEntry", + "MessageEvent", + "Navigator", + "Position", + "PositionError", + "PositionOptions", + "StorageEvent", "TimeRanges", "Touch", "TouchList", - "HtmlLinkElement", - "HtmlCollection", - "Blob", - "StorageEvent", + "UrlSearchParams", + "WebSocket", ] [dev-dependencies] diff --git a/crates/yew-hooks/src/hooks/mod.rs b/crates/yew-hooks/src/hooks/mod.rs index 6532801..4c62fa0 100644 --- a/crates/yew-hooks/src/hooks/mod.rs +++ b/crates/yew-hooks/src/hooks/mod.rs @@ -49,6 +49,7 @@ mod use_title; mod use_toggle; mod use_unmount; mod use_update; +mod use_visible; mod use_websocket; mod use_window_scroll; mod use_window_size; @@ -104,6 +105,7 @@ pub use use_title::*; pub use use_toggle::*; pub use use_unmount::*; pub use use_update::*; +pub use use_visible::*; pub use use_websocket::*; pub use use_window_scroll::*; pub use use_window_size::*; diff --git a/crates/yew-hooks/src/hooks/use_visible.rs b/crates/yew-hooks/src/hooks/use_visible.rs new file mode 100644 index 0000000..b9da72a --- /dev/null +++ b/crates/yew-hooks/src/hooks/use_visible.rs @@ -0,0 +1,69 @@ +use wasm_bindgen::{ + closure::Closure, + JsCast, +}; +use web_sys::{IntersectionObserver, IntersectionObserverEntry}; +use yew::{NodeRef, functional::*}; +use crate::use_effect_once; + + +#[hook] +/// Check if an element is visible. Internally, it uses an [`IntersectionObserver`] to receive +/// notifications from the browser whenever the visibility state of the node changes. +/// +/// Setting the sticky bit makes this hook disconnect the observer once the element is visible, and +/// keep the visibility set to `true`, even when it becomes invisible. This is often desired +/// for lazy-loading components. +/// +/// # Example +/// +/// ```rust +/// use yew::prelude::*; +/// use yew_hooks::use_visible; +/// +/// #[function_component] +/// fn MyComponent() -> Html { +/// let node = use_node_ref(); +/// let visible = use_visible(node.clone(), false); +/// html! { +///
{"I'm visible!"}
+/// } else { +///{"I'm invisible!"}
+/// } +///