Skip to Content

UI API

Extend the app’s UI through dmn.ui.

UI API is only available in main window. Calling from overlay shows a warning and does nothing.

Context Menu

Key Menu (addKeyMenuItem)

Add items to the menu shown when right-clicking a key.

const menuId = dmn.ui.contextMenu.addKeyMenuItem({ id: "copy-keycode", label: "Copy Key Code", onClick: (context) => { navigator.clipboard.writeText(context.keyCode); }, });

Context Object:

PropertyTypeDescription
keyCodestringKey code (e.g., “KeyD”)
indexnumberKey index
positionKeyPositionKey position info
modestringCurrent key mode

Grid Menu (addGridMenuItem)

Add items to the menu shown when right-clicking empty grid space.

dmn.ui.contextMenu.addGridMenuItem({ id: "add-timer", label: "Add Timer", onClick: (context) => { createTimer(context.position); }, });

Context Object:

PropertyTypeDescription
position{ dx, dy }Click position (grid coordinates)
modestringCurrent key mode
{ id: "my-menu", // Unique ID within plugin label: "Menu Item", // Display text position: "bottom", // "top" | "bottom" (default: bottom) // Conditional visibility visible: (context) => context.mode === "4key", // Conditional disable disabled: (context) => context.position.count === 0, // Click handler onClick: async (context) => { // ... }, }
// Update menu dmn.ui.contextMenu.updateMenuItem(menuId, { label: "New Label", disabled: true, }); // Remove specific menu dmn.ui.contextMenu.removeMenuItem(menuId); // Remove all menus from this plugin dmn.ui.contextMenu.clearMyMenuItems();

Display Element

displayElement is a low-level (primitive) API, not recommended for direct use. For adding custom UI elements to grid and overlay, strongly recommend using the declarative defineElement approach.

Add custom UI elements to grid and overlay.

Basic Usage

const panel = dmn.ui.displayElement.add({ html: `<div style="background: #000; color: #fff; padding: 16px;"> Hello! </div>`, position: { x: 100, y: 100 }, draggable: true, }); // Remove panel.remove();

State-based Template

const panel = dmn.ui.displayElement.add({ position: { x: 100, y: 100 }, state: { value: 0, history: [] }, template: (state, { html }) => html` <div style="background: #000; color: #fff; padding: 16px;"> <strong>${state.value}</strong> <div style="display: flex; gap: 2px;"> ${state.history.map( (v) => html` <span style="width: 4px; height: ${v}px; background: #86EFAC;" ></span> `, )} </div> </div> `, }); // State update → auto re-render panel.setState({ value: 42, history: [10, 20, 30] });

Event Handlers

dmn.ui.displayElement.add({ html: `<div>Click me</div>`, position: { x: 100, y: 100 }, // Direct function (recommended) onClick: async () => { console.log("Clicked!"); }, onPositionChange: async (pos) => { await dmn.plugin.storage.set("position", pos); }, onDelete: async () => { console.log("Deleted!"); }, });

Instance Methods

MethodDescription
setState(updates)Update state (re-renders template)
setData(updates)Update state (setState alias)
getState()Get current state
setText(selector, text)Set element text
setHTML(selector, html)Set element HTML
setStyle(selector, styles)Apply styles
addClass(selector, ...classes)Add classes
removeClass(selector, ...classes)Remove classes
toggleClass(selector, className)Toggle class
query(selector)Find element (including Shadow DOM)
update(config)Update metadata
remove()Remove element

Dialog

Modal dialogs for user interaction.

alert

Show simple alert.

await dmn.ui.dialog.alert("Saved!"); await dmn.ui.dialog.alert("Task complete", { confirmText: "OK" });

confirm

Show confirm/cancel dialog.

const ok = await dmn.ui.dialog.confirm("Proceed?"); if (ok) { // Confirm clicked }