biji_ui/utils/
prevent_scroll.rs1use std::time::Duration;
2
3use leptos::{
4 leptos_dom::{self, helpers::TimeoutHandle},
5 prelude::*,
6};
7
8pub fn use_prevent_scroll<F>(should_prevent: F, hide_delay: Duration) -> RenderEffect<()>
25where
26 F: Fn() -> bool + 'static,
27{
28 let hide_handle: StoredValue<Option<TimeoutHandle>> = StoredValue::new(None);
29
30 RenderEffect::new(move |_| {
31 if should_prevent() {
32 if let Some(h) = hide_handle.get_value() {
34 h.clear();
35 }
36
37 if let Some(doc) = document().body() {
39 let client_width = f64::from(doc.client_width());
40 let inner_width = window()
41 .inner_width()
42 .unwrap()
43 .as_f64()
44 .unwrap_or(client_width);
45 let scrollbar_width = inner_width - client_width;
46
47 let _ = doc.style().set_property("overflow", "hidden");
48 let _ = doc
49 .style()
50 .set_property("--scrollbar-width", &format!("{}px", scrollbar_width));
51 let _ = doc
52 .style()
53 .set_property("padding-right", &format!("calc({}px)", scrollbar_width));
54 }
55 } else {
56 let h = leptos_dom::helpers::set_timeout_with_handle(
58 move || {
59 if let Some(doc) = document().body() {
60 let _ = doc.style().remove_property("overflow");
61 let _ = doc.style().remove_property("--scrollbar-width");
62 let _ = doc.style().remove_property("padding-right");
63 }
64 },
65 hide_delay,
66 )
67 .expect("set timeout in use_prevent_scroll");
68 hide_handle.set_value(Some(h));
69 }
70 })
71}