Edit in GitHubLog an issue

The main.js file

Every UI entry point you declare in manifest.json must be fulfilled by a definition exported from your main.js module.

Exporting happens by setting the value of module.exports:

Copied to your clipboard
1module.exports = {
2 commands: {
3 // definitions for each commandId in manifest go here
4 },
5 panels: {
6 // definitions for each panelId in manifest go here
7 },
8};

The details of what you need to export are different depending on the type of UI entry point. One plugin may use multiple types of UI entry points.

Direct-action commands (commandId)

exports.commands is a map linking each commandId from the manifest to a JS handler function in your code.

Manifest:

Copied to your clipboard
1"uiEntryPoints": [
2 {
3 "type": "menu",
4 "label": "Hello World Command",
5 "commandId": "helloCommand"
6 }
7]

main.js:

Copied to your clipboard
1function sayHello(selection, documentRoot) {
2 console.log("Hello, world!");
3}
4
5module.exports = {
6 commands: {
7 helloCommand: sayHello,
8 },
9};

Notice how the exported map object makes the connection from manifest to code:

  1. The commandId from the manifest, helloCommand, is the key
  2. The handler function, sayHello, is the value that the key maps to

The handler is called each time the command is invoked, and XD passes it two arguments providing useful context. Your handler function can show UI in a dialog box and/or edit the XD document.

Panel UI (panelId)

exports.panels is a map linking each panelId from the manifest to a JS panel object in your code.

Manifest:

Copied to your clipboard
1"uiEntryPoints": [
2 {
3 "type": "panel",
4 "label": "Hello World Panel",
5 "panelId": "helloPanel"
6 }
7]

main.js:

Copied to your clipboard
1function show(event) {
2 let dom = document.createElement("panel");
3 dom.innerHTML = `
4 <form method="dialog" id="main">
5 </form>
6 `;
7 event.node.appendChild(dom);
8}
9
10function hide(event) {
11 event.node.firstChild.remove();
12}
13
14function update(selection, documentRoot) {
15 // ...update panel DOM based on selection...
16}
17
18module.exports = {
19 panels: {
20 helloPanel: {
21 show,
22 hide,
23 update,
24 },
25 },
26};

Notice how the exported map object makes the connection from manifest to code:

  1. The panelId from the manifest, helloPanel, is the key
  2. An object with three methods (show(), hide(), and update()) is the value that the key maps to

The panel object implements this interface:

  • show() (required): called when your panel is made visible to the user. To populate the panel with UI elements, add DOM nodes to the event.node root node that is provided.

  • hide() (optional): called when your panel is hidden/closed.

  • update (optional): called whenever panel UI content should be updated. This includes when the panel is is shown, when the selection changes, or when the selected objects are mutated (move, resize, fill color change, etc.). This function should execute quickly since it's triggered for essentially every user action in XD while your panel is open. XD passes update() two arguments providing useful context.

Typically, you'll attach UI event listeners to the DOM nodes in your panel, and these event listeners may edit the XD document using an application.editDocument() operation.

Contextual arguments

The handler function for commands (sayHello() above) and the update() function for panels are both called with two arguments that provide useful context about XD's current state:

The argument names selection and documentRoot seen in the code samples above are arbitrary, but you'll see this naming convention used throughout our documentation.

Accessing app APIs

XD calls into your plugin code via the above exports. To call into XD's APIs from your plugin code, see Accessing APIs.

  • Privacy
  • Terms of Use
  • Do not sell or share my personal information
  • AdChoices
Copyright © 2023 Adobe. All rights reserved.