Visual Linker
0.4.3
2026-10-02
- Changed (default behavior):
hoverandhighlightare now opt-in. A line used to react to the pointer in every diagram: it took thehoverstate with a width bump, showed a pointer cursor over its click area, and hovering a block lit up its connections. Now none of that happens until you turn it on, so a diagram that is only looked at stays still. The pointer cursor appears on a line only when hover is on for it or when it is selectable. To get the previous behavior, setinteraction: { hover: true, highlight: true }. - New:
interaction.hoverandinteraction.highlight. Two independent flags, bothfalseby default.hoveris the pointer over a line,highlightis the pointer over a block lighting up its connections. See Visual States. - New:
hoverableon a connection andhighlightableon a block. Each turns its mode on or off for one entity, and the local value wins over the global one.highlightableis also an option ofv-vl-block, a field of theblocksprop and thedata-vl-highlightableattribute. - Unchanged: the events
connection:mouseenter,connection:mouseleave,connection:click,block:mouseenterandblock:mouseleavefire as before, and theselectedandfocusstates, selection and keyboard operation do not depend on the new flags. Ahoverorhighlightbucket does nothing while its mode is off. Both flags can be changed withsetConfig.
0.4.2
2026-10-02
- A port anchored to a block is no longer pinned by a clipping wrapper inside that block. For a port with
anchorBlockIdoranchorEl, the point is drawn on the border of the anchor, but whether it is clipped was decided by that point. A row inside an element withoverflow: hidden— a rounded segmented control, a card — inside a padded block, anchored to the block's bottom border, has its point below the wrapper, so its line was pulled up to the wrapper's edge and lost its marker and port dot. Whether such a port is clipped is now decided by its own element: a row that is visible keeps its point on the anchor's border, and a row that has scrolled out of view is pinned as before. Ports without an anchor are unchanged. See Scrolling Containers.
0.4.1
2026-10-02
- Strings are accepted wherever an enum was. The types of
lines.curve, a marker'sshapeandorient, and a port'ssidewere unions of enum members, so TypeScript rejectedcurve: 'straight'orshape: 'arrow'withType '"straight"' is not assignable to type 'ConnectionCurve', although both worked at runtime. They are now the plain string unions ('bezier' | 'straight' | 'smoothstep','circle' | 'square' | 'diamond' | 'arrow','top' | 'right' | 'bottom' | 'left','auto' | 'fixed') and still accept the enum members, so existing code keeps compiling.VLConnectionCurveEnum,VLMarkerShapeEnum,VLFixedSideEnumandVLOrientEnumare still exported. See Configuration.
0.4.0
2026-10-02
Breaking (all packages): the flat
VisualLinkerOptionsis replaced by one structuredVisualLinkerConfig, grouped by what it styles:theme,lines,markers,ports,labels,blocksandinteraction. EverydefaultXxxoption is gone; each setting has a place in a group. A connection'sstylehas the same shape as thelinesgroup, plusmarkers: { start, end }. See Configuration. The old names map to the new ones like this:0.3.x 0.4.0 defaultCurvelines.curvedefaultCurvature,defaultCurveMinReach,defaultCurveMaxReach,defaultCurveAngleBlend,defaultCurveAngleMaxOffsetlines.bezier.curvature,minReach,maxReach,angleBlend,angleMaxOffsetdefaultCornerRadius,defaultMaxTrunkReachlines.smoothstep.cornerRadius,lines.smoothstep.maxTrunkReachavoidObstacles,obstaclePaddinglines.routing.avoidObstacles,lines.routing.paddingjumps,defaultAnimatedlines.jumps,lines.animatedshowPortsports.showdefaultPortRadius,defaultPortColor,defaultPortStrokeColor,defaultPortStrokeWidthports.radius,ports.fill,ports.stroke,ports.strokeWidthdefaultPortSpreadports.spreaddefaultCircleMarkerSize,defaultSquareMarkerSize,defaultDiamondMarkerSize,defaultArrowMarkerSizemarkers.sizes.circle,square,diamond,arrowdraggable,dragGridSize,dragBoundsblocks.draggable,blocks.drag.grid,blocks.drag.boundsselectable,clipToScrollParentsinteraction.selectable,interaction.clipToScrollParentsstyle.curvature,curveMinReach,curveMaxReach,curveAngleBlend,curveAngleMaxOffsetstyle.bezier.curvature,minReach,maxReach,angleBlend,angleMaxOffsetstyle.cornerRadius,style.maxTrunkReachstyle.smoothstep.cornerRadius,style.smoothstep.maxTrunkReachstyle.avoidObstaclesstyle.routing.avoidObstaclesstyle.startMarker,style.endMarkerstyle.markers.start,style.markers.endstyle.hoverStyle,style.selectedStylestyle.hover,style.selectedhoverStyle.markerSize,selectedStyle.markerSizesizein the marker's ownhoverandselectedVisualLinkerOptionsVisualLinkerConfigBreaking (Vue): the
optionsprop of<VisualLinker>is nowconfig, and theUseVisualLinkerOptionsofuseVisualLinker()no longer extends the engine's options: it hasconfig,blocksandconnections.configis reactive, so changing it redraws the diagram. See VisualLinker Component.Breaking (Vue): the shared configuration moves from a global object to Vue's
provide/inject.setVisualLinkerDefaults(),resetVisualLinkerDefaults(),visualLinkerDefaultsand theVisualLinkerDefaultstype are removed. Pass the configuration toapp.use(VisualLinkerPlugin, { config }), and change it later throughuseVisualLinkerConfig(). See Shared Configuration.Breaking (Nuxt): the module options are the engine's configuration itself — the same
theme,lines,markers,ports,labels,blocksandinteractiongroups — instead of a separate flat list (defaultCurve,portRadius,curvature, …). They must be JSON-serializable. The four settings the old list could not reach (defaultCornerRadius,defaultMaxTrunkReach,draggable,dragBounds) are now ordinary fields. The client-only plugin is gone; one universal plugin registers the directives and installs the configuration. See Nuxt Module.Breaking (core): a marker configured in
markers.startormarkers.endreplaces the built-in port dot at that end of every connection, as a marker set on a single connection always did. Marker colors now follow the theme's line colors too.New (core): visual states for every visual entity. Lines, markers, ports and labels take
highlight,hover,selectedandfocusbuckets with the fields of the entity itself, stacked in that order over the base. A marker can change itsshape,size, colors, outline,arrowor wholesvgin a state; a port can grow, a label can change its fill. Markers, ports and labels follow the state of their connection. See Visual States.New (core): the
highlightstate. A hovered block now puts its connections intohighlight, apart fromhover, the pointer over the line itself. Until ahighlightbucket is set it looks the same ashover, so existing configurations look as before.New (core):
opacityfor lines, markers, ports and labels, also per state. A marker without its ownopacityfades with its line, and an animated line multiplies it with its dimming.New (core): themes. A
themeis a set of color tokens —line,lineHover,lineSelected,selectedHalo,focusRing,portFill,portStroke,labelBackground,labelBorder,labelText— written to CSS variables.lightTheme,darkThemeanddefineTheme(overrides, base)are exported. See Themes.New (core):
labelsgroup —background,border,color,fontSize,paddingX,paddingYandopacityof library-drawn labels, with states — andports.sideandports.offsetas the defaults for ports that set none of their own.New (core): the configuration can be changed while the engine runs.
setConfig(patch)deep-merges (a key set toundefinedis removed),replaceConfig(next)replaces,getConfig()returns a copy. Dragging and selection are attached or detached to match, and everything is redrawn. Also exported:mergeConfig,patchConfigandmergeMarkerInputs.New (Vue): the shared configuration.
VisualLinkerPlugintakes{ config };useVisualLinkerConfig()returns the reactive object;provideVisualLinkerConfig(initial?)scopes one to a subtree;installVisualLinkerConfig,createSharedConfigandVISUAL_LINKER_CONFIG_KEYserve integrations. Every diagram merges it under its ownconfig, and a change to it redraws all of them. Nothing is global, so several apps on a page do not interfere.Changed (core): the
block:mouseenterevent puts the block's connections intohighlightrather thanhover, and the line under the pointer is the only one inhover.