Skip to content

Commit c38366a

Browse files
author
Roy Lin
committed
feat: support multi-item drag payloads
1 parent 7af6ae3 commit c38366a

26 files changed

Lines changed: 606 additions & 58 deletions

README.md

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,11 @@ versioned [component matrix](docs/react-aria-component-matrix.json) pins
6868
authoring components;
6969
- `Button` currently has scene/software-pixel smoke evidence through the shared
7070
calculator, but no component is self-drawn conformant yet;
71-
- the shared pointer/keyboard drag/drop state machine now covers multi-type and
72-
wildcard negotiation for draggable/drop-target authoring, but multi-item and
73-
per-format payloads, collection delegates, external transfer, pixels,
74-
accessibility, and real hosts still keep `DropZone` below conformance;
71+
- the shared pointer/keyboard drag/drop state machine now covers multi-type,
72+
wildcard, multi-item, and per-format payload negotiation for
73+
draggable/drop-target authoring, but collection delegates, external
74+
transfer, pixels, accessibility, and real hosts still keep `DropZone` below
75+
conformance;
7576
- Checkbox, Radio, and Switch Field/Button parts plus ToastList and
7677
ToastContent are recorded as eight explicit API gaps;
7778
- a component reaches `conformant` only with behavior, layout/hit, Graphics
@@ -301,10 +302,11 @@ independently.
301302
acknowledgement, and surface-loss replay without changing semantic identity
302303
- raw pointer, keyboard, Tab-focus, hover, press, cancellation, wheel,
303304
scheduled long press, incremental captured move, and self-drawn drag/drop
304-
routing over `PlatformElementId`; drag sessions negotiate multiple MIME
305-
types and wildcards plus copy/move/link/cancel operations, while event-loop
306-
deadlines, stable action bubbling, keyed reconciliation, and reducer rollback
307-
share one staged interaction session
305+
routing over `PlatformElementId`; drag sessions retain multiple text items
306+
and every MIME/custom representation, filter compatible target items,
307+
negotiate wildcards plus copy/move/link/cancel operations, and share
308+
event-loop deadlines, stable action bubbling, keyed reconciliation, and
309+
reducer rollback in one staged interaction session
308310
- an identical-frame fast path that performs no layout, scene, host, or
309311
presentation work, plus semantic-only commits that skip pixel presentation
310312
- a software Graphics presenter and interactive shared

docs/architecture.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,9 @@ such as `onClick`, `onLongPress`, `onMoveStart`, `onMove`, `onMoveEnd`,
480480
`onDragStart`, `onDragMove`, `onDragEnd`, `onDropEnter`, `onDropMove`,
481481
`onDropExit`, `onDrop`, `onChange`, `onInput`, `onFocusChange`, `onAction`,
482482
`onExpandedChange`, `onKeyDown`, and `onKeyUp`.
483+
Self-drawn drag callbacks carry a typed item array. Each text item preserves its
484+
complete format map; source events receive every item, while target events
485+
receive the subset matching that target without flattening per-format data.
483486
Focus and blur events always carry canonical `true` and `false` payloads for
484487
`onFocusChange`. These direct focus callbacks are target-only. The runtime
485488
separately derives `onFocusWithin`, `onBlurWithin`, and

docs/platform-hosts.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,8 @@ src/platform_runtime/
223223
|- drag_drop_tests.rs pointer negotiation, rollback, and reconcile gates
224224
|- drag_drop_keyboard_tests.rs
225225
| keyboard and style-only drag/drop gates
226+
|- drag_drop_items_tests.rs
227+
| multi-item/per-format transfer and filtering gates
226228
|- presenter.rs raw-surface prepare/publish contract and recorder
227229
|- reference_presenter.rs
228230
| transactional software Graphics evidence
@@ -385,15 +387,16 @@ Landed evidence:
385387
delta, remains captured outside its hit region, retains incremental delta and
386388
pointer identity, and ends on release, cancellation, or terminal long press;
387389
arrow keys route a handled one-unit lifecycle through the same action batch
388-
- callback-driven and style-only drag/drop negotiates multiple MIME/custom
389-
types, wildcard patterns, and copy/move/link/cancel operations; pointer drags
390-
report target-local coordinates, keyboard Enter/Tab/Escape provides the same
391-
accessible source/compatible-target lifecycle, and keyed frames plus reducer
392-
errors preserve or roll back the entire session atomically
390+
- callback-driven and style-only drag/drop retains multiple text items and all
391+
per-item MIME/custom representations, filters target items by exact or
392+
wildcard types, and negotiates copy/move/link/cancel operations; pointer
393+
drags report target-local coordinates, keyboard Enter/Tab/Escape provides the
394+
same accessible source/compatible-target lifecycle, and keyed frames plus
395+
reducer errors preserve or roll back the entire session atomically
393396
- reducer errors restore the staged interaction state and sequence before the
394397
event is exposed as successful; successful frame reconciliation preserves
395398
focused stable ids, while rejected frames do not touch them
396-
- 44 focused runtime/software tests and four recursive feature/source
399+
- 48 focused runtime/software tests and four recursive feature/source
397400
firewall tests pass without any legacy renderer or OS toolkit dependency
398401
- `self_drawn_calculator` reproduces layout fingerprint
399402
`16529597026056060935`, scene fingerprint `2100550662756266801`, and

docs/react-aria-native.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -144,15 +144,16 @@ The first shared interaction milestone is available in the portable runtime:
144144
- Self-drawn drag routing starts on the first non-zero primary-pointer delta or
145145
keyboard Enter. It negotiates multiple MIME/custom source types, `image/*`
146146
and `all` patterns, allowed copy/move/link/cancel operations, and target-local
147-
pointer coordinates. Keyboard Tab cycles compatible targets only; Enter
148-
drops and Escape cancels. Source/target state, keyed reconciliation, and
149-
reducer rollback remain one transaction.
147+
pointer coordinates. Multiple text items retain all per-item formats, and
148+
accepted types filter whole target items without removing their fallback
149+
representations. Keyboard Tab cycles compatible targets only; Enter drops
150+
and Escape cancels. Source/target state, keyed reconciliation, and reducer
151+
rollback remain one transaction.
150152
- `use_drag`, `use_drop`, `UiDraggable`, `UiDroppable`, and `UiDropZone` lower
151153
their source/target metadata and focusable keyboard affordances into that
152-
shared runtime. Multi-item and per-format payloads, collection
153-
item/between/root delegates, external files and directories,
154-
cross-application transfer, and drag previews remain separate M7 work, so
155-
the DropZone family is not yet marked conformant.
154+
shared runtime. Collection item/between/root delegates, external files and
155+
directories, cross-application transfer, and drag previews remain separate
156+
M7 work, so the DropZone family is not yet marked conformant.
156157

157158
- `NativeInputModality` represents keyboard, mouse, touch, pen, virtual, and
158159
unknown input.

docs/roadmap.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -506,10 +506,14 @@ Landed evidence:
506506
custom exact types, and `all`; `DropEnter`/`DropMove`/`DropExit` ordering,
507507
`data-[dragging]`/`data-[drop-target]` state, keyed-frame reconciliation, and
508508
reducer failure rollback share the same transactional interaction session
509+
- drag sources retain multiple text items and every per-item MIME/custom
510+
representation; target callbacks receive only matching items without losing
511+
the other representations on those items, while legacy `dragType` plus
512+
`dragValue` normalizes to one compatible text item
509513
- the shared 410x620 calculator preserves its reviewed layout and scene
510514
fingerprints, routes eight fake-host events through four reducer actions,
511515
commits the resulting frames, and reaches display value `10`
512-
- 44 focused runtime/software tests plus four recursive H1 firewall tests are
516+
- 48 focused runtime/software tests plus four recursive H1 firewall tests are
513517
included in `just verify`
514518

515519
Remaining H1 work:
@@ -518,10 +522,10 @@ Remaining H1 work:
518522
pinned Graphics commit `8748fab` owns only a surface-independent texture and
519523
readback today, so its safe host-owned surface attachment/recovery contract
520524
must land before GUI can implement this edge without duplicating `wgpu`
521-
- multi-item and per-format drag payloads, collection item/between/root drag
522-
delegates, native file/directory and cross-application transfer, drag
523-
previews, text editing, IME, overlay gestures, and component-specific
524-
interaction conformance remain explicit M4 and M6-M8 work
525+
- collection item/between/root drag delegates, native file/directory and
526+
cross-application transfer, drag previews, text editing, IME, overlay
527+
gestures, and component-specific interaction conformance remain explicit M4
528+
and M6-M8 work
525529

526530
Gates:
527531

docs/rsx.md

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -582,16 +582,23 @@ Semantic UI projections:
582582
only direct focus by default. Set `within={true}` when descendant focus should
583583
also display the ring.
584584

585-
Self-drawn drag sources expose `dragType`, `dragValue`, and
586-
`allowedDropOperations` (comma- or whitespace-separated
587-
`copy`/`move`/`link`). Drop targets expose `acceptedDragTypes` and
588-
`dropOperation`; accepted types may contain multiple exact values, `all`, or a
589-
MIME wildcard such as `image/*`. `UiDraggable`, `UiDroppable`, and `UiDropZone`
590-
include a keyboard-focusable affordance: Enter starts or commits a drag, Tab
591-
cycles compatible targets, and Escape cancels. Pointer and keyboard callbacks
592-
receive the same typed transfer context. External OS files/directories and
593-
collection before/after insertion targets are not part of this first shared
594-
runtime slice.
585+
Self-drawn drag sources expose `dragItems`, a JSON array equivalent to React
586+
Aria's `getItems()` result. Each array entry maps MIME/custom types to their
587+
text representation, for example
588+
`[{"text/plain":"alpha","text/html":"<b>alpha</b>"}]`. Rust hooks may use
589+
`UseDragProps::drag_items(Vec<DragItem>)` instead of encoding JSON. The legacy
590+
`dragType` and `dragValue` pair remains supported and normalizes to one text
591+
item. `allowedDropOperations` accepts comma- or whitespace-separated
592+
`copy`/`move`/`link` values.
593+
594+
Drop targets expose `acceptedDragTypes` and `dropOperation`; accepted types may
595+
contain multiple exact values, `all`, or a MIME wildcard such as `image/*`.
596+
Target callbacks receive only matching items, with every representation on
597+
those items preserved. `UiDraggable`, `UiDroppable`, and `UiDropZone` include a
598+
keyboard-focusable affordance: Enter starts or commits a drag, Tab cycles
599+
compatible targets, and Escape cancels. Pointer and keyboard callbacks receive
600+
the same typed transfer context. External OS files/directories and collection
601+
before/after insertion targets remain separate work.
595602

596603
Runtime lifecycle and effects:
597604

src/compiler.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2591,6 +2591,10 @@ fn drag_scope_value(props: &CompiledProps) -> GuiResult<JsonValue> {
25912591
props,
25922592
&["dragValue", "data-drag-value"],
25932593
))
2594+
.drag_items_json(non_empty_attribute(
2595+
props,
2596+
&["dragItems", "data-drag-items"],
2597+
))
25942598
.allowed_drop_operations(non_empty_attribute(
25952599
props,
25962600
&["allowedDropOperations", "data-allowed-drop-operations"],

src/lib.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,11 @@ pub use platform_host::{
207207
#[cfg(feature = "platform-runtime")]
208208
pub use platform_runtime::{
209209
PlatformRenderFrame, PlatformScenePresenter, RecordingPreparedFrame, RecordingScenePresenter,
210-
SelfDrawnActionInvocation, SelfDrawnActionPropagation, SelfDrawnElementInteraction,
211-
SelfDrawnEventContext, SelfDrawnFrameCommit, SelfDrawnFrameCommitStatus,
212-
SelfDrawnFrameSnapshot, SelfDrawnHostEventOutcome, SelfDrawnInputDispatch,
213-
SelfDrawnInteractionChange, SelfDrawnRuntimeStats, SelfDrawnWindowRuntime,
210+
SelfDrawnActionInvocation, SelfDrawnActionPropagation, SelfDrawnDragContext, SelfDrawnDropItem,
211+
SelfDrawnDropOperation, SelfDrawnElementInteraction, SelfDrawnEventContext,
212+
SelfDrawnFrameCommit, SelfDrawnFrameCommitStatus, SelfDrawnFrameSnapshot,
213+
SelfDrawnHostEventOutcome, SelfDrawnInputDispatch, SelfDrawnInteractionChange,
214+
SelfDrawnRuntimeStats, SelfDrawnWindowRuntime,
214215
};
215216
#[cfg(all(feature = "platform-runtime", feature = "software-reference"))]
216217
pub use platform_runtime::{
@@ -437,7 +438,7 @@ pub use semantic_ui::{
437438
UseLongPressResult, UseMoveProps, UseMoveResult,
438439
};
439440
pub use semantic_ui::{
440-
use_drag, use_drag_value, use_drop, use_drop_value, DragButtonProps, DragProps,
441+
use_drag, use_drag_value, use_drop, use_drop_value, DragButtonProps, DragItem, DragProps,
441442
DropButtonProps, DropProps, UseDragProps, UseDragResult, UseDropProps, UseDropResult,
442443
};
443444
pub use semantic_ui::{

0 commit comments

Comments
 (0)