Expand description
§Drop effects API reference
The move/copy/link vocabulary of a drop, its modifier-key resolution, and the model helpers that apply a completed drop to app-owned state.
Concept guide: docs/concepts/drop-effects.md.
The crate never touches your data: drops arrive as DropOutcome values and
you decide what they mean. The two helpers here cover the most common
meaning, the remove-from-source, append-to-target dance, without imposing
bounds on your item type: no Clone (the payload arrives owned), no
PartialEq (matching is by the key you extract). DropEffect and
effective_effect, DropEffects, and DropQuery are re-exported from the
prelude alongside the helpers.
DropZone::<Card> {
on_drop: move |o: DropOutcome<Card>| {
try_apply_clone_or_move(
&mut zones.write(),
o,
|c| c.id, // identity function
|mut c| { c.id = fresh_id(); c }, // clone hook, runs only on Copy
).expect("target accepts only move or copy");
},
"Drop here"
}§DropEffect
The visual and semantic effect of a drop, mirroring the HTML5
dropEffect/effectAllowed vocabulary.
| Variant | Meaning |
|---|---|
Move | The item leaves its source and lands in the target. The default, and what most drags mean. |
Copy | The target receives a duplicate; the source keeps the original. Forced by Ctrl or Cmd held at release. |
Link | A reference-style drop, forced by Alt. Rare, but the vocabulary matches the platform convention. |
None | Advertises that the drag carries no data effect. Modifier keys never override it; the crate still delivers the outcome, so interpretation stays with your handler. |
as_str returns the string the native DataTransfer API expects:
"move", "copy", "link", "none". The drag-out sources pass it to
effectAllowed when advertising a drag to other applications
(drag-out.md).
Where it appears:
- The
Draggableeffectprop (defaultMove) sets the drag’s base effect (drag-and-drop.md). DropOutcome::effectcarries the resolved value toon_drop.
§Target effect negotiation
DropEffects is a compact set with MOVE, COPY, LINK, NONE,
STANDARD, ALL, and EMPTY constants. Combine flags with | and declare
them on a target:
DropZone::<Card> {
allowed_effects: DropEffects::MOVE | DropEffects::COPY,
accepts_query: move |query: DropQuery<Card>| {
query.source != Some(ARCHIVE) && query.pointer_kind != PointerKind::Pen
},
on_drop: move |outcome| { /* ... */ },
}If the proposed effect is supported, it is preserved. Otherwise the target
selects the first supported fallback in Move, Copy, Link order. EMPTY
rejects the drag. DropEffect::None is a disabled proposal, not a selectable
effect: it is rejected before legacy or rich acceptance callbacks, hover,
collision, or delivery. The complete DropQuery<T> contains payload, source,
proposed_effect, mode, pointer_kind, and drag_id. Highlighting,
pointer collision, keyboard navigation, cross-window resolution, and final
delivery all evaluate the same query.
§effective_effect
pub fn effective_effect(base: DropEffect, modifiers: dioxus::prelude::Modifiers) -> DropEffectResolves the effect a drag should use given the currently held modifier keys, the file-manager convention:
| Held at release | Result |
|---|---|
| Ctrl or Cmd (Meta) | Copy |
| Alt | Link |
| Ctrl and Alt together | Copy (Ctrl wins) |
| Neither | base |
Anything, when base is DropEffect::None | None (a base of None is never overridden) |
The library applies this for you. Pointer drags sample the held modifiers
on every pointer event and resolve them against the Draggable’s base
effect at release, just before delivery, so the state held at release wins,
not the state at pickup. Host-side multi-window deliveries resolve the same
function against the drag world’s modifier snapshot, so a release in
another window behaves identically. Keyboard drops skip resolution and
deliver the base effect unchanged. The function is public for custom drag
sources and handlers that need the same answer.
§apply_clone_or_move and try_apply_clone_or_move
pub fn apply_clone_or_move<T, K>(
zones: &mut HashMap<ZoneId, Vec<T>>,
outcome: DropOutcome<T>,
key: impl Fn(&T) -> K,
clone_item: impl FnMut(T) -> T,
) where
K: PartialEq,Applies a drop to a HashMap<ZoneId, Vec<T>> model: one Vec per zone,
keyed by the ids your DropZones declare.
| Argument | Type | What it does |
|---|---|---|
zones | &mut HashMap<ZoneId, Vec<T>> | Your model. An unknown to zone is created on the fly rather than dropping the item on the floor. |
outcome | DropOutcome<T> | The drop as delivered; from, to and effect steer what happens. |
key | impl Fn(&T) -> K | The identity function. Extracts each item’s key (typically an id field) so a move can find and remove the original in the source Vec. Matching is by this key, never PartialEq on the item. |
clone_item | impl FnMut(T) -> T | The clone hook. Runs only on Copy, receiving the owned payload and returning the item to append. Assign the fresh id here so the copy gets its own identity. |
Semantics:
Moveremoves the matching item fromoutcome.from, then appends the payload tooutcome.to.Copyleaves the source alone and appendsclone_item(payload)to the target.- The compatibility helper preserves the 3.x contract: every non-
Copyeffect follows its historical move path and the function returns(). try_apply_clone_or_movehas the same arguments but returnsResult<(), ApplyDropError>;LinkandNoneare rejected without mutation. Prefer it when a target has not already constrainedallowed_effectsto Move/Copy.- Removal matches every item in the source whose key equals the payload’s key. Keys are expected to be unique within a zone; if they are not, a single move prunes all of them.
- A move where
from == Some(to)removes and re-appends, so dropping an item back onto its own zone sends it to the end of that list. - A move with
from: None(payload from outside any zone, e.g. a palette) skips removal and just appends.fromis filled by theDraggable’szoneprop; declare it or removal never runs.
§apply_list_clone_or_move and try_apply_list_clone_or_move
pub fn apply_list_clone_or_move<T, K>(
source: Option<&mut Vec<T>>,
target: &mut Vec<T>,
outcome: DropOutcome<T>,
key: impl Fn(&T) -> K,
clone_item: impl FnMut(T) -> T,
) where
K: PartialEq,The two-list version applies a drop between two plain Vec<T>s with the same
move/copy semantics. You choose which lists to pass, so the outcome’s from
and to fields are ignored here; only payload and effect are
consulted. try_apply_list_clone_or_move is the checked form and returns
ApplyDropError for Link or None before mutation.
| Argument | Type | What it does |
|---|---|---|
source | Option<&mut Vec<T>> | The list a move removes from. Pass None when the payload came from outside any list; removal is skipped. |
target | &mut Vec<T> | The list the item is appended to. |
outcome | DropOutcome<T> | Only payload and effect are read. |
key | impl Fn(&T) -> K | Identity function, as above. A move removes every source item whose key matches the payload’s. |
clone_item | impl FnMut(T) -> T | Clone hook, as above. Runs only on Copy. |
§Where the rest lives
The full DropOutcome field reference and the Draggable and DropZone
props: drag-and-drop.md. ZoneId and the registry:
core.md. Advertising effects to other applications:
drag-out.md. Cross-window modifier behavior:
multi-window.md.
Structs§
- DndScope
- An explicit lifetime for Dioxus signals and stores created outside a component scope.
Enums§
- Apply
Drop Error - A model helper refused to guess semantics for an unsupported effect.
Functions§
- apply_
clone_ or_ move - Apply a drop to a
HashMap<ZoneId, Vec<T>>model. - apply_
list_ clone_ or_ move - Apply a drop between two plain
Vec<T>lists. - try_
apply_ clone_ or_ move - Checked form of
apply_clone_or_move. - try_
apply_ list_ clone_ or_ move - Checked form of
apply_list_clone_or_move. - use_
dnd_ model - Create and provide an app-wide model whose Dioxus state survives every window close order.