Skip to main content

Reflex bindings for Atlassian Pragmatic drag and drop (sortable lists, Kanban) in pure Python

Project description

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.

Project details


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.0.tar.gz (17.7 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.0-py3-none-any.whl (10.1 kB view details)

Uploaded Python 3

File details

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

File metadata

File hashes

Hashes for reflex_pragmatic_drag_and_drop-0.1.0.tar.gz
Algorithm Hash digest
SHA256 67c272f130be697f167ebf0e03d53c4767b0ae9cf0c62a9df541b9916bdd9600
MD5 7cd33658f491f2c68530336d01ea6de6
BLAKE2b-256 80dafc221e95e3632843175e75eb320494457c69a99da7195a007084663068f7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reflex_pragmatic_drag_and_drop-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6b12c184b19d58a74bfacd9c78f95a6617f9ae5ae54a3941720f70c4b9b71198
MD5 039d482222f761fa79ba2f610a52d8da
BLAKE2b-256 c2a7e61e0ef1a10ea4dac8a1acd52d02c1c0d34e483ac736ba8e72a4f3015c40

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 Pingdom Monitoring Sentry Error logging StatusPage Status page