From dc7c0a1b711d2e39b6804cee2383afe978e2c44d Mon Sep 17 00:00:00 2001 From: Dariusz L Date: Thu, 28 May 2026 04:32:18 +0200 Subject: [PATCH] Replace inline style display toggles with CSS class-based visibility - Add new utility classes: ml-is-hidden, ml-is-visible, ml-is-inline-flex - Add ml-is-muted and ml-is-error for text color states - Add ml-is-success-action for success button styling - Add ml-icon-img for icon vertical alignment - Replace style.display = 'block/none' with classList toggles in linker.js - Update getIconHtml to use ml-icon-img class instead of inline styles --- web/css/linker-main.css | 35 +++++++++++++++++++++++++++++ web/linker.js | 50 ++++++++++++++++++++++++++++++----------- web/utils/icon_utils.js | 7 +++--- 3 files changed, 76 insertions(+), 16 deletions(-) diff --git a/web/css/linker-main.css b/web/css/linker-main.css index 1b3af39..1362d27 100644 --- a/web/css/linker-main.css +++ b/web/css/linker-main.css @@ -17,6 +17,41 @@ display: none !important; } +.ml-is-hidden { + display: none !important; +} + +.ml-is-visible { + display: block !important; +} + +.ml-is-inline-flex { + display: inline-flex !important; +} + +.ml-is-muted { + color: var(--ml-text-muted) !important; +} + +.ml-is-error { + color: var(--ml-color-error-light, #f44336) !important; +} + +.ml-is-active-text { + color: var(--ml-text) !important; +} + +.ml-is-success-action { + background: var(--ml-accent, #4CAF50) !important; + border-color: var(--ml-accent, #4CAF50) !important; + color: #101010 !important; + box-shadow: none !important; +} + +.ml-icon-img { + vertical-align: middle; +} + .ml-meta-line { margin-top: var(--ml-spacing-4); font-size: var(--ml-font-md); diff --git a/web/linker.js b/web/linker.js index 7cc15d7..b6ee095 100644 --- a/web/linker.js +++ b/web/linker.js @@ -690,7 +690,7 @@ class LinkerManagerDialog extends ComfyDialog { html += ``; const downloadSourceRow = this.getDownloadSourceTableRow(missing, downloadSource); - html += `
`; + html += `
`; html += this.renderSearchResultsTable(downloadSourceRow ? [downloadSourceRow] : []); html += `
`; return html; @@ -2908,7 +2908,8 @@ class LinkerManagerDialog extends ComfyDialog { if (!input || !button) return; const visible = input.type === 'text'; button.innerHTML = getVisibilityIcon(visible); - button.style.color = visible ? 'var(--ml-text)' : 'var(--ml-text-muted)'; + button.classList.toggle('ml-is-active-text', visible); + button.classList.toggle('ml-is-muted', !visible); button.setAttribute('aria-pressed', visible ? 'true' : 'false'); this.setTooltip(button, visible ? 'Hide saved value' : 'Show saved value'); }; @@ -4037,7 +4038,8 @@ class LinkerManagerDialog extends ComfyDialog { info.downloadBtn = newDownloadBtn; // Show that download is in progress - newProgressDiv.style.display = 'block'; + newProgressDiv.classList.remove('ml-is-hidden'); + newProgressDiv.classList.add('ml-is-visible'); newProgressDiv.innerHTML = this.renderProgressWithAction({ percent: 0, leftText: 'Downloading...', @@ -4458,12 +4460,18 @@ class LinkerManagerDialog extends ComfyDialog { }, 200); comboInput.addEventListener('input', debouncedFilter); comboInput.addEventListener('focus', () => { - if (comboList) comboList.style.display = 'block'; + if (comboList) { + comboList.classList.remove('ml-is-hidden'); + comboList.classList.add('ml-is-visible'); + } populateComboOptions(comboInput.value); }); comboInput.addEventListener('blur', () => { setTimeout(() => { - if (comboList) comboList.style.display = 'none'; + if (comboList) { + comboList.classList.remove('ml-is-visible'); + comboList.classList.add('ml-is-hidden'); + } }, 200); }); } @@ -4479,7 +4487,8 @@ class LinkerManagerDialog extends ComfyDialog { const state = this.searchResultCache.get(this.getMissingSearchKey(missing)); const searchResultsDiv = container.querySelector(`#search-results-${missing.node_id}-${missing.widget_index}`); if (state && searchResultsDiv && this.hasRenderableSearchState(state)) { - searchResultsDiv.style.display = 'block'; + searchResultsDiv.classList.remove('ml-is-hidden'); + searchResultsDiv.classList.add('ml-is-visible'); this.displaySearchResults(missing, state, searchResultsDiv); } } @@ -5146,10 +5155,12 @@ class LinkerManagerDialog extends ComfyDialog { // Disable button and show progress with cancel button immediately if (downloadBtn) { downloadBtn.disabled = true; + downloadBtn.classList.remove('ml-is-success-action', 'ml-btn-primary'); downloadBtn.textContent = 'Starting...'; } if (progressDiv) { - progressDiv.style.display = 'block'; + progressDiv.classList.remove('ml-is-hidden'); + progressDiv.classList.add('ml-is-visible'); // Show progress bar with cancel button immediately progressDiv.innerHTML = this.renderProgressWithAction({ percent: 0, @@ -5205,6 +5216,7 @@ class LinkerManagerDialog extends ComfyDialog { } if (downloadBtn) { downloadBtn.disabled = false; + downloadBtn.classList.remove('ml-is-success-action', 'ml-btn-primary'); downloadBtn.innerHTML = '☁ Retry'; } this.showNotification('Download failed: ' + error.message, 'error'); @@ -5262,6 +5274,7 @@ class LinkerManagerDialog extends ComfyDialog { } if (downloadBtn) { downloadBtn.textContent = '✓ Done'; + downloadBtn.classList.remove('ml-is-success-action'); downloadBtn.classList.add('ml-btn-primary'); } delete this.activeDownloads[downloadId]; @@ -5280,6 +5293,7 @@ class LinkerManagerDialog extends ComfyDialog { } if (downloadBtn) { downloadBtn.disabled = false; + downloadBtn.classList.remove('ml-is-success-action', 'ml-btn-primary'); downloadBtn.textContent = 'Retry'; } delete this.activeDownloads[downloadId]; @@ -5291,6 +5305,7 @@ class LinkerManagerDialog extends ComfyDialog { } if (downloadBtn) { downloadBtn.disabled = false; + downloadBtn.classList.remove('ml-is-success-action', 'ml-btn-primary'); downloadBtn.innerHTML = '☁ Download'; } delete this.activeDownloads[downloadId]; @@ -5314,7 +5329,8 @@ class LinkerManagerDialog extends ComfyDialog { if (downloadBtn) { downloadBtn.disabled = false; downloadBtn.textContent = 'Retry'; - downloadBtn.style.background = '#4CAF50'; + downloadBtn.classList.remove('ml-btn-primary'); + downloadBtn.classList.add('ml-is-success-action'); } } delete this.activeDownloads[downloadId]; @@ -5418,7 +5434,8 @@ class LinkerManagerDialog extends ComfyDialog { searchBtn.innerHTML = `${this.getSearchIconHtml()} Searching ${selectedSourceLabel}...`; } if (resultsDiv) { - resultsDiv.style.display = 'block'; + resultsDiv.classList.remove('ml-is-hidden'); + resultsDiv.classList.add('ml-is-visible'); this.displaySearchResults(missing, state, resultsDiv); } for (const source of sourceIds) { @@ -5603,6 +5620,7 @@ class LinkerManagerDialog extends ComfyDialog { const data = await response.json(); const loadingEl = document.getElementById(loadingElementId); if (loadingEl && data.civitai) { + loadingEl.classList.remove('ml-is-muted', 'ml-is-error'); const civitai = data.civitai; const labelHtml = this.renderVersionedModelNameHtml(civitai.name, civitai.version_name) || this.escapeHtml(civitai.filename || 'Model'); @@ -5610,7 +5628,8 @@ class LinkerManagerDialog extends ComfyDialog { loadingEl.innerHTML = `${labelHtml}`; } else if (loadingEl) { loadingEl.textContent = 'Not found'; - loadingEl.style.color = 'var(--ml-text-muted)'; + loadingEl.classList.remove('ml-is-error'); + loadingEl.classList.add('ml-is-muted'); } const downloadContainerId = loadingElementId.replace('urn-loading-', 'urn-download-'); @@ -5655,7 +5674,8 @@ class LinkerManagerDialog extends ComfyDialog { const loadingEl = document.getElementById(loadingElementId); if (loadingEl) { loadingEl.textContent = 'Error'; - loadingEl.style.color = '#f44336'; + loadingEl.classList.remove('ml-is-muted'); + loadingEl.classList.add('ml-is-error'); } const downloadContainerId = loadingElementId.replace('urn-loading-', 'urn-download-'); const downloadEl = document.getElementById(downloadContainerId); @@ -5668,7 +5688,8 @@ class LinkerManagerDialog extends ComfyDialog { const loadingEl = document.getElementById(loadingElementId); if (loadingEl) { loadingEl.textContent = 'Error'; - loadingEl.style.color = '#f44336'; + loadingEl.classList.remove('ml-is-muted'); + loadingEl.classList.add('ml-is-error'); } const downloadContainerId = loadingElementId.replace('urn-loading-', 'urn-download-'); const downloadEl = document.getElementById(downloadContainerId); @@ -5926,10 +5947,12 @@ class LinkerManagerDialog extends ComfyDialog { try { btn.disabled = true; + btn.classList.remove('ml-is-success-action', 'ml-btn-primary'); btn.textContent = 'Starting...'; if (progressDiv) { - progressDiv.style.display = 'block'; + progressDiv.classList.remove('ml-is-hidden'); + progressDiv.classList.add('ml-is-visible'); // Show progress bar with cancel button immediately progressDiv.innerHTML = this.renderProgressWithAction({ percent: 0, @@ -5983,6 +6006,7 @@ class LinkerManagerDialog extends ComfyDialog { progressDiv.innerHTML = this.renderStatusMessage(error.message, 'error'); } btn.disabled = false; + btn.classList.remove('ml-is-success-action', 'ml-btn-primary'); btn.textContent = 'Retry'; this.showNotification('Download failed: ' + error.message, 'error'); } diff --git a/web/utils/icon_utils.js b/web/utils/icon_utils.js index 47f8067..5801897 100644 --- a/web/utils/icon_utils.js +++ b/web/utils/icon_utils.js @@ -24,12 +24,13 @@ const SVG_ICONS = { * @param {Image} icon - The icon Image object (or null) * @param {string} fallback - Fallback text/emoji if icon is not available (default: '') * @param {number} size - Size of the icon in pixels (default: 14) - * @param {string} extraStyles - Additional CSS styles (default: 'vertical-align: middle;') + * @param {string} extraStyles - Optional additional CSS styles * @returns {string} HTML string for the icon or fallback */ -export function getIconHtml(icon, fallback = '', size = 14, extraStyles = 'vertical-align: middle;') { +export function getIconHtml(icon, fallback = '', size = 14, extraStyles = '') { if (!icon) return fallback; - return ``; + const styleAttr = extraStyles ? ` style="${extraStyles}"` : ''; + return ``; } /**