2026-02-05 21:56:23 -08:00
|
|
|
/**
|
|
|
|
|
* 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
|
2026-02-05 22:01:45 -08:00
|
|
|
* - Enter submits, Escape/blur reverts to static display
|
2026-02-05 21:56:23 -08:00
|
|
|
*
|
|
|
|
|
* 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 input = this.querySelector("input[type=text]");
|
2026-02-05 22:01:45 -08:00
|
|
|
if (!pencil || !input) return;
|
2026-02-05 21:56:23 -08:00
|
|
|
|
|
|
|
|
pencil.addEventListener("click", () => {
|
|
|
|
|
this.dataset.originalValue = input.value;
|
|
|
|
|
this.setAttribute("editing", "");
|
|
|
|
|
input.focus();
|
|
|
|
|
input.select();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
this.addEventListener("keydown", (e) => {
|
|
|
|
|
if (e.key === "Escape" && this.hasAttribute("editing")) {
|
|
|
|
|
e.preventDefault();
|
2026-02-05 22:01:45 -08:00
|
|
|
this.#cancelEditing(input);
|
2026-02-05 21:56:23 -08:00
|
|
|
}
|
|
|
|
|
});
|
2026-02-05 22:01:45 -08:00
|
|
|
|
|
|
|
|
this.addEventListener("focusout", (e) => {
|
|
|
|
|
if (this.hasAttribute("editing") && !this.contains(e.relatedTarget)) {
|
|
|
|
|
this.#cancelEditing(input);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#cancelEditing(input) {
|
|
|
|
|
input.value = this.dataset.originalValue ?? input.value;
|
|
|
|
|
this.removeAttribute("editing");
|
2026-02-05 21:56:23 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
customElements.define("outfit-rename-field", OutfitRenameField);
|