| 1 | import type { App } from 'vue' |
| 2 | import type { DragElementState } from '../composables/useDragElements' |
| 3 | import { watch } from 'vue' |
| 4 | import { useDragElement } from '../composables/useDragElements' |
| 5 | |
| 6 | export function createVDragDirective() { |
| 7 | return { |
| 8 | install(app: App) { |
| 9 | app.directive<HTMLElement & { draggingState: DragElementState }>('drag', { |
| 10 | // @ts-expect-error extra prop |
| 11 | name: 'v-drag', |
| 12 | |
| 13 | created(el, binding, vnode) { |
| 14 | const state = useDragElement(binding, binding.value, vnode.props?.markdownSource) |
| 15 | if (vnode.props) { |
| 16 | vnode.props = { ...vnode.props } |
| 17 | delete vnode.props.markdownSource |
| 18 | } |
| 19 | state.container.value = el |
| 20 | el.draggingState = state |
| 21 | el.dataset.dragId = state.dragId |
| 22 | state.watchStopHandles.push( |
| 23 | watch(state.containerStyle, (style) => { |
| 24 | for (const [k, v] of Object.entries(style)) { |
| 25 | if (v) |
| 26 | el.style[k as any] = v as any |
| 27 | } |
| 28 | }, { immediate: true }), |
| 29 | ) |
| 30 | el.addEventListener('dblclick', state.startDragging) |
| 31 | }, |
| 32 | mounted(el) { |
| 33 | el.draggingState.mounted() |
| 34 | }, |
| 35 | unmounted(el) { |
| 36 | const state = el.draggingState |
| 37 | state.unmounted() |
| 38 | el.removeEventListener('dblclick', state.startDragging) |
| 39 | state.watchStopHandles.forEach(fn => fn()) |
| 40 | }, |
| 41 | }) |
| 42 | }, |
| 43 | } |
| 44 | } |
| 45 |