feat(node-resizer): add shouldResize option
Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com>
This commit is contained in:
@@ -1,20 +1,21 @@
|
||||
<script lang="ts" setup>
|
||||
// todo: add plugin to emit resize events via vue flow store; requires plugin API to be added to core
|
||||
import ResizeControl from './ResizeControl.vue'
|
||||
import type { ControlLinePosition, ControlPosition, NodeResizerProps, ResizeDragEvent, ResizeEventParams } from './types'
|
||||
import type { ControlLinePosition, ControlPosition, NodeResizerProps, OnResize, OnResizeStart } from './types'
|
||||
import { ResizeControlVariant } from './types'
|
||||
|
||||
const props = withDefaults(defineProps<NodeResizerProps>(), {
|
||||
withDefaults(defineProps<NodeResizerProps>(), {
|
||||
isVisible: true,
|
||||
})
|
||||
|
||||
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 handleControls: ControlPosition[] = ['top-left', 'top-right', 'bottom-left', 'bottom-right']
|
||||
|
||||
const lineControls: ControlLinePosition[] = ['top', 'right', 'bottom', 'left']
|
||||
</script>
|
||||
|
||||
@@ -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)"
|
||||
/>
|
||||
|
||||
<ResizeControl
|
||||
v-for="c of handleControls"
|
||||
:key="c"
|
||||
@@ -51,6 +54,7 @@ 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)"
|
||||
|
||||
@@ -3,8 +3,9 @@ import type { NodeChange, NodeDimensionChange, NodePositionChange } from '@vue-f
|
||||
import { NodeIdInjection, useGetPointerPosition, useVueFlow } from '@vue-flow/core'
|
||||
import { select } from 'd3-selection'
|
||||
import { drag } from 'd3-drag'
|
||||
import type { ResizeControlProps, ResizeDragEvent, ResizeEventParams } from './types'
|
||||
import type { OnResize, OnResizeStart, ResizeControlProps, ResizeDragEvent } from './types'
|
||||
import { ResizeControlVariant } from './types'
|
||||
import { getDirection } from './utils'
|
||||
|
||||
const props = withDefaults(defineProps<ResizeControlProps>(), {
|
||||
variant: 'handle' as ResizeControlVariant,
|
||||
@@ -13,9 +14,9 @@ const props = withDefaults(defineProps<ResizeControlProps>(), {
|
||||
})
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<script lang="ts" setup>
|
||||
import ResizeControl from './ResizeControl.vue'
|
||||
import type { ResizeControlLineProps, ResizeDragEvent, ResizeEventParams } from './types'
|
||||
import type { OnResize, OnResizeStart, ResizeControlLineProps } from './types'
|
||||
import { ResizeControlVariant } from './types'
|
||||
|
||||
const props = defineProps<ResizeControlLineProps>()
|
||||
|
||||
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
|
||||
}>()
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,13 +1,36 @@
|
||||
import type { D3DragEvent, SubjectPosition } from 'd3-drag'
|
||||
import type { CSSProperties } from 'vue'
|
||||
|
||||
export interface ResizeEventParams {
|
||||
export type ResizeDragEvent = D3DragEvent<HTMLDivElement, null, SubjectPosition>
|
||||
|
||||
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<HTMLDivElement, null, SubjectPosition>
|
||||
|
||||
27
packages/node-resizer/src/utils.ts
Normal file
27
packages/node-resizer/src/utils.ts
Normal file
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user