Skip to main content

reflex-pragmatic-drag-and-drop

Reflex bindings for Atlassian's Pragmatic drag and drop. Build sortable lists and Kanban boards in pure Python, without writing JavaScript.

Wraps the full suite: @atlaskit/pragmatic-drag-and-drop (core), -hitbox (closest edge), -auto-scroll, and -react-drop-indicator.

Status

Functional core (Phases 1–3 of the plan) with a test suite. See specs/ for the complete design (PRD, API, Tech Design, Data Model, Plan).

Requirements

  • Python ≥ 3.12 · Reflex ≥ 0.9 · uv package manager

Installation and running (Kanban demo)

uv sync                 # installs Python dependencies
uv run reflex run       # installs @atlaskit packages in .web and starts on :3000

Open http://localhost:3000 and drag the cards between columns.

Usage

import reflex as rx
import reflex_pragmatic_dnd as dnd


class State(rx.State):
    msg: str = ""

    @rx.event
    def on_drop(self, payload: dict):
        self.msg = f"{payload['source']} -> {payload.get('target')}"


def index():
    return rx.box(
        # Global listener: a single handler for the whole page.
        dnd.monitor(on_drop=State.on_drop),

        # A draggable element that carries data.
        dnd.draggable(
            rx.text("Drag me"),
            drag_id="card-1",
            item_data={"cardId": "card-1"},
        ),

        # A drop target with edge detection (for reordering).
        dnd.drop_target(
            rx.text("Drop it here"),
            drop_id="zone-1",
            target_data={"kind": "zone"},
            with_closest_edge=True,
            allowed_edges=["top", "bottom"],
        ),

        rx.text(State.msg),
    )

Components

Factory Wraps Events
dnd.draggable(...) draggable (element adapter) on_drag_start, on_drop
dnd.drop_target(...) dropTargetForElements (+ hitbox) on_drag_enter, on_drag_leave, on_drop
dnd.monitor(...) monitorForElements on_drag_start, on_drop
dnd.scroll_container(...) autoScrollForElements

Full details on props and payloads: specs/api/component-api-v1.md.

State reducers (optional)

The library includes two pure functions that transform the payload of monitor(on_drop=...) into the new state, implementing the rules of specs/data-model/event-payloads.md §4. They do not mutate their inputs and return the original object unchanged on a no-op (dropping outside, onto itself, or onto an unknown column):

@rx.event
def handle_drop(self, payload: dict):
    self.cards = dnd.move_card(self.cards, payload, columns=["todo", "doing", "done"])

@rx.event
def reorder(self, payload: dict):
    self.items = dnd.reorder_list(self.items, payload)

Visual states (CSS)

drop_target exposes attributes on the DOM for styling during the drag, and draggable marks the element in progress:

Attribute Value Component
data-dragging true/false draggable
data-over true/false drop_target
data-closest-edge top/bottom/left/right/"" drop_target (with with_closest_edge)
data-drop-id the drop_id drop_target
dnd.drop_target(
    rx.text("Drop it here"),
    drop_id="zone-1",
    with_closest_edge=True,
    # Highlight the target and draw a line on the closest edge.
    style={
        "&[data-over='true']": {"background": "var(--accent-3)"},
        "&[data-closest-edge='top']": {"box_shadow": "inset 0 2px 0 var(--accent-9)"},
        "&[data-closest-edge='bottom']": {"box_shadow": "inset 0 -2px 0 var(--accent-9)"},
    },
)

Examples

Structure

reflex_pragmatic_dnd/            # the library (wrappers + JSX glue)
reflex_pragmatic_drag_and_drop/  # Kanban demo app
examples/                        # additional examples
specs/                           # SDD documentation

How it works

A local React glue (pragmatic_dnd.jsx, bundled with rx.asset) attaches Pragmatic to the DOM elements via useEffect/useRef and emits JSON-serializable payloads. NoSSRComponent wrappers expose them as Reflex components with typed events. Only discrete events (start/drop) cross the WebSocket; the continuous computation happens on the client. See specs/technical/architecture.md.

Tests

uv run pytest

Covers the pure reducers (transformation rules from Data Model §4 and edge cases from API Spec §4), the states of the demo/example app, and the wrapper contract (tags, snake↔camel props, events, NoSSRComponent, pinned @atlaskit dependencies).

License

MIT.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

reflex_pragmatic_drag_and_drop-0.1.1.tar.gz (19.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

reflex_pragmatic_drag_and_drop-0.1.1-py3-none-any.whl (12.0 kB view details)

Uploaded Python 3

File details

Details for the file reflex_pragmatic_drag_and_drop-0.1.1.tar.gz.

File metadata

File hashes

Hashes for reflex_pragmatic_drag_and_drop-0.1.1.tar.gz
Algorithm Hash digest
SHA256 ac7f3e287c672fcd3a4da4a99d8e336b220e116393163698785b7f95f1ecf0e8
MD5 073ee0a1ac0e47bd9953a5886309619f
BLAKE2b-256 ebef916499fe43fac0716254adb18ba378b243b5e74f970d85181249d310274c

See more details on using hashes here.

File details

Details for the file reflex_pragmatic_drag_and_drop-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for reflex_pragmatic_drag_and_drop-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 6e022d01a4103478f6aed7c16344a5ff37cace2ae35cf03b3fa03806171bd02f
MD5 ee5e6a3dedee0f13e728dd65b9929ba7
BLAKE2b-256 4b359cec7a8ad9926a2739984a95eefd517aad532d1ff29b762a4f8c5d562db8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page