Skip to content

0.24.0

Latest

Choose a tag to compare

@github-actions github-actions released this 08 Jul 15:55
· 19 commits to main since this release
Immutable release. Only release title and notes can be modified.
v0.24.0
1264b06

Version 0.24.0 released on 2026-07-08.

⚡ This new version continues improving modularity and tree-shaking: the image bundle feature moves to a dedicated plugin and per-edge-style registration helpers are introduced. ⚡

Breaking changes

Edge handle visibility is now driven by registry metadata

EdgeHandler.isHandleVisible() now uses EdgeStyleRegistry.allowsIntermediateHandles() instead of checking against the EdgeStyle.EntityRelation function reference.

  • If you register custom edge styles that should hide intermediate bend handles, you must now set allowIntermediateHandles: false in the EdgeStyleMetaData when calling EdgeStyleRegistry.add().
  • If you register EdgeStyle.EntityRelation yourself (e.g. when using BaseGraph), include { allowIntermediateHandles: false } in the metadata to preserve the previous behavior, or call the new registerEntityRelationEdgeStyle() function which sets the correct metadata for you.
  • EdgeStyleRegistryInterface has a new allowsIntermediateHandles method. If you implement this interface directly, you must add this method.

If you register EdgeStyle.EntityRelation yourself:

// Before: the previous behavior was implied by the EntityRelation reference
import { EdgeStyle, EdgeStyleRegistry } from '@maxgraph/core';

EdgeStyleRegistry.add('entityRelationEdgeStyle', EdgeStyle.EntityRelation, {
  isOrthogonal: true,
});
// After: opt in explicitly, or use the dedicated helper
import { EdgeStyle, EdgeStyleRegistry, registerEntityRelationEdgeStyle } from '@maxgraph/core';

EdgeStyleRegistry.add('entityRelationEdgeStyle', EdgeStyle.EntityRelation, {
  allowIntermediateHandles: false,
  isOrthogonal: true,
});
// or simply:
registerEntityRelationEdgeStyle();

For more details, see #1040.

ImageMixin converted to ImageBundlePlugin

ImageMixin has been converted to a new ImageBundlePlugin (id 'image-bundle'). Unlike a mixin, which shares a single state tree across all Graph instances and adds domain-specific methods to AbstractGraph, the plugin is per-instance and opt-in, keeping AbstractGraph lean. As a result, AbstractGraph.addImageBundle, removeImageBundle, getImageFromBundles and the imageBundles property no longer exist on AbstractGraph, Graph, or BaseGraph.

  • Migrate mutating call sites from graph.addImageBundle(bundle) (and siblings) to graph.getPlugin<ImageBundlePlugin>('image-bundle')!.addImageBundle(bundle). The non-null assertion is deliberate: if the plugin is not registered, the call fails fast rather than silently dropping the registration.
  • For read-only key resolution, use graph.getPlugin<ImageBundlePlugin>('image-bundle')?.getImageFromBundles(key).
  • BaseGraph no longer ships image-bundle support by default. Add ImageBundlePlugin to the plugins option to opt in. Graph continues to work unchanged because ImageBundlePlugin is part of getDefaultPlugins().
  • XML serialization of <Graph> and <BaseGraph> no longer emits <Array as="imageBundles" />. Existing XML documents containing that element still decode without error, but the field is silently ignored.
// Before
graph.addImageBundle(bundle);
const image = graph.getImageFromBundles(key);
// After
import { ImageBundlePlugin } from '@maxgraph/core';

graph.getPlugin<ImageBundlePlugin>('image-bundle')!.addImageBundle(bundle);
const image = graph.getPlugin<ImageBundlePlugin>('image-bundle')?.getImageFromBundles(key);

A new "image bundles" usage guide and a Storybook story cover registration, the BaseGraph opt-in, and the XML-serialization change.

This change is part of #762. For more details, see #1050.

Highlights

Per-edge-style register helpers

There is now one register*EdgeStyle helper per built-in edge style (Elbow, EntityRelation, Loop, Manhattan, Orthogonal, Segment, SideToSide, TopToBottom), so BaseGraph users can register only what they need, without pulling in all of them and without having to know the associated EdgeStyleMetaData. registerDefaultEdgeStyles() now simply calls these eight helpers.

Before, you had to register each style explicitly and pass the right metadata by hand:

import { EdgeStyle, EdgeStyleRegistry } from '@maxgraph/core';

EdgeStyleRegistry.add('entityRelationEdgeStyle', EdgeStyle.EntityRelation, {
  allowIntermediateHandles: false,
  isOrthogonal: true,
});
EdgeStyleRegistry.add('manhattanEdgeStyle', EdgeStyle.ManhattanConnector, {
  handlerKind: 'segment',
  isOrthogonal: true,
});

Now, call the dedicated helper for each style you need:

import {
  registerEntityRelationEdgeStyle,
  registerManhattanEdgeStyle,
} from '@maxgraph/core';

registerEntityRelationEdgeStyle();
registerManhattanEdgeStyle();

For more details, see #1077.

Edge handle visibility driven by registry metadata

Intermediate bend handle visibility is now resolved from edge style registry metadata (allowsIntermediateHandles) rather than from a hard-coded reference to EdgeStyle.EntityRelation. Previously only EntityRelation could influence handle visibility; now any edge style, including custom ones, controls it through configuration instead of being forced to write code to override maxGraph's defaults. Because EdgeHandler no longer imports EdgeStyle directly, EntityRelation is tree-shaken when your application does not register it, saving about 2 kB. See the Breaking changes section above for the migration details.

This closes #978. For more details, see #1040.

Bundle size

Overall the example bundle sizes stay roughly stable. The reduced examples (selected-features and without-defaults) shrink by 1 to 3 kB because EntityRelation and the image-bundle code path are now tree-shaken when they are not used. The fully featured examples (js-example, ts-example) grow by about 1 kB: they still register EntityRelation by default, so they do not benefit from the tree-shaking but do include the new handle-visibility code.

Examples in the maxGraph repository

Example 0.23.0 0.24.0
js-example 467.65 kB 468.70 kB
js-example-selected-features 388.78 kB 386.38 kB
js-example-without-defaults 323.37 kB 320.97 kB
ts-example 433.53 kB 434.58 kB
ts-example-selected-features 367.64 kB 366.37 kB
ts-example-without-defaults 306.64 kB 303.70 kB

Resources

What's Changed

🎉 New Features

🐛 Bug Fixes

  • fix: restore preview edge default target position on cell hover by @LOUISNOYEZ in #1025
  • fix(connectionHandler): apply perimeter style to new edges by @LOUISNOYEZ in #1026
  • fix : make the KeyHandler work in the Validation story by @LOUISNOYEZ in #1027
  • fix(ConnectorShape): ignore unset arrows in edge bounding box by @tbouffard in #1094

📝 Documentation

  • docs: fix wording in the perimeters documentation by @tbouffard in #1032
  • docs: add AGENTS.md and align agent configs with current code by @redfish4ktc in #1049
  • docs: add graph documentation page and refine related pages by @redfish4ktc in #1048

⚙️ Refactor

  • refactor!: convert ImageMixin to ImageBundlePlugin by @tbouffard in #1050
  • refactor: improve GraphSelectionModel implementation, jsdoc and tests by @redfish4ktc in #1055
  • test(FitPlugin): simplify container dimension setup by @redfish4ktc in #1079

🛠 Chore

New Contributors

Full Changelog: v0.23.0...v0.24.0