CxJS

Drag and Drop

import { DragSource, DropZone, DragHandle } from 'cx/widgets'; Copied

CxJS provides components for implementing drag and drop functionality:

  • DragSource - Wraps elements that can be dragged
  • DropZone - Defines areas where items can be dropped
  • DragHandle - Optional handle to initiate dragging

Example

This example demonstrates list reordering using drag and drop:

<div class="flex flex-col gap-2" controller={PageController}>
  <Repeater
    records={m.items}
    recordAlias={m.$record}
    indexAlias={m.$index}
    keyField="id"
  >
    <DropZone
      mod="block"
      onDrop={({ source }, { store }) => {
        let targetIndex = store.get(m.$index)
        let items = store
          .get(m.items)
          .filter((item) => item.id !== source.data.id)
        store.set(m.items, [
          ...items.slice(0, targetIndex),
          source.data,
          ...items.slice(targetIndex),
        ])
      }}
      matchWidth
      matchHeight
      matchMargin
      inflate={50}
    />
    <DragSource
      data={m.$record}
      //hideOnDrag
      class="p-2 border rounded bg-white cursor-move hover:bg-gray-50"
    >
      <span text={m.$record.text} />
    </DragSource>
  </Repeater>
  <DropZone
    mod="block"
    matchWidth
    matchHeight
    matchMargin
    onDrop={({ source }, { store }) => {
      let items = store
        .get(m.items)
        .filter((item) => item.id !== source.data.id)
      store.set(m.items, [...items, source.data])
    }}
    inflate={50}
  >
    <div class="h-2" />
  </DropZone>
</div>
Apple
Banana
Cherry
Date
Elderberry

How It Works

  1. Each item is wrapped in a DragSource that passes the record data when dragged
  2. A DropZone around each item receives the dropped data
  3. The onDrop handler reorders the array by removing the item from its old position and inserting it at the new position