diff --git a/apps/code/src/renderer/components/action-selector/ActionSelector.tsx b/apps/code/src/renderer/components/action-selector/ActionSelector.tsx index 0dfa07722..bd039e457 100644 --- a/apps/code/src/renderer/components/action-selector/ActionSelector.tsx +++ b/apps/code/src/renderer/components/action-selector/ActionSelector.tsx @@ -52,6 +52,7 @@ export function ActionSelector({ hasSteps, numSteps, showSubmitButton, + canSubmitOrAdvance, allOptions, showInlineEdit, moveUp, @@ -284,6 +285,10 @@ export function ActionSelector({ const isSelected = selectedIndex === index; const isHovered = hoveredIndex === index; + const isDisabled = + isSubmitOption(option.id) && + showSubmitButton && + !canSubmitOrAdvance; return ( void; onNavigateUp: () => void; onNavigateDown: () => void; @@ -52,6 +53,7 @@ export function OptionRow({ customInputPlaceholder, isEditing, submitLabel, + disabled = false, onCustomInputChange, onNavigateUp, onNavigateDown, @@ -63,34 +65,37 @@ export function OptionRow({ }: OptionRowProps) { if (isSubmitOption(option.id) || isCancelOption(option.id)) { const isCancel = isCancelOption(option.id); + const submitBg = disabled + ? "bg-(--gray-4)" + : isSelected + ? "bg-(--blue-8)" + : isHovered + ? "bg-(--blue-4)" + : "bg-(--blue-3)"; return ( {isCancel ? option.label : submitLabel} diff --git a/apps/code/src/renderer/components/action-selector/useActionSelectorState.ts b/apps/code/src/renderer/components/action-selector/useActionSelectorState.ts index 057be94d2..dd77e2c23 100644 --- a/apps/code/src/renderer/components/action-selector/useActionSelectorState.ts +++ b/apps/code/src/renderer/components/action-selector/useActionSelectorState.ts @@ -76,6 +76,8 @@ export function useActionSelectorState({ ); const containerRef = useRef(null); const prevActiveStepRef = useRef(currentStep); + const customInputRef = useRef(""); + customInputRef.current = customInput; const activeStep = internalStep; const hasSteps = steps !== undefined && steps.length > 1; @@ -99,6 +101,7 @@ export function useActionSelectorState({ const selectedOption = allOptions[selectedIndex]; const showInlineEdit = isEditing && selectedOption && needsCustomInput(selectedOption); + const canSubmitOrAdvance = checkedOptions.size > 0; useEffect(() => { if (!isInteractiveElementInDifferentCell(containerRef)) { @@ -164,12 +167,17 @@ export function useActionSelectorState({ }, [activeStep, restoreStepAnswer]); useEffect(() => { - if (selectedOption && needsCustomInput(selectedOption)) { - setIsEditing(true); - } else { - setIsEditing(false); + const isCustom = !!selectedOption && needsCustomInput(selectedOption); + setIsEditing(isCustom); + if (isCustom && showSubmitButton && customInputRef.current.trim()) { + setCheckedOptions((prev) => { + if (prev.has(selectedOption.id)) return prev; + const next = multiSelect ? new Set(prev) : new Set(); + next.add(selectedOption.id); + return next; + }); } - }, [selectedOption]); + }, [selectedOption, showSubmitButton, multiSelect]); const moveUp = useCallback(() => { setHoveredIndex(null); @@ -249,6 +257,7 @@ export function useActionSelectorState({ onSelect(selected.id); return; } + if (!canSubmitOrAdvance) return; if (hasSteps && activeStep < numSteps - 1) { saveCurrentStepAnswer(); setStep(activeStep + 1); @@ -294,6 +303,7 @@ export function useActionSelectorState({ saveCurrentStepAnswer, setStep, isEditing, + canSubmitOrAdvance, ]); const selectByIndex = useCallback( @@ -306,6 +316,7 @@ export function useActionSelectorState({ onSelect(selected.id); return; } + if (!canSubmitOrAdvance) return; if (hasSteps && activeStep < numSteps - 1) { saveCurrentStepAnswer(); setStep(activeStep + 1); @@ -340,6 +351,7 @@ export function useActionSelectorState({ onSelect, saveCurrentStepAnswer, setStep, + canSubmitOrAdvance, ], ); @@ -355,6 +367,7 @@ export function useActionSelectorState({ onSelect(selected.id); return; } + if (!canSubmitOrAdvance) return; if (hasSteps && activeStep < numSteps - 1) { saveCurrentStepAnswer(); setStep(activeStep + 1); @@ -396,6 +409,7 @@ export function useActionSelectorState({ onSelect, saveCurrentStepAnswer, setStep, + canSubmitOrAdvance, ], ); @@ -451,16 +465,53 @@ export function useActionSelectorState({ const handleInlineSubmit = useCallback(() => { if (!selectedOption) return; - if (showSubmitButton) { - if (customInput.trim()) { - ensureChecked(selectedOption.id); + const trimmed = customInput.trim(); + + if (!showSubmitButton) { + if (trimmed) { + onSelect(selectedOption.id, trimmed); } - setIsEditing(false); + return; + } + + if (trimmed) { + ensureChecked(selectedOption.id); + } + setIsEditing(false); + + if (!trimmed && !canSubmitOrAdvance) { containerRef.current?.focus(); - } else if (customInput.trim()) { - onSelect(selectedOption.id, customInput.trim()); + return; } - }, [showSubmitButton, ensureChecked, selectedOption, customInput, onSelect]); + + if (hasSteps && activeStep < numSteps - 1) { + saveCurrentStepAnswer(); + setStep(activeStep + 1); + containerRef.current?.focus(); + return; + } + + if (multiSelect) { + handleSubmitMulti(); + } else { + handleSubmitSingle(); + } + }, [ + showSubmitButton, + ensureChecked, + selectedOption, + customInput, + onSelect, + hasSteps, + activeStep, + numSteps, + saveCurrentStepAnswer, + setStep, + multiSelect, + handleSubmitMulti, + handleSubmitSingle, + canSubmitOrAdvance, + ]); const handleNavigateUp = useCallback(() => { if ( @@ -503,6 +554,7 @@ export function useActionSelectorState({ hasSteps, numSteps, showSubmitButton, + canSubmitOrAdvance, allOptions, selectedOption, showInlineEdit,