Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 122 additions & 0 deletions docs/components/DocsRepl.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
<script lang="ts" setup>
import type { SFCOptions } from '@vue/repl'
import { ReplStore, Repl as VueRepl } from '@vue/repl'
import { useVueFlow } from '@vue-flow/core'
import '@vue/repl/style.css'
import { isClient } from '@vueuse/core'
import { exampleImports } from './examples'

const props = defineProps<{ example: keyof typeof exampleImports; mainFile?: string; dependencies?: Record<string, string> }>()

const { vueFlowVersion } = useVueFlow()

let css = `@import 'https://cdn.jsdelivr.net/npm/@vue-flow/core@${vueFlowVersion.value}/dist/style.css';
@import 'https://cdn.jsdelivr.net/npm/@vue-flow/core@${vueFlowVersion.value}/dist/theme-default.css';

html,
body,
#app {
margin: 0;
height: 100%;
}

#app {
text-transform: uppercase;
font-family: 'JetBrains Mono', monospace;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}

.vue-flow__minimap {
transform: scale(75%);
transform-origin: bottom right;
}
\n`

const store = new ReplStore({
showOutput: true,
outputMode: 'preview',
})

const vh = useCssVar('--vh')

watchEffect(() => {
vh.value = `${window.innerHeight}px`
})

const files: any = {}
const imports = exampleImports[props.example]
const additionalImports = 'additionalImports' in imports ? imports.additionalImports : {}

for (const example of Object.keys(imports).filter((i) => i !== 'additionalImports')) {
if (example.includes('css')) {
css += `${imports[example as keyof typeof imports]}`
} else {
files[example] = imports[example as keyof typeof imports]
}
}

onMounted(async () => {
await store.setVueVersion('3.2.37')

await store.setFiles(
{
...files,
'main.css': css,
},
props.mainFile ?? 'App.vue',
)

// pre-set import map
await store.setImportMap({
imports: {
'@vue-flow/additional-components': `${location.origin}/vue-flow-additional-components.mjs`,
'@vue-flow/core': `${location.origin}/vue-flow-core.mjs`,
...additionalImports,
},
})

if (isClient) {
document.body.className = 'examples'
}
})

const sfcOptions = {
script: {
reactivityTransform: true,
},
} as SFCOptions
</script>

<template>
<VueRepl
:clear-console="true"
:auto-resize="true"
:store="store"
:show-compile-output="false"
:show-import-map="false"
:sfc-options="sfcOptions"
@keydown.ctrl.s.prevent
@keydown.meta.s.prevent
/>
</template>

<style>
.file-selector {
@apply scrollbar scrollbar-thin scrollbar-thumb-rounded scrollbar-thumb-green-500 scrollbar-track-black;
}

.vue-repl {
--vh: 100vh;

@apply rounded-lg border-1 border-solid dark:border-gray-200/10 border-gray-200;

height: calc(var(--vh) - 72px);
}

.msg.err {
@apply hidden;
}
</style>
126 changes: 12 additions & 114 deletions docs/components/Repl.vue
Original file line number Diff line number Diff line change
@@ -1,117 +1,15 @@
<script lang="ts" setup>
import { ReplStore, Repl as VueRepl } from '@vue/repl'
import { useVueFlow } from '@vue-flow/core'
import '@vue/repl/style.css'
import { exampleImports } from './examples'

const props = defineProps<{ example: keyof typeof exampleImports; mainFile?: string; dependencies?: Record<string, string> }>()
const { vueFlowVersion } = useVueFlow()
let css = `@import 'https://cdn.jsdelivr.net/npm/@vue-flow/core@${vueFlowVersion.value}/dist/style.css';
@import 'https://cdn.jsdelivr.net/npm/@vue-flow/core@${vueFlowVersion.value}/dist/theme-default.css';

html,
body,
#app {
margin: 0;
height: 100%;
}

#app {
text-transform: uppercase;
font-family: 'JetBrains Mono', monospace;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}

.vue-flow__minimap {
transform: scale(75%);
transform-origin: bottom right;
}
\n`

const store = new ReplStore({
showOutput: true,
outputMode: 'preview',
})

const vh = useCssVar('--vh')

watchEffect(
() => {
vh.value = `${window.innerHeight}px`
<script>
import { isClient } from '@vueuse/core'
import DocsRepl from './DocsRepl.vue'

export default defineComponent({
props: ['example'],
setup(props) {
return () => {
if (!isClient) return null

return h(DocsRepl, props)
}
},
{ flush: 'post' },
)

const files: any = {}
const imports = exampleImports[props.example]
const additionalImports = 'additionalImports' in imports ? imports.additionalImports : {}

for (const example of Object.keys(imports).filter((i) => i !== 'additionalImports')) {
if (example.includes('css')) {
css += `${imports[example as keyof typeof imports]}`
} else {
files[example] = imports[example as keyof typeof imports]
}
}

onMounted(async () => {
await store.setVueVersion('3.2.37')

await store.setFiles(
{
...files,
'main.css': css,
},
props.mainFile ?? 'App.vue',
)

// pre-set import map
store.setImportMap({
imports: {
'@vue-flow/additional-components': `${location.origin}/vue-flow-additional-components.mjs`,
'@vue-flow/core': `${location.origin}/vue-flow-core.mjs`,
...additionalImports,
},
})
})

const sfcOptions = {
script: {
reactivityTransform: true,
},
}
</script>

<template>
<VueRepl
:clear-console="true"
:auto-resize="true"
:store="store"
:show-compile-output="false"
:show-import-map="false"
:sfc-options="sfcOptions"
@keydown.ctrl.s.prevent
@keydown.meta.s.prevent
/>
</template>

<style>
.file-selector {
@apply scrollbar scrollbar-thin scrollbar-thumb-rounded scrollbar-thumb-green-500 scrollbar-track-black;
}

.vue-repl {
--vh: 100vh;

@apply rounded-lg border-1 border-solid dark:border-gray-200/10 border-gray-200;

height: calc(var(--vh) - 72px);
}

.msg.err {
@apply hidden;
}
</style>
62 changes: 48 additions & 14 deletions docs/components/examples/basic/App.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup>
import { Background, Controls, MiniMap } from '@vue-flow/additional-components'
import { Background, Controls, MiniMap, Panel, PanelPosition } from '@vue-flow/additional-components'
import { VueFlow, isNode, useVueFlow } from '@vue-flow/core'
import { ref } from 'vue'
import { initialElements } from './initial-elements.js'
Expand Down Expand Up @@ -58,28 +58,62 @@ const logToObject = () => console.log(toObject())
*/
const resetTransform = () => setTransform({ x: 0, y: 0, zoom: 1 })

const toggleClass = () => {
dark.value = !dark.value
elements.value.forEach((el) => (el.class = dark.value ? 'dark' : 'light'))
}
const toggleClass = () => (dark.value = !dark.value)
</script>

<template>
<VueFlow v-model="elements" class="basicflow" :default-zoom="1.5" :min-zoom="0.2" :max-zoom="4">
<Background pattern-color="#aaa" gap="8" />
<VueFlow v-model="elements" :class="{ dark }" class="basicflow" :default-zoom="1.5" :min-zoom="0.2" :max-zoom="4">
<Background :pattern-color="dark ? '#FFFFFB' : '#aaa'" gap="8" />
<MiniMap />
<Controls />

<div class="controls">
<button style="background-color: #113285; color: white" @click="resetTransform">reset transform</button>
<button style="background-color: #6f3381; color: white" @click="updatePos">update positions</button>
<Panel :position="PanelPosition.TopRight" class="controls">
<button style="background-color: #113285; color: white" title="Reset Transform" @click="resetTransform">
<svg width="16" height="16" viewBox="0 0 32 32">
<path fill="#FFFFFB" d="M18 28A12 12 0 1 0 6 16v6.2l-3.6-3.6L1 20l6 6l6-6l-1.4-1.4L8 22.2V16a10 10 0 1 1 10 10Z" />
</svg>
</button>

<button style="background-color: #6f3381" title="Shuffle Node Positions" @click="updatePos">
<svg width="16" height="16" viewBox="0 0 24 24">
<path
fill="#FFFFFB"
d="M14 20v-2h2.6l-3.2-3.2l1.425-1.425L18 16.55V14h2v6Zm-8.6 0L4 18.6L16.6 6H14V4h6v6h-2V7.4Zm3.775-9.425L4 5.4L5.4 4l5.175 5.175Z"
/>
</svg>
</button>

<button
:style="{ backgroundColor: dark ? '#FFFFFB' : '#1C1C1C', color: dark ? '#1C1C1C' : '#FFFFFB' }"
:style="{ backgroundColor: dark ? '#FFFFFB' : '#292524', color: dark ? '#292524' : '#FFFFFB' }"
@click="toggleClass"
>
toggle {{ dark ? 'light' : 'dark' }}
<template v-if="dark">
<svg width="16" height="16" viewBox="0 0 24 24">
<path
fill="#292524"
d="M12 17q-2.075 0-3.537-1.463Q7 14.075 7 12t1.463-3.538Q9.925 7 12 7t3.538 1.462Q17 9.925 17 12q0 2.075-1.462 3.537Q14.075 17 12 17ZM2 13q-.425 0-.712-.288Q1 12.425 1 12t.288-.713Q1.575 11 2 11h2q.425 0 .713.287Q5 11.575 5 12t-.287.712Q4.425 13 4 13Zm18 0q-.425 0-.712-.288Q19 12.425 19 12t.288-.713Q19.575 11 20 11h2q.425 0 .712.287q.288.288.288.713t-.288.712Q22.425 13 22 13Zm-8-8q-.425 0-.712-.288Q11 4.425 11 4V2q0-.425.288-.713Q11.575 1 12 1t.713.287Q13 1.575 13 2v2q0 .425-.287.712Q12.425 5 12 5Zm0 18q-.425 0-.712-.288Q11 22.425 11 22v-2q0-.425.288-.712Q11.575 19 12 19t.713.288Q13 19.575 13 20v2q0 .425-.287.712Q12.425 23 12 23ZM5.65 7.05L4.575 6q-.3-.275-.288-.7q.013-.425.288-.725q.3-.3.725-.3t.7.3L7.05 5.65q.275.3.275.7q0 .4-.275.7q-.275.3-.687.287q-.413-.012-.713-.287ZM18 19.425l-1.05-1.075q-.275-.3-.275-.712q0-.413.275-.688q.275-.3.688-.287q.412.012.712.287L19.425 18q.3.275.288.7q-.013.425-.288.725q-.3.3-.725.3t-.7-.3ZM16.95 7.05q-.3-.275-.287-.688q.012-.412.287-.712L18 4.575q.275-.3.7-.288q.425.013.725.288q.3.3.3.725t-.3.7L18.35 7.05q-.3.275-.7.275q-.4 0-.7-.275ZM4.575 19.425q-.3-.3-.3-.725t.3-.7l1.075-1.05q.3-.275.713-.275q.412 0 .687.275q.3.275.288.688q-.013.412-.288.712L6 19.425q-.275.3-.7.287q-.425-.012-.725-.287Z"
/>
</svg>
</template>

<template v-else>
<svg width="16" height="16" viewBox="0 0 24 24">
<path
fill="#FFFFFB"
d="M12 21q-3.75 0-6.375-2.625T3 12q0-3.75 2.625-6.375T12 3q.35 0 .688.025q.337.025.662.075q-1.025.725-1.637 1.887Q11.1 6.15 11.1 7.5q0 2.25 1.575 3.825Q14.25 12.9 16.5 12.9q1.375 0 2.525-.613q1.15-.612 1.875-1.637q.05.325.075.662Q21 11.65 21 12q0 3.75-2.625 6.375T12 21Z"
/>
</svg>
</template>
</button>

<button title="Log `toObject`" @click="logToObject">
<svg width="16" height="16" viewBox="0 0 24 24">
<path
fill="#292524"
d="M20 19V7H4v12h16m0-16a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h16m-7 14v-2h5v2h-5m-3.42-4L5.57 9H8.4l3.3 3.3c.39.39.39 1.03 0 1.42L8.42 17H5.59l3.99-4Z"
/>
</svg>
</button>
<button @click="logToObject">log toObject</button>
</div>
</Panel>
</VueFlow>
</template>
5 changes: 2 additions & 3 deletions docs/components/examples/basic/initial-elements.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,20 @@ import { MarkerType } from '@vue-flow/core'
* or split them up into nodes and edges and pass them to the `nodes` and `edges` props of Vue Flow (or useVueFlow composable)
*/
export const initialElements = [
{ id: '1', type: 'input', label: 'Node 1', position: { x: 250, y: 5 }, class: 'light' },
{ id: '1', type: 'input', label: 'Node 1', position: { x: 250, y: 0 }, class: 'light' },
{ id: '2', type: 'output', label: 'Node 2', position: { x: 100, y: 100 }, class: 'light' },
{ id: '3', label: 'Node 3', position: { x: 400, y: 100 }, class: 'light' },
{ id: '4', label: 'Node 4', position: { x: 150, y: 200 }, class: 'light' },
{ id: '5', type: 'output', label: 'Node 5', position: { x: 300, y: 300 }, class: 'light' },
{ id: 'e1-2', source: '1', target: '2', animated: true },
{ id: 'e1-3', label: 'edge with arrowhead', source: '1', target: '3', markerEnd: MarkerType.Arrow },
{ id: 'e1-3', label: 'edge with arrowhead', source: '1', target: '3', markerEnd: MarkerType.ArrowClosed },
{
id: 'e4-5',
type: 'step',
label: 'step-edge',
source: '4',
target: '5',
style: { stroke: 'orange' },
labelStyle: { stroke: 'black' },
labelBgStyle: { fill: 'orange' },
},
{ id: 'e3-4', type: 'smoothstep', label: 'smoothstep-edge', source: '3', target: '4' },
Expand Down
Loading