dioxus_dnd/desktop/
provider.rs1use dioxus::prelude::*;
4
5use crate::core::world::WorldMembership;
6use crate::core::{Direction, DndProvider, DndWorld};
7
8use super::{use_window_geometry_feed, DragBridge};
9
10#[component]
25pub fn MultiWindowProvider<T: Clone + PartialEq + 'static>(
26 #[props(default)]
28 phantom: std::marker::PhantomData<T>,
29 #[props(default)]
31 dir: Direction,
32 children: Element,
33) -> Element {
34 let _ = phantom;
35 use_window_geometry_feed();
36 use_hook(|| {
37 let has_world = try_consume_context::<DndWorld<T>>().is_some();
38 let has_ancestor_provider = try_consume_context::<WorldMembership<T>>().is_some();
39 if let Some(message) = wiring_warning(has_world, has_ancestor_provider) {
40 tracing::warn!(
41 target: "dioxus_dnd::desktop",
42 payload_type = std::any::type_name::<T>(),
43 "{message}"
44 );
45 }
46 });
47
48 rsx! {
49 DndProvider::<T> { dir,
50 DragBridge::<T> {}
51 {children}
52 }
53 }
54}
55
56fn wiring_warning(has_world: bool, has_ancestor_provider: bool) -> Option<&'static str> {
57 if has_ancestor_provider {
58 Some(
59 "MultiWindowProvider mounted beneath an existing DndProvider for the same payload; \
60 replace that provider instead of wrapping it, and ensure a DndWorld is in context; \
61 the nested provider's drags will otherwise remain isolated",
62 )
63 } else if !has_world {
64 Some(
65 "MultiWindowProvider mounted without a DndWorld in context; call use_dnd_world in one \
66 window and create siblings with DndWorld::vdom; this window's drags will remain isolated",
67 )
68 } else {
69 None
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76
77 #[test]
78 fn wiring_diagnostic_covers_missing_world_and_nested_provider() {
79 assert!(wiring_warning(true, false).is_none());
80 assert!(wiring_warning(false, false)
81 .expect("missing world warning")
82 .contains("without a DndWorld"));
83 assert!(wiring_warning(true, true)
84 .expect("nested provider warning")
85 .contains("replace that provider"));
86 assert!(wiring_warning(false, true)
87 .expect("combined warning")
88 .contains("ensure a DndWorld"));
89 }
90}