chore: cleanup components
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import { useVueFlow } from '@vue-flow/core'
|
||||
import { computed } from 'vue'
|
||||
import { computed, toRef } from 'vue'
|
||||
import { BackgroundVariant } from './types'
|
||||
import type { BackgroundProps } from './types'
|
||||
import { DotPattern, LinePattern } from './patterns'
|
||||
import { DefaultBgColors, DotPattern, LinePattern } from './patterns'
|
||||
|
||||
const {
|
||||
id,
|
||||
@@ -20,11 +20,6 @@ const {
|
||||
offset = 2,
|
||||
} = defineProps<BackgroundProps>()
|
||||
|
||||
const defaultColors: Record<BackgroundVariant, string> = {
|
||||
[BackgroundVariant.Dots]: '#81818a',
|
||||
[BackgroundVariant.Lines]: '#eee',
|
||||
}
|
||||
|
||||
const { id: vueFlowId, viewport } = useVueFlow()
|
||||
|
||||
const background = computed(() => {
|
||||
@@ -47,9 +42,9 @@ const background = computed(() => {
|
||||
})
|
||||
|
||||
// when there are multiple flows on a page we need to make sure that every background gets its own pattern.
|
||||
const patternId = computed(() => `pattern-${vueFlowId}${id ? `-${id}` : ''}`)
|
||||
const patternId = toRef(() => `pattern-${vueFlowId}${id ? `-${id}` : ''}`)
|
||||
|
||||
const patternColor = computed(() => initialPatternColor || defaultColors[variant || BackgroundVariant.Dots])
|
||||
const patternColor = toRef(() => initialPatternColor || DefaultBgColors[variant || BackgroundVariant.Dots])
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
@@ -29,3 +29,8 @@ export const Patterns = {
|
||||
[BackgroundVariant.Lines]: LinePattern,
|
||||
[BackgroundVariant.Dots]: DotPattern,
|
||||
}
|
||||
|
||||
export const DefaultBgColors: Record<BackgroundVariant, string> = {
|
||||
[BackgroundVariant.Dots]: '#81818a',
|
||||
[BackgroundVariant.Lines]: '#eee',
|
||||
}
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
// todo: replace with a simple string type
|
||||
export enum BackgroundVariant {
|
||||
Lines = 'lines',
|
||||
Dots = 'dots',
|
||||
}
|
||||
|
||||
export type BackgroundVariantType = Lowercase<keyof typeof BackgroundVariant>
|
||||
|
||||
export interface BackgroundProps {
|
||||
id?: string
|
||||
/** The background pattern variant, {@link BackgroundVariant} */
|
||||
variant?: BackgroundVariant
|
||||
/** The background pattern variant */
|
||||
variant?: BackgroundVariant | BackgroundVariantType
|
||||
/** Background pattern gap */
|
||||
gap?: number | number[]
|
||||
/** Background pattern size */
|
||||
@@ -16,9 +19,9 @@ export interface BackgroundProps {
|
||||
patternColor?: string
|
||||
/** Background color */
|
||||
bgColor?: string
|
||||
/** Background height */
|
||||
/** @deprecated Background height */
|
||||
height?: number
|
||||
/** Background width */
|
||||
/** @deprecated Background width */
|
||||
width?: number
|
||||
/** Background x-coordinate (offset x) */
|
||||
x?: number
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
import { Panel, PanelPosition, useVueFlow } from '@vue-flow/core'
|
||||
import { computed } from 'vue'
|
||||
import { toRef } from 'vue'
|
||||
import type { ControlProps } from './types'
|
||||
import ControlButton from './ControlButton.vue'
|
||||
import PlusIcon from './icons/plus.svg'
|
||||
@@ -37,11 +37,11 @@ const {
|
||||
maxZoom,
|
||||
} = useVueFlow()
|
||||
|
||||
const isInteractive = computed(() => nodesDraggable.value || nodesConnectable.value || elementsSelectable.value)
|
||||
const isInteractive = toRef(() => nodesDraggable.value || nodesConnectable.value || elementsSelectable.value)
|
||||
|
||||
const minZoomReached = computed(() => viewport.value.zoom <= minZoom.value)
|
||||
const minZoomReached = toRef(() => viewport.value.zoom <= minZoom.value)
|
||||
|
||||
const maxZoomReached = computed(() => viewport.value.zoom >= maxZoom.value)
|
||||
const maxZoomReached = toRef(() => viewport.value.zoom >= maxZoom.value)
|
||||
|
||||
function onZoomInHandler() {
|
||||
zoomIn()
|
||||
@@ -78,6 +78,7 @@ export default {
|
||||
<template>
|
||||
<Panel class="vue-flow__controls" :position="position">
|
||||
<slot name="top" />
|
||||
|
||||
<template v-if="showZoom">
|
||||
<slot name="control-zoom-in">
|
||||
<ControlButton class="vue-flow__controls-zoomin" :disabled="maxZoomReached" @click="onZoomInHandler">
|
||||
|
||||
@@ -5,7 +5,7 @@ import { zoom, zoomIdentity } from 'd3-zoom'
|
||||
import type { D3ZoomEvent } from 'd3-zoom'
|
||||
import { pointer, select } from 'd3-selection'
|
||||
import { computed, provide, ref, useAttrs, useSlots, watchEffect } from 'vue'
|
||||
import type { MiniMapNodeFunc, MiniMapProps, ShapeRendering } from './types'
|
||||
import type { MiniMapEmits, MiniMapNodeFunc, MiniMapProps, ShapeRendering } from './types'
|
||||
import MiniMapNode from './MiniMapNode'
|
||||
import { MiniMapSlots } from './types'
|
||||
|
||||
@@ -29,7 +29,7 @@ const {
|
||||
offsetScale = 5,
|
||||
} = defineProps<MiniMapProps>()
|
||||
|
||||
const emit = defineEmits(['click', 'nodeClick', 'nodeDblclick', 'nodeMouseenter', 'nodeMousemove', 'nodeMouseleave'])
|
||||
const emit = defineEmits<MiniMapEmits>()
|
||||
|
||||
const attrs: Record<string, any> = useAttrs()
|
||||
|
||||
@@ -202,6 +202,7 @@ function onNodeMouseLeave(event: MouseEvent, node: GraphNode) {
|
||||
export default {
|
||||
name: 'MiniMap',
|
||||
compatConfig: { MODE: 3 },
|
||||
inheritAttrs: false,
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -209,6 +210,7 @@ export default {
|
||||
<Panel :position="position" class="vue-flow__minimap" :class="{ pannable, zoomable }">
|
||||
<svg
|
||||
ref="el"
|
||||
v-bind="attrs"
|
||||
:width="elementWidth"
|
||||
:height="elementHeight"
|
||||
:viewBox="[viewBox.x, viewBox.y, viewBox.width, viewBox.height].join(' ')"
|
||||
|
||||
@@ -3,6 +3,7 @@ import { defineComponent, h, inject } from 'vue'
|
||||
import type { MiniMapNodeProps } from './types'
|
||||
import { MiniMapSlots } from './types'
|
||||
|
||||
// todo: typings
|
||||
export default defineComponent({
|
||||
name: 'MiniMapNode',
|
||||
compatConfig: { MODE: 3 },
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Dimensions, GraphNode, PanelPosition, XYPosition } from '@vue-flow/core'
|
||||
import type { Dimensions, GraphNode, NodeMouseEvent, PanelPosition, XYPosition } from '@vue-flow/core'
|
||||
import type { CSSProperties, InjectionKey, Slots } from 'vue'
|
||||
|
||||
/** expects a node and returns a color value */
|
||||
@@ -61,4 +61,19 @@ export interface MiniMapNodeProps {
|
||||
strokeWidth?: number
|
||||
}
|
||||
|
||||
export interface MiniMapEmits {
|
||||
(
|
||||
event: 'click',
|
||||
params: {
|
||||
event: MouseEvent
|
||||
position: { x: number; y: number }
|
||||
},
|
||||
): void
|
||||
(event: 'nodeClick', params: NodeMouseEvent): void
|
||||
(event: 'nodeDblclick', params: NodeMouseEvent): void
|
||||
(event: 'nodeMouseenter', params: NodeMouseEvent): void
|
||||
(event: 'nodeMousemove', params: NodeMouseEvent): void
|
||||
(event: 'nodeMouseleave', params: NodeMouseEvent): void
|
||||
}
|
||||
|
||||
export const MiniMapSlots: InjectionKey<Slots> = Symbol('MiniMapSlots')
|
||||
|
||||
@@ -4,18 +4,14 @@ import { computed, inject, watch } from 'vue'
|
||||
import type { NodeDimensionChange } from '@vue-flow/core'
|
||||
import { NodeIdInjection, useVueFlow } from '@vue-flow/core'
|
||||
import ResizeControl from './ResizeControl.vue'
|
||||
import type { ControlLinePosition, ControlPosition, NodeResizerProps, OnResize, OnResizeStart } from './types'
|
||||
import type { ControlLinePosition, ControlPosition, NodeResizerEmits, NodeResizerProps } from './types'
|
||||
import { ResizeControlVariant } from './types'
|
||||
|
||||
const props = withDefaults(defineProps<NodeResizerProps>(), {
|
||||
isVisible: true,
|
||||
})
|
||||
|
||||
const emits = defineEmits<{
|
||||
(event: 'resizeStart', resizeEvent: OnResizeStart): void
|
||||
(event: 'resize', resizeEvent: OnResize): void
|
||||
(event: 'resizeEnd', resizeEvent: OnResizeStart): void
|
||||
}>()
|
||||
const emits = defineEmits<NodeResizerEmits>()
|
||||
|
||||
const { findNode, emits: triggerEmits } = useVueFlow()
|
||||
|
||||
|
||||
@@ -3,10 +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 { computed, ref, watchEffect } from 'vue'
|
||||
import type { OnResize, OnResizeStart, ResizeControlProps, ResizeDragEvent } from './types'
|
||||
import { ResizeControlVariant } from './types'
|
||||
import { getDirection } from './utils'
|
||||
import { ref, toRef, watchEffect } from 'vue'
|
||||
import type { NodeResizerEmits, ResizeControlProps, ResizeControlVariant, ResizeDragEvent } from './types'
|
||||
import { DefaultPositions, StylingProperty, getDirection } from './utils'
|
||||
|
||||
const props = withDefaults(defineProps<ResizeControlProps>(), {
|
||||
variant: 'handle' as ResizeControlVariant,
|
||||
@@ -17,11 +16,7 @@ const props = withDefaults(defineProps<ResizeControlProps>(), {
|
||||
keepAspectRatio: false,
|
||||
})
|
||||
|
||||
const emits = defineEmits<{
|
||||
(event: 'resizeStart', resizeEvent: OnResizeStart): void
|
||||
(event: 'resize', resizeEvent: OnResize): void
|
||||
(event: 'resizeEnd', resizeEvent: OnResizeStart): void
|
||||
}>()
|
||||
const emits = defineEmits<NodeResizerEmits>()
|
||||
|
||||
const initPrevValues = { width: 0, height: 0, x: 0, y: 0 }
|
||||
|
||||
@@ -42,9 +37,11 @@ let startValues: typeof initStartValues = initStartValues
|
||||
|
||||
let prevValues: typeof initPrevValues = initPrevValues
|
||||
|
||||
const defaultPosition = computed(() => (props.variant === ResizeControlVariant.Line ? 'right' : 'bottom-right'))
|
||||
const controlPosition = toRef(() => props.position ?? DefaultPositions[props.variant])
|
||||
|
||||
const controlPosition = computed(() => props.position ?? defaultPosition.value)
|
||||
const positionClassNames = toRef(() => controlPosition.value.split('-'))
|
||||
|
||||
const controlStyle = toRef(() => (props.color ? { [StylingProperty[props.variant]]: props.color } : {}))
|
||||
|
||||
watchEffect((onCleanup) => {
|
||||
if (!resizeControlRef.value || !props.nodeId) {
|
||||
@@ -228,10 +225,6 @@ watchEffect((onCleanup) => {
|
||||
selection.on('.drag', null)
|
||||
})
|
||||
})
|
||||
|
||||
const positionClassNames = computed(() => controlPosition.value.split('-'))
|
||||
const colorStyleProp = computed(() => (props.variant === ResizeControlVariant.Line ? 'borderColor' : 'backgroundColor'))
|
||||
const controlStyle = computed(() => (props.color ? { [colorStyleProp.value]: props.color } : {}))
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
<script lang="ts" setup>
|
||||
import ResizeControl from './ResizeControl.vue'
|
||||
import type { OnResize, OnResizeStart, ResizeControlLineProps } from './types'
|
||||
import type { NodeResizerEmits, ResizeControlLineProps } from './types'
|
||||
import { ResizeControlVariant } from './types'
|
||||
|
||||
const props = defineProps<ResizeControlLineProps>()
|
||||
|
||||
const emits = defineEmits<{
|
||||
(event: 'resizeStart', resizeEvent: OnResizeStart): void
|
||||
(event: 'resize', resizeEvent: OnResize): void
|
||||
(event: 'resizeEnd', resizeEvent: OnResizeStart): void
|
||||
}>()
|
||||
const emits = defineEmits<NodeResizerEmits>()
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { ResizeControlVariant } from './types'
|
||||
|
||||
interface GetDirectionParams {
|
||||
width: number
|
||||
prevWidth: number
|
||||
@@ -25,3 +27,13 @@ export function getDirection({ width, prevWidth, height, prevHeight, invertX, in
|
||||
|
||||
return direction
|
||||
}
|
||||
|
||||
export const DefaultPositions = {
|
||||
[ResizeControlVariant.Line]: 'right',
|
||||
[ResizeControlVariant.Handle]: 'bottom-right',
|
||||
}
|
||||
|
||||
export const StylingProperty = {
|
||||
[ResizeControlVariant.Line]: 'borderColor',
|
||||
[ResizeControlVariant.Handle]: 'backgroundColor',
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, inject } from 'vue'
|
||||
import { computed, inject, toRef } from 'vue'
|
||||
import type { GraphNode, Rect, ViewportTransform } from '@vue-flow/core'
|
||||
import { NodeIdInjection, Position, getRectOfNodes, useVueFlow } from '@vue-flow/core'
|
||||
|
||||
@@ -16,6 +16,36 @@ const contextNodeId = inject(NodeIdInjection, null)
|
||||
|
||||
const { viewportRef, viewport, getSelectedNodes, findNode } = useVueFlow()
|
||||
|
||||
const nodes = computed(() => {
|
||||
const nodeIds = Array.isArray(props.nodeId) ? props.nodeId : [props.nodeId || contextNodeId || '']
|
||||
|
||||
return nodeIds.reduce<GraphNode[]>((acc, id) => {
|
||||
const node = findNode(id)
|
||||
|
||||
if (node) {
|
||||
acc.push(node)
|
||||
}
|
||||
|
||||
return acc
|
||||
}, [] as GraphNode[])
|
||||
})
|
||||
|
||||
const isActive = toRef(() =>
|
||||
typeof props.isVisible === 'boolean'
|
||||
? props.isVisible
|
||||
: nodes.value.length === 1 && nodes.value[0].selected && getSelectedNodes.value.length === 1,
|
||||
)
|
||||
|
||||
const nodeRect = computed(() => getRectOfNodes(nodes.value))
|
||||
|
||||
const zIndex = computed(() => Math.max(...nodes.value.map((node) => (node.computedPosition.z || 1) + 1)))
|
||||
|
||||
const wrapperStyle = computed<CSSProperties>(() => ({
|
||||
position: 'absolute',
|
||||
transform: getTransform(nodeRect.value, viewport.value, props.position, props.offset, props.align),
|
||||
zIndex: zIndex.value,
|
||||
}))
|
||||
|
||||
function getTransform(nodeRect: Rect, transform: ViewportTransform, position: Position, offset: number, align: Align): string {
|
||||
let alignmentOffset = 0.5
|
||||
|
||||
@@ -57,36 +87,6 @@ function getTransform(nodeRect: Rect, transform: ViewportTransform, position: Po
|
||||
|
||||
return `translate(${pos[0]}px, ${pos[1]}px) translate(${shift[0]}%, ${shift[1]}%)`
|
||||
}
|
||||
|
||||
const nodes = computed(() => {
|
||||
const nodeIds = Array.isArray(props.nodeId) ? props.nodeId : [props.nodeId || contextNodeId || '']
|
||||
|
||||
return nodeIds.reduce<GraphNode[]>((acc, id) => {
|
||||
const node = findNode(id)
|
||||
|
||||
if (node) {
|
||||
acc.push(node)
|
||||
}
|
||||
|
||||
return acc
|
||||
}, [] as GraphNode[])
|
||||
})
|
||||
|
||||
const isActive = computed(() =>
|
||||
typeof props.isVisible === 'boolean'
|
||||
? props.isVisible
|
||||
: nodes.value.length === 1 && nodes.value[0].selected && getSelectedNodes.value.length === 1,
|
||||
)
|
||||
|
||||
const nodeRect = computed(() => getRectOfNodes(nodes.value))
|
||||
|
||||
const zIndex = computed(() => Math.max(...nodes.value.map((node) => (node.computedPosition.z || 1) + 1)))
|
||||
|
||||
const wrapperStyle = computed<CSSProperties>(() => ({
|
||||
position: 'absolute',
|
||||
transform: getTransform(nodeRect.value, viewport.value, props.position, props.offset, props.align),
|
||||
zIndex: zIndex.value,
|
||||
}))
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
Reference in New Issue
Block a user