Vue composables
Reactive composables for accessing board state inside Vue components.
All composables must be called inside a component that is a descendant of <BoardRoot>. They inject the board engine context via Vue's provide/inject system.
useBoardEngine
Returns the full board engine context. This is the primary composable — all other composables are thin wrappers over this.
function useBoardEngine(): BoardEngineContextReturn type
| Property | Type | Description |
|---|---|---|
engine | BoardEngine | The engine instance for calling commands. |
rootElement | Ref<HTMLElement | null> | The BoardRoot DOM element. |
viewportSize | Ref<Point> | Current viewport dimensions in pixels. |
renderers | ShallowRef<BoardRendererRegistry> | Registered custom renderers. |
resolvedGrid | ComputedRef<ResolvedBoardGridOptions> | Resolved grid options (engine defaults merged with BoardRoot props). |
toLocalPoint | (clientX, clientY) => Point | Converts page coordinates to board-local coordinates. |
$camera | ShallowRef<Camera> | Reactive camera state. |
$grid | ShallowRef<GridSettings> | Reactive grid state. |
$nodes | ShallowRef<ReadonlyMap<NodeId, BoardNode>> | Reactive node map. |
$selection | ShallowRef<ReadonlySet<NodeId>> | Reactive selection set. |
$interaction | ShallowRef<InteractionState> | Reactive interaction state. |
$snapGuides | ShallowRef<readonly SnapGuide[]> | Reactive snap guides. |
<script setup lang="ts">
import { useBoardEngine } from '@lupinum/vue-board'
const { engine, $camera, $nodes } = useBoardEngine()
// Read the current camera
console.log($camera.value.z) // zoom level
// Call engine commands
engine.selectAll()
</script>useBoardCamera
Returns a computed ref of the current camera state.
function useBoardCamera(): ComputedRef<Camera><script setup lang="ts">
import { useBoardCamera } from '@lupinum/vue-board'
const camera = useBoardCamera()
</script>
<template>
<div>Zoom: {{ Math.round(camera.z * 100) }}%</div>
</template>useBoardNodes
Returns a computed ref of the node map.
function useBoardNodes(): ComputedRef<ReadonlyMap<NodeId, BoardNode>><script setup lang="ts">
import { useBoardNodes } from '@lupinum/vue-board'
const nodes = useBoardNodes()
const nodeCount = computed(() => nodes.value.size)
</script>useBoardSelection
Returns a computed ref of the currently selected node IDs as an array.
function useBoardSelection(): ComputedRef<readonly NodeId[]><script setup lang="ts">
import { useBoardSelection } from '@lupinum/vue-board'
const selection = useBoardSelection()
</script>
<template>
<div>{{ selection.length }} selected</div>
</template>useBoardInteraction
Returns a computed ref of the current interaction state.
function useBoardInteraction(): ComputedRef<InteractionState><script setup lang="ts">
import { useBoardInteraction } from '@lupinum/vue-board'
const interaction = useBoardInteraction()
const isDragging = computed(() => interaction.value.mode === 'dragging-nodes')
</script>useBoardVisibleBounds
Returns a computed ref of the current viewport bounds in world-space coordinates.
function useBoardVisibleBounds(): ComputedRef<Bounds><script setup lang="ts">
import { useBoardVisibleBounds } from '@lupinum/vue-board'
const bounds = useBoardVisibleBounds()
// bounds.value = { minX, minY, maxX, maxY }
</script>useBoardVisibleNodes
Returns a computed ref of all visible nodes within the viewport, with an optional culling margin.
function useBoardVisibleNodes(
margin?: number,
): ComputedRef<readonly BoardNode[]>| Parameter | Type | Default | Description |
|---|---|---|---|
margin | number | 200 | Extra world-space margin around the viewport for culling. |
<script setup lang="ts">
import { useBoardVisibleNodes } from '@lupinum/vue-board'
const visible = useBoardVisibleNodes(300) // 300 world-unit margin
</script>
<template>
<div>{{ visible.length }} nodes visible</div>
</template>useBoardGridStyle
Returns a computed CSS variable object for rendering the grid. Used internally by BoardGrid but available for custom grid implementations.
function useBoardGridStyle(): ComputedRef<Record<string, string>>Returned CSS variables
| Variable | Description |
|---|---|
--grid-minor-size | Screen-space minor grid step. |
--grid-major-size | Screen-space major grid step. |
--grid-minor-x | Minor grid horizontal offset. |
--grid-minor-y | Minor grid vertical offset. |
--grid-major-x | Major grid horizontal offset. |
--grid-major-y | Major grid vertical offset. |
--grid-minor-color | Minor grid line color (with computed opacity). |
--grid-major-color | Major grid line color (with computed opacity). |
--grid-mask-image | Edge fade mask (radial gradient or none). |
Grid opacity automatically reduces at low zoom levels (minor lines fade below 12px screen step, disappear below 6px).
useBoardNode
Returns reactive state and actions for a single node. Ideal for custom renderer components.
function useBoardNode(id: MaybeRefOrGetter<NodeId>): {
node: ComputedRef<BoardNode>
selected: ComputedRef<boolean>
editing: ComputedRef<boolean>
locked: ComputedRef<boolean>
style: ComputedRef<CSSProperties>
beginEdit: () => void
commitText: (text: string) => void
startDrag: (event: PointerEvent) => void
startResize: (handle: ResizeHandle, event: PointerEvent) => void
}Return type
| Property | Type | Description |
|---|---|---|
node | ComputedRef<BoardNode> | The reactive node data. Throws if the node is removed. |
selected | ComputedRef<boolean> | Whether the node is selected. |
editing | ComputedRef<boolean> | Whether the node is being text-edited. |
locked | ComputedRef<boolean> | Whether the node is locked. |
style | ComputedRef<CSSProperties> | CSS position/size/zIndex for absolute positioning. |
beginEdit | () => void | Start text editing when this is a text node. |
commitText | (text: string) => void | Commit text when this is a text node. |
startDrag | (event: PointerEvent) => void | Begin dragging this node from a pointer event. |
startResize | (handle, event) => void | Begin resizing this node from a handle and pointer event. |
<script setup lang="ts">
import { useBoardNode } from '@lupinum/vue-board'
import type { NodeId } from '@lupinum/board-core'
const props = defineProps<{ nodeId: NodeId }>()
const { node, selected, style, beginEdit } = useBoardNode(() => props.nodeId)
</script>
<template>
<div :style="style" :class="{ selected }" @dblclick="beginEdit">
{{ node.text }}
</div>
</template>useBoardBoxSelectBounds
Returns a computed ref of the current box selection bounds in screen-space, or null if no box selection is active.
function useBoardBoxSelectBounds(): ComputedRef<Bounds | null><script setup lang="ts">
import { useBoardBoxSelectBounds } from '@lupinum/vue-board'
const bounds = useBoardBoxSelectBounds()
</script>
<template>
<div
v-if="bounds"
class="custom-box-select"
:style="{
left: bounds.minX + 'px',
top: bounds.minY + 'px',
width: bounds.maxX - bounds.minX + 'px',
height: bounds.maxY - bounds.minY + 'px',
}"
/>
</template>