Skip to content

Commit 753589e

Browse files
committed
refac
1 parent 3dea69f commit 753589e

1 file changed

Lines changed: 21 additions & 18 deletions

File tree

src/lib/components/admin/Settings/Models/ModelList.svelte

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script lang="ts">
22
import Sortable from 'sortablejs';
33
4-
import { createEventDispatcher, getContext, onDestroy, onMount, tick } from 'svelte';
4+
import { createEventDispatcher, getContext, onMount, onDestroy, tick } from 'svelte';
55
const i18n = getContext('i18n');
66
77
import { models } from '$lib/stores';
@@ -13,22 +13,20 @@
1313
let sortable = null;
1414
let modelListElement = null;
1515
16-
const positionChangeHandler = () => {
17-
// Read new order from DOM
18-
const newOrder = Array.from(modelListElement.children).map((child) =>
19-
child.id.replace('model-item-', '')
20-
);
16+
const positionChangeHandler = (event) => {
17+
const { oldIndex, newIndex, item } = event;
2118
22-
// Revert SortableJS DOM manipulation so Svelte stays in control of the DOM
23-
if (sortable) {
24-
sortable.sort(
25-
modelIds.map((id) => `model-item-${id}`),
26-
true
27-
);
28-
}
19+
// Revert SortableJS's DOM manipulation so Svelte doesn't get out of sync.
20+
// Svelte expects the DOM to match its virtual DOM before it applies state updates.
21+
const parent = item.parentNode;
22+
const target = parent.children[oldIndex < newIndex ? oldIndex : oldIndex + 1];
23+
parent.insertBefore(item, target);
2924
30-
// Update reactive data — Svelte will re-render with the new order
31-
modelIds = newOrder;
25+
// Now apply the logical state update, letting Svelte handle the real DOM move.
26+
const updatedIds = [...modelIds];
27+
const [movedId] = updatedIds.splice(oldIndex, 1);
28+
updatedIds.splice(newIndex, 0, movedId);
29+
modelIds = updatedIds;
3230
};
3331
3432
const initSortable = () => {
@@ -41,15 +39,20 @@
4139
sortable = new Sortable(modelListElement, {
4240
animation: 150,
4341
handle: '.model-item-handle',
44-
onUpdate: async (event) => {
45-
positionChangeHandler();
42+
onUpdate: (event) => {
43+
positionChangeHandler(event);
4644
}
4745
});
4846
}
4947
};
5048
49+
$: if (modelIds && modelListElement) {
50+
tick().then(() => {
51+
initSortable();
52+
});
53+
}
54+
5155
onMount(() => {
52-
// Wait a tick for the {#if} block to render and bind modelListElement
5356
tick().then(() => {
5457
initSortable();
5558
});

0 commit comments

Comments
 (0)