use dioxus::prelude::*;
#[derive(Props, Clone, PartialEq)]
pub struct PortalProps {
children: Element,
#[props(default = "main".to_string())]
container: String,
#[props(default = None)]
class: Option<String>,
#[props(default = None)]
id: Option<String>,
}
#[component]
pub fn Portal(props: PortalProps) -> Element {
let mut mounted = use_signal(|| false);
let portal_id = format!(
"portal-{}",
(js_sys::Math::random() * 1_000_000_000.0) as u64
);
use_effect(move || {
mounted.set(true);
});
if !mounted() {
return rsx! {};
}
let container = props.container.clone();
let portal_id_clone = portal_id.clone();
rsx! {
div {
class: props.class.clone(),
id: props.id.clone(),
style: "position: fixed; z-index: 9999; inset: 0;",
"data-portal-id": portal_id.clone(),
"data-portal-container": props.container.clone(),
onmounted: move |_| {
let script = format!(
r#"
setTimeout(function() {{
const portalElement = document.querySelector('[data-portal-id="{}"]');
const targetContainer = document.querySelector('#{}');
if (portalElement && targetContainer) {{
targetContainer.appendChild(portalElement);
}}
}}, 50);
"#,
portal_id_clone, container
);
let _ = js_sys::Function::new_no_args(&script).call0(&wasm_bindgen::JsValue::NULL);
},
{props.children}
}
}
}