From ec3ef27c90f99637f8928f6c9f1eb491a35558f0 Mon Sep 17 00:00:00 2001 From: moklick Date: Wed, 11 Jun 2025 09:59:49 +0200 Subject: [PATCH] chore(resizer): cleanup and add scaleControls --- .../NodeResizer/BottomRightResizer.tsx | 2 ++ .../NodeResizer/NodeResizeControl.tsx | 33 +++++++++++-------- .../NodeResizer/NodeResizer.tsx | 3 ++ .../NodeResizer/types.ts | 6 ++++ 4 files changed, 30 insertions(+), 14 deletions(-) diff --git a/examples/react/src/examples/NodeResizer/BottomRightResizer.tsx b/examples/react/src/examples/NodeResizer/BottomRightResizer.tsx index ca860fdf..9809ef61 100644 --- a/examples/react/src/examples/NodeResizer/BottomRightResizer.tsx +++ b/examples/react/src/examples/NodeResizer/BottomRightResizer.tsx @@ -10,6 +10,8 @@ const CustomResizerNode: FC = ({ data }) => { resizeDirection="horizontal" minWidth={100} maxWidth={500} + color="orange" + scaleControls />
{data.label}
diff --git a/packages/react/src/additional-components/NodeResizer/NodeResizeControl.tsx b/packages/react/src/additional-components/NodeResizer/NodeResizeControl.tsx index fc758d8d..1bd1f3d3 100644 --- a/packages/react/src/additional-components/NodeResizer/NodeResizeControl.tsx +++ b/packages/react/src/additional-components/NodeResizer/NodeResizeControl.tsx @@ -1,4 +1,4 @@ -import { useRef, useEffect, memo } from 'react'; +import { useRef, useEffect, memo, useCallback } from 'react'; import cc from 'classcat'; import { shallow } from 'zustand/shallow'; import { @@ -14,6 +14,7 @@ import { evaluateAbsolutePosition, ParentExpandChild, XYPosition, + ControlPosition, } from '@xyflow/system'; import { useStoreApi, useStore } from '../../hooks/useStore'; @@ -21,14 +22,20 @@ import { useNodeId } from '../../contexts/NodeIdContext'; import type { ResizeControlProps, ResizeControlLineProps } from './types'; import { ReactFlowState } from '../../types'; -const selector = (store: ReactFlowState) => store.transform[2]; +const scaleSelector = (calculateScale: boolean) => (store: ReactFlowState) => + calculateScale ? `${Math.max(1 / store.transform[2], 1)}` : undefined; + +const defaultPositions: Record = { + [ResizeControlVariant.Line]: 'right', + [ResizeControlVariant.Handle]: 'bottom-right', +}; function ResizeControl({ nodeId, position, variant = ResizeControlVariant.Handle, className, - style = {}, + style = undefined, children, color, minWidth = 10, @@ -37,6 +44,7 @@ function ResizeControl({ maxHeight = Number.MAX_VALUE, keepAspectRatio = false, resizeDirection, + scaleControls = false, shouldResize, onResizeStart, onResize, @@ -46,13 +54,10 @@ function ResizeControl({ const id = typeof nodeId === 'string' ? nodeId : contextNodeId; const store = useStoreApi(); const resizeControlRef = useRef(null); - const isLineVariant = variant === ResizeControlVariant.Line; - const defaultPosition = isLineVariant ? 'right' : 'bottom-right'; - const controlPosition = position ?? defaultPosition; - + const isHandleControl = variant === ResizeControlVariant.Handle; + const scale = useStore(useCallback(scaleSelector(isHandleControl && !scaleControls), [isHandleControl]), shallow); const resizer = useRef(null); - - const zoom = useStore(selector, shallow); + const controlPosition = position ?? defaultPositions[variant]; useEffect(() => { if (!resizeControlRef.current || !id) { @@ -199,16 +204,16 @@ function ResizeControl({ ]); const positionClassNames = controlPosition.split('-'); - const colorStyleProp = isLineVariant ? 'borderColor' : 'backgroundColor'; - - const styleWithTransform = { ...style, scale: isLineVariant ? undefined : `${Math.max(1 / zoom, 1)}` }; - const controlStyle = color ? { ...styleWithTransform, [colorStyleProp]: color } : styleWithTransform; return (
{children}
diff --git a/packages/react/src/additional-components/NodeResizer/NodeResizer.tsx b/packages/react/src/additional-components/NodeResizer/NodeResizer.tsx index 434be4b7..efde9724 100644 --- a/packages/react/src/additional-components/NodeResizer/NodeResizer.tsx +++ b/packages/react/src/additional-components/NodeResizer/NodeResizer.tsx @@ -40,6 +40,7 @@ export function NodeResizer({ maxWidth = Number.MAX_VALUE, maxHeight = Number.MAX_VALUE, keepAspectRatio = false, + scaleControls = false, shouldResize, onResizeStart, onResize, @@ -66,6 +67,7 @@ export function NodeResizer({ maxHeight={maxHeight} onResizeStart={onResizeStart} keepAspectRatio={keepAspectRatio} + scaleControls={scaleControls} shouldResize={shouldResize} onResize={onResize} onResizeEnd={onResizeEnd} @@ -85,6 +87,7 @@ export function NodeResizer({ maxHeight={maxHeight} onResizeStart={onResizeStart} keepAspectRatio={keepAspectRatio} + scaleControls={scaleControls} shouldResize={shouldResize} onResize={onResize} onResizeEnd={onResizeEnd} diff --git a/packages/react/src/additional-components/NodeResizer/types.ts b/packages/react/src/additional-components/NodeResizer/types.ts index e6dd9d36..1e3b737b 100644 --- a/packages/react/src/additional-components/NodeResizer/types.ts +++ b/packages/react/src/additional-components/NodeResizer/types.ts @@ -59,6 +59,11 @@ export type NodeResizerProps = { * @default false */ keepAspectRatio?: boolean; + /** + * Scale the controls with the zoom level. + * @default false + */ + scaleControls?: boolean; /** Callback to determine if node should resize. */ shouldResize?: ShouldResize; /** Callback called when resizing starts. */ @@ -82,6 +87,7 @@ export type ResizeControlProps = Pick< | 'maxHeight' | 'keepAspectRatio' | 'shouldResize' + | 'scaleControls' | 'onResizeStart' | 'onResize' | 'onResizeEnd'