Skip to content

Commit

Permalink
use_visible demo
Browse files Browse the repository at this point in the history
  • Loading branch information
jetli committed Mar 5, 2024
1 parent 63e5c43 commit 4bfd439
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 13 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ fn counter() -> Html {
let counter = counter.clone();
Callback::from(move |_| counter.decrease())
};

html! {
<>
<button onclick={onincrease}>{ "Increase" }</button>
Expand All @@ -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.
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -178,7 +179,7 @@ fn counter() -> Html {
let counter = counter.clone();
Callback::from(move |_| counter.reset())
};

html! {
<div>
<button onclick={onincrease}>{ "Increase" }</button>
Expand Down
4 changes: 2 additions & 2 deletions crates/yew-hooks/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "yew-hooks"
version = "0.3.0"
version = "0.3.1"
edition = "2021"
authors = ["Jet Li <jing.i.qin@icloud.com>"]
categories = ["gui", "wasm", "web-programming"]
Expand All @@ -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"
Expand Down
14 changes: 8 additions & 6 deletions crates/yew-hooks/src/hooks/use_visible.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand All @@ -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! {
/// <div ref={node}>
/// if visible {
Expand All @@ -33,21 +34,21 @@ 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::<dyn Fn(Vec<IntersectionObserverEntry>, IntersectionObserver)>::new(
move |entries: Vec<IntersectionObserverEntry>, observer: IntersectionObserver| {
// determine if any part of this node is visible.
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 {
Expand All @@ -62,5 +63,6 @@ pub fn use_visible(node: NodeRef, sticky: bool) -> bool {
}
move || observer.disconnect()
});

*visible
}
4 changes: 2 additions & 2 deletions crates/yew-hooks/src/hooks/use_websocket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ pub struct UseWebSocketOptions {
/// `WebSocket` close callback.
pub onclose: Option<Box<dyn FnMut(CloseEvent)>>,

/// Retry times.
/// Retry times. Defaults to 3, use `u32::MAX` for infinite retries.
pub reconnect_limit: Option<u32>,
/// Retry interval(ms).
/// Retry interval(ms). Defaults to 3000.
pub reconnect_interval: Option<u32>,
/// Manually starts connection
pub manual: Option<bool>,
Expand Down
1 change: 1 addition & 0 deletions examples/yew-app/src/app/home.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ pub fn home() -> Html {
<li><Link<AppRoute> to={AppRoute::UseMeasure} classes="text-emerald-800 underline" >{ "use_measure" }</Link<AppRoute>> { " - tracks an HTML element's dimensions using the ResizeObserver API." }</li>
<li><Link<AppRoute> to={AppRoute::UseGeolocation} classes="text-emerald-800 underline" >{ "use_geolocation" }</Link<AppRoute>> { " - tracks user's geographic location." }</li>
<li><Link<AppRoute> to={AppRoute::UseSwipe} classes="text-emerald-800 underline" >{ "use_swipe" }</Link<AppRoute>> { " - detects swipe based on TouchEvent." }</li>
<li><Link<AppRoute> to={AppRoute::UseVisible} classes="text-emerald-800 underline" >{ "use_visible" }</Link<AppRoute>> { " - checks if an element is visible." }</li>
</ul>

<h2 class="text-2xl font-bold">{ "UI" }</h2>
Expand Down
2 changes: 2 additions & 0 deletions examples/yew-app/src/app/hooks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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::*;
28 changes: 28 additions & 0 deletions examples/yew-app/src/app/hooks/use_visible.rs
Original file line number Diff line number Diff line change
@@ -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! {
<div class="container">
<header class="mt-24 text-xl text-center">
<div class="space-x-4 space-y-4">
<p>
<b>{ " Visible: " }</b>
{ visible }
</p>
<div class="w-[600px] h-[400px] overflow-scroll bg-emerald-800 mx-auto text-slate-100">
<div class="w-[1000px] h-[1000px] text-left">
<div class="h-[600px]">{ "Try to scroll in this area." }</div>
<div ref={node} class="w-[100px] h-[100px] bg-slate-800"></div>
</div>
</div>
</div>
</header>
</div>
}
}
3 changes: 3 additions & 0 deletions examples/yew-app/src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ pub enum AppRoute {
UseClipboard,
#[at("/use_infinite_scroll")]
UseInfiniteScroll,
#[at("/use_visible")]
UseVisible,
#[not_found]
#[at("/page-not-found")]
PageNotFound,
Expand Down Expand Up @@ -195,6 +197,7 @@ pub fn switch(routes: AppRoute) -> Html {
AppRoute::UseFavicon => html! { <UseFavicon /> },
AppRoute::UseClipboard => html! { <UseClipboard /> },
AppRoute::UseInfiniteScroll => html! { <UseInfiniteScroll /> },
AppRoute::UseVisible => html! { <UseVisible /> },
AppRoute::PageNotFound => html! { <Home /> },
}
}
Expand Down

0 comments on commit 4bfd439

Please sign in to comment.