update(docs): Add all examples

This commit is contained in:
Braks
2021-11-06 08:54:35 +01:00
parent 61779638ac
commit e99dfc3dd2
54 changed files with 2582 additions and 285 deletions
+80
View File
@@ -0,0 +1,80 @@
<script lang="ts" setup>
import {
useHooks,
useStore,
getEdgeCenter,
getBezierPath,
getMarkerEnd,
ArrowHeadType,
EdgeProps,
ElementId,
Position,
} from '@braks/vue-flow'
interface CustomEdgeProps<T = any> extends EdgeProps<T> {
id: ElementId
sourceX: number
sourceY: number
targetX: number
targetY: number
sourcePosition: Position
targetPosition: Position
arrowHeadType?: ArrowHeadType
markerEndId?: string
data?: T
}
const props = defineProps<CustomEdgeProps>()
const store = useStore()
const hooks = useHooks()
const onEdgeClick = (evt: Event, id: string) => {
const edge = store.edges.find((edge) => edge.id === id)
if (edge) {
hooks.elementsRemove.trigger([edge])
}
evt.stopPropagation()
alert(`remove ${id}`)
}
const foreignObjectSize = 40
const edgePath = computed(() =>
getBezierPath({
sourceX: props.sourceX,
sourceY: props.sourceY,
sourcePosition: props.sourcePosition,
targetX: props.targetX,
targetY: props.targetY,
targetPosition: props.targetPosition,
}),
)
const markerEnd = computed(() => getMarkerEnd(props.arrowHeadType, props.markerEndId))
const center = computed(() =>
getEdgeCenter({
sourceX: props.sourceX,
sourceY: props.sourceY,
targetX: props.targetX,
targetY: props.targetY,
}),
)
</script>
<template>
<path :id="props.id" :style="props.style" class="vue-flow__edge-path" :d="edgePath" :marker-end="markerEnd" />
<foreignObject
:width="foreignObjectSize"
:height="foreignObjectSize"
:x="center[0] - foreignObjectSize / 2"
:y="center[1] - foreignObjectSize / 2"
class="edgebutton-foreignobject"
requiredExtensions="http://www.w3.org/1999/xhtml"
>
<body class="p-1">
<button class="edgebutton bg-gray-500 p-[4px] h-full w-full" @click="(event) => onEdgeClick(event, props.id)">×</button>
</body>
</foreignObject>
</template>
<style scoped>
body {
background: unset;
}
</style>
+38
View File
@@ -0,0 +1,38 @@
<script lang="ts" setup>
import { CSSProperties } from 'vue'
import { Handle, Position, Connection, Edge, NodeProps } from '@braks/vue-flow'
interface ColorSelectorNodeProps extends NodeProps {
data: {
color: string
onChange: (event: any) => void
}
type: string
selected?: boolean
connectable?: boolean
xPos?: number
yPos?: number
targetPosition?: Position
sourcePosition?: Position
dragging?: boolean
}
const props = defineProps<ColorSelectorNodeProps>()
const targetHandleStyle: CSSProperties = { background: '#555' }
const sourceHandleStyleA: CSSProperties = { ...targetHandleStyle, top: '10px' }
const sourceHandleStyleB: CSSProperties = { ...targetHandleStyle, bottom: '10px', top: 'auto' }
const onConnect = (params: Connection | Edge) => console.log('handle onConnect', params)
</script>
<template>
<div class="py-1 px-1 flex flex-col gap-1 justify-center items-center">
<Handle type="target" :position="Position.Left" :style="targetHandleStyle" :on-connect="onConnect" />
<div class="text-md font-bold">Custom Color Picker Node</div>
<div :style="{ color: data.color }" class="text-md font-semibold">
{{ data.color }}
</div>
<input class="nodrag" type="color" :value="data.color" @input="props.data.onChange" />
<Handle id="a" type="source" :position="Position.Right" :style="sourceHandleStyleA" />
<Handle id="b" type="source" :position="Position.Right" :style="sourceHandleStyleB" />
</div>
</template>
+23
View File
@@ -0,0 +1,23 @@
<script lang="ts" setup>
import { ConnectionLineComponentProps } from '@braks/vue-flow'
interface ConnectionLineProps extends ConnectionLineComponentProps {
sourceX: number
sourceY: number
targetX: number
targetY: number
}
const props = defineProps<ConnectionLineProps>()
</script>
<template>
<g>
<path
class="animated"
fill="none"
stroke="#222"
:stroke-width="1.5"
:d="`M${props.sourceX},${props.sourceY} C ${props.sourceX} ${props.targetY} ${props.sourceX} ${props.targetY} ${props.targetX},${props.targetY}`"
/>
<circle :cx="props.targetX" :cy="props.targetY" fill="#fff" :r="3" stroke="#222" :stroke-width="1.5" />
</g>
</template>
+41
View File
@@ -0,0 +1,41 @@
<script lang="ts" setup>
import { ArrowHeadType, ElementId, getBezierPath, getMarkerEnd, Position, EdgeProps } from '@braks/vue-flow'
interface CustomEdgeProps<T = any> extends EdgeProps<T> {
source: ElementId
target: ElementId
sourceHandleId?: ElementId
targetHandleId?: ElementId
id: ElementId
sourceX: number
sourceY: number
targetX: number
targetY: number
sourcePosition: Position
targetPosition: Position
arrowHeadType?: ArrowHeadType
markerEndId?: string
data?: T
}
const props = defineProps<CustomEdgeProps>()
const edgePath = computed(() =>
getBezierPath({
sourceX: props.sourceX,
sourceY: props.sourceY,
sourcePosition: props.sourcePosition,
targetX: props.targetX,
targetY: props.targetY,
targetPosition: props.targetPosition,
}),
)
const markerEnd = computed(() => getMarkerEnd(props.arrowHeadType, props.markerEndId))
</script>
<template>
<path :id="props.id" class="vue-flow__edge-path" :d="edgePath" :marker-end="markerEnd" />
<text>
<textPath :href="`#${props.id}`" :style="{ fontSize: '12px' }" startOffset="50%" text-anchor="middle">
{{ props.data.text }}
</textPath>
</text>
</template>
+65
View File
@@ -0,0 +1,65 @@
<script lang="ts" setup>
import {
getBezierPath,
getMarkerEnd,
ArrowHeadType,
EdgeProps,
ElementId,
getEdgeCenter,
Position,
EdgeText,
} from '@braks/vue-flow'
interface CustomEdgeProps<T = any> extends EdgeProps<T> {
source: ElementId
target: ElementId
sourceHandleId?: ElementId
targetHandleId?: ElementId
id: ElementId
sourceX: number
sourceY: number
targetX: number
targetY: number
sourcePosition: Position
targetPosition: Position
arrowHeadType?: ArrowHeadType
markerEndId?: string
data?: T
}
const props = defineProps<CustomEdgeProps>()
const edgePath = computed(() =>
getBezierPath({
sourceX: props.sourceX,
sourceY: props.sourceY,
sourcePosition: props.sourcePosition,
targetX: props.targetX,
targetY: props.targetY,
targetPosition: props.targetPosition,
}),
)
const markerEnd = computed(() => getMarkerEnd(props.arrowHeadType, props.markerEndId))
const center = computed(() =>
getEdgeCenter({
sourceX: props.sourceX,
sourceY: props.sourceY,
targetX: props.targetX,
targetY: props.targetY,
}),
)
</script>
<template>
<path :id="props.id" class="vue-flow__edge-path" :d="edgePath" :marker-end="markerEnd" />
<EdgeText
:x="center[0]"
:y="center[1]"
:label="props.data?.text"
:label-style="{ fill: 'white' }"
:label-show-bg="true"
:label-bg-style="{ fill: 'red' }"
:label-bg-padding="[2, 4]"
:label-bg-border-radius="2"
@click="() => console.log(props.data)"
/>
</template>
+10
View File
@@ -0,0 +1,10 @@
<script lang="ts" setup>
interface CustomLabelProps {
text: string
}
const props = defineProps<CustomLabelProps>()
</script>
<template>
<tspan dy="10" x="0">{{ props.text }}</tspan>
</template>
+47
View File
@@ -0,0 +1,47 @@
<script lang="ts" setup>
const onDragStart = (event: DragEvent, nodeType: string) => {
if (event.dataTransfer) {
event.dataTransfer.setData('application/vueflow', nodeType)
event.dataTransfer.effectAllowed = 'move'
}
}
</script>
<template>
<aside class="md:(w-[30%] max-w-[200px])">
<div class="mb-6">You can drag these nodes to the pane on the left.</div>
<div
class="droppable-node vue-flow__node-input"
:draggable="true"
@dragstart="(event: DragEvent) => onDragStart(event, 'input')"
>
Input Node
</div>
<div
class="droppable-node vue-flow__node-default"
:draggable="true"
@dragstart="(event: DragEvent) => onDragStart(event, 'default')"
>
Default Node
</div>
<div
class="droppable-node vue-flow__node-output"
:draggable="true"
@dragstart="(event: DragEvent) => onDragStart(event, 'output')"
>
Output Node
</div>
</aside>
</template>
<style scoped>
aside {
border-right: 1px solid #eee;
padding: 15px 10px;
font-size: 12px;
background: #fcfcfc;
}
.droppable-node {
@apply mb-6;
cursor: grab;
}
</style>
+20
View File
@@ -0,0 +1,20 @@
<script lang="ts" setup>
import Flow, { Background, Connection, Elements, Edge, removeElements, addEdge } from '@braks/vue-flow'
const initialElements: Elements = [
{ id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 }, class: 'light' },
{ id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 100 }, class: 'light' },
{ id: '3', data: { label: 'Node 3' }, position: { x: 400, y: 100 }, class: 'light' },
{ id: '4', data: { label: 'Node 4' }, position: { x: 400, y: 200 }, class: 'light' },
{ id: 'e1-2', source: '1', target: '2', animated: true },
{ id: 'e1-3', source: '1', target: '3' },
]
const elements = ref<Elements>(initialElements)
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value))
const onElementsRemove = (elementsToRemove: Elements) => (elements.value = removeElements(elementsToRemove, elements.value))
</script>
<template>
<Flow :elements="elements" @elements-remove="onElementsRemove" @connect="onConnect">
<Background />
</Flow>
</template>
+1 -1
View File
@@ -11,6 +11,6 @@
<div class="flex-1">
<router-link to="/examples"> Examples </router-link>
</div>
<div class="flex-1">Github</div>
<div class="flex-1"><a href="https://github.com/bcakmakoglu/vue-flow">Github</a></div>
</header>
</template>
+11
View File
@@ -0,0 +1,11 @@
<script lang="ts" setup>
import { NodeProps } from '@braks/vue-flow'
interface NodeAProps extends NodeProps {
nodeStyles: Record<string, any>
}
const props = defineProps<NodeAProps>()
</script>
<template>
<div :style="props.nodeStyles">A</div>
</template>
+11
View File
@@ -0,0 +1,11 @@
<script lang="ts" setup>
import { NodeProps } from '@braks/vue-flow'
interface NodeBPro extends NodeProps {
nodeStyles: Record<string, any>
}
const props = defineProps<NodeBPro>()
</script>
<template>
<div :style="props.nodeStyles">B</div>
</template>
+27
View File
@@ -0,0 +1,27 @@
<script lang="ts" setup>
import { useStore } from '@braks/vue-flow'
const store = useStore()
const nodes = computed(() => store.nodes)
const transform = computed(() => store.transform)
const selectAll = () => {
store.selectedElements = nodes.value
store.unsetUserSelection()
}
</script>
<template>
<aside>
<div class="description">This is an example of how you can access the internal state outside of the Vue Flow component.</div>
<div class="title">Zoom & pan transform</div>
<div class="transform">{{ [transform[0].toFixed(2), transform[1].toFixed(2), transform[2].toFixed(2)] }}</div>
<div class="title">Nodes</div>
<div v-for="node of nodes" :key="node.id">
Node {{ node.id }} - x: {{ node.__rf.position.x.toFixed(2) }}, y: {{ node.__rf.position.y.toFixed(2) }}
</div>
<div class="selectall">
<button class="button" @click="selectAll">select all nodes</button>
</div>
</aside>
</template>
+60
View File
@@ -0,0 +1,60 @@
<script lang="ts" setup>
import localforage from 'localforage'
import { useZoomPanHelper, FlowInstance, FlowExportObject, Node } from '@braks/vue-flow'
localforage.config({
name: 'vue-flow',
storeName: 'flows',
})
const flowKey = 'example-flow'
const getNodeId = () => `randomnode_${+new Date()}`
const { transform } = useZoomPanHelper()
type ControlsProps = {
flowInstance?: FlowInstance
}
const props = defineProps<ControlsProps>()
const emit = defineEmits(['restore', 'add'])
const onSave = () => {
if (props.flowInstance) {
const flow = props.flowInstance.toObject()
localforage.setItem(flowKey, flow)
}
}
const onRestore = () => {
const restoreFlow = async () => {
const flow: FlowExportObject | null = await localforage.getItem(flowKey)
console.log(flow)
if (flow) {
const [x = 0, y = 0] = flow.position
emit('restore', flow.elements ?? [])
transform({ x, y, zoom: flow.zoom || 0 })
}
}
restoreFlow()
}
const onAdd = () => {
const newNode = {
id: `random_node-${getNodeId()}`,
data: { label: 'Added node' },
position: { x: Math.random() * window.innerWidth - 100, y: Math.random() * window.innerHeight },
} as Node
emit('add', newNode)
}
</script>
<template>
<div class="save__controls">
<button class="button" @click="onSave">save</button>
<button class="button" @click="onRestore">restore</button>
<button class="button" @click="onAdd">add node</button>
</div>
</template>
+2 -2
View File
@@ -81,7 +81,7 @@ const examples = [
label: 'Unidirectional',
},
{
path: '/updateable-edge',
path: '/updatable-edge',
label: 'Updatable Edge',
},
{
@@ -119,7 +119,7 @@ const examples = [
</template>
<style>
.example-link {
@apply text-md text-white hover:text-black mt-2 p-2 underline;
@apply text-lg text-white hover:text-black py-2 underline;
}
aside {
border-right: 1px solid #eee;
@@ -0,0 +1,19 @@
<script lang="ts" setup>
import { CSSProperties } from 'vue'
import { Handle, NodeProps, Position } from '@braks/vue-flow'
interface CustomNodeProps extends NodeProps {
id: string
}
const props = defineProps<CustomNodeProps>()
const nodeStyles: CSSProperties = { padding: '10px 15px', border: '1px solid #ddd' }
</script>
<template>
<div :style="nodeStyles">
<div>node {{ props.id }}</div>
<Handle id="left" type="source" :position="Position.Left" />
<Handle id="right" type="source" :position="Position.Right" />
<Handle id="top" type="source" :position="Position.Top" />
<Handle id="bottom" type="source" :position="Position.Bottom" />
</div>
</template>
@@ -0,0 +1,25 @@
<script lang="ts" setup>
import { CSSProperties } from 'vue'
import { Handle, Position, NodeProps } from '@braks/vue-flow'
interface CustomNodeProps extends NodeProps {
data: any
}
const nodeStyles: CSSProperties = { padding: 10, border: '1px solid #ddd' }
const props = defineProps<CustomNodeProps>()
</script>
<template>
<div :style="nodeStyles">
<Handle type="target" :position="Position.Left" />
<div>output handle count: {{ props.data.handleCount }}</div>
<Handle
v-for="i of props.data.handleCount"
:id="`handle-${i}`"
:key="`handle-${i}`"
type="source"
:position="Position.Right"
:style="{ top: 10 * i + props.data.handlePosition * 10 }"
/>
</div>
</template>
@@ -0,0 +1,9 @@
<script lang="ts" setup>
import { Position, Handle, Connection } from '@braks/vue-flow'
const isValidConnection = (connection: Connection) => connection.target === 'B'
</script>
<template>
<div>Only connectable with B</div>
<Handle type="source" :position="Position.Right" :is-valid-connection="isValidConnection" />
</template>
+16
View File
@@ -0,0 +1,16 @@
<script lang="ts" setup>
import { Position, Handle, Connection, NodeProps } from '@braks/vue-flow'
interface CustomNodeProps extends NodeProps {
id: string
}
const props = defineProps<CustomNodeProps>()
const isValidConnection = (connection: Connection) => connection.target === 'B'
</script>
<template>
<Handle type="target" :position="Position.Left" :is-valid-connection="isValidConnection" />
<div>{{ props.id }}</div>
<Handle type="source" :position="Position.Right" :is-valid-connection="isValidConnection" />
</template>