diff --git a/app/assets/javascripts/outfit-rename-field.js b/app/assets/javascripts/outfit-rename-field.js index c3b0d4f8..60a42e69 100644 --- a/app/assets/javascripts/outfit-rename-field.js +++ b/app/assets/javascripts/outfit-rename-field.js @@ -5,7 +5,7 @@ * - 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 + * - Enter submits, Escape/blur 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 @@ -14,9 +14,8 @@ 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; + if (!pencil || !input) return; pencil.addEventListener("click", () => { this.dataset.originalValue = input.value; @@ -25,17 +24,23 @@ class OutfitRenameField extends HTMLElement { 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(); + this.#cancelEditing(input); } }); + + 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"); } } diff --git a/app/assets/stylesheets/wardrobe/show.css b/app/assets/stylesheets/wardrobe/show.css index fe6a24a3..92ef48eb 100644 --- a/app/assets/stylesheets/wardrobe/show.css +++ b/app/assets/stylesheets/wardrobe/show.css @@ -981,10 +981,6 @@ outfit-rename-field[editing] .outfit-name-form { opacity: 1; } -.outfit-rename-cancel { - margin-left: 0.5rem; -} - /* Hide save button when rename is in editing state */ .outfit-header:has(outfit-rename-field[editing]) .outfit-save-form, .outfit-header:has(outfit-rename-field[editing]) .outfit-save-button:disabled { diff --git a/app/views/wardrobe/_outfit_rename_field.html.haml b/app/views/wardrobe/_outfit_rename_field.html.haml index ddb6636d..70cb2665 100644 --- a/app/views/wardrobe/_outfit_rename_field.html.haml +++ b/app/views/wardrobe/_outfit_rename_field.html.haml @@ -19,4 +19,4 @@ class: "outfit-name-input", placeholder: "Untitled outfit", "aria-label": "Outfit name" = f.submit "Rename", name: nil, class: "outfit-name-submit" - %button.outfit-rename-cancel{type: "button"} Cancel +