mirror of
https://github.com/adoyle0/leptos-use.git
synced 2025-02-02 10:54:15 -05:00
added use_window and use_document
This commit is contained in:
parent
7f5ee51e49
commit
0aff004250
9 changed files with 109 additions and 33 deletions
|
@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
Please check the release notes of Leptos 0.5 for how to upgrade.
|
Please check the release notes of Leptos 0.5 for how to upgrade.
|
||||||
- `watch` is now deprecated in favor of `leptos::watch` and will be removed in a future release.
|
- `watch` is now deprecated in favor of `leptos::watch` and will be removed in a future release.
|
||||||
`watch_with_options` will continue to exist.
|
`watch_with_options` will continue to exist.
|
||||||
|
- `use_event_listener_with_options` now takes a `UseEventListenerOptions` instead of a `web_sys::AddEventListenerOptions`.
|
||||||
- `use_websocket`:
|
- `use_websocket`:
|
||||||
- takes now a `&str` instead of a `String` as its `url` parameter.
|
- takes now a `&str` instead of a `String` as its `url` parameter.
|
||||||
- The `ready_state` return type is now renamed to `ConnectionReadyState` instead of `UseWebSocketReadyState`.
|
- The `ready_state` return type is now renamed to `ConnectionReadyState` instead of `UseWebSocketReadyState`.
|
||||||
|
@ -38,6 +39,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- Callbacks in options don't require to be cloneable anymore
|
- Callbacks in options don't require to be cloneable anymore
|
||||||
- Callback in `use_raf_fn` doesn't require to be cloneable anymore
|
- Callback in `use_raf_fn` doesn't require to be cloneable anymore
|
||||||
- `use_scroll` is now callable on the server
|
- `use_scroll` is now callable on the server
|
||||||
|
- `use_event_listener` can now be called safely on the server.
|
||||||
|
|
||||||
|
|
||||||
### Fixes 🍕
|
### Fixes 🍕
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::{UseDocument, UseWindow};
|
||||||
use leptos::html::ElementDescriptor;
|
use leptos::html::ElementDescriptor;
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
@ -153,6 +154,22 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! impl_from_deref_option {
|
||||||
|
($ty:ty, $ty2:ty) => {
|
||||||
|
impl<E> From<$ty> for ElementMaybeSignal<$ty2, E>
|
||||||
|
where
|
||||||
|
E: From<$ty2> + 'static,
|
||||||
|
{
|
||||||
|
fn from(value: $ty) -> Self {
|
||||||
|
Self::Static((*value).clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_from_deref_option!(UseWindow, web_sys::Window);
|
||||||
|
impl_from_deref_option!(UseDocument, web_sys::Document);
|
||||||
|
|
||||||
// From string (selector) ///////////////////////////////////////////////////////////////
|
// From string (selector) ///////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
impl<'a, E> From<&'a str> for ElementMaybeSignal<web_sys::Element, E>
|
impl<'a, E> From<&'a str> for ElementMaybeSignal<web_sys::Element, E>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::core::ElementMaybeSignal;
|
use crate::core::ElementMaybeSignal;
|
||||||
|
use crate::{UseDocument, UseWindow};
|
||||||
use leptos::html::ElementDescriptor;
|
use leptos::html::ElementDescriptor;
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
@ -154,6 +155,22 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! impl_from_deref_option {
|
||||||
|
($ty:ty, $ty2:ty) => {
|
||||||
|
impl<E> From<$ty> for ElementsMaybeSignal<$ty2, E>
|
||||||
|
where
|
||||||
|
E: From<$ty2> + 'static,
|
||||||
|
{
|
||||||
|
fn from(value: $ty) -> Self {
|
||||||
|
Self::Static(vec![(*value).clone()])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_from_deref_option!(UseWindow, web_sys::Window);
|
||||||
|
impl_from_deref_option!(UseDocument, web_sys::Document);
|
||||||
|
|
||||||
// From string (selector) ///////////////////////////////////////////////////////////////
|
// From string (selector) ///////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
impl<'a, E> From<&'a str> for ElementsMaybeSignal<web_sys::Node, E>
|
impl<'a, E> From<&'a str> for ElementsMaybeSignal<web_sys::Node, E>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::core::{ElementMaybeSignal, ElementsMaybeSignal};
|
use crate::core::{ElementMaybeSignal, ElementsMaybeSignal};
|
||||||
use crate::utils::IS_IOS;
|
use crate::utils::IS_IOS;
|
||||||
use crate::{use_event_listener, use_event_listener_with_options};
|
use crate::{use_event_listener, use_event_listener_with_options, UseEventListenerOptions};
|
||||||
use default_struct_builder::DefaultBuilder;
|
use default_struct_builder::DefaultBuilder;
|
||||||
use leptos::ev::{blur, click, pointerdown};
|
use leptos::ev::{blur, click, pointerdown};
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
|
@ -9,7 +9,6 @@ use std::rc::Rc;
|
||||||
use std::sync::RwLock;
|
use std::sync::RwLock;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use wasm_bindgen::JsCast;
|
use wasm_bindgen::JsCast;
|
||||||
use web_sys::AddEventListenerOptions;
|
|
||||||
|
|
||||||
static IOS_WORKAROUND: RwLock<bool> = RwLock::new(false);
|
static IOS_WORKAROUND: RwLock<bool> = RwLock::new(false);
|
||||||
|
|
||||||
|
@ -151,14 +150,13 @@ where
|
||||||
let remove_click_listener = {
|
let remove_click_listener = {
|
||||||
let mut listener = listener.clone();
|
let mut listener = listener.clone();
|
||||||
|
|
||||||
let mut options = AddEventListenerOptions::default();
|
|
||||||
options.passive(true).capture(capture);
|
|
||||||
|
|
||||||
use_event_listener_with_options::<_, web_sys::Window, _, _>(
|
use_event_listener_with_options::<_, web_sys::Window, _, _>(
|
||||||
window(),
|
window(),
|
||||||
click,
|
click,
|
||||||
move |event| listener(event.into()),
|
move |event| listener(event.into()),
|
||||||
options,
|
UseEventListenerOptions::default()
|
||||||
|
.passive(true)
|
||||||
|
.capture(capture),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -166,9 +164,6 @@ where
|
||||||
let target = target.clone();
|
let target = target.clone();
|
||||||
let should_listen = Rc::clone(&should_listen);
|
let should_listen = Rc::clone(&should_listen);
|
||||||
|
|
||||||
let mut options = AddEventListenerOptions::default();
|
|
||||||
options.passive(true);
|
|
||||||
|
|
||||||
use_event_listener_with_options::<_, web_sys::Window, _, _>(
|
use_event_listener_with_options::<_, web_sys::Window, _, _>(
|
||||||
window(),
|
window(),
|
||||||
pointerdown,
|
pointerdown,
|
||||||
|
@ -180,7 +175,7 @@ where
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
options,
|
UseEventListenerOptions::default().passive(true),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use cfg_if::cfg_if;
|
use cfg_if::cfg_if;
|
||||||
use default_struct_builder::DefaultBuilder;
|
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
@ -34,6 +33,7 @@ pub fn use_document() -> UseDocument {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return type of [`use_document`].
|
/// Return type of [`use_document`].
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct UseDocument(Option<web_sys::Document>);
|
pub struct UseDocument(Option<web_sys::Document>);
|
||||||
|
|
||||||
impl Deref for UseDocument {
|
impl Deref for UseDocument {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::core::{ElementMaybeSignal, MaybeRwSignal, PointerType, Position};
|
use crate::core::{ElementMaybeSignal, MaybeRwSignal, PointerType, Position};
|
||||||
use crate::use_event_listener_with_options;
|
use crate::{use_event_listener_with_options, UseEventListenerOptions};
|
||||||
use default_struct_builder::DefaultBuilder;
|
use default_struct_builder::DefaultBuilder;
|
||||||
use leptos::ev::{pointerdown, pointermove, pointerup};
|
use leptos::ev::{pointerdown, pointermove, pointerup};
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
|
@ -183,20 +183,19 @@ where
|
||||||
handle_event(event);
|
handle_event(event);
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut listener_options = web_sys::AddEventListenerOptions::new();
|
let listener_options = UseEventListenerOptions::default().capture(true);
|
||||||
listener_options.capture(true);
|
|
||||||
|
|
||||||
let _ = use_event_listener_with_options(
|
let _ = use_event_listener_with_options(
|
||||||
dragging_handle,
|
dragging_handle,
|
||||||
pointerdown,
|
pointerdown,
|
||||||
on_pointer_down,
|
on_pointer_down,
|
||||||
listener_options.clone(),
|
listener_options,
|
||||||
);
|
);
|
||||||
let _ = use_event_listener_with_options(
|
let _ = use_event_listener_with_options(
|
||||||
dragging_element.clone(),
|
dragging_element.clone(),
|
||||||
pointermove,
|
pointermove,
|
||||||
on_pointer_move,
|
on_pointer_move,
|
||||||
listener_options.clone(),
|
listener_options,
|
||||||
);
|
);
|
||||||
let _ = use_event_listener_with_options(
|
let _ = use_event_listener_with_options(
|
||||||
dragging_element,
|
dragging_element,
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
use crate::core::ElementMaybeSignal;
|
use crate::core::ElementMaybeSignal;
|
||||||
use crate::use_event_listener_with_options;
|
use crate::{use_event_listener_with_options, UseEventListenerOptions};
|
||||||
use default_struct_builder::DefaultBuilder;
|
use default_struct_builder::DefaultBuilder;
|
||||||
use leptos::ev::{mouseenter, mouseleave};
|
use leptos::ev::{mouseenter, mouseleave};
|
||||||
use leptos::leptos_dom::helpers::TimeoutHandle;
|
use leptos::leptos_dom::helpers::TimeoutHandle;
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use web_sys::AddEventListenerOptions;
|
|
||||||
|
|
||||||
/// Reactive element's hover state.
|
/// Reactive element's hover state.
|
||||||
///
|
///
|
||||||
|
@ -81,14 +80,13 @@ where
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut listener_options = AddEventListenerOptions::new();
|
let mut listener_options = UseEventListenerOptions::default().passive(true);
|
||||||
listener_options.passive(true);
|
|
||||||
|
|
||||||
let _ = use_event_listener_with_options(
|
let _ = use_event_listener_with_options(
|
||||||
el.clone(),
|
el.clone(),
|
||||||
mouseenter,
|
mouseenter,
|
||||||
move |_| toggle(true),
|
move |_| toggle(true),
|
||||||
listener_options.clone(),
|
listener_options,
|
||||||
);
|
);
|
||||||
|
|
||||||
let _ =
|
let _ =
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::core::ElementMaybeSignal;
|
use crate::core::ElementMaybeSignal;
|
||||||
use crate::{watch_with_options, WatchOptions};
|
use crate::{watch_with_options, WatchOptions};
|
||||||
|
use default_struct_builder::DefaultBuilder;
|
||||||
use leptos::ev::EventDescriptor;
|
use leptos::ev::EventDescriptor;
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
@ -17,11 +18,11 @@ use wasm_bindgen::JsCast;
|
||||||
/// # use leptos::*;
|
/// # use leptos::*;
|
||||||
/// # use leptos::ev::visibilitychange;
|
/// # use leptos::ev::visibilitychange;
|
||||||
/// # use leptos::logging::log;
|
/// # use leptos::logging::log;
|
||||||
/// # use leptos_use::use_event_listener;
|
/// # use leptos_use::{use_document, use_event_listener};
|
||||||
/// #
|
/// #
|
||||||
/// # #[component]
|
/// # #[component]
|
||||||
/// # fn Demo() -> impl IntoView {
|
/// # fn Demo() -> impl IntoView {
|
||||||
/// use_event_listener(document(), visibilitychange, |evt| {
|
/// use_event_listener(use_document(), visibilitychange, |evt| {
|
||||||
/// log!("{:?}", evt);
|
/// log!("{:?}", evt);
|
||||||
/// });
|
/// });
|
||||||
/// # view! { }
|
/// # view! { }
|
||||||
|
@ -81,7 +82,7 @@ use wasm_bindgen::JsCast;
|
||||||
///
|
///
|
||||||
/// ## Server-Side Rendering
|
/// ## Server-Side Rendering
|
||||||
///
|
///
|
||||||
/// Please refer to ["Functions with Target Elements"](https://leptos-use.rs/server_side_rendering.html#functions-with-target-elements)
|
/// On the server this amounts to a noop.
|
||||||
pub fn use_event_listener<Ev, El, T, F>(target: El, event: Ev, handler: F) -> impl Fn() + Clone
|
pub fn use_event_listener<Ev, El, T, F>(target: El, event: Ev, handler: F) -> impl Fn() + Clone
|
||||||
where
|
where
|
||||||
Ev: EventDescriptor + 'static,
|
Ev: EventDescriptor + 'static,
|
||||||
|
@ -89,12 +90,7 @@ where
|
||||||
T: Into<web_sys::EventTarget> + Clone + 'static,
|
T: Into<web_sys::EventTarget> + Clone + 'static,
|
||||||
F: FnMut(<Ev as EventDescriptor>::EventType) + 'static,
|
F: FnMut(<Ev as EventDescriptor>::EventType) + 'static,
|
||||||
{
|
{
|
||||||
use_event_listener_with_options(
|
use_event_listener_with_options(target, event, handler, UseEventListenerOptions::default())
|
||||||
target,
|
|
||||||
event,
|
|
||||||
handler,
|
|
||||||
web_sys::AddEventListenerOptions::new(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Version of [`use_event_listener`] that takes `web_sys::AddEventListenerOptions`. See the docs for [`use_event_listener`] for how to use.
|
/// Version of [`use_event_listener`] that takes `web_sys::AddEventListenerOptions`. See the docs for [`use_event_listener`] for how to use.
|
||||||
|
@ -102,7 +98,7 @@ pub fn use_event_listener_with_options<Ev, El, T, F>(
|
||||||
target: El,
|
target: El,
|
||||||
event: Ev,
|
event: Ev,
|
||||||
handler: F,
|
handler: F,
|
||||||
options: web_sys::AddEventListenerOptions,
|
options: UseEventListenerOptions,
|
||||||
) -> impl Fn() + Clone
|
) -> impl Fn() + Clone
|
||||||
where
|
where
|
||||||
Ev: EventDescriptor + 'static,
|
Ev: EventDescriptor + 'static,
|
||||||
|
@ -115,7 +111,7 @@ where
|
||||||
|
|
||||||
let cleanup_fn = {
|
let cleanup_fn = {
|
||||||
let closure_js = closure_js.clone();
|
let closure_js = closure_js.clone();
|
||||||
let options = options.clone();
|
let options = options.as_add_event_listener_options();
|
||||||
|
|
||||||
move |element: &web_sys::EventTarget| {
|
move |element: &web_sys::EventTarget| {
|
||||||
let _ = element.remove_event_listener_with_callback_and_event_listener_options(
|
let _ = element.remove_event_listener_with_callback_and_event_listener_options(
|
||||||
|
@ -152,6 +148,8 @@ where
|
||||||
prev_element.replace(element.clone());
|
prev_element.replace(element.clone());
|
||||||
|
|
||||||
if let Some(element) = element {
|
if let Some(element) = element {
|
||||||
|
let options = options.as_add_event_listener_options();
|
||||||
|
|
||||||
_ = element.add_event_listener_with_callback_and_add_event_listener_options(
|
_ = element.add_event_listener_with_callback_and_add_event_listener_options(
|
||||||
&event_name,
|
&event_name,
|
||||||
closure_js.as_ref().unchecked_ref(),
|
closure_js.as_ref().unchecked_ref(),
|
||||||
|
@ -172,3 +170,52 @@ where
|
||||||
|
|
||||||
stop
|
stop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Options for [`use_event_listener_with_options`].
|
||||||
|
#[derive(DefaultBuilder, Default, Copy, Clone)]
|
||||||
|
pub struct UseEventListenerOptions {
|
||||||
|
/// A boolean value indicating that events of this type will be dispatched to
|
||||||
|
/// the registered `listener` before being dispatched to any `EventTarget`
|
||||||
|
/// beneath it in the DOM tree. If not specified, defaults to `false`.
|
||||||
|
capture: bool,
|
||||||
|
|
||||||
|
/// A boolean value indicating that the `listener` should be invoked at most
|
||||||
|
/// once after being added. If `true`, the `listener` would be automatically
|
||||||
|
/// removed when invoked. If not specified, defaults to `false`.
|
||||||
|
once: bool,
|
||||||
|
|
||||||
|
/// A boolean value that, if `true`, indicates that the function specified by
|
||||||
|
/// `listener` will never call
|
||||||
|
/// [`preventDefault()`](https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault "preventDefault()").
|
||||||
|
/// If a passive listener does call `preventDefault()`, the user agent will do
|
||||||
|
/// nothing other than generate a console warning. If not specified,
|
||||||
|
/// defaults to `false` – except that in browsers other than Safari,
|
||||||
|
/// defaults to `true` for the
|
||||||
|
/// [`wheel`](https://developer.mozilla.org/en-US/docs/Web/API/Element/wheel_event "wheel"),
|
||||||
|
/// [`mousewheel`](https://developer.mozilla.org/en-US/docs/Web/API/Element/mousewheel_event "mousewheel"),
|
||||||
|
/// [`touchstart`](https://developer.mozilla.org/en-US/docs/Web/API/Element/touchstart_event "touchstart") and
|
||||||
|
/// [`touchmove`](https://developer.mozilla.org/en-US/docs/Web/API/Element/touchmove_event "touchmove")
|
||||||
|
/// events. See [Improving scrolling performance with passive listeners](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#improving_scrolling_performance_with_passive_listeners)
|
||||||
|
/// to learn more.
|
||||||
|
#[builder(into)]
|
||||||
|
passive: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UseEventListenerOptions {
|
||||||
|
fn as_add_event_listener_options(&self) -> web_sys::AddEventListenerOptions {
|
||||||
|
let UseEventListenerOptions {
|
||||||
|
capture,
|
||||||
|
once,
|
||||||
|
passive,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
let mut options = web_sys::AddEventListenerOptions::new();
|
||||||
|
options.capture(*capture);
|
||||||
|
options.once(*once);
|
||||||
|
if let Some(passive) = passive {
|
||||||
|
options.passive(*passive);
|
||||||
|
}
|
||||||
|
|
||||||
|
options
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::{use_document, UseDocument};
|
use crate::{use_document, UseDocument};
|
||||||
use cfg_if::cfg_if;
|
use cfg_if::cfg_if;
|
||||||
use default_struct_builder::DefaultBuilder;
|
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
@ -36,6 +35,7 @@ pub fn use_window() -> UseWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return type of [`use_window`].
|
/// Return type of [`use_window`].
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct UseWindow(Option<web_sys::Window>);
|
pub struct UseWindow(Option<web_sys::Window>);
|
||||||
|
|
||||||
impl Deref for UseWindow {
|
impl Deref for UseWindow {
|
||||||
|
|
Loading…
Add table
Reference in a new issue