Merge pull request #2900 from wbkd/feature/max-properties-resizer

Feature/max properties resizer
This commit is contained in:
Moritz Klack
2023-03-07 18:02:17 +01:00
committed by GitHub
13 changed files with 285 additions and 152 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ export { default as SimpleBezierEdge, getSimpleBezierPath } from './components/E
export { default as SmoothStepEdge, getSmoothStepPath } from './components/Edges/SmoothStepEdge';
export { default as BaseEdge } from './components/Edges/BaseEdge';
export { internalsSymbol, rectToBox, boxToRect, getBoundsOfRects } from './utils';
export { internalsSymbol, rectToBox, boxToRect, getBoundsOfRects, clamp } from './utils';
export {
isNode,
isEdge,
@@ -14,6 +14,9 @@ export default function NodeResizer({
color,
minWidth = 10,
minHeight = 10,
maxWidth = Number.MAX_VALUE,
maxHeight = Number.MAX_VALUE,
keepAspectRatio = false,
shouldResize,
onResizeStart,
onResize,
@@ -36,7 +39,10 @@ export default function NodeResizer({
color={color}
minWidth={minWidth}
minHeight={minHeight}
maxWidth={maxWidth}
maxHeight={maxHeight}
onResizeStart={onResizeStart}
keepAspectRatio={keepAspectRatio}
shouldResize={shouldResize}
onResize={onResize}
onResizeEnd={onResizeEnd}
@@ -52,7 +58,10 @@ export default function NodeResizer({
color={color}
minWidth={minWidth}
minHeight={minHeight}
maxWidth={maxWidth}
maxHeight={maxHeight}
onResizeStart={onResizeStart}
keepAspectRatio={keepAspectRatio}
shouldResize={shouldResize}
onResize={onResize}
onResizeEnd={onResizeEnd}
+45 -7
View File
@@ -9,6 +9,7 @@ import {
NodeDimensionChange,
useNodeId,
NodePositionChange,
clamp,
} from '@reactflow/core';
import { ResizeDragEvent, ResizeControlProps, ResizeControlLineProps, ResizeControlVariant } from './types';
@@ -20,6 +21,7 @@ const initStartValues = {
...initPrevValues,
pointerX: 0,
pointerY: 0,
aspectRatio: 1,
};
function ResizeControl({
@@ -32,6 +34,9 @@ function ResizeControl({
color,
minWidth = 10,
minHeight = 10,
maxWidth = Number.MAX_VALUE,
maxHeight = Number.MAX_VALUE,
keepAspectRatio = false,
shouldResize,
onResizeStart,
onResize,
@@ -53,6 +58,12 @@ function ResizeControl({
}
const selection = select(resizeControlRef.current);
const enableX = controlPosition.includes('right') || controlPosition.includes('left');
const enableY = controlPosition.includes('bottom') || controlPosition.includes('top');
const invertX = controlPosition.includes('left');
const invertY = controlPosition.includes('top');
const dragHandler = drag<HTMLDivElement, unknown>()
.on('start', (event: ResizeDragEvent) => {
const node = store.getState().nodeInternals.get(id);
@@ -69,6 +80,7 @@ function ResizeControl({
...prevValues.current,
pointerX: xSnapped,
pointerY: ySnapped,
aspectRatio: prevValues.current.width / prevValues.current.height,
};
onResizeStart?.(event, { ...prevValues.current });
@@ -77,10 +89,6 @@ function ResizeControl({
const { nodeInternals, triggerNodeChanges } = store.getState();
const { xSnapped, ySnapped } = getPointerPosition(event);
const node = nodeInternals.get(id);
const enableX = controlPosition.includes('right') || controlPosition.includes('left');
const enableY = controlPosition.includes('bottom') || controlPosition.includes('top');
const invertX = controlPosition.includes('left');
const invertY = controlPosition.includes('top');
if (node) {
const changes: NodeChange[] = [];
@@ -91,13 +99,43 @@ function ResizeControl({
height: startHeight,
x: startNodeX,
y: startNodeY,
aspectRatio,
} = startValues.current;
const { x: prevX, y: prevY, width: prevWidth, height: prevHeight } = prevValues.current;
const distX = Math.floor(enableX ? xSnapped - startX : 0);
const distY = Math.floor(enableY ? ySnapped - startY : 0);
const width = Math.max(startWidth + (invertX ? -distX : distX), minWidth);
const height = Math.max(startHeight + (invertY ? -distY : distY), minHeight);
let width = clamp(startWidth + (invertX ? -distX : distX), minWidth, maxWidth);
let height = clamp(startHeight + (invertY ? -distY : distY), minHeight, maxHeight);
if (keepAspectRatio) {
const nextAspectRatio = width / height;
const isDiagonal = enableX && enableY;
const isHorizontal = enableX && !enableY;
const isVertical = enableY && !enableX;
width = (nextAspectRatio <= aspectRatio && isDiagonal) || isVertical ? height * aspectRatio : width;
height = (nextAspectRatio > aspectRatio && isDiagonal) || isHorizontal ? width / aspectRatio : height;
if (width >= maxWidth) {
width = maxWidth;
height = maxWidth / aspectRatio;
} else if (width <= minWidth) {
width = minWidth;
height = minWidth / aspectRatio;
}
if (height >= maxHeight) {
height = maxHeight;
width = maxHeight * aspectRatio;
} else if (height <= minHeight) {
height = minHeight;
width = minHeight * aspectRatio;
}
}
const isWidthChange = width !== prevWidth;
const isHeightChange = height !== prevHeight;
@@ -183,7 +221,7 @@ function ResizeControl({
return () => {
selection.on('.drag', null);
};
}, [id, controlPosition, minWidth, minHeight, getPointerPosition]);
}, [id, controlPosition, minWidth, minHeight, maxWidth, maxHeight, keepAspectRatio, getPointerPosition]);
const positionClassNames = controlPosition.split('-');
const colorStyleProp = variant === ResizeControlVariant.Line ? 'borderColor' : 'backgroundColor';
+14 -1
View File
@@ -29,6 +29,9 @@ export type NodeResizerProps = {
isVisible?: boolean;
minWidth?: number;
minHeight?: number;
maxWidth?: number;
maxHeight?: number;
keepAspectRatio?: boolean;
shouldResize?: ShouldResize;
onResizeStart?: OnResizeStart;
onResize?: OnResize;
@@ -46,7 +49,17 @@ export enum ResizeControlVariant {
export type ResizeControlProps = Pick<
NodeResizerProps,
'nodeId' | 'color' | 'minWidth' | 'minHeight' | 'shouldResize' | 'onResizeStart' | 'onResize' | 'onResizeEnd'
| 'nodeId'
| 'color'
| 'minWidth'
| 'minHeight'
| 'maxWidth'
| 'maxHeight'
| 'keepAspectRatio'
| 'shouldResize'
| 'onResizeStart'
| 'onResize'
| 'onResizeEnd'
> & {
position?: ControlPosition;
variant?: ResizeControlVariant;