impress/app/assets/javascripts/outfit-rename-field.js

42 lines
1.4 KiB
JavaScript

/**
* OutfitRenameField web component
*
* Progressive enhancement for the outfit name field:
* - Shows a static text header with a pencil icon button
* - Pencil appears on hover/focus of the container
* - Clicking pencil switches to the editable form
* - Enter submits, Escape or Cancel reverts to static display
*
* State is managed via the `editing` attribute, which CSS uses to toggle
* visibility. Turbo morphs naturally reset this attribute (since it's not in
* the server HTML), so no morph-specific handling is needed.
*/
class OutfitRenameField extends HTMLElement {
connectedCallback() {
const pencil = this.querySelector(".outfit-rename-pencil");
const cancel = this.querySelector(".outfit-rename-cancel");
const input = this.querySelector("input[type=text]");
if (!pencil || !cancel || !input) return;
pencil.addEventListener("click", () => {
this.dataset.originalValue = input.value;
this.setAttribute("editing", "");
input.focus();
input.select();
});
cancel.addEventListener("click", () => {
input.value = this.dataset.originalValue ?? input.value;
this.removeAttribute("editing");
});
this.addEventListener("keydown", (e) => {
if (e.key === "Escape" && this.hasAttribute("editing")) {
e.preventDefault();
cancel.click();
}
});
}
}
customElements.define("outfit-rename-field", OutfitRenameField);