(folderId)
| 663 | const isValidFolderName = (s) => FOLDER_NAME_RE.test(s); |
| 664 | |
| 665 | function openFolderEditor(folderId) { |
| 666 | const folder = folders.find((f) => f.id === folderId); |
| 667 | if (!folder || folder.id === TRASH_ID) return; |
| 668 | closeFolderEditor(); |
| 669 | |
| 670 | let selectedColor = normalizeFolderColor(folder.color); |
| 671 | const overlay = document.createElement("div"); |
| 672 | overlay.className = "folder-editor-backdrop"; |
| 673 | overlay.innerHTML = ` |
| 674 | <form class="folder-editor" role="dialog" aria-modal="true" aria-label="Edit folder"> |
| 675 | <div class="folder-editor-head"> |
| 676 | <span>Edit folder</span> |
| 677 | <button class="folder-editor-close" type="button" aria-label="Close"> |
| 678 | <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"> |
| 679 | <path d="M18 6 6 18M6 6l12 12"></path> |
| 680 | </svg> |
| 681 | </button> |
| 682 | </div> |
| 683 | <label class="folder-editor-field"> |
| 684 | <span>Name</span> |
| 685 | <input class="folder-editor-name" type="text" maxlength="100" autocomplete="off" spellcheck="false" /> |
| 686 | </label> |
| 687 | <div class="folder-editor-field"> |
| 688 | <span>Color</span> |
| 689 | <div class="folder-editor-colors" role="group" aria-label="Folder color"> |
| 690 | ${folderColorButtonsHtml(selectedColor)} |
| 691 | </div> |
| 692 | </div> |
| 693 | <div class="folder-editor-msg" role="alert" aria-live="polite"></div> |
| 694 | <div class="folder-editor-actions"> |
| 695 | <button class="folder-editor-cancel" type="button">Cancel</button> |
| 696 | <button class="folder-editor-save" type="submit">Save</button> |
| 697 | </div> |
| 698 | </form> |
| 699 | `; |
| 700 | |
| 701 | const form = overlay.querySelector(".folder-editor"); |
| 702 | const input = overlay.querySelector(".folder-editor-name"); |
| 703 | input.value = folder.name; |
| 704 | |
| 705 | const refreshDots = () => { |
| 706 | for (const dot of overlay.querySelectorAll(".folder-color-dot")) { |
| 707 | const active = dot.dataset.color === selectedColor; |
| 708 | dot.classList.toggle("active", active); |
| 709 | dot.setAttribute("aria-pressed", String(active)); |
| 710 | } |
| 711 | }; |
| 712 | |
| 713 | overlay.addEventListener("mousedown", (e) => { |
| 714 | if (e.target === overlay) closeFolderEditor(); |
| 715 | }); |
| 716 | overlay.querySelector(".folder-editor-close")?.addEventListener("click", closeFolderEditor); |
| 717 | overlay.querySelector(".folder-editor-cancel")?.addEventListener("click", closeFolderEditor); |
| 718 | for (const dot of overlay.querySelectorAll(".folder-color-dot")) { |
| 719 | dot.addEventListener("click", () => { |
| 720 | selectedColor = normalizeFolderColor(dot.dataset.color); |
| 721 | refreshDots(); |
| 722 | }); |
no test coverage detected