public inbox for yew-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [PATCH yew-widget-toolkit] widget: charts: map: update info location if page is scrolled
@ 2026-05-27  9:37 Dominik Csapak
  2026-05-27 14:21 ` applied: " Thomas Lamprecht
  0 siblings, 1 reply; 2+ messages in thread
From: Dominik Csapak @ 2026-05-27  9:37 UTC (permalink / raw)
  To: yew-devel

When the map is part of a scrollable container and the info is shown,
scrolling the container does not move the info box.

To fix that, install a capturing scroll event handler that triggers on
all scroll events on the page, and trigger an alignment update of the
info box.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
This is sadly the only way to "fix" this issue and also keep the current
behaviour (drawing on top of other elements, etc.) until we can use
the anchor positioning api which is (at least partially) implemented in
all browsers, but only very recently (~end of last year).

 src/widget/charts/map/mod.rs | 78 +++++++++++++++++++++++++++---------
 1 file changed, 60 insertions(+), 18 deletions(-)

diff --git a/src/widget/charts/map/mod.rs b/src/widget/charts/map/mod.rs
index 330c5fb..39b0c9c 100644
--- a/src/widget/charts/map/mod.rs
+++ b/src/widget/charts/map/mod.rs
@@ -1,5 +1,8 @@
 use std::marker::PhantomData;
 
+use wasm_bindgen::prelude::Closure;
+use wasm_bindgen::{JsCast, UnwrapThrowExt};
+
 mod map_point;
 pub use map_point::{
     MapPointData, PointsRenderArgs, render_info_default, render_point_default,
@@ -93,6 +96,7 @@ pub enum Msg {
     ToggleInfo(usize),
     CloseInfo,
     Drag(GestureDragEvent),
+    UpdateInfoAlignment,
 }
 
 #[derive(PartialEq, Clone)]
@@ -117,6 +121,7 @@ pub struct MapComp<T: Clone + PartialEq> {
     // set while a drag is in progress so the trailing synthetic click does not dismiss the info card
     dragged: bool,
     clusters: Vec<Cluster>,
+    scroll_handler: Closure<dyn FnMut()>,
     _phantom_data: PhantomData<T>,
 }
 
@@ -192,6 +197,39 @@ impl<T: MapPointData + 'static> MapComp<T> {
         }
         self.clusters = clusters;
     }
+
+    fn update_info_alignment(&self, ctx: &Context<Self>) {
+        if let (Some(_), Some(anchor), Some(el)) = (
+            self.info_visible,
+            self.info_anchor_ref.get(),
+            self.info_ref.get(),
+        ) {
+            let _ = align_to(
+                anchor,
+                el,
+                Some(
+                    AlignOptions::new(
+                        crate::dom::align::Point::Top,
+                        crate::dom::align::Point::Bottom,
+                        crate::dom::align::GrowDirection::None,
+                    )
+                    .offset(0.0, ctx.props().info_point_radius * 2.0),
+                ),
+            );
+        }
+    }
+}
+
+impl<T: PartialEq + Clone> Drop for MapComp<T> {
+    fn drop(&mut self) {
+        gloo_utils::document()
+            .remove_event_listener_with_callback_and_bool(
+                "scroll",
+                self.scroll_handler.as_ref().unchecked_ref(),
+                true,
+            )
+            .unwrap_throw();
+    }
 }
 
 impl<T: MapPointData + 'static> yew::Component for MapComp<T> {
@@ -206,6 +244,22 @@ impl<T: MapPointData + 'static> yew::Component for MapComp<T> {
             2.0 * props.info_point_radius,
         );
 
+        let link = ctx.link().clone();
+        let scroll_handler = Closure::new(move || {
+            link.send_message(Msg::UpdateInfoAlignment);
+        });
+
+        // capturing event handler, triggers for *all* scroll events on the page
+        // even unrelated ones, but it's still cheaper than attaching an event handler
+        // to every ancestor that might scroll
+        gloo_utils::document()
+            .add_event_listener_with_callback_and_bool(
+                "scroll",
+                scroll_handler.as_ref().unchecked_ref(),
+                true,
+            )
+            .unwrap_throw();
+
         let mut this = Self {
             zoom,
             pinch_start_scale: 1.0,
@@ -220,6 +274,7 @@ impl<T: MapPointData + 'static> yew::Component for MapComp<T> {
             grab_start: None,
             dragged: false,
             clusters: Vec::new(),
+            scroll_handler,
             _phantom_data: PhantomData::<T>,
         };
 
@@ -339,6 +394,10 @@ impl<T: MapPointData + 'static> yew::Component for MapComp<T> {
                 }
                 self.info_visible = None;
             }
+            Msg::UpdateInfoAlignment => {
+                self.update_info_alignment(ctx);
+                return false;
+            }
         }
         true
     }
@@ -564,23 +623,6 @@ impl<T: MapPointData + 'static> yew::Component for MapComp<T> {
                 crate::dom::align::Point::TopStart,
             );
         }
-        if let (Some(_), Some(anchor), Some(el)) = (
-            self.info_visible,
-            self.info_anchor_ref.get(),
-            self.info_ref.get(),
-        ) {
-            let _ = align_to(
-                anchor,
-                el,
-                Some(
-                    AlignOptions::new(
-                        crate::dom::align::Point::Top,
-                        crate::dom::align::Point::Bottom,
-                        crate::dom::align::GrowDirection::None,
-                    )
-                    .offset(0.0, ctx.props().info_point_radius * 2.0),
-                ),
-            );
-        }
+        self.update_info_alignment(ctx);
     }
 }
-- 
2.47.3





^ permalink raw reply related	[flat|nested] 2+ messages in thread

* applied: [PATCH yew-widget-toolkit] widget: charts: map: update info location if page is scrolled
  2026-05-27  9:37 [PATCH yew-widget-toolkit] widget: charts: map: update info location if page is scrolled Dominik Csapak
@ 2026-05-27 14:21 ` Thomas Lamprecht
  0 siblings, 0 replies; 2+ messages in thread
From: Thomas Lamprecht @ 2026-05-27 14:21 UTC (permalink / raw)
  To: yew-devel, Dominik Csapak

On Wed, 27 May 2026 11:37:57 +0200, Dominik Csapak wrote:
> When the map is part of a scrollable container and the info is shown,
> scrolling the container does not move the info box.
> 
> To fix that, install a capturing scroll event handler that triggers on
> all scroll events on the page, and trigger an alignment update of the
> info box.
> 
> [...]

Applied, thanks!

[1/1] widget: charts: map: update info location if page is scrolled
      commit: dd1bffe928cbfebeac548012cd8ced3b2f5ddf4f




^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-05-27 14:21 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-27  9:37 [PATCH yew-widget-toolkit] widget: charts: map: update info location if page is scrolled Dominik Csapak
2026-05-27 14:21 ` applied: " Thomas Lamprecht

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal