dioxus_dnd/core/hooks.rs
1//! Hooks for providing and consuming the drag context.
2
3use dioxus::prelude::*;
4
5use super::registry::ZoneRegistry;
6use super::state::{DndContext, DragState};
7use super::types::{Point, ZoneId};
8
9/// Provide a `DndContext<T>` (and its zone registry) to this component's
10/// subtree. Call once, high up (or use the
11/// [`crate::core::components::DndProvider`] component).
12pub fn use_dnd_provider<T: Clone + 'static>() -> DndContext<T> {
13 let state = use_store(DragState::<T>::default);
14 let announcement = use_signal(String::new);
15 use_context_provider(|| ZoneRegistry::<T>::from_signal(Signal::new(Vec::new())));
16 use_context_provider(move || DndContext::from_parts(state, announcement))
17}
18
19/// Grab the nearest `DndContext<T>` from context.
20///
21/// # Panics
22/// Panics if no ancestor provided a context for this payload type.
23pub fn use_dnd<T: Clone + 'static>() -> DndContext<T> {
24 use_context()
25}
26
27/// Grab the zone registry (mounted drop zones, in order). Provided alongside
28/// the context by [`use_dnd_provider`].
29pub fn use_zone_registry<T: Clone + 'static>() -> ZoneRegistry<T> {
30 use_context()
31}
32
33/// A stable, auto-generated [`ZoneId`] for this component instance.
34pub fn use_zone_id() -> ZoneId {
35 use_hook(ZoneId::auto)
36}
37
38/// Client (viewport) coordinates of a native drag event as a [`Point`].
39/// In-app drags don't produce `DragEvent`s; this serves the boundary
40/// modules ([`crate::files`], [`crate::external`]) and custom native zones.
41pub fn client_point(evt: &DragEvent) -> Point {
42 let c = evt.client_coordinates();
43 Point::new(c.x, c.y)
44}
45
46/// Element-relative coordinates of a native drag event as a [`Point`].
47/// See [`client_point`] for when these apply.
48pub fn element_point(evt: &DragEvent) -> Point {
49 let c = evt.element_coordinates();
50 Point::new(c.x, c.y)
51}