diff --git a/web/css/resolver-main.css b/web/css/resolver-main.css index 0b054d7..2b6f044 100644 --- a/web/css/resolver-main.css +++ b/web/css/resolver-main.css @@ -5785,6 +5785,7 @@ box-shadow: inset 0 0 0 1px rgba(114,211,138,0.32); } .mr-folder-browser-toggle { + box-sizing: border-box; width: 18px; height: 18px; min-width: 18px; @@ -5798,6 +5799,13 @@ justify-content: center; cursor: pointer; } +.mr-folder-browser-row.is-expandable .mr-folder-browser-toggle { + width: 29px; + min-width: 29px; + margin-left: -7px; + margin-right: -4px; + padding-left: 7px; +} .mr-folder-browser-toggle:hover { background: rgba(255,255,255,0.06); color: var(--mr-text); diff --git a/web/resolver/search/download_target_methods.js b/web/resolver/search/download_target_methods.js index 6cc4436..1c7cb46 100644 --- a/web/resolver/search/download_target_methods.js +++ b/web/resolver/search/download_target_methods.js @@ -1772,10 +1772,18 @@ export const downloadTargetMethods = { const children = hasChildren ? `
${renderFolderTreeNodes(node.children, rootGroup, expandedSet, filter, selectedValue, selectedBaseDirectory)}
` : ''; + const rowClass = [ + 'mr-folder-browser-row', + isSelected ? 'is-selected' : '', + hasChildren ? 'is-expandable' : '' + ].filter(Boolean).join(' '); + const rowStateAttribute = hasChildren + ? ` data-state-key="${encodeURIComponent(stateKey)}"` + : ''; return `
-
+
${toggle} ${getSvgIcon('folderOpen', 'currentColor', 'mr-folder-browser-svg')} ${this.escapeHtml(node.name)} @@ -1890,20 +1898,38 @@ export const downloadTargetMethods = { requestAnimationFrame(restoreScrollPosition); } + const toggleFolderBrowserState = (encodedStateKey) => { + const stateKey = decodeURIComponent(encodedStateKey || ''); + if (!stateKey) return; + if (expandedSet.has(stateKey)) { + expandedSet.delete(stateKey); + } else { + expandedSet.add(stateKey); + } + renderDownloadFolderBrowser(targetEl, folders, filterText, onSelect, { + preserveScroll: true + }); + }; + + const isFolderBrowserToggleZoneClick = (event, row) => { + if (!row?.dataset?.stateKey) return false; + const rowRect = row.getBoundingClientRect(); + const toggleEl = row.querySelector('.mr-folder-browser-toggle:not(.mr-folder-browser-toggle-empty)'); + const folderIconEl = row.querySelector('.mr-folder-browser-folder-icon'); + const toggleRect = toggleEl?.getBoundingClientRect(); + const iconRect = folderIconEl?.getBoundingClientRect(); + const toggleZoneRight = Math.max( + toggleRect?.right || rowRect.left, + iconRect?.left || rowRect.left + ); + return event.clientX >= rowRect.left && event.clientX <= toggleZoneRight; + }; + targetEl.querySelectorAll('[data-browser-action="toggle"]').forEach(button => { button.addEventListener('mousedown', (event) => { event.preventDefault(); event.stopPropagation(); - const stateKey = decodeURIComponent(button.dataset.stateKey || ''); - if (!stateKey) return; - if (expandedSet.has(stateKey)) { - expandedSet.delete(stateKey); - } else { - expandedSet.add(stateKey); - } - renderDownloadFolderBrowser(targetEl, folders, filterText, onSelect, { - preserveScroll: true - }); + toggleFolderBrowserState(button.dataset.stateKey || ''); }); }); @@ -1911,6 +1937,10 @@ export const downloadTargetMethods = { row.addEventListener('mousedown', (event) => { event.preventDefault(); event.stopPropagation(); + if (isFolderBrowserToggleZoneClick(event, row)) { + toggleFolderBrowserState(row.dataset.stateKey || ''); + return; + } const value = decodeURIComponent(row.dataset.value || ''); const baseDirectory = decodeURIComponent(row.dataset.baseDirectory || ''); onSelect(value, '', baseDirectory);