refactor(node-resizer): add auto-scale prop & scale resize controls with zoom level (#1872)

* refactor(node-resizer): add auto-scale prop & scale resize controls with zoom

Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com>

* chore(changeset): add

---------

Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com>
This commit is contained in:
Braks
2025-06-12 10:51:38 +02:00
parent e7dec135e1
commit f4e139f1bc
5 changed files with 35 additions and 12 deletions

View File

@@ -0,0 +1,5 @@
---
"@vue-flow/node-resizer": minor
---
Add auto-scale prop to node resizer (default `true`) that forces node resizer controls to scale with the viewport zoom level.

View File

@@ -8,6 +8,7 @@ import { ResizeControlVariant } from './types'
const props = withDefaults(defineProps<NodeResizerProps>(), {
isVisible: true,
autoScale: true,
})
const emits = defineEmits<NodeResizerEmits>()
@@ -92,13 +93,14 @@ export default {
:node-id="nodeId"
:position="c"
:variant="ResizeControlVariant.Line"
:keep-aspect-ratio="keepAspectRatio"
:color="color"
:min-width="minWidth"
:min-height="minHeight"
:max-width="maxWidth"
:max-height="maxHeight"
:should-resize="shouldResize"
:keep-aspect-ratio="keepAspectRatio"
:auto-scale="autoScale"
@resize-start="emits('resizeStart', $event)"
@resize="emits('resize', $event)"
@resize-end="emits('resizeEnd', $event)"
@@ -118,6 +120,7 @@ export default {
:max-height="maxHeight"
:should-resize="shouldResize"
:keep-aspect-ratio="keepAspectRatio"
:auto-scale="autoScale"
@resize-start="emits('resizeStart', $event)"
@resize="emits('resize', $event)"
@resize-end="emits('resizeEnd', $event)"

View File

@@ -3,8 +3,9 @@ import type { NodeChange, NodeDimensionChange, NodePositionChange } from '@vue-f
import { clamp, useGetPointerPosition, useVueFlow } from '@vue-flow/core'
import { select } from 'd3-selection'
import { drag } from 'd3-drag'
import { ref, toRef, watchEffect } from 'vue'
import type { NodeResizerEmits, ResizeControlProps, ResizeControlVariant, ResizeDragEvent } from './types'
import { computed, ref, toRef, watchEffect } from 'vue'
import type { NodeResizerEmits, ResizeControlProps, ResizeDragEvent } from './types'
import { ResizeControlVariant } from './types'
import { DefaultPositions, StylingProperty, getDirection } from './utils'
const props = withDefaults(defineProps<ResizeControlProps>(), {
@@ -14,6 +15,7 @@ const props = withDefaults(defineProps<ResizeControlProps>(), {
maxWidth: Number.MAX_VALUE,
maxHeight: Number.MAX_VALUE,
keepAspectRatio: false,
autoScale: true,
})
const emits = defineEmits<NodeResizerEmits>()
@@ -27,7 +29,7 @@ const initStartValues = {
aspectRatio: 1,
}
const { findNode, emits: triggerEmits } = useVueFlow()
const { findNode, emits: triggerEmits, viewport, noDragClassName } = useVueFlow()
const getPointerPosition = useGetPointerPosition()
@@ -39,7 +41,7 @@ let prevValues: typeof initPrevValues = initPrevValues
const controlPosition = toRef(() => props.position ?? DefaultPositions[props.variant])
const positionClassNames = toRef(() => controlPosition.value.split('-'))
const positionClassNames = computed(() => controlPosition.value.split('-'))
const controlStyle = toRef(() => (props.color ? { [StylingProperty[props.variant]]: props.color } : {}))
@@ -237,9 +239,12 @@ export default {
<template>
<div
ref="resizeControlRef"
class="vue-flow__resize-control nodrag"
:class="[...positionClassNames, variant]"
:style="controlStyle"
class="vue-flow__resize-control"
:class="[...positionClassNames, variant, noDragClassName]"
:style="{
...controlStyle,
scale: variant === ResizeControlVariant.Handle ? `${Math.max(1 / viewport.zoom, 1)}` : undefined,
}"
>
<slot />
</div>

View File

@@ -24,8 +24,8 @@
/* handle styles */
.vue-flow__resize-control.handle {
width: 4px;
height: 4px;
width: 5px;
height: 5px;
border: 1px solid #fff;
border-radius: 1px;
background-color: #3367d9;

View File

@@ -45,6 +45,11 @@ export interface NodeResizerProps {
maxHeight?: number
shouldResize?: ShouldResize
keepAspectRatio?: boolean | number
/**
* Scale the controls with the zoom level.
* @default true
*/
autoScale?: boolean
}
export interface NodeResizerEmits {
@@ -62,8 +67,8 @@ export enum ResizeControlVariant {
Handle = 'handle',
}
export interface ResizeControlProps {
nodeId?: string | null
export interface ResizeControlProps extends NodeResizerProps {
nodeId?: string
color?: string
minWidth?: number
minHeight?: number
@@ -73,6 +78,11 @@ export interface ResizeControlProps {
variant?: ResizeControlVariant
shouldResize?: ShouldResize
keepAspectRatio?: boolean | number
/**
* Scale the controls with the zoom level.
* @default true
*/
autoScale?: boolean
}
export interface ResizeControlLineProps extends ResizeControlProps {