diff --git a/web/comfyui/loras_widget.js b/web/comfyui/loras_widget.js index cd8cca35..ef7457a3 100644 --- a/web/comfyui/loras_widget.js +++ b/web/comfyui/loras_widget.js @@ -1,4 +1,4 @@ -import { createToggle, createArrowButton, PreviewTooltip, createDragHandle, updateEntrySelection } from "./loras_widget_components.js"; +import { createToggle, createArrowButton, PreviewTooltip, createDragHandle, updateEntrySelection, createExpandButton, updateExpandButtonState } from "./loras_widget_components.js"; import { parseLoraValue, formatLoraValue, @@ -215,7 +215,8 @@ export function addLorasWidget(node, name, opts, callback) { if (e.target.closest('.comfy-lora-toggle') || e.target.closest('input') || e.target.closest('.comfy-lora-arrow') || - e.target.closest('.comfy-lora-drag-handle')) { + e.target.closest('.comfy-lora-drag-handle') || + e.target.closest('.comfy-lora-expand-button')) { return; } @@ -225,41 +226,6 @@ export function addLorasWidget(node, name, opts, callback) { container.focus(); // Focus container for keyboard events }); - // Add double-click handler to toggle clip entry - loraEl.addEventListener('dblclick', (e) => { - // Skip if clicking on toggle or strength control areas - if (e.target.closest('.comfy-lora-toggle') || - e.target.closest('input') || - e.target.closest('.comfy-lora-arrow')) { - return; - } - - // Prevent default behavior - e.preventDefault(); - e.stopPropagation(); - - // Toggle the clip entry expanded state - const lorasData = parseLoraValue(widget.value); - const loraIndex = lorasData.findIndex(l => l.name === name); - - if (loraIndex >= 0) { - // Explicitly toggle the expansion state - const currentExpanded = shouldShowClipEntry(lorasData[loraIndex]); - lorasData[loraIndex].expanded = !currentExpanded; - - // If collapsing, set clipStrength = strength - if (!lorasData[loraIndex].expanded) { - lorasData[loraIndex].clipStrength = lorasData[loraIndex].strength; - } - - // Update the widget value - widget.value = formatLoraValue(lorasData); - - // Re-render to show/hide clip entry - renderLoras(widget.value, widget); - } - }); - // Create drag handle for reordering const dragHandle = createDragHandle(); @@ -280,11 +246,34 @@ export function addLorasWidget(node, name, opts, callback) { } }); + // Create expand button + const expandButton = createExpandButton(isExpanded, (shouldExpand) => { + // Toggle the clip entry expanded state + const lorasData = parseLoraValue(widget.value); + const loraIndex = lorasData.findIndex(l => l.name === name); + + if (loraIndex >= 0) { + // Set the expansion state + lorasData[loraIndex].expanded = shouldExpand; + + // If collapsing, set clipStrength = strength + if (!shouldExpand) { + lorasData[loraIndex].clipStrength = lorasData[loraIndex].strength; + } + + // Update the widget value + widget.value = formatLoraValue(lorasData); + + // Re-render to show/hide clip entry + renderLoras(widget.value, widget); + } + }); + // Create name display const nameEl = document.createElement("div"); nameEl.textContent = name; Object.assign(nameEl.style, { - marginLeft: "10px", + marginLeft: "4px", flex: "1", overflow: "hidden", textOverflow: "ellipsis", @@ -297,14 +286,6 @@ export function addLorasWidget(node, name, opts, callback) { msUserSelect: "none", }); - // Add expand indicator to name element - const expandIndicator = document.createElement("span"); - expandIndicator.textContent = isExpanded ? " ▼" : " ▶"; - expandIndicator.style.opacity = "0.7"; - expandIndicator.style.fontSize = "9px"; - expandIndicator.style.marginLeft = "4px"; - nameEl.appendChild(expandIndicator); - // Move preview tooltip events to nameEl instead of loraEl nameEl.addEventListener('mouseenter', async (e) => { e.stopPropagation(); @@ -463,6 +444,7 @@ export function addLorasWidget(node, name, opts, callback) { leftSection.appendChild(dragHandle); // Add drag handle first leftSection.appendChild(toggle); + leftSection.appendChild(expandButton); // Add expand button leftSection.appendChild(nameEl); loraEl.appendChild(leftSection); diff --git a/web/comfyui/loras_widget_components.js b/web/comfyui/loras_widget_components.js index 796ee061..b7bdecad 100644 --- a/web/comfyui/loras_widget_components.js +++ b/web/comfyui/loras_widget_components.js @@ -403,3 +403,86 @@ export class PreviewTooltip { this.element.remove(); } } + +// Function to create expand/collapse button +export function createExpandButton(isExpanded, onClick) { + const button = document.createElement("button"); + button.className = "comfy-lora-expand-button"; + button.type = "button"; + + Object.assign(button.style, { + width: "20px", + height: "20px", + display: "flex", + alignItems: "center", + justifyContent: "center", + cursor: "pointer", + userSelect: "none", + fontSize: "10px", + color: "rgba(226, 232, 240, 0.7)", + backgroundColor: "rgba(45, 55, 72, 0.3)", + border: "1px solid rgba(226, 232, 240, 0.2)", + borderRadius: "3px", + transition: "all 0.2s ease", + marginLeft: "6px", + marginRight: "4px", + flexShrink: "0", + outline: "none" + }); + + // Set icon based on expanded state + updateExpandButtonState(button, isExpanded); + + button.addEventListener("click", (e) => { + e.preventDefault(); + e.stopPropagation(); + onClick(!isExpanded); + }); + + // Add hover effects + button.addEventListener("mouseenter", () => { + button.style.backgroundColor = "rgba(66, 153, 225, 0.2)"; + button.style.borderColor = "rgba(66, 153, 225, 0.4)"; + button.style.color = "rgba(226, 232, 240, 0.9)"; + button.style.transform = "scale(1.05)"; + }); + + button.addEventListener("mouseleave", () => { + button.style.backgroundColor = "rgba(45, 55, 72, 0.3)"; + button.style.borderColor = "rgba(226, 232, 240, 0.2)"; + button.style.color = "rgba(226, 232, 240, 0.7)"; + button.style.transform = "scale(1)"; + }); + + // Add active (pressed) state + button.addEventListener("mousedown", () => { + button.style.transform = "scale(0.95)"; + button.style.backgroundColor = "rgba(66, 153, 225, 0.3)"; + }); + + button.addEventListener("mouseup", () => { + button.style.transform = "scale(1.05)"; // Return to hover state + }); + + // Add focus state for keyboard accessibility + button.addEventListener("focus", () => { + button.style.boxShadow = "0 0 0 2px rgba(66, 153, 225, 0.5)"; + }); + + button.addEventListener("blur", () => { + button.style.boxShadow = "none"; + }); + + return button; +} + +// Helper function to update expand button state +export function updateExpandButtonState(button, isExpanded) { + if (isExpanded) { + button.innerHTML = "▼"; // Down arrow for expanded + button.title = "Collapse clip controls"; + } else { + button.innerHTML = "▶"; // Right arrow for collapsed + button.title = "Expand clip controls"; + } +} diff --git a/web/comfyui/loras_widget_events.js b/web/comfyui/loras_widget_events.js index 9108a173..fa0d5633 100644 --- a/web/comfyui/loras_widget_events.js +++ b/web/comfyui/loras_widget_events.js @@ -120,7 +120,9 @@ export function initDrag(dragEl, name, widget, isClipStrength = false, previewTo // Skip if clicking on toggle or strength control areas if (e.target.closest('.comfy-lora-toggle') || e.target.closest('input') || - e.target.closest('.comfy-lora-arrow')) { + e.target.closest('.comfy-lora-arrow') || + e.target.closest('.comfy-lora-drag-handle') || + e.target.closest('.comfy-lora-expand-button')) { return; }