Skip to content

Commit de3330c

Browse files
committed
fix: fix edge resize snap, snap-back on release, and core block handles (#100)
1 parent d4ad1cf commit de3330c

3 files changed

Lines changed: 58 additions & 3 deletions

File tree

src/app/components/project/CustomNodeResizer.tsx

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { memo, useCallback, useMemo, useRef } from "react";
44
import {
55
NodeResizer,
66
NodeResizerProps,
7+
NodeResizeControl,
78
useViewport,
89
useStore,
910
useNodeId,
@@ -249,12 +250,11 @@ const CustomNodeResizer = memo((props: NodeResizerProps) => {
249250
(event, params) => {
250251
resizeStateRef.current = null;
251252
helperLinesCtxRef.current?.setHelperLines([]);
252-
helperLinesCtxRef.current?.setActiveResizeSnap(null);
253253

254254
const node = resizingNodeRef.current;
255255
const fallbackParams: ResizeParams | undefined =
256-
params ??
257256
lastResizeParamsRef.current ??
257+
params ??
258258
(node
259259
? {
260260
x: node.position.x,
@@ -347,6 +347,7 @@ const CustomNodeResizer = memo((props: NodeResizerProps) => {
347347
y: corrected.y,
348348
width: corrected.width,
349349
height: corrected.height,
350+
handle: currentHandle,
350351
}
351352
: null,
352353
);
@@ -366,6 +367,42 @@ const CustomNodeResizer = memo((props: NodeResizerProps) => {
366367
return null;
367368
}
368369

370+
const isCore = resizingNode?.type === "core";
371+
372+
const coreHandleStyle = useMemo(
373+
() =>
374+
({
375+
background: "transparent",
376+
backgroundColor: "transparent",
377+
border: "none",
378+
boxShadow: "none",
379+
width: `${hitboxSize}px`,
380+
height: `${hitboxSize}px`,
381+
"--hitbox-size": `${hitboxSize}px`,
382+
pointerEvents: "auto",
383+
}) as React.CSSProperties,
384+
[hitboxSize],
385+
);
386+
387+
if (isCore) {
388+
return (
389+
<NodeResizeControl
390+
position="bottom-right"
391+
className={`${styles.handle} ${props.handleClassName || ""}`}
392+
style={coreHandleStyle}
393+
minWidth={props.minWidth}
394+
minHeight={props.minHeight}
395+
maxWidth={props.maxWidth}
396+
maxHeight={props.maxHeight}
397+
keepAspectRatio={props.keepAspectRatio}
398+
shouldResize={shouldResize}
399+
onResizeStart={onResizeStart}
400+
onResize={onResize}
401+
onResizeEnd={onResizeEnd}
402+
/>
403+
);
404+
}
405+
369406
return (
370407
<NodeResizer
371408
{...props}

src/app/components/project/HelperLinesContext.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export interface ActiveResizeSnap {
99
y: number;
1010
width: number;
1111
height: number;
12+
handle: string;
1213
}
1314

1415
interface HelperLinesContextValue {

src/app/components/project/hooks/useProjectCanvasGraph.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,17 +385,34 @@ export const useProjectCanvasGraph = ({
385385
});
386386

387387
const snap = activeResizeSnapRef.current;
388+
const snapMovesX =
389+
snap !== null &&
390+
(snap.handle === "left" ||
391+
snap.handle === "top-left" ||
392+
snap.handle === "bottom-left");
393+
const snapMovesY =
394+
snap !== null &&
395+
(snap.handle === "top" ||
396+
snap.handle === "top-left" ||
397+
snap.handle === "top-right");
388398
const resolvedChanges = snap
389399
? filteredChanges.map((c) => {
390400
if (!("id" in c) || c.id !== snap.id) return c;
391401
if (c.type === "dimensions" && c.dimensions) {
402+
if (c.resizing === false) activeResizeSnapRef.current = null;
392403
return {
393404
...c,
394405
dimensions: { width: snap.width, height: snap.height },
395406
};
396407
}
397408
if (c.type === "position" && c.position) {
398-
return { ...c, position: { x: snap.x, y: snap.y } };
409+
return {
410+
...c,
411+
position: {
412+
x: snapMovesX ? snap.x : c.position.x,
413+
y: snapMovesY ? snap.y : c.position.y,
414+
},
415+
};
399416
}
400417
return c;
401418
})

0 commit comments

Comments
 (0)