at main 82 lines 2.4 kB view raw
1use dioxus::prelude::*; 2use dioxus_primitives::dialog::{ 3 self, DialogContentProps, DialogDescriptionProps, DialogRootProps, DialogTitleProps, 4}; 5 6const DIALOG_CSS: Asset = asset!("./dialog.css"); 7 8/// Fixed-position overlay that works in both SSR and client-only modes. 9/// Wraps dioxus_primitives DialogRoot with inline positioning styles 10/// since the CSS file doesn't load reliably in client-only mode. 11#[component] 12pub fn DialogRoot(props: DialogRootProps) -> Element { 13 let is_open = props.open.read().unwrap_or(false); 14 15 let overlay_style = if is_open { 16 "position: fixed; inset: 0; z-index: 1000; background: rgba(0,0,0,0.3); display: flex; align-items: center; justify-content: center;" 17 } else { 18 "display: none;" 19 }; 20 21 rsx! { 22 document::Link { rel: "stylesheet", href: DIALOG_CSS } 23 div { 24 style: "{overlay_style}", 25 onclick: { 26 let on_change = props.on_open_change.clone(); 27 move |_| { 28 on_change.call(false); 29 } 30 }, 31 dialog::DialogRoot { 32 class: "dialog-backdrop-inner", 33 id: props.id, 34 is_modal: props.is_modal, 35 open: props.open, 36 default_open: props.default_open, 37 on_open_change: props.on_open_change, 38 attributes: props.attributes, 39 {props.children} 40 } 41 } 42 } 43} 44 45#[component] 46pub fn DialogContent(props: DialogContentProps) -> Element { 47 rsx! { 48 div { 49 onclick: move |e| e.stop_propagation(), 50 dialog::DialogContent { 51 class: "dialog", 52 id: props.id, 53 attributes: props.attributes, 54 {props.children} 55 } 56 } 57 } 58} 59 60#[component] 61pub fn DialogTitle(props: DialogTitleProps) -> Element { 62 rsx! { 63 dialog::DialogTitle { 64 class: "dialog-title", 65 id: props.id, 66 attributes: props.attributes, 67 {props.children} 68 } 69 } 70} 71 72#[component] 73pub fn DialogDescription(props: DialogDescriptionProps) -> Element { 74 rsx! { 75 dialog::DialogDescription { 76 class: "dialog-description", 77 id: props.id, 78 attributes: props.attributes, 79 {props.children} 80 } 81 } 82}