authorgravatar for 150583432+RaitP1@users.noreply.github.comRaitP1 <150583432+RaitP1@users.noreply.github.com> 2026-08-15 15:25:57+03:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-08-15 12:25:57+00:00
log1a5ff424cee104e1e8bbcf9bbf5414bbad843be3
treeab7c7a44b26ba976b6b64b02e8aeea8f43ae6589
parentb72d5d79889ad9b4c022060be9eccdfa64733d18
signature Signed by PGP key B5690EEEBB952194

fix(web): keep multi-select questions open after the first click (#6646)


1 files changed, 19 insertions(+), 16 deletions(-)

apps/web/src/components/chat/ComposerPendingUserInputPanel.tsx+19-16
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1import { type ApprovalRequestId } from "@t3tools/contracts";1import { type ApprovalRequestId } from "@t3tools/contracts";
2import { memo, useEffect, useEffectEvent, useRef, useState } from "react";2import { memo, useCallback, useEffect, useRef, useState } from "react";
3import { type PendingUserInput } from "../../session-logic";3import { type PendingUserInput } from "../../session-logic";
4import {4import {
5 derivePendingUserInputProgress,5 derivePendingUserInputProgress,
...@@ -109,21 +109,24 @@ const ComposerPendingUserInputCard = memo(function ComposerPendingUserInputCard(...@@ -109,21 +109,24 @@ const ComposerPendingUserInputCard = memo(function ComposerPendingUserInputCard(
109 };109 };
110 }, []);110 }, []);
111111
112 const handleOptionSelection = useEffectEvent((questionId: string, optionLabel: string) => {112 const handleOptionSelection = useCallback(
113 if (activeQuestion?.multiSelect) {113 (questionId: string, optionLabel: string) => {
114 if (activeQuestion?.multiSelect) {
115 onToggleOption(questionId, optionLabel);
116 return;
117 }
118 setOptimisticSingleSelect({ questionId, optionLabel });
114 onToggleOption(questionId, optionLabel);119 onToggleOption(questionId, optionLabel);
115 return;120 if (autoAdvanceTimerRef.current !== null) {
116 }121 window.clearTimeout(autoAdvanceTimerRef.current);
117 setOptimisticSingleSelect({ questionId, optionLabel });122 }
118 onToggleOption(questionId, optionLabel);123 autoAdvanceTimerRef.current = window.setTimeout(() => {
119 if (autoAdvanceTimerRef.current !== null) {124 autoAdvanceTimerRef.current = null;
120 window.clearTimeout(autoAdvanceTimerRef.current);125 onAdvanceRef.current();
121 }126 }, 200);
122 autoAdvanceTimerRef.current = window.setTimeout(() => {127 },
123 autoAdvanceTimerRef.current = null;128 [activeQuestion, onToggleOption],
124 onAdvanceRef.current();129 );
125 }, 200);
126 });
127130
128 // Keyboard shortcut: number keys 1-9 select corresponding options when focus is131 // Keyboard shortcut: number keys 1-9 select corresponding options when focus is
129 // outside editable fields. Multi-select prompts toggle options in place; single-132 // outside editable fields. Multi-select prompts toggle options in place; single-
...@@ -154,7 +157,7 @@ const ComposerPendingUserInputCard = memo(function ComposerPendingUserInputCard(...@@ -154,7 +157,7 @@ const ComposerPendingUserInputCard = memo(function ComposerPendingUserInputCard(
154 };157 };
155 document.addEventListener("keydown", handler);158 document.addEventListener("keydown", handler);
156 return () => document.removeEventListener("keydown", handler);159 return () => document.removeEventListener("keydown", handler);
157 }, [activeQuestion, isCollapsed, isResponding]);160 }, [activeQuestion, handleOptionSelection, isCollapsed, isResponding]);
158161
159 if (!activeQuestion) {162 if (!activeQuestion) {
160 return null;163 return null;