Skip to content

Instantly share code, notes, and snippets.

@zerkalica
Created October 11, 2023 10:15
Show Gist options
  • Save zerkalica/c1b9d3606bd6a7d743711d82148414d8 to your computer and use it in GitHub Desktop.
Save zerkalica/c1b9d3606bd6a7d743711d82148414d8 to your computer and use it in GitHub Desktop.
list.js
import type { mpk_core_map_exchange } from '../../core/map/map.js'
import { mpk_ui_object } from '../object/object.js'
import './list.css'
export class mpk_ui_sortable_list extends mpk_ui_object {
protected dragEl = undefined as undefined | HTMLElement
protected onDragStart(evt: DragEvent) {
const target = evt.target as HTMLElement | undefined
if (!target) return
const dragEl = target.getAttribute('draggable')
? target
: (target.closest(`[draggable=true]`) as undefined | HTMLElement)
this.dragEl = dragEl
this.prevSibling = undefined
if (!dragEl) return
const sortableId = dragEl.dataset['sortable-id'] as undefined | string
if (!evt.dataTransfer) return
evt.dataTransfer.effectAllowed = 'move'
if (sortableId) evt.dataTransfer.setData('text/plain', sortableId)
setTimeout(() => dragEl.setAttribute('mpk_ui_sortable_moving', '1'), 0)
}
protected onDragOver(evt: DragEvent) {
const dragEl = this.dragEl
if (!dragEl) return
evt.preventDefault()
if (!evt.dataTransfer) return
evt.dataTransfer.dropEffect = 'move'
this.prevSibling?.removeAttribute('mpk_ui_sortable_dest')
this.lastSelection = undefined
const target = evt.target as undefined | HTMLElement
if (!target) return
const sibling = target.getAttribute('draggable')
? target
: (target.closest(`[draggable=true]`) as undefined | HTMLElement)
if (!sibling) return
if (sibling === dragEl) return
const rect = sibling.getBoundingClientRect()
const offset = {
x: evt.pageX - rect.left,
y: evt.pageY - rect.top,
}
const middle = {
x: (rect.right - rect.left) / 2,
y: (rect.bottom - rect.top) / 2,
}
const isInsertAfter = offset.y > middle.y
sibling.setAttribute('mpk_ui_sortable_dest', isInsertAfter ? 'after' : 'before')
this.prevSibling = sibling
const drag_id = dragEl.id || dragEl.dataset['dragid'] || ''
const sibling_id = sibling.id || sibling.dataset['dragid'] || ''
this.lastSelection = { after: isInsertAfter, drag_id, sibling_id }
}
protected prevSibling = undefined as undefined | HTMLElement
protected lastSelection = undefined as undefined | mpk_core_map_exchange
protected onDragEnd(evt: DragEvent) {
const dragEl = this.dragEl
if (!dragEl) return
evt.preventDefault()
this.prevSibling?.removeAttribute('mpk_ui_sortable_dest')
dragEl.removeAttribute('mpk_ui_sortable_moving')
dragEl.removeAttribute('mpk_ui_sortable_dest')
this.dragEl = undefined
this.prevSibling = undefined
if (this.lastSelection) this.move(this.lastSelection)
}
move(next: mpk_core_map_exchange) {}
readonly props = {
onDragEnd: this.onDragEnd.bind(this),
onDragStart: this.onDragStart.bind(this),
onDragOver: this.onDragOver.bind(this),
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment