Skip to content

Commit f21a40d

Browse files
committed
docs: add workflow examples
1 parent 576d882 commit f21a40d

File tree

4 files changed

+1082
-382
lines changed

4 files changed

+1082
-382
lines changed

apps/www/app.config.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export default defineAppConfig({
6262
target: '_blank',
6363
}, {
6464
title: 'Discord',
65-
to: 'https://discord.gg/fxBU6M5Jyh',
65+
to: 'https://discord.gg/SWzhwGMxsZ',
6666
description: 'Join our Discord server to get help and connect with other developers',
6767
target: '_blank',
6868
}],
@@ -81,8 +81,19 @@ export default defineAppConfig({
8181
folderStyle: 'default',
8282
},
8383
main: {
84+
padded: true,
8485
breadCrumb: true,
8586
showTitle: true,
87+
codeCopyToast: false,
88+
codeCopyIcon: 'lucide:clipboard',
89+
editLink: {
90+
enable: true,
91+
pattern: 'https://github.com/vuepont/ai-elements-vue/edit/main/apps/www/content/:path',
92+
text: 'Edit this page',
93+
icon: 'lucide:square-pen',
94+
placement: ['docsFooter'],
95+
},
96+
backToTop: true,
8697
},
8798
footer: {
8899
credits: 'Copyright © 2025',
@@ -92,12 +103,16 @@ export default defineAppConfig({
92103
target: '_blank',
93104
}, {
94105
icon: 'simple-icons:discord',
95-
to: 'https://discord.gg/fxBU6M5Jyh',
106+
to: 'https://discord.gg/SWzhwGMxsZ',
96107
target: '_blank',
97108
}],
98109
},
99110
toc: {
100111
enable: true,
112+
enableInMobile: true,
113+
enableInHomepage: false,
114+
progressBar: true,
115+
title: 'On this page',
101116
links: [{
102117
title: 'Star on GitHub',
103118
icon: 'lucide:star',
Lines changed: 287 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,294 @@
11
---
22
title: Workflow
3-
description:
3+
description: An example of how to use the AI Elements Vue to build a workflow visualization.
44
icon: lucide:workflow
55
---
66

7+
An example of how to use the AI Elements Vue to build a workflow visualization with interactive nodes and animated connections, built with [Vue Flow](https://vueflow.dev/).
8+
79
:::ComponentLoader{label="Workflow" componentName="Workflow"}
810
:::
11+
12+
## Tutorial
13+
14+
Let's walk through how to build a workflow visualization using AI Elements Vue. Our example will include custom nodes with headers, content, and footers, along with animated and temporary edge types.
15+
16+
::steps
17+
### Setup
18+
19+
First, set up a new Vue.js repo by running the following command:
20+
21+
:pm-x{command="create vite@latest ai-workflow --template vue-ts"}
22+
23+
::alert{type="info" icon="lucide:book"}
24+
Follow this [guide](https://www.shadcn-vue.com/docs/installation/vite.html) to setup **shadcn/vue** and **Tailwind**.
25+
::
26+
27+
Run the following command to install AI Elements:
28+
29+
:pm-x{command="ai-elements-vue@latest"}
30+
31+
Now, install the required dependencies:
32+
33+
:pm-install{name="@vue-flow/core @vue-flow/background @vue-flow/controls @vue-flow/node-toolbar"}
34+
35+
Now let's build the workflow step by step: create the component structure, define our nodes and edges, and configure the canvas.
36+
37+
### Import the components
38+
39+
Import the necessary AI Elements Vue components in your `src/App.vue`:
40+
41+
```vue [src/App.vue]
42+
<script setup lang="ts">
43+
import type { EdgeTypesObject, NodeTypesObject } from '@vue-flow/core'
44+
import { markRaw } from 'vue'
45+
import { Canvas } from '@/components/ai-elements/canvas'
46+
import { Connection } from '@/components/ai-elements/connection'
47+
import { Controls } from '@/components/ai-elements/controls'
48+
import { Animated, Temporary } from '@/components/ai-elements/edge'
49+
import { Panel } from '@/components/ai-elements/panel'
50+
import CustomNode from '@/components/custom-node.vue'
51+
import { Button } from '@/components/ui/button'
52+
</script>
53+
```
54+
55+
### Define node IDs
56+
57+
Create a constant object to manage node identifiers. This makes it easier to reference nodes when creating edges:
58+
59+
```ts [src/App.vue]
60+
const nodeIds = {
61+
start: 'start',
62+
process1: 'process1',
63+
process2: 'process2',
64+
decision: 'decision',
65+
output1: 'output1',
66+
output2: 'output2',
67+
}
68+
```
69+
70+
### Create mock nodes
71+
72+
Define the nodes array with position, type, and data for each node in your workflow:
73+
74+
```ts [src/App.vue] height=200 collapse
75+
const nodes = [
76+
{
77+
id: nodeIds.start,
78+
type: 'workflow',
79+
position: { x: 0, y: 0 },
80+
data: {
81+
label: 'Start',
82+
description: 'Initialize workflow',
83+
handles: { target: false, source: true },
84+
content: 'Triggered by user action at 09:30 AM',
85+
footer: 'Status: Ready',
86+
},
87+
},
88+
{
89+
id: nodeIds.process1,
90+
type: 'workflow',
91+
position: { x: 500, y: 0 },
92+
data: {
93+
label: 'Process Data',
94+
description: 'Transform input',
95+
handles: { target: true, source: true },
96+
content: 'Validating 1,234 records and applying business rules',
97+
footer: 'Duration: ~2.5s',
98+
},
99+
},
100+
{
101+
id: nodeIds.decision,
102+
type: 'workflow',
103+
position: { x: 1000, y: 0 },
104+
data: {
105+
label: 'Decision Point',
106+
description: 'Route based on conditions',
107+
handles: { target: true, source: true },
108+
content: 'Evaluating: data.status === \'valid\' && data.score > 0.8',
109+
footer: 'Confidence: 94%',
110+
},
111+
},
112+
{
113+
id: nodeIds.output1,
114+
type: 'workflow',
115+
position: { x: 1500, y: -300 },
116+
data: {
117+
label: 'Success Path',
118+
description: 'Handle success case',
119+
handles: { target: true, source: true },
120+
content: '1,156 records passed validation (93.7%)',
121+
footer: 'Next: Send to production',
122+
},
123+
},
124+
{
125+
id: nodeIds.output2,
126+
type: 'workflow',
127+
position: { x: 1500, y: 300 },
128+
data: {
129+
label: 'Error Path',
130+
description: 'Handle error case',
131+
handles: { target: true, source: true },
132+
content: '78 records failed validation (6.3%)',
133+
footer: 'Next: Queue for review',
134+
},
135+
},
136+
{
137+
id: nodeIds.process2,
138+
type: 'workflow',
139+
position: { x: 2000, y: 0 },
140+
data: {
141+
label: 'Complete',
142+
description: 'Finalize workflow',
143+
handles: { target: true, source: false },
144+
content: 'All records processed and routed successfully',
145+
footer: 'Total time: 4.2s',
146+
},
147+
},
148+
]
149+
```
150+
151+
### Create mock edges
152+
153+
Define the connections between nodes. Use `animated` for active paths and `temporary` for conditional or error paths:
154+
155+
```ts [src/App.vue] height=200 collapse
156+
const edges = [
157+
{
158+
id: 'edge1',
159+
source: nodeIds.start,
160+
target: nodeIds.process1,
161+
type: 'animated',
162+
},
163+
{
164+
id: 'edge2',
165+
source: nodeIds.process1,
166+
target: nodeIds.decision,
167+
type: 'animated',
168+
},
169+
{
170+
id: 'edge3',
171+
source: nodeIds.decision,
172+
target: nodeIds.output1,
173+
type: 'animated',
174+
},
175+
{
176+
id: 'edge4',
177+
source: nodeIds.decision,
178+
target: nodeIds.output2,
179+
type: 'temporary',
180+
},
181+
{
182+
id: 'edge5',
183+
source: nodeIds.output1,
184+
target: nodeIds.process2,
185+
type: 'animated',
186+
},
187+
{
188+
id: 'edge6',
189+
source: nodeIds.output2,
190+
target: nodeIds.process2,
191+
type: 'temporary',
192+
},
193+
]
194+
```
195+
196+
### Create the node types
197+
198+
Create a custom node component:
199+
200+
```vue [src/components/custom-node.vue] height=200 collapse
201+
<script setup lang="ts">
202+
import type { NodeProps } from '@vue-flow/core'
203+
import { Node, NodeContent, NodeDescription, NodeFooter, NodeHeader, NodeTitle } from '@/components/ai-elements/node'
204+
205+
const props = defineProps<NodeProps>()
206+
</script>
207+
208+
<template>
209+
<Node :handles="props.data?.handles">
210+
<NodeHeader>
211+
<NodeTitle>{{ props.data?.label }}</NodeTitle>
212+
<NodeDescription>{{ props.data?.description }}</NodeDescription>
213+
</NodeHeader>
214+
215+
<NodeContent>
216+
<p class="text-sm">
217+
{{ props.data?.content }}
218+
</p>
219+
</NodeContent>
220+
221+
<NodeFooter>
222+
<p class="text-muted-foreground text-xs">
223+
{{ props.data?.footer }}
224+
</p>
225+
</NodeFooter>
226+
</Node>
227+
</template>
228+
```
229+
230+
Define the node types to use the custom Node component:
231+
232+
```ts [src/App.vue]
233+
const nodeTypes: NodeTypesObject = {
234+
workflow: markRaw(CustomNode),
235+
}
236+
```
237+
238+
### Create the edge types
239+
240+
Map the edge type names to the Edge components:
241+
242+
```ts [src/App.vue]
243+
const edgeTypes: EdgeTypesObject = {
244+
animated: markRaw(Animated),
245+
temporary: markRaw(Temporary),
246+
}
247+
```
248+
249+
### Create the template
250+
251+
Finally, create the template that combines the Canvas with all nodes, edges, controls, and custom UI panels:
252+
253+
```vue [src/App.vue]
254+
<template>
255+
<div class="h-screen w-screen">
256+
<Canvas :nodes="nodes" :edges="edges" :node-types="nodeTypes" :edge-types="edgeTypes">
257+
<template #connection-line="connectionLineProps">
258+
<Connection v-bind="connectionLineProps" />
259+
</template>
260+
261+
<Controls />
262+
263+
<Panel position="top-right">
264+
<Button size="sm" variant="secondary">
265+
Export
266+
</Button>
267+
</Panel>
268+
</Canvas>
269+
</div>
270+
</template>
271+
```
272+
::
273+
274+
### Key Features
275+
276+
The workflow visualization demonstrates several powerful features:
277+
278+
- **Custom Node Components**: Each node uses the compound components (`NodeHeader`, `NodeTitle`, `NodeDescription`, `NodeContent`, `NodeFooter`) for consistent, structured layouts.
279+
280+
- **Node Toolbars**: The `Toolbar` component attaches contextual actions (like Edit and Delete buttons) to individual nodes, appearing when hovering or selecting them.
281+
282+
- **Handle Configuration**: Nodes can have source and/or target handles, controlling which connections are possible.
283+
284+
- **Multiple Edge Types**: The `animated` type shows active data flow, while `temporary` indicates conditional or error paths.
285+
286+
- **Custom Connection Lines**: The `Connection` component provides styled bezier curves when dragging new connections between nodes.
287+
288+
- **Interactive Controls**: The `Controls` component adds zoom in/out and fit view buttons with a modern, themed design.
289+
290+
- **Custom UI Panels**: The `Panel` component allows you to position custom UI elements (like buttons, filters, or legends) anywhere on the canvas.
291+
292+
- **Automatic Layout**: The `Canvas` component auto-fits the view and provides pan/zoom controls out of the box.
293+
294+
You now have a working workflow visualization! Feel free to explore dynamic workflows by connecting this to AI-generated process flows, or extend it with interactive editing capabilities using Vue Flow's built-in features.

apps/www/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"@repo/examples": "workspace:*",
1616
"highlight.js": "^11.11.1",
1717
"nuxt": "3.18.0",
18-
"shadcn-docs-nuxt": "^1.1.2",
18+
"shadcn-docs-nuxt": "^1.1.4",
1919
"tailwindcss": "^4.1.14",
2020
"vue": "^3.5.22",
2121
"vue-router": "^4.5.1"

0 commit comments

Comments
 (0)