better drag & drop experience
This commit is contained in:
parent
8338657bad
commit
06edcf7dd1
|
|
@ -59,6 +59,7 @@ function noteApp() {
|
||||||
expandedFolders: new Set(),
|
expandedFolders: new Set(),
|
||||||
draggedNote: null,
|
draggedNote: null,
|
||||||
draggedFolder: null,
|
draggedFolder: null,
|
||||||
|
dragOverFolder: null, // Track which folder is being hovered during drag
|
||||||
|
|
||||||
// Scroll sync state
|
// Scroll sync state
|
||||||
isScrolling: false,
|
isScrolling: false,
|
||||||
|
|
@ -441,15 +442,25 @@ function noteApp() {
|
||||||
<div
|
<div
|
||||||
draggable="true"
|
draggable="true"
|
||||||
x-data="{}"
|
x-data="{}"
|
||||||
@dragstart="onFolderDragStart('${folder.path.replace(/'/g, "\\'")}' )"
|
@dragstart="onFolderDragStart('${folder.path.replace(/'/g, "\\'")}', $event)"
|
||||||
@dragend="onFolderDragEnd()"
|
@dragend="onFolderDragEnd()"
|
||||||
@dragover.prevent
|
@dragover.prevent="dragOverFolder = '${folder.path.replace(/'/g, "\\'")}'"
|
||||||
@drop.stop="onFolderDrop('${folder.path.replace(/'/g, "\\'")}')"
|
@dragenter.prevent="dragOverFolder = '${folder.path.replace(/'/g, "\\'")}'"
|
||||||
class="folder-item px-2 py-2 mb-1 text-sm rounded transition-all relative"
|
@dragleave="dragOverFolder = null"
|
||||||
|
@drop.stop="onFolderDrop('${folder.path.replace(/'/g, "\\'")}' )"
|
||||||
|
class="folder-item px-3 py-3 mb-1 text-sm rounded transition-all relative"
|
||||||
style="color: var(--text-primary); cursor: pointer;"
|
style="color: var(--text-primary); cursor: pointer;"
|
||||||
:class="draggedNote || draggedFolder ? 'border-2 border-dashed border-accent-primary bg-accent-light' : 'border-2 border-transparent'"
|
:class="{
|
||||||
|
'border-2 border-dashed bg-accent-light': (draggedNote || draggedFolder) && dragOverFolder === '${folder.path.replace(/'/g, "\\'")}',
|
||||||
|
'border-2 border-dashed': (draggedNote || draggedFolder) && dragOverFolder !== '${folder.path.replace(/'/g, "\\'")}',
|
||||||
|
'border-2 border-transparent': !draggedNote && !draggedFolder
|
||||||
|
}"
|
||||||
|
:style="{
|
||||||
|
'border-color': (draggedNote || draggedFolder) && dragOverFolder === '${folder.path.replace(/'/g, "\\'")}' ? 'var(--accent-primary)' : 'var(--border-secondary)',
|
||||||
|
'background-color': dragOverFolder === '${folder.path.replace(/'/g, "\\'")}' ? 'var(--accent-light)' : ''
|
||||||
|
}"
|
||||||
@mouseover="if(!draggedNote && !draggedFolder) $el.style.backgroundColor='var(--bg-hover)'"
|
@mouseover="if(!draggedNote && !draggedFolder) $el.style.backgroundColor='var(--bg-hover)'"
|
||||||
@mouseout="if(!draggedNote && !draggedFolder) $el.style.backgroundColor='transparent'"
|
@mouseout="if(!draggedNote && !draggedFolder && dragOverFolder !== '${folder.path.replace(/'/g, "\\'")}' ) $el.style.backgroundColor='transparent'"
|
||||||
@click="toggleFolder('${folder.path.replace(/'/g, "\\'")}')"
|
@click="toggleFolder('${folder.path.replace(/'/g, "\\'")}')"
|
||||||
>
|
>
|
||||||
<div class="flex items-center gap-1">
|
<div class="flex items-center gap-1">
|
||||||
|
|
@ -665,12 +676,21 @@ function noteApp() {
|
||||||
// Move mode: drag to move note
|
// Move mode: drag to move note
|
||||||
this.draggedNote = notePath;
|
this.draggedNote = notePath;
|
||||||
event.dataTransfer.effectAllowed = 'move';
|
event.dataTransfer.effectAllowed = 'move';
|
||||||
|
// Make drag image semi-transparent
|
||||||
|
if (event.target) {
|
||||||
|
event.target.style.opacity = '0.5';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onNoteDragEnd() {
|
onNoteDragEnd() {
|
||||||
this.draggedNote = null;
|
this.draggedNote = null;
|
||||||
this.draggedNoteForLink = null;
|
this.draggedNoteForLink = null;
|
||||||
|
this.dragOverFolder = null;
|
||||||
|
// Reset opacity of all note items
|
||||||
|
document.querySelectorAll('.note-item').forEach(el => {
|
||||||
|
el.style.opacity = '1';
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// Handle dragover on editor to show cursor position
|
// Handle dragover on editor to show cursor position
|
||||||
|
|
@ -776,12 +796,21 @@ function noteApp() {
|
||||||
},
|
},
|
||||||
|
|
||||||
// Folder drag handlers
|
// Folder drag handlers
|
||||||
onFolderDragStart(folderPath) {
|
onFolderDragStart(folderPath, event) {
|
||||||
this.draggedFolder = folderPath;
|
this.draggedFolder = folderPath;
|
||||||
|
// Make drag image semi-transparent
|
||||||
|
if (event && event.target) {
|
||||||
|
event.target.style.opacity = '0.5';
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onFolderDragEnd() {
|
onFolderDragEnd() {
|
||||||
this.draggedFolder = null;
|
this.draggedFolder = null;
|
||||||
|
this.dragOverFolder = null;
|
||||||
|
// Reset opacity of all folder items
|
||||||
|
document.querySelectorAll('.folder-item').forEach(el => {
|
||||||
|
el.style.opacity = '1';
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
async onFolderDrop(targetFolderPath) {
|
async onFolderDrop(targetFolderPath) {
|
||||||
|
|
|
||||||
|
|
@ -350,6 +350,7 @@
|
||||||
/* Folder tree styling */
|
/* Folder tree styling */
|
||||||
.folder-item {
|
.folder-item {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
transition: all 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.folder-item:hover {
|
.folder-item:hover {
|
||||||
|
|
@ -362,6 +363,29 @@
|
||||||
|
|
||||||
.note-item {
|
.note-item {
|
||||||
padding-left: 1.5rem;
|
padding-left: 1.5rem;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Drag and drop improvements */
|
||||||
|
.note-item[draggable="true"],
|
||||||
|
.folder-item[draggable="true"] {
|
||||||
|
cursor: grab;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-item[draggable="true"]:active,
|
||||||
|
.folder-item[draggable="true"]:active {
|
||||||
|
cursor: grabbing;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Smooth transitions for drag states */
|
||||||
|
.folder-item,
|
||||||
|
.note-item {
|
||||||
|
transition: opacity 0.2s ease, transform 0.15s ease, background-color 0.15s ease, border-color 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Better drop zone visibility */
|
||||||
|
.folder-item:has(+ .folder-contents) {
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hover-buttons {
|
.hover-buttons {
|
||||||
|
|
@ -893,13 +917,19 @@
|
||||||
<!-- Root drop zone - only visible when dragging -->
|
<!-- Root drop zone - only visible when dragging -->
|
||||||
<div
|
<div
|
||||||
x-show="draggedNote || draggedFolder"
|
x-show="draggedNote || draggedFolder"
|
||||||
@dragover.prevent
|
x-transition
|
||||||
|
@dragover.prevent="dragOverFolder = '';"
|
||||||
|
@dragenter.prevent="dragOverFolder = '';"
|
||||||
|
@dragleave="dragOverFolder = null;"
|
||||||
@drop="onFolderDrop('')"
|
@drop="onFolderDrop('')"
|
||||||
class="mb-3 px-3 py-2 rounded-lg border-2 border-dashed transition-all"
|
class="mb-3 px-4 py-3 rounded-lg border-2 border-dashed transition-all"
|
||||||
style="border-color: var(--accent-primary); background-color: var(--accent-light);"
|
:class="dragOverFolder === '' ? 'bg-accent-light' : ''"
|
||||||
|
:style="dragOverFolder === '' ? 'border-color: var(--accent-primary); transform: scale(1.02);' : 'border-color: var(--border-primary);'"
|
||||||
>
|
>
|
||||||
<div class="text-xs text-center font-medium" style="color: var(--accent-primary);">
|
<div class="text-sm text-center font-medium flex items-center justify-center gap-2"
|
||||||
📂 Drop here to move to root folder
|
:style="dragOverFolder === '' ? 'color: var(--accent-primary);' : 'color: var(--text-secondary);'">
|
||||||
|
<span>📂</span>
|
||||||
|
<span>Drop here to move to root folder</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue