Given a dialog of the form:
<dialog id="dlg">
<form method="dialog">
<sp-textfield type="text"></sp-textfield>
<sp-button type="submit" id="formTestButton">Submit</sp-button>
</form>
</dialog>
You can use this JS to respond to normal or alternate dismissal:
function decorateDialogWithAltKeySubmission(theDialog, {normal, alternate} = {}) {
const theDialogForm = theDialog.querySelector("form");
// if dialog has been decorated before, bail
if (theDialog.dataset.decorated) return;
// keep track of user's intent throughout key presses, clicks, and submits
let theDialogReturnValue = normal;
// detect if ALT is pressed
function setDialogReturnValue(event) {
if (event.altKey === undefined) return; // ignore events where this
// isn't set so we don't
// forget the user intent
// pick the right return value based on altKey
theDialogReturnValue = event.altKey ? alternate : normal;
}
// if user presses ENTER, we want a chance to see if ALT is pressed
theDialogForm.addEventListener("keydown", event => {
if (event.key !== "Enter") return; // bail if ENTER isn't pressed
setDialogReturnValue(event);
});
// If the form is submitted, forward along our return value
theDialogForm.addEventListener("submit", (event) => {
event.preventDefault(); // prevent default blank (""_ return value
theDialog.close(theDialogReturnValue);
});
// sp-buttons don't automatically act as submit buttons, so
// check for ALT here and close
theDialogForm.querySelector("sp-button[type=submit]")
.addEventListener("click", event => {
setDialogReturnValue(event);
theDialog.close(theDialogReturnValue);
});
// don't decorate the dialog again
theDialog.dataset.decorated = "yes";
}
Then “decorate” the dialog with:
const theDialog = document.querySelector("#dlg");
decorateDialogWithAltKeySubmission(theDialog , {
normal: "translate", // return if ALT is not pressed
alternate: "duplicate" // return if ALT is pressed
});
Then when you show and get a response, you’ll get reasonCanceled
(ESC or other dismissal), the “normal” response (translate
) if ALT is not held, and the “alternate” response (duplicate
) if ALT is held.
const response = await theDialog.uxpShowModal({
title: "Title",
size: { width: 480, height: 320 }
})
if (response === "reasonCanceled") return;
if (response === "translate") { /* do translate stuff */ }
if (response === "duplicate") { /* do duplicate stuff */ }
Some other observations:
-
<button>
in PS doesn’t send UXP any modifiers. As such, altKey
(et al) will all be false
. Yes, I’d call it a bug, but the workaround is to use sp-button
.
-
<sp-button>
, however, is controlled by UXP and does send modifiers. altKey
will contain the state of the Alt key (whatever that is for the OS in question)
- ctrl+click has lots of funky behavior in Ps – on a
<button>
, submission will happen, but you won’t see ctrlKey === true
(it’ll be false
). On an <sp-button>
, ctrl+click won’t submit or send a click
event at all.
- As such, your most reliable option is
<sp-button>
and avoid the ctrl
key.