chore(resizer): cleanup and add scaleControls

This commit is contained in:
moklick
2025-06-11 09:59:49 +02:00
parent 178ad01f51
commit ec3ef27c90
4 changed files with 30 additions and 14 deletions

View File

@@ -10,6 +10,8 @@ const CustomResizerNode: FC<NodeProps> = ({ data }) => {
resizeDirection="horizontal"
minWidth={100}
maxWidth={500}
color="orange"
scaleControls
/>
<Handle type="target" position={Position.Left} />
<div>{data.label}</div>

View File

@@ -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, ControlPosition> = {
[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<HTMLDivElement>(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<XYResizerInstance | null>(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 (
<div
className={cc(['react-flow__resize-control', 'nodrag', ...positionClassNames, variant, className])}
ref={resizeControlRef}
style={controlStyle}
style={{
...style,
scale,
...(color && { [isHandleControl ? 'backgroundColor' : 'borderColor']: color }),
}}
>
{children}
</div>

View File

@@ -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}

View File

@@ -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'