Skip to content

Commit f6059be

Browse files
removes double raf in place of storing necessary data before reset state takes place
1 parent bfeb431 commit f6059be

File tree

1 file changed

+54
-46
lines changed

1 file changed

+54
-46
lines changed

src/index.ts

Lines changed: 54 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1856,76 +1856,84 @@ export function handlePointercancel<T>(
18561856
export function handleEnd<T>(state: DragState<T> | SynthDragState<T>) {
18571857
if (state.draggedNode) state.draggedNode.el.draggable = true;
18581858

1859-
if (isSynthDragState(state)) {
1860-
state.clonedDraggedNode.remove();
1859+
// --- Capture necessary data BEFORE resetState might affect it ---
1860+
const nodesToClean = state.draggedNodes.map((x) => x.el);
1861+
const initialParentData = state.initialParent.data;
1862+
const isSynth = isSynthDragState(state);
1863+
const config = parents.get(state.initialParent.el)?.config;
1864+
const dropZoneClass = isSynth
1865+
? config?.synthDropZoneClass
1866+
: config?.dropZoneClass;
1867+
const longPressClass = initialParentData?.config?.longPressClass;
1868+
const placeholderClass = isSynth
1869+
? initialParentData?.config?.synthDragPlaceholderClass // Corrected potential typo: used initialParentData
1870+
: initialParentData?.config?.dragPlaceholderClass;
1871+
const originalZIndex = state.originalZIndex;
1872+
// --- End data capture ---
18611873

1862-
clearTimeout(state.longPressTimeout);
1874+
if (isSynthDragState(state)) {
1875+
// Ensure cloned node removal happens reasonably quickly
1876+
if (state.clonedDraggedNode) {
1877+
// Check if it exists
1878+
state.clonedDraggedNode.remove();
1879+
}
1880+
if (state.longPressTimeout) {
1881+
// Check if timeout exists
1882+
clearTimeout(state.longPressTimeout);
1883+
}
18631884
}
18641885

1865-
// Ensure scrolling is properly cancelled
1886+
// Ensure scrolling is properly cancelled (needs state, do before reset)
18661887
cancelSynthScroll(state);
18671888

1868-
// Clear any lingering scroll directions and timeouts
1889+
// Clear any lingering scroll directions and timeouts (needs state, do before reset)
18691890
state.lastScrollDirectionX = undefined;
18701891
state.lastScrollDirectionY = undefined;
18711892
state.preventEnter = false;
1872-
1873-
// CRITICAL: Clear the scroll debounce timeout
18741893
if (state.scrollDebounceTimeout) {
18751894
clearTimeout(state.scrollDebounceTimeout);
1876-
state.scrollDebounceTimeout = undefined;
1895+
state.scrollDebounceTimeout = undefined; // Ensure it's marked as cleared
18771896
}
18781897

1879-
const config = parents.get(state.initialParent.el)?.config;
1880-
1881-
const isSynth = isSynthDragState(state);
1882-
1883-
const dropZoneClass = isSynth
1884-
? config?.synthDropZoneClass
1885-
: config?.dropZoneClass;
1886-
1887-
if (state.originalZIndex !== undefined) {
1888-
state.draggedNode.el.style.zIndex = state.originalZIndex;
1898+
// Apply z-index change synchronously if needed
1899+
if (originalZIndex !== undefined && state.draggedNode) {
1900+
state.draggedNode.el.style.zIndex = originalZIndex;
18891901
}
18901902

1903+
// Use single rAF with captured data for class removal
18911904
requestAnimationFrame(() => {
1892-
requestAnimationFrame(() => {
1893-
removeClass(
1894-
state.draggedNodes.map((x) => x.el),
1895-
dropZoneClass
1896-
);
1897-
1898-
removeClass(
1899-
state.draggedNodes.map((x) => x.el),
1900-
state.initialParent.data?.config?.longPressClass
1901-
);
1902-
1903-
removeClass(
1904-
state.draggedNodes.map((x) => x.el),
1905-
isSynth
1906-
? state.initialParent.data.config.synthDragPlaceholderClass
1907-
: state.initialParent.data?.config?.dragPlaceholderClass
1908-
);
1909-
});
1905+
// Use the captured data, not the potentially reset global state
1906+
removeClass(nodesToClean, dropZoneClass);
1907+
removeClass(nodesToClean, longPressClass);
1908+
removeClass(nodesToClean, placeholderClass);
19101909
});
19111910

1911+
// Deselect and reset active state (needs state, do before reset)
19121912
deselect(state.draggedNodes, state.currentParent, state);
1913-
19141913
setActive(state.currentParent, undefined, state);
19151914

1916-
resetState();
1917-
1918-
state.selectedState = undefined;
1915+
// Prepare data for callback/event *before* resetState
1916+
const finalStateForCallback = { ...state }; // Shallow copy for safety
19191917

1918+
// Call onDragend callback *before* resetState
19201919
config?.onDragend?.({
1921-
parent: state.currentParent,
1922-
values: parentValues(state.currentParent.el, state.currentParent.data),
1923-
draggedNode: state.draggedNode,
1924-
draggedNodes: state.draggedNodes,
1925-
state,
1920+
parent: finalStateForCallback.currentParent,
1921+
values: parentValues(
1922+
finalStateForCallback.currentParent.el,
1923+
finalStateForCallback.currentParent.data
1924+
),
1925+
draggedNode: finalStateForCallback.draggedNode,
1926+
draggedNodes: finalStateForCallback.draggedNodes,
1927+
state: finalStateForCallback,
19261928
});
19271929

1928-
state.emit("dragEnded", state);
1930+
// Emit event *before* resetState
1931+
state.emit("dragEnded", finalStateForCallback); // Emit with the final state representation
1932+
1933+
// Reset global state LAST
1934+
resetState();
1935+
1936+
// No need to set state.selectedState = undefined; resetState handles it.
19291937
}
19301938

19311939
/**

0 commit comments

Comments
 (0)