From 98a893108c2fe1875b9457468658aa735f3ae141 Mon Sep 17 00:00:00 2001 From: Braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Thu, 26 May 2022 19:23:35 +0200 Subject: [PATCH] docs: replace codesandbox embed with repl (#122) * docs: Animations * docs: add confetti gun * docs: update basic example on home page * docs(deps): Add stackblitz sdk to deps * chore: update yarn.lock * docs: use vue repl * docs: remove stackblitz sdk * docs: basic repl example * docs: use repl for examples/index.md (basic example) * docs: pass ext to repl * docs: add copy plugin * docs: use import map instead of dynamic imports * docs: use repl for custom node example * docs: hide repl errors * docs: use repl for custom connectionline example * docs: use repl for edges example * docs: exclude repl from ssr * docs: use repl for nested example * docs: use repl for stress example * docs: rename customNode to custom-node * docs: use repl for update-edge example * docs: use repl for update-node example * docs: use repl for validation example * docs: use repl for save-restore example * docs: scale down minimap in repl examples * docs: use repl for dnd example * docs: use repl for empty example * docs: use repl for hidden example * docs: use repl for interaction example * docs: use repl for multi example * docs: add pinia example with stackblitz * docs: update basic example * docs: update examples * docs: remove transition from intro * docs: update features * update: README.md * docs: scope css --- README.md | 17 +- docs/components/Repl.vue | 107 +++++++++++++ docs/components/examples/basic/App.vue | 84 ++++++++++ docs/components/examples/basic/index.ts | 3 + .../examples/basic/initial-elements.js | 25 +++ docs/components/examples/basic/style.css | 30 ++++ .../examples/connectionline/App.vue | 24 +++ .../connectionline/CustomConnectionLine.vue | 33 ++++ .../examples/connectionline/index.ts | 2 + docs/components/examples/custom-node/App.vue | 82 ++++++++++ .../examples/custom-node/CustomNode.vue | 64 ++++++++ docs/components/examples/custom-node/index.ts | 4 + .../examples/custom-node/presets.js | 23 +++ .../components/examples/custom-node/style.css | 12 ++ docs/components/examples/dnd/App.vue | 47 ++++++ docs/components/examples/dnd/Sidebar.vue | 19 +++ docs/components/examples/dnd/index.ts | 3 + docs/components/examples/dnd/style.css | 51 ++++++ docs/components/examples/edges/App.vue | 74 +++++++++ docs/components/examples/edges/CustomEdge.vue | 100 ++++++++++++ .../components/examples/edges/CustomEdge2.vue | 97 +++++++++++ .../examples/edges/CustomEdgeLabel.vue | 12 ++ docs/components/examples/edges/index.ts | 5 + docs/components/examples/edges/style.css | 34 ++++ docs/components/examples/empty/App.vue | 31 ++++ docs/components/examples/empty/index.ts | 1 + docs/components/examples/hidden/App.vue | 41 +++++ docs/components/examples/hidden/index.ts | 1 + docs/components/examples/index.ts | 87 ++++++++++ docs/components/examples/interaction/App.vue | 20 +++ .../interaction/InteractionControls.vue | 110 +++++++++++++ docs/components/examples/interaction/index.ts | 3 + .../components/examples/interaction/style.css | 22 +++ docs/components/examples/multi/App.vue | 10 ++ docs/components/examples/multi/Flow.vue | 36 +++++ docs/components/examples/multi/index.ts | 3 + docs/components/examples/multi/style.css | 18 +++ docs/components/examples/nested/App.vue | 98 ++++++++++++ docs/components/examples/nested/index.ts | 1 + .../examples/pinia/PiniaExample.vue | 23 +++ docs/components/examples/save-restore/App.vue | 13 ++ .../examples/save-restore/Controls.vue | 40 +++++ .../components/examples/save-restore/index.ts | 3 + .../examples/save-restore/style.css | 25 +++ docs/components/examples/stress/App.vue | 38 +++++ docs/components/examples/stress/index.ts | 3 + docs/components/examples/stress/style.css | 4 + docs/components/examples/stress/utils.js | 32 ++++ docs/components/examples/update-edge/App.vue | 47 ++++++ docs/components/examples/update-edge/index.ts | 1 + docs/components/examples/update-node/App.vue | 48 ++++++ docs/components/examples/update-node/index.ts | 2 + .../components/examples/update-node/style.css | 30 ++++ docs/components/examples/validation/App.vue | 47 ++++++ .../examples/validation/CustomInput.vue | 21 +++ .../examples/validation/CustomNode.vue | 25 +++ docs/components/examples/validation/index.ts | 4 + docs/components/examples/validation/style.css | 31 ++++ docs/components/home/Features.vue | 35 ++-- docs/components/home/Home.vue | 6 +- docs/components/home/flows/Basic.vue | 41 +++-- docs/components/home/flows/Intro.vue | 151 +++++++++++------- docs/components/home/flows/Nested.vue | 2 +- docs/components/home/flows/confetti.ts | 69 ++++++++ docs/components/home/nodes/Box.vue | 12 -- docs/package.json | 10 +- docs/src/.vuepress/components.d.ts | 14 +- docs/src/.vuepress/config.ts | 6 + docs/src/.vuepress/copy-plugin.ts | 27 ++++ docs/src/.vuepress/theme/clientAppEnhance.ts | 6 + docs/src/.vuepress/theme/index.ts | 2 + docs/src/.vuepress/theme/layouts/default.vue | 1 + docs/src/examples/connectionline.md | 31 +--- docs/src/examples/custom-node.md | 23 +-- docs/src/examples/dnd.md | 17 +- docs/src/examples/edges.md | 17 +- docs/src/examples/empty.md | 17 +- docs/src/examples/hidden.md | 17 +- docs/src/examples/index.md | 17 +- docs/src/examples/interaction.md | 17 +- docs/src/examples/multi.md | 17 +- docs/src/examples/nesting.md | 17 +- docs/src/examples/pinia.md | 15 ++ docs/src/examples/save.md | 30 ++-- docs/src/examples/stress.md | 17 +- docs/src/examples/updatable-edge.md | 17 +- docs/src/examples/update-node.md | 17 +- docs/src/examples/validation.md | 17 +- docs/src/index.md | 4 +- examples/src/Edges/CustomEdge.vue | 2 +- examples/src/Overview/Overview.vue | 4 +- examples/vite.config.ts | 2 +- .../additional-components/MiniMap/MiniMap.vue | 1 - .../src/components/Nodes/NodeWrapper.vue | 4 +- yarn.lock | 90 ++++++++++- 95 files changed, 2342 insertions(+), 321 deletions(-) create mode 100644 docs/components/Repl.vue create mode 100644 docs/components/examples/basic/App.vue create mode 100644 docs/components/examples/basic/index.ts create mode 100644 docs/components/examples/basic/initial-elements.js create mode 100644 docs/components/examples/basic/style.css create mode 100644 docs/components/examples/connectionline/App.vue create mode 100644 docs/components/examples/connectionline/CustomConnectionLine.vue create mode 100644 docs/components/examples/connectionline/index.ts create mode 100644 docs/components/examples/custom-node/App.vue create mode 100644 docs/components/examples/custom-node/CustomNode.vue create mode 100644 docs/components/examples/custom-node/index.ts create mode 100644 docs/components/examples/custom-node/presets.js create mode 100644 docs/components/examples/custom-node/style.css create mode 100644 docs/components/examples/dnd/App.vue create mode 100644 docs/components/examples/dnd/Sidebar.vue create mode 100644 docs/components/examples/dnd/index.ts create mode 100644 docs/components/examples/dnd/style.css create mode 100644 docs/components/examples/edges/App.vue create mode 100644 docs/components/examples/edges/CustomEdge.vue create mode 100644 docs/components/examples/edges/CustomEdge2.vue create mode 100644 docs/components/examples/edges/CustomEdgeLabel.vue create mode 100644 docs/components/examples/edges/index.ts create mode 100644 docs/components/examples/edges/style.css create mode 100644 docs/components/examples/empty/App.vue create mode 100644 docs/components/examples/empty/index.ts create mode 100644 docs/components/examples/hidden/App.vue create mode 100644 docs/components/examples/hidden/index.ts create mode 100644 docs/components/examples/index.ts create mode 100644 docs/components/examples/interaction/App.vue create mode 100644 docs/components/examples/interaction/InteractionControls.vue create mode 100644 docs/components/examples/interaction/index.ts create mode 100644 docs/components/examples/interaction/style.css create mode 100644 docs/components/examples/multi/App.vue create mode 100644 docs/components/examples/multi/Flow.vue create mode 100644 docs/components/examples/multi/index.ts create mode 100644 docs/components/examples/multi/style.css create mode 100644 docs/components/examples/nested/App.vue create mode 100644 docs/components/examples/nested/index.ts create mode 100644 docs/components/examples/pinia/PiniaExample.vue create mode 100644 docs/components/examples/save-restore/App.vue create mode 100644 docs/components/examples/save-restore/Controls.vue create mode 100644 docs/components/examples/save-restore/index.ts create mode 100644 docs/components/examples/save-restore/style.css create mode 100644 docs/components/examples/stress/App.vue create mode 100644 docs/components/examples/stress/index.ts create mode 100644 docs/components/examples/stress/style.css create mode 100644 docs/components/examples/stress/utils.js create mode 100644 docs/components/examples/update-edge/App.vue create mode 100644 docs/components/examples/update-edge/index.ts create mode 100644 docs/components/examples/update-node/App.vue create mode 100644 docs/components/examples/update-node/index.ts create mode 100644 docs/components/examples/update-node/style.css create mode 100644 docs/components/examples/validation/App.vue create mode 100644 docs/components/examples/validation/CustomInput.vue create mode 100644 docs/components/examples/validation/CustomNode.vue create mode 100644 docs/components/examples/validation/index.ts create mode 100644 docs/components/examples/validation/style.css create mode 100644 docs/components/home/flows/confetti.ts delete mode 100644 docs/components/home/nodes/Box.vue create mode 100644 docs/src/.vuepress/copy-plugin.ts create mode 100644 docs/src/.vuepress/theme/clientAppEnhance.ts create mode 100644 docs/src/examples/pinia.md diff --git a/README.md b/README.md index 4c5d832b..81a6635c 100644 --- a/README.md +++ b/README.md @@ -22,16 +22,16 @@ the [examples](https://vueflow.dev/examples). * [🎮 Quickstart](#-quickstart) - + [▸ Vue 2](#-vue-2) + + [🪴 Vue 2](#-vue-2) * [🧪 Development](#-development) + [🐳 Dev Container](#-dev-container) -* [⭐ Stargazers](#-stargazers) - * [💝 Special Thanks](#-special-thanks) +* [⭐ Stargazers](#-stargazers) + ## ⭐️ Features - 👶 __Easy setup__: Get started hassle-free - Built-in zoom- & pan features, element dragging, selection and much more @@ -50,6 +50,8 @@ the [examples](https://vueflow.dev/examples). - 🕹 Controls: Control zoom behavior from a panel on the bottom left + - 🤖 And (many) more to come... + - 🦾 __Reliable__: Fully written in TypeScript ## 🛠 Setup @@ -147,15 +149,14 @@ This project is built with - [React Flow](https://reactflow.dev/) - Vue flow is heavily based on [webkids'](https://webkid.io/) [react flow](https://reactflow.dev/). I wholeheartedly thank - them for their amazing work! Without them, Vue Flow would not exist. - Please consider [donating](https://github.com/sponsors/wbkd) to them! + them for their amazing work! Without them Vue Flow would not exist. + Please consider [donating](https://github.com/sponsors/wbkd) to them. - [D3.js](https://d3js.org/) - - D3 makes all the zoom and pan actions in the graph possible. - Check it out to see if you can find other uses for it too! + - D3 makes all the zoom and pan actions in Vue Flow possible. - [VueUse](https://vueuse.org/) - - VueUse is a collection of helpful utilities/composables that have been battle-tested. + - VueUse is a collection of essential vue composition utilities ## ⭐ Stargazers diff --git a/docs/components/Repl.vue b/docs/components/Repl.vue new file mode 100644 index 00000000..dcedf57d --- /dev/null +++ b/docs/components/Repl.vue @@ -0,0 +1,107 @@ + + + + + diff --git a/docs/components/examples/basic/App.vue b/docs/components/examples/basic/App.vue new file mode 100644 index 00000000..faf4c180 --- /dev/null +++ b/docs/components/examples/basic/App.vue @@ -0,0 +1,84 @@ + + + diff --git a/docs/components/examples/basic/index.ts b/docs/components/examples/basic/index.ts new file mode 100644 index 00000000..05bd1883 --- /dev/null +++ b/docs/components/examples/basic/index.ts @@ -0,0 +1,3 @@ +export { default as BasicApp } from './App.vue?raw' +export { default as BasicElements } from './initial-elements.js?raw' +export { default as BasicCSS } from './style.css' diff --git a/docs/components/examples/basic/initial-elements.js b/docs/components/examples/basic/initial-elements.js new file mode 100644 index 00000000..68f5e14d --- /dev/null +++ b/docs/components/examples/basic/initial-elements.js @@ -0,0 +1,25 @@ +import { MarkerType } from '@braks/vue-flow' + +/** + * You can pass elements together as a v-model value + * 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: '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: 'e4-5', + type: 'step', + label: 'step-edge', + source: '4', + target: '5', + style: { stroke: 'orange' }, + labelBgStyle: { fill: 'orange' }, + }, + { id: 'e3-4', type: 'smoothstep', label: 'smoothstep-edge', source: '3', target: '4' }, +] diff --git a/docs/components/examples/basic/style.css b/docs/components/examples/basic/style.css new file mode 100644 index 00000000..425bc525 --- /dev/null +++ b/docs/components/examples/basic/style.css @@ -0,0 +1,30 @@ +.basicflow .vue-flow__node.dark { + background: #1C1C1C; + color: #FFFFFB; +} + +.basicflow .controls { + position: absolute; + left: 10px; + top: 10px; + z-index: 4; + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 8px; +} + +.basicflow .controls button { + padding: 5px; + border-radius: 5px; + font-weight: 500; + -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); + cursor: pointer; +} + +.basicflow .controls button:hover { + opacity: 0.8; + transform: scale(105%); + transition: 250ms all ease; +} diff --git a/docs/components/examples/connectionline/App.vue b/docs/components/examples/connectionline/App.vue new file mode 100644 index 00000000..4bda5dff --- /dev/null +++ b/docs/components/examples/connectionline/App.vue @@ -0,0 +1,24 @@ + + + diff --git a/docs/components/examples/connectionline/CustomConnectionLine.vue b/docs/components/examples/connectionline/CustomConnectionLine.vue new file mode 100644 index 00000000..64759b84 --- /dev/null +++ b/docs/components/examples/connectionline/CustomConnectionLine.vue @@ -0,0 +1,33 @@ + + + diff --git a/docs/components/examples/connectionline/index.ts b/docs/components/examples/connectionline/index.ts new file mode 100644 index 00000000..e93b98df --- /dev/null +++ b/docs/components/examples/connectionline/index.ts @@ -0,0 +1,2 @@ +export { default as CustomConnectionLineApp } from './App.vue?raw' +export { default as CustomConnectionLine } from './CustomConnectionLine.vue?raw' diff --git a/docs/components/examples/custom-node/App.vue b/docs/components/examples/custom-node/App.vue new file mode 100644 index 00000000..a887c37c --- /dev/null +++ b/docs/components/examples/custom-node/App.vue @@ -0,0 +1,82 @@ + + + diff --git a/docs/components/examples/custom-node/CustomNode.vue b/docs/components/examples/custom-node/CustomNode.vue new file mode 100644 index 00000000..6ef6ebb1 --- /dev/null +++ b/docs/components/examples/custom-node/CustomNode.vue @@ -0,0 +1,64 @@ + + + + + diff --git a/docs/components/examples/custom-node/index.ts b/docs/components/examples/custom-node/index.ts new file mode 100644 index 00000000..cebea17a --- /dev/null +++ b/docs/components/examples/custom-node/index.ts @@ -0,0 +1,4 @@ +export { default as CustomNodeApp } from './App.vue?raw' +export { default as CustomNode } from './CustomNode.vue?raw' +export { default as CustomNodeCSS } from './style.css' +export { default as ColorPresets } from './presets.js?raw' diff --git a/docs/components/examples/custom-node/presets.js b/docs/components/examples/custom-node/presets.js new file mode 100644 index 00000000..ac92eea5 --- /dev/null +++ b/docs/components/examples/custom-node/presets.js @@ -0,0 +1,23 @@ +export const presets = { + byakuroku: '#A8D8B9', + mizu: '#81C7D4', + asagi: '#33A6B8', + ukon: '#EFBB24', + mushikuri: '#D9CD90', + hiwa: '#BEC23F', + ichigo: '#B5495B', + kurenai: '#CB1B45', + syojyohi: '#E83015', + konjyo: '#113285', + fuji: '#8B81C3', + ayame: '#6F3381', + gofun: '#FFFFFB', + torinoko: '#DAC9A6', + kurotsurubami: '#0B1013', + sumi: '#1C1C1C', + ohni: '#F05E1C', + kokikuchinashi: '#FB9966', + beniukon: '#E98B2A', + sakura: '#FEDFE1', + toki: '#EEA9A9', +} diff --git a/docs/components/examples/custom-node/style.css b/docs/components/examples/custom-node/style.css new file mode 100644 index 00000000..59f92f78 --- /dev/null +++ b/docs/components/examples/custom-node/style.css @@ -0,0 +1,12 @@ +.vue-flow__node-custom { + border: 1px solid #777; + padding: 10px; + border-radius: 10px; + background: whitesmoke; + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; + gap: 10px; + max-width: 250px; +} diff --git a/docs/components/examples/dnd/App.vue b/docs/components/examples/dnd/App.vue new file mode 100644 index 00000000..3cd5831f --- /dev/null +++ b/docs/components/examples/dnd/App.vue @@ -0,0 +1,47 @@ + + + diff --git a/docs/components/examples/dnd/Sidebar.vue b/docs/components/examples/dnd/Sidebar.vue new file mode 100644 index 00000000..7a42607b --- /dev/null +++ b/docs/components/examples/dnd/Sidebar.vue @@ -0,0 +1,19 @@ + + + diff --git a/docs/components/examples/dnd/index.ts b/docs/components/examples/dnd/index.ts new file mode 100644 index 00000000..a8c16c1a --- /dev/null +++ b/docs/components/examples/dnd/index.ts @@ -0,0 +1,3 @@ +export { default as DndApp } from './App.vue?raw' +export { default as DndSidebar } from './Sidebar.vue?raw' +export { default as DndCSS } from './style.css' diff --git a/docs/components/examples/dnd/style.css b/docs/components/examples/dnd/style.css new file mode 100644 index 00000000..d6560044 --- /dev/null +++ b/docs/components/examples/dnd/style.css @@ -0,0 +1,51 @@ +.dndflow { + flex-direction: column; + display: flex; + height: 100%; +} + +.dndflow 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); +} + +.dndflow aside .nodes > * { + 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); +} + +.dndflow aside .description { + margin-bottom: 10px; +} + +.dndflow .vue-flow-wrapper { + flex-grow: 1; + height: 100%; +} + +@media screen and (min-width: 640px) { + .dndflow { + flex-direction: row; + } + + .dndflow aside { + min-width: 25%; + } +} + +@media screen and (max-width: 639px) { + .dndflow aside .nodes { + display: flex; + flex-direction: row; + gap: 5px; + } +} diff --git a/docs/components/examples/edges/App.vue b/docs/components/examples/edges/App.vue new file mode 100644 index 00000000..f308dda5 --- /dev/null +++ b/docs/components/examples/edges/App.vue @@ -0,0 +1,74 @@ + + + diff --git a/docs/components/examples/edges/CustomEdge.vue b/docs/components/examples/edges/CustomEdge.vue new file mode 100644 index 00000000..bde25a2a --- /dev/null +++ b/docs/components/examples/edges/CustomEdge.vue @@ -0,0 +1,100 @@ + + + + + diff --git a/docs/components/examples/edges/CustomEdge2.vue b/docs/components/examples/edges/CustomEdge2.vue new file mode 100644 index 00000000..9feffda1 --- /dev/null +++ b/docs/components/examples/edges/CustomEdge2.vue @@ -0,0 +1,97 @@ + + + + + diff --git a/docs/components/examples/edges/CustomEdgeLabel.vue b/docs/components/examples/edges/CustomEdgeLabel.vue new file mode 100644 index 00000000..19d19e75 --- /dev/null +++ b/docs/components/examples/edges/CustomEdgeLabel.vue @@ -0,0 +1,12 @@ + + + diff --git a/docs/components/examples/edges/index.ts b/docs/components/examples/edges/index.ts new file mode 100644 index 00000000..5d38a75c --- /dev/null +++ b/docs/components/examples/edges/index.ts @@ -0,0 +1,5 @@ +export { default as EdgesApp } from './App.vue?raw' +export { default as CustomEdge } from './CustomEdge.vue?raw' +export { default as CustomEdge2 } from './CustomEdge2.vue?raw' +export { default as CustomEdgeLabel } from './CustomEdgeLabel.vue?raw' +export { default as EdgeCSS } from './style.css' diff --git a/docs/components/examples/edges/style.css b/docs/components/examples/edges/style.css new file mode 100644 index 00000000..bbdfc7c1 --- /dev/null +++ b/docs/components/examples/edges/style.css @@ -0,0 +1,34 @@ +.edgebutton { + color: whitesmoke; + border-radius: 999px; + cursor: pointer; +} + +.edgebutton:hover { + box-shadow: 0 0 0 2px pink, 0 0 0 4px #f05f75; +} + +.animated-text-gradient { + background: linear-gradient(122deg, #6f3381, #81c7d4, #fedfe1, #fffffb); + background-size: 800% 800%; + + -webkit-animation: textgradient 4s ease infinite; + -moz-animation: textgradient 4s ease infinite; + animation: textgradient 4s ease infinite; +} + +@-webkit-keyframes textgradient { + 0%{background-position:0% 22%} + 50%{background-position:100% 79%} + 100%{background-position:0% 22%} +} +@-moz-keyframes textgradient { + 0%{background-position:0% 22%} + 50%{background-position:100% 79%} + 100%{background-position:0% 22%} +} +@keyframes textgradient { + 0%{background-position:0% 22%} + 50%{background-position:100% 79%} + 100%{background-position:0% 22%} +} diff --git a/docs/components/examples/empty/App.vue b/docs/components/examples/empty/App.vue new file mode 100644 index 00000000..bf823312 --- /dev/null +++ b/docs/components/examples/empty/App.vue @@ -0,0 +1,31 @@ + + + diff --git a/docs/components/examples/empty/index.ts b/docs/components/examples/empty/index.ts new file mode 100644 index 00000000..74eb2379 --- /dev/null +++ b/docs/components/examples/empty/index.ts @@ -0,0 +1 @@ +export { default as EmptyApp } from './App.vue?raw' diff --git a/docs/components/examples/hidden/App.vue b/docs/components/examples/hidden/App.vue new file mode 100644 index 00000000..87811329 --- /dev/null +++ b/docs/components/examples/hidden/App.vue @@ -0,0 +1,41 @@ + + + diff --git a/docs/components/examples/hidden/index.ts b/docs/components/examples/hidden/index.ts new file mode 100644 index 00000000..b6a6a585 --- /dev/null +++ b/docs/components/examples/hidden/index.ts @@ -0,0 +1 @@ +export { default as HiddenApp } from './App.vue?raw' diff --git a/docs/components/examples/index.ts b/docs/components/examples/index.ts new file mode 100644 index 00000000..93f7834d --- /dev/null +++ b/docs/components/examples/index.ts @@ -0,0 +1,87 @@ +import { BasicApp, BasicCSS, BasicElements } from './basic' +import { ColorPresets, CustomNode, CustomNodeApp, CustomNodeCSS } from './custom-node' +import { CustomConnectionLine, CustomConnectionLineApp } from './connectionline' +import { CustomEdge, CustomEdge2, CustomEdgeLabel, EdgeCSS, EdgesApp } from './edges' +import { NestedApp } from './nested' +import { StressApp, StressCSS, StressUtils } from './stress' +import { UpdateEdgeApp } from './update-edge' +import { UpdateNodeApp, UpdateNodeCSS } from './update-node' +import { ValidationApp, ValidationCSS, ValidationCustomInput, ValidationCustomNode } from './validation' +import { SaveRestoreApp, SaveRestoreCSS, SaveRestoreControls } from './save-restore' +import { DndApp, DndCSS, DndSidebar } from './dnd' +import { EmptyApp } from './empty' +import { HiddenApp } from './hidden' +import { InteractionApp, InteractionCSS, InteractionControls } from './interaction' +import { MultiApp, MultiCSS, MultiFlow } from './multi' + +export const exampleImports = { + basic: { + 'App.vue': BasicApp, + 'initial-elements.js': BasicElements, + 'style.css': BasicCSS, + }, + customNode: { + 'App.vue': CustomNodeApp, + 'CustomNode.vue': CustomNode, + 'style.css': CustomNodeCSS, + 'presets.js': ColorPresets, + }, + connectionline: { + 'App.vue': CustomConnectionLineApp, + 'CustomConnectionLine.vue': CustomConnectionLine, + }, + edges: { + 'App.vue': EdgesApp, + 'CustomEdge.vue': CustomEdge, + 'CustomEdge2.vue': CustomEdge2, + 'CustomEdgeLabel.vue': CustomEdgeLabel, + 'style.css': EdgeCSS, + }, + nested: { + 'App.vue': NestedApp, + }, + stress: { + 'App.vue': StressApp, + 'utils.js': StressUtils, + 'style.css': StressCSS, + }, + updateEdge: { + 'App.vue': UpdateEdgeApp, + }, + updateNode: { + 'App.vue': UpdateNodeApp, + 'style.css': UpdateNodeCSS, + }, + validation: { + 'App.vue': ValidationApp, + 'CustomInput.vue': ValidationCustomInput, + 'CustomNode.vue': ValidationCustomNode, + 'style.css': ValidationCSS, + }, + saveRestore: { + 'App.vue': SaveRestoreApp, + 'Controls.vue': SaveRestoreControls, + 'style.css': SaveRestoreCSS, + }, + dnd: { + 'App.vue': DndApp, + 'Sidebar.vue': DndSidebar, + 'style.css': DndCSS, + }, + empty: { + 'App.vue': EmptyApp, + }, + hidden: { + 'App.vue': HiddenApp, + }, + interaction: { + 'App.vue': InteractionApp, + 'InteractionControls.vue': InteractionControls, + 'style.css': InteractionCSS, + }, + multi: { + 'App.vue': MultiApp, + 'Flow.vue': MultiFlow, + 'style.css': MultiCSS, + }, +} diff --git a/docs/components/examples/interaction/App.vue b/docs/components/examples/interaction/App.vue new file mode 100644 index 00000000..c8fca777 --- /dev/null +++ b/docs/components/examples/interaction/App.vue @@ -0,0 +1,20 @@ + + + diff --git a/docs/components/examples/interaction/InteractionControls.vue b/docs/components/examples/interaction/InteractionControls.vue new file mode 100644 index 00000000..942f4d00 --- /dev/null +++ b/docs/components/examples/interaction/InteractionControls.vue @@ -0,0 +1,110 @@ + + + diff --git a/docs/components/examples/interaction/index.ts b/docs/components/examples/interaction/index.ts new file mode 100644 index 00000000..84792f94 --- /dev/null +++ b/docs/components/examples/interaction/index.ts @@ -0,0 +1,3 @@ +export { default as InteractionApp } from './App.vue?raw' +export { default as InteractionControls } from './InteractionControls.vue?raw' +export { default as InteractionCSS } from './style.css' diff --git a/docs/components/examples/interaction/style.css b/docs/components/examples/interaction/style.css new file mode 100644 index 00000000..b979c3c7 --- /dev/null +++ b/docs/components/examples/interaction/style.css @@ -0,0 +1,22 @@ +.interactionflow .controls { + position: absolute; + left: 0; + top: 0; + z-index: 4; + font-size: 11px; + background-color: lightgray; + border-bottom-right-radius: 10px; + padding: 12px; +} + +.interactionflow .controls .label { + display: flex; + justify-content: space-between; + align-items: center; + gap: 5px; + cursor: pointer; +} + +.interactionflow .controls .label input { + cursor: pointer; +} diff --git a/docs/components/examples/multi/App.vue b/docs/components/examples/multi/App.vue new file mode 100644 index 00000000..2f9b72a7 --- /dev/null +++ b/docs/components/examples/multi/App.vue @@ -0,0 +1,10 @@ + + + diff --git a/docs/components/examples/multi/Flow.vue b/docs/components/examples/multi/Flow.vue new file mode 100644 index 00000000..18058d87 --- /dev/null +++ b/docs/components/examples/multi/Flow.vue @@ -0,0 +1,36 @@ + + + diff --git a/docs/components/examples/multi/index.ts b/docs/components/examples/multi/index.ts new file mode 100644 index 00000000..d6731a00 --- /dev/null +++ b/docs/components/examples/multi/index.ts @@ -0,0 +1,3 @@ +export { default as MultiApp } from './App.vue?raw' +export { default as MultiFlow } from './Flow.vue?raw' +export { default as MultiCSS } from './style.css' diff --git a/docs/components/examples/multi/style.css b/docs/components/examples/multi/style.css new file mode 100644 index 00000000..92c483fd --- /dev/null +++ b/docs/components/examples/multi/style.css @@ -0,0 +1,18 @@ +.vue-flow__node.dark { + background: #000000; + color: #ffffff; +} + +.multiflows { + display: flex; + height: 100%; +} + +.multiflows .vue-flow { + width: 100%; + height: 100%; +} + +.multiflows .vue-flow:first-child { + border-right: 2px solid #333; +} diff --git a/docs/components/examples/nested/App.vue b/docs/components/examples/nested/App.vue new file mode 100644 index 00000000..6b5e8c52 --- /dev/null +++ b/docs/components/examples/nested/App.vue @@ -0,0 +1,98 @@ + + + diff --git a/docs/components/examples/nested/index.ts b/docs/components/examples/nested/index.ts new file mode 100644 index 00000000..7aef51bc --- /dev/null +++ b/docs/components/examples/nested/index.ts @@ -0,0 +1 @@ +export { default as NestedApp } from './App.vue?raw' diff --git a/docs/components/examples/pinia/PiniaExample.vue b/docs/components/examples/pinia/PiniaExample.vue new file mode 100644 index 00000000..99678c6e --- /dev/null +++ b/docs/components/examples/pinia/PiniaExample.vue @@ -0,0 +1,23 @@ + + + + + diff --git a/docs/components/examples/save-restore/App.vue b/docs/components/examples/save-restore/App.vue new file mode 100644 index 00000000..55d9d552 --- /dev/null +++ b/docs/components/examples/save-restore/App.vue @@ -0,0 +1,13 @@ + + + diff --git a/docs/components/examples/save-restore/Controls.vue b/docs/components/examples/save-restore/Controls.vue new file mode 100644 index 00000000..c5eda385 --- /dev/null +++ b/docs/components/examples/save-restore/Controls.vue @@ -0,0 +1,40 @@ + + + diff --git a/docs/components/examples/save-restore/index.ts b/docs/components/examples/save-restore/index.ts new file mode 100644 index 00000000..d6faf819 --- /dev/null +++ b/docs/components/examples/save-restore/index.ts @@ -0,0 +1,3 @@ +export { default as SaveRestoreApp } from './App.vue?raw' +export { default as SaveRestoreControls } from './Controls.vue?raw' +export { default as SaveRestoreCSS } from './style.css' diff --git a/docs/components/examples/save-restore/style.css b/docs/components/examples/save-restore/style.css new file mode 100644 index 00000000..ab1c9790 --- /dev/null +++ b/docs/components/examples/save-restore/style.css @@ -0,0 +1,25 @@ +.save__controls { + position: absolute; + left: 10px; + top: 10px; + z-index: 4; + font-size: 12px; +} + +.save__controls button { + margin-left: 5px; + padding: 5px; + border-radius: 5px; + font-weight: 700; + text-transform: uppercase; + color: white; + -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); + cursor: pointer; +} + +.save__controls button:hover { + opacity: 0.8; + transform: scale(105%); + transition: 250ms all ease-in-out; +} diff --git a/docs/components/examples/stress/App.vue b/docs/components/examples/stress/App.vue new file mode 100644 index 00000000..4c48b65c --- /dev/null +++ b/docs/components/examples/stress/App.vue @@ -0,0 +1,38 @@ + + + diff --git a/docs/components/examples/stress/index.ts b/docs/components/examples/stress/index.ts new file mode 100644 index 00000000..2b70f3e0 --- /dev/null +++ b/docs/components/examples/stress/index.ts @@ -0,0 +1,3 @@ +export { default as StressApp } from './App.vue?raw' +export { default as StressUtils } from './utils.js?raw' +export { default as StressCSS } from './style.css' diff --git a/docs/components/examples/stress/style.css b/docs/components/examples/stress/style.css new file mode 100644 index 00000000..f835f6ea --- /dev/null +++ b/docs/components/examples/stress/style.css @@ -0,0 +1,4 @@ +.vue-flow__node.dark { + background: #000000; + color: #ffffff; +} diff --git a/docs/components/examples/stress/utils.js b/docs/components/examples/stress/utils.js new file mode 100644 index 00000000..5d17c2eb --- /dev/null +++ b/docs/components/examples/stress/utils.js @@ -0,0 +1,32 @@ +export function getElements(xElements = 10, yElements = 10) { + const initialNodes = [] + const initialEdges = [] + let nodeId = 1 + let recentNodeId = null + + for (let y = 0; y < yElements; y++) { + for (let x = 0; x < xElements; x++) { + const position = { x: x * 75, y: y * 75 } + const node = { + id: nodeId.toString(), + style: { width: `50px`, fontSize: `11px` }, + label: `Node ${nodeId}`, + class: 'light', + position, + } + initialNodes.push(node) + + if (recentNodeId && nodeId <= xElements * yElements) { + initialEdges.push({ id: `${x}-${y}`, source: recentNodeId.toString(), target: nodeId.toString() }) + } + + recentNodeId = nodeId + nodeId++ + } + } + + return { + nodes: initialNodes, + edges: initialEdges, + } +} diff --git a/docs/components/examples/update-edge/App.vue b/docs/components/examples/update-edge/App.vue new file mode 100644 index 00000000..bb224f7a --- /dev/null +++ b/docs/components/examples/update-edge/App.vue @@ -0,0 +1,47 @@ + + + diff --git a/docs/components/examples/update-edge/index.ts b/docs/components/examples/update-edge/index.ts new file mode 100644 index 00000000..ad531558 --- /dev/null +++ b/docs/components/examples/update-edge/index.ts @@ -0,0 +1 @@ +export { default as UpdateEdgeApp } from './App.vue?raw' diff --git a/docs/components/examples/update-node/App.vue b/docs/components/examples/update-node/App.vue new file mode 100644 index 00000000..1e9bc50c --- /dev/null +++ b/docs/components/examples/update-node/App.vue @@ -0,0 +1,48 @@ + + + diff --git a/docs/components/examples/update-node/index.ts b/docs/components/examples/update-node/index.ts new file mode 100644 index 00000000..2d3749b4 --- /dev/null +++ b/docs/components/examples/update-node/index.ts @@ -0,0 +1,2 @@ +export { default as UpdateNodeApp } from './App.vue?raw' +export { default as UpdateNodeCSS } from './style.css' diff --git a/docs/components/examples/update-node/style.css b/docs/components/examples/update-node/style.css new file mode 100644 index 00000000..26021bf4 --- /dev/null +++ b/docs/components/examples/update-node/style.css @@ -0,0 +1,30 @@ +.updatenode__controls { + position: absolute; + right: 10px; + top: 10px; + z-index: 4; + font-size: 11px; + background-color: lightgray; + border-radius: 10px; + padding: 8px; +} + +.updatenode__controls label { + display: blocK; +} + +.updatenode__controls input { + padding: 2px; + border-radius: 5px; +} + +.updatenode__bglabel { + margin-top: 8px; +} + +.updatenode__checkboxwrapper { + display: flex; + justify-content: center; + align-items: center; + margin-top: 8px; +} diff --git a/docs/components/examples/validation/App.vue b/docs/components/examples/validation/App.vue new file mode 100644 index 00000000..a9576e98 --- /dev/null +++ b/docs/components/examples/validation/App.vue @@ -0,0 +1,47 @@ + + + diff --git a/docs/components/examples/validation/CustomInput.vue b/docs/components/examples/validation/CustomInput.vue new file mode 100644 index 00000000..f6501416 --- /dev/null +++ b/docs/components/examples/validation/CustomInput.vue @@ -0,0 +1,21 @@ + + + + + diff --git a/docs/components/examples/validation/CustomNode.vue b/docs/components/examples/validation/CustomNode.vue new file mode 100644 index 00000000..9d28c452 --- /dev/null +++ b/docs/components/examples/validation/CustomNode.vue @@ -0,0 +1,25 @@ + + + + + diff --git a/docs/components/examples/validation/index.ts b/docs/components/examples/validation/index.ts new file mode 100644 index 00000000..d2674919 --- /dev/null +++ b/docs/components/examples/validation/index.ts @@ -0,0 +1,4 @@ +export { default as ValidationApp } from './App.vue?raw' +export { default as ValidationCustomInput } from './CustomInput.vue?raw' +export { default as ValidationCustomNode } from './CustomNode.vue?raw' +export { default as ValidationCSS } from './style.css' diff --git a/docs/components/examples/validation/style.css b/docs/components/examples/validation/style.css new file mode 100644 index 00000000..98f3a03b --- /dev/null +++ b/docs/components/examples/validation/style.css @@ -0,0 +1,31 @@ +.validationflow .vue-flow__node { + width: 150px; + border-radius: 5px; + padding: 10px; + color: #555; + border: 1px solid #ddd; + text-align: center; + font-size: 12px; +} + +.validationflow .vue-flow__node-customnode { + background: #e6e6e9; + border: 1px solid #ddd; +} + +.validationflow .vue-flow__node-custominput .vue-flow__handle { + background: #e6e6e9; +} + +.validationflow .vue-flow__node-custominput { + background: #fff; + +} + +.validationflow .vue-flow__handle-connecting { + background: #ff6060; +} + +.validationflow .vue-flow__handle-valid { + background: #55dd99; +} diff --git a/docs/components/home/Features.vue b/docs/components/home/Features.vue index beb90f1f..4276bc1d 100644 --- a/docs/components/home/Features.vue +++ b/docs/components/home/Features.vue @@ -28,18 +28,31 @@ watch([breakpoints.sm, breakpoints.md, breakpoints.lg, breakpoints.xl, breakpoin
-
- -
-
- -
-
- -
-
- +
+ +
+ +
+
+ + +
+ +
+
+ + +
+ +
+
+ + +
+ +
+
diff --git a/docs/components/home/Home.vue b/docs/components/home/Home.vue index 302c8699..85606398 100644 --- a/docs/components/home/Home.vue +++ b/docs/components/home/Home.vue @@ -18,9 +18,11 @@ onMounted(() => { magnetic: false, dotColor: '#10b981', radius: 8, - focusableElementsOffsetX: 2, - focusableElementsOffsetY: 2, + focusableElementsOffsetX: 5, + focusableElementsOffsetY: 4, mode: 'bouncy', + focusableElements: + '[data-blobity], a:not([data-no-blobity]), button:not([data-no-blobity]), [data-blobity-tooltip], .back-to-top, .intro', }) onBeforeUnmount(() => { diff --git a/docs/components/home/flows/Basic.vue b/docs/components/home/flows/Basic.vue index 9f00be3d..efeafc63 100644 --- a/docs/components/home/flows/Basic.vue +++ b/docs/components/home/flows/Basic.vue @@ -1,5 +1,6 @@ diff --git a/docs/components/home/flows/Intro.vue b/docs/components/home/flows/Intro.vue index fc1a438a..93727e86 100644 --- a/docs/components/home/flows/Intro.vue +++ b/docs/components/home/flows/Intro.vue @@ -1,11 +1,17 @@ - - diff --git a/docs/package.json b/docs/package.json index 487c524e..a646fa50 100644 --- a/docs/package.json +++ b/docs/package.json @@ -8,11 +8,17 @@ "lint": "eslint --ext \".js,.jsx,.ts,.tsx\" --fix --ignore-path .gitignore ." }, "dependencies": { - "@braks/vue-flow": "^0.4.6", - "blobity": "^0.1.7" + "@animxyz/core": "^0.6.6", + "@animxyz/vue3": "^0.6.6", + "@braks/vue-flow": "^0.4.11", + "@stackblitz/sdk": "^1.6.0", + "@vue/repl": "^1.1.2", + "blobity": "^0.1.7", + "canvas-confetti": "^1.5.1" }, "devDependencies": { "@iconify/json": "^2.1.22", + "@types/canvas-confetti": "^1.4.2", "@types/node": "^17.0.23", "@vuepress/bundler-vite": "^2.0.0-beta.37", "@vuepress/plugin-docsearch": "^2.0.0-beta.37", diff --git a/docs/src/.vuepress/components.d.ts b/docs/src/.vuepress/components.d.ts index f3d41eea..f14b8376 100644 --- a/docs/src/.vuepress/components.d.ts +++ b/docs/src/.vuepress/components.d.ts @@ -6,17 +6,29 @@ declare module 'vue' { export interface GlobalComponents { Acknowledgement: typeof import('./../../components/home/Acknowledgement.vue')['default'] Additional: typeof import('./../../components/home/flows/Additional.vue')['default'] + App: typeof import('./../../components/examples/basic/App.vue')['default'] Banner: typeof import('./../../components/home/Banner.vue')['default'] Basic: typeof import('./../../components/home/flows/Basic.vue')['default'] - Box: typeof import('./../../components/home/nodes/Box.vue')['default'] + Controls: typeof import('./../../components/examples/save-restore/Controls.vue')['default'] Custom: typeof import('./../../components/home/edges/Custom.vue')['default'] + CustomConnectionLine: typeof import('./../../components/examples/connectionline/CustomConnectionLine.vue')['default'] + CustomEdge: typeof import('./../../components/examples/edges/CustomEdge.vue')['default'] + CustomEdge2: typeof import('./../../components/examples/edges/CustomEdge2.vue')['default'] + CustomEdgeLabel: typeof import('./../../components/examples/edges/CustomEdgeLabel.vue')['default'] + CustomInput: typeof import('./../../components/examples/validation/CustomInput.vue')['default'] + CustomNode: typeof import('./../../components/examples/custom-node/CustomNode.vue')['default'] Features: typeof import('./../../components/home/Features.vue')['default'] + Flow: typeof import('./../../components/examples/multi/Flow.vue')['default'] Home: typeof import('./../../components/home/Home.vue')['default'] Input: typeof import('./../../components/home/nodes/Input.vue')['default'] + InteractionControls: typeof import('./../../components/examples/interaction/InteractionControls.vue')['default'] Intro: typeof import('./../../components/home/flows/Intro.vue')['default'] Nested: typeof import('./../../components/home/flows/Nested.vue')['default'] Output: typeof import('./../../components/home/nodes/Output.vue')['default'] + PiniaExample: typeof import('./../../components/examples/pinia/PiniaExample.vue')['default'] + Repl: typeof import('./../../components/Repl.vue')['default'] RGB: typeof import('./../../components/home/flows/RGB.vue')['default'] + Sidebar: typeof import('./../../components/examples/dnd/Sidebar.vue')['default'] } } diff --git a/docs/src/.vuepress/config.ts b/docs/src/.vuepress/config.ts index e8012ba5..5bfc4234 100644 --- a/docs/src/.vuepress/config.ts +++ b/docs/src/.vuepress/config.ts @@ -10,6 +10,7 @@ import Components from 'unplugin-vue-components/vite' import AutoImport from 'unplugin-auto-import/vite' import head from './head' import { useVueFlow } from '@braks/vue-flow' +import { copyVueFlowPlugin } from "./copy-plugin"; config({ path: resolve(__dirname, '.env') }) @@ -23,7 +24,11 @@ export default defineUserConfig({ bundler: '@vuepress/bundler-vite', bundlerConfig: { viteOptions: { + optimizeDeps: { + exclude: ['@animxyz/vue3'], + }, plugins: [ + copyVueFlowPlugin(), AutoImport({ imports: ['vue', '@vueuse/core'], dts: resolve(__dirname, './auto-imports.d.ts'), @@ -109,6 +114,7 @@ export default defineUserConfig({ '/examples/hidden', '/examples/interaction', '/examples/multi', + '/examples/pinia', '/examples/stress', ], }, diff --git a/docs/src/.vuepress/copy-plugin.ts b/docs/src/.vuepress/copy-plugin.ts new file mode 100644 index 00000000..f1ec3758 --- /dev/null +++ b/docs/src/.vuepress/copy-plugin.ts @@ -0,0 +1,27 @@ +import { Plugin } from 'vite' +import { existsSync, readFileSync } from 'fs' +import { resolve } from 'path' + +export function copyVueFlowPlugin(): Plugin { + return { + name: 'copy-vue-flow', + generateBundle() { + console.log('building') + const filePath = resolve( + __dirname, + '../../../node_modules/@braks/vue-flow/dist/vue-flow.es.js' + ) + if (!existsSync(filePath)) { + throw new Error( + `@braks/vue-flow/dist/vue-flow.es.js not built. ` + + `Run "yarn build" first.` + ) + } + this.emitFile({ + type: 'asset', + fileName: 'vue-flow.es.js', + source: readFileSync(filePath, 'utf-8'), + }) + } + } +} diff --git a/docs/src/.vuepress/theme/clientAppEnhance.ts b/docs/src/.vuepress/theme/clientAppEnhance.ts new file mode 100644 index 00000000..1fa02f56 --- /dev/null +++ b/docs/src/.vuepress/theme/clientAppEnhance.ts @@ -0,0 +1,6 @@ +import { defineClientAppEnhance } from '@vuepress/client' +import VueAnimXyz from '@animxyz/vue3' + +export default defineClientAppEnhance(({ app }) => { + app.use(VueAnimXyz) +}) diff --git a/docs/src/.vuepress/theme/index.ts b/docs/src/.vuepress/theme/index.ts index 728a615e..9b0c7f10 100644 --- a/docs/src/.vuepress/theme/index.ts +++ b/docs/src/.vuepress/theme/index.ts @@ -1,5 +1,6 @@ import { resolve } from 'path' import { Theme } from 'vuepress' +import { path } from '@vuepress/utils' export default { name: 'vuepress-theme-local', @@ -7,4 +8,5 @@ export default { layouts: { Layout: resolve(__dirname, 'layouts/default.vue'), }, + clientAppEnhanceFiles: path.resolve(__dirname, './clientAppEnhance.ts'), } as Theme diff --git a/docs/src/.vuepress/theme/layouts/default.vue b/docs/src/.vuepress/theme/layouts/default.vue index c13e3c99..2a8734ec 100644 --- a/docs/src/.vuepress/theme/layouts/default.vue +++ b/docs/src/.vuepress/theme/layouts/default.vue @@ -1,5 +1,6 @@