Fix bugs with creating component by DnD to canvas (#1510)

## Description

https://discord.com/channels/955905230107738152/1098959267396059228

There were two bugs:

1. Same as in
https://github.com/webstudio-is/webstudio-builder/pull/1483 setState
didn't work correctly after React update
2. Scrub used to call `onStatusChange("idle")` at unmount (now fixed).
We use scrub for canvas resize, and restore pointer events when status
changes to "idle". But we also unmount scrub on DnD start. So on DnD
start we ended up with pointer events turned on.

## Steps for reproduction

1. DnD of components to canvas should work well now
This commit is contained in:
Roman Pominov authored and GitHub committed 2023-04-21 18:03:58 +03:00
1 parent 885fa38885
commit a74dbe06d3
2 files changed
+14 -5

No files matched your search

@@ -2,20 +2,20 @@ import { useSubscribe } from "~/shared/pubsub";
import { useDragAndDropState } from "~/shared/nano-states";
export const useSubscribeDragAndDropState = () => {
const [state, setState] = useDragAndDropState();
const [, setState] = useDragAndDropState();
useSubscribe("dragStart", (dragPayload) => {
// It's possible that dropTargetChange comes before dragStart.
// So it's important to spread the current ...state here.
setState({ ...state, isDragging: true, dragPayload });
setState((state) => ({ ...state, isDragging: true, dragPayload }));
});
useSubscribe("dropTargetChange", (dropTarget) => {
setState({ ...state, dropTarget });
setState((state) => ({ ...state, dropTarget }));
});
useSubscribe("placementIndicatorChange", (placementIndicator) => {
setState({ ...state, placementIndicator });
setState((state) => ({ ...state, placementIndicator }));
});
useSubscribe("dragEnd", () => {
@@ -46,6 +46,7 @@ type NumericScrubState = {
cursor?: SVGElement;
direction: string;
timerId?: ReturnType<typeof window.setTimeout>;
status: "idle" | "scrubbing";
};
const getValueDefault = (
@@ -86,6 +87,7 @@ export const numericScrubControl = (
cursor: undefined,
direction: direction,
timerId: undefined,
status: "idle",
};
let exitPointerLock: (() => void) | undefined = undefined;
@@ -94,7 +96,12 @@ export const numericScrubControl = (
const cleanup = () => {
targetNode.removeEventListener("pointermove", handleEvent);
onStatusChange?.("idle");
if (state.status === "scrubbing") {
state.status = "idle";
onStatusChange?.("idle");
}
clearTimeout(state.timerId);
exitPointerLock?.();
@@ -162,7 +169,9 @@ export const numericScrubControl = (
exitPointerLock = requestPointerLock(state, event, targetNode);
}, 150);
state.status = "scrubbing";
onStatusChange?.("scrubbing");
targetNode.addEventListener("pointermove", handleEvent);
originalUserSelect =
targetNode.ownerDocument.documentElement.style.userSelect;