Note: This post by @kerrishotts is a mirror of an Adobe Tech Blog post to facilitate discussion.
In UXP 5.5.1 (the version shipping at MAX’21 in both Adobe XD version 45 and Photoshop version 23), there are some issues that may impact the usability of your plugin. You may wish to apply some of these workarounds in order to avoid any issues after MAX.
Issues you may encounter
- sp-textfield doesn’t fire
change
- Setting a numeric sp-textfield’s
value
attribute can fail - Typing a decimal point in a numeric
sp-textfield
is difficult
sp-textfield doesn’t fire change
Applies to PS 23 and XD 45
sp-textfield
won’t send change
events. If your code relies upon change
events for functionality this may cause issues in your plugin. For example, if you rely on change
to handle validation checks, then those validation checks won’t run when you expect. If you rely on change
to update other UI widgets, those will also fail to be updated.
Manual workarounds
Other events on sp-textfield
continue to work, including input
, focus
, and blur
. As such, you may elect to use these events instead of change
.
You can also switch from sp-textfield
to sp-textarea
if your design will accommodate it. Alternatively, you can switch to the native input type="text"
widget temporarily.
Automatic workaround (“buggyfill”)
Alternatively, you can drop in the following code snippet in your index.html
or your main JavaScript file. This code will attempt to synthesize the change
event whenever a change occurs in sp-textfield
widgets. This is done by hooking into the focus
and blur
events. It works with both Vanilla and React. It’s not been tested with other frameworks.
(function () {
if(require("uxp").versions.uxp.startsWith("uxp-5.5.1")) {
let curField, curValue;
document.addEventListener("focus", evt => {
curField = evt.target;
curValue = curField.value;
}, true);
document.addEventListener("blur", evt => {
if (evt.target.tagName === "SP-TEXTFIELD") {
if (curField === evt.target) {
if (curValue !== evt.target.value) {
const changeEvent = new Event("change", {
bubbles: true
});
evt.target.dispatchEvent(changeEvent);
}
}
}
}, true);
}
})();
Setting a numeric sp-textfield’s value
attribute can fail
Applies to PS 23 and XD 45
If you set the value
attribute of a numeric sp-textfield, you should do so using strings, as the implicit type conversion will fail.
const numberField = document.querySelector("sp-textfield[type=number]");
numberField.value = 10; /* won't work; field will be blank */
numberField.value = "10"; /* will work. */
Manual workaround
There’s no drop-in code to address this issue. Instead, you should be certain that you’re assigning a string representation of a number instead of the actual number itself.
const numberField = document.querySelector("sp-textfield[type=number]");
numberField.value = `${numberOfSteps}`; /* template literals will work */
numberField.value = "" + numberOfSteps; /* or you can do this. */
Typing a decimal point in a numeric sp-textfield
is difficult
Applies to PS 23
Typing a decimal point as part of a non-integer number can be difficult. Users may need to repeat the keystroke several times before the decimal point stays.
Manual workarounds
You can temporarily switch from <sp-textfield type="number">
to <sp-textfield type="text">
. This does mean that users could enter non-numeric data, but you can add validators to handle this.
You could also switch to input type="text"
temporarily.
Automatic workaround
Alternatively, you can use the following drop-in workaround. It detects any new numeric sp-textfield
widgets and automatically converts them to a regular text field. It then adds a handler that forces the contents of the field to be numeric. Note that the type of the value
attribute remains a string, so you’ll need to convert the value to a number if you intend on using it as such (e.g., Number(field.value)
)
(function () {
function fixNumericSpTextField() {
if(require("uxp").versions.uxp.startsWith("uxp-5.5.1")) {
const candidates = document.querySelectorAll("sp-textfield[type=number]");
candidates.forEach(el => {
el.setAttribute("type", "text");
el.setAttribute("data-uxp-type", "number");
});
}
document.addEventListener("input", evt => {
const { target } = evt;
if (target.tagName === "SP-TEXTFIELD") {
if (target.getAttribute("data-uxp-type") === "number") {
if (Number.isNaN(Number(target.value)) || target.value.indexOf(" ") > -1) {
target.value = target.getAttribute("data-uxp-last-good-value") || "0";
} else {
target.setAttribute("data-uxp-last-good-value", target.value.trim());
}
}
}
});
const timer = setInterval(() => {
/* IMPORTANT: next lines use private APIs to make sure we keep
fixing up text fields as they are added to the DOM.
DO NOT USE _domClient OR frameAck FOR ANY OTHER PURPOSE. */
if (document._domClient) {
document._domClient.addEventListener("frameAck", fixNumericSpTextField);
clearInterval(timer);
fixNumericSpTextField();
}
}, 16);
}
})();
Next Steps
Now that you know the issues, what should you do next?
-
You should immediately test your plugins in the Prerelease build of Photoshop and/or XD. (To join the Photoshop or XD prerelease groups, if you’re not already a member, reach out to finnegan@adobe.com.)This will help you determine if your plugins are impacted by the issues.
While the issues themselves are present in all builds, how your plugin is impacted will be based upon your code. If you use
input
instead ofchange
, for example, you’re unlikely to be impacted by the fact thatsp-textfield
doesn’t want to fire thechange
event. -
Apply the appropriate remediations to your plugin and re-test.
You may elect to use the automated workarounds above to help address the issue more quickly, but you should still test your plugin to ensure that these workarounds provide an acceptable experience.
-
If you’ve made changes, resubmit your plugin to the marketplace.
Please be sure to let us know if you submit a change so that we can ensure your fix is approved before MAX. Email xdplugindevs1@adobe.com, or respond here in the forums.
If you have questions or run into issues, please don’t hesitate to reach out.