floating_ui/floating_ui/dom/
auto_update.rs1use js_sys::Object;
2use wasm_bindgen::prelude::*;
3use web_sys::HtmlElement;
4
5use crate::{
6 error::{Error, Result},
7 utils_::object_utils,
8};
9
10#[wasm_bindgen(js_namespace=["window", "FloatingUIDOM"])]
11extern "C" {
12 #[wasm_bindgen]
13 fn autoUpdate(
14 reference: HtmlElement,
15 floating: HtmlElement,
16 update: &Closure<dyn Fn()>,
17 options: JsValue,
18 );
19}
20
21pub fn auto_update<F>(
22 reference: HtmlElement,
23 floating: HtmlElement,
24 update: F,
25 options: AutoUpdateOptions,
26) -> Result<()>
27where
28 F: Fn() + 'static,
29{
30 let update: Closure<dyn Fn()> = Closure::new(update);
31 let options: JsValue = options.try_into()?;
32
33 let cleanup = autoUpdate(reference, floating, &update, options);
35
36 update.forget();
37
38 Ok(cleanup)
39}
40pub struct AutoUpdateOptions {
41 ancestor_scroll: Option<bool>,
42 ancestor_resize: Option<bool>,
43 element_resize: Option<bool>,
44 layout_shift: Option<bool>,
45 animation_frame: Option<bool>,
46}
47
48impl AutoUpdateOptions {
49 pub fn new() -> Self {
50 Self {
51 ancestor_scroll: None,
52 ancestor_resize: None,
53 element_resize: None,
54 layout_shift: None,
55 animation_frame: None,
56 }
57 }
58
59 pub fn ancestor_scroll(&mut self) -> &mut Self {
60 self.ancestor_scroll = Some(true);
61 self
62 }
63
64 pub fn ancestor_resize(&mut self) -> &mut Self {
65 self.ancestor_resize = Some(true);
66 self
67 }
68
69 pub fn element_resize(&mut self) -> &mut Self {
70 self.element_resize = Some(true);
71 self
72 }
73
74 pub fn layout_shift(&mut self) -> &mut Self {
75 self.layout_shift = Some(true);
76 self
77 }
78
79 pub fn animation_frame(&mut self) -> &mut Self {
80 self.animation_frame = Some(true);
81 self
82 }
83}
84
85impl TryInto<JsValue> for AutoUpdateOptions {
86 type Error = Error;
87
88 fn try_into(self) -> Result<JsValue> {
89 let obj = Object::new();
90
91 object_utils::set_option_bool(&obj, "ancestorScroll", self.ancestor_scroll)?;
92 object_utils::set_option_bool(&obj, "ancestorResize", self.ancestor_resize)?;
93 object_utils::set_option_bool(&obj, "elementResize", self.element_resize)?;
94 object_utils::set_option_bool(&obj, "layoutShift", self.layout_shift)?;
95 object_utils::set_option_bool(&obj, "animationFrame", self.animation_frame)?;
96
97 Ok(obj.into())
98 }
99}