docs: add teleportable example

This commit is contained in:
bcakmakoglu
2022-05-27 23:36:01 +02:00
committed by Braks
parent e38cb4e0c2
commit 5d94a988c7
8 changed files with 109 additions and 79 deletions
+2 -1
View File
@@ -14,7 +14,7 @@ import { HiddenApp } from './hidden'
import { InteractionApp, InteractionCSS, InteractionControls } from './interaction' import { InteractionApp, InteractionCSS, InteractionControls } from './interaction'
import { MultiApp, MultiCSS, MultiFlow } from './multi' import { MultiApp, MultiCSS, MultiFlow } from './multi'
import { HorizontalApp, HorizontalElements } from './horizontal' import { HorizontalApp, HorizontalElements } from './horizontal'
import { TeleportApp, TeleportSidebar, TeleportCSS } from './teleport' import { TeleportApp, TeleportCSS, TeleportSidebar, TeleportableNode } from './teleport'
export const exampleImports = { export const exampleImports = {
basic: { basic: {
@@ -93,6 +93,7 @@ export const exampleImports = {
teleport: { teleport: {
'App.vue': TeleportApp, 'App.vue': TeleportApp,
'Sidebar.vue': TeleportSidebar, 'Sidebar.vue': TeleportSidebar,
'TeleportableNode.vue': TeleportableNode,
'style.css': TeleportCSS, 'style.css': TeleportCSS,
}, },
} }
+13 -34
View File
@@ -1,23 +1,30 @@
<script setup> <script setup>
import { VueFlow, useVueFlow } from '@braks/vue-flow' import { VueFlow, useVueFlow } from '@braks/vue-flow'
import { reactive, ref } from 'vue' import { ref } from 'vue'
import Sidebar from './Sidebar.vue' import Sidebar from './Sidebar.vue'
import TeleportableNode from './TeleportableNode.vue'
const elements = ref([ const elements = ref([
{ {
id: '1', id: '1',
label: 'Click to teleport', label: 'Click to teleport',
type: 'teleportable',
position: { x: 125, y: 0 }, position: { x: 125, y: 0 },
data: {},
}, },
{ {
id: '2', id: '2',
label: 'Click to teleport', label: 'Click to teleport',
type: 'teleportable',
position: { x: 250, y: 100 }, position: { x: 250, y: 100 },
data: {},
}, },
{ {
id: '3', id: '3',
label: 'Click to teleport', label: 'Click to teleport',
type: 'teleportable',
position: { x: 0, y: 100 }, position: { x: 0, y: 100 },
data: {},
}, },
{ {
id: 'e1-2', id: 'e1-2',
@@ -25,43 +32,15 @@ const elements = ref([
target: '2', target: '2',
}, },
]) ])
const { onNodeClick } = useVueFlow()
const lastPositions = {}
onNodeClick(({ node, connectedEdges }) => {
/**
* specify a selector to teleport to
* beware that teleports only work after viewpane is ready
*
* teleported elements still behave like they're at their position before,
* i.e. if they emit events, they will still emit them up their regular tree
*/
const target = node.teleport ? null : '#port'
// teleport to target or disable teleport
node.teleport = target
// hide connected edges when teleporting
connectedEdges.forEach((edge) => (edge.hidden = !!target))
if (!target) {
// apply last position (so the transformation gets applied)
node.position = lastPositions[node.id]
} else {
// save last position
lastPositions[node.id] = Object.assign({}, { ...node.position })
// remove current position (so the transformation gets removed)
node.position = { x: 0, y: 0 }
}
})
</script> </script>
<template> <template>
<div class="teleportflow"> <div class="teleportflow">
<VueFlow v-model="elements" :fit-view-on-init="true" /> <VueFlow v-model="elements" :fit-view-on-init="true">
<template #node-teleportable="props">
<TeleportableNode :id="props.id" />
</template>
</VueFlow>
<Sidebar /> <Sidebar />
</div> </div>
</template> </template>
@@ -0,0 +1,45 @@
<script setup>
import { Handle, Position, getConnectedEdges, useVueFlow } from '@braks/vue-flow'
import { ref } from 'vue'
const props = defineProps({
id: {
type: String,
required: true,
},
})
const { edges, getNode } = useVueFlow()
const teleport = ref(null)
const onClick = () => {
/**
* specify a selector to teleport to
*
* teleported elements still behave like they're at their position before,
* i.e. if they emit events, they will still emit them up their regular tree
*/
const target = teleport.value ? null : '#port'
// teleport to target or disable teleport
teleport.value = target
// hide connected edges when teleporting
const connectedEdges = getConnectedEdges([getNode.value(props.id)], edges.value)
console.log(connectedEdges)
connectedEdges.forEach((edge) => (edge.hidden = !!target))
}
</script>
<template>
<teleport :disabled="!teleport" :to="teleport">
<div class="teleportable" @click.prevent="onClick">
<Handle type="target" :position="Position.Top" />
Click to teleport
<Handle type="source" :position="Position.Bottom" />
</div>
</teleport>
</template>
@@ -1,3 +1,4 @@
export { default as TeleportApp } from './App.vue?raw' export { default as TeleportApp } from './App.vue?raw'
export { default as TeleportSidebar } from './Sidebar.vue?raw' export { default as TeleportSidebar } from './Sidebar.vue?raw'
export { default as TeleportableNode } from './TeleportableNode.vue?raw'
export { default as TeleportCSS } from './style.css' export { default as TeleportCSS } from './style.css'
@@ -50,3 +50,11 @@
gap: 5px; gap: 5px;
} }
} }
.teleportable {
padding: 10px;
background: white;
border: 1px solid black;
border-radius: 10px;
color: black
}
+1
View File
@@ -29,6 +29,7 @@ declare module 'vue' {
Repl: typeof import('./../../components/Repl.vue')['default'] Repl: typeof import('./../../components/Repl.vue')['default']
RGB: typeof import('./../../components/home/flows/RGB.vue')['default'] RGB: typeof import('./../../components/home/flows/RGB.vue')['default']
Sidebar: typeof import('./../../components/examples/dnd/Sidebar.vue')['default'] Sidebar: typeof import('./../../components/examples/dnd/Sidebar.vue')['default']
TeleportableNode: typeof import('./../../components/examples/teleport/TeleportableNode.vue')['default']
} }
} }
@@ -246,7 +246,6 @@ export default {
</script> </script>
<template> <template>
<Teleport :disabled="!node.teleport" :to="node.teleport">
<div <div
ref="nodeElement" ref="nodeElement"
:class="getClass" :class="getClass"
@@ -281,5 +280,4 @@ export default {
:node-element="nodeElement" :node-element="nodeElement"
/> />
</div> </div>
</Teleport>
</template> </template>
+1 -4
View File
@@ -1,4 +1,4 @@
import type { Component, TeleportProps, VNode } from 'vue' import type { Component, VNode } from 'vue'
import type { BaseElement, Dimensions, ElementData, Position, SnapGrid, XYPosition, XYZPosition } from './flow' import type { BaseElement, Dimensions, ElementData, Position, SnapGrid, XYPosition, XYZPosition } from './flow'
import type { DefaultNodeTypes, NodeComponent } from './components' import type { DefaultNodeTypes, NodeComponent } from './components'
import type { HandleElement, ValidConnectionFunc } from './handle' import type { HandleElement, ValidConnectionFunc } from './handle'
@@ -69,9 +69,6 @@ export interface GraphNode<Data = ElementData> extends Node<Data> {
isParent: boolean isParent: boolean
selected: boolean selected: boolean
dragging: boolean dragging: boolean
/** teleports node element to specified dom location, this property is _not_ available on initial load, only after viewpane is ready */
teleport?: TeleportProps['to']
} }
/** these props are passed to node components */ /** these props are passed to node components */