docs: add teleport example
This commit is contained in:
@@ -14,6 +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'
|
||||||
|
|
||||||
export const exampleImports = {
|
export const exampleImports = {
|
||||||
basic: {
|
basic: {
|
||||||
@@ -89,4 +90,9 @@ export const exampleImports = {
|
|||||||
'App.vue': HorizontalApp,
|
'App.vue': HorizontalApp,
|
||||||
'initial-elements.js': HorizontalElements,
|
'initial-elements.js': HorizontalElements,
|
||||||
},
|
},
|
||||||
|
teleport: {
|
||||||
|
'App.vue': TeleportApp,
|
||||||
|
'Sidebar.vue': TeleportSidebar,
|
||||||
|
'style.css': TeleportCSS,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
<script setup>
|
||||||
|
import { VueFlow, useVueFlow } from '@braks/vue-flow'
|
||||||
|
import { reactive, ref } from 'vue'
|
||||||
|
import Sidebar from './Sidebar.vue'
|
||||||
|
|
||||||
|
const elements = ref([
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
label: 'Click to teleport',
|
||||||
|
position: { x: 125, y: 0 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
label: 'Click to teleport',
|
||||||
|
position: { x: 250, y: 100 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '3',
|
||||||
|
label: 'Click to teleport',
|
||||||
|
position: { x: 0, y: 100 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'e1-2',
|
||||||
|
source: '1',
|
||||||
|
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>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="teleportflow">
|
||||||
|
<VueFlow v-model="elements" :fit-view-on-init="true" />
|
||||||
|
<Sidebar />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<script setup>
|
||||||
|
//
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<aside>
|
||||||
|
<div class="description">Teleport destination</div>
|
||||||
|
<div id="port" class="port"></div>
|
||||||
|
</aside>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export { default as TeleportApp } from './App.vue?raw'
|
||||||
|
export { default as TeleportSidebar } from './Sidebar.vue?raw'
|
||||||
|
export { default as TeleportCSS } from './style.css'
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
.teleportflow {
|
||||||
|
flex-direction: column;
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.teleportflow aside {
|
||||||
|
color: white;
|
||||||
|
font-weight: 700;
|
||||||
|
border-right: 1px solid #eee;
|
||||||
|
padding: 15px 10px;
|
||||||
|
font-size: 12px;
|
||||||
|
background: rgba(16, 185, 129, 0.75);
|
||||||
|
-webkit-box-shadow: 0px 5px 10px 0px rgba(0,0,0,0.3);
|
||||||
|
box-shadow: 0px 5px 10px 0px rgba(0,0,0,0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.teleportflow aside .port > * {
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
cursor: grab;
|
||||||
|
font-weight: 500;
|
||||||
|
-webkit-box-shadow: 5px 5px 10px 2px rgba(0,0,0,0.25);
|
||||||
|
box-shadow: 5px 5px 10px 2px rgba(0,0,0,0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.teleportflow aside .description {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.teleportflow .vue-flow-wrapper {
|
||||||
|
flex-grow: 1;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 640px) {
|
||||||
|
.teleportflow {
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.teleportflow aside {
|
||||||
|
min-width: 25%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 639px) {
|
||||||
|
.teleportflow aside .port {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -115,6 +115,7 @@ export default defineUserConfig<DefaultThemeOptions>({
|
|||||||
'/examples/interaction',
|
'/examples/interaction',
|
||||||
'/examples/multi',
|
'/examples/multi',
|
||||||
'/examples/horizontal',
|
'/examples/horizontal',
|
||||||
|
'/examples/teleport',
|
||||||
'/examples/pinia',
|
'/examples/pinia',
|
||||||
'/examples/stress',
|
'/examples/stress',
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
pageClass: examples
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Teleport
|
||||||
|
|
||||||
|
Teleport your nodes to another dom element using Vue 3 [`Teleport`](https://vuejs.org/guide/built-ins/teleport.html).
|
||||||
|
|
||||||
|
<div class="mt-6">
|
||||||
|
<client-only>
|
||||||
|
<Suspense>
|
||||||
|
<Repl example="teleport"></Repl>
|
||||||
|
</Suspense>
|
||||||
|
</client-only>
|
||||||
|
</div>
|
||||||
Reference in New Issue
Block a user