rust-dominator icon indicating copy to clipboard operation
rust-dominator copied to clipboard

Add `show_picker()` functionality to `focused_signal()` Upon wasm-bindgen/issues/3036 being implemented.

Open Billy-Sheppard opened this issue 2 years ago • 4 comments

Focused signal works great for text inputs but for picker style inputs it doesn't work.

Unsure exactly how to implement it though, also heavily dependant on how/if/when the wasm-bindgen guys get the following issue working.

https://github.com/rustwasm/wasm-bindgen/issues/3036

pub(crate) fn show_picker(elem: &HtmlElement) {
    elem.show_picker().unwrap_throw();
}
fn set_focused_signal<B>(&mut self, value: B)
        where B: Signal<Item = bool> + 'static {

        let element = self.element.as_ref().clone();

        // This needs to use `after_insert` because calling `.focus()` on an element before it is in the DOM has no effect
        self.callbacks.after_insert(move |callbacks| {
            // TODO verify that this is correct under all circumstances
            callbacks.after_remove(for_each(value, move |value| {
                // TODO avoid updating if the focused state hasn't changed ?
                if value {
                    bindings::focus(&element);
                }
                else if value { // && [ "date", "datetime-local", "month", "time", "week", "color", "file"].contains(input_type) ??
                    bindings::show_picker(&element); // COULD ADD HERE?
                } else {
                    bindings::blur(&element);
                    // NOT SURE HOW TO HANDLE BLUR-ING
                }
            }));
        });
    }

Billy-Sheppard avatar Aug 18 '22 07:08 Billy-Sheppard

I think we have to wait for it to be stabilized, I don't want to rely on unstable APIs.

Also, it sounds like you can only call it inside of an event listener, like click. You can't just call it whenever you want.

So in that case there's nothing that dominator can do, you can instead use it like this:

html!("input" => HtmlInputElement, {
    .with_node!(element => {
        .event(move |_: events::Click| {
            element.show_picker();
        })
    })
})

This works without any changes needed to dominator.

Pauan avatar Aug 18 '22 14:08 Pauan

Interesting, thanks Pauan.

Am I correct in thinking that the with_node! macro behind the scenes calls __internal_element()?

Billy-Sheppard avatar Aug 19 '22 02:08 Billy-Sheppard

Yes, but that's a completely internal implementation detail that you shouldn't rely upon.

What you can rely upon is that it gives you the raw web_sys DOM node which is being wrapped by DomBuilder.

Since it's a web_sys DOM node, you can of course call all of the web_sys methods on it.

Pauan avatar Aug 19 '22 02:08 Pauan

The reason I am hesitant to use with_node! is I try to avoid using macros if possible (due to a few reasons but primarily that it can cause issues with rust-fmt).

Is there a reason its not a properly/"publicly" implemented method?

Billy-Sheppard avatar Aug 19 '22 03:08 Billy-Sheppard