chore: cleanup components

This commit is contained in:
braks
2023-10-30 13:36:07 +01:00
committed by Braks
parent c32c0df4fa
commit 119f6d15db
12 changed files with 97 additions and 78 deletions
+4 -9
View File
@@ -1,9 +1,9 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useVueFlow } from '@vue-flow/core' import { useVueFlow } from '@vue-flow/core'
import { computed } from 'vue' import { computed, toRef } from 'vue'
import { BackgroundVariant } from './types' import { BackgroundVariant } from './types'
import type { BackgroundProps } from './types' import type { BackgroundProps } from './types'
import { DotPattern, LinePattern } from './patterns' import { DefaultBgColors, DotPattern, LinePattern } from './patterns'
const { const {
id, id,
@@ -20,11 +20,6 @@ const {
offset = 2, offset = 2,
} = defineProps<BackgroundProps>() } = defineProps<BackgroundProps>()
const defaultColors: Record<BackgroundVariant, string> = {
[BackgroundVariant.Dots]: '#81818a',
[BackgroundVariant.Lines]: '#eee',
}
const { id: vueFlowId, viewport } = useVueFlow() const { id: vueFlowId, viewport } = useVueFlow()
const background = computed(() => { 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. // 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>
<script lang="ts"> <script lang="ts">
+5
View File
@@ -29,3 +29,8 @@ export const Patterns = {
[BackgroundVariant.Lines]: LinePattern, [BackgroundVariant.Lines]: LinePattern,
[BackgroundVariant.Dots]: DotPattern, [BackgroundVariant.Dots]: DotPattern,
} }
export const DefaultBgColors: Record<BackgroundVariant, string> = {
[BackgroundVariant.Dots]: '#81818a',
[BackgroundVariant.Lines]: '#eee',
}
+7 -4
View File
@@ -1,12 +1,15 @@
// todo: replace with a simple string type
export enum BackgroundVariant { export enum BackgroundVariant {
Lines = 'lines', Lines = 'lines',
Dots = 'dots', Dots = 'dots',
} }
export type BackgroundVariantType = Lowercase<keyof typeof BackgroundVariant>
export interface BackgroundProps { export interface BackgroundProps {
id?: string id?: string
/** The background pattern variant, {@link BackgroundVariant} */ /** The background pattern variant */
variant?: BackgroundVariant variant?: BackgroundVariant | BackgroundVariantType
/** Background pattern gap */ /** Background pattern gap */
gap?: number | number[] gap?: number | number[]
/** Background pattern size */ /** Background pattern size */
@@ -16,9 +19,9 @@ export interface BackgroundProps {
patternColor?: string patternColor?: string
/** Background color */ /** Background color */
bgColor?: string bgColor?: string
/** Background height */ /** @deprecated Background height */
height?: number height?: number
/** Background width */ /** @deprecated Background width */
width?: number width?: number
/** Background x-coordinate (offset x) */ /** Background x-coordinate (offset x) */
x?: number x?: number
+5 -4
View File
@@ -1,6 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import { Panel, PanelPosition, useVueFlow } from '@vue-flow/core' import { Panel, PanelPosition, useVueFlow } from '@vue-flow/core'
import { computed } from 'vue' import { toRef } from 'vue'
import type { ControlProps } from './types' import type { ControlProps } from './types'
import ControlButton from './ControlButton.vue' import ControlButton from './ControlButton.vue'
import PlusIcon from './icons/plus.svg' import PlusIcon from './icons/plus.svg'
@@ -37,11 +37,11 @@ const {
maxZoom, maxZoom,
} = useVueFlow() } = 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() { function onZoomInHandler() {
zoomIn() zoomIn()
@@ -78,6 +78,7 @@ export default {
<template> <template>
<Panel class="vue-flow__controls" :position="position"> <Panel class="vue-flow__controls" :position="position">
<slot name="top" /> <slot name="top" />
<template v-if="showZoom"> <template v-if="showZoom">
<slot name="control-zoom-in"> <slot name="control-zoom-in">
<ControlButton class="vue-flow__controls-zoomin" :disabled="maxZoomReached" @click="onZoomInHandler"> <ControlButton class="vue-flow__controls-zoomin" :disabled="maxZoomReached" @click="onZoomInHandler">
+4 -2
View File
@@ -5,7 +5,7 @@ import { zoom, zoomIdentity } from 'd3-zoom'
import type { D3ZoomEvent } from 'd3-zoom' import type { D3ZoomEvent } from 'd3-zoom'
import { pointer, select } from 'd3-selection' import { pointer, select } from 'd3-selection'
import { computed, provide, ref, useAttrs, useSlots, watchEffect } from 'vue' 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 MiniMapNode from './MiniMapNode'
import { MiniMapSlots } from './types' import { MiniMapSlots } from './types'
@@ -29,7 +29,7 @@ const {
offsetScale = 5, offsetScale = 5,
} = defineProps<MiniMapProps>() } = defineProps<MiniMapProps>()
const emit = defineEmits(['click', 'nodeClick', 'nodeDblclick', 'nodeMouseenter', 'nodeMousemove', 'nodeMouseleave']) const emit = defineEmits<MiniMapEmits>()
const attrs: Record<string, any> = useAttrs() const attrs: Record<string, any> = useAttrs()
@@ -202,6 +202,7 @@ function onNodeMouseLeave(event: MouseEvent, node: GraphNode) {
export default { export default {
name: 'MiniMap', name: 'MiniMap',
compatConfig: { MODE: 3 }, compatConfig: { MODE: 3 },
inheritAttrs: false,
} }
</script> </script>
@@ -209,6 +210,7 @@ export default {
<Panel :position="position" class="vue-flow__minimap" :class="{ pannable, zoomable }"> <Panel :position="position" class="vue-flow__minimap" :class="{ pannable, zoomable }">
<svg <svg
ref="el" ref="el"
v-bind="attrs"
:width="elementWidth" :width="elementWidth"
:height="elementHeight" :height="elementHeight"
:viewBox="[viewBox.x, viewBox.y, viewBox.width, viewBox.height].join(' ')" :viewBox="[viewBox.x, viewBox.y, viewBox.width, viewBox.height].join(' ')"
+1
View File
@@ -3,6 +3,7 @@ import { defineComponent, h, inject } from 'vue'
import type { MiniMapNodeProps } from './types' import type { MiniMapNodeProps } from './types'
import { MiniMapSlots } from './types' import { MiniMapSlots } from './types'
// todo: typings
export default defineComponent({ export default defineComponent({
name: 'MiniMapNode', name: 'MiniMapNode',
compatConfig: { MODE: 3 }, compatConfig: { MODE: 3 },
+16 -1
View File
@@ -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' import type { CSSProperties, InjectionKey, Slots } from 'vue'
/** expects a node and returns a color value */ /** expects a node and returns a color value */
@@ -61,4 +61,19 @@ export interface MiniMapNodeProps {
strokeWidth?: number 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') export const MiniMapSlots: InjectionKey<Slots> = Symbol('MiniMapSlots')
+2 -6
View File
@@ -4,18 +4,14 @@ import { computed, inject, watch } from 'vue'
import type { NodeDimensionChange } from '@vue-flow/core' import type { NodeDimensionChange } from '@vue-flow/core'
import { NodeIdInjection, useVueFlow } from '@vue-flow/core' import { NodeIdInjection, useVueFlow } from '@vue-flow/core'
import ResizeControl from './ResizeControl.vue' 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' import { ResizeControlVariant } from './types'
const props = withDefaults(defineProps<NodeResizerProps>(), { const props = withDefaults(defineProps<NodeResizerProps>(), {
isVisible: true, isVisible: true,
}) })
const emits = defineEmits<{ const emits = defineEmits<NodeResizerEmits>()
(event: 'resizeStart', resizeEvent: OnResizeStart): void
(event: 'resize', resizeEvent: OnResize): void
(event: 'resizeEnd', resizeEvent: OnResizeStart): void
}>()
const { findNode, emits: triggerEmits } = useVueFlow() const { findNode, emits: triggerEmits } = useVueFlow()
+8 -15
View File
@@ -3,10 +3,9 @@ import type { NodeChange, NodeDimensionChange, NodePositionChange } from '@vue-f
import { clamp, useGetPointerPosition, useVueFlow } from '@vue-flow/core' import { clamp, useGetPointerPosition, useVueFlow } from '@vue-flow/core'
import { select } from 'd3-selection' import { select } from 'd3-selection'
import { drag } from 'd3-drag' import { drag } from 'd3-drag'
import { computed, ref, watchEffect } from 'vue' import { ref, toRef, watchEffect } from 'vue'
import type { OnResize, OnResizeStart, ResizeControlProps, ResizeDragEvent } from './types' import type { NodeResizerEmits, ResizeControlProps, ResizeControlVariant, ResizeDragEvent } from './types'
import { ResizeControlVariant } from './types' import { DefaultPositions, StylingProperty, getDirection } from './utils'
import { getDirection } from './utils'
const props = withDefaults(defineProps<ResizeControlProps>(), { const props = withDefaults(defineProps<ResizeControlProps>(), {
variant: 'handle' as ResizeControlVariant, variant: 'handle' as ResizeControlVariant,
@@ -17,11 +16,7 @@ const props = withDefaults(defineProps<ResizeControlProps>(), {
keepAspectRatio: false, keepAspectRatio: false,
}) })
const emits = defineEmits<{ const emits = defineEmits<NodeResizerEmits>()
(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 } const initPrevValues = { width: 0, height: 0, x: 0, y: 0 }
@@ -42,9 +37,11 @@ let startValues: typeof initStartValues = initStartValues
let prevValues: typeof initPrevValues = initPrevValues 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) => { watchEffect((onCleanup) => {
if (!resizeControlRef.value || !props.nodeId) { if (!resizeControlRef.value || !props.nodeId) {
@@ -228,10 +225,6 @@ watchEffect((onCleanup) => {
selection.on('.drag', null) 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>
<script lang="ts"> <script lang="ts">
@@ -1,15 +1,11 @@
<script lang="ts" setup> <script lang="ts" setup>
import ResizeControl from './ResizeControl.vue' import ResizeControl from './ResizeControl.vue'
import type { OnResize, OnResizeStart, ResizeControlLineProps } from './types' import type { NodeResizerEmits, ResizeControlLineProps } from './types'
import { ResizeControlVariant } from './types' import { ResizeControlVariant } from './types'
const props = defineProps<ResizeControlLineProps>() const props = defineProps<ResizeControlLineProps>()
const emits = defineEmits<{ const emits = defineEmits<NodeResizerEmits>()
(event: 'resizeStart', resizeEvent: OnResizeStart): void
(event: 'resize', resizeEvent: OnResize): void
(event: 'resizeEnd', resizeEvent: OnResizeStart): void
}>()
</script> </script>
<script lang="ts"> <script lang="ts">
+12
View File
@@ -1,3 +1,5 @@
import { ResizeControlVariant } from './types'
interface GetDirectionParams { interface GetDirectionParams {
width: number width: number
prevWidth: number prevWidth: number
@@ -25,3 +27,13 @@ export function getDirection({ width, prevWidth, height, prevHeight, invertX, in
return direction return direction
} }
export const DefaultPositions = {
[ResizeControlVariant.Line]: 'right',
[ResizeControlVariant.Handle]: 'bottom-right',
}
export const StylingProperty = {
[ResizeControlVariant.Line]: 'borderColor',
[ResizeControlVariant.Handle]: 'backgroundColor',
}
+31 -31
View File
@@ -1,5 +1,5 @@
<script lang="ts" setup> <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 type { GraphNode, Rect, ViewportTransform } from '@vue-flow/core'
import { NodeIdInjection, Position, getRectOfNodes, useVueFlow } 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 { 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 { function getTransform(nodeRect: Rect, transform: ViewportTransform, position: Position, offset: number, align: Align): string {
let alignmentOffset = 0.5 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]}%)` 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>
<script lang="ts"> <script lang="ts">