Drag-and-drop waypoint reordering in sidebar list
This commit is contained in:
+49
-2
@@ -391,6 +391,40 @@
|
||||
fetchRoute();
|
||||
}
|
||||
|
||||
let dragSrcIdx = $state(null);
|
||||
let dragOverIdx = $state(null);
|
||||
|
||||
function onDragStart(e, i) {
|
||||
dragSrcIdx = i;
|
||||
e.dataTransfer.effectAllowed = 'move';
|
||||
e.dataTransfer.setData('text/plain', i);
|
||||
}
|
||||
|
||||
function onDragOver(e, i) {
|
||||
e.preventDefault();
|
||||
e.dataTransfer.dropEffect = 'move';
|
||||
dragOverIdx = i;
|
||||
}
|
||||
|
||||
function onDrop(e, i) {
|
||||
e.preventDefault();
|
||||
if (dragSrcIdx === null || dragSrcIdx === i) { dragSrcIdx = null; dragOverIdx = null; return; }
|
||||
const arr = [...waypoints];
|
||||
const [moved] = arr.splice(dragSrcIdx, 1);
|
||||
arr.splice(i, 0, moved);
|
||||
waypoints = arr;
|
||||
waypoints.forEach((wp, idx) => { wp.marker.getElement().textContent = idx + 1; });
|
||||
activePlanId = null;
|
||||
fetchRoute();
|
||||
dragSrcIdx = null;
|
||||
dragOverIdx = null;
|
||||
}
|
||||
|
||||
function onDragEnd() {
|
||||
dragSrcIdx = null;
|
||||
dragOverIdx = null;
|
||||
}
|
||||
|
||||
function removeWaypoint(i) {
|
||||
waypoints[i].marker.remove();
|
||||
waypoints = waypoints.filter((_, idx) => idx !== i);
|
||||
@@ -1094,7 +1128,16 @@ ${trkpts}
|
||||
{:else}
|
||||
<ul class="wp-list">
|
||||
{#each waypoints as wp, i}
|
||||
<li>
|
||||
<li
|
||||
draggable="true"
|
||||
class:wp-drag-over={dragOverIdx === i && dragSrcIdx !== i}
|
||||
class:wp-dragging={dragSrcIdx === i}
|
||||
ondragstart={(e) => onDragStart(e, i)}
|
||||
ondragover={(e) => onDragOver(e, i)}
|
||||
ondrop={(e) => onDrop(e, i)}
|
||||
ondragend={onDragEnd}
|
||||
>
|
||||
<span class="wp-drag-handle" title="Drag to reorder">⠿</span>
|
||||
<span class="wp-num" style={wp.gpxSnapped ? `background:${gpxColor}` : ''}>{i + 1}</span>
|
||||
<span class="wp-coord">{wp.lat.toFixed(4)}, {wp.lng.toFixed(4)}</span>
|
||||
{#if waypoints.length > 1}
|
||||
@@ -1463,7 +1506,11 @@ ${trkpts}
|
||||
.pill.active { background: var(--accent-dim); border-color: var(--accent); color: var(--accent); }
|
||||
|
||||
.wp-list { list-style: none; margin: 0 0 0.5rem; padding: 0; display: flex; flex-direction: column; gap: 0.25rem; }
|
||||
.wp-list li { display: flex; align-items: center; gap: 0.375rem; font-size: 0.75rem; }
|
||||
.wp-list li { display: flex; align-items: center; gap: 0.375rem; font-size: 0.75rem; cursor: grab; border-radius: 0.25rem; transition: background 0.1s, opacity 0.1s; }
|
||||
.wp-list li:active { cursor: grabbing; }
|
||||
.wp-dragging { opacity: 0.4; }
|
||||
.wp-drag-over { background: var(--accent-dim); outline: 1px dashed var(--accent); }
|
||||
.wp-drag-handle { color: var(--text-5); font-size: 0.75rem; cursor: grab; flex-shrink: 0; user-select: none; }
|
||||
.wp-num { width: 1.25rem; height: 1.25rem; border-radius: 50%; background: var(--accent); color: #000; font-size: 0.65rem; font-weight: 700; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
|
||||
.wp-coord { flex: 1; color: var(--text-4); font-variant-numeric: tabular-nums; }
|
||||
.remove-btn { background: none; border: none; color: var(--text-5); cursor: pointer; font-size: 1rem; line-height: 1; padding: 0 0.125rem; }
|
||||
|
||||
Reference in New Issue
Block a user