feat: reorderable list now working

This commit is contained in:
2026-08-31 16:59:25 +02:00
parent 4753d998b3
commit eead8b558a
+15 -7
View File
@@ -5,7 +5,7 @@
useTemplateRef useTemplateRef
} from 'vue'; } from 'vue';
const queue = defineModel<T[]>( { const array = defineModel<T[]>( {
'required': true 'required': true
} ); } );
@@ -68,7 +68,7 @@
// Determine current index to insert // Determine current index to insert
const percentage = ( relToContainer + scrollContainer.value!.scrollTop ) / scrollContainer.value!.scrollHeight; const percentage = ( relToContainer + scrollContainer.value!.scrollTop ) / scrollContainer.value!.scrollHeight;
const newIdx = Math.min( Math.max( Math.round( percentage * queue.value.length ), 0 ), queue.value.length - 1 ); const newIdx = Math.min( Math.max( Math.round( percentage * array.value.length ), 0 ), array.value.length - 1 );
if ( newIdx !== movingIdx.value ) if ( newIdx !== movingIdx.value )
movingCurrentIdx.value = newIdx; movingCurrentIdx.value = newIdx;
@@ -86,20 +86,28 @@
const end = () => { const end = () => {
offset.value = -1; offset.value = -1;
movingIdx.value = -1;
// TODO: Actually do the move
try { try {
clearInterval( mover ); clearInterval( mover );
mover = -1; mover = -1;
} catch { /* empty */ } } catch { /* empty */ }
const before = array.value.slice( 0, movingIdx.value );
const after = array.value.slice( movingIdx.value + 1 );
const el = array.value[ movingIdx.value ]!;
const arr = before.concat( after );
arr.splice( movingCurrentIdx.value, 0, el );
array.value = arr;
movingIdx.value = -1;
movingCurrentIdx.value = -1;
emit( 'dropped' ); emit( 'dropped' );
}; };
const style = computed( () => { const style = computed( () => {
return ( index: number ) => { return ( index: number ) => {
if ( movingIdx.value === queue.value.length - 1 && movingIdx.value === index + 1 if ( movingIdx.value === array.value.length - 1 && movingIdx.value === index + 1
&& movingCurrentIdx.value === movingIdx.value ) && movingCurrentIdx.value === movingIdx.value )
return `margin-bottom: ${ movableSize.value }px;`; return `margin-bottom: ${ movableSize.value }px;`;
@@ -109,7 +117,7 @@
return `top: ${ offset.value }px;`; return `top: ${ offset.value }px;`;
} else { } else {
// Current item is not moved // Current item is not moved
if ( movingCurrentIdx.value === queue.value.length - 1 && index === movingCurrentIdx.value ) { if ( movingCurrentIdx.value === array.value.length - 1 && index === movingCurrentIdx.value ) {
// Create gap below // Create gap below
return `margin-bottom: ${ movableSize.value }px;`; return `margin-bottom: ${ movableSize.value }px;`;
} else if ( movingCurrentIdx.value === index } else if ( movingCurrentIdx.value === index
@@ -136,7 +144,7 @@
> >
</div> </div>
<div <div
v-for="(item, index) in queue" v-for="(item, index) in array"
:id="'movable-' + index" :id="'movable-' + index"
:key="index" :key="index"
:class="[ 'movable', movingIdx === index ? 'moving' : undefined ]" :class="[ 'movable', movingIdx === index ? 'moving' : undefined ]"