@bagelink/vue 0.0.1147 → 0.0.1155
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/common-C_IH8b5S.cjs +12580 -0
- package/dist/common-DoeNgx31.js +12579 -0
- package/dist/components/AddressSaerch.vue.d.ts +7 -0
- package/dist/components/AddressSaerch.vue.d.ts.map +1 -0
- package/dist/components/ComboBox.vue.d.ts +3 -3
- package/dist/components/Comments.vue.d.ts +2 -2
- package/dist/components/ContactSubmissions.vue.d.ts +2 -2
- package/dist/components/DataPreview.vue.d.ts +12 -35
- package/dist/components/DataPreview.vue.d.ts.map +1 -1
- package/dist/components/DataTable/DataTable.vue.d.ts +1 -1
- package/dist/components/DataTable/DataTable.vue.d.ts.map +1 -1
- package/dist/components/DataTable/useTableData.d.ts +10 -2
- package/dist/components/DataTable/useTableData.d.ts.map +1 -1
- package/dist/components/Draggable/Draggable.vue.d.ts +45 -0
- package/dist/components/Draggable/Draggable.vue.d.ts.map +1 -0
- package/dist/components/Draggable/index.d.ts +5 -0
- package/dist/components/Draggable/index.d.ts.map +1 -0
- package/dist/components/Draggable/useDraggable.d.ts +31 -0
- package/dist/components/Draggable/useDraggable.d.ts.map +1 -0
- package/dist/components/Draggable/vDraggable.d.ts +4 -0
- package/dist/components/Draggable/vDraggable.d.ts.map +1 -0
- package/dist/components/FormSchema.vue.d.ts +4 -5
- package/dist/components/LangText.vue.d.ts +2 -2
- package/dist/components/ListView.vue.d.ts.map +1 -1
- package/dist/components/ModalBglForm.vue.d.ts +20 -21
- package/dist/components/PersonPreview.vue.d.ts +4 -5
- package/dist/components/PersonPreviewFormkit.vue.d.ts +3 -4
- package/dist/components/Popover.vue.d.ts +10 -0
- package/dist/components/Popover.vue.d.ts.map +1 -0
- package/dist/components/RTXEditor.vue.d.ts +3 -3
- package/dist/components/TabbedLayout.vue.d.ts +4 -5
- package/dist/components/TableSchema.vue.d.ts +2 -2
- package/dist/components/TableSchema.vue.d.ts.map +1 -1
- package/dist/components/charts/BarChart.vue.d.ts +2 -2
- package/dist/components/form/BagelForm.vue.d.ts.map +1 -1
- package/dist/components/form/FieldArray.vue.d.ts.map +1 -1
- package/dist/components/form/ItemRef.vue.d.ts +3 -5
- package/dist/components/form/ItemRef.vue.d.ts.map +1 -1
- package/dist/components/form/MaterialIcon.vue.d.ts +3 -4
- package/dist/components/form/PlainInputField.vue.d.ts +3 -3
- package/dist/components/form/index.d.ts +0 -1
- package/dist/components/form/index.d.ts.map +1 -1
- package/dist/components/form/inputs/CurrencyInput.vue.d.ts +3 -3
- package/dist/components/form/inputs/DatetimeInput.vue.d.ts +3 -3
- package/dist/components/form/inputs/DurationInput.vue.d.ts +3 -3
- package/dist/components/form/inputs/DynamicLinkField.vue.d.ts +3 -3
- package/dist/components/form/inputs/EmailInput.vue.d.ts +3 -3
- package/dist/components/form/inputs/FloatInput.vue.d.ts +3 -3
- package/dist/components/form/inputs/IntInput.vue.d.ts +3 -3
- package/dist/components/form/inputs/LinkField.vue.d.ts +3 -3
- package/dist/components/form/inputs/Password.vue.d.ts +3 -3
- package/dist/components/form/inputs/PlainText.vue.d.ts +3 -3
- package/dist/components/form/inputs/ReadOnlyInput.vue.d.ts +2 -2
- package/dist/components/form/inputs/RichText/Toolbar.vue.d.ts +14 -0
- package/dist/components/form/inputs/RichText/Toolbar.vue.d.ts.map +1 -0
- package/dist/components/form/inputs/RichText/formatting.d.ts +11 -0
- package/dist/components/form/inputs/RichText/formatting.d.ts.map +1 -0
- package/dist/components/form/inputs/RichText/richtext-types.d.ts +3 -0
- package/dist/components/form/inputs/RichText/richtext-types.d.ts.map +1 -0
- package/dist/components/form/inputs/RichText2/Toolbar.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText2/index.vue.d.ts +0 -1
- package/dist/components/form/inputs/RichText2/index.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RichTextEditor.vue.d.ts +3 -3
- package/dist/components/form/inputs/SelectField.vue.d.ts +8 -6
- package/dist/components/form/inputs/SelectField.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/SelectInput.vue.d.ts +4 -4
- package/dist/components/form/inputs/TextArea.vue.d.ts +3 -3
- package/dist/components/form/inputs/TextInput.vue.d.ts +1 -1
- package/dist/components/form/inputs/TextInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/Upload/UploadFile.vue.d.ts +86 -0
- package/dist/components/form/inputs/Upload/UploadFile.vue.d.ts.map +1 -0
- package/dist/components/formkit/AddressArray.vue.d.ts +2 -2
- package/dist/components/formkit/BankDetailsArray.vue.d.ts +2 -2
- package/dist/components/formkit/ContactArrayFormKit.vue.d.ts +2 -2
- package/dist/components/formkit/FileUploader.vue.d.ts +2 -2
- package/dist/components/formkit/MiscFields.vue.d.ts +2 -2
- package/dist/components/formkit/Toggle.vue.d.ts +2 -2
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/layout/Layout.vue.d.ts +1 -1
- package/dist/components/layout/Layout.vue.d.ts.map +1 -1
- package/dist/components/sortable/Animation.d.ts +43 -0
- package/dist/components/sortable/Animation.d.ts.map +1 -0
- package/dist/components/sortable/BrowserInfo.d.ts +7 -0
- package/dist/components/sortable/BrowserInfo.d.ts.map +1 -0
- package/dist/components/sortable/EventDispatcher.d.ts +13 -0
- package/dist/components/sortable/EventDispatcher.d.ts.map +1 -0
- package/dist/components/sortable/PluginManager.d.ts +27 -0
- package/dist/components/sortable/PluginManager.d.ts.map +1 -0
- package/dist/components/sortable/Sortable.d.ts +81 -0
- package/dist/components/sortable/Sortable.d.ts.map +1 -0
- package/dist/components/sortable/index.d.ts +5 -0
- package/dist/components/sortable/index.d.ts.map +1 -0
- package/dist/components/sortable/utils.d.ts +49 -0
- package/dist/components/sortable/utils.d.ts.map +1 -0
- package/dist/components/whatsapp/form/MsgTemplate.vue.d.ts +3 -4
- package/dist/components/whatsapp/form/TextVariableExamples.vue.d.ts +2 -2
- package/dist/composables/drag-n-drop/useDraggable.d.ts +2 -0
- package/dist/composables/drag-n-drop/useDraggable.d.ts.map +1 -0
- package/dist/composables/useSchemaField.d.ts +15 -0
- package/dist/composables/useSchemaField.d.ts.map +1 -0
- package/dist/editor-CUDRLdmS.js +4 -0
- package/dist/editor-Cu374vEW.cjs +4 -0
- package/dist/editor-a8DSbb6P.js +4 -0
- package/dist/editor-xBt_vIha.cjs +4 -0
- package/dist/heic2any-8wMqMfB_.js +933 -0
- package/dist/heic2any-BrqcNzfV.js +935 -0
- package/dist/heic2any-C8KwH72N.cjs +934 -0
- package/dist/heic2any-k9wDCKka.cjs +932 -0
- package/dist/index-DiG-xM9T.cjs +35016 -0
- package/dist/index-nGuSAiY2.js +35017 -0
- package/dist/index.cjs +1322 -884
- package/dist/index.mjs +1324 -886
- package/dist/plugins/drag-n-drop/draggable.d.ts +4 -0
- package/dist/plugins/drag-n-drop/draggable.d.ts.map +1 -0
- package/dist/plugins/drag-n-drop/droppable.d.ts +4 -0
- package/dist/plugins/drag-n-drop/droppable.d.ts.map +1 -0
- package/dist/plugins/drag-n-drop/index.d.ts +5 -0
- package/dist/plugins/drag-n-drop/index.d.ts.map +1 -0
- package/dist/plugins/drag-n-drop/useDraggable.d.ts +8 -0
- package/dist/plugins/drag-n-drop/useDraggable.d.ts.map +1 -0
- package/dist/plugins/drag-n-drop/useDroppable.d.ts +7 -0
- package/dist/plugins/drag-n-drop/useDroppable.d.ts.map +1 -0
- package/dist/style.css +186 -208
- package/dist/types/materialIcon.d.ts +2 -0
- package/dist/types/materialIcon.d.ts.map +1 -0
- package/dist/utils/objects.d.ts +0 -1
- package/package.json +1 -1
- package/src/components/DataPreview.vue +45 -116
- package/src/components/DataTable/DataTable.vue +18 -12
- package/src/components/DataTable/useTableData.ts +50 -16
- package/src/components/Draggable/Draggable.vue +64 -0
- package/src/components/Draggable/index.ts +4 -0
- package/src/components/Draggable/useDraggable.ts +632 -0
- package/src/components/Draggable/vDraggable.ts +17 -0
- package/src/components/ListView.vue +6 -2
- package/src/components/Pill.vue +1 -1
- package/src/components/form/BagelForm.vue +16 -101
- package/src/components/form/FieldArray.vue +21 -3
- package/src/components/form/index.ts +0 -1
- package/src/components/form/inputs/TextInput.vue +5 -5
- package/src/components/index.ts +5 -1
- package/src/composables/useSchemaField.ts +193 -0
- package/src/styles/text.css +15 -11
- package/dist/components/Accordion.d.ts +0 -12
- package/dist/components/Accordion.d.ts.map +0 -1
- package/dist/components/AccordionItem.d.ts +0 -34
- package/dist/components/AccordionItem.d.ts.map +0 -1
- package/dist/components/Alert.d.ts +0 -34
- package/dist/components/Alert.d.ts.map +0 -1
- package/dist/components/Avatar.d.ts +0 -36
- package/dist/components/Avatar.d.ts.map +0 -1
- package/dist/components/Badge.d.ts +0 -22
- package/dist/components/Badge.d.ts.map +0 -1
- package/dist/components/BglVideo.d.ts +0 -20
- package/dist/components/BglVideo.d.ts.map +0 -1
- package/dist/components/Btn.d.ts +0 -99
- package/dist/components/Btn.d.ts.map +0 -1
- package/dist/components/Card.d.ts +0 -39
- package/dist/components/Card.d.ts.map +0 -1
- package/dist/components/Carousel.d.ts +0 -74
- package/dist/components/Carousel.d.ts.map +0 -1
- package/dist/components/DataPreview.d.ts +0 -42
- package/dist/components/DataPreview.d.ts.map +0 -1
- package/dist/components/Drop.vue.d.ts +0 -34
- package/dist/components/Drop.vue.d.ts.map +0 -1
- package/dist/components/FileUploader.vue.d.ts +0 -60
- package/dist/components/FileUploader.vue.d.ts.map +0 -1
- package/dist/components/Flag.d.ts +0 -20
- package/dist/components/Flag.d.ts.map +0 -1
- package/dist/components/ListItem.d.ts +0 -34
- package/dist/components/ListItem.d.ts.map +0 -1
- package/dist/components/ListView.d.ts +0 -13
- package/dist/components/ListView.d.ts.map +0 -1
- package/dist/components/MapEmbed.d.ts +0 -3
- package/dist/components/MapEmbed.d.ts.map +0 -1
- package/dist/components/MaterialIcon.d.ts +0 -26
- package/dist/components/MaterialIcon.d.ts.map +0 -1
- package/dist/components/Modal.d.ts +0 -46
- package/dist/components/Modal.d.ts.map +0 -1
- package/dist/components/ModalConfirm.d.ts +0 -24
- package/dist/components/ModalConfirm.d.ts.map +0 -1
- package/dist/components/ModalForm.d.ts +0 -78
- package/dist/components/ModalForm.d.ts.map +0 -1
- package/dist/components/NavBar.d.ts +0 -64
- package/dist/components/NavBar.d.ts.map +0 -1
- package/dist/components/PageTitle.d.ts +0 -24
- package/dist/components/PageTitle.d.ts.map +0 -1
- package/dist/components/RouterWrapper.d.ts +0 -3
- package/dist/components/RouterWrapper.d.ts.map +0 -1
- package/dist/components/TableSchema.d.ts +0 -35
- package/dist/components/TableSchema.d.ts.map +0 -1
- package/dist/components/Title.d.ts +0 -42
- package/dist/components/Title.d.ts.map +0 -1
- package/dist/components/TopBar.d.ts +0 -12
- package/dist/components/TopBar.d.ts.map +0 -1
- package/dist/components/dashboard/Lineart.d.ts +0 -20
- package/dist/components/dashboard/Lineart.d.ts.map +0 -1
- package/dist/components/form/BglField.d.ts +0 -25
- package/dist/components/form/BglField.d.ts.map +0 -1
- package/dist/components/form/BglForm.d.ts +0 -75
- package/dist/components/form/BglForm.d.ts.map +0 -1
- package/dist/components/form/inputs/CheckInput.d.ts +0 -56
- package/dist/components/form/inputs/CheckInput.d.ts.map +0 -1
- package/dist/components/form/inputs/Checkbox.d.ts +0 -16
- package/dist/components/form/inputs/Checkbox.d.ts.map +0 -1
- package/dist/components/form/inputs/ColorPicker.d.ts +0 -48
- package/dist/components/form/inputs/ColorPicker.d.ts.map +0 -1
- package/dist/components/form/inputs/DateInput.d.ts +0 -64
- package/dist/components/form/inputs/DateInput.d.ts.map +0 -1
- package/dist/components/form/inputs/DatePicker.d.ts +0 -33
- package/dist/components/form/inputs/DatePicker.d.ts.map +0 -1
- package/dist/components/form/inputs/FileUpload.d.ts +0 -108
- package/dist/components/form/inputs/FileUpload.d.ts.map +0 -1
- package/dist/components/form/inputs/JSONInput.d.ts +0 -53
- package/dist/components/form/inputs/JSONInput.d.ts.map +0 -1
- package/dist/components/form/inputs/RadioGroup.d.ts +0 -42
- package/dist/components/form/inputs/RadioGroup.d.ts.map +0 -1
- package/dist/components/form/inputs/RadioPillsInput.d.ts +0 -48
- package/dist/components/form/inputs/RadioPillsInput.d.ts.map +0 -1
- package/dist/components/form/inputs/RichText.d.ts +0 -20
- package/dist/components/form/inputs/RichText.d.ts.map +0 -1
- package/dist/components/form/inputs/RichText2/Toolbar.d.ts +0 -22
- package/dist/components/form/inputs/RichText2/Toolbar.d.ts.map +0 -1
- package/dist/components/form/inputs/RichText2/index.d.ts +0 -24
- package/dist/components/form/inputs/RichText2/index.d.ts.map +0 -1
- package/dist/components/form/inputs/SelectInput.d.ts +0 -55
- package/dist/components/form/inputs/SelectInput.d.ts.map +0 -1
- package/dist/components/form/inputs/SignaturePad.d.ts +0 -72
- package/dist/components/form/inputs/SignaturePad.d.ts.map +0 -1
- package/dist/components/form/inputs/TableField.d.ts +0 -45
- package/dist/components/form/inputs/TableField.d.ts.map +0 -1
- package/dist/components/form/inputs/TelInput.d.ts +0 -241
- package/dist/components/form/inputs/TelInput.d.ts.map +0 -1
- package/dist/components/form/inputs/TextInput.d.ts +0 -90
- package/dist/components/form/inputs/TextInput.d.ts.map +0 -1
- package/dist/components/form/inputs/ToggleInput.d.ts +0 -58
- package/dist/components/form/inputs/ToggleInput.d.ts.map +0 -1
- package/dist/components/layout/BottomMenu.d.ts +0 -27
- package/dist/components/layout/BottomMenu.d.ts.map +0 -1
- package/dist/components/layout/Layout.d.ts +0 -58
- package/dist/components/layout/Layout.d.ts.map +0 -1
- package/dist/components/layout/SidebarMenu.d.ts +0 -38
- package/dist/components/layout/SidebarMenu.d.ts.map +0 -1
- package/dist/components/layout/TabbedLayout.d.ts +0 -42
- package/dist/components/layout/TabbedLayout.d.ts.map +0 -1
- package/dist/components/layout/Tabs.d.ts +0 -31
- package/dist/components/layout/Tabs.d.ts.map +0 -1
- package/dist/components/layout/TabsBody.d.ts +0 -23
- package/dist/components/layout/TabsBody.d.ts.map +0 -1
- package/dist/components/layout/TabsNav.d.ts +0 -35
- package/dist/components/layout/TabsNav.d.ts.map +0 -1
- package/dist/styles.css +0 -14073
- package/dist/vue.css +0 -14073
- package/src/components/form/BglField.vue +0 -132
- package/src/components/form/BglForm.vue +0 -157
|
@@ -0,0 +1,632 @@
|
|
|
1
|
+
import { ref, onUnmounted } from 'vue'
|
|
2
|
+
|
|
3
|
+
export interface DraggableEvent extends MouseEvent {
|
|
4
|
+
oldIndex: number
|
|
5
|
+
newIndex: number
|
|
6
|
+
item?: any
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface DraggableOptions {
|
|
10
|
+
group?: string
|
|
11
|
+
animation?: number
|
|
12
|
+
disabled?: boolean
|
|
13
|
+
handle?: string
|
|
14
|
+
ghostClass?: string
|
|
15
|
+
dragClass?: string
|
|
16
|
+
mode?: 'ghost' | 'line'
|
|
17
|
+
dropIndicatorClass?: string
|
|
18
|
+
items?: any[]
|
|
19
|
+
onStart?: (event: MouseEvent) => void
|
|
20
|
+
onEnd?: (event: DraggableEvent) => void
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface DraggableElement extends HTMLElement {
|
|
24
|
+
__drag_group?: string
|
|
25
|
+
__drag_index?: number
|
|
26
|
+
__drag_list?: DraggableElement[]
|
|
27
|
+
__intended_index?: number
|
|
28
|
+
__drag_data?: any
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function useDraggable(options: DraggableOptions = {}) {
|
|
32
|
+
const isDragging = ref(false)
|
|
33
|
+
const dragElement = ref<DraggableElement | null>(null)
|
|
34
|
+
const ghostElement = ref<HTMLElement | null>(null)
|
|
35
|
+
const dropIndicator = ref<HTMLElement | null>(null)
|
|
36
|
+
const dropTarget = ref<DraggableElement | null>(null)
|
|
37
|
+
|
|
38
|
+
const defaultOptions: DraggableOptions = {
|
|
39
|
+
animation: 150,
|
|
40
|
+
mode: 'line',
|
|
41
|
+
ghostClass: 'draggable-ghost',
|
|
42
|
+
dragClass: 'draggable-dragging',
|
|
43
|
+
dropIndicatorClass: 'draggable-drop-indicator',
|
|
44
|
+
...options
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
let startX = 0
|
|
48
|
+
let startY = 0
|
|
49
|
+
let initialX = 0
|
|
50
|
+
let initialY = 0
|
|
51
|
+
let shiftAmount = 0
|
|
52
|
+
|
|
53
|
+
let cleanupFn: (() => void) | undefined
|
|
54
|
+
let scrollRAF: number | null = null
|
|
55
|
+
|
|
56
|
+
let lastDropIndex = -1
|
|
57
|
+
let lastUpdateTime = 0
|
|
58
|
+
const UPDATE_THRESHOLD = 150 // ms between updates
|
|
59
|
+
const POSITION_CACHE = new Map<number, { top: number, bottom: number }>()
|
|
60
|
+
|
|
61
|
+
function createGhost(el: DraggableElement) {
|
|
62
|
+
const ghost = el.cloneNode(true) as HTMLElement
|
|
63
|
+
const rect = el.getBoundingClientRect()
|
|
64
|
+
ghost.style.position = 'fixed'
|
|
65
|
+
ghost.style.margin = '0'
|
|
66
|
+
ghost.style.top = `${rect.top}px`
|
|
67
|
+
ghost.style.left = `${rect.left}px`
|
|
68
|
+
ghost.style.width = `${rect.width}px`
|
|
69
|
+
ghost.style.height = `${rect.height}px`
|
|
70
|
+
ghost.style.transform = 'translate3d(0, 0, 0)'
|
|
71
|
+
ghost.style.pointerEvents = 'none'
|
|
72
|
+
ghost.style.zIndex = '9999'
|
|
73
|
+
ghost.style.cursor = 'grabbing'
|
|
74
|
+
ghost.style.willChange = 'transform'
|
|
75
|
+
ghost.classList.add(defaultOptions.ghostClass!)
|
|
76
|
+
document.body.appendChild(ghost)
|
|
77
|
+
return ghost
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function createDropIndicator(el: DraggableElement) {
|
|
81
|
+
const line = document.createElement('div')
|
|
82
|
+
line.classList.add(defaultOptions.dropIndicatorClass!)
|
|
83
|
+
line.style.position = 'fixed'
|
|
84
|
+
line.style.pointerEvents = 'none'
|
|
85
|
+
line.style.zIndex = '9999'
|
|
86
|
+
line.style.height = '2px'
|
|
87
|
+
line.style.background = 'var(--primary-color, #0066ff)'
|
|
88
|
+
line.style.boxShadow = '0 0 4px rgba(0, 102, 255, 0.5)'
|
|
89
|
+
line.style.transition = 'all 0.15s ease'
|
|
90
|
+
line.style.display = 'none' // Start hidden
|
|
91
|
+
|
|
92
|
+
// Add the dot indicator
|
|
93
|
+
const dot = document.createElement('div')
|
|
94
|
+
dot.style.position = 'absolute'
|
|
95
|
+
dot.style.left = '-4px'
|
|
96
|
+
dot.style.top = '-3px'
|
|
97
|
+
dot.style.width = '8px'
|
|
98
|
+
dot.style.height = '8px'
|
|
99
|
+
dot.style.borderRadius = '50%'
|
|
100
|
+
dot.style.background = 'var(--primary-color, #0066ff)'
|
|
101
|
+
|
|
102
|
+
line.appendChild(dot)
|
|
103
|
+
document.body.appendChild(line)
|
|
104
|
+
return line
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function updateDropIndicator(target: DraggableElement, isAfter: boolean) {
|
|
108
|
+
if (!dropIndicator.value) return
|
|
109
|
+
|
|
110
|
+
const rect = target.getBoundingClientRect()
|
|
111
|
+
dropIndicator.value.style.display = 'block'
|
|
112
|
+
dropIndicator.value.style.width = `${rect.width}px`
|
|
113
|
+
dropIndicator.value.style.left = `${rect.left}px`
|
|
114
|
+
|
|
115
|
+
// Move indicator to match the actual drop position
|
|
116
|
+
if (isAfter) {
|
|
117
|
+
dropIndicator.value.style.top = `${rect.bottom}px`
|
|
118
|
+
} else {
|
|
119
|
+
dropIndicator.value.style.top = `${rect.top}px`
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function findDraggableParent(element: Element | null): DraggableElement | null {
|
|
124
|
+
let current = element
|
|
125
|
+
while (current && (!('__drag_group' in current) || (current as any).dataset.draggable === 'false')) {
|
|
126
|
+
current = current.parentElement
|
|
127
|
+
}
|
|
128
|
+
return current as DraggableElement | null
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function handleGhostMode(dragEl: DraggableElement) {
|
|
132
|
+
dragEl.style.opacity = '0.4'
|
|
133
|
+
dragEl.style.transform = 'scale(0.95)'
|
|
134
|
+
return dragEl.offsetHeight
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function handleLineMode(dragEl: DraggableElement) {
|
|
138
|
+
dragEl.style.opacity = '0.5'
|
|
139
|
+
return 2
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function resetDragStyles(dragEl: DraggableElement) {
|
|
143
|
+
if (defaultOptions.mode === 'ghost') {
|
|
144
|
+
dragEl.style.opacity = ''
|
|
145
|
+
dragEl.style.transform = ''
|
|
146
|
+
} else {
|
|
147
|
+
dragEl.style.opacity = ''
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function cacheElementPositions(draggedList: DraggableElement[]) {
|
|
152
|
+
POSITION_CACHE.clear()
|
|
153
|
+
draggedList.forEach((el, index) => {
|
|
154
|
+
const rect = el.getBoundingClientRect()
|
|
155
|
+
POSITION_CACHE.set(index, {
|
|
156
|
+
top: rect.top,
|
|
157
|
+
bottom: rect.bottom
|
|
158
|
+
})
|
|
159
|
+
})
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function calculateDropIndex(e: MouseEvent, draggedList: DraggableElement[], dragIndex: number, newDropTarget: DraggableElement) {
|
|
163
|
+
const now = Date.now()
|
|
164
|
+
if (now - lastUpdateTime < UPDATE_THRESHOLD) {
|
|
165
|
+
// Return last calculated index if we're within threshold
|
|
166
|
+
return lastDropIndex !== -1 ? lastDropIndex : dragIndex
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Use cached positions if available, otherwise calculate new ones
|
|
170
|
+
if (POSITION_CACHE.size === 0) {
|
|
171
|
+
cacheElementPositions(draggedList)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const mouseY = e.clientY
|
|
175
|
+
const targetIndex = draggedList.indexOf(newDropTarget)
|
|
176
|
+
const targetPos = POSITION_CACHE.get(targetIndex)
|
|
177
|
+
|
|
178
|
+
if (!targetPos) return dragIndex
|
|
179
|
+
|
|
180
|
+
const elementHeight = targetPos.bottom - targetPos.top
|
|
181
|
+
const relativeY = mouseY - targetPos.top
|
|
182
|
+
|
|
183
|
+
// Calculate sticky zones
|
|
184
|
+
const upperSticky = elementHeight * 0.3
|
|
185
|
+
const lowerSticky = elementHeight * 0.7
|
|
186
|
+
|
|
187
|
+
let dropIndex = targetIndex
|
|
188
|
+
|
|
189
|
+
// Different behavior based on context
|
|
190
|
+
if (targetIndex === dragIndex) {
|
|
191
|
+
// On original element - require significant movement
|
|
192
|
+
if (relativeY > lowerSticky) dropIndex += 1
|
|
193
|
+
} else if (targetIndex === lastDropIndex) {
|
|
194
|
+
// On previously targeted element - use sticky zones
|
|
195
|
+
if (targetIndex > dragIndex) {
|
|
196
|
+
if (relativeY < upperSticky) dropIndex = targetIndex
|
|
197
|
+
else dropIndex = targetIndex + 1
|
|
198
|
+
} else {
|
|
199
|
+
if (relativeY > lowerSticky) dropIndex = targetIndex + 1
|
|
200
|
+
else dropIndex = targetIndex
|
|
201
|
+
}
|
|
202
|
+
} else {
|
|
203
|
+
// On new element - use 60/40 split
|
|
204
|
+
if (relativeY > elementHeight * 0.6) dropIndex += 1
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Update state
|
|
208
|
+
lastDropIndex = dropIndex
|
|
209
|
+
lastUpdateTime = now
|
|
210
|
+
|
|
211
|
+
return dropIndex
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function cleanup() {
|
|
215
|
+
document.removeEventListener('mousemove', onDragMove)
|
|
216
|
+
document.removeEventListener('mouseup', onDragEnd)
|
|
217
|
+
document.removeEventListener('keydown', onKeyDown)
|
|
218
|
+
document.removeEventListener('touchmove', onTouchMove)
|
|
219
|
+
document.removeEventListener('touchend', onTouchEnd)
|
|
220
|
+
document.removeEventListener('touchcancel', onTouchEnd)
|
|
221
|
+
window.removeEventListener('blur', cleanup)
|
|
222
|
+
|
|
223
|
+
// Remove elements with animation
|
|
224
|
+
if (ghostElement.value) {
|
|
225
|
+
ghostElement.value.style.opacity = '0'
|
|
226
|
+
ghostElement.value.style.transform += ' scale(0.8)'
|
|
227
|
+
setTimeout(() => {
|
|
228
|
+
ghostElement.value?.parentNode?.removeChild(ghostElement.value)
|
|
229
|
+
ghostElement.value = null
|
|
230
|
+
}, 150)
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (dropIndicator.value) {
|
|
234
|
+
dropIndicator.value.style.opacity = '0'
|
|
235
|
+
setTimeout(() => {
|
|
236
|
+
dropIndicator.value?.parentNode?.removeChild(dropIndicator.value)
|
|
237
|
+
dropIndicator.value = null
|
|
238
|
+
}, 150)
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Reset all elements
|
|
242
|
+
if (dragElement.value) {
|
|
243
|
+
const list = dragElement.value.__drag_list
|
|
244
|
+
list?.forEach((el) => {
|
|
245
|
+
el.style.transition = ''
|
|
246
|
+
el.style.transform = ''
|
|
247
|
+
el.style.opacity = ''
|
|
248
|
+
})
|
|
249
|
+
dragElement.value.classList.remove(defaultOptions.dragClass!)
|
|
250
|
+
dragElement.value = null
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
isDragging.value = false
|
|
254
|
+
dropTarget.value = null
|
|
255
|
+
document.body.style.userSelect = ''
|
|
256
|
+
document.body.style.webkitUserSelect = ''
|
|
257
|
+
document.body.style.cursor = ''
|
|
258
|
+
|
|
259
|
+
if (scrollRAF) {
|
|
260
|
+
cancelAnimationFrame(scrollRAF)
|
|
261
|
+
scrollRAF = null
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
lastDropIndex = -1
|
|
265
|
+
lastUpdateTime = 0
|
|
266
|
+
POSITION_CACHE.clear()
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function onKeyDown(e: KeyboardEvent) {
|
|
270
|
+
if (e.key === 'Escape' && isDragging.value) {
|
|
271
|
+
cleanup()
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function onDragStart(e: MouseEvent) {
|
|
276
|
+
if (defaultOptions.disabled) return
|
|
277
|
+
if (e.button !== 0) return // Only left mouse button
|
|
278
|
+
if (e.ctrlKey || e.metaKey || e.shiftKey || e.altKey) return
|
|
279
|
+
|
|
280
|
+
const dragEl = findDraggableParent(e.target as Element)
|
|
281
|
+
if (!dragEl || dragEl.dataset.draggable === 'false') return
|
|
282
|
+
|
|
283
|
+
// If handle is specified, check if clicked element matches
|
|
284
|
+
if (defaultOptions.handle) {
|
|
285
|
+
const handleEl = (e.target as Element).closest(defaultOptions.handle)
|
|
286
|
+
if (!handleEl || !dragEl.contains(handleEl)) return
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
e.preventDefault()
|
|
290
|
+
isDragging.value = true
|
|
291
|
+
dragElement.value = dragEl
|
|
292
|
+
|
|
293
|
+
// Store initial positions
|
|
294
|
+
startX = e.clientX
|
|
295
|
+
startY = e.clientY
|
|
296
|
+
const rect = dragEl.getBoundingClientRect()
|
|
297
|
+
initialX = rect.left
|
|
298
|
+
initialY = rect.top
|
|
299
|
+
|
|
300
|
+
// Create ghost element that follows mouse
|
|
301
|
+
ghostElement.value = createGhost(dragEl)
|
|
302
|
+
if (ghostElement.value) {
|
|
303
|
+
ghostElement.value.style.left = `${initialX}px`
|
|
304
|
+
ghostElement.value.style.top = `${initialY}px`
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Only create drop indicator in line mode
|
|
308
|
+
if (defaultOptions.mode === 'line') {
|
|
309
|
+
dropIndicator.value = createDropIndicator(dragEl)
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Apply mode-specific styles and get shift amount
|
|
313
|
+
dragEl.classList.add(defaultOptions.dragClass!)
|
|
314
|
+
shiftAmount = defaultOptions.mode === 'ghost'
|
|
315
|
+
? handleGhostMode(dragEl)
|
|
316
|
+
: handleLineMode(dragEl)
|
|
317
|
+
|
|
318
|
+
defaultOptions.onStart?.(e)
|
|
319
|
+
|
|
320
|
+
// Prevent text selection during drag
|
|
321
|
+
document.body.style.userSelect = 'none'
|
|
322
|
+
document.body.style.webkitUserSelect = 'none'
|
|
323
|
+
|
|
324
|
+
// Add grabbing cursor to body during drag
|
|
325
|
+
document.body.style.cursor = 'grabbing'
|
|
326
|
+
|
|
327
|
+
window.addEventListener('blur', cleanup)
|
|
328
|
+
document.addEventListener('mousemove', onDragMove)
|
|
329
|
+
document.addEventListener('mouseup', onDragEnd)
|
|
330
|
+
document.addEventListener('keydown', onKeyDown)
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function findScrollParent(element: Element): Element {
|
|
334
|
+
let parent = element.parentElement
|
|
335
|
+
while (parent) {
|
|
336
|
+
const { overflow, overflowY } = window.getComputedStyle(parent)
|
|
337
|
+
if (/auto|scroll/.test(overflow + overflowY)) {
|
|
338
|
+
return parent
|
|
339
|
+
}
|
|
340
|
+
parent = parent.parentElement
|
|
341
|
+
}
|
|
342
|
+
return document.scrollingElement || document.documentElement || document.body
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
function autoScroll(e: MouseEvent) {
|
|
346
|
+
if (!dragElement.value) return
|
|
347
|
+
if (scrollRAF) cancelAnimationFrame(scrollRAF)
|
|
348
|
+
|
|
349
|
+
scrollRAF = requestAnimationFrame(() => {
|
|
350
|
+
const scrollParent = findScrollParent(dragElement.value!) as HTMLElement
|
|
351
|
+
const rect = scrollParent.getBoundingClientRect()
|
|
352
|
+
const margin = 50
|
|
353
|
+
const speed = Math.min(20, rect.height * 0.1) // Adjust speed based on container height
|
|
354
|
+
|
|
355
|
+
const { scrollTop } = scrollParent
|
|
356
|
+
const maxScroll = scrollParent.scrollHeight - scrollParent.clientHeight
|
|
357
|
+
|
|
358
|
+
// Use requestAnimationFrame for smoother scrolling
|
|
359
|
+
if (e.clientY - rect.top < margin) {
|
|
360
|
+
const newScroll = Math.max(0, scrollTop - speed)
|
|
361
|
+
scrollParent.scrollTop = newScroll
|
|
362
|
+
} else if (rect.bottom - e.clientY < margin) {
|
|
363
|
+
const newScroll = Math.min(maxScroll, scrollTop + speed)
|
|
364
|
+
scrollParent.scrollTop = newScroll
|
|
365
|
+
}
|
|
366
|
+
})
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
function onDragMove(e: MouseEvent) {
|
|
370
|
+
if (!isDragging.value || !dragElement.value) return
|
|
371
|
+
|
|
372
|
+
// Move ghost element with cursor
|
|
373
|
+
if (ghostElement.value) {
|
|
374
|
+
const dx = e.clientX - startX
|
|
375
|
+
const dy = e.clientY - startY
|
|
376
|
+
ghostElement.value.style.transform = `translate3d(${dx}px, ${dy}px, 0)`
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// Get the draggable list and current positions
|
|
380
|
+
const list = dragElement.value.__drag_list!
|
|
381
|
+
const draggedList = list.filter(el => el.dataset.draggable !== 'false')
|
|
382
|
+
const dragIndex = draggedList.indexOf(dragElement.value)
|
|
383
|
+
|
|
384
|
+
// Find the element at cursor position
|
|
385
|
+
const elementAtPoint = document.elementFromPoint(e.clientX, e.clientY)
|
|
386
|
+
const newDropTarget = findDraggableParent(elementAtPoint)
|
|
387
|
+
|
|
388
|
+
// Validate drop target
|
|
389
|
+
if (!newDropTarget || newDropTarget.__drag_group !== dragElement.value.__drag_group) {
|
|
390
|
+
if (dropIndicator.value) {
|
|
391
|
+
dropIndicator.value.style.display = 'none'
|
|
392
|
+
}
|
|
393
|
+
return
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const dropIndex = calculateDropIndex(e, draggedList, dragIndex, newDropTarget)
|
|
397
|
+
|
|
398
|
+
// Only update if position actually changed
|
|
399
|
+
if (dropTarget.value !== newDropTarget || dropTarget.value.__intended_index !== dropIndex) {
|
|
400
|
+
dropTarget.value = newDropTarget
|
|
401
|
+
dropTarget.value.__intended_index = dropIndex
|
|
402
|
+
|
|
403
|
+
// Update line indicator
|
|
404
|
+
if (dropIndicator.value && defaultOptions.mode === 'line') {
|
|
405
|
+
const isAfter = dropIndex > dragIndex
|
|
406
|
+
updateDropIndicator(newDropTarget, isAfter)
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// Update element positions
|
|
410
|
+
const shift = shiftAmount
|
|
411
|
+
draggedList.forEach((el) => {
|
|
412
|
+
// Use transform3d for better performance
|
|
413
|
+
el.style.transition = `transform ${defaultOptions.animation}ms cubic-bezier(0.2, 0, 0, 1)`
|
|
414
|
+
el.style.transform = 'translate3d(0, 0, 0)'
|
|
415
|
+
|
|
416
|
+
if (el === dragElement.value) {
|
|
417
|
+
if (defaultOptions.mode === 'ghost') {
|
|
418
|
+
const offset = (dropIndex - dragIndex) * shift
|
|
419
|
+
el.style.transform = `translate3d(0, ${offset}px, 0)`
|
|
420
|
+
}
|
|
421
|
+
} else {
|
|
422
|
+
const currentIndex = draggedList.indexOf(el)
|
|
423
|
+
if (dragIndex < dropIndex) {
|
|
424
|
+
if (currentIndex > dragIndex && currentIndex <= dropIndex) {
|
|
425
|
+
el.style.transform = `translate3d(0, -${shift}px, 0)`
|
|
426
|
+
}
|
|
427
|
+
} else if (dragIndex > dropIndex) {
|
|
428
|
+
if (currentIndex >= dropIndex && currentIndex < dragIndex) {
|
|
429
|
+
el.style.transform = `translate3d(0, ${shift}px, 0)`
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
})
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
autoScroll(e)
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
function onDragEnd(e: MouseEvent) {
|
|
440
|
+
if (!isDragging.value || !dragElement.value || !dropTarget.value) {
|
|
441
|
+
cleanup()
|
|
442
|
+
return
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
const list = dragElement.value.__drag_list
|
|
446
|
+
if (!list || !list.length) {
|
|
447
|
+
cleanup()
|
|
448
|
+
return
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
const draggedList = list.filter(el => el.dataset.draggable !== 'false')
|
|
452
|
+
const actualDragIndex = draggedList.indexOf(dragElement.value)
|
|
453
|
+
const actualDropIndex = dropTarget.value.__intended_index!
|
|
454
|
+
|
|
455
|
+
if (actualDragIndex !== -1 && actualDropIndex !== -1) {
|
|
456
|
+
list.forEach((el) => {
|
|
457
|
+
el.style.transition = 'none'
|
|
458
|
+
el.style.transform = ''
|
|
459
|
+
})
|
|
460
|
+
|
|
461
|
+
void document.body.offsetHeight
|
|
462
|
+
|
|
463
|
+
const dragEvent = new MouseEvent('mouseup', e) as DraggableEvent
|
|
464
|
+
dragEvent.oldIndex = actualDragIndex
|
|
465
|
+
dragEvent.newIndex = actualDropIndex
|
|
466
|
+
dragEvent.item = dragElement.value.__drag_data
|
|
467
|
+
|
|
468
|
+
defaultOptions.onEnd?.(dragEvent)
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
cleanup()
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
function onTouchStart(e: TouchEvent) {
|
|
475
|
+
if (defaultOptions.disabled || !e.target) return
|
|
476
|
+
|
|
477
|
+
const touch = e.touches[0]
|
|
478
|
+
if (!touch) return
|
|
479
|
+
|
|
480
|
+
const target = e.target as Element
|
|
481
|
+
const draggableParent = findDraggableParent(target)
|
|
482
|
+
|
|
483
|
+
if (!draggableParent) return
|
|
484
|
+
|
|
485
|
+
const { handle } = defaultOptions
|
|
486
|
+
if (handle && !target.closest(handle)) return
|
|
487
|
+
|
|
488
|
+
e.preventDefault() // Prevent scrolling
|
|
489
|
+
isDragging.value = true
|
|
490
|
+
dragElement.value = draggableParent
|
|
491
|
+
|
|
492
|
+
startX = touch.clientX
|
|
493
|
+
startY = touch.clientY
|
|
494
|
+
const rect = draggableParent.getBoundingClientRect()
|
|
495
|
+
initialX = rect.left
|
|
496
|
+
initialY = rect.top
|
|
497
|
+
|
|
498
|
+
// Rest of the setup same as onDragStart...
|
|
499
|
+
ghostElement.value = createGhost(draggableParent)
|
|
500
|
+
if (ghostElement.value) {
|
|
501
|
+
ghostElement.value.style.left = `${initialX}px`
|
|
502
|
+
ghostElement.value.style.top = `${initialY}px`
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// Only create drop indicator in line mode
|
|
506
|
+
if (defaultOptions.mode === 'line') {
|
|
507
|
+
dropIndicator.value = createDropIndicator(draggableParent)
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// Apply mode-specific styles and get shift amount
|
|
511
|
+
dragElement.value.classList.add(defaultOptions.dragClass!)
|
|
512
|
+
shiftAmount = defaultOptions.mode === 'ghost'
|
|
513
|
+
? handleGhostMode(dragElement.value)
|
|
514
|
+
: handleLineMode(dragElement.value)
|
|
515
|
+
|
|
516
|
+
defaultOptions.onStart?.(e as unknown as MouseEvent)
|
|
517
|
+
|
|
518
|
+
// Prevent text selection during drag
|
|
519
|
+
document.body.style.userSelect = 'none'
|
|
520
|
+
document.body.style.webkitUserSelect = 'none'
|
|
521
|
+
|
|
522
|
+
// Add grabbing cursor to body during drag
|
|
523
|
+
document.body.style.cursor = 'grabbing'
|
|
524
|
+
|
|
525
|
+
window.addEventListener('blur', cleanup)
|
|
526
|
+
document.addEventListener('touchmove', onTouchMove, { passive: false })
|
|
527
|
+
document.addEventListener('touchend', onTouchEnd)
|
|
528
|
+
document.addEventListener('touchcancel', onTouchEnd)
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
function onTouchMove(e: TouchEvent) {
|
|
532
|
+
e.preventDefault() // Prevent scrolling
|
|
533
|
+
const touch = e.touches[0]
|
|
534
|
+
if (!touch) return
|
|
535
|
+
|
|
536
|
+
const mouseEvent = {
|
|
537
|
+
clientX: touch.clientX,
|
|
538
|
+
clientY: touch.clientY,
|
|
539
|
+
target: document.elementFromPoint(touch.clientX, touch.clientY)
|
|
540
|
+
} as MouseEvent
|
|
541
|
+
|
|
542
|
+
onDragMove(mouseEvent)
|
|
543
|
+
autoScroll(mouseEvent)
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
function onTouchEnd(e: TouchEvent) {
|
|
547
|
+
const touch = e.changedTouches[0]
|
|
548
|
+
if (!touch) return
|
|
549
|
+
|
|
550
|
+
const mouseEvent = {
|
|
551
|
+
clientX: touch.clientX,
|
|
552
|
+
clientY: touch.clientY,
|
|
553
|
+
target: document.elementFromPoint(touch.clientX, touch.clientY)
|
|
554
|
+
} as MouseEvent
|
|
555
|
+
|
|
556
|
+
onDragEnd(mouseEvent)
|
|
557
|
+
document.removeEventListener('touchmove', onTouchMove)
|
|
558
|
+
document.removeEventListener('touchend', onTouchEnd)
|
|
559
|
+
document.removeEventListener('touchcancel', onTouchEnd)
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
function initDraggableContainer(container: HTMLElement) {
|
|
563
|
+
cleanupFn?.()
|
|
564
|
+
|
|
565
|
+
// Reset state
|
|
566
|
+
isDragging.value = false
|
|
567
|
+
dragElement.value = null
|
|
568
|
+
ghostElement.value = null
|
|
569
|
+
dropIndicator.value = null
|
|
570
|
+
dropTarget.value = null
|
|
571
|
+
|
|
572
|
+
const elements = Array.from(container.children) as DraggableElement[]
|
|
573
|
+
|
|
574
|
+
elements.forEach((el) => {
|
|
575
|
+
delete el.__drag_group
|
|
576
|
+
delete el.__drag_index
|
|
577
|
+
delete el.__drag_list
|
|
578
|
+
})
|
|
579
|
+
|
|
580
|
+
let currentIndex = 0
|
|
581
|
+
elements.forEach((el, index) => {
|
|
582
|
+
if (el.dataset.draggable !== 'false') {
|
|
583
|
+
el.style.userSelect = 'none'
|
|
584
|
+
el.style.webkitUserSelect = 'none'
|
|
585
|
+
el.__drag_group = options.group
|
|
586
|
+
el.__drag_index = currentIndex++
|
|
587
|
+
el.__drag_list = elements.filter(e => e.dataset.draggable !== 'false')
|
|
588
|
+
|
|
589
|
+
if (options.items) {
|
|
590
|
+
el.__drag_data = options.items[index]
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
el.addEventListener('mousedown', onDragStart)
|
|
594
|
+
el.addEventListener('touchstart', onTouchStart)
|
|
595
|
+
}
|
|
596
|
+
})
|
|
597
|
+
|
|
598
|
+
cleanupFn = () => {
|
|
599
|
+
elements.forEach((el) => {
|
|
600
|
+
el.removeEventListener('mousedown', onDragStart)
|
|
601
|
+
el.removeEventListener('touchstart', onTouchStart)
|
|
602
|
+
delete el.__drag_group
|
|
603
|
+
delete el.__drag_index
|
|
604
|
+
delete el.__drag_list
|
|
605
|
+
})
|
|
606
|
+
cleanup()
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
// Automatically clean up when component is unmounted
|
|
611
|
+
onUnmounted(() => {
|
|
612
|
+
cleanupFn?.()
|
|
613
|
+
})
|
|
614
|
+
|
|
615
|
+
return {
|
|
616
|
+
isDragging,
|
|
617
|
+
dragElement,
|
|
618
|
+
initDraggableContainer
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
// Simplified default styles
|
|
623
|
+
const style = document.createElement('style')
|
|
624
|
+
style.textContent = `
|
|
625
|
+
.draggable-ghost {
|
|
626
|
+
opacity: 0.5;
|
|
627
|
+
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
|
628
|
+
transition: transform 0.1s;
|
|
629
|
+
|
|
630
|
+
}
|
|
631
|
+
`
|
|
632
|
+
document.head.appendChild(style)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Directive } from 'vue'
|
|
2
|
+
import type { DraggableOptions } from './useDraggable'
|
|
3
|
+
import { useDraggable } from './useDraggable'
|
|
4
|
+
|
|
5
|
+
export const vDraggable: Directive<HTMLElement, DraggableOptions> = {
|
|
6
|
+
mounted(el, binding) {
|
|
7
|
+
const { initDraggableContainer } = useDraggable(binding.value || {})
|
|
8
|
+
initDraggableContainer(el)
|
|
9
|
+
},
|
|
10
|
+
updated(el, binding) {
|
|
11
|
+
// Only reinitialize if options changed
|
|
12
|
+
if (binding.value !== binding.oldValue) {
|
|
13
|
+
const { initDraggableContainer } = useDraggable(binding.value || {})
|
|
14
|
+
initDraggableContainer(el)
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
<script lang="ts" setup
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { useSlots } from 'vue'
|
|
3
|
+
|
|
4
|
+
const slots = useSlots()
|
|
5
|
+
</script>
|
|
2
6
|
|
|
3
7
|
<template>
|
|
4
8
|
<div class="list-wrap bgl_card thin grid overflow-hidden h-100 pt-0 pb-05 px-0 m_pb-0">
|
|
5
|
-
<div class="p-1">
|
|
9
|
+
<div v-if="slots.header" class="p-1">
|
|
6
10
|
<slot name="header" />
|
|
7
11
|
</div>
|
|
8
12
|
<div class="list-content auto-flow-rows align-items-start overflow-y h-100">
|
package/src/components/Pill.vue
CHANGED
|
@@ -92,7 +92,7 @@ const computedBackgroundColor = $computed(
|
|
|
92
92
|
</div>
|
|
93
93
|
<Icon v-if="icon" :icon="icon" />
|
|
94
94
|
<slot />
|
|
95
|
-
<template v-if="!slots.default
|
|
95
|
+
<template v-if="!slots.default">
|
|
96
96
|
{{ value || modelValue }}
|
|
97
97
|
</template>
|
|
98
98
|
<Icon v-if="iconEnd" :icon="iconEnd" />
|