leptos_use/
use_window.rs

1use crate::core::impl_ssr_safe_method;
2use crate::{use_document, UseDocument};
3use cfg_if::cfg_if;
4use std::ops::Deref;
5
6#[cfg(not(feature = "ssr"))]
7use leptos::prelude::*;
8
9/// SSR safe `window()`.
10/// This returns just a new-type wrapper around `Option<Window>`.
11/// Calling this amounts to `None` on the server and `Some(Window)` on the client.
12///
13/// It provides some convenient methods for working with the window like `document()` and `navigator()`.
14/// These will all return `None` on the server.
15///
16/// ## Usage
17///
18/// ```
19/// # use leptos::prelude::*;
20/// # use leptos_use::use_window;
21/// #
22/// # #[component]
23/// # fn Demo() -> impl IntoView {
24/// let window = use_window();
25///
26/// // Returns `None` on the server but will not panic.
27/// let navigator = window.navigator();
28/// #
29/// # view! { }
30/// # }
31/// ```
32pub fn use_window() -> UseWindow {
33    cfg_if! { if #[cfg(feature = "ssr")] {
34        UseWindow(None)
35    } else {
36        UseWindow(Some(window()))
37    }}
38}
39
40/// Return type of [`use_window`].
41#[derive(Debug, Clone, PartialEq, Eq)]
42pub struct UseWindow(Option<web_sys::Window>);
43
44impl Deref for UseWindow {
45    type Target = Option<web_sys::Window>;
46    fn deref(&self) -> &Self::Target {
47        &self.0
48    }
49}
50
51impl UseWindow {
52    impl_ssr_safe_method!(
53        /// Returns `Some(Navigator)` in the Browser. `None` otherwise.
54        navigator(&self) -> Option<web_sys::Navigator>
55    );
56
57    /// Returns the same as [`fn@use_document`].
58    #[inline(always)]
59    pub fn document(&self) -> UseDocument {
60        use_document()
61    }
62
63    impl_ssr_safe_method!(
64        /// Returns the same as `window().match_media()` in the Browser. `Ok(None)` otherwise.
65        match_media(&self, query: &str) -> Result<Option<web_sys::MediaQueryList>, wasm_bindgen::JsValue>;
66        .unwrap_or(Ok(None))
67    );
68}