Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resize handlers #333

Closed
Boscop opened this issue Jul 21, 2018 · 8 comments
Closed

Resize handlers #333

Boscop opened this issue Jul 21, 2018 · 8 comments

Comments

@Boscop
Copy link

Boscop commented Jul 21, 2018

Yew should have a way to notify components when they are resized, and allow them to execute their own resize handler, similar to IronResizableBehavior in Polymer. (It also has other behaviors for similar things.)
But maybe there's an even better solution?
How do other js frameworks do this?

@kradical
Copy link

There is a global "resize" event in javascript but there is no "this component got resized" event. I know there are wrapper libraries for React components that will notify your component when it changes size. I think this is something that possibly isn't the responsibility of the framework but a library. Also apparently there is "Resize Observers" which I haven't looked into much.. not even sure if it is implemented in any browsers...

@hgzimmerman
Copy link
Member

Hey, here is the following code I am using for handling resize events. Since I am testing using the i3 window manager on linux, it appears that the WM already limits the window resize to when I perform a mouse-up when dragging a window around. For other WMs/Desktop Environments, the windowing system may very rapidly tell the browser to resize itself, inundating your application with resize events, causing performance hitching. Workarounds to rate-limit the event firing are present in the @kradical's "resize event" link, or you could use Yew's existing timeout service to toggle some resizing: bool value to indicate a resize occurred recently to prevent redraws.

pub struct ResizeService {}

pub struct ResizeTask(Option<Value>);

impl ResizeService {
    pub fn new() -> ResizeService {
        ResizeService {}
    }

    pub fn register(&mut self, callback: Callback<()>) -> ResizeTask {
        let callback = move || {
            callback.emit(());
        };
        let handle = js! {
            var callback = @{callback};
            var action = function() {
                callback();
            };
            return window.addEventListener("resize", action);
        };
        return ResizeTask(Some(handle))
    }
}

impl Drop for ResizeTask {
    fn drop(&mut self) {
        let handle = self.0.take().expect("Resize task already empty.");
        js! {
            @(no_return)
            var handle = @{handle};
            handle.callback.drop();
        }
    }
}

@Boscop
Copy link
Author

Boscop commented Jul 25, 2018

Thanks!
Could I do it more "typed", similar to this?
https://github.com/DenisKolodin/yew/blob/master/examples/routing/src/routing.rs#L47

But what should I use instead of PopStateEvent?

@Boscop
Copy link
Author

Boscop commented Jul 25, 2018

@kradical Thanks, do you know how these React libs detect when a component gets resized (if the viewport stays the same so that window's resize handler is not triggered)?

@hgzimmerman
Copy link
Member

There does exist a resize event in stdweb, but that doesn't contain any meaningful data about the viewport, so () is just about as useful as ResizeEvent.

@Boscop
Copy link
Author

Boscop commented Jul 25, 2018

Ah, it's necessary to use a type that impls ConcreteEvent here, such as ResizeEvent. () doesn't impl ConcreteEvent.
It's identified by the EVENT_TYPE associated constant:
https://docs.rs/stdweb/*/src/stdweb/webapi/events/dom.rs.html#100

Thanks, I can work with this for now, but I'm still curious how I could detect when a component is resized without the window/viewport being resized..

@kradical
Copy link

kradical commented Jul 25, 2018

@Boscop The specific example I linked uses a polyfill for ResizeObserver which I believe it uses MutationObservers in the background. It really is not a simple problem and you will have to write a non-trivial amount of filler code to make it work properly. Or there might be some way to "include" the javascript and interact with it. I am not super familiar with Yew. Goodluck!

Edit: mdn has documentation about MutationObservers and W3 has a spec for ResizeObservers.

@jstarry
Copy link
Member

jstarry commented Sep 27, 2019

A ResizeService has been added to Yew 0.9 via #577

@jstarry jstarry closed this as completed Sep 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants