diff --git a/docs/components/examples/index.ts b/docs/components/examples/index.ts
index 526d1066..7887b8a9 100644
--- a/docs/components/examples/index.ts
+++ b/docs/components/examples/index.ts
@@ -17,6 +17,7 @@ import { HorizontalApp, HorizontalElements } from './horizontal'
import { TeleportApp, TeleportCSS, TeleportSidebar, TeleportableNode, TeleportableUseTransition } from './teleport'
import { TransitionApp, TransitionCSS, TransitionEdge } from './transition'
import { IntersectionApp, IntersectionCSS, IntersectionElements } from './intersection'
+import { SnapToHandleApp, SnappableConnectionLine } from './snap-to-handle'
export const exampleImports = {
basic: {
@@ -114,4 +115,8 @@ export const exampleImports = {
'initial-elements.js': IntersectionElements,
'style.css': IntersectionCSS,
},
+ snappable: {
+ 'App.vue': SnapToHandleApp,
+ 'SnappableConnectionLine.vue': SnappableConnectionLine,
+ },
}
diff --git a/docs/components/examples/snap-to-handle/App.vue b/docs/components/examples/snap-to-handle/App.vue
new file mode 100644
index 00000000..2ea93848
--- /dev/null
+++ b/docs/components/examples/snap-to-handle/App.vue
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
diff --git a/docs/components/examples/snap-to-handle/SnappableConnectionLine.vue b/docs/components/examples/snap-to-handle/SnappableConnectionLine.vue
new file mode 100644
index 00000000..4ed472f8
--- /dev/null
+++ b/docs/components/examples/snap-to-handle/SnappableConnectionLine.vue
@@ -0,0 +1,149 @@
+
+
+
+
+
+
+
+
diff --git a/docs/components/examples/snap-to-handle/index.ts b/docs/components/examples/snap-to-handle/index.ts
new file mode 100644
index 00000000..ac77651f
--- /dev/null
+++ b/docs/components/examples/snap-to-handle/index.ts
@@ -0,0 +1,2 @@
+export { default as SnapToHandleApp } from './App.vue?raw'
+export { default as SnappableConnectionLine } from './SnappableConnectionLine.vue?raw'
diff --git a/docs/src/.vitepress/config.ts b/docs/src/.vitepress/config.ts
index 6231330c..2db45ba2 100644
--- a/docs/src/.vitepress/config.ts
+++ b/docs/src/.vitepress/config.ts
@@ -218,6 +218,7 @@ export default defineConfigWithTheme({
{ text: 'Updatable Edge', link: '/examples/edges/updatable-edge' },
{ text: 'Custom Connection Line', link: '/examples/edges/connection-line' },
{ text: 'Connection Validation', link: '/examples/edges/validation' },
+ { text: 'Snap To Handle', link: '/examples/edges/snap-to-handle' },
],
},
],
diff --git a/docs/src/components.d.ts b/docs/src/components.d.ts
index 28995439..48884bc7 100644
--- a/docs/src/components.d.ts
+++ b/docs/src/components.d.ts
@@ -35,6 +35,7 @@ declare module '@vue/runtime-core' {
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
Sidebar: typeof import('./../components/examples/dnd/Sidebar.vue')['default']
+ SnappableConnectionLine: typeof import('./../components/examples/snap-to-handle/SnappableConnectionLine.vue')['default']
Team: typeof import('./../components/home/Team.vue')['default']
TeleportableNode: typeof import('./../components/examples/teleport/TeleportableNode.vue')['default']
TransitionEdge: typeof import('./../components/examples/transition/TransitionEdge.vue')['default']
diff --git a/docs/src/examples/edges/snap-to-handle.md b/docs/src/examples/edges/snap-to-handle.md
new file mode 100644
index 00000000..cacef240
--- /dev/null
+++ b/docs/src/examples/edges/snap-to-handle.md
@@ -0,0 +1,8 @@
+# Custom Connection Line
+
+In this example we will create a custom connection line
+that snaps to the nearest handle when the connection is dropped within distance of a handle.
+
+
+
+
diff --git a/examples/vite/router.ts b/examples/vite/router.ts
index 71101096..975a15fc 100644
--- a/examples/vite/router.ts
+++ b/examples/vite/router.ts
@@ -6,10 +6,6 @@ export const routes: RouterOptions['routes'] = [
path: '/',
redirect: '/overview',
},
- {
- path: '/rgb',
- component: () => import('./src/RGBFlow/RGBFlow.vue'),
- },
{
path: '/basic',
component: () => import('./src/Basic/Basic.vue'),
@@ -18,6 +14,10 @@ export const routes: RouterOptions['routes'] = [
path: '/basic-options-api',
component: () => import('./src/Basic/BasicOptionsAPI.vue'),
},
+ {
+ path: '/snap-handle',
+ component: () => import('./src/SnapHandle/SnapHandleExample.vue'),
+ },
{
path: '/custom-connectionline',
component: () => import('./src/CustomConnectionLine/CustomConnectionLine.vue'),
@@ -106,6 +106,10 @@ export const routes: RouterOptions['routes'] = [
path: '/nesting',
component: () => import('./src/Nesting/Nesting.vue'),
},
+ {
+ path: '/rgb',
+ component: () => import('./src/RGBFlow/RGBFlow.vue'),
+ },
]
export const router = createRouter({
diff --git a/examples/vite/src/SnapHandle/SnapHandleExample.vue b/examples/vite/src/SnapHandle/SnapHandleExample.vue
new file mode 100644
index 00000000..0a68ba2d
--- /dev/null
+++ b/examples/vite/src/SnapHandle/SnapHandleExample.vue
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
diff --git a/examples/vite/src/SnapHandle/SnappableConnectionLine.vue b/examples/vite/src/SnapHandle/SnappableConnectionLine.vue
new file mode 100644
index 00000000..c6eecc96
--- /dev/null
+++ b/examples/vite/src/SnapHandle/SnappableConnectionLine.vue
@@ -0,0 +1,126 @@
+
+
+
+
+
+
+
+