From 98678a86982ab6f44e0ec8e66660096a88f95ce5 Mon Sep 17 00:00:00 2001 From: Will Miao Date: Mon, 27 Oct 2025 19:39:49 +0800 Subject: [PATCH] feat(loras): add backspace key handling for LoRA deletion with input focus check, fixes #601 Add keyboard navigation support for deleting selected LoRA entries using Backspace key while preventing accidental deletion when editing strength input values. The implementation includes: - Backspace key now deletes selected LoRA when pressed outside strength inputs - Backspace is ignored when focused on strength input fields to allow normal text editing - Added corresponding test cases to verify both deletion and non-deletion scenarios This prevents users from accidentally deleting LoRA entries while editing strength values and provides intuitive keyboard controls for LoRA management. --- .../lorasWidgetEvents.interactions.test.js | 58 +++++++++++++++++++ web/comfyui/loras_widget_events.js | 7 ++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/tests/frontend/components/lorasWidgetEvents.interactions.test.js b/tests/frontend/components/lorasWidgetEvents.interactions.test.js index 099f60c8..3a34faee 100644 --- a/tests/frontend/components/lorasWidgetEvents.interactions.test.js +++ b/tests/frontend/components/lorasWidgetEvents.interactions.test.js @@ -105,4 +105,62 @@ describe('LoRA widget drag interactions', () => { document.dispatchEvent(new MouseEvent('mouseup')); expect(document.body.classList.contains('lm-lora-strength-dragging')).toBe(false); }); + + it('deletes the selected LoRA when backspace is pressed outside of strength inputs', async () => { + const { handleKeyboardNavigation } = await import(EVENTS_MODULE); + const widget = { + value: [{ name: 'Test', strength: 0.5, clipStrength: 0.5 }], + callback: vi.fn(), + }; + const preventDefault = vi.fn(); + const renderSpy = vi.fn(); + const selectLora = vi.fn(); + const event = { + key: 'Backspace', + preventDefault, + ctrlKey: false, + metaKey: false, + target: document.createElement('div'), + }; + + const handled = handleKeyboardNavigation(event, 'Test', widget, renderSpy, selectLora); + + expect(handled).toBe(true); + expect(preventDefault).toHaveBeenCalled(); + expect(widget.value).toEqual([]); + expect(widget.callback).toHaveBeenCalledWith([]); + expect(renderSpy).toHaveBeenCalledWith([], widget); + expect(selectLora).toHaveBeenCalledWith(null); + }); + + it('keeps the LoRA entry when editing strength input and pressing backspace', async () => { + const { handleKeyboardNavigation } = await import(EVENTS_MODULE); + const strengthInput = document.createElement('input'); + strengthInput.classList.add('lm-lora-strength-input'); + + const widget = { + value: [{ name: 'Test', strength: 0.5, clipStrength: 0.5 }], + callback: vi.fn(), + }; + const preventDefault = vi.fn(); + const renderSpy = vi.fn(); + const selectLora = vi.fn(); + + const event = { + key: 'Backspace', + preventDefault, + ctrlKey: false, + metaKey: false, + target: strengthInput, + }; + + const handled = handleKeyboardNavigation(event, 'Test', widget, renderSpy, selectLora); + + expect(handled).toBe(false); + expect(preventDefault).not.toHaveBeenCalled(); + expect(widget.value).toHaveLength(1); + expect(widget.callback).not.toHaveBeenCalled(); + expect(renderSpy).not.toHaveBeenCalled(); + expect(selectLora).not.toHaveBeenCalled(); + }); }); diff --git a/web/comfyui/loras_widget_events.js b/web/comfyui/loras_widget_events.js index 06d4675b..4c074a26 100644 --- a/web/comfyui/loras_widget_events.js +++ b/web/comfyui/loras_widget_events.js @@ -354,9 +354,11 @@ export function initReorderDrag(dragHandle, loraName, widget, renderFunction) { // Function to handle keyboard navigation export function handleKeyboardNavigation(event, selectedLora, widget, renderFunction, selectLora) { if (!selectedLora) return false; - + const lorasData = parseLoraValue(widget.value); let handled = false; + const isStrengthInputFocused = + event?.target?.classList?.contains('lm-lora-strength-input') ?? false; // Check for Ctrl/Cmd modifier for reordering if (event.ctrlKey || event.metaKey) { @@ -420,6 +422,9 @@ export function handleKeyboardNavigation(event, selectedLora, widget, renderFunc case 'Delete': case 'Backspace': + if (isStrengthInputFocused) { + break; + } event.preventDefault(); const filtered = lorasData.filter(l => l.name !== selectedLora); widget.value = formatLoraValue(filtered);