Append Menu internals
Overview
The custom append menu replaces the default popup from bpmn-js-create-append-anything with a positioned two-panel Preact overlay that combines element templates with standard BPMN elements. The override is transparent to the rest of bpmn-js — commandStack.append flows are unchanged.
See the user-facing Append Menu page for screenshots and the UX contract.
System overview
Two libraries cooperate:
| Library | Role |
|---|---|
libs/append-menu/ | UI overlay — decorates the diagram-js popup menu and renders the Preact panel. |
libs/create-append-c7-element-templates/ | Polyfills elementTemplates.createElement() for Camunda 7, so bpmn-js-create-append-anything can instantiate template-preconfigured elements. |
Both are registered as additionalModules when the modeler is constructed in apps/bpmn-webview/src/app/modeler.ts.
Entry points
AppendMenuOverridedecorates diagram-js'spopupMenu.open(...). When the provider id isbpmn-appendorbpmn-create, the override collects entries frompopupMenu._getContext()and renders the overlay instead of the default popup.TemplateElementFactory(C7 polyfill) patcheselementTemplates.createElementon the Camunda 7 element templates service at module init.
Key files
| File | Purpose |
|---|---|
libs/append-menu/src/index.ts | DI module export |
libs/append-menu/src/AppendMenuOverride.ts | Decorates popupMenu.open(), manages overlay lifecycle |
libs/append-menu/src/types.ts | Entry types, classification, BPMN type → icon mapping |
libs/append-menu/src/components/AppendMenuOverlay.tsx | Root component: positioning, search, state management |
libs/append-menu/src/components/TemplatePanel.tsx | Template list with category chips and keyboard navigation |
libs/append-menu/src/components/BpmnElementPalette.tsx | Collapsible BPMN element palette with favourites |
libs/append-menu/src/components/ExpandableTemplateCard.tsx | Template card with hover-to-expand detail |
libs/append-menu/src/append-menu.css | All styles (prefixed with am-) |
libs/create-append-c7-element-templates/src/index.ts | C7 createElement polyfill module |
libs/create-append-c7-element-templates/src/TemplateElementFactory.ts | Creates shapes with templates applied via command stack |
libs/create-append-c7-element-templates/src/ExtendElementTemplates.ts | Patches createElement onto the C7 element templates service |
Interaction flow
- User clicks the Append element button in the context pad, or presses
Ain the palette. - diagram-js invokes
popupMenu.open('bpmn-append', …)— intercepted byAppendMenuOverride. - The override collects all provider entries, classifies them into templates (enriched with the full
ElementTemplateobject) and standard BPMN elements (grouped by category). - A Preact overlay is rendered into
document.body, positioned near the trigger point and clamped to the canvas bounds. - Clicking an entry triggers the underlying
bpmn-append/bpmn-createaction through the realpopupMenu(the override only short-circuits the presentation, not the command dispatch). - The overlay closes on outside click,
Escape,contextPad.close,canvas.viewbox.changing, orcommandStack.changed.
Gotchas
- The override must not swallow the entries — after rendering the overlay it still calls the underlying factory when the user picks something, so the regular
bpmn-appendcommand flow runs intact. - The BPMN element palette defaults to icon-only to keep the panel compact. Expanding it changes layout — test overlay positioning at both sizes when you touch
am-palette-*CSS. - The C7 template-creation polyfill exists because the upstream
@camunda/element-templatesC7 build doesn't shipcreateElement. If you upgrade that package, double-check whether the polyfill is still needed.
Related
- bpmn-js-create-append-anything — upstream palette
- diagram-js
popupMenu— the primitive being decorated - Architecture overview — mental model for bpmn-js DI modules