diff --git a/README.md b/README.md index af48b1a..da4fedf 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ fn counter() -> Html { let counter = counter.clone(); Callback::from(move |_| counter.decrease()) }; - + html! { <> @@ -72,7 +72,7 @@ fn counter() -> Html { - `use_toggle` - tracks state of counterparts. - `use_bool_toggle` - tracks state of a boolean. -- `use_counter` - tracks state of a number. +- `use_counter` - tracks state of a number. - `use_latest` - returns the latest immutable ref to state or props. - `use_mut_latest` - returns the latest mutable ref to state or props. - `use_previous` - returns the previous immutable ref to state or props. @@ -134,6 +134,7 @@ fn counter() -> Html { - `use_measure` - tracks an HTML element's dimensions using the `ResizeObserver` API. - `use_geolocation` - tracks user's geographic location. - `use_swipe` - detects swipe based on TouchEvent. +- `use_visible` - checks if an element is visible. ### UI @@ -178,7 +179,7 @@ fn counter() -> Html { let counter = counter.clone(); Callback::from(move |_| counter.reset()) }; - + html! {
diff --git a/crates/yew-hooks/Cargo.toml b/crates/yew-hooks/Cargo.toml index 27d40fa..cdde7fb 100644 --- a/crates/yew-hooks/Cargo.toml +++ b/crates/yew-hooks/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "yew-hooks" -version = "0.3.0" +version = "0.3.1" edition = "2021" authors = ["Jet Li "] categories = ["gui", "wasm", "web-programming"] @@ -16,7 +16,7 @@ documentation = "https://docs.rs/yew-hooks/" [dependencies] log = "0.4" -yew = { version = "0.21.0", features=["csr"] } +yew = { version = "0.21.0", features = ["csr"] } gloo = "0.10" wasm-bindgen = "0.2" wasm-bindgen-futures = "0.4" diff --git a/crates/yew-hooks/src/hooks/use_visible.rs b/crates/yew-hooks/src/hooks/use_visible.rs index 61a0d8e..812c10c 100644 --- a/crates/yew-hooks/src/hooks/use_visible.rs +++ b/crates/yew-hooks/src/hooks/use_visible.rs @@ -4,7 +4,6 @@ use yew::prelude::*; use super::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. /// @@ -15,13 +14,15 @@ use super::use_effect_once; /// # Example /// /// ```rust -/// use yew::prelude::*; -/// use yew_hooks::use_visible; +/// # use yew::prelude::*; +/// # +/// use yew_hooks::prelude::*; /// /// #[function_component] /// fn MyComponent() -> Html { /// let node = use_node_ref(); /// let visible = use_visible(node.clone(), false); +/// /// html! { ///
/// if visible { @@ -33,11 +34,13 @@ use super::use_effect_once; /// } /// } /// ``` +#[hook] pub fn use_visible(node: NodeRef, sticky: bool) -> bool { // code adapted from: // https://stackoverflow.com/questions/1462138/event-listener-for-when-element-becomes-visible let visible = use_state_eq(|| false); let visible_clone = visible.clone(); + use_effect_once(move || { let closure = Closure::, IntersectionObserver)>::new( move |entries: Vec, observer: IntersectionObserver| { @@ -45,9 +48,7 @@ pub fn use_visible(node: NodeRef, sticky: bool) -> bool { let visible = entries.iter().any(|entry| entry.intersection_ratio() > 0.0); // if the visibility changed, update the state. - if (visible != *visible_clone) && (!sticky || !*visible_clone) { - visible_clone.set(visible); - } + visible_clone.set(visible); // if this is sticky and it is currently visible, disconnect the observer. if visible && sticky { @@ -62,5 +63,6 @@ pub fn use_visible(node: NodeRef, sticky: bool) -> bool { } move || observer.disconnect() }); + *visible } diff --git a/crates/yew-hooks/src/hooks/use_websocket.rs b/crates/yew-hooks/src/hooks/use_websocket.rs index fd11804..d39a63f 100644 --- a/crates/yew-hooks/src/hooks/use_websocket.rs +++ b/crates/yew-hooks/src/hooks/use_websocket.rs @@ -33,9 +33,9 @@ pub struct UseWebSocketOptions { /// `WebSocket` close callback. pub onclose: Option>, - /// Retry times. + /// Retry times. Defaults to 3, use `u32::MAX` for infinite retries. pub reconnect_limit: Option, - /// Retry interval(ms). + /// Retry interval(ms). Defaults to 3000. pub reconnect_interval: Option, /// Manually starts connection pub manual: Option, diff --git a/examples/yew-app/src/app/home.rs b/examples/yew-app/src/app/home.rs index d968b6c..e90474f 100644 --- a/examples/yew-app/src/app/home.rs +++ b/examples/yew-app/src/app/home.rs @@ -89,6 +89,7 @@ pub fn home() -> Html {
  • to={AppRoute::UseMeasure} classes="text-emerald-800 underline" >{ "use_measure" }> { " - tracks an HTML element's dimensions using the ResizeObserver API." }
  • to={AppRoute::UseGeolocation} classes="text-emerald-800 underline" >{ "use_geolocation" }> { " - tracks user's geographic location." }
  • to={AppRoute::UseSwipe} classes="text-emerald-800 underline" >{ "use_swipe" }> { " - detects swipe based on TouchEvent." }
  • +
  • to={AppRoute::UseVisible} classes="text-emerald-800 underline" >{ "use_visible" }> { " - checks if an element is visible." }
  • { "UI" }

    diff --git a/examples/yew-app/src/app/hooks/mod.rs b/examples/yew-app/src/app/hooks/mod.rs index 811beed..4201893 100644 --- a/examples/yew-app/src/app/hooks/mod.rs +++ b/examples/yew-app/src/app/hooks/mod.rs @@ -51,6 +51,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; @@ -108,6 +109,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/examples/yew-app/src/app/hooks/use_visible.rs b/examples/yew-app/src/app/hooks/use_visible.rs new file mode 100644 index 0000000..644b71a --- /dev/null +++ b/examples/yew-app/src/app/hooks/use_visible.rs @@ -0,0 +1,28 @@ +use yew::prelude::*; +use yew_hooks::prelude::*; + +/// `use_visible` demo +#[function_component] +pub fn UseVisible() -> Html { + let node = use_node_ref(); + let visible = use_visible(node.clone(), false); + + html! { +
    +
    +
    +

    + { " Visible: " } + { visible } +

    +
    +
    +
    { "Try to scroll in this area." }
    +
    +
    +
    +
    +
    +
    + } +} diff --git a/examples/yew-app/src/app/mod.rs b/examples/yew-app/src/app/mod.rs index 8e429e5..a21f97c 100644 --- a/examples/yew-app/src/app/mod.rs +++ b/examples/yew-app/src/app/mod.rs @@ -127,6 +127,8 @@ pub enum AppRoute { UseClipboard, #[at("/use_infinite_scroll")] UseInfiniteScroll, + #[at("/use_visible")] + UseVisible, #[not_found] #[at("/page-not-found")] PageNotFound, @@ -195,6 +197,7 @@ pub fn switch(routes: AppRoute) -> Html { AppRoute::UseFavicon => html! { }, AppRoute::UseClipboard => html! { }, AppRoute::UseInfiniteScroll => html! { }, + AppRoute::UseVisible => html! { }, AppRoute::PageNotFound => html! { }, } }