From d3e1ba415f3ab4d5876eac74d83dfe1a4ba9da7a Mon Sep 17 00:00:00 2001 From: igor Date: Mon, 30 Sep 2024 14:02:06 +0200 Subject: [PATCH] feat(web): using `None` instead of `Element` (#3012) Can mount the Dioxus component into every node. As `Element` and `ShadowRoot` are `Node` we can now mount a dioxus component into a shadow root. --- packages/web/src/cfg.rs | 14 ++++++++++++-- packages/web/src/dom.rs | 8 ++++---- packages/web/src/hydration/hydrate.rs | 2 +- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/packages/web/src/cfg.rs b/packages/web/src/cfg.rs index ab62932fb..ddc589414 100644 --- a/packages/web/src/cfg.rs +++ b/packages/web/src/cfg.rs @@ -1,3 +1,5 @@ +use wasm_bindgen::JsCast as _; + /// Configuration for the WebSys renderer for the Dioxus VirtualDOM. /// /// This struct helps configure the specifics of hydration and render destination for WebSys. @@ -15,7 +17,7 @@ pub struct Config { pub(crate) enum ConfigRoot { RootName(String), - RootElement(web_sys::Element), + RootNode(web_sys::Node), } impl Config { @@ -52,7 +54,15 @@ impl Config { /// /// This is akin to calling React.render() on the given element. pub fn rootelement(mut self, elem: web_sys::Element) -> Self { - self.root = ConfigRoot::RootElement(elem); + self.root = ConfigRoot::RootNode(elem.unchecked_into()); + self + } + + /// Set the node that Dioxus will use as root. + /// + /// This is akin to calling React.render() on the given element. + pub fn rootnode(mut self, node: web_sys::Node) -> Self { + self.root = ConfigRoot::RootNode(node); self } diff --git a/packages/web/src/dom.rs b/packages/web/src/dom.rs index a0b5e4afe..3cc3568d2 100644 --- a/packages/web/src/dom.rs +++ b/packages/web/src/dom.rs @@ -13,13 +13,13 @@ use dioxus_core::{ElementId, Template}; use dioxus_interpreter_js::unified_bindings::Interpreter; use rustc_hash::FxHashMap; use wasm_bindgen::{closure::Closure, JsCast}; -use web_sys::{Document, Element, Event, Node}; +use web_sys::{Document, Event, Node}; use crate::{load_document, virtual_event_from_websys_event, Config, WebEventConverter}; pub struct WebsysDom { #[allow(dead_code)] - pub(crate) root: Element, + pub(crate) root: Node, pub(crate) document: Document, pub(crate) templates: FxHashMap, pub(crate) interpreter: Interpreter, @@ -67,9 +67,9 @@ impl WebsysDom { document.create_element("body").ok().unwrap() } }; - (document, root) + (document, root.unchecked_into()) } - crate::cfg::ConfigRoot::RootElement(root) => { + crate::cfg::ConfigRoot::RootNode(root) => { let document = match root.owner_document() { Some(document) => document, None => load_document(), diff --git a/packages/web/src/hydration/hydrate.rs b/packages/web/src/hydration/hydrate.rs index a362eddef..713c864f7 100644 --- a/packages/web/src/hydration/hydrate.rs +++ b/packages/web/src/hydration/hydrate.rs @@ -218,7 +218,7 @@ impl WebsysDom { // Rehydrate the root scope that was rendered on the server. We will likely run into suspense boundaries. // Any suspense boundaries we run into are stored for hydration later. - self.start_hydration_at_scope(vdom.base_scope(), vdom, vec![self.root.clone().into()])?; + self.start_hydration_at_scope(vdom.base_scope(), vdom, vec![self.root.clone()])?; Ok(rx) }