update(docs): Add windicss
* remove unused files
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue'
|
||||
import { VueFlow, Background, Elements, isNode, MarkerType, useVueFlow } from '@braks/vue-flow'
|
||||
|
||||
const elements = ref<Elements>([
|
||||
{ id: '1', type: 'input', label: 'Input Node', position: { x: 250, y: 15 } },
|
||||
{ id: '2', label: 'Default Node', position: { x: 100, y: 150 } },
|
||||
{ id: '3', label: 'Default Node', position: { x: 400, y: 150 } },
|
||||
{ id: '4', type: 'button', position: { x: 240, y: 300 }, style: { borderRadius: '50%' } },
|
||||
{ id: 'e1-2', type: 'step', source: '1', target: '2', markerEnd: MarkerType.Arrow },
|
||||
{ id: 'e2-4', type: 'smoothstep', source: '2', target: '4', animated: true, style: { strokeWidth: 2, stroke: '#3b82f6' } },
|
||||
{ id: 'e3-4', type: 'smoothstep', source: '3', target: '4', animated: true, style: { strokeWidth: 2, stroke: '#3b82f6' } },
|
||||
{ id: 'e1-3', type: 'step', source: '1', target: '3', markerEnd: MarkerType.Arrow },
|
||||
])
|
||||
|
||||
const { onConnect, onPaneReady, addEdges } = useVueFlow()
|
||||
onConnect((connection) => addEdges([connection]))
|
||||
onPaneReady(({ fitView }) => {
|
||||
fitView({ padding: 0.3, offset: { y: 30 } })
|
||||
})
|
||||
|
||||
const toggleClassnames = () => {
|
||||
elements.value = elements.value.map((el) => {
|
||||
if (isNode(el)) el.class = el.class === 'dark' ? 'light' : 'dark'
|
||||
return el
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div class="relative w-[100vw] h-[80vh] flex flex-col-reverse md:flex-row font-mono border-1 border-white bg-white">
|
||||
<div class="flex bg-light-800 flex-col justify-center gap-2 md:gap-4 p-6 w-full md:w-1/3">
|
||||
<h1 class="pointer-events-none text-xl lg:text-4xl">Easy to use</h1>
|
||||
<h2 class="pointer-events-none text-sm lg:text-xl text-black font-normal">
|
||||
Getting started is simple. All you need are some <strong>elements</strong> and you're ready to go.
|
||||
<span class="font-bold">Each element needs a unique id.</span> A node also needs a <strong>position (x and y)</strong>. An
|
||||
edge needs <strong>a source and a target</strong>.
|
||||
</h2>
|
||||
<div class="!pointer-events-auto transform scale-75 lg:scale-100 flex flex-row justify-center items-center gap-4">
|
||||
<a class="p-4 bg-green-500 hover:bg-black rounded-xl !text-white font-semibold text-lg" href="/docs">
|
||||
Documentation
|
||||
</a>
|
||||
<a
|
||||
class="!pointer-events-auto p-4 bg-white hover:bg-black rounded-xl bg-blue-500 !text-white font-semibold text-lg"
|
||||
href="/examples"
|
||||
>
|
||||
Examples
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<VueFlow
|
||||
id="basic-flow"
|
||||
v-model="elements"
|
||||
class="vue-flow-basic-example"
|
||||
:default-zoom="1.5"
|
||||
:min-zoom="0.2"
|
||||
:max-zoom="4"
|
||||
:zoom-on-scroll="false"
|
||||
>
|
||||
<Background variant="dots" color="black" />
|
||||
<template #node-button>
|
||||
<slot></slot>
|
||||
</template>
|
||||
<div class="absolute right-[10px] top-[10px] z-4">
|
||||
<button class="button" @click="toggleClassnames">toggle class</button>
|
||||
</div>
|
||||
</VueFlow>
|
||||
</div>
|
||||
</template>
|
||||
<style>
|
||||
.vue-flow__node.dark {
|
||||
@apply !bg-black;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,60 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue'
|
||||
import { VueFlow, MiniMap, Background, Controls, Elements, MarkerType, FlowEvents } from '@braks/vue-flow'
|
||||
|
||||
interface Props {
|
||||
next: (node: string[], duration: number) => void
|
||||
}
|
||||
const props = defineProps<Props>()
|
||||
|
||||
const elements = ref<Elements>([
|
||||
{ id: '1', type: 'input', label: 'Back To The Start', position: { x: 200, y: 0 } },
|
||||
{ id: '2', label: 'Node 2', position: { x: 0, y: 130 } },
|
||||
{ id: '3', label: 'Node 3', position: { x: 400, y: 130 } },
|
||||
{ id: 'e1-2', source: '1', target: '2', markerEnd: MarkerType.Arrow },
|
||||
{ id: 'e1-3', source: '1', target: '3', markerEnd: MarkerType.Arrow },
|
||||
])
|
||||
|
||||
const onLoad = ({ fitView }) => fitView({ padding: 0.5 })
|
||||
const onNodeClick = ({ node }: FlowEvents['nodeClick']) => {
|
||||
if (node.type === 'input') props.next(['intro', 'examples', 'tour', 'documentation'], 4000)
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div
|
||||
ref="page"
|
||||
class="!pointer-events-auto font-mono flex flex flex-col md:flex-row bg-white w-[100vw] h-[80vh]"
|
||||
:style="{ borderRadius: 0 }"
|
||||
>
|
||||
<VueFlow
|
||||
id="features-flow"
|
||||
v-model="elements"
|
||||
class="relative font-mono"
|
||||
:pane-moveable="true"
|
||||
@pane-ready="onLoad"
|
||||
@node-click="onNodeClick"
|
||||
>
|
||||
<Controls />
|
||||
<Background />
|
||||
<MiniMap />
|
||||
</VueFlow>
|
||||
<div class="flex bg-light-800 flex-col justify-center gap-2 md:gap-4 p-6 w-full md:w-1/3">
|
||||
<h1 class="pointer-events-none text-xl lg:text-4xl">Everything you need</h1>
|
||||
<h2 class="pointer-events-none text-sm lg:text-xl text-black font-normal">
|
||||
Vue Flow ships with a <strong>Minimap-, Background- and Controls-Component</strong>. On top of that we add
|
||||
<strong>Zoom & Pan utilities</strong> with which you can create the exact same transitions that are used on this site!
|
||||
</h2>
|
||||
<div class="!pointer-events-auto transform scale-75 lg:scale-100 flex flex-row justify-center items-center gap-4">
|
||||
<a class="p-4 bg-green-500 hover:bg-black rounded-xl !text-white font-semibold text-lg" href="/docs">
|
||||
Documentation
|
||||
</a>
|
||||
<a
|
||||
class="!pointer-events-auto p-4 bg-white hover:bg-black rounded-xl bg-blue-500 !text-white font-semibold text-lg"
|
||||
href="/examples"
|
||||
>
|
||||
Examples
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,311 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue'
|
||||
import { VueFlow, Handle, Position, Elements, FlowInstance } from '@braks/vue-flow'
|
||||
import { useBreakpoints } from '@vueuse/core'
|
||||
import BoxNode from './nodes/Box.vue'
|
||||
import RGBFlow from './RGB.vue'
|
||||
import BasicFlow from './Basic.vue'
|
||||
import FeaturesFlow from './Features.vue'
|
||||
|
||||
const breakpoints = useBreakpoints({
|
||||
mobile: 320,
|
||||
tablet: 640,
|
||||
laptop: 1024,
|
||||
desktop: 1280,
|
||||
})
|
||||
|
||||
const desktop = breakpoints.greater('tablet')
|
||||
|
||||
const elements: Elements = [
|
||||
{ id: 'intro', type: 'box', position: { x: 480, y: 50 }, draggable: true },
|
||||
{ id: 'demo', type: 'box', position: { x: desktop.value ? 1250 : 1150, y: 400 } },
|
||||
{ id: 'examples', type: 'box', position: { x: 800, y: 400 } },
|
||||
{ id: 'tour', type: 'box', position: { x: 650, y: 550 } },
|
||||
{ id: 'documentation', type: 'box', position: { x: 400, y: 400 } },
|
||||
{ id: 'github', type: 'box', position: { x: 1100, y: 200 } },
|
||||
{ id: 'features', type: 'features', position: { x: 3000, y: 5000 }, style: { cursor: 'default' } },
|
||||
{ id: 'rgb', type: 'rgb', position: { x: 3000, y: 2500 }, style: { cursor: 'default' } },
|
||||
{ id: 'basic', type: 'basic', position: { x: 250, y: 2500 }, style: { cursor: 'default' } },
|
||||
{
|
||||
id: 'eintro-examples',
|
||||
type: 'smoothstep',
|
||||
sourceHandle: 'a',
|
||||
source: 'intro',
|
||||
target: 'examples',
|
||||
animated: true,
|
||||
style: { strokeWidth: 2, stroke: '#8b5cf6' },
|
||||
},
|
||||
{
|
||||
id: 'eexamples-tour',
|
||||
type: 'smoothstep',
|
||||
sourceHandle: 'a',
|
||||
source: 'examples',
|
||||
target: 'tour',
|
||||
animated: true,
|
||||
style: { strokeWidth: 3, stroke: '#3b82f6' },
|
||||
},
|
||||
{
|
||||
id: 'eexamples-demo',
|
||||
type: 'smoothstep',
|
||||
sourceHandle: 'right',
|
||||
source: 'examples',
|
||||
target: 'demo',
|
||||
animated: true,
|
||||
style: { strokeWidth: 2 },
|
||||
},
|
||||
{
|
||||
id: 'edocumentation-tour',
|
||||
type: 'smoothstep',
|
||||
sourceHandle: 'a',
|
||||
source: 'documentation',
|
||||
target: 'tour',
|
||||
animated: true,
|
||||
style: { strokeWidth: 3, stroke: '#3b82f6' },
|
||||
},
|
||||
{
|
||||
id: 'eintro-documentation',
|
||||
type: 'smoothstep',
|
||||
sourceHandle: 'a',
|
||||
source: 'intro',
|
||||
target: 'documentation',
|
||||
animated: true,
|
||||
style: { strokeWidth: 2, stroke: '#f97316' },
|
||||
},
|
||||
{
|
||||
id: 'eintro-github',
|
||||
sourceHandle: 'b',
|
||||
source: 'intro',
|
||||
target: 'github',
|
||||
animated: true,
|
||||
style: { strokeWidth: 2 },
|
||||
},
|
||||
{
|
||||
id: 'etour-basic',
|
||||
targetHandle: 'basic-b',
|
||||
source: 'tour',
|
||||
target: 'basic',
|
||||
animated: true,
|
||||
style: { strokeWidth: 3, stroke: '#3b82f6' },
|
||||
},
|
||||
{
|
||||
id: 'ebasic-rgb',
|
||||
targetHandle: 'rgb-a',
|
||||
sourceHandle: 'basic-a',
|
||||
source: 'basic',
|
||||
target: 'rgb',
|
||||
animated: true,
|
||||
style: { strokeWidth: 3, stroke: '#3b82f6' },
|
||||
},
|
||||
{
|
||||
id: 'ergb-features',
|
||||
targetHandle: 'features-a',
|
||||
sourceHandle: 'rgb-b',
|
||||
source: 'rgb',
|
||||
target: 'basic',
|
||||
animated: true,
|
||||
style: { strokeWidth: 3, stroke: '#3b82f6' },
|
||||
},
|
||||
]
|
||||
const instance = ref<FlowInstance>()
|
||||
const onLoad = (i: FlowInstance) => {
|
||||
instance.value = i
|
||||
setTimeout(() => {
|
||||
i.fitView({
|
||||
nodes: ['intro', 'examples', 'tour', 'documentation'],
|
||||
padding: 0.2,
|
||||
offset: { x: !desktop.value ? -10 : -50 },
|
||||
duration: 1500,
|
||||
})
|
||||
})
|
||||
}
|
||||
const nextNode = (id: string[], duration = 2000, padding = 0) => instance.value.fitView({ padding, nodes: id, duration })
|
||||
</script>
|
||||
<template>
|
||||
<div class="home-page">
|
||||
<div class="flex h-[60vh] md:h-[80vh] w-full gap-4" style="border-radius: 0">
|
||||
<VueFlow
|
||||
v-model="elements"
|
||||
:elements-selectable="true"
|
||||
:nodes-draggable="false"
|
||||
:pane-moveable="false"
|
||||
:zoom-on-scroll="false"
|
||||
@pane-ready="onLoad"
|
||||
>
|
||||
<template #node-features>
|
||||
<FeaturesFlow :next="nextNode" />
|
||||
<Handle id="features-a" type="target" :position="Position.Top" />
|
||||
</template>
|
||||
<template #node-basic>
|
||||
<BasicFlow>
|
||||
<button
|
||||
class="
|
||||
flex flex-row
|
||||
gap-3
|
||||
items-center
|
||||
p-4
|
||||
shadow-lg
|
||||
hover:bg-black
|
||||
dark:(bg-black) dark:hover:bg-blue-500
|
||||
bg-blue-500
|
||||
rounded-xl
|
||||
!text-white
|
||||
font-semibold
|
||||
text-lg
|
||||
"
|
||||
@click="nextNode(['rgb'], 3500)"
|
||||
>
|
||||
<i class="icon-sm icon-heart !text-red-300" />Continue Demo
|
||||
</button>
|
||||
<Handle type="target" :position="Position.Top" />
|
||||
</BasicFlow>
|
||||
<Handle id="basic-a" type="source" :position="Position.Right" />
|
||||
<Handle id="basic-b" type="target" :position="Position.Top" />
|
||||
</template>
|
||||
<template #node-rgb>
|
||||
<RGBFlow :next="nextNode" />
|
||||
<Handle id="rgb-a" type="target" :position="Position.Left" />
|
||||
<Handle id="rgb-b" type="source" :position="Position.Bottom" />
|
||||
</template>
|
||||
<template #node-box="props">
|
||||
{{ props }}
|
||||
<template v-if="props.id === 'intro'">
|
||||
<div class="max-w-[500px]">
|
||||
<BoxNode class="bg-green-500 text-white">
|
||||
<div class="font-mono flex flex-col gap-4 p-4 items-center">
|
||||
<h1 class="pointer-events-none text-2xl lg:text-4xl">Visualize your ideas with Vue Flow</h1>
|
||||
<h2 class="pointer-events-none text-lg lg:text-xl font-normal">
|
||||
A customizable Vue.js library for building node-based editors and diagrams.
|
||||
</h2>
|
||||
</div>
|
||||
</BoxNode>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="props.id === 'documentation'">
|
||||
<div class="flex">
|
||||
<a
|
||||
class="
|
||||
flex flex-row
|
||||
gap-3
|
||||
items-center
|
||||
p-4
|
||||
shadow-lg
|
||||
bg-orange-500
|
||||
hover:bg-black
|
||||
rounded-xl
|
||||
!text-white
|
||||
font-semibold
|
||||
text-lg
|
||||
"
|
||||
href="/docs"
|
||||
>
|
||||
<i class="icon-sm icon-file-document !text-blue-700" />Read The Documentation
|
||||
</a>
|
||||
</div>
|
||||
<Handle type="target" :position="Position.Top" />
|
||||
<Handle type="source" :position="Position.Bottom" />
|
||||
</template>
|
||||
<template v-else-if="props.id === 'tour'">
|
||||
<button
|
||||
class="
|
||||
flex flex-row
|
||||
gap-3
|
||||
items-center
|
||||
p-4
|
||||
shadow-lg
|
||||
hover:bg-black
|
||||
bg-blue-500
|
||||
rounded-xl
|
||||
!text-white
|
||||
font-semibold
|
||||
text-lg
|
||||
"
|
||||
@click="nextNode(['basic'])"
|
||||
>
|
||||
<i class="icon-sm icon-heart !text-red-300" />Start the Tour
|
||||
</button>
|
||||
<Handle type="target" :position="Position.Top" />
|
||||
<Handle type="source" :position="Position.Bottom" />
|
||||
</template>
|
||||
<template v-else-if="props.id === 'demo'">
|
||||
<a
|
||||
class="
|
||||
flex flex-row
|
||||
gap-3
|
||||
items-center
|
||||
p-4
|
||||
shadow-lg
|
||||
hover:bg-black
|
||||
bg-pink-400
|
||||
rounded-xl
|
||||
!text-white
|
||||
font-semibold
|
||||
text-lg
|
||||
"
|
||||
href="/examples/playground"
|
||||
>
|
||||
<i class="icon-sm icon-toolbox !text-blue-700" />Playground
|
||||
</a>
|
||||
<Handle type="target" :position="Position.Left" />
|
||||
</template>
|
||||
<template v-else-if="props.id === 'examples'">
|
||||
<div class="flex">
|
||||
<a
|
||||
class="
|
||||
flex flex-row
|
||||
gap-3
|
||||
items-center
|
||||
p-4
|
||||
shadow-lg
|
||||
hover:bg-black
|
||||
bg-purple-500
|
||||
rounded-xl
|
||||
!text-white
|
||||
font-semibold
|
||||
text-lg
|
||||
"
|
||||
href="/examples"
|
||||
>
|
||||
<i class="icon-sun icon-sm !text-yellow-300" />Check The Examples
|
||||
</a>
|
||||
</div>
|
||||
<Handle type="target" :position="Position.Top" />
|
||||
<Handle type="source" :position="Position.Bottom" />
|
||||
<Handle type="source" id="right" :position="Position.Right" />
|
||||
</template>
|
||||
<template v-else-if="props.id === 'github'">
|
||||
<div class="flex">
|
||||
<a
|
||||
class="
|
||||
flex flex-row
|
||||
items-center
|
||||
gap-3
|
||||
p-4
|
||||
bg-black
|
||||
rounded-xl
|
||||
!text-white
|
||||
hover:(bg-white
|
||||
border-1 border-black
|
||||
!text-black)
|
||||
text-lg
|
||||
"
|
||||
href="https://github.com/bcakmakoglu/vue-flow"
|
||||
target="_blank"
|
||||
>
|
||||
<i class="icon-sm icon-git-branch" />Github
|
||||
</a>
|
||||
</div>
|
||||
<Handle type="target" :position="Position.Left" />
|
||||
</template>
|
||||
</template>
|
||||
</VueFlow>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped>
|
||||
a {
|
||||
@apply text-green-500 font-semibold hover:text-green-300;
|
||||
}
|
||||
button:focus {
|
||||
outline: none;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,103 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue'
|
||||
import { Elements, FlowInstance, VueFlow, Background, Controls, MiniMap, BackgroundVariant } from '@braks/vue-flow'
|
||||
import { templateRef, useBreakpoints, useElementBounding, whenever } from '@vueuse/core'
|
||||
import CustomEdge from './edges/Custom.vue'
|
||||
import RGBNode from './nodes/Input.vue'
|
||||
import RGBOutputNode from './nodes/Output.vue'
|
||||
|
||||
type Colors = {
|
||||
red: number
|
||||
green: number
|
||||
blue: number
|
||||
}
|
||||
|
||||
interface Props {
|
||||
next: (node: string[], duration?: number, padding?: number) => void
|
||||
}
|
||||
const props = defineProps<Props>()
|
||||
|
||||
const breakpoints = useBreakpoints({
|
||||
mobile: 360,
|
||||
tablet: 640,
|
||||
laptop: 1024,
|
||||
desktop: 1280,
|
||||
})
|
||||
|
||||
const elements = ref<Elements>([
|
||||
{ id: '1', type: 'rgb', data: { color: 'g' }, position: { x: -25, y: 50 } },
|
||||
{ id: '2', type: 'rgb', data: { color: 'r' }, position: { x: 50, y: -100 } },
|
||||
{ id: '3', type: 'rgb', data: { color: 'b' }, position: { x: 0, y: 200 } },
|
||||
{ id: '4', type: 'rgb-output', label: 'RGB', position: { x: 400, y: 50 } },
|
||||
{ id: 'e1-4', type: 'rgb-line', data: { color: 'green' }, source: '1', target: '4', animated: true },
|
||||
{ id: 'e2-4', type: 'rgb-line', data: { color: 'red' }, source: '2', target: '4', animated: true },
|
||||
{ id: 'e3-4', type: 'rgb-line', data: { color: 'blue' }, source: '3', target: '4', animated: true },
|
||||
])
|
||||
const instance = ref<FlowInstance>()
|
||||
|
||||
const el = templateRef<HTMLDivElement>('page', null)
|
||||
|
||||
const bounds = useElementBounding(el)
|
||||
const onLoad = (flowInstance: FlowInstance) => {
|
||||
instance.value = flowInstance
|
||||
if (breakpoints.greater('tablet').value) flowInstance.fitView({ padding: 0.5 })
|
||||
else flowInstance.fitView()
|
||||
}
|
||||
whenever(breakpoints.greater('tablet'), () => onLoad(instance.value))
|
||||
whenever(breakpoints.smaller('tablet'), () => onLoad(instance.value))
|
||||
|
||||
const color = ref<Colors>({
|
||||
red: 100,
|
||||
green: 150,
|
||||
blue: 100,
|
||||
})
|
||||
const onChange = ({ color: c, val }: { color: keyof Colors; val: number }) => (color.value[c] = Number(val))
|
||||
const bg = ref(BackgroundVariant.Lines)
|
||||
const bgSize = ref(1)
|
||||
const bgGap = ref(48)
|
||||
const backgroundChange = (variant: BackgroundVariant) => (bg.value = variant)
|
||||
const sizeChange = (size: number) => (bgSize.value = size)
|
||||
</script>
|
||||
<template>
|
||||
<div ref="page" class="font-mono flex flex flex-col md:flex-row bg-white w-[100vw] h-[80vh]" :style="{ borderRadius: 0 }">
|
||||
<VueFlow id="rgb-flow" v-model="elements" class="relative font-mono" :zoom-on-scroll="false" @pane-ready="onLoad">
|
||||
<template #edge-rgb-line="rgbLineProps">
|
||||
<CustomEdge v-bind="{ ...rgbLineProps }" />
|
||||
</template>
|
||||
<template #node-rgb="rgbProps">
|
||||
<RGBNode v-bind="rgbProps" :amount="color" @change="onChange" />
|
||||
</template>
|
||||
<template #node-rgb-output="rgbOutputProps">
|
||||
<RGBOutputNode
|
||||
v-bind="rgbOutputProps"
|
||||
:rgb="`rgb(${color.red}, ${color.green}, ${color.blue})`"
|
||||
@next="props.next(['features'], 3500)"
|
||||
/>
|
||||
</template>
|
||||
<Controls />
|
||||
<Background :variant="bg" :color="`rgb(${color.red}, ${color.green}, ${color.blue})`" :gap="bgGap" :size="bgSize" />
|
||||
<MiniMap />
|
||||
</VueFlow>
|
||||
<div class="flex bg-light-800 flex-col justify-center gap-2 md:gap-4 p-6 w-full md:w-1/3">
|
||||
<h1 class="pointer-events-none text-xl lg:text-4xl" :style="{ color: `rgb(${color.red}, ${color.green}, ${color.blue})` }">
|
||||
Highly customizable
|
||||
</h1>
|
||||
<h2 class="pointer-events-none text-sm lg:text-xl text-black font-normal">
|
||||
With Vue Flow you can create the most beautiful <strong>static diagrams</strong> or even <strong>custom editors</strong>.
|
||||
Thanks to a lot of handy utilities that come out of the box, you jump right into <strong>customizing</strong> Vue Flow to
|
||||
your hearts desire and utilize the <strong>seamless zoom & panning</strong> feature.
|
||||
</h2>
|
||||
<div class="!pointer-events-auto transform scale-75 lg:scale-100 flex flex-row justify-center items-center gap-4">
|
||||
<a class="p-4 bg-green-500 hover:bg-black rounded-xl !text-white font-semibold text-lg" href="/docs">
|
||||
Documentation
|
||||
</a>
|
||||
<a
|
||||
class="!pointer-events-auto p-4 bg-white hover:bg-black rounded-xl bg-blue-500 !text-white font-semibold text-lg"
|
||||
href="/examples"
|
||||
>
|
||||
Examples
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,61 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue'
|
||||
import { MarkerType, getBezierPath, Position, EdgeProps } from '@braks/vue-flow'
|
||||
|
||||
interface CustomEdgeProps extends EdgeProps {
|
||||
source: string
|
||||
target: string
|
||||
sourceHandleId?: string
|
||||
targetHandleId?: string
|
||||
id: string
|
||||
sourceX: number
|
||||
sourceY: number
|
||||
targetX: number
|
||||
targetY: number
|
||||
sourcePosition: Position
|
||||
targetPosition: Position
|
||||
markerEnd?: MarkerType
|
||||
data?: {
|
||||
text?: string
|
||||
color?: 'red' | 'green' | 'blue'
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
}),
|
||||
)
|
||||
|
||||
console.log(props)
|
||||
</script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
inheritAttrs: false,
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<path
|
||||
:id="props.id"
|
||||
class="vue-flow__edge-path"
|
||||
:style="{ stroke: props.data?.color }"
|
||||
:d="edgePath"
|
||||
:marker-end="props.markerEnd"
|
||||
/>
|
||||
<text>
|
||||
<textPath
|
||||
:href="`#${props.id}`"
|
||||
:style="{ fontSize: '12px', fill: props.data?.color }"
|
||||
startOffset="50%"
|
||||
text-anchor="middle"
|
||||
>
|
||||
{{ props.data?.text }}
|
||||
</textPath>
|
||||
</text>
|
||||
</template>
|
||||
@@ -0,0 +1,12 @@
|
||||
<script lang="ts" setup>
|
||||
import { Handle, Position } from '@braks/vue-flow'
|
||||
|
||||
const emit = defineEmits(['next'])
|
||||
</script>
|
||||
<template>
|
||||
<div class="px-4 py-2 bg-white shadow-lg rounded-md border-2 border-solid border-black">
|
||||
<slot />
|
||||
<Handle id="a" type="source" :position="Position.Bottom" />
|
||||
<Handle id="b" type="source" :position="Position.Right" />
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,44 @@
|
||||
<script lang="ts" setup>
|
||||
import { Handle, NodeProps, Position } from '@braks/vue-flow'
|
||||
|
||||
interface RGBNodeProps extends NodeProps {
|
||||
data: {
|
||||
color: 'r' | 'g' | 'b'
|
||||
}
|
||||
amount: {
|
||||
red: number
|
||||
green: number
|
||||
blue: number
|
||||
}
|
||||
}
|
||||
const props = defineProps<RGBNodeProps>()
|
||||
const emit = defineEmits(['change'])
|
||||
let color = 'red'
|
||||
switch (props.data?.color) {
|
||||
case 'r':
|
||||
color = 'red'
|
||||
break
|
||||
case 'g':
|
||||
color = 'green'
|
||||
break
|
||||
case 'b':
|
||||
color = 'blue'
|
||||
break
|
||||
}
|
||||
const onChange = (e: any) => emit('change', { color, val: e.target.value })
|
||||
</script>
|
||||
<template>
|
||||
<div class="px-4 py-2 bg-white rounded-md border-2 border-solid border-black text-left transform scale-75 lg:scale-100">
|
||||
<div class="text-md" :style="{ color }">{{ `${color} Amount`.toUpperCase() }}</div>
|
||||
<input
|
||||
v-model="props.amount[color]"
|
||||
class="slider nodrag"
|
||||
:style="{ '--color': color }"
|
||||
type="range"
|
||||
min="0"
|
||||
max="255"
|
||||
@input="onChange"
|
||||
/>
|
||||
<Handle type="source" :position="Position.Right" :style="{ backgroundColor: color }" />
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,24 @@
|
||||
<script lang="ts" setup>
|
||||
import { Handle, NodeProps, Position } from '@braks/vue-flow'
|
||||
interface RBGOutputNodeProps extends NodeProps {
|
||||
rgb: string
|
||||
}
|
||||
const props = defineProps<RBGOutputNodeProps>()
|
||||
const emit = defineEmits(['next'])
|
||||
const next = () => emit('next')
|
||||
</script>
|
||||
<template>
|
||||
<div :style="{ backgroundColor: props.rgb }" class="rgb-output-node" @click="next">
|
||||
<div class="text-md uppercase">{{ props.rgb }}</div>
|
||||
Click me to continue.
|
||||
<Handle type="target" :position="Position.Left" />
|
||||
</div>
|
||||
</template>
|
||||
<style>
|
||||
.rgb-output-node {
|
||||
padding: 9px;
|
||||
border-radius: 25px;
|
||||
text-align: left;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user