Skip to content

Low-Level Composable ​

useVisualLinker(container, options?) — the low-level composable, wired straight to a container element you render yourself. No directives, no discovery, no drawing layer of its own: the engine draws directly inside container, and blocks come only from the reactive blocks option (or your own setBlocks() calls).

ts
function useVisualLinker(
  container: MaybeRefOrGetter<HTMLElement | null | undefined>,
  options?: UseVisualLinkerOptions,
): UseVisualLinkerReturn

Creates the engine on mount and destroys it automatically on unmount.

Options ​

UseVisualLinkerOptions has three reactive fields:

config ​

MaybeRefOrGetter<VisualLinkerConfig> · default: {}

The diagram's configuration. A ref, a getter or a plain object; when it changes, the engine takes the new configuration and redraws. It is merged over the shared configuration of the app, when there is one, and wins over it.

blocks ​

MaybeRefOrGetter<RefFriendlyBlock[]> · default: — (unset, call the engine's own setBlocks() manually)

RefFriendlyBlock is core's BlockDescriptor with el (and dragHandle/dragBounds/a port's target/anchorEl) accepting a Vue ref/getter in addition to a plain element or CSS selector — a block whose el starts out null (its template ref hasn't mounted yet) syncs in automatically once it resolves.

connections ​

MaybeRefOrGetter<ConnectionDescriptor[]> · default: — (unset, call the engine's own setConnections() manually)

Watched with deep: true — mutating an existing connection's style in place re-renders too, not just replacing the whole array.

Return value ​

engine ​

ShallowRef<VisualLinker | null>

The engine instance (see Engine API) — null until the component mounts and container resolves to a real element. Use this for everything the reactive blocks/connections options don't cover: addConnection/removeConnection, refresh(), on(), or calling setBlocks/setConnections yourself instead of passing the reactive options.

Example:

vue
<script setup lang="ts">
import { ref, computed } from 'vue'
import { useVisualLinker } from '@macrulez/visual-linker-vue'

const containerEl = ref<HTMLElement | null>(null)
const blockAEl = ref<HTMLElement | null>(null)
const blockBEl = ref<HTMLElement | null>(null)

const blocks = computed(() => [
  { id: 'a', el: blockAEl },
  { id: 'b', el: blockBEl },
])
const connections = ref([{ id: 'a-b', from: { blockId: 'a' }, to: { blockId: 'b' } }])

const config = ref({ lines: { curve: 'smoothstep' } }) // change it later and the diagram follows

const { engine } = useVisualLinker(containerEl, { blocks, connections, config })
</script>

<template>
  <div ref="containerEl" style="position: relative">
    <div ref="blockAEl">A</div>
    <div ref="blockBEl">B</div>
  </div>
</template>