Synchronous prevent default (#2792)

* add prevent default methods to the event

* sync prevent default almost working

* sync prevent default working

* Move event handling into the runtime

* update core tests

* restore desktop file dialog

* implement prevent default on web

* add a hint about the new prevent default method

* fix web prevent default

* Fix CTRL+click on links

* fix values memorize in place test

* Fix a few more tests

* Add a playwright test for sync prevent default

* Fix core doc tests

* create a deprecated VirtualDom::handle_event

* fix macos imports in desktop

* Fix onmounted event

* Fix liveview support

* switch to RefCell for metadata

* Remove println

* remove prevent default attribute

* remove web specific link behavior

* Fix liveview links

* more liveview fixes for link

* Fix merge conflicts

* Fix clippy

* use the new prevent default in the file upload example
This commit is contained in:
Evan Almloff authored and GitHub committed 2024-08-13 11:57:54 -07:00
1 parent 8b62b71e2d
commit cab573eefd
54 files changed
+940 -729

No files matched your search

@@ -51,7 +51,7 @@ pub struct HistoryButtonProps {
/// # vdom.rebuild_in_place();
/// # assert_eq!(
/// # dioxus_ssr::render(&vdom),
/// # r#"<button disabled="true" dioxus-prevent-default="onclick">go back</button>"#
/// # r#"<button disabled="true">go back</button>"#
/// # );
/// ```
pub fn GoBackButton(props: HistoryButtonProps) -> Element {
@@ -75,8 +75,10 @@ pub fn GoBackButton(props: HistoryButtonProps) -> Element {
rsx! {
button {
disabled: "{disabled}",
prevent_default: "onclick",
onclick: move |_| router.go_back(),
onclick: move |evt| {
evt.prevent_default();
router.go_back()
},
{children}
}
}
@@ -122,7 +124,7 @@ pub fn GoBackButton(props: HistoryButtonProps) -> Element {
/// # vdom.rebuild_in_place();
/// # assert_eq!(
/// # dioxus_ssr::render(&vdom),
/// # r#"<button disabled="true" dioxus-prevent-default="onclick">go forward</button>"#
/// # r#"<button disabled="true">go forward</button>"#
/// # );
/// ```
pub fn GoForwardButton(props: HistoryButtonProps) -> Element {
@@ -146,8 +148,10 @@ pub fn GoForwardButton(props: HistoryButtonProps) -> Element {
rsx! {
button {
disabled: "{disabled}",
prevent_default: "onclick",
onclick: move |_| router.go_forward(),
onclick: move |evt| {
evt.prevent_default();
router.go_forward()
},
{children}
}
}
+24 -4
View File
@@ -195,7 +195,7 @@ impl Debug for LinkProps {
/// # vdom.rebuild_in_place();
/// # assert_eq!(
/// # dioxus_ssr::render(&vdom),
/// # r#"<a href="/" dioxus-prevent-default="" class="link_class active" rel="link_rel" target="_blank" aria-current="page" id="link_id">A fully configured link</a>"#
/// # r#"<a href="/" class="link_class active" rel="link_rel" target="_blank" aria-current="page" id="link_id">A fully configured link</a>"#
/// # );
/// ```
#[doc(alias = "<a>")]
@@ -259,12 +259,21 @@ pub fn Link(props: LinkProps) -> Element {
let is_external = matches!(parsed_route, NavigationTarget::External(_));
let is_router_nav = !is_external && !new_tab;
let prevent_default = is_router_nav.then_some("onclick").unwrap_or_default();
let rel = rel.or_else(|| is_external.then_some("noopener noreferrer".to_string()));
let do_default = onclick.is_none() || !onclick_only;
let action = move |event| {
let action = move |event: MouseEvent| {
// Only handle events without modifiers
if !event.modifiers().is_empty() {
return;
}
// only handle left clicks
if event.trigger_button() != Some(dioxus_elements::input_data::MouseButton::Primary) {
return;
}
event.prevent_default();
if do_default && is_router_nav {
router.push_any(router.resolve_into_routable(to.clone()));
}
@@ -280,12 +289,23 @@ pub fn Link(props: LinkProps) -> Element {
}
};
// In liveview, we need to prevent the default action if the user clicks on the link with modifiers
// in javascript. The prevent_default method is not available in the liveview renderer because
// event handlers are handled over a websocket.
let liveview_prevent_default = {
// If the event is a click with the left mouse button and no modifiers, prevent the default action
// and navigate to the href with client side routing
router.is_liveview().then_some(
"if (event.button === 0 && !event.ctrlKey && !event.metaKey && !event.shiftKey && !event.altKey) { event.preventDefault() }"
)
};
rsx! {
a {
onclick: action,
"onclick": liveview_prevent_default,
href,
onmounted: onmounted,
prevent_default,
class,
rel,
target: tag_target,