Skip to main content

Dropzone

Dropzone is the richer drag-and-drop surface helper.

Use it when a part of the screen should visibly respond as something is dragged over it, then handle the eventual drop. Typical examples are attachment areas, upload panels, and kanban columns that highlight as the user drags over them.

Example

use fission::prelude::*;

let node = Dropzone {
child: Box::new(upload_panel_node),
on_drag_enter: Some(with_reducer!(ctx, SetHoveringUpload(true), on_set_hovering_upload)),
on_drag_leave: Some(with_reducer!(ctx, SetHoveringUpload(false), on_set_hovering_upload)),
on_drop: Some(ctx.bind(
FilesDropped,
reduce_with!((|state: &mut ComposerState, _action: FilesDropped, ctx| {
if let Some(paths) = ctx.input.as_drop_paths() {
state.attachments.extend(paths.iter().cloned());
}
})),
)),
}
.build(ctx, view);

Here the hover state lives in AppState, so the next build can re-render the dropzone with a highlight border.

Field table

FieldTypeMeaningNotes / default behavior
childBox<Node>Visible content wrapped by the drop surface.Required.
on_dropOption<ActionEnvelope>Action dispatched when something is dropped on the surface.Read external paths with ctx.input.as_drop_paths() or internal bytes with ctx.input.as_internal_drop().
on_drag_enterOption<ActionEnvelope>Action dispatched when a drag enters the bounds.Useful for setting hover state in AppState.
on_drag_leaveOption<ActionEnvelope>Action dispatched when a drag leaves the bounds.Useful for clearing hover state.

Internal drags versus file drops

Dropzone sits at the point where two kinds of drag input can meet. Internal drags, started by Draggable, arrive as raw bytes. External file drops arrive as host-provided file paths. The widget does not merge those models for you. Your reducer decides which input it expects and how to decode it.

Specific advice

Keep visual hover feedback in state, not in a hidden mutable local flag. That way a rebuild, test harness, or target-level snapshot sees the same dropzone state the user sees.

Draggable, DragTarget, FormControl, and GestureDetector.