Skip to Content
DocumentationDeclarative API

Declarative API (defineElement)

dmn.plugin.defineElement is an API that lets you define plugin UI declaratively without complex DOM manipulation.

Key Benefits

FeatureDescription
Automatic settings UIJust define settings schema, panel (default) or modal auto-generated
Instance state isolationCreate multiple panels from the same plugin
Tab-based isolationPanels only appear in the tab they were created
Automatic state syncMain ↔ Overlay state auto-synchronized
Context menu integrationRight-click menu auto-generated
Lifecycle managementAuto mount/unmount on tab switch
Free resizeResize directly in the grid

Basic Structure

// @id my-plugin dmn.plugin.defineElement({ // Plugin name (shown in context menu) name: "My Plugin", // Max instances (optional, 0 = unlimited) maxInstances: 1, // Enable grid resize (optional, default: false) resizable: true, // Axis to preserve on settings change (optional, only when resizable is true, default: "both") // "width" | "height" | "both" | "none" preserveAxis: "both", // Resize anchor (optional, default: "top-left") resizeAnchor: "center", // Context menu settings contextMenu: { create: "Create Panel", delete: "Delete Panel", items: [ /* custom menu items */ ], }, // Settings UI mode (optional, default: "panel") // "panel" | "modal" settingsUI: "panel", // Settings schema (auto UI generation) settings: { /* settings definition */ }, // i18n messages messages: { /* translation data */ }, // Main window preview state previewState: { /* initial state for preview */ }, // HTML template function template: (state, settings, helpers) => { /* return template */ }, // Overlay mount logic onMount: (context) => { /* initialization logic */ return () => { /* cleanup */ }; }, });

Settings Schema

Define settings schema to auto-generate settings UI. Default is property panel; use settingsUI: "modal" for modal style.

Supported Types

settings: { // String nickname: { type: "string", default: "", label: "Nickname", placeholder: "Enter value", // optional }, // Number fontSize: { type: "number", default: 14, label: "Font Size", min: 8, // optional max: 48, // optional step: 2, // optional }, // Boolean (toggle) showGraph: { type: "boolean", default: true, label: "Show Graph", }, // Divider sectionDivider: { type: "divider", }, // Color textColor: { type: "color", default: "#FFFFFF", label: "Text Color", }, // Select (dropdown) theme: { type: "select", default: "dark", label: "Theme", options: [ { label: "Dark", value: "dark" }, { label: "Light", value: "light" }, ], }, },

type: "divider" adds only a divider in the settings UI without needing default or label.

Accessing Settings

// In template template: (state, settings, { html }) => html` <div style="color: ${settings.textColor};"> ${settings.showGraph ? html`<div class="graph">...</div>` : ""} </div> `, // In onMount onMount: ({ getSettings }) => { const settings = getSettings(); console.log("Current settings:", settings); },

Resize Anchor (resizeAnchor)

Sets the anchor position when element size changes. Default is "top-left".

Supported Anchor Positions (9 directions)

ValueDescription
top-leftTop-left (default)
top-centerTop center
top-rightTop-right
center-leftCenter-left
centerCenter
center-rightCenter-right
bottom-leftBottom-left
bottom-centerBottom center
bottom-rightBottom-right

Definition Level Setting

Define default anchor for all instances:

dmn.plugin.defineElement({ name: "Centered Panel", resizeAnchor: "center", // Default anchor for all instances // ... });

Dynamic Anchor Change (onMount)

Use setAnchor() and getAnchor() in onMount to dynamically change anchor:

dmn.plugin.defineElement({ name: "Dynamic Anchor Panel", onMount: ({ setAnchor, getAnchor }) => { // Check current anchor console.log("Current anchor:", getAnchor()); // "top-left" // Change anchor to center setAnchor("center"); // Change anchor based on condition const settings = getSettings(); if (settings.expandFromCenter) { setAnchor("center"); } else { setAnchor("top-left"); } }, });

Resize Settings (resizable, preserveAxis)

Use resizable option to let users resize elements directly in the grid.

resizable

Set resizable: true to show 8-direction resize handles:

dmn.plugin.defineElement({ name: "Resizable Panel", resizable: true, // Enable grid resize // ... });

Responsive design required: When using resizable, plugin internal elements must be responsive. Use relative units (%, flex, fr, etc.) instead of fixed sizes (px), and apply width: 100%; height: 100% to root element. Otherwise, internal content won’t adjust to container size on resize.

preserveAxis

Specifies which size axis to preserve when settings change. Only applies when resizable: true.

ValueDescription
bothPreserve both width and height (default)
widthPreserve width, adjust height to content
heightPreserve height, adjust width to content
noneFit both to content (resets resize effect)
dmn.plugin.defineElement({ name: "KPS Panel", resizable: true, preserveAxis: "width", // Preserve width on settings change // ... });