import { createApp, DragEventPlugin, DragEvent, Plugin, View } from 'veloxi'
class DragToReorderPlugin extends Plugin {
static pluginName = 'DragToReorderPlugin'
dragEventPlugin = this.useEventPlugin(DragEventPlugin)
draggingItem: View | null = null
itemIdSlotMap = new Map()
slotPositionMap = new Map()
this.items = this.getViews('item')
this.items.forEach((item, index) => {
this.assignItemToSlot(item, index)
this.dragEventPlugin.addView(item)
item.position.animator.set('dynamic')
this.slotPositionMap.set(index, item.position.y)
this.dragEventPlugin.on(DragEvent, this.onDrag.bind(this))
onDrag(event: DragEvent) {
this.draggingItem = event.view
this.draggingItem.position.set({ x: event.x, y: event.y })
this.draggingItem.styles.zIndex = '2'
this.updateItemPositions()
if (!this.draggingItem) return
this.draggingItem.styles.zIndex = ''
this.draggingItem.position.set({
x: this.draggingItem.position.initialX,
y: this.getSlotPositionForItem(this.draggingItem)
.filter((item) => item.id !== this.draggingItem?.id)
if (!this.draggingItem) return
const draggingItemSlot = this.itemIdSlotMap.get(this.draggingItem.id)
const itemSlot = this.itemIdSlotMap.get(item.id)
if (draggingItemSlot === undefined || itemSlot === undefined) return
const draggingItemPosition = this.draggingItem.position.y
const itemPosition = this.getSlotPositionForItem(item)
draggingItemSlot < itemSlot &&
draggingItemPosition + this.draggingItem.size.height >
itemPosition + item.size.height / 2
this.assignItemToSlot(item, draggingItemSlot)
this.assignItemToSlot(this.draggingItem, itemSlot)
y: this.slotPositionMap.get(draggingItemSlot)
draggingItemSlot > itemSlot &&
draggingItemPosition < itemPosition + item.size.height / 2
this.assignItemToSlot(item, draggingItemSlot)
this.assignItemToSlot(this.draggingItem, itemSlot)
y: this.slotPositionMap.get(draggingItemSlot)
assignItemToSlot(item: View, slot: number) {
this.itemIdSlotMap.set(item.id, slot)
getSlotPositionForItem(item: View) {
const slot = this.itemIdSlotMap.get(item.id)
return this.slotPositionMap.get(slot)
app.addPlugin(DragToReorderPlugin)