leptos_use/
use_active_element.rs

1#![cfg_attr(feature = "ssr", allow(unused_variables, unused_imports))]
2
3use crate::{use_document, use_event_listener_with_options, use_window, UseEventListenerOptions};
4use leptos::ev::{blur, focus};
5use leptos::prelude::*;
6use leptos::reactive::wrappers::read::Signal;
7
8/// Reactive `document.activeElement`
9///
10/// ## Demo
11///
12/// [Link to Demo](https://github.com/Synphonyte/leptos-use/tree/main/examples/use_active_element)
13///
14/// ## Usage
15///
16/// ```
17/// # use leptos::prelude::*;
18/// # use leptos::logging::log;
19/// # use leptos_use::use_active_element;
20/// #
21/// # #[component]
22/// # fn Demo() -> impl IntoView {
23/// let active_element = use_active_element();
24///
25/// Effect::new(move || {
26///     log!("focus changed to {:?}", active_element.get());
27/// });
28/// #
29/// # view! { }
30/// # }
31/// ```
32///
33/// ## Server-Side Rendering
34///
35/// On the server this returns a `Signal` that always contains the value `None`.
36pub fn use_active_element() -> Signal<Option<web_sys::Element>, LocalStorage> {
37    let get_active_element = move || use_document().active_element();
38
39    let (active_element, set_active_element) = signal_local(get_active_element());
40
41    let listener_options = UseEventListenerOptions::default().capture(true);
42
43    let _ = use_event_listener_with_options(
44        use_window(),
45        blur,
46        move |event| {
47            if event.related_target().is_some() {
48                return;
49            }
50
51            set_active_element.update(|el| *el = get_active_element());
52        },
53        listener_options,
54    );
55
56    let _ = use_event_listener_with_options(
57        use_window(),
58        focus,
59        move |_| {
60            set_active_element.update(|el| *el = get_active_element());
61        },
62        listener_options,
63    );
64
65    active_element.into()
66}