Help Needed: Creating a Custom OutlineProvider in BPMN.js for Custom Shapes

Hi everyone,

I’m trying to extend the OutlineProvider class in BPMN.js to create custom outlines for my custom shapes, but I’m facing challenges and haven’t found a solution yet. The default implementation always renders a rectangle, and I need to customize it for specific shapes.

I followed the guidance in this forum thread, but extending OutlineProvider directly doesn’t seem to work in my case.

Here’s the code I’m working with:

import { create as svgCreate, attr as svgAttr } from "tiny-svg";
import OutlineProvider from "diagram-js/lib/features/outline";

export default class CustomOutlineProvider extends OutlineProvider {
  constructor(styles) {
    super(styles);
    this.styles = styles;
  }

  getOutline(element) {
    if (element.type === "traza:Terminal") {
      const outline = svgCreate("rect");

      const width = element.width || 160;
      const height = element.height || 40;
      const rx = Math.min(width, height) / 4;

      const style = this.styles.cls("djs-outline", ["no-fill"]);

      svgAttr(outline, {
        x: -5,
        y: -5,
        width: width + 10,
        height: height + 10,
        rx: rx,
        ry: rx,
        ...style,
      });

      return outline;
    }

    return super.getOutline(element);
  }
}

CustomOutlineProvider.$inject = ["styles"];

The problem is that I cannot extend OutlineProvider properly. It throws an error or doesn’t work as expected during runtime. I suspect it might be related to how OutlineProvider is structured or exported in the library.

Has anyone successfully implemented a custom OutlineProvider or found a workaround to achieve this? Any guidance, code examples, or pointers would be greatly appreciated.

Thanks in advance! :blush:

Hey! I’ve faced the same problem before — extending OutlineProvider directly can be a bit tricky because the way it’s built doesn’t make it easy to customize through inheritance. A better way is to create your own service or function that handles the getOutline logic for your shapes, and then make sure it runs before the default provider by setting a higher priority when you register it. Another option is to add a custom shape outline using event listeners or custom rendering, instead of trying to extend the class itself. If you can share the exact error message, I’d be happy to help you figure it out!