Skip to content

Instantly share code, notes, and snippets.

@kerrishotts
Last active February 4, 2019 00:46
Show Gist options
  • Save kerrishotts/1e41ada40bc3f907472c42f4f6565a71 to your computer and use it in GitHub Desktop.
Save kerrishotts/1e41ada40bc3f907472c42f4f6565a71 to your computer and use it in GitHub Desktop.
XD Plugin Lab: Part Three, Step 4: Validation (Optional)
/*
* Sample plugin code for Adobe XD.
*
* Visit http://adobexdplatform.com/ for API docs and more sample code.
*/
var {Rectangle, Color} = require("scenegraph");
function createRectangle(selection, hPadding, vPadding) {
var textNode = selection.items[0];
var bounds = textNode.boundsInParent;
console.log(bounds);
var shape = new Rectangle();
shape.width = bounds.width + 2 * hPadding
shape.height = bounds.height + 2 * vPadding;
shape.stroke = new Color("blue");
selection.insertionParent.addChild(shape);
shape.placeInParentCoordinates(
{x: 0, y: 0},
{x: bounds.x - hPadding, y: bounds.y - vPadding}
);
}
let dialog;
function createDialog() {
dialog = document.createElement("dialog");
dialog.innerHTML = `
<style>
form {
width: 400px;
}
.row {
display: flex;
align-items: center;
}
#error {
display: none;
background-color: red;
color: white;
border-radius: 4px;
border: 1px solid white;
text-align: center;
font-size: 12px;
flex: 1 1 auto;
}
</style>
<form method="dialog">
<h1>Create Button Frame</h1>
<hr />
<div class="row">
<label class="row">
<span>V:</span>
<input type="text" uxp-quiet="true" id="txtV" placeholder="V padding" />
</label>
<label class="row">
<span>H:</span>
<input type="text" uxp-quiet="true" id="txtH" placeholder="H padding" />
</label>
</div>
<footer>
<div id="error">Paddings must be specified as numbers.</div>
<button id="cancel" type="reset" uxp-variant="secondary">Cancel</button>
<button id="ok" type="submit" uxp-variant="cta">Apply</button>
</footer>
</form>`;
dialog.querySelector("#cancel").addEventListener("click", () => {
dialog.close("reasonCanceled");
});
dialog.querySelector("form").onsubmit = evt => {
const hPaddingValue = dialog.querySelector("#txtH").value;
const vPaddingValue = dialog.querySelector("#txtV").value;
if (Number.isNaN(Number(hPaddingValue)) || Number.isNaN(Number(vPaddingValue))) {
evt.preventDefault(); // cancels the dialog close
dialog.querySelector("#error").style.display = "block";
}
};
document.appendChild(dialog);
}
async function showDialog() {
const { selection } = require("scenegraph");
if (!dialog) {
createDialog();
}
// prevent user application if the selection is not the expected length
// could also alert the user, of course!
document.querySelector("#ok").disabled = selection.items.length !== 1;
// reset our error message as well.
dialog.querySelector("#error").style.display = "none";
const response = await dialog.showModal();
if (response !== 'reasonCanceled') {
// user wants to create the rectangle!
const hPadding = Number(dialog.querySelector("#txtH").value);
const vPadding = Number(dialog.querySelector("#txtV").value);
createRectangle(selection, hPadding, vPadding);
}
}
module.exports = {
commands: {
myPluginCommand: showDialog
}
};
{
"name": "Sample Plugin: Create Button Frame",
"id": "YOUR_ID_HERE",
"version": "1.0.0",
"description": "Sample plugin code for Adobe XD. Creates a rectangle around the selected text, with fixed padding.",
"host": {
"app": "XD",
"minVersion": "13.0.0"
},
"uiEntryPoints": [
{
"type": "menu",
"label": "Create Button Frame",
"commandId": "myPluginCommand"
}
]
}

XD Plugin Lab: Part Three, Step 4: Validation (Optional)

Note: This is part of a longer series.

This section covers how we can add some validation to our dialog. It's optional for the plugin lab.

NOTE: There are many ways to add validation; this section only presents a couple. Feel free to explore what works best for your plugin.

We're going to have two validation methods:

  1. If nothing (or too much) is selected, we'll disable the Apply button. (A better UX would be to show an error, but this suffices for our purposes now.)
  2. If something other than numbers are provided, we'll show an error to the user and refuse to close the dialog. (Another option would be to only enable the Apply button if all fields were truly numbers.)

Validation 1

In main.js:

  • Line 95: We can use the disabled property on the #ok button to prevent it from functioning if the selection is incorrect. Note: this won't prevent form submission: how might you accomplish that?

Validation 2

In main.js:

  • First, we define some styles in lines 40-49. Note that you can be fairly inventive with how things look.
  • Line 65: we add the error message. Note that it's hidden by default because the style has display: none
  • Lines 75-82: We check if the inputs are numbers. If not, we prevent the dialog closure (line 79), and then show the error
  • Line 97: When we're showing the dialog, we hide the error message
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment