From 222b58afd45aac9c33ade7bd29bb4fbd41721c10 Mon Sep 17 00:00:00 2001 From: braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Thu, 2 Feb 2023 14:28:22 +0100 Subject: [PATCH] feat(node-resizer): add `shouldResize` option Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com> --- packages/node-resizer/src/NodeResizer.vue | 14 +++++--- packages/node-resizer/src/ResizeControl.vue | 28 ++++++++++++--- .../node-resizer/src/ResizeControlLine.vue | 8 ++--- packages/node-resizer/src/types.ts | 35 +++++++++++++++---- packages/node-resizer/src/utils.ts | 27 ++++++++++++++ 5 files changed, 92 insertions(+), 20 deletions(-) create mode 100644 packages/node-resizer/src/utils.ts diff --git a/packages/node-resizer/src/NodeResizer.vue b/packages/node-resizer/src/NodeResizer.vue index 443de833..a482d3f8 100644 --- a/packages/node-resizer/src/NodeResizer.vue +++ b/packages/node-resizer/src/NodeResizer.vue @@ -1,20 +1,21 @@ @@ -37,10 +38,12 @@ export default { :color="color" :min-width="minWidth" :min-height="minHeight" + :should-resize="shouldResize" @resize-start="emits('resizeStart', $event)" @resize="emits('resize', $event)" @resize-end="emits('resizeEnd', $event)" /> + (), { variant: 'handle' as ResizeControlVariant, @@ -13,9 +14,9 @@ const props = withDefaults(defineProps(), { }) const emits = defineEmits<{ - (event: 'resizeStart', data: { event: ResizeDragEvent; params: ResizeEventParams }): void - (event: 'resize', data: { event: ResizeDragEvent; params: ResizeEventParams }): void - (event: 'resizeEnd', data: { event: ResizeDragEvent; params: ResizeEventParams }): void + (event: 'resizeStart', resizeEvent: OnResizeStart): void + (event: 'resize', resizeEvent: OnResize): void + (event: 'resizeEnd', resizeEvent: OnResizeStart): void }>() const initPrevValues = { width: 0, height: 0, x: 0, y: 0 } @@ -142,7 +143,24 @@ watchEffect((onCleanup) => { prevValues.value.height = height } - emits('resize', { event, params: prevValues.value }) + if (changes.length === 0) return + + const direction = getDirection({ + width: prevValues.value.width, + prevWidth, + height: prevValues.value.height, + prevHeight, + invertX, + invertY, + }) + + const nextValues = { ...prevValues.value, direction } + + const callResize = props.shouldResize?.(event, nextValues) + + if (callResize === false) return + + emits('resize', { event, params: nextValues }) triggerEmits.nodesChange(changes) } diff --git a/packages/node-resizer/src/ResizeControlLine.vue b/packages/node-resizer/src/ResizeControlLine.vue index d2ce734f..432f7421 100644 --- a/packages/node-resizer/src/ResizeControlLine.vue +++ b/packages/node-resizer/src/ResizeControlLine.vue @@ -1,14 +1,14 @@ diff --git a/packages/node-resizer/src/types.ts b/packages/node-resizer/src/types.ts index 875fc2db..7f35a918 100644 --- a/packages/node-resizer/src/types.ts +++ b/packages/node-resizer/src/types.ts @@ -1,13 +1,36 @@ import type { D3DragEvent, SubjectPosition } from 'd3-drag' import type { CSSProperties } from 'vue' -export interface ResizeEventParams { +export type ResizeDragEvent = D3DragEvent + +export type ResizeParamsWithDirection = ResizeParams & { + direction: number[] +} + +export interface ResizeParams { x: number y: number width: number height: number } +export type ShouldResize = (event: ResizeDragEvent, params: ResizeParamsWithDirection) => boolean + +export interface OnResizeStart { + event: ResizeDragEvent + params: ResizeParams +} + +export interface OnResize { + event: ResizeDragEvent + params: ResizeParamsWithDirection +} + +export interface OnResizeEnd { + event: ResizeDragEvent + params: ResizeParams +} + export interface NodeResizerProps { nodeId?: string color?: string @@ -18,12 +41,13 @@ export interface NodeResizerProps { isVisible?: boolean minWidth?: number minHeight?: number + shouldResize?: ShouldResize } export interface NodeResizerEmits { - (event: 'resizeStart', data: { event: ResizeDragEvent; params: ResizeEventParams }): void - (event: 'resize', data: { event: ResizeDragEvent; params: ResizeEventParams }): void - (event: 'resizeEnd', data: { event: ResizeDragEvent; params: ResizeEventParams }): void + (event: 'resizeStart', resizeEvent: OnResizeStart): void + (event: 'resize', resizeEvent: OnResize): void + (event: 'resizeEnd', resizeEvent: OnResizeStart): void } export type ControlLinePosition = 'top' | 'bottom' | 'left' | 'right' @@ -42,6 +66,7 @@ export interface ResizeControlProps { minHeight?: number position?: ControlPosition variant?: ResizeControlVariant + shouldResize?: ShouldResize } export interface ResizeControlLineProps { @@ -52,5 +77,3 @@ export interface ResizeControlLineProps { variant?: ResizeControlVariant position?: ControlLinePosition } - -export type ResizeDragEvent = D3DragEvent diff --git a/packages/node-resizer/src/utils.ts b/packages/node-resizer/src/utils.ts new file mode 100644 index 00000000..1124d4b3 --- /dev/null +++ b/packages/node-resizer/src/utils.ts @@ -0,0 +1,27 @@ +interface GetDirectionParams { + width: number + prevWidth: number + height: number + prevHeight: number + invertX: boolean + invertY: boolean +} + +// returns an array of two numbers (0, 1 or -1) representing the direction of the resize +// 0 = no change, 1 = increase, -1 = decrease +export function getDirection({ width, prevWidth, height, prevHeight, invertX, invertY }: GetDirectionParams) { + const deltaWidth = width - prevWidth + const deltaHeight = height - prevHeight + + const direction = [deltaWidth > 0 ? 1 : deltaWidth < 0 ? -1 : 0, deltaHeight > 0 ? 1 : deltaHeight < 0 ? -1 : 0] + + if (deltaWidth && invertX) { + direction[0] = direction[0] * -1 + } + + if (deltaHeight && invertY) { + direction[1] = direction[1] * -1 + } + + return direction +}